Decompiled source of Scouttf2 v1.0.0

plugins/Sandevistan.dll

Decompiled 6 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("Sandevistan")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Sandevistan")]
[assembly: AssemblyTitle("Sandevistan")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace UltrakillSandevistan
{
	[BepInPlugin("com.example.ultrakill.sandevistan", "Sandevistan", "1.7.0")]
	public class SandevistanPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.example.ultrakill.sandevistan";

		public const string PluginName = "Sandevistan";

		public const string PluginVersion = "1.7.0";

		internal static bool IsActive;

		internal static int PlayerFixedDepth;

		internal static float OrigFixedDelta = 0.02f;

		internal static int WeaponDepth;

		private ConfigEntry<KeyCode> _toggleKey;

		private ConfigEntry<float> _targetTimeScale;

		private ConfigEntry<bool> _compensateVertical;

		private ConfigEntry<float> _speedCompensation;

		private ConfigEntry<bool> _compensateGravity;

		private ConfigEntry<bool> _keepWeaponsFullSpeed;

		private ConfigEntry<string> _weaponClassNames;

		private ConfigEntry<bool> _playerRealTime;

		private ConfigEntry<string> _playerClassNames;

		private ConfigEntry<bool> _debugLog;

		private ConfigEntry<float> _trailInterval;

		private ConfigEntry<float> _fadeDuration;

		private ConfigEntry<int> _maxGhosts;

		private ConfigEntry<float> _behindDistance;

		private ConfigEntry<float> _sideOffset;

		private ConfigEntry<float> _centerClearDistance;

		private ConfigEntry<float> _ghostHeightCfg;

		private ConfigEntry<float> _modelYaw;

		private ConfigEntry<float> _sfxVolume;

		private float _origFixedDelta = 0.02f;

		private GameObject _player;

		private Rigidbody _playerRb;

		private Vector3 _lastAfterPos;

		private bool _hasLastPos;

		private float _nextGhostTime;

		private Vector3 _lastGhostPos;

		private float _sideFlip = 1f;

		private int _colorIndex;

		private int _liveGhosts;

		private Shader _ghostShader;

		private Mesh[] _ghostMeshes;

		private int _poseIndex;

		private float _autoGhostHeight;

		private Camera _mainCam;

		private Color _origCamColor;

		private CameraClearFlags _origFlags;

		private Color _origAmbientLight;

		private Color _origFogColor;

		private bool _origFogState;

		private static readonly Color SandyWorldColor = new Color(0f, 8f / 51f, 14f / 51f, 1f);

		private readonly Dictionary<Animator, AnimatorUpdateMode> _animOriginal = new Dictionary<Animator, AnimatorUpdateMode>();

		private bool _animsUnscaled;

		private float _nextAnimScan;

		private Harmony _harmony;

		private bool _weaponsPatched;

		private bool _playerPatched;

		private float _nextDebugLog;

		private AudioSource _audio;

		private AudioClip _startClip;

		private AudioClip _endClip;

		private static readonly Color[] Palette = (Color[])(object)new Color[3]
		{
			new Color(0f, 1f, 1f, 1f),
			new Color(1f, 0f, 1f / 3f, 1f),
			new Color(1f, 46f / 51f, 0f, 1f)
		};

		private void Awake()
		{
			_toggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "ToggleKey", (KeyCode)121, "Key that toggles Sandevistan on/off.");
			_targetTimeScale = ((BaseUnityPlugin)this).Config.Bind<float>("Time", "TimeScale", 0.2f, "World time scale while active.");
			_compensateVertical = ((BaseUnityPlugin)this).Config.Bind<bool>("Time", "CompensateVertical", true, "Speed up vertical velocity.");
			_compensateGravity = ((BaseUnityPlugin)this).Config.Bind<bool>("Time", "CompensateGravity", true, "Cancel slow-motion on gravity.");
			_speedCompensation = ((BaseUnityPlugin)this).Config.Bind<float>("Time", "PlayerSpeedCompensation", 1f, "Cancel slowdown for player.");
			_keepWeaponsFullSpeed = ((BaseUnityPlugin)this).Config.Bind<bool>("Weapons", "KeepWeaponsFullSpeed", true, "Weapons ignore slow-mo.");
			_weaponClassNames = ((BaseUnityPlugin)this).Config.Bind<string>("Weapons", "WeaponClasses", "Revolver,Shotgun,ShotgunHammer,Nailgun,Railcannon,RocketLauncher,Punch,FistControl,GunControl,WeaponCharges", "Weapon class names.");
			_playerRealTime = ((BaseUnityPlugin)this).Config.Bind<bool>("Player", "PlayerLogicRealTime", true, "Run player movement in real time.");
			_playerClassNames = ((BaseUnityPlugin)this).Config.Bind<string>("Player", "PlayerClasses", "NewMovement", "Player movement classes.");
			_debugLog = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "DebugLog", false, "Log movement numbers.");
			_trailInterval = ((BaseUnityPlugin)this).Config.Bind<float>("Trail", "SpawnInterval", 0.04f, "Real-time seconds between after-images.");
			_fadeDuration = ((BaseUnityPlugin)this).Config.Bind<float>("Trail", "FadeDuration", 0.5f, "Fade-out duration.");
			_maxGhosts = ((BaseUnityPlugin)this).Config.Bind<int>("Trail", "MaxGhosts", 60, "Max ghosts cap.");
			_behindDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Trail", "BehindDistance", 3f, "Distance behind player.");
			_sideOffset = ((BaseUnityPlugin)this).Config.Bind<float>("Trail", "SideOffset", 1.5f, "Sideways offset.");
			_centerClearDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Trail", "CenterClearDistance", 15f, "Center screen clear distance.");
			_ghostHeightCfg = ((BaseUnityPlugin)this).Config.Bind<float>("Trail", "GhostHeight", 0f, "Height of ghost figure.");
			_modelYaw = ((BaseUnityPlugin)this).Config.Bind<float>("Trail", "ModelYawDegrees", 0f, "Extra rotation for custom obj.");
			_sfxVolume = ((BaseUnityPlugin)this).Config.Bind<float>("Audio", "Volume", 0.8f, "Volume of start/end sounds.");
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			_origFixedDelta = ((Time.fixedDeltaTime > 0.0001f) ? Time.fixedDeltaTime : 0.02f);
			OrigFixedDelta = _origFixedDelta;
			_ghostShader = ResolveGhostShader();
			Mesh val = LoadObjMesh(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "ghost_model.obj"));
			_ghostMeshes = (Mesh[])(object)((!((Object)(object)val != (Object)null)) ? new Mesh[2]
			{
				BuildHumanoidMesh(flip: false),
				BuildHumanoidMesh(flip: true)
			} : new Mesh[1] { val });
			SetupAudio();
			SetupHarmony();
			SceneManager.sceneLoaded += OnSceneLoaded;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Sandevistan 1.7.0 loaded.");
		}

		private void OnDestroy()
		{
			SceneManager.sceneLoaded -= OnSceneLoaded;
			if (IsActive)
			{
				SetActive(on: false, playSound: false);
			}
			if (_harmony != null)
			{
				_harmony.UnpatchSelf();
			}
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			_player = null;
			_playerRb = null;
			_liveGhosts = 0;
			WeaponDepth = 0;
			PlayerFixedDepth = 0;
			_animOriginal.Clear();
			_animsUnscaled = false;
			if (IsActive)
			{
				SetActive(on: false, playSound: false);
			}
			if (!_weaponsPatched)
			{
				TryPatchWeapons();
			}
			if (!_playerPatched)
			{
				TryPatchPlayerClasses();
			}
		}

		private void Update()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Invalid comparison between Unknown and I4
			if (Input.GetKeyDown(_toggleKey.Value) && (int)Cursor.lockState == 1)
			{
				SetActive(!IsActive, playSound: true);
			}
			if (IsActive && Time.unscaledTime >= _nextGhostTime)
			{
				_nextGhostTime = Time.unscaledTime + Mathf.Max(0.01f, _trailInterval.Value);
				TrySpawnGhost();
			}
		}

		private void LateUpdate()
		{
			if (!IsActive)
			{
				return;
			}
			if (Time.timeScale <= 0.0001f)
			{
				if (_animsUnscaled)
				{
					RestoreWeaponAnimators();
				}
				return;
			}
			float num = (Time.timeScale = _targetTimeScale.Value);
			Time.fixedDeltaTime = _origFixedDelta * num;
			if (_keepWeaponsFullSpeed.Value && (!_animsUnscaled || Time.unscaledTime >= _nextAnimScan))
			{
				_nextAnimScan = Time.unscaledTime + 1f;
				ApplyWeaponAnimators();
			}
		}

		private void FixedUpdate()
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: 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_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: 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_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: 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_017e: 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_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			if (!IsActive)
			{
				_hasLastPos = false;
				return;
			}
			float timeScale = Time.timeScale;
			if (timeScale <= 0.0001f || timeScale >= 0.999f)
			{
				_hasLastPos = false;
			}
			else
			{
				if (!EnsurePlayer() || (Object)(object)_playerRb == (Object)null)
				{
					return;
				}
				Vector3 position = _playerRb.position;
				if (!_hasLastPos)
				{
					_lastAfterPos = position;
					_hasLastPos = true;
					return;
				}
				Vector3 val = position - _lastAfterPos;
				if (!_compensateVertical.Value)
				{
					val.y = 0f;
				}
				if (((Vector3)(ref val)).sqrMagnitude > 25f)
				{
					_lastAfterPos = position;
					return;
				}
				if (!IsGrounded() && _compensateGravity.Value && _playerRb.useGravity && !_playerRb.isKinematic)
				{
					_playerRb.AddForce(Physics.gravity * (1f / timeScale - 1f), (ForceMode)5);
				}
				float num = (1f / timeScale - 1f) * _speedCompensation.Value;
				Vector3 val2 = val * num;
				float magnitude = ((Vector3)(ref val2)).magnitude;
				if (magnitude > 0.0001f)
				{
					Vector3 val3 = val2 / magnitude;
					float num2 = magnitude;
					RaycastHit[] array = _playerRb.SweepTestAll(val3, magnitude + 0.05f, (QueryTriggerInteraction)1);
					for (int i = 0; i < array.Length; i++)
					{
						RaycastHit val4 = array[i];
						if (!(Vector3.Dot(((RaycastHit)(ref val4)).normal, val3) > -0.25f) && (!(((RaycastHit)(ref val4)).normal.y > 0.6f) || !(val3.y > -0.1f)) && (!(((RaycastHit)(ref val4)).distance < 0.001f) || !(Vector3.Dot(((RaycastHit)(ref val4)).normal, val3) > -0.8f)))
						{
							num2 = Mathf.Min(num2, Mathf.Max(0f, ((RaycastHit)(ref val4)).distance - 0.05f));
						}
					}
					_playerRb.position = position + val3 * num2;
				}
				_lastAfterPos = _playerRb.position;
			}
		}

		private void SetActive(bool on, bool playSound)
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			IsActive = on;
			if (on)
			{
				if (Time.timeScale > 0.99f && Time.fixedDeltaTime > 0.0001f)
				{
					_origFixedDelta = Time.fixedDeltaTime;
					OrigFixedDelta = _origFixedDelta;
				}
				_hasLastPos = false;
				_colorIndex = 0;
				_nextGhostTime = 0f;
				_animsUnscaled = false;
				if (EnsurePlayer())
				{
					_lastGhostPos = _player.transform.position;
				}
				ApplyWorldColorShift();
				if (playSound)
				{
					PlaySfx(_startClip);
				}
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Sandevistan ON");
			}
			else
			{
				Time.timeScale = 1f;
				Time.fixedDeltaTime = _origFixedDelta;
				RestoreWeaponAnimators();
				RestoreWorldColorShift();
				if (playSound)
				{
					PlaySfx(_endClip);
				}
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Sandevistan OFF");
			}
		}

		private void ApplyWorldColorShift()
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: 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_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			_mainCam = Camera.main;
			if ((Object)(object)_mainCam != (Object)null)
			{
				_origCamColor = _mainCam.backgroundColor;
				_origFlags = _mainCam.clearFlags;
				_mainCam.clearFlags = (CameraClearFlags)2;
				_mainCam.backgroundColor = SandyWorldColor;
			}
			_origAmbientLight = RenderSettings.ambientLight;
			_origFogColor = RenderSettings.fogColor;
			_origFogState = RenderSettings.fog;
			RenderSettings.ambientLight = SandyWorldColor * 1.5f;
			RenderSettings.fog = true;
			RenderSettings.fogColor = SandyWorldColor * 0.8f;
		}

		private void RestoreWorldColorShift()
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: 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)
			if ((Object)(object)_mainCam != (Object)null)
			{
				_mainCam.backgroundColor = _origCamColor;
				_mainCam.clearFlags = _origFlags;
			}
			RenderSettings.ambientLight = _origAmbientLight;
			RenderSettings.fogColor = _origFogColor;
			RenderSettings.fog = _origFogState;
		}

		private bool IsGrounded()
		{
			//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_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_0045: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_playerRb == (Object)null)
			{
				return false;
			}
			float num = 1f;
			Collider val = (((Object)(object)_player != (Object)null) ? _player.GetComponent<Collider>() : null);
			if ((Object)(object)val != (Object)null)
			{
				Bounds bounds = val.bounds;
				num = ((Bounds)(ref bounds)).extents.y;
			}
			return Physics.Raycast(_playerRb.position, Vector3.down, num + 0.2f, -5, (QueryTriggerInteraction)1);
		}

		private bool EnsurePlayer()
		{
			if ((Object)(object)_player != (Object)null)
			{
				return true;
			}
			try
			{
				_player = GameObject.FindGameObjectWithTag("Player");
			}
			catch
			{
				_player = null;
			}
			if ((Object)(object)_player == (Object)null)
			{
				return false;
			}
			_playerRb = _player.GetComponent<Rigidbody>();
			if ((Object)(object)_playerRb == (Object)null)
			{
				_playerRb = _player.GetComponentInChildren<Rigidbody>();
			}
			return true;
		}

		private void ApplyWeaponAnimators()
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			if (!EnsurePlayer())
			{
				return;
			}
			Animator[] componentsInChildren = _player.GetComponentsInChildren<Animator>(true);
			foreach (Animator val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null) && !_animOriginal.ContainsKey(val))
				{
					_animOriginal[val] = val.updateMode;
					val.updateMode = (AnimatorUpdateMode)2;
				}
			}
			_animsUnscaled = true;
		}

		private void RestoreWeaponAnimators()
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			foreach (KeyValuePair<Animator, AnimatorUpdateMode> item in _animOriginal)
			{
				if ((Object)(object)item.Key != (Object)null)
				{
					item.Key.updateMode = item.Value;
				}
			}
			_animOriginal.Clear();
			_animsUnscaled = false;
		}

		private void SetupHarmony()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Expected O, but got Unknown
			_harmony = new Harmony("com.example.ultrakill.sandevistan");
			try
			{
				MethodInfo methodInfo = AccessTools.PropertyGetter(typeof(Time), "deltaTime");
				_harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(Patches).GetMethod("DeltaTimePrefix")), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			catch
			{
			}
			try
			{
				MethodInfo methodInfo2 = AccessTools.PropertyGetter(typeof(Time), "fixedDeltaTime");
				_harmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(typeof(Patches).GetMethod("FixedDeltaTimePrefix")), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			catch
			{
			}
			TryPatchWeapons();
			TryPatchPlayerClasses();
		}

		private void TryPatchPlayerClasses()
		{
			//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_0089: Expected O, but got Unknown
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Expected O, but got Unknown
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Expected O, but got Unknown
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Expected O, but got Unknown
			if (!_playerRealTime.Value)
			{
				_playerPatched = true;
				return;
			}
			Assembly assembly = null;
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly2 in assemblies)
			{
				if (assembly2.GetName().Name == "Assembly-CSharp")
				{
					assembly = assembly2;
					break;
				}
			}
			if (assembly == null)
			{
				return;
			}
			HarmonyMethod val = new HarmonyMethod(typeof(Patches).GetMethod("EnterWeapon"))
			{
				priority = 800
			};
			HarmonyMethod val2 = new HarmonyMethod(typeof(Patches).GetMethod("ExitWeapon"));
			HarmonyMethod val3 = new HarmonyMethod(typeof(Patches).GetMethod("EnterPlayerFixed"))
			{
				priority = 800
			};
			HarmonyMethod val4 = new HarmonyMethod(typeof(Patches).GetMethod("ExitPlayerFixed"));
			string[] array = _playerClassNames.Value.Split(new char[1] { ',' });
			for (int i = 0; i < array.Length; i++)
			{
				string text = array[i].Trim();
				if (text.Length == 0)
				{
					continue;
				}
				Type type = assembly.GetType(text);
				if (type == null)
				{
					continue;
				}
				string[] array2 = new string[3] { "Update", "LateUpdate", "FixedUpdate" };
				foreach (string text2 in array2)
				{
					MethodInfo method = type.GetMethod(text2, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
					if (!(method == null))
					{
						bool flag = text2 == "FixedUpdate";
						try
						{
							_harmony.Patch((MethodBase)method, flag ? val3 : val, (HarmonyMethod)null, (HarmonyMethod)null, flag ? val4 : val2, (HarmonyMethod)null);
						}
						catch
						{
						}
					}
				}
			}
			_playerPatched = true;
		}

		private void TryPatchWeapons()
		{
			//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_0086: Expected O, but got Unknown
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Expected O, but got Unknown
			if (!_keepWeaponsFullSpeed.Value)
			{
				_weaponsPatched = true;
				return;
			}
			Assembly assembly = null;
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly2 in assemblies)
			{
				if (assembly2.GetName().Name == "Assembly-CSharp")
				{
					assembly = assembly2;
					break;
				}
			}
			if (assembly == null)
			{
				return;
			}
			HarmonyMethod val = new HarmonyMethod(typeof(Patches).GetMethod("EnterWeapon"))
			{
				priority = 800
			};
			HarmonyMethod val2 = new HarmonyMethod(typeof(Patches).GetMethod("ExitWeapon"));
			string[] array = _weaponClassNames.Value.Split(new char[1] { ',' });
			for (int i = 0; i < array.Length; i++)
			{
				string text = array[i].Trim();
				if (text.Length == 0)
				{
					continue;
				}
				Type type = assembly.GetType(text);
				if (type == null)
				{
					continue;
				}
				string[] array2 = new string[2] { "Update", "LateUpdate" };
				foreach (string name in array2)
				{
					MethodInfo method = type.GetMethod(name, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
					if (!(method == null))
					{
						try
						{
							_harmony.Patch((MethodBase)method, val, (HarmonyMethod)null, (HarmonyMethod)null, val2, (HarmonyMethod)null);
						}
						catch
						{
						}
					}
				}
			}
			_weaponsPatched = true;
		}

		private void TrySpawnGhost()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: 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_00a8: 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_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: 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)
			//IL_00d2: 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_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: 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_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			if (!EnsurePlayer() || _liveGhosts >= _maxGhosts.Value)
			{
				return;
			}
			Vector3 position = _player.transform.position;
			Vector3 val = position - _lastGhostPos;
			if (!(((Vector3)(ref val)).sqrMagnitude < 0.0625f))
			{
				Vector3 val2 = _lastGhostPos - position;
				val2.y = 0f;
				if (((Vector3)(ref val2)).sqrMagnitude < 0.0001f)
				{
					val2 = -_player.transform.forward;
				}
				val2.y = 0f;
				((Vector3)(ref val2)).Normalize();
				Vector3 val3 = Vector3.Cross(Vector3.up, val2);
				_lastGhostPos = position;
				_sideFlip = 0f - _sideFlip;
				Vector3 val4 = position + val2 * _behindDistance.Value + val3 * (_sideOffset.Value * _sideFlip);
				if (!IsInCenterOfView(val4))
				{
					Color color = Palette[_colorIndex];
					_colorIndex = (_colorIndex + 1) % Palette.Length;
					MeasurePlayerHeight();
					SpawnGhost(val4, -val2, color);
				}
			}
		}

		private bool IsInCenterOfView(Vector3 worldPos)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			Camera main = Camera.main;
			if ((Object)(object)main == (Object)null)
			{
				return false;
			}
			Vector3 val = main.WorldToViewportPoint(worldPos);
			if (val.z <= 0f || val.z > _centerClearDistance.Value)
			{
				return false;
			}
			if (val.x > 0.15f && val.x < 0.85f && val.y > 0.05f)
			{
				return val.y < 0.95f;
			}
			return false;
		}

		private void MeasurePlayerHeight()
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_player == (Object)null)
			{
				return;
			}
			Collider val = _player.GetComponent<Collider>();
			if ((Object)(object)val == (Object)null)
			{
				val = _player.GetComponentInChildren<Collider>();
			}
			if (!((Object)(object)val == (Object)null))
			{
				Bounds bounds = val.bounds;
				float num = Mathf.Clamp(((Bounds)(ref bounds)).size.y, 1.5f, 4.5f);
				if (num > _autoGhostHeight)
				{
					_autoGhostHeight = num;
				}
			}
		}

		private void SpawnGhost(Vector3 position, Vector3 forward, Color color)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected O, but got Unknown
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: 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_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: 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_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: 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)
			Material val = new Material(_ghostShader);
			color.a = 0.7f;
			val.color = color;
			val.renderQueue = 3000;
			float num = ((_ghostHeightCfg.Value > 0.1f) ? _ghostHeightCfg.Value : ((_autoGhostHeight > 0f) ? _autoGhostHeight : 2f));
			GameObject val2 = new GameObject("SandevistanGhost");
			val2.layer = 2;
			val2.transform.position = position;
			if (((Vector3)(ref forward)).sqrMagnitude > 0.0001f)
			{
				val2.transform.rotation = Quaternion.LookRotation(forward, Vector3.up);
			}
			val2.transform.localScale = Vector3.one * num;
			Transform transform = val2.transform;
			transform.rotation *= Quaternion.Euler(0f, Random.Range(-8f, 8f), 0f);
			Transform transform2 = val2.transform;
			transform2.position += new Vector3(Random.Range(-0.15f, 0.15f), 0f, Random.Range(-0.15f, 0.15f));
			_poseIndex = (_poseIndex + 1) % _ghostMeshes.Length;
			val2.AddComponent<MeshFilter>().sharedMesh = _ghostMeshes[_poseIndex];
			MeshRenderer obj = val2.AddComponent<MeshRenderer>();
			((Renderer)obj).sharedMaterial = val;
			((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0;
			((Renderer)obj).receiveShadows = false;
			_liveGhosts++;
			((MonoBehaviour)this).StartCoroutine(FadeAndDestroy(val2, val, color));
		}

		private static Mesh BuildHumanoidMesh(bool flip)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: 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_0088: 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_00bc: 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_00eb: 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_011a: 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_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_0286: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02df: Expected O, but got Unknown
			Mesh primitiveMesh = GetPrimitiveMesh((PrimitiveType)3);
			Mesh primitiveMesh2 = GetPrimitiveMesh((PrimitiveType)0);
			Mesh primitiveMesh3 = GetPrimitiveMesh((PrimitiveType)1);
			List<CombineInstance> list = new List<CombineInstance>();
			AddPart(list, primitiveMesh2, new Vector3(0f, 0.435f, 0.04f), Quaternion.identity, new Vector3(0.13f, 0.15f, 0.15f));
			AddPart(list, primitiveMesh, new Vector3(0f, 0.2f, 0.03f), Quaternion.Euler(18f, 0f, 0f), new Vector3(0.25f, 0.3f, 0.13f));
			AddPart(list, primitiveMesh, new Vector3(0f, 0.03f, 0f), Quaternion.identity, new Vector3(0.21f, 0.09f, 0.13f));
			AddPart(list, primitiveMesh, new Vector3(-0.15f, 0.27f, -0.12f), Quaternion.Euler(-20f, 0f, 32f), new Vector3(0.02f, 0.36f, 0.15f));
			AddPart(list, primitiveMesh, new Vector3(0.15f, 0.27f, -0.12f), Quaternion.Euler(-20f, 0f, -32f), new Vector3(0.02f, 0.36f, 0.15f));
			float num = -50f;
			float num2 = 75f;
			float num3 = 30f;
			float num4 = 50f;
			float num5 = -50f;
			float num6 = -50f;
			float num7 = 45f;
			float num8 = -40f;
			float thighAngle = (flip ? num3 : num);
			float kneeAngle = (flip ? num4 : num2);
			float thighAngle2 = (flip ? num : num3);
			float kneeAngle2 = (flip ? num2 : num4);
			float thighAngle3 = (flip ? num5 : num7);
			float kneeAngle3 = (flip ? num6 : num8);
			float thighAngle4 = (flip ? num7 : num5);
			float kneeAngle4 = (flip ? num8 : num6);
			AddLimb(list, primitiveMesh3, new Vector3(-0.07f, 0f, 0f), thighAngle, 0.25f, 0.095f, kneeAngle, 0.25f, 0.075f);
			AddLimb(list, primitiveMesh3, new Vector3(0.07f, 0f, 0f), thighAngle2, 0.25f, 0.095f, kneeAngle2, 0.25f, 0.075f);
			AddLimb(list, primitiveMesh3, new Vector3(-0.14f, 0.32f, 0.05f), thighAngle3, 0.16f, 0.07f, kneeAngle3, 0.16f, 0.06f);
			AddLimb(list, primitiveMesh3, new Vector3(0.14f, 0.32f, 0.05f), thighAngle4, 0.16f, 0.07f, kneeAngle4, 0.16f, 0.06f);
			Mesh val = new Mesh
			{
				name = (flip ? "SandevistanGhostB" : "SandevistanGhostA")
			};
			val.CombineMeshes(list.ToArray(), true, true);
			val.RecalculateBounds();
			((Object)val).hideFlags = (HideFlags)61;
			return val;
		}

		private Mesh LoadObjMesh(string path)
		{
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: 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_0209: 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)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: 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_0241: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Expected O, but got Unknown
			try
			{
				if (!File.Exists(path))
				{
					return null;
				}
				CultureInfo invariantCulture = CultureInfo.InvariantCulture;
				List<Vector3> list = new List<Vector3>();
				List<int> list2 = new List<int>();
				char[] separator = new char[2] { ' ', '\t' };
				string[] array = File.ReadAllLines(path);
				for (int i = 0; i < array.Length; i++)
				{
					string text = array[i].Trim();
					if (text.StartsWith("v ", StringComparison.Ordinal))
					{
						string[] array2 = text.Split(separator, StringSplitOptions.RemoveEmptyEntries);
						list.Add(new Vector3(0f - float.Parse(array2[1], invariantCulture), float.Parse(array2[2], invariantCulture), float.Parse(array2[3], invariantCulture)));
					}
					else if (text.StartsWith("f ", StringComparison.Ordinal))
					{
						string[] array3 = text.Split(separator, StringSplitOptions.RemoveEmptyEntries);
						int num = array3.Length - 1;
						int[] array4 = new int[num];
						for (int j = 0; j < num; j++)
						{
							int num2 = int.Parse(array3[j + 1].Split(new char[1] { '/' })[0], invariantCulture);
							array4[j] = ((num2 > 0) ? (num2 - 1) : (list.Count + num2));
						}
						for (int k = 1; k < num - 1; k++)
						{
							list2.Add(array4[0]);
							list2.Add(array4[k + 1]);
							list2.Add(array4[k]);
						}
					}
				}
				if (list.Count == 0 || list2.Count == 0)
				{
					return null;
				}
				Bounds val = default(Bounds);
				((Bounds)(ref val))..ctor(list[0], Vector3.zero);
				for (int l = 1; l < list.Count; l++)
				{
					((Bounds)(ref val)).Encapsulate(list[l]);
				}
				float num3 = 1f / Mathf.Max(0.0001f, ((Bounds)(ref val)).size.y);
				Vector3 center = ((Bounds)(ref val)).center;
				Quaternion val2 = Quaternion.Euler(0f, _modelYaw.Value, 0f);
				for (int m = 0; m < list.Count; m++)
				{
					Vector3 val3 = (list[m] - center) * num3;
					list[m] = val2 * val3;
				}
				Mesh val4 = new Mesh();
				val4.SetVertices(list);
				val4.SetTriangles(list2, 0);
				val4.RecalculateNormals();
				((Object)val4).hideFlags = (HideFlags)61;
				return val4;
			}
			catch
			{
				return null;
			}
		}

		private static Mesh GetPrimitiveMesh(PrimitiveType type)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = GameObject.CreatePrimitive(type);
			Mesh sharedMesh = obj.GetComponent<MeshFilter>().sharedMesh;
			Object.Destroy((Object)(object)obj);
			return sharedMesh;
		}

		private static void AddPart(List<CombineInstance> parts, Mesh m, Vector3 pos, Quaternion rot, Vector3 scale)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: 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_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			CombineInstance item = default(CombineInstance);
			((CombineInstance)(ref item)).mesh = m;
			((CombineInstance)(ref item)).transform = Matrix4x4.TRS(pos, rot, scale);
			parts.Add(item);
		}

		private static void AddLimb(List<CombineInstance> parts, Mesh capsule, Vector3 hip, float thighAngle, float upperLen, float upperRad, float kneeAngle, float lowerLen, float lowerRad)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: 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_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: 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_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			Quaternion val = Quaternion.Euler(thighAngle, 0f, 0f);
			Vector3 val2 = val * Vector3.down;
			Vector3 val3 = hip + val2 * upperLen;
			Vector3 pos = hip + val2 * (upperLen * 0.5f);
			AddPart(parts, capsule, pos, val, new Vector3(upperRad * 2f, upperLen * 0.5f, upperRad * 2f));
			Quaternion val4 = val * Quaternion.Euler(kneeAngle, 0f, 0f);
			Vector3 val5 = val4 * Vector3.down;
			Vector3 pos2 = val3 + val5 * (lowerLen * 0.5f);
			AddPart(parts, capsule, pos2, val4, new Vector3(lowerRad * 2f, lowerLen * 0.5f, lowerRad * 2f));
		}

		private Shader ResolveGhostShader()
		{
			string[] array = new string[5] { "Sprites/Default", "UI/Default", "Legacy Shaders/Particles/Alpha Blended", "Unlit/Color", "Standard" };
			for (int i = 0; i < array.Length; i++)
			{
				Shader val = Shader.Find(array[i]);
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			return Shader.Find("Sprites/Default");
		}

		private IEnumerator FadeAndDestroy(GameObject ghost, Material mat, Color baseColor)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			float duration = Mathf.Max(0.05f, _fadeDuration.Value);
			float t = 0f;
			Vector3 startScale = (((Object)(object)ghost != (Object)null) ? ghost.transform.localScale : Vector3.one);
			while (t < duration && !((Object)(object)ghost == (Object)null) && !((Object)(object)mat == (Object)null))
			{
				t += Time.unscaledDeltaTime;
				float num = Mathf.Clamp01(t / duration);
				Color color = baseColor;
				color.a = baseColor.a * (1f - num) * (1f - num);
				mat.color = color;
				ghost.transform.localScale = startScale * Mathf.Lerp(1f, 0.9f, num);
				yield return null;
			}
			if ((Object)(object)ghost != (Object)null)
			{
				Object.Destroy((Object)(object)ghost);
			}
			if ((Object)(object)mat != (Object)null)
			{
				Object.Destroy((Object)(object)mat);
			}
			_liveGhosts = Mathf.Max(0, _liveGhosts - 1);
		}

		private void SetupAudio()
		{
			_audio = ((Component)this).gameObject.AddComponent<AudioSource>();
			_audio.playOnAwake = false;
			_audio.spatialBlend = 0f;
			_audio.ignoreListenerPause = true;
			string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
			_startClip = LoadWav(Path.Combine(directoryName, "sandevistan_start.wav"), "SandevistanStart");
			_endClip = LoadWav(Path.Combine(directoryName, "sandevistan_end.wav"), "SandevistanEnd");
			if ((Object)(object)_startClip == (Object)null)
			{
				_startClip = SynthStartClip();
			}
			if ((Object)(object)_endClip == (Object)null)
			{
				_endClip = SynthEndClip();
			}
		}

		private void PlaySfx(AudioClip clip)
		{
			if ((Object)(object)_audio != (Object)null && (Object)(object)clip != (Object)null)
			{
				_audio.PlayOneShot(clip, _sfxVolume.Value);
			}
		}

		private AudioClip LoadWav(string path, string clipName)
		{
			try
			{
				if (!File.Exists(path))
				{
					return null;
				}
				byte[] array = File.ReadAllBytes(path);
				if (array.Length < 44 || array[0] != 82)
				{
					return null;
				}
				int num = 0;
				int num2 = 0;
				int num3 = 0;
				int num4 = -1;
				int num5 = 0;
				int num6 = 12;
				while (num6 + 8 <= array.Length)
				{
					string text = Encoding.ASCII.GetString(array, num6, 4);
					int num7 = BitConverter.ToInt32(array, num6 + 4);
					int num8 = num6 + 8;
					if (text == "fmt ")
					{
						num = BitConverter.ToUInt16(array, num8 + 2);
						num2 = BitConverter.ToInt32(array, num8 + 4);
						num3 = BitConverter.ToUInt16(array, num8 + 14);
					}
					else if (text == "data")
					{
						num4 = num8;
						num5 = Mathf.Min(num7, array.Length - num8);
						break;
					}
					num6 = num8 + num7 + (num7 & 1);
				}
				if (num3 != 16 || num4 < 0)
				{
					return null;
				}
				int num9 = num5 / 2;
				float[] array2 = new float[num9];
				for (int i = 0; i < num9; i++)
				{
					array2[i] = (float)BitConverter.ToInt16(array, num4 + i * 2) / 32768f;
				}
				AudioClip obj = AudioClip.Create(clipName, num9 / num, num, num2, false);
				obj.SetData(array2, 0);
				return obj;
			}
			catch
			{
				return null;
			}
		}

		private static AudioClip SynthStartClip()
		{
			int num = 52920;
			float[] array = new float[num];
			for (int i = 0; i < num; i++)
			{
				array[i] = Mathf.Sin((float)i * 0.1f) * 0.1f * Mathf.Exp((float)(-i) / (float)num);
			}
			AudioClip obj = AudioClip.Create("SandevistanStart", num, 1, 44100, false);
			obj.SetData(array, 0);
			return obj;
		}

		private static AudioClip SynthEndClip()
		{
			int num = 35280;
			float[] array = new float[num];
			for (int i = 0; i < num; i++)
			{
				array[i] = Mathf.Cos((float)i * 0.1f) * 0.1f * Mathf.Exp((float)(-i) / (float)num);
			}
			AudioClip obj = AudioClip.Create("SandevistanEnd", num, 1, 44100, false);
			obj.SetData(array, 0);
			return obj;
		}
	}
	internal static class Patches
	{
		public static bool DeltaTimePrefix(ref float __result)
		{
			if (SandevistanPlugin.IsActive && Time.timeScale > 0.0001f)
			{
				if (SandevistanPlugin.PlayerFixedDepth > 0)
				{
					__result = SandevistanPlugin.OrigFixedDelta;
					return false;
				}
				if (SandevistanPlugin.WeaponDepth > 0)
				{
					__result = Time.unscaledDeltaTime;
					return false;
				}
			}
			return true;
		}

		public static bool FixedDeltaTimePrefix(ref float __result)
		{
			if (SandevistanPlugin.PlayerFixedDepth > 0 && SandevistanPlugin.IsActive && Time.timeScale > 0.0001f)
			{
				__result = SandevistanPlugin.OrigFixedDelta;
				return false;
			}
			return true;
		}

		public static void EnterPlayerFixed()
		{
			SandevistanPlugin.PlayerFixedDepth++;
		}

		public static Exception ExitPlayerFixed(Exception __exception)
		{
			if (SandevistanPlugin.PlayerFixedDepth > 0)
			{
				SandevistanPlugin.PlayerFixedDepth--;
			}
			return __exception;
		}

		public static void EnterWeapon()
		{
			SandevistanPlugin.WeaponDepth++;
		}

		public static Exception ExitWeapon(Exception __exception)
		{
			if (SandevistanPlugin.WeaponDepth > 0)
			{
				SandevistanPlugin.WeaponDepth--;
			}
			return __exception;
		}
	}
}