Decompiled source of Sandevistan v1.1.0

Sandevistan.dll

Decompiled 3 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using HarmonyLib;
using Il2Cpp;
using Il2CppHurricaneVR.Framework.Core;
using Il2CppHurricaneVR.Framework.Core.Grabbers;
using Il2CppHurricaneVR.Framework.Shared;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using MelonLoader;
using SandevistanMod;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(Core), "SandevistanMod", "60.7.0", "YourName", null)]
[assembly: MelonGame("Kubunautilus", "BrutalistickVR")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("Sandevistan")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Sandevistan")]
[assembly: AssemblyTitle("Sandevistan")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace SandevistanMod;

public static class SandevistanState
{
	public static bool IsActive;

	public static float TimeScale = 1f;

	public static float Strength = 0f;

	public static readonly Dictionary<int, float> ImpactInfluencedBodies = new Dictionary<int, float>();

	public static readonly Dictionary<int, float> ReleaseInfluencedBodies = new Dictionary<int, float>();
}
public static class RigTransformCache
{
	private static readonly Dictionary<string, Transform> cache = new Dictionary<string, Transform>();

	public static void Build(Transform rig)
	{
		cache.Clear();
		if ((Object)(object)rig == (Object)null)
		{
			return;
		}
		Transform[] array = Il2CppArrayBase<Transform>.op_Implicit(((Component)rig).GetComponentsInChildren<Transform>(true));
		if (array == null)
		{
			return;
		}
		Transform[] array2 = array;
		foreach (Transform val in array2)
		{
			if (!((Object)(object)val == (Object)null) && !cache.ContainsKey(((Object)val).name))
			{
				cache[((Object)val).name] = val;
			}
		}
	}

	public static Transform Find(string name)
	{
		cache.TryGetValue(name, out var value);
		return value;
	}

	public static void Clear()
	{
		cache.Clear();
	}
}
public static class SandevistanVisuals
{
	private static readonly Color LIME = new Color(0.1f, 0.3f, 0.06f);

	private static readonly Color TURQUOISE = new Color(0.05f, 0.78f, 0.75f);

	private static readonly Color VIGNETTE_DARK = new Color(0.01f, 0.06f, 0.01f);

	private const float MAX_TINT_ALPHA = 0.14f;

	private const float MAX_VIGNETTE_ALPHA = 0.28f;

	private const float TINT_DISTANCE = 0.25f;

	private const float VIGNETTE_DISTANCE = 0.3f;

	private const float OVERLAY_SIZE = 3f;

	private const float TRAIL_TIME = 0.25f;

	private const float TRAIL_START_WIDTH = 0.025f;

	private const float TRAIL_END_WIDTH = 0.002f;

	private const float MIN_HAND_SPEED_FOR_TRAIL = 0.6f;

	private const float TRAIL_MIN_STRENGTH = 0.3f;

	private static Camera playerCam;

	private static GameObject overlayRoot;

	private static GameObject tintQuad;

	private static GameObject vignetteQuad;

	private static GameObject leftTrailObj;

	private static GameObject rightTrailObj;

	private static Material tintMat;

	private static Material vignetteMat;

	private static Material trailMat;

	private static Texture2D vignetteTex;

	private static int refLayer = -1;

	private static TrailRenderer leftTrail;

	private static TrailRenderer rightTrail;

	private static bool trailsWereOn;

	private static bool initialized;

	public static void Init(Transform playerRig)
	{
		Cleanup();
		if (!((Object)(object)playerRig == (Object)null))
		{
			playerCam = FindCamera(playerRig);
			if (!((Object)(object)playerCam == (Object)null))
			{
				FindReferenceOverlay(playerCam);
				CreateOverlays();
				CreateTrails(RigTransformCache.Find("LeftHandModel"), RigTransformCache.Find("RightHandModel"));
				initialized = true;
			}
		}
	}

	private static Camera FindCamera(Transform rig)
	{
		Camera val = Camera.main;
		if ((Object)(object)val == (Object)null && (Object)(object)rig != (Object)null)
		{
			val = ((Component)rig).GetComponentInChildren<Camera>(true);
		}
		if ((Object)(object)val == (Object)null)
		{
			val = Object.FindObjectOfType<Camera>();
		}
		return val;
	}

	private static void FindReferenceOverlay(Camera cam)
	{
		refLayer = -1;
		if ((Object)(object)cam == (Object)null)
		{
			return;
		}
		string[] array = new string[2] { "DamageOverlay", "FadeToBlack" };
		foreach (string text in array)
		{
			Transform val = ((Component)cam).transform.Find(text);
			if ((Object)(object)val != (Object)null)
			{
				refLayer = ((Component)val).gameObject.layer;
				break;
			}
		}
	}

	private static void CreateOverlays()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Expected O, but got Unknown
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Expected O, but got Unknown
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_0155: Unknown result type (might be due to invalid IL or missing references)
		//IL_015f: Expected O, but got Unknown
		//IL_0188: Unknown result type (might be due to invalid IL or missing references)
		overlayRoot = new GameObject("SandevistanOverlayRoot");
		overlayRoot.transform.SetParent(((Component)playerCam).transform, false);
		overlayRoot.transform.localPosition = Vector3.zero;
		overlayRoot.transform.localRotation = Quaternion.identity;
		tintQuad = CreateQuad("SandevistanTint", 0.25f);
		if ((Object)(object)tintQuad != (Object)null)
		{
			MeshRenderer component = tintQuad.GetComponent<MeshRenderer>();
			tintMat = new Material(PickShader());
			tintMat.color = new Color(LIME.r, LIME.g, LIME.b, 0f);
			SetupTransparent(tintMat);
			tintMat.renderQueue = 5000;
			if ((Object)(object)component != (Object)null)
			{
				((Renderer)component).material = tintMat;
				((Renderer)component).shadowCastingMode = (ShadowCastingMode)0;
				((Renderer)component).receiveShadows = false;
			}
		}
		vignetteQuad = CreateQuad("SandevistanVignette", 0.3f);
		if ((Object)(object)vignetteQuad != (Object)null)
		{
			MeshRenderer component2 = vignetteQuad.GetComponent<MeshRenderer>();
			vignetteTex = CreateVignetteTexture(256);
			vignetteMat = new Material(PickShader());
			vignetteMat.mainTexture = (Texture)(object)vignetteTex;
			vignetteMat.color = new Color(1f, 1f, 1f, 0f);
			SetupTransparent(vignetteMat);
			vignetteMat.renderQueue = 5001;
			if ((Object)(object)component2 != (Object)null)
			{
				((Renderer)component2).material = vignetteMat;
				((Renderer)component2).shadowCastingMode = (ShadowCastingMode)0;
				((Renderer)component2).receiveShadows = false;
			}
		}
	}

	private static GameObject CreateQuad(string name, float distance)
	{
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)overlayRoot == (Object)null)
		{
			return null;
		}
		GameObject val = GameObject.CreatePrimitive((PrimitiveType)5);
		((Object)val).name = name;
		Collider component = val.GetComponent<Collider>();
		if ((Object)(object)component != (Object)null)
		{
			Object.Destroy((Object)(object)component);
		}
		if (refLayer >= 0)
		{
			val.layer = refLayer;
		}
		val.transform.SetParent(overlayRoot.transform, false);
		val.transform.localPosition = new Vector3(0f, 0f, distance);
		val.transform.localRotation = Quaternion.Euler(0f, 180f, 0f);
		val.transform.localScale = Vector3.one * 3f;
		return val;
	}

	private static Texture2D CreateVignetteTexture(int size)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Expected O, but got Unknown
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		Texture2D val = new Texture2D(size, size, (TextureFormat)4, false);
		float num = (float)size * 0.5f;
		for (int i = 0; i < size; i++)
		{
			for (int j = 0; j < size; j++)
			{
				float num2 = ((float)j - num) / num;
				float num3 = ((float)i - num) / num;
				float num4 = Mathf.Sqrt(num2 * num2 + num3 * num3);
				float num5 = Mathf.Clamp01((num4 - 0.55f) / 0.7f);
				num5 = num5 * num5 * (3f - 2f * num5);
				val.SetPixel(j, i, new Color(VIGNETTE_DARK.r, VIGNETTE_DARK.g, VIGNETTE_DARK.b, num5));
			}
		}
		val.Apply();
		return val;
	}

	private static void CreateTrails(Transform lm, Transform rm)
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Expected O, but got Unknown
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		trailMat = new Material(PickShader());
		trailMat.color = new Color(TURQUOISE.r, TURQUOISE.g, TURQUOISE.b, 1f);
		SetupTransparent(trailMat);
		trailMat.renderQueue = 4500;
		leftTrailObj = CreateTrail("SandevistanTrailL", lm);
		rightTrailObj = CreateTrail("SandevistanTrailR", rm);
		leftTrail = (((Object)(object)leftTrailObj != (Object)null) ? leftTrailObj.GetComponent<TrailRenderer>() : null);
		rightTrail = (((Object)(object)rightTrailObj != (Object)null) ? rightTrailObj.GetComponent<TrailRenderer>() : null);
	}

	private static GameObject CreateTrail(string name, Transform parent)
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Expected O, but got Unknown
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)parent == (Object)null)
		{
			return null;
		}
		GameObject val = new GameObject(name);
		val.transform.SetParent(parent, false);
		val.transform.localPosition = Vector3.zero;
		val.transform.localRotation = Quaternion.identity;
		TrailRenderer val2 = val.AddComponent<TrailRenderer>();
		if ((Object)(object)val2 == (Object)null)
		{
			Object.Destroy((Object)(object)val);
			return null;
		}
		val2.time = 0.25f;
		val2.startWidth = 0.025f;
		val2.endWidth = 0.002f;
		val2.minVertexDistance = 0.02f;
		val2.autodestruct = false;
		val2.emitting = false;
		val2.alignment = (LineAlignment)0;
		((Renderer)val2).material = trailMat;
		Color tURQUOISE = TURQUOISE;
		tURQUOISE.a = 0.5f;
		Color tURQUOISE2 = TURQUOISE;
		tURQUOISE2.a = 0f;
		val2.startColor = tURQUOISE;
		val2.endColor = tURQUOISE2;
		((Renderer)val2).shadowCastingMode = (ShadowCastingMode)0;
		((Renderer)val2).receiveShadows = false;
		return val;
	}

	public static void UpdateVisuals(float strength)
	{
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: 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_0084: Unknown result type (might be due to invalid IL or missing references)
		if (!initialized)
		{
			return;
		}
		float num = Mathf.Clamp01(strength);
		if ((Object)(object)tintMat != (Object)null)
		{
			Color color = tintMat.color;
			color.a = 0.14f * num;
			tintMat.color = color;
		}
		if ((Object)(object)vignetteMat != (Object)null)
		{
			Color color2 = vignetteMat.color;
			color2.a = 0.28f * num;
			vignetteMat.color = color2;
		}
		bool flag = num > 0.001f;
		if ((Object)(object)tintQuad != (Object)null)
		{
			tintQuad.SetActive(flag);
		}
		if ((Object)(object)vignetteQuad != (Object)null)
		{
			vignetteQuad.SetActive(flag);
		}
		bool flag2 = num > 0.3f;
		if ((Object)(object)leftTrail != (Object)null)
		{
			leftTrail.emitting = flag2 && ((Vector3)(ref Core.LeftHandVelocity)).magnitude > 0.6f;
		}
		if ((Object)(object)rightTrail != (Object)null)
		{
			rightTrail.emitting = flag2 && ((Vector3)(ref Core.RightHandVelocity)).magnitude > 0.6f;
		}
		if (!flag && trailsWereOn)
		{
			if ((Object)(object)leftTrail != (Object)null)
			{
				leftTrail.Clear();
			}
			if ((Object)(object)rightTrail != (Object)null)
			{
				rightTrail.Clear();
			}
		}
		trailsWereOn = flag;
	}

	private static Shader PickShader()
	{
		Shader val = Shader.Find("Universal Render Pipeline/Unlit");
		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("Unlit/Transparent");
		}
		if ((Object)(object)val == (Object)null)
		{
			val = Shader.Find("Unlit/Color");
		}
		if ((Object)(object)val == (Object)null)
		{
			val = Shader.Find("Standard");
		}
		return val;
	}

	private static void SetupTransparent(Material mat)
	{
		if (!((Object)(object)mat == (Object)null))
		{
			if (mat.HasProperty("_Mode"))
			{
				mat.SetFloat("_Mode", 3f);
			}
			if (mat.HasProperty("_Surface"))
			{
				mat.SetFloat("_Surface", 1f);
			}
			mat.EnableKeyword("_SURFACE_TYPE_TRANSPARENT");
			if (mat.HasProperty("_SrcBlend"))
			{
				mat.SetFloat("_SrcBlend", 5f);
			}
			if (mat.HasProperty("_DstBlend"))
			{
				mat.SetFloat("_DstBlend", 10f);
			}
			if (mat.HasProperty("_ZWrite"))
			{
				mat.SetFloat("_ZWrite", 0f);
			}
			if (mat.HasProperty("_Cull"))
			{
				mat.SetFloat("_Cull", 0f);
			}
			if (mat.HasProperty("_Blend"))
			{
				mat.SetFloat("_Blend", 0f);
			}
		}
	}

	public static void Cleanup()
	{
		leftTrail = null;
		rightTrail = null;
		if ((Object)(object)leftTrailObj != (Object)null)
		{
			Object.Destroy((Object)(object)leftTrailObj);
		}
		if ((Object)(object)rightTrailObj != (Object)null)
		{
			Object.Destroy((Object)(object)rightTrailObj);
		}
		if ((Object)(object)overlayRoot != (Object)null)
		{
			Object.Destroy((Object)(object)overlayRoot);
		}
		if ((Object)(object)tintMat != (Object)null)
		{
			Object.Destroy((Object)(object)tintMat);
		}
		if ((Object)(object)vignetteMat != (Object)null)
		{
			Object.Destroy((Object)(object)vignetteMat);
		}
		if ((Object)(object)trailMat != (Object)null)
		{
			Object.Destroy((Object)(object)trailMat);
		}
		if ((Object)(object)vignetteTex != (Object)null)
		{
			Object.Destroy((Object)(object)vignetteTex);
		}
		overlayRoot = null;
		tintQuad = null;
		vignetteQuad = null;
		tintMat = null;
		vignetteMat = null;
		trailMat = null;
		vignetteTex = null;
		leftTrailObj = null;
		rightTrailObj = null;
		refLayer = -1;
		playerCam = null;
		trailsWereOn = false;
		initialized = false;
	}
}
public static class PlayerGhostTrail
{
	private sealed class GhostSlot
	{
		public GameObject[] parts;

		public Material material;

		public bool inUse;
	}

	private sealed class GhostInstance
	{
		public GhostSlot slot;

		public bool fading;

		public float fadeTimer;
	}

	private const float SPAWN_INTERVAL = 0.12f;

	private const float FADE_DURATION = 0.8f;

	private const int MAX_GHOSTS = 25;

	private const int FADE_BUFFER = 10;

	private const int POOL_SIZE = 35;

	private const float GHOST_ALPHA = 0.3f;

	private const float GHOST_SCALE = 1f;

	private const float GHOST_BACK_OFFSET = 0.55f;

	private const int GHOSTS_PER_TRANSITION = 6;

	private const int DESTROY_BUDGET = 5;

	private static readonly Color DESAT_GRAY = new Color(0.5f, 0.5f, 0.5f);

	private const float DESAT_AMOUNT = 0.15f;

	private static readonly Color[] COLOR_CYCLE = (Color[])(object)new Color[5]
	{
		new Color(0.05f, 0.75f, 0.35f),
		new Color(0.1f, 0.3f, 1f),
		new Color(0.7f, 0.1f, 1f),
		new Color(1f, 0.15f, 0.1f),
		new Color(1f, 0.9f, 0.1f)
	};

	private static readonly HashSet<string> DUPLICATE_NAMES = new HashSet<string>
	{
		"Eyeball_L", "Eyeball_R", "EyeLight", "Head (1)", "Chest (1)", "HeadShadows", "JawShadows", "Hip_R (1)", "Knee_R (1)", "Hip_L (1)",
		"Knee_L (1)", "Sphere", "Neck", "Collarbone", "CollarboneL", "CollarboneR", "Chest"
	};

	private static readonly HashSet<string> EXCLUDED_PARENT_NAMES = new HashSet<string>
	{
		"LegsIK", "LArmIK", "RArmIK", "CameraRig", "InventorySlots", "IKHintLHand", "IKHintRHand", "JointAnchor", "ForceGrabber", "OverlapSizer",
		"SocketBag", "GrabbableBag", "Teleport", "CenterOfMasses", "UIPointer", "HandRayCastOrigin", "FallbackPoser", "ImpactParticle"
	};

	private static bool initialized;

	private static bool active;

	private static Transform playerRoot;

	private static Camera playerCam;

	private static List<MeshRenderer> bodyRenderers;

	private static float spawnTimer;

	private static int colorIndex;

	private static Material ghostMatTemplate;

	private static GameObject matAnchor;

	private static bool firstSpawnLogged;

	private static GhostSlot[] ghostPool;

	private static readonly List<GhostInstance> ghosts = new List<GhostInstance>();

	private static readonly List<int> removeBuffer = new List<int>();

	private static Color GetGhostColor(int idx)
	{
		//IL_0024: 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_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		int num = COLOR_CYCLE.Length * 6;
		int num2 = idx % num;
		int num3 = num2 / 6;
		float num4 = (float)(num2 % 6) / 6f;
		return Color.Lerp(Color.Lerp(COLOR_CYCLE[num3], COLOR_CYCLE[(num3 + 1) % COLOR_CYCLE.Length], num4), DESAT_GRAY, 0.15f);
	}

	public static void Init(Transform rig)
	{
		//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fa: Expected O, but got Unknown
		//IL_0125: Unknown result type (might be due to invalid IL or missing references)
		//IL_012f: Expected O, but got Unknown
		Cleanup();
		if (!((Object)(object)rig == (Object)null))
		{
			playerRoot = rig;
			bodyRenderers = new List<MeshRenderer>();
			firstSpawnLogged = false;
			playerCam = Camera.main;
			if ((Object)(object)playerCam == (Object)null)
			{
				playerCam = ((Component)rig).GetComponentInChildren<Camera>(true);
			}
			Transform val = FindDeepByPath(rig, "HexaBody/PlayerHexaPelvis/PhysicalUpperbody/Physical/Body");
			if ((Object)(object)val == (Object)null)
			{
				val = FindBodyWithChest(rig);
			}
			if ((Object)(object)val != (Object)null)
			{
				CollectRenderers(val, bodyRenderers);
			}
			Transform val2 = RigTransformCache.Find("LeftHandModel");
			if ((Object)(object)val2 != (Object)null)
			{
				CollectRenderers(val2, bodyRenderers);
			}
			Transform val3 = RigTransformCache.Find("RightHandModel");
			if ((Object)(object)val3 != (Object)null)
			{
				CollectRenderers(val3, bodyRenderers);
			}
			Shader val4 = PickGhostShader();
			if ((Object)(object)val4 != (Object)null)
			{
				matAnchor = new GameObject("SandevistanGhostMatAnchor");
				matAnchor.transform.SetParent(rig, false);
				matAnchor.SetActive(false);
				MeshRenderer val5 = matAnchor.AddComponent<MeshRenderer>();
				ghostMatTemplate = new Material(val4);
				SetupGhostMaterial(ghostMatTemplate);
				((Renderer)val5).material = ghostMatTemplate;
			}
			BuildPool();
			spawnTimer = 0f;
			colorIndex = 0;
			initialized = true;
		}
	}

	private static void BuildPool()
	{
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Expected O, but got Unknown
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c6: Expected O, but got Unknown
		int count = bodyRenderers.Count;
		if (count == 0)
		{
			ghostPool = new GhostSlot[0];
			return;
		}
		ghostPool = new GhostSlot[35];
		for (int i = 0; i < 35; i++)
		{
			GhostSlot ghostSlot = new GhostSlot();
			ghostSlot.inUse = false;
			ghostSlot.material = new Material(ghostMatTemplate);
			ghostSlot.material.color = new Color(1f, 1f, 1f, 0f);
			ghostSlot.parts = (GameObject[])(object)new GameObject[count];
			for (int j = 0; j < count; j++)
			{
				MeshFilter val = (((Object)(object)bodyRenderers[j] != (Object)null) ? ((Component)bodyRenderers[j]).GetComponent<MeshFilter>() : null);
				GameObject val2 = new GameObject("SandevistanGhost");
				val2.SetActive(false);
				MeshFilter val3 = val2.AddComponent<MeshFilter>();
				if ((Object)(object)val != (Object)null && (Object)(object)val.sharedMesh != (Object)null)
				{
					val3.sharedMesh = val.sharedMesh;
				}
				MeshRenderer val4 = val2.AddComponent<MeshRenderer>();
				((Renderer)val4).material = ghostSlot.material;
				((Renderer)val4).shadowCastingMode = (ShadowCastingMode)0;
				((Renderer)val4).receiveShadows = false;
				ghostSlot.parts[j] = val2;
			}
			ghostPool[i] = ghostSlot;
		}
	}

	private static void CollectRenderers(Transform root, List<MeshRenderer> list)
	{
		if ((Object)(object)root == (Object)null)
		{
			return;
		}
		MeshRenderer[] array = Il2CppArrayBase<MeshRenderer>.op_Implicit(((Component)root).GetComponentsInChildren<MeshRenderer>(true));
		if (array == null)
		{
			return;
		}
		MeshRenderer[] array2 = array;
		foreach (MeshRenderer val in array2)
		{
			if ((Object)(object)val == (Object)null || !((Renderer)val).enabled)
			{
				continue;
			}
			string name = ((Object)((Component)val).gameObject).name;
			if (DUPLICATE_NAMES.Contains(name))
			{
				continue;
			}
			switch (name)
			{
			case "Shoulder_R":
			case "Shoulder_L":
			case "Elbow_R":
			case "Elbow_L":
				if ((Object)(object)((Component)val).transform.parent == (Object)(object)root)
				{
					continue;
				}
				break;
			}
			if (!IsInsideExcludedParent(((Component)val).transform, root))
			{
				MeshFilter component = ((Component)val).GetComponent<MeshFilter>();
				if (!((Object)(object)component == (Object)null) && !((Object)(object)component.sharedMesh == (Object)null) && component.sharedMesh.vertexCount > 0)
				{
					list.Add(val);
				}
			}
		}
	}

	private static bool IsInsideExcludedParent(Transform t, Transform root)
	{
		Transform parent = t.parent;
		while ((Object)(object)parent != (Object)null && (Object)(object)parent != (Object)(object)root)
		{
			if (EXCLUDED_PARENT_NAMES.Contains(((Object)parent).name))
			{
				return true;
			}
			parent = parent.parent;
		}
		return false;
	}

	private static Transform FindDeepByPath(Transform root, string path)
	{
		if ((Object)(object)root == (Object)null || string.IsNullOrEmpty(path))
		{
			return null;
		}
		Transform val = root.Find(path);
		if ((Object)(object)val != (Object)null)
		{
			return val;
		}
		Transform[] array = Il2CppArrayBase<Transform>.op_Implicit(((Component)root).GetComponentsInChildren<Transform>(true));
		if (array == null)
		{
			return null;
		}
		string text = path.Split('/')[^1];
		Transform[] array2 = array;
		foreach (Transform val2 in array2)
		{
			if (!((Object)(object)val2 == (Object)null) && !(((Object)val2).name != text) && GetFullPath(val2, root) == path)
			{
				return val2;
			}
		}
		return null;
	}

	private static string GetFullPath(Transform t, Transform root)
	{
		string text = ((Object)t).name;
		Transform parent = t.parent;
		while ((Object)(object)parent != (Object)null && (Object)(object)parent != (Object)(object)root)
		{
			text = ((Object)parent).name + "/" + text;
			parent = parent.parent;
		}
		return text;
	}

	private static Transform FindBodyWithChest(Transform root)
	{
		if ((Object)(object)root == (Object)null)
		{
			return null;
		}
		Transform[] array = Il2CppArrayBase<Transform>.op_Implicit(((Component)root).GetComponentsInChildren<Transform>(true));
		if (array == null)
		{
			return null;
		}
		Transform[] array2 = array;
		foreach (Transform val in array2)
		{
			if ((Object)(object)val == (Object)null || ((Object)val).name != "Body")
			{
				continue;
			}
			for (int j = 0; j < val.childCount; j++)
			{
				if (((Object)val.GetChild(j)).name == "Chest")
				{
					return val;
				}
			}
		}
		return null;
	}

	public static void SetActive(bool value)
	{
		if (!initialized)
		{
			return;
		}
		active = value;
		if (value)
		{
			spawnTimer = 0.12f;
			colorIndex = 0;
			return;
		}
		foreach (GhostInstance ghost in ghosts)
		{
			if (!ghost.fading)
			{
				ghost.fading = true;
				ghost.fadeTimer = 0.8f;
			}
		}
	}

	public static bool HasLiveGhosts()
	{
		return ghosts.Count > 0;
	}

	public static void Update(float unscaledDt)
	{
		//IL_00db: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
		if (!initialized)
		{
			return;
		}
		if (active)
		{
			spawnTimer += unscaledDt;
			if (spawnTimer >= 0.12f)
			{
				spawnTimer = 0f;
				SpawnGhost();
			}
		}
		removeBuffer.Clear();
		for (int i = 0; i < ghosts.Count; i++)
		{
			GhostInstance ghostInstance = ghosts[i];
			if (ghostInstance.fading)
			{
				ghostInstance.fadeTimer -= unscaledDt;
				float a = 0.3f * Mathf.Clamp01(ghostInstance.fadeTimer / 0.8f);
				if (ghostInstance.slot != null && (Object)(object)ghostInstance.slot.material != (Object)null)
				{
					Color color = ghostInstance.slot.material.color;
					color.a = a;
					ghostInstance.slot.material.color = color;
				}
				if (ghostInstance.fadeTimer <= 0f)
				{
					removeBuffer.Add(i);
				}
			}
		}
		int num = 0;
		int num2 = removeBuffer.Count - 1;
		while (num2 >= 0 && num < 5)
		{
			ReturnToPool(ghosts[removeBuffer[num2]]);
			ghosts.RemoveAt(removeBuffer[num2]);
			num++;
			num2--;
		}
	}

	private static void SpawnGhost()
	{
		//IL_013b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0140: Unknown result type (might be due to invalid IL or missing references)
		//IL_0153: Unknown result type (might be due to invalid IL or missing references)
		//IL_0159: Unknown result type (might be due to invalid IL or missing references)
		//IL_015f: Unknown result type (might be due to invalid IL or missing references)
		//IL_016a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0175: Unknown result type (might be due to invalid IL or missing references)
		//IL_017a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0197: Unknown result type (might be due to invalid IL or missing references)
		//IL_019c: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c5: 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)
		//IL_01d4: 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_023a: Unknown result type (might be due to invalid IL or missing references)
		//IL_023b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0254: Unknown result type (might be due to invalid IL or missing references)
		//IL_026d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0277: Unknown result type (might be due to invalid IL or missing references)
		if (bodyRenderers.Count == 0 || ghostPool == null || ghostPool.Length == 0)
		{
			return;
		}
		int num = 0;
		for (int i = 0; i < ghosts.Count; i++)
		{
			if (!ghosts[i].fading)
			{
				num++;
			}
		}
		if (num >= 25)
		{
			for (int j = 0; j < ghosts.Count; j++)
			{
				if (!ghosts[j].fading)
				{
					ghosts[j].fading = true;
					ghosts[j].fadeTimer = 0.8f;
					break;
				}
			}
		}
		GhostSlot ghostSlot = null;
		for (int k = 0; k < ghostPool.Length; k++)
		{
			if (!ghostPool[k].inUse)
			{
				ghostSlot = ghostPool[k];
				break;
			}
		}
		if (ghostSlot == null)
		{
			return;
		}
		ghostSlot.inUse = true;
		Color ghostColor = GetGhostColor(colorIndex);
		colorIndex++;
		ghostSlot.material.color = new Color(ghostColor.r, ghostColor.g, ghostColor.b, 0.3f);
		Vector3 val = Vector3.zero;
		if ((Object)(object)playerCam != (Object)null)
		{
			Vector3 forward = ((Component)playerCam).transform.forward;
			forward.y = 0f;
			if (((Vector3)(ref forward)).sqrMagnitude > 0.001f)
			{
				val = -((Vector3)(ref forward)).normalized * 0.55f;
			}
		}
		int count = bodyRenderers.Count;
		for (int l = 0; l < count && l < ghostSlot.parts.Length; l++)
		{
			MeshRenderer val2 = bodyRenderers[l];
			if (!((Object)(object)val2 == (Object)null))
			{
				GameObject val3 = ghostSlot.parts[l];
				if (!((Object)(object)val3 == (Object)null))
				{
					val3.transform.position = ((Component)val2).transform.position + val;
					val3.transform.rotation = ((Component)val2).transform.rotation;
					val3.transform.localScale = ((Component)val2).transform.lossyScale * 1f;
					val3.SetActive(true);
				}
			}
		}
		ghosts.Add(new GhostInstance
		{
			slot = ghostSlot,
			fading = false,
			fadeTimer = 0f
		});
		if (!firstSpawnLogged)
		{
			firstSpawnLogged = true;
		}
	}

	private static void ReturnToPool(GhostInstance g)
	{
		if (g.slot == null)
		{
			return;
		}
		g.slot.inUse = false;
		if (g.slot.parts == null)
		{
			return;
		}
		for (int i = 0; i < g.slot.parts.Length; i++)
		{
			if ((Object)(object)g.slot.parts[i] != (Object)null)
			{
				g.slot.parts[i].SetActive(false);
			}
		}
	}

	private static Shader PickGhostShader()
	{
		Shader val = Shader.Find("Universal Render Pipeline/Unlit");
		if ((Object)(object)val == (Object)null)
		{
			val = Shader.Find("Sprites/Default");
		}
		if ((Object)(object)val == (Object)null)
		{
			val = Shader.Find("Unlit/Color");
		}
		if ((Object)(object)val == (Object)null)
		{
			val = Shader.Find("Unlit/Transparent");
		}
		return val;
	}

	private static void SetupGhostMaterial(Material mat)
	{
		if (!((Object)(object)mat == (Object)null))
		{
			if (mat.HasProperty("_Surface"))
			{
				mat.SetFloat("_Surface", 1f);
			}
			mat.EnableKeyword("_SURFACE_TYPE_TRANSPARENT");
			if (mat.HasProperty("_SrcBlend"))
			{
				mat.SetFloat("_SrcBlend", 5f);
			}
			if (mat.HasProperty("_DstBlend"))
			{
				mat.SetFloat("_DstBlend", 10f);
			}
			if (mat.HasProperty("_ZWrite"))
			{
				mat.SetFloat("_ZWrite", 0f);
			}
			if (mat.HasProperty("_Cull"))
			{
				mat.SetFloat("_Cull", 0f);
			}
			if (mat.HasProperty("_Blend"))
			{
				mat.SetFloat("_Blend", 0f);
			}
			mat.renderQueue = 3500;
		}
	}

	public static void Cleanup()
	{
		if (ghostPool != null)
		{
			for (int i = 0; i < ghostPool.Length; i++)
			{
				GhostSlot ghostSlot = ghostPool[i];
				if (ghostSlot == null)
				{
					continue;
				}
				if (ghostSlot.parts != null)
				{
					GameObject[] parts = ghostSlot.parts;
					foreach (GameObject val in parts)
					{
						if ((Object)(object)val != (Object)null)
						{
							Object.Destroy((Object)(object)val);
						}
					}
				}
				if ((Object)(object)ghostSlot.material != (Object)null)
				{
					Object.Destroy((Object)(object)ghostSlot.material);
				}
			}
			ghostPool = null;
		}
		ghosts.Clear();
		if ((Object)(object)ghostMatTemplate != (Object)null)
		{
			Object.Destroy((Object)(object)ghostMatTemplate);
			ghostMatTemplate = null;
		}
		if ((Object)(object)matAnchor != (Object)null)
		{
			Object.Destroy((Object)(object)matAnchor);
			matAnchor = null;
		}
		bodyRenderers = null;
		playerRoot = null;
		playerCam = null;
		initialized = false;
		active = false;
		spawnTimer = 0f;
		colorIndex = 0;
		firstSpawnLogged = false;
	}
}
public static class HandGhostTrail
{
	private sealed class HandGhostSlot
	{
		public GameObject[] parts;

		public Material material;

		public bool inUse;
	}

	private sealed class HandGhost
	{
		public HandGhostSlot slot;

		public float fadeTimer;
	}

	private const float SPAWN_INTERVAL = 0.07f;

	private const float FADE_DURATION = 0.3f;

	private const int MAX_GHOSTS_PER_HAND = 3;

	private const int HAND_FADE_BUFFER = 2;

	private const int HAND_POOL_SIZE = 5;

	private const float GHOST_ALPHA = 0.25f;

	private const float GHOST_SCALE = 1f;

	private const int DESTROY_BUDGET = 4;

	private static readonly Color HAND_COLOR = new Color(0.05f, 0.78f, 0.75f);

	private static bool initialized;

	private static bool active;

	private static List<MeshRenderer> leftRenderers;

	private static List<MeshRenderer> rightRenderers;

	private static float spawnTimer;

	private static Material ghostMatTemplate;

	private static GameObject matAnchor;

	private static bool firstSpawnLogged;

	private static HandGhostSlot[] leftPool;

	private static HandGhostSlot[] rightPool;

	private static readonly List<HandGhost> leftGhosts = new List<HandGhost>();

	private static readonly List<HandGhost> rightGhosts = new List<HandGhost>();

	private static readonly List<int> removeBuffer = new List<int>();

	public static void Init(Transform rig)
	{
		//IL_0126: Unknown result type (might be due to invalid IL or missing references)
		//IL_0130: Expected O, but got Unknown
		//IL_015c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0166: Expected O, but got Unknown
		Cleanup();
		if (!((Object)(object)rig == (Object)null))
		{
			leftRenderers = new List<MeshRenderer>();
			rightRenderers = new List<MeshRenderer>();
			Transform val = RigTransformCache.Find("LShoulderPoint");
			Transform val2 = RigTransformCache.Find("LElbowPoint");
			Transform val3 = RigTransformCache.Find("LeftHandModel");
			if ((Object)(object)val != (Object)null)
			{
				CollectRenderers(val, leftRenderers);
			}
			if ((Object)(object)val2 != (Object)null)
			{
				CollectRenderers(val2, leftRenderers);
			}
			if ((Object)(object)val3 != (Object)null)
			{
				CollectRenderers(val3, leftRenderers);
			}
			Transform val4 = RigTransformCache.Find("RShoulderPoint");
			Transform val5 = RigTransformCache.Find("RElbowPoint");
			Transform val6 = RigTransformCache.Find("RightHandModel");
			if ((Object)(object)val4 != (Object)null)
			{
				CollectRenderers(val4, rightRenderers);
			}
			if ((Object)(object)val5 != (Object)null)
			{
				CollectRenderers(val5, rightRenderers);
			}
			if ((Object)(object)val6 != (Object)null)
			{
				CollectRenderers(val6, rightRenderers);
			}
			Shader val7 = PickGhostShader();
			if ((Object)(object)val7 != (Object)null)
			{
				matAnchor = new GameObject("SandevistanHandGhostMatAnchor");
				matAnchor.transform.SetParent(rig, false);
				matAnchor.SetActive(false);
				MeshRenderer val8 = matAnchor.AddComponent<MeshRenderer>();
				ghostMatTemplate = new Material(val7);
				SetupGhostMaterial(ghostMatTemplate);
				((Renderer)val8).material = ghostMatTemplate;
			}
			leftPool = BuildHandPool(leftRenderers);
			rightPool = BuildHandPool(rightRenderers);
			spawnTimer = 0f;
			initialized = true;
		}
	}

	private static HandGhostSlot[] BuildHandPool(List<MeshRenderer> renderers)
	{
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Expected O, but got Unknown
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d2: Expected O, but got Unknown
		int count = renderers.Count;
		if (count == 0 || (Object)(object)ghostMatTemplate == (Object)null)
		{
			return new HandGhostSlot[0];
		}
		HandGhostSlot[] array = new HandGhostSlot[5];
		for (int i = 0; i < 5; i++)
		{
			HandGhostSlot handGhostSlot = new HandGhostSlot();
			handGhostSlot.inUse = false;
			handGhostSlot.material = new Material(ghostMatTemplate);
			handGhostSlot.material.color = new Color(HAND_COLOR.r, HAND_COLOR.g, HAND_COLOR.b, 0f);
			handGhostSlot.parts = (GameObject[])(object)new GameObject[count];
			for (int j = 0; j < count; j++)
			{
				MeshFilter val = (((Object)(object)renderers[j] != (Object)null) ? ((Component)renderers[j]).GetComponent<MeshFilter>() : null);
				GameObject val2 = new GameObject("SandevistanHandGhost");
				val2.SetActive(false);
				MeshFilter val3 = val2.AddComponent<MeshFilter>();
				if ((Object)(object)val != (Object)null && (Object)(object)val.sharedMesh != (Object)null)
				{
					val3.sharedMesh = val.sharedMesh;
				}
				MeshRenderer val4 = val2.AddComponent<MeshRenderer>();
				((Renderer)val4).material = handGhostSlot.material;
				((Renderer)val4).shadowCastingMode = (ShadowCastingMode)0;
				((Renderer)val4).receiveShadows = false;
				handGhostSlot.parts[j] = val2;
			}
			array[i] = handGhostSlot;
		}
		return array;
	}

	private static void CollectRenderers(Transform root, List<MeshRenderer> list)
	{
		if ((Object)(object)root == (Object)null)
		{
			return;
		}
		MeshRenderer[] array = Il2CppArrayBase<MeshRenderer>.op_Implicit(((Component)root).GetComponentsInChildren<MeshRenderer>(true));
		if (array == null)
		{
			return;
		}
		MeshRenderer[] array2 = array;
		foreach (MeshRenderer val in array2)
		{
			if (!((Object)(object)val == (Object)null) && ((Renderer)val).enabled)
			{
				MeshFilter component = ((Component)val).GetComponent<MeshFilter>();
				if (!((Object)(object)component == (Object)null) && !((Object)(object)component.sharedMesh == (Object)null) && component.sharedMesh.vertexCount > 0)
				{
					list.Add(val);
				}
			}
		}
	}

	public static void SetActive(bool value)
	{
		if (initialized)
		{
			active = value;
			if (value)
			{
				spawnTimer = 0.07f;
			}
		}
	}

	public static bool HasLiveGhosts()
	{
		return leftGhosts.Count > 0 || rightGhosts.Count > 0;
	}

	public static void Update(float unscaledDt)
	{
		if (!initialized)
		{
			return;
		}
		if (active)
		{
			spawnTimer += unscaledDt;
			if (spawnTimer >= 0.07f)
			{
				spawnTimer = 0f;
				SpawnHandGhost(leftRenderers, leftPool, leftGhosts);
				SpawnHandGhost(rightRenderers, rightPool, rightGhosts);
			}
		}
		UpdateGhostList(leftGhosts, unscaledDt);
		UpdateGhostList(rightGhosts, unscaledDt);
	}

	private static void UpdateGhostList(List<HandGhost> ghosts, float unscaledDt)
	{
		//IL_0070: 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_008a: Unknown result type (might be due to invalid IL or missing references)
		removeBuffer.Clear();
		for (int i = 0; i < ghosts.Count; i++)
		{
			HandGhost handGhost = ghosts[i];
			handGhost.fadeTimer -= unscaledDt;
			float a = 0.25f * Mathf.Clamp01(handGhost.fadeTimer / 0.3f);
			if (handGhost.slot != null && (Object)(object)handGhost.slot.material != (Object)null)
			{
				Color color = handGhost.slot.material.color;
				color.a = a;
				handGhost.slot.material.color = color;
			}
			if (handGhost.fadeTimer <= 0f)
			{
				removeBuffer.Add(i);
			}
		}
		int num = 0;
		int num2 = removeBuffer.Count - 1;
		while (num2 >= 0 && num < 4)
		{
			ReturnHandToPool(ghosts[removeBuffer[num2]]);
			ghosts.RemoveAt(removeBuffer[num2]);
			num++;
			num2--;
		}
	}

	private static void SpawnHandGhost(List<MeshRenderer> renderers, HandGhostSlot[] pool, List<HandGhost> ghosts)
	{
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0104: Unknown result type (might be due to invalid IL or missing references)
		//IL_011d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0127: Unknown result type (might be due to invalid IL or missing references)
		if (renderers == null || renderers.Count == 0 || pool == null || pool.Length == 0)
		{
			return;
		}
		HandGhostSlot handGhostSlot = null;
		for (int i = 0; i < pool.Length; i++)
		{
			if (!pool[i].inUse)
			{
				handGhostSlot = pool[i];
				break;
			}
		}
		if (handGhostSlot == null)
		{
			return;
		}
		handGhostSlot.inUse = true;
		handGhostSlot.material.color = new Color(HAND_COLOR.r, HAND_COLOR.g, HAND_COLOR.b, 0.25f);
		int count = renderers.Count;
		for (int j = 0; j < count && j < handGhostSlot.parts.Length; j++)
		{
			MeshRenderer val = renderers[j];
			if (!((Object)(object)val == (Object)null))
			{
				GameObject val2 = handGhostSlot.parts[j];
				if (!((Object)(object)val2 == (Object)null))
				{
					val2.transform.position = ((Component)val).transform.position;
					val2.transform.rotation = ((Component)val).transform.rotation;
					val2.transform.localScale = ((Component)val).transform.lossyScale * 1f;
					val2.SetActive(true);
				}
			}
		}
		ghosts.Add(new HandGhost
		{
			slot = handGhostSlot,
			fadeTimer = 0.3f
		});
		while (ghosts.Count > 3)
		{
			ReturnHandToPool(ghosts[0]);
			ghosts.RemoveAt(0);
		}
		if (!firstSpawnLogged)
		{
			firstSpawnLogged = true;
		}
	}

	private static void ReturnHandToPool(HandGhost g)
	{
		if (g.slot == null)
		{
			return;
		}
		g.slot.inUse = false;
		if (g.slot.parts == null)
		{
			return;
		}
		for (int i = 0; i < g.slot.parts.Length; i++)
		{
			if ((Object)(object)g.slot.parts[i] != (Object)null)
			{
				g.slot.parts[i].SetActive(false);
			}
		}
	}

	private static Shader PickGhostShader()
	{
		Shader val = Shader.Find("Universal Render Pipeline/Unlit");
		if ((Object)(object)val == (Object)null)
		{
			val = Shader.Find("Sprites/Default");
		}
		if ((Object)(object)val == (Object)null)
		{
			val = Shader.Find("Unlit/Color");
		}
		if ((Object)(object)val == (Object)null)
		{
			val = Shader.Find("Unlit/Transparent");
		}
		return val;
	}

	private static void SetupGhostMaterial(Material mat)
	{
		if (!((Object)(object)mat == (Object)null))
		{
			if (mat.HasProperty("_Surface"))
			{
				mat.SetFloat("_Surface", 1f);
			}
			mat.EnableKeyword("_SURFACE_TYPE_TRANSPARENT");
			if (mat.HasProperty("_SrcBlend"))
			{
				mat.SetFloat("_SrcBlend", 5f);
			}
			if (mat.HasProperty("_DstBlend"))
			{
				mat.SetFloat("_DstBlend", 10f);
			}
			if (mat.HasProperty("_ZWrite"))
			{
				mat.SetFloat("_ZWrite", 0f);
			}
			if (mat.HasProperty("_Cull"))
			{
				mat.SetFloat("_Cull", 0f);
			}
			if (mat.HasProperty("_Blend"))
			{
				mat.SetFloat("_Blend", 0f);
			}
			mat.renderQueue = 3500;
		}
	}

	public static void Cleanup()
	{
		DestroyHandPool(leftPool);
		leftPool = null;
		DestroyHandPool(rightPool);
		rightPool = null;
		leftGhosts.Clear();
		rightGhosts.Clear();
		if ((Object)(object)ghostMatTemplate != (Object)null)
		{
			Object.Destroy((Object)(object)ghostMatTemplate);
			ghostMatTemplate = null;
		}
		if ((Object)(object)matAnchor != (Object)null)
		{
			Object.Destroy((Object)(object)matAnchor);
			matAnchor = null;
		}
		leftRenderers = null;
		rightRenderers = null;
		initialized = false;
		active = false;
		spawnTimer = 0f;
		firstSpawnLogged = false;
	}

	private static void DestroyHandPool(HandGhostSlot[] pool)
	{
		if (pool == null)
		{
			return;
		}
		for (int i = 0; i < pool.Length; i++)
		{
			if (pool[i] == null)
			{
				continue;
			}
			if (pool[i].parts != null)
			{
				GameObject[] parts = pool[i].parts;
				foreach (GameObject val in parts)
				{
					if ((Object)(object)val != (Object)null)
					{
						Object.Destroy((Object)(object)val);
					}
				}
			}
			if ((Object)(object)pool[i].material != (Object)null)
			{
				Object.Destroy((Object)(object)pool[i].material);
			}
		}
	}
}
public static class SandevistanGrade
{
	private const float SATURATION = 55f;

	private const float HUE_DRIFT_AMPLITUDE = 12f;

	private const float HUE_DRIFT_SPEED = 0.5f;

	private const float EXPOSURE_BREATH_AMPLITUDE = 0.12f;

	private const float EXPOSURE_BREATH_SPEED = 3.14159f;

	private const float BLOOM_THRESHOLD = 0.9f;

	private const float BLOOM_SCATTER = 0.75f;

	private const float BLOOM_INTENSITY_BASE = 0.55f;

	private const float BLOOM_INTENSITY_MAX = 0.9f;

	private const float CA_INTENSITY = 0.3f;

	private const float VIGNETTE_INTENSITY = 0.3f;

	private const float VIGNETTE_SMOOTHNESS = 0.65f;

	private static readonly Color MAGENTA_TINT = new Color(1f, 0.85f, 0.95f);

	private static readonly Color CYAN_TINT = new Color(0.85f, 0.97f, 1f);

	private static readonly Color SHADOW_PURPLE = new Color(0.42f, 0.35f, 0.55f);

	private static readonly Color HIGHLIGHT_CYAN = new Color(0.62f, 0.8f, 0.85f);

	private static readonly Color VIGNETTE_COLOR = new Color(0.3f, 0.12f, 0.4f);

	private static readonly Color BLOOM_TINT = new Color(0.65f, 1f, 0.35f, 1f);

	private static GameObject volumeObj;

	private static VolumeProfile profile;

	private static Volume volume;

	private static ColorAdjustments colorAdj;

	private static SplitToning splitToning;

	private static Bloom bloom;

	private static Vignette vignette;

	private static ChromaticAberration chroma;

	private static UniversalAdditionalCameraData camData;

	private static bool originalPostProcessing;

	private static bool initialized;

	private static float time;

	private static int setOk;

	private static int setFail;

	private static PropertyInfo hueShiftProp;

	private static PropertyInfo postExposureProp;

	private static PropertyInfo colorFilterProp;

	private static PropertyInfo bloomIntensityProp;

	public static void Init()
	{
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Expected O, but got Unknown
		//IL_01de: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0308: Unknown result type (might be due to invalid IL or missing references)
		//IL_022e: Unknown result type (might be due to invalid IL or missing references)
		//IL_024d: Unknown result type (might be due to invalid IL or missing references)
		Cleanup();
		Camera main = Camera.main;
		if ((Object)(object)main == (Object)null)
		{
			MelonLogger.Warning("SandevistanGrade: камера не найдена.");
			return;
		}
		try
		{
			camData = ((Component)main).GetComponent<UniversalAdditionalCameraData>();
			if ((Object)(object)camData != (Object)null)
			{
				originalPostProcessing = camData.renderPostProcessing;
				camData.renderPostProcessing = true;
				volumeObj = new GameObject("SandevistanGradeVolume");
				Object.DontDestroyOnLoad((Object)(object)volumeObj);
				volume = volumeObj.AddComponent<Volume>();
				volume.isGlobal = true;
				volume.priority = 100f;
				volume.weight = 0f;
				profile = ScriptableObject.CreateInstance<VolumeProfile>();
				volume.profile = profile;
				colorAdj = AddOverride<ColorAdjustments>();
				splitToning = AddOverride<SplitToning>();
				bloom = AddOverride<Bloom>();
				vignette = AddOverride<Vignette>();
				chroma = AddOverride<ChromaticAberration>();
				if ((Object)(object)colorAdj == (Object)null || (Object)(object)bloom == (Object)null || (Object)(object)vignette == (Object)null || (Object)(object)chroma == (Object)null)
				{
					MelonLogger.Error("SandevistanGrade: компоненты не создались.");
					Cleanup();
					return;
				}
				setOk = 0;
				setFail = 0;
				SetParam("ca.saturation", colorAdj.saturation, 55f);
				SetParam("ca.hueShift", colorAdj.hueShift, 0f);
				SetParam("ca.postExposure", colorAdj.postExposure, 0f);
				SetParam("ca.colorFilter", colorAdj.colorFilter, MAGENTA_TINT);
				SetParam("ca.contrast", colorAdj.contrast, 12f);
				if ((Object)(object)splitToning != (Object)null)
				{
					SetParam("st.shadows", splitToning.shadows, SHADOW_PURPLE);
					SetParam("st.highlights", splitToning.highlights, HIGHLIGHT_CYAN);
					SetParam("st.balance", splitToning.balance, 0f);
				}
				SetParam("bloom.threshold", bloom.threshold, 0.9f);
				SetParam("bloom.scatter", bloom.scatter, 0.75f);
				SetParam("bloom.intensity", bloom.intensity, 0.55f);
				SetParam("bloom.tint", bloom.tint, BLOOM_TINT);
				SetParam("vig.color", vignette.color, VIGNETTE_COLOR);
				SetParam("vig.intensity", vignette.intensity, 0.3f);
				SetParam("vig.smoothness", vignette.smoothness, 0.65f);
				SetParam("chroma.intensity", chroma.intensity, 0.3f);
				hueShiftProp = FindValueProperty(colorAdj.hueShift);
				postExposureProp = FindValueProperty(colorAdj.postExposure);
				colorFilterProp = FindValueProperty(colorAdj.colorFilter);
				bloomIntensityProp = FindValueProperty(bloom.intensity);
				initialized = true;
			}
			else
			{
				MelonLogger.Warning("SandevistanGrade: нет UniversalAdditionalCameraData.");
			}
		}
		catch
		{
			Cleanup();
		}
	}

	private static PropertyInfo FindValueProperty(object param)
	{
		if (param == null)
		{
			return null;
		}
		string[] array = new string[3] { "m_Value", "_value", "value" };
		foreach (string name in array)
		{
			Type type = param.GetType();
			while (type != null)
			{
				PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (property != null && property.CanWrite)
				{
					return property;
				}
				type = type.BaseType;
			}
		}
		return null;
	}

	private static void SetCachedValue(PropertyInfo prop, object target, object value)
	{
		if (prop != null && target != null)
		{
			try
			{
				prop.SetValue(target, value);
			}
			catch
			{
			}
		}
	}

	private static void SetParam(string name, object param, object value)
	{
		if (param == null)
		{
			setFail++;
			return;
		}
		try
		{
			bool flag = false;
			string[] array = new string[3] { "m_Value", "_value", "value" };
			foreach (string propName in array)
			{
				if (TrySetProperty(param, propName, value))
				{
					flag = true;
					break;
				}
			}
			string[] array2 = new string[2] { "overrideState", "m_OverrideState" };
			foreach (string propName2 in array2)
			{
				if (TrySetProperty(param, propName2, true))
				{
					break;
				}
			}
			if (flag)
			{
				setOk++;
			}
			else
			{
				setFail++;
			}
		}
		catch
		{
			setFail++;
		}
	}

	private static bool TrySetProperty(object obj, string propName, object value)
	{
		Type type = obj.GetType();
		while (type != null)
		{
			PropertyInfo property = type.GetProperty(propName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (property != null && property.CanWrite)
			{
				try
				{
					property.SetValue(obj, value);
					return true;
				}
				catch
				{
					return false;
				}
			}
			type = type.BaseType;
		}
		return false;
	}

	public static void UpdateGrade(float strength)
	{
		//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: Unknown result type (might be due to invalid IL or missing references)
		if (!initialized || (Object)(object)volume == (Object)null || (Object)(object)colorAdj == (Object)null)
		{
			return;
		}
		float num = Mathf.Clamp01(strength);
		time += Time.unscaledDeltaTime;
		volume.weight = num;
		if (num <= 0.001f)
		{
			return;
		}
		try
		{
			SetCachedValue(hueShiftProp, colorAdj.hueShift, Mathf.Sin(time * 0.5f) * 12f);
			float num2 = Mathf.Sin(time * 3.14159f);
			SetCachedValue(postExposureProp, colorAdj.postExposure, num2 * 0.12f);
			float num3 = Mathf.Sin(time * 0.5f * 0.7f) * 0.5f + 0.5f;
			SetCachedValue(colorFilterProp, colorAdj.colorFilter, Color.Lerp(MAGENTA_TINT, CYAN_TINT, num3));
			float num4 = num2 * 0.5f + 0.5f;
			SetCachedValue(bloomIntensityProp, bloom.intensity, Mathf.Lerp(0.55f, 0.9f, num4));
		}
		catch
		{
		}
	}

	public static void Cleanup()
	{
		if ((Object)(object)camData != (Object)null)
		{
			try
			{
				camData.renderPostProcessing = originalPostProcessing;
			}
			catch
			{
			}
		}
		if ((Object)(object)profile != (Object)null)
		{
			Object.Destroy((Object)(object)profile);
		}
		if ((Object)(object)volumeObj != (Object)null)
		{
			Object.Destroy((Object)(object)volumeObj);
		}
		volumeObj = null;
		profile = null;
		volume = null;
		colorAdj = null;
		splitToning = null;
		bloom = null;
		vignette = null;
		chroma = null;
		camData = null;
		time = 0f;
		initialized = false;
		setOk = 0;
		setFail = 0;
		hueShiftProp = null;
		postExposureProp = null;
		colorFilterProp = null;
		bloomIntensityProp = null;
	}

	private static T AddOverride<T>() where T : VolumeComponent
	{
		try
		{
			return profile.Add<T>(true);
		}
		catch
		{
			try
			{
				Type val = ToIl2CppType(typeof(T));
				if (val != (Type)null)
				{
					VolumeComponent val2 = profile.Add(val, true);
					return (T)(object)((val2 is T) ? val2 : null);
				}
			}
			catch
			{
			}
		}
		return default(T);
	}

	private static Type ToIl2CppType(Type proxy)
	{
		try
		{
			Type type = Type.GetType("Il2CppInterop.Runtime.Il2CppType, Il2CppInterop.Runtime");
			if (type != null)
			{
				MethodInfo method = type.GetMethod("Of", BindingFlags.Static | BindingFlags.Public);
				if (method != null)
				{
					object obj = method.MakeGenericMethod(proxy).Invoke(null, null);
					return (Type)((obj is Type) ? obj : null);
				}
			}
		}
		catch
		{
		}
		return null;
	}
}
public static class RagdollImpactManager
{
	private sealed class PendingImpact
	{
		public object stick;

		public Vector3 impulse;

		public Vector3 releaseImpulse;

		public Vector3 launchDirection;

		public float launchPower;

		public string hitPartName;

		public float strongestImmediate;

		public Vector3 point;

		public bool hasPoint;

		public float lastTime;
	}

	private sealed class ActiveLaunch
	{
		public object stick;

		public Vector3 totalImpulse;

		public float duration;

		public float elapsed;

		public bool started;

		public string hitPartName;
	}

	private sealed class JointRestoreEntry
	{
		public ConfigurableJoint joint;

		public JointDrive xDrive;

		public JointDrive yDrive;

		public JointDrive zDrive;

		public JointDrive slerpDrive;

		public float restoreTime;
	}

	private sealed class ArmDamperRestore
	{
		public object stick;

		public float restoreTime;
	}

	private const bool DEBUG_LOG = false;

	private const float MAX_PENDING_IMPULSE = 55f;

	private const float HIT_IMPULSE_SCALE = 1.7f;

	private const float KICK_IMPULSE_SCALE = 0.1f;

	private const float SLASH_RELATIVE_VELOCITY_SCALE = 0.25f;

	private const float SLASH_SLASHER_VELOCITY_SCALE = 0.4f;

	private const float SLASH_DAMAGE_IMPULSE_SCALE = 0.03f;

	private const float MIN_REGISTER_MAGNITUDE = 0.8f;

	private const float MIN_EFFECTIVE_IMPULSE = 5f;

	private const bool USE_IMMEDIATE_IMPULSE_DURING_ACTIVE = true;

	private const float IMMEDIATE_IMPULSE_FRACTION = 0.22f;

	private const float IMMEDIATE_MIN_IMPULSE = 1.2f;

	private const float IMMEDIATE_MAX_IMPULSE = 12f;

	private const float IMMEDIATE_COOLDOWN = 0.08f;

	private const bool IMMEDIATE_WEAKEN_JOINTS = true;

	private const float IMMEDIATE_ARM_DAMPER_DURATION = 0.35f;

	private const float IMMEDIATE_JOINT_DURATION = 0.35f;

	private const float IMMEDIATE_LOCAL_BODY_WEIGHT = 0.15f;

	private const float IMPACT_INFLUENCE_DURATION = 0.3f;

	private const bool IMMEDIATE_TRY_STAGGER = true;

	private const float IMMEDIATE_STAGGER_THRESHOLD = 4.5f;

	private const float RELEASE_POWER_FROM_IMMEDIATE = 0.6f;

	private const float MAX_RELEASE_POWER = 54f;

	private const float RELEASE_LAUNCH_MULTIPLIER = 5.1f;

	private const float RELEASE_UPWARD_BIAS = 0.25f;

	private const float HAND_DIRECTION_WEIGHT = 0.65f;

	private const float RELEASE_LAUNCH_DURATION = 0.2f;

	private const float RELEASE_FALLBACK_POWER_FRACTION = 1.65f;

	private const float RELEASE_CURRENT_VELOCITY_BOOST = 1.18f;

	private const float RELEASE_MIN_STRENGTH = 0.25f;

	private const float RELEASE_INFLUENCE_DURATION = 0.85f;

	private const bool RELEASE_TRY_STAGGER = true;

	private const bool RELEASE_TRY_FORCE_UNBALANCE = true;

	private const float RELEASE_DECAY = 0.7f;

	private const float RELEASE_CHARGE_FRACTION = 0.6f;

	private const float MAX_RELEASE_IMPULSE = 65f;

	private const float PROPAGATION_PELVIS_BASE = 0.22f;

	private const float MAX_PART_IMPULSE = 90f;

	private const bool USE_UPPER_CHEST_IMPULSE = true;

	private const bool WEAKEN_JOINTS_ON_APPLY = true;

	private const bool WEAKEN_ARM_DAMPERS_ON_APPLY = true;

	private const bool WEAKEN_CONFIGURABLE_JOINTS_ON_APPLY = true;

	private const float ARM_DAMPER_MULTIPLIER = 0.25f;

	private const float JOINT_WEAKEN_DURATION = 0.45f;

	private const float JOINT_SPRING_MULTIPLIER = 0.15f;

	private const float JOINT_DAMPER_MULTIPLIER = 0.25f;

	private const float CLEANUP_INTERVAL = 0.5f;

	private static readonly Dictionary<int, PendingImpact> pending = new Dictionary<int, PendingImpact>();

	private static readonly List<ActiveLaunch> activeLaunches = new List<ActiveLaunch>();

	private static readonly List<int> removeBuffer = new List<int>();

	private static readonly Dictionary<int, object> bridgeToStick = new Dictionary<int, object>();

	private static readonly Dictionary<int, JointRestoreEntry> jointWeakenEntries = new Dictionary<int, JointRestoreEntry>();

	private static readonly Dictionary<int, ArmDamperRestore> armDamperRestores = new Dictionary<int, ArmDamperRestore>();

	private static readonly Dictionary<int, float> immediateLastApply = new Dictionary<int, float>();

	private static readonly HashSet<int> propagationApplied = new HashSet<int>();

	private static readonly Dictionary<int, MemberInfo> memberCache = new Dictionary<int, MemberInfo>();

	private static bool initialized;

	private static float cleanupTimer;

	private static int MemberKey(Type type, string name)
	{
		return (RuntimeHelpers.GetHashCode(type) * 397) ^ name.GetHashCode();
	}

	public static void Initialize(Harmony harmony)
	{
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Expected O, but got Unknown
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d1: Expected O, but got Unknown
		//IL_0103: Unknown result type (might be due to invalid IL or missing references)
		//IL_0110: Expected O, but got Unknown
		if (initialized)
		{
			return;
		}
		initialized = true;
		cleanupTimer = 0f;
		try
		{
			Type type = FindType("StickHealth");
			Type type2 = FindType("ColliderBridge");
			if (type != null)
			{
				MethodInfo methodInfo = FindMethod(type, "HitDetected", 5, 5);
				if (methodInfo != null)
				{
					harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(RagdollImpactManager), "HitDetectedPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
			}
			if (type2 != null)
			{
				MethodInfo methodInfo2 = FindMethod(type2, "KickedByPlayer", 3, 3);
				if (methodInfo2 != null)
				{
					harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(typeof(RagdollImpactManager), "KickedByPlayerPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
				MethodInfo methodInfo3 = FindMethod(type2, "ColBridgeSlashed", 6, 7);
				if (methodInfo3 != null)
				{
					harmony.Patch((MethodBase)methodInfo3, (HarmonyMethod)null, new HarmonyMethod(typeof(RagdollImpactManager), "ColBridgeSlashedPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
			}
		}
		catch
		{
		}
	}

	public static void HitDetectedPostfix(object __instance, object[] __args)
	{
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: 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_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_012a: Unknown result type (might be due to invalid IL or missing references)
		//IL_012c: 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_0122: Unknown result type (might be due to invalid IL or missing references)
		//IL_0127: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if (!SandevistanState.IsActive || __instance == null)
			{
				return;
			}
			object obj = null;
			object obj2 = null;
			object contactObj = null;
			if (__args != null)
			{
				if (__args.Length > 1)
				{
					obj = __args[1];
				}
				if (__args.Length > 3)
				{
					obj2 = __args[3];
				}
				if (__args.Length > 4)
				{
					contactObj = __args[4];
				}
			}
			string text = ((obj2 != null) ? obj2.ToString() : "");
			if (!text.Contains("Bullet"))
			{
				Vector3 value = Vector3.zero;
				if (obj != null)
				{
					TryGetVector3Member(obj, "relativeVelocity", out value);
				}
				Vector3 point = Vector3.zero;
				Vector3 normal = Vector3.zero;
				bool flag = TryGetContactInfo(contactObj, out point, out normal);
				if (((Vector3)(ref value)).sqrMagnitude < 0.0001f && flag && (text.Contains("Hand") || text.Contains("Blunt") || text.Contains("Sharp") || text.Contains("Stab") || text.Contains("Slash")))
				{
					value = normal * 2f;
				}
				AddImpulse(__instance, value, point, flag);
			}
		}
		catch
		{
		}
	}

	public static void KickedByPlayerPostfix(object __instance, object[] __args)
	{
		//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_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: 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_0068: 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_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: 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)
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if (!SandevistanState.IsActive || __instance == null || __args == null || __args.Length < 3)
			{
				return;
			}
			float num = ToFloat(__args[0]);
			Vector3 val = ToVector3(__args[1]);
			Vector3 val2 = ToVector3(__args[2]);
			object stickHealthFromBridge = GetStickHealthFromBridge(__instance);
			if (stickHealthFromBridge != null)
			{
				Vector3 val3 = val2;
				if (((Vector3)(ref val3)).sqrMagnitude < 0.001f)
				{
					val3 = val - GetPelvisCenter(stickHealthFromBridge);
				}
				if (((Vector3)(ref val3)).sqrMagnitude < 0.001f)
				{
					val3 = Vector3.forward;
				}
				AddImpulse(stickHealthFromBridge, ((Vector3)(ref val3)).normalized * num * 0.1f, val, hasPoint: true);
			}
		}
		catch
		{
		}
	}

	public static void ColBridgeSlashedPostfix(object __instance, object[] __args)
	{
		//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_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: 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_0065: 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_00d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: 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_0090: 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_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if (!SandevistanState.IsActive || __instance == null || __args == null || __args.Length < 5)
			{
				return;
			}
			float num = ToFloat(__args[2]);
			Vector3 val = ToVector3(__args[3]);
			Vector3 val2 = ToVector3(__args[4]);
			object stickHealthFromBridge = GetStickHealthFromBridge(__instance);
			if (stickHealthFromBridge == null)
			{
				return;
			}
			Vector3 val3 = val * 0.25f + val2 * 0.4f;
			if (num > 0f)
			{
				Vector3 val4 = ((((Vector3)(ref val2)).sqrMagnitude > 0.001f) ? ((Vector3)(ref val2)).normalized : ((Vector3)(ref val)).normalized);
				if (((Vector3)(ref val4)).sqrMagnitude > 0.001f)
				{
					val3 += val4 * num * 0.03f;
				}
			}
			AddImpulse(stickHealthFromBridge, val3, GetComponentPosition(__instance), hasPoint: true);
		}
		catch
		{
		}
	}

	public static void Update()
	{
		float realtimeSinceStartup = Time.realtimeSinceStartup;
		if (SandevistanState.IsActive && activeLaunches.Count > 0)
		{
			activeLaunches.Clear();
		}
		if (!SandevistanState.IsActive && pending.Count > 0 && SandevistanState.Strength <= 0.25f)
		{
			ApplyAllAndClear();
		}
		cleanupTimer -= Time.unscaledDeltaTime;
		if (cleanupTimer > 0f)
		{
			return;
		}
		cleanupTimer = 0.5f;
		if (pending.Count > 0)
		{
			removeBuffer.Clear();
			foreach (KeyValuePair<int, PendingImpact> item in pending)
			{
				if (item.Value == null || IsUnityNull(item.Value.stick))
				{
					removeBuffer.Add(item.Key);
				}
			}
			foreach (int item2 in removeBuffer)
			{
				pending.Remove(item2);
			}
		}
		removeBuffer.Clear();
		foreach (KeyValuePair<int, ArmDamperRestore> armDamperRestore in armDamperRestores)
		{
			ArmDamperRestore value = armDamperRestore.Value;
			if (value == null || IsUnityNull(value.stick))
			{
				removeBuffer.Add(armDamperRestore.Key);
			}
			else if (realtimeSinceStartup >= value.restoreTime)
			{
				InvokeMethod(value.stick, "SetLeftArmDamper", 1f);
				InvokeMethod(value.stick, "SetRightArmDamper", 1f);
				removeBuffer.Add(armDamperRestore.Key);
			}
		}
		foreach (int item3 in removeBuffer)
		{
			armDamperRestores.Remove(item3);
		}
		removeBuffer.Clear();
		foreach (KeyValuePair<int, JointRestoreEntry> jointWeakenEntry in jointWeakenEntries)
		{
			JointRestoreEntry value2 = jointWeakenEntry.Value;
			if (value2 == null || (Object)(object)value2.joint == (Object)null)
			{
				removeBuffer.Add(jointWeakenEntry.Key);
			}
			else if (realtimeSinceStartup >= value2.restoreTime)
			{
				RestoreJointEntry(value2);
				removeBuffer.Add(jointWeakenEntry.Key);
			}
		}
		foreach (int item4 in removeBuffer)
		{
			jointWeakenEntries.Remove(item4);
		}
		removeBuffer.Clear();
		foreach (KeyValuePair<int, float> impactInfluencedBody in SandevistanState.ImpactInfluencedBodies)
		{
			if (realtimeSinceStartup >= impactInfluencedBody.Value)
			{
				removeBuffer.Add(impactInfluencedBody.Key);
			}
		}
		foreach (int item5 in removeBuffer)
		{
			SandevistanState.ImpactInfluencedBodies.Remove(item5);
		}
		removeBuffer.Clear();
		foreach (KeyValuePair<int, float> releaseInfluencedBody in SandevistanState.ReleaseInfluencedBodies)
		{
			if (realtimeSinceStartup >= releaseInfluencedBody.Value)
			{
				removeBuffer.Add(releaseInfluencedBody.Key);
			}
		}
		foreach (int item6 in removeBuffer)
		{
			SandevistanState.ReleaseInfluencedBodies.Remove(item6);
		}
		removeBuffer.Clear();
		foreach (KeyValuePair<int, float> item7 in immediateLastApply)
		{
			if (realtimeSinceStartup - item7.Value > 5f)
			{
				removeBuffer.Add(item7.Key);
			}
		}
		foreach (int item8 in removeBuffer)
		{
			immediateLastApply.Remove(item8);
		}
	}

	public static void FixedUpdate()
	{
		//IL_0117: 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 (SandevistanState.IsActive)
		{
			if (activeLaunches.Count > 0)
			{
				activeLaunches.Clear();
			}
		}
		else
		{
			if (activeLaunches.Count == 0)
			{
				return;
			}
			float fixedDeltaTime = Time.fixedDeltaTime;
			for (int num = activeLaunches.Count - 1; num >= 0; num--)
			{
				ActiveLaunch activeLaunch = activeLaunches[num];
				if (activeLaunch == null || IsUnityNull(activeLaunch.stick))
				{
					activeLaunches.RemoveAt(num);
				}
				else
				{
					if (!activeLaunch.started)
					{
						StartLaunch(activeLaunch);
						activeLaunch.started = true;
					}
					float num2 = Mathf.Max(0.01f, activeLaunch.duration);
					float num3 = Mathf.Clamp01(activeLaunch.elapsed / num2);
					activeLaunch.elapsed += fixedDeltaTime;
					float num4 = Mathf.Clamp01(activeLaunch.elapsed / num2) - num3;
					if (num4 > 0.0001f)
					{
						ApplyPropagationLaunch(activeLaunch.stick, activeLaunch.totalImpulse * num4, activeLaunch.hitPartName);
					}
					if (activeLaunch.elapsed >= num2)
					{
						activeLaunches.RemoveAt(num);
					}
				}
			}
		}
	}

	public static bool HasActiveLaunches()
	{
		return activeLaunches.Count > 0;
	}

	public static void CleanupDestroyed()
	{
		if (pending.Count > 0)
		{
			removeBuffer.Clear();
			float realtimeSinceStartup = Time.realtimeSinceStartup;
			foreach (KeyValuePair<int, PendingImpact> item in pending)
			{
				PendingImpact value = item.Value;
				if (value == null || IsUnityNull(value.stick))
				{
					removeBuffer.Add(item.Key);
				}
				else if (realtimeSinceStartup - value.lastTime > 20f)
				{
					removeBuffer.Add(item.Key);
				}
			}
			foreach (int item2 in removeBuffer)
			{
				pending.Remove(item2);
			}
		}
		if (bridgeToStick.Count > 0)
		{
			removeBuffer.Clear();
			foreach (KeyValuePair<int, object> item3 in bridgeToStick)
			{
				if (IsUnityNull(item3.Value))
				{
					removeBuffer.Add(item3.Key);
				}
			}
			foreach (int item4 in removeBuffer)
			{
				bridgeToStick.Remove(item4);
			}
		}
		if (bridgeToStick.Count > 400)
		{
			bridgeToStick.Clear();
		}
	}

	public static void ClearWithoutApply()
	{
		pending.Clear();
		activeLaunches.Clear();
		bridgeToStick.Clear();
		jointWeakenEntries.Clear();
		armDamperRestores.Clear();
		immediateLastApply.Clear();
		SandevistanState.ImpactInfluencedBodies.Clear();
		SandevistanState.ReleaseInfluencedBodies.Clear();
		cleanupTimer = 0f;
	}

	public static void ApplyAllAndClear()
	{
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0109: Unknown result type (might be due to invalid IL or missing references)
		//IL_010e: Unknown result type (might be due to invalid IL or missing references)
		//IL_013f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0141: Unknown result type (might be due to invalid IL or missing references)
		if (pending.Count == 0)
		{
			return;
		}
		foreach (KeyValuePair<int, PendingImpact> item in pending)
		{
			PendingImpact value = item.Value;
			if (value == null || IsUnityNull(value.stick))
			{
				continue;
			}
			Vector3 val = value.launchDirection;
			if (((Vector3)(ref val)).sqrMagnitude < 0.0001f && ((Vector3)(ref value.releaseImpulse)).sqrMagnitude > 0.0001f)
			{
				val = ((Vector3)(ref value.releaseImpulse)).normalized;
			}
			if (!(((Vector3)(ref val)).sqrMagnitude < 0.0001f))
			{
				float num = value.launchPower;
				if (num < 0.5f && ((Vector3)(ref value.releaseImpulse)).sqrMagnitude > 0.0001f)
				{
					num = ((Vector3)(ref value.releaseImpulse)).magnitude * 1.65f;
				}
				if (!(num <= 0.01f))
				{
					Vector3 totalImpulse = val * (num * 5.1f);
					totalImpulse.y += ((Vector3)(ref totalImpulse)).magnitude * 0.25f;
					activeLaunches.Add(new ActiveLaunch
					{
						stick = value.stick,
						totalImpulse = totalImpulse,
						duration = 0.2f,
						elapsed = 0f,
						started = false,
						hitPartName = value.hitPartName
					});
				}
			}
		}
		pending.Clear();
	}

	private static void AddImpulse(object stick, Vector3 impulse, Vector3 point, bool hasPoint)
	{
		//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_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ba: 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_00f4: 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_00f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d8: 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_0169: Unknown result type (might be due to invalid IL or missing references)
		//IL_016e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0170: Unknown result type (might be due to invalid IL or missing references)
		//IL_0175: Unknown result type (might be due to invalid IL or missing references)
		//IL_012e: 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)
		//IL_018f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0199: Unknown result type (might be due to invalid IL or missing references)
		//IL_019e: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0211: Unknown result type (might be due to invalid IL or missing references)
		//IL_0216: Unknown result type (might be due to invalid IL or missing references)
		//IL_021d: 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_0226: Unknown result type (might be due to invalid IL or missing references)
		//IL_022b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0204: Unknown result type (might be due to invalid IL or missing references)
		//IL_0206: Unknown result type (might be due to invalid IL or missing references)
		//IL_025f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0269: 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_0275: Unknown result type (might be due to invalid IL or missing references)
		//IL_027a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0284: Unknown result type (might be due to invalid IL or missing references)
		//IL_0289: Unknown result type (might be due to invalid IL or missing references)
		if (!SandevistanState.IsActive || IsUnityNull(stick))
		{
			return;
		}
		float magnitude = ((Vector3)(ref impulse)).magnitude;
		if (magnitude < 0.8f)
		{
			return;
		}
		int objectId = GetObjectId(stick);
		float num = 1f / Mathf.Clamp(SandevistanState.TimeScale, 0.25f, 1f);
		float num2 = Mathf.Max(magnitude, 5f) * 1.7f * num;
		impulse = ((Vector3)(ref impulse)).normalized * num2;
		if (!pending.TryGetValue(objectId, out var value))
		{
			value = new PendingImpact
			{
				stick = stick
			};
			pending[objectId] = value;
		}
		value.impulse = Vector3.ClampMagnitude(value.impulse + impulse, 55f);
		if (hasPoint)
		{
			value.point = point;
			value.hasPoint = true;
		}
		value.lastTime = Time.realtimeSinceStartup;
		Vector3 val = ApplyImmediateImpulse(stick, impulse, point, hasPoint);
		if (!(((Vector3)(ref val)).sqrMagnitude > 0.0001f))
		{
			return;
		}
		if (((Vector3)(ref val)).magnitude > value.strongestImmediate)
		{
			Rigidbody val2 = FindBestRigidbody(stick, point, hasPoint);
			if ((Object)(object)val2 != (Object)null)
			{
				value.hitPartName = ((Object)((Component)val2).gameObject).name;
			}
			value.strongestImmediate = ((Vector3)(ref val)).magnitude;
		}
		Vector3 val3 = ((Vector3)(ref val)).normalized;
		Vector3 dominantHandVelocity = Core.GetDominantHandVelocity();
		Vector3 val4;
		if (((Vector3)(ref dominantHandVelocity)).magnitude > 1.2f)
		{
			val4 = Vector3.Lerp(val3, ((Vector3)(ref dominantHandVelocity)).normalized, 0.65f);
			val3 = ((Vector3)(ref val4)).normalized;
		}
		if (((Vector3)(ref val3)).sqrMagnitude < 0.0001f)
		{
			val3 = Vector3.forward;
		}
		val3.y = Mathf.Clamp(val3.y, -0.25f, 1f);
		((Vector3)(ref val3)).Normalize();
		if (((Vector3)(ref value.launchDirection)).sqrMagnitude < 0.0001f)
		{
			value.launchDirection = val3;
		}
		else
		{
			PendingImpact pendingImpact = value;
			val4 = Vector3.Lerp(value.launchDirection, val3, 0.35f);
			pendingImpact.launchDirection = ((Vector3)(ref val4)).normalized;
		}
		value.launchPower = Mathf.Clamp(value.launchPower + ((Vector3)(ref val)).magnitude * 0.6f, 0f, 54f);
		value.releaseImpulse = Vector3.ClampMagnitude(value.releaseImpulse * 0.7f + val * 0.6f, 65f);
	}

	private static Vector3 ApplyImmediateImpulse(object stick, Vector3 impulse, Vector3 point, bool hasPoint)
	{
		//IL_000f: 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_020f: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0110: 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_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_015c: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bf: 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_020b: Unknown result type (might be due to invalid IL or missing references)
		if (!SandevistanState.IsActive)
		{
			return Vector3.zero;
		}
		if (stick == null || IsUnityNull(stick) || ((Vector3)(ref impulse)).sqrMagnitude < 0.0001f)
		{
			return Vector3.zero;
		}
		int objectId = GetObjectId(stick);
		float realtimeSinceStartup = Time.realtimeSinceStartup;
		if (immediateLastApply.TryGetValue(objectId, out var value) && realtimeSinceStartup - value < 0.08f)
		{
			return Vector3.zero;
		}
		immediateLastApply[objectId] = realtimeSinceStartup;
		Vector3 val = impulse * 0.22f;
		if (((Vector3)(ref val)).magnitude < 1.2f)
		{
			val = ((Vector3)(ref val)).normalized * 1.2f;
		}
		if (((Vector3)(ref val)).magnitude > 12f)
		{
			val = ((Vector3)(ref val)).normalized * 12f;
		}
		bool flag = true;
		WeakenJointsForImpact(stick, 0.35f, 0.35f);
		object memberValue = GetMemberValue(stick, "pelvisRb");
		Rigidbody val2 = (Rigidbody)((memberValue is Rigidbody) ? memberValue : null);
		Rigidbody val3 = FindBestRigidbody(stick, point, hasPoint);
		Rigidbody val4 = (((Object)(object)val2 != (Object)null && !val2.isKinematic) ? val2 : val3);
		if ((Object)(object)val4 != (Object)null && !val4.isKinematic)
		{
			val4.WakeUp();
			val4.AddForce(val, (ForceMode)2);
			SandevistanState.ImpactInfluencedBodies[((Object)val4).GetInstanceID()] = realtimeSinceStartup + 0.3f;
		}
		if (hasPoint && (Object)(object)val3 != (Object)null && (Object)(object)val3 != (Object)(object)val4 && !val3.isKinematic)
		{
			val3.WakeUp();
			val3.AddForceAtPosition(val * 0.15f, point, (ForceMode)2);
			SandevistanState.ImpactInfluencedBodies[((Object)val3).GetInstanceID()] = realtimeSinceStartup + 0.3f;
		}
		if (((Vector3)(ref val)).magnitude >= 4.5f)
		{
			InvokeMethodWithOptional(stick, "StartStaggering", false);
		}
		return val;
	}

	private static void StartLaunch(ActiveLaunch launch)
	{
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_010e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0114: Unknown result type (might be due to invalid IL or missing references)
		if (launch == null || IsUnityNull(launch.stick))
		{
			return;
		}
		WeakenJointsForImpact(launch.stick, 0.5f, 0.5f);
		float num = 0.17999995f;
		if (num > 0.0001f)
		{
			object memberValue = GetMemberValue(launch.stick, "pelvisRb");
			Rigidbody val = (Rigidbody)((memberValue is Rigidbody) ? memberValue : null);
			if ((Object)(object)val != (Object)null && !val.isKinematic)
			{
				val.WakeUp();
				val.AddForce(val.velocity * num, (ForceMode)2);
				SandevistanState.ReleaseInfluencedBodies[((Object)val).GetInstanceID()] = Time.realtimeSinceStartup + 0.85f;
			}
			bool flag = true;
			object memberValue2 = GetMemberValue(launch.stick, "upperChest");
			GameObject val2 = (GameObject)((memberValue2 is GameObject) ? memberValue2 : null);
			if ((Object)(object)val2 != (Object)null)
			{
				Rigidbody component = val2.GetComponent<Rigidbody>();
				if ((Object)(object)component != (Object)null && !component.isKinematic)
				{
					component.WakeUp();
					component.AddForce(component.velocity * num, (ForceMode)2);
					SandevistanState.ReleaseInfluencedBodies[((Object)component).GetInstanceID()] = Time.realtimeSinceStartup + 0.85f;
				}
			}
		}
		bool flag2 = true;
		InvokeMethodWithOptional(launch.stick, "StartStaggering", false);
		bool flag3 = true;
		InvokeMethodWithOptional(launch.stick, "ForceUnbalance", false);
	}

	private static void ApplyPropagationLaunch(object stick, Vector3 impulse, string hitPartName)
	{
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_015a: 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)
		if (stick == null || IsUnityNull(stick) || ((Vector3)(ref impulse)).sqrMagnitude < 0.0001f)
		{
			return;
		}
		float realtimeSinceStartup = Time.realtimeSinceStartup;
		propagationApplied.Clear();
		object memberValue = GetMemberValue(stick, "pelvisRb");
		Rigidbody val = (Rigidbody)((memberValue is Rigidbody) ? memberValue : null);
		if ((Object)(object)val != (Object)null && !val.isKinematic)
		{
			float num = Mathf.Max(GetPropagationWeight(hitPartName, "Pelvis"), 0.22f);
			ApplyPartImpulse(val, impulse * num, realtimeSinceStartup);
			propagationApplied.Add(((Object)val).GetInstanceID());
		}
		object memberValue2 = GetMemberValue(stick, "bodyParts");
		if (!(memberValue2 is IEnumerable enumerable))
		{
			return;
		}
		foreach (object item in enumerable)
		{
			GameObject val2 = (GameObject)((item is GameObject) ? item : null);
			if ((Object)(object)val2 == (Object)null)
			{
				continue;
			}
			Rigidbody component = val2.GetComponent<Rigidbody>();
			if ((Object)(object)component == (Object)null || component.isKinematic)
			{
				continue;
			}
			int instanceID = ((Object)component).GetInstanceID();
			if (!propagationApplied.Contains(instanceID))
			{
				float propagationWeight = GetPropagationWeight(hitPartName, ((Object)val2).name);
				if (!(propagationWeight <= 0.01f))
				{
					ApplyPartImpulse(component, impulse * propagationWeight, realtimeSinceStartup);
					propagationApplied.Add(instanceID);
				}
			}
		}
	}

	private static void ApplyPartImpulse(Rigidbody rb, Vector3 partImpulse, float now)
	{
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)rb == (Object)null) && !(((Vector3)(ref partImpulse)).sqrMagnitude < 0.0001f))
		{
			if (((Vector3)(ref partImpulse)).magnitude > 90f)
			{
				partImpulse = ((Vector3)(ref partImpulse)).normalized * 90f;
			}
			rb.WakeUp();
			rb.AddForce(partImpulse, (ForceMode)2);
			SandevistanState.ReleaseInfluencedBodies[((Object)rb).GetInstanceID()] = now + 0.85f;
		}
	}

	private static string BasePartName(string name)
	{
		if (string.IsNullOrEmpty(name))
		{
			return "";
		}
		if (name.EndsWith("_L") || name.EndsWith("_R"))
		{
			return name.Substring(0, name.Length - 2);
		}
		return name;
	}

	private static bool SameSide(string a, string b)
	{
		if (string.IsNullOrEmpty(a) || string.IsNullOrEmpty(b) || a.Length < 2 || b.Length < 2)
		{
			return false;
		}
		string text = a.Substring(a.Length - 2);
		string text2 = b.Substring(b.Length - 2);
		if (text != "_L" && text != "_R")
		{
			return false;
		}
		if (text2 != "_L" && text2 != "_R")
		{
			return false;
		}
		return text == text2;
	}

	private static float GetPropagationWeight(string hitPart, string part)
	{
		if (string.IsNullOrEmpty(part))
		{
			return 0f;
		}
		if (string.IsNullOrEmpty(hitPart))
		{
			string text = BasePartName(part);
			if (text == "Pelvis")
			{
				return 1f;
			}
			if (text == "UpperChest" || text == "MiddleChest")
			{
				return 0.65f;
			}
			if (text == "Neck" || text == "Head" || text == "Jaw")
			{
				return 0.45f;
			}
			return 0.35f;
		}
		if (hitPart == part)
		{
			return 1f;
		}
		string text2 = BasePartName(hitPart);
		string text3 = BasePartName(part);
		bool flag = SameSide(hitPart, part);
		return text2 switch
		{
			"Head" => text3 switch
			{
				"Pelvis" => 0.15f, 
				"MiddleChest" => 0.2f, 
				"UpperChest" => 0.35f, 
				"Neck" => 0.6f, 
				"Jaw" => 0.7f, 
				_ => 0f, 
			}, 
			"Jaw" => text3 switch
			{
				"Pelvis" => 0.15f, 
				"MiddleChest" => 0.2f, 
				"UpperChest" => 0.35f, 
				"Neck" => 0.6f, 
				"Head" => 0.7f, 
				_ => 0f, 
			}, 
			"Neck" => text3 switch
			{
				"Shoulder" => flag ? 0.45f : 0.3f, 
				"Pelvis" => 0.18f, 
				"MiddleChest" => 0.3f, 
				"UpperChest" => 0.55f, 
				"Jaw" => 0.45f, 
				"Head" => 0.55f, 
				_ => 0f, 
			}, 
			"Shoulder" => text3 switch
			{
				"Pelvis" => 0.18f, 
				"MiddleChest" => 0.3f, 
				"Neck" => 0.35f, 
				"UpperChest" => 0.55f, 
				"Hand" => flag ? 0.35f : 0.08f, 
				"Elbow" => flag ? 0.6f : 0.12f, 
				_ => 0f, 
			}, 
			"Elbow" => text3 switch
			{
				"Neck" => 0.15f, 
				"UpperChest" => 0.25f, 
				"Hand" => flag ? 0.55f : 0.1f, 
				"Shoulder" => flag ? 0.6f : 0.12f, 
				_ => 0f, 
			}, 
			"Hand" => text3 switch
			{
				"UpperChest" => 0.15f, 
				"Shoulder" => flag ? 0.35f : 0.08f, 
				"Elbow" => flag ? 0.6f : 0.1f, 
				_ => 0f, 
			}, 
			"UpperChest" => text3 switch
			{
				"Jaw" => 0.15f, 
				"Head" => 0.2f, 
				"Pelvis" => 0.3f, 
				"Shoulder" => 0.4f, 
				"Neck" => 0.5f, 
				"MiddleChest" => 0.65f, 
				_ => 0f, 
			}, 
			"MiddleChest" => text3 switch
			{
				"Head" => 0.15f, 
				"Neck" => 0.3f, 
				"Shoulder" => 0.3f, 
				"Pelvis" => 0.5f, 
				"UpperChest" => 0.65f, 
				_ => 0f, 
			}, 
			"Pelvis" => text3 switch
			{
				"Neck" => 0.15f, 
				"Foot" => 0.15f, 
				"Knee" => 0.3f, 
				"Hip" => 0.55f, 
				"UpperChest" => 0.3f, 
				"MiddleChest" => 0.5f, 
				_ => 0f, 
			}, 
			"Hip" => text3 switch
			{
				"MiddleChest" => 0.25f, 
				"Foot" => flag ? 0.3f : 0.05f, 
				"Knee" => flag ? 0.55f : 0.1f, 
				"Pelvis" => 0.6f, 
				_ => 0f, 
			}, 
			"Knee" => text3 switch
			{
				"Pelvis" => 0.3f, 
				"Foot" => flag ? 0.55f : 0.1f, 
				"Hip" => flag ? 0.6f : 0.1f, 
				_ => 0f, 
			}, 
			"Foot" => text3 switch
			{
				"Pelvis" => 0.18f, 
				"Hip" => flag ? 0.35f : 0.08f, 
				"Knee" => flag ? 0.6f : 0.1f, 
				_ => 0f, 
			}, 
			_ => 0.1f, 
		};
	}

	private static void WeakenJointsForImpact(object stick, float armDuration, float jointDuration)
	{
		if (stick != null && !IsUnityNull(stick))
		{
			bool flag = true;
			WeakenArmDampers(stick, armDuration);
			bool flag2 = true;
			WeakenAllConfigurableJoints(stick, jointDuration);
		}
	}

	private static void WeakenArmDampers(object stick, float duration)
	{
		if (stick != null && !IsUnityNull(stick))
		{
			int objectId = GetObjectId(stick);
			float realtimeSinceStartup = Time.realtimeSinceStartup;
			if (!armDamperRestores.TryGetValue(objectId, out var value))
			{
				value = new ArmDamperRestore
				{
					stick = stick
				};
				armDamperRestores[objectId] = value;
				InvokeMethod(stick, "SetLeftArmDamper", 0.25f);
				InvokeMethod(stick, "SetRightArmDamper", 0.25f);
			}
			value.restoreTime = realtimeSinceStartup + duration;
		}
	}

	private static void WeakenAllConfigurableJoints(object stick, float duration)
	{
		if (stick == null || IsUnityNull(stick))
		{
			return;
		}
		object memberValue = GetMemberValue(stick, "configurableJoints");
		bool flag = false;
		if (memberValue is ConfigurableJoint[] array)
		{
			ConfigurableJoint[] array2 = array;
			foreach (ConfigurableJoint val in array2)
			{
				if (!((Object)(object)val == (Object)null))
				{
					WeakenConfigurableJoint(val, duration);
					flag = true;
				}
			}
		}
		else if (memberValue is IEnumerable enumerable)
		{
			foreach (object item in enumerable)
			{
				ConfigurableJoint val2 = (ConfigurableJoint)((item is ConfigurableJoint) ? item : null);
				if (!((Object)(object)val2 == (Object)null))
				{
					WeakenConfigurableJoint(val2, duration);
					flag = true;
				}
			}
		}
		if (!flag)
		{
			object memberValue2 = GetMemberValue(stick, "pelvisJoint");
			WeakenConfigurableJoint((ConfigurableJoint)((memberValue2 is ConfigurableJoint) ? memberValue2 : null), duration);
			object memberValue3 = GetMemberValue(stick, "upperChestJoint");
			WeakenConfigurableJoint((ConfigurableJoint)((memberValue3 is ConfigurableJoint) ? memberValue3 : null), duration);
		}
	}

	private static void WeakenConfigurableJoint(ConfigurableJoint joint, float duration)
	{
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: 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_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)joint == (Object)null))
		{
			int instanceID = ((Object)joint).GetInstanceID();
			float realtimeSinceStartup = Time.realtimeSinceStartup;
			if (!jointWeakenEntries.TryGetValue(instanceID, out var value))
			{
				value = new JointRestoreEntry
				{
					joint = joint,
					xDrive = joint.xDrive,
					yDrive = joint.yDrive,
					zDrive = joint.zDrive,
					slerpDrive = joint.slerpDrive
				};
				jointWeakenEntries[instanceID] = value;
			}
			value.joint.xDrive = WeakenDrive(value.xDrive);
			value.joint.yDrive = WeakenDrive(value.yDrive);
			value.joint.zDrive = WeakenDrive(value.zDrive);
			value.joint.slerpDrive = WeakenDrive(value.slerpDrive);
			value.restoreTime = realtimeSinceStartup + duration;
		}
	}

	private static JointDrive WeakenDrive(JointDrive original)
	{
		//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_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		JointDrive result = original;
		((JointDrive)(ref result)).positionSpring = ((JointDrive)(ref result)).positionSpring * 0.15f;
		((JointDrive)(ref result)).positionDamper = ((JointDrive)(ref result)).positionDamper * 0.25f;
		return result;
	}

	private static void RestoreJointEntry(JointRestoreEntry entry)
	{
		//IL_0022: 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_0046: 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)
		if (entry == null || (Object)(object)entry.joint == (Object)null)
		{
			return;
		}
		try
		{
			entry.joint.xDrive = entry.xDrive;
			entry.joint.yDrive = entry.yDrive;
			entry.joint.zDrive = entry.zDrive;
			entry.joint.slerpDrive = entry.slerpDrive;
		}
		catch
		{
		}
	}

	private static object GetStickHealthFromBridge(object bridge)
	{
		try
		{
			if (IsUnityNull(bridge))
			{
				return null;
			}
			Component val = (Component)((bridge is Component) ? bridge : null);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			int instanceID = ((Object)val).GetInstanceID();
			if (bridgeToStick.TryGetValue(instanceID, out var value) && !IsUnityNull(value))
			{
				return value;
			}
			Component[] array = Il2CppArrayBase<Component>.op_Implicit(val.GetComponentsInParent<Component>(true));
			if (array != null)
			{
				Component[] array2 = array;
				foreach (Component val2 in array2)
				{
					if (!((Object)(object)val2 == (Object)null) && ((object)val2).GetType().Name == "StickHealth")
					{
						bridgeToStick[instanceID] = val2;
						return val2;
					}
				}
			}
		}
		catch
		{
		}
		return null;
	}

	private static Rigidbody FindBestRigidbody(object stick, Vector3 point, bool hasPoint)
	{
		//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		object memberValue = GetMemberValue(stick, "pelvisRb");
		Rigidbody val = (Rigidbody)((memberValue is Rigidbody) ? memberValue : null);
		if (!hasPoint && (Object)(object)val != (Object)null && !val.isKinematic)
		{
			return val;
		}
		Rigidbody val2 = null;
		float num = float.MaxValue;
		object memberValue2 = GetMemberValue(stick, "bodyParts");
		if (memberValue2 is IEnumerable enumerable)
		{
			foreach (object item in enumerable)
			{
				GameObject val3 = (GameObject)((item is GameObject) ? item : null);
				if ((Object)(object)val3 == (Object)null)
				{
					continue;
				}
				Rigidbody component = val3.GetComponent<Rigidbody>();
				if (!((Object)(object)component == (Object)null) && !component.isKinematic)
				{
					float num2 = (hasPoint ? Vector3.Distance(point, component.worldCenterOfMass) : Vector3.Distance(((Object)(object)val != (Object)null) ? val.worldCenterOfMass : component.worldCenterOfMass, component.worldCenterOfMass));
					if (num2 < num)
					{
						num = num2;
						val2 = component;
					}
				}
			}
		}
		if ((Object)(object)val2 == (Object)null)
		{
			val2 = val;
		}
		return val2;
	}

	private static Vector3 GetPelvisCenter(object stick)
	{
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		object memberValue = GetMemberValue(stick, "pelvisRb");
		Rigidbody val = (Rigidbody)((memberValue is Rigidbody) ? memberValue : null);
		return ((Object)(object)val != (Object)null) ? val.worldCenterOfMass : Vector3.zero;
	}

	private static Vector3 GetComponentPosition(object obj)
	{
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		Component val = (Component)((obj is Component) ? obj : null);
		return ((Object)(object)val != (Object)null) ? val.transform.position : Vector3.zero;
	}

	private static int GetObjectId(object obj)
	{
		Object val = (Object)((obj is Object) ? obj : null);
		if (val != null)
		{
			return val.GetInstanceID();
		}
		return obj?.GetHashCode() ?? 0;
	}

	private static bool IsUnityNull(object obj)
	{
		if (obj == null)
		{
			return true;
		}
		Object val = (Object)((obj is Object) ? obj : null);
		if (val