Decompiled source of I am a Tornado v0.0.3

plugins/Thanks.I_am_a_Tornado.dll

Decompiled 3 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Thanks.ImTornado")]
[assembly: AssemblyDescription("Client-side controllable tornado form for PEAK. Press H to become a tornado.")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Thanks")]
[assembly: AssemblyProduct("I'm a Tornado")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e7f2c4a1-8b3d-4e5f-9a60-1c2d3e4f5a6b")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("0.1.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 ImTornado
{
	[BepInPlugin("com.github.Thanks.ImTornado", "I'm a Tornado", "0.1.0")]
	public sealed class WindPlugin : BaseUnityPlugin
	{
		public const string Id = "com.github.Thanks.ImTornado";

		public const string Name = "I'm a Tornado";

		public const string Version = "0.1.0";

		internal static ManualLogSource Log;

		internal static ConfigEntry<KeyCode> ToggleKey;

		internal static ConfigEntry<float> WindStrength;

		internal static ConfigEntry<float> MovementSpeed;

		internal static ConfigEntry<float> HoverHeight;

		internal static ConfigEntry<float> CameraDistance;

		internal static ConfigEntry<float> CameraHeight;

		internal static ConfigEntry<float> CameraFov;

		internal static ConfigEntry<bool> ShowTornadoVisual;

		private readonly Harmony _harmony = new Harmony("com.github.Thanks.ImTornado");

		private TornadoController _controller;

		private bool _switching;

		private bool _lastTogglePressed;

		private void Awake()
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Expected O, but got Unknown
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Expected O, but got Unknown
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Expected O, but got Unknown
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Expected O, but got Unknown
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			_harmony.PatchAll(typeof(WindHarmonyPatches).Assembly);
			ConfigureOptionalCharacterPatches();
			ToggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "ToggleKey", (KeyCode)104, "Press to toggle tornado form. Press again to return to normal.");
			WindStrength = ((BaseUnityPlugin)this).Config.Bind<float>("Wind", "WindStrength", 1f, new ConfigDescription("Wind force multiplier applied to pushed players. (Push force now comes from the vanilla Tornado prefab; kept for config compatibility.)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 5f), Array.Empty<object>()));
			MovementSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Wind", "MovementSpeed", 12f, new ConfigDescription("How fast the tornado moves with WASD.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 40f), Array.Empty<object>()));
			HoverHeight = ((BaseUnityPlugin)this).Config.Bind<float>("Wind", "HoverHeight", 7f, new ConfigDescription("How high the tornado hovers above the ground.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 25f), Array.Empty<object>()));
			CameraDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "Distance", 18f, new ConfigDescription("Third-person tornado camera distance.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(8f, 30f), Array.Empty<object>()));
			CameraHeight = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "Height", 6f, new ConfigDescription("Third-person tornado camera height above the player.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 14f), Array.Empty<object>()));
			CameraFov = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "Fov", 82f, new ConfigDescription("Field of view while in tornado form.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(60f, 110f), Array.Empty<object>()));
			ShowTornadoVisual = ((BaseUnityPlugin)this).Config.Bind<bool>("Wind", "ShowTornadoVisual", true, "Show a spinning tornado visual while transformed.");
			((BaseUnityPlugin)this).Logger.LogInfo((object)"[I'm a Tornado] Loaded version 0.1.0.");
		}

		private void ConfigureOptionalCharacterPatches()
		{
			TryPatchOptionalCharacterMethod("RPCA_Die", Type.EmptyTypes, "CharacterRpcDiePrefix", "Character.RPCA_Die()");
			TryPatchOptionalCharacterMethod("RPCA_SetDead", Type.EmptyTypes, "CharacterRpcSetDeadPrefix", "Character.RPCA_SetDead()");
			TryPatchOptionalCharacterMethod("RPCA_PassOut", Type.EmptyTypes, "CharacterRpcPassOutPrefix", "Character.RPCA_PassOut()");
			TryPatchOptionalCharacterMethod("DieInstantly", Type.EmptyTypes, "CharacterDieInstantlyPrefix", "Character.DieInstantly()");
			TryPatchOptionalCharacterMethod("HandleDeath", Type.EmptyTypes, "CharacterHandleDeathPrefix", "Character.HandleDeath()");
			TryPatchOptionalCharacterMethod("WarpPlayerRPC", new Type[2]
			{
				typeof(Vector3),
				typeof(bool)
			}, "CharacterWarpPlayerRpcPrefix", "Character.WarpPlayerRPC(Vector3,bool)");
			TryPatchOptionalCharacterMethod("WarpPlayer", new Type[2]
			{
				typeof(Vector3),
				typeof(bool)
			}, "CharacterWarpPlayerPrefix", "Character.WarpPlayer(Vector3,bool)");
		}

		private void TryPatchOptionalCharacterMethod(string methodName, Type[] parameterTypes, string prefixName, string description)
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Expected O, but got Unknown
			try
			{
				MethodInfo methodInfo = AccessTools.Method(typeof(Character), methodName, parameterTypes, (Type[])null);
				if (methodInfo == null)
				{
					((BaseUnityPlugin)this).Logger.LogInfo((object)("[I'm a Tornado] Optional " + description + " patch skipped; method is not present in this game build."));
					return;
				}
				MethodInfo methodInfo2 = AccessTools.Method(typeof(WindHarmonyPatches), prefixName, (Type[])null, (Type[])null);
				if (methodInfo2 == null)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("[I'm a Tornado] Optional " + description + " patch skipped; prefix method was not found."));
				}
				else
				{
					_harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("[I'm a Tornado] Optional " + description + " patch failed: " + ex.Message));
			}
		}

		private void Update()
		{
			//IL_0005: 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)
			try
			{
				if ((int)ToggleKey.Value != 0)
				{
					bool key = Input.GetKey(ToggleKey.Value);
					if (key && !_lastTogglePressed)
					{
						ToggleTornadoForm();
					}
					_lastTogglePressed = key;
					if ((Object)(object)_controller != (Object)null && _controller.Active && !_controller.IsValid())
					{
						ForceExit();
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogError((object)("[I'm a Tornado] Plugin.Update: " + ex));
				}
			}
		}

		private void OnDestroy()
		{
			try
			{
				ForceExit();
			}
			catch (Exception ex)
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogWarning((object)("[I'm a Tornado] Exit during cleanup failed: " + ex.Message));
				}
			}
			try
			{
				_harmony.UnpatchSelf();
			}
			catch (Exception ex2)
			{
				ManualLogSource log2 = Log;
				if (log2 != null)
				{
					log2.LogWarning((object)("[I'm a Tornado] Harmony unpatch failed (non-fatal): " + ex2.Message));
				}
			}
		}

		private void ToggleTornadoForm()
		{
			if (_switching)
			{
				return;
			}
			if ((Object)(object)_controller != (Object)null && _controller.Active)
			{
				ExitTornado();
				return;
			}
			Character localCharacter = Character.localCharacter;
			if (CanTransform(localCharacter))
			{
				_switching = true;
				((MonoBehaviour)this).StartCoroutine(EnterTornadoRoutine(localCharacter));
			}
		}

		private static bool CanTransform(Character character)
		{
			if ((Object)(object)character == (Object)null)
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogWarning((object)"[I'm a Tornado] No local character found.");
				}
				return false;
			}
			if (TornadoController.IsLocalTornadoCharacter(character))
			{
				ManualLogSource log2 = Log;
				if (log2 != null)
				{
					log2.LogWarning((object)"[I'm a Tornado] Already in tornado form.");
				}
				return false;
			}
			if (character.isZombie || character.isBot || character.isScoutmaster)
			{
				ManualLogSource log3 = Log;
				if (log3 != null)
				{
					log3.LogWarning((object)"[I'm a Tornado] Cannot transform while in another special form.");
				}
				return false;
			}
			if ((Object)(object)character.data == (Object)null || character.refs == null || (Object)(object)((MonoBehaviourPun)character).photonView == (Object)null)
			{
				ManualLogSource log4 = Log;
				if (log4 != null)
				{
					log4.LogWarning((object)"[I'm a Tornado] Local character is not ready yet.");
				}
				return false;
			}
			if (character.data.dead || character.data.passedOut || character.data.fullyPassedOut || character.data.fallSeconds > 0f || character.data.isClimbing || character.data.isRopeClimbing || character.data.isVineClimbing)
			{
				ManualLogSource log5 = Log;
				if (log5 != null)
				{
					log5.LogWarning((object)"[I'm a Tornado] Local character is not in a valid state to transform.");
				}
				return false;
			}
			return true;
		}

		private IEnumerator EnterTornadoRoutine(Character character)
		{
			try
			{
				_controller = ((Component)character).gameObject.GetComponent<TornadoController>();
				if ((Object)(object)_controller == (Object)null)
				{
					_controller = ((Component)character).gameObject.AddComponent<TornadoController>();
				}
				_controller.EnterTornado(character);
			}
			catch (Exception ex)
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogError((object)("[I'm a Tornado] Failed to enter tornado form:\n" + ex));
				}
				_controller = null;
			}
			finally
			{
				_switching = false;
			}
			yield break;
		}

		private void ExitTornado()
		{
			_switching = true;
			try
			{
				_controller?.ExitTornado();
				_controller = null;
			}
			catch (Exception ex)
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogError((object)("[I'm a Tornado] Failed to exit tornado form:\n" + ex));
				}
			}
			finally
			{
				_switching = false;
			}
		}

		private void ForceExit()
		{
			if ((Object)(object)_controller == (Object)null)
			{
				return;
			}
			try
			{
				_controller.ExitTornado();
			}
			catch (Exception ex)
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogWarning((object)("[I'm a Tornado] ForceExit failed: " + ex.Message));
				}
			}
			_controller = null;
		}
	}
	[DefaultExecutionOrder(600)]
	public sealed class TornadoController : MonoBehaviour
	{
		private const float HoverLerpRate = 4f;

		private const float HoverSnapDistance = 1.2f;

		private const float HoverMaxClimbSpeed = 6f;

		private const float VelocitySharpness = 7f;

		private const float MaxVelocity = 34f;

		private const float AngularVelocityDamping = 0.92f;

		private const float MaxAngularVelocity = 10f;

		private const float SpinAngularSpeed = 3.2f;

		private const float DefaultCameraDistance = 18f;

		private const float DefaultCameraHeight = 6f;

		private const float CameraLookAhead = 5f;

		private const float CameraCollisionRadius = 0.35f;

		private const float CameraTerrainClearance = 0.8f;

		private const float CameraSmoothTime = 0.08f;

		private const float CameraRotationSharpness = 12f;

		private const float DefaultCameraFov = 82f;

		private Character _character;

		private Vector3 _prevCenter;

		private Vector3 _cameraVelocity;

		private Vector3 _cameraSmoothedPosition;

		private Quaternion _cameraSmoothedRotation;

		private bool _cameraHasSmoothedPosition;

		private float _lastGroundY;

		private GameObject _tornadoVisualRoot;

		private Tornado _tornadoAI;

		private PhotonView _tornadoPhotonView;

		private bool _tornadoIsNetworked;

		private float _nextTornadoVisualSync;

		internal const string NetworkVisualMarker = "ImTornado.Visual";

		private const float NetworkVisualSyncInterval = 0.25f;

		private static readonly FieldInfo TornadoLifeTimeField = typeof(Tornado).GetField("lifeTime", BindingFlags.Instance | BindingFlags.NonPublic);

		private readonly Dictionary<GameObject, bool> _hiddenHudStates = new Dictionary<GameObject, bool>();

		public static Tornado ActiveTornadoAI { get; private set; }

		public static Character ActiveTornadoCharacter { get; private set; }

		public bool Active { get; private set; }

		public Character CharacterRef => _character;

		public bool IsValid()
		{
			if (!Active || (Object)(object)_character == (Object)null || (Object)(object)_character.data == (Object)null)
			{
				return false;
			}
			if (!_character.data.dead)
			{
				return !_character.data.fullyPassedOut;
			}
			return false;
		}

		private static void LogInfo(string message)
		{
			ManualLogSource log = WindPlugin.Log;
			if (log != null)
			{
				log.LogInfo((object)("[I'm a Tornado] " + message));
			}
		}

		private static void LogError(string entryPoint, Exception ex)
		{
			ManualLogSource log = WindPlugin.Log;
			if (log != null)
			{
				log.LogError((object)("[I'm a Tornado] " + entryPoint + ": " + ex));
			}
		}

		public static bool IsLocalTornadoCharacter(Character character)
		{
			if ((Object)(object)character == (Object)null || !character.IsLocal)
			{
				return false;
			}
			TornadoController component = ((Component)character).GetComponent<TornadoController>();
			if ((Object)(object)component != (Object)null)
			{
				return component.Active;
			}
			return false;
		}

		public void EnterTornado(Character character)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: 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_0019: Unknown result type (might be due to invalid IL or missing references)
			_character = character;
			_prevCenter = character.Center;
			_cameraVelocity = Vector3.zero;
			_cameraHasSmoothedPosition = false;
			Active = true;
			ActiveTornadoCharacter = character;
			((Behaviour)this).enabled = true;
			BuildTornadoVisual();
			HideHud();
			LogInfo("Entered tornado form.");
		}

		public void ExitTornado()
		{
			Active = false;
			ActiveTornadoCharacter = null;
			((Behaviour)this).enabled = false;
			DestroyTornadoVisual();
			RestoreHud();
			LogInfo("Exited tornado form.");
		}

		private void Update()
		{
			if (!Active || (Object)(object)_character == (Object)null)
			{
				return;
			}
			try
			{
				ClearNonMovementInput();
				KeepPlayerAlive();
				UpdateTornadoVisual();
				HideHud();
			}
			catch (Exception ex)
			{
				LogError("TornadoController.Update", ex);
			}
		}

		private void FixedUpdate()
		{
			if (!Active || (Object)(object)_character == (Object)null || _character.refs == null || (Object)(object)_character.refs.ragdoll == (Object)null)
			{
				return;
			}
			try
			{
				ApplyMovementVelocity();
				ApplyHoverVelocity();
				ApplySpinningMotion();
				StabilizeRagdoll();
			}
			catch (Exception ex)
			{
				LogError("TornadoController.FixedUpdate", ex);
			}
		}

		private void LateUpdate()
		{
			if (!Active || (Object)(object)_character == (Object)null)
			{
				return;
			}
			try
			{
				SyncCharacterData();
				RefreshCamera();
			}
			catch (Exception ex)
			{
				LogError("TornadoController.LateUpdate", ex);
			}
		}

		private void OnDestroy()
		{
			if (Active)
			{
				Active = false;
				ActiveTornadoCharacter = null;
				DestroyTornadoVisual();
				RestoreHud();
			}
		}

		private void HideHud()
		{
			if (_hiddenHudStates.Count < 2)
			{
				TryHideCanvas("Canvas_HUD");
				TryHideCanvas("Canvas_Names");
			}
		}

		private void TryHideCanvas(string canvasName)
		{
			GameObject val = GameObject.Find(canvasName);
			if (!((Object)(object)val == (Object)null) && !_hiddenHudStates.ContainsKey(val))
			{
				_hiddenHudStates[val] = val.activeSelf;
				if (val.activeSelf)
				{
					val.SetActive(false);
				}
			}
		}

		private void RestoreHud()
		{
			if (_hiddenHudStates.Count == 0)
			{
				return;
			}
			foreach (KeyValuePair<GameObject, bool> hiddenHudState in _hiddenHudStates)
			{
				if ((Object)(object)hiddenHudState.Key != (Object)null)
				{
					hiddenHudState.Key.SetActive(hiddenHudState.Value);
				}
			}
			_hiddenHudStates.Clear();
		}

		private void ClearNonMovementInput()
		{
			if (!((Object)(object)_character == (Object)null) && !((Object)(object)_character.input == (Object)null))
			{
				_character.input.jumpWasPressed = false;
				_character.input.jumpIsPressed = false;
				_character.input.sprintIsPressed = false;
				_character.input.sprintWasPressed = false;
				_character.input.sprintToggleWasPressed = false;
				_character.input.usePrimaryWasPressed = false;
				_character.input.usePrimaryIsPressed = false;
				_character.input.useSecondaryWasPressed = false;
				_character.input.useSecondaryIsPressed = false;
				_character.input.crouchWasPressed = false;
				_character.input.crouchIsPressed = false;
				_character.input.crouchToggleWasPressed = false;
				_character.input.dropWasPressed = false;
				_character.input.dropIsPressed = false;
				_character.input.interactWasPressed = false;
				_character.input.interactIsPressed = false;
			}
		}

		private void KeepPlayerAlive()
		{
			if (!((Object)(object)_character == (Object)null) && !((Object)(object)_character.data == (Object)null))
			{
				_character.data.dead = false;
				_character.data.zombified = false;
				_character.data.passedOut = false;
				_character.data.fullyPassedOut = false;
				_character.data.fallSeconds = 0f;
				_character.data.isSprinting = false;
			}
		}

		private Vector2 GetMovementInput()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: 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_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_character == (Object)null || (Object)(object)_character.input == (Object)null)
			{
				return Vector2.zero;
			}
			Vector2 movementInput = _character.input.movementInput;
			movementInput.x = Mathf.Clamp(movementInput.x, -1f, 1f);
			movementInput.y = Mathf.Clamp(movementInput.y, -1f, 1f);
			return movementInput;
		}

		private void ApplyMovementVelocity()
		{
			//IL_0025: 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_002a: 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_0050: 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_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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_0049: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0085: 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_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: 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_0095: 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_00a7: 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_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: 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)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: 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_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = (((Object)(object)_character.data != (Object)null) ? _character.data.lookDirection_Flat : Vector3.zero);
			if (((Vector3)(ref val)).sqrMagnitude < 0.0001f)
			{
				val = Vector3.ProjectOnPlane(((Component)this).transform.forward, Vector3.up);
			}
			Vector3 val2 = Vector3.ProjectOnPlane(val, Vector3.up);
			val = ((Vector3)(ref val2)).normalized;
			if (((Vector3)(ref val)).sqrMagnitude < 0.0001f)
			{
				val = Vector3.forward;
			}
			Vector2 movementInput = GetMovementInput();
			val2 = Vector3.Cross(Vector3.up, val);
			Vector3 normalized = ((Vector3)(ref val2)).normalized;
			Vector3 val3 = val * movementInput.y + normalized * movementInput.x;
			if (((Vector3)(ref val3)).sqrMagnitude > 1f)
			{
				((Vector3)(ref val3)).Normalize();
			}
			float value = WindPlugin.MovementSpeed.Value;
			Vector3 val4 = val3 * value;
			foreach (Bodypart part in _character.refs.ragdoll.partList)
			{
				Rigidbody val5 = (((Object)(object)part != (Object)null) ? part.Rig : null);
				if (!((Object)(object)val5 == (Object)null) && !val5.isKinematic)
				{
					Vector3 linearVelocity = val5.linearVelocity;
					Vector3 val6 = linearVelocity;
					val6.y = 0f;
					Vector3 val7 = Vector3.Lerp(val6, val4, Time.fixedDeltaTime * 7f) + Vector3.up * linearVelocity.y;
					val5.linearVelocity = Vector3.ClampMagnitude(val7, 34f);
				}
			}
		}

		private void ApplyHoverVelocity()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: 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_0047: 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_00d0: 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)
			if ((Object)(object)_character == (Object)null)
			{
				return;
			}
			Vector3 center = _character.Center;
			float num = GetGroundHeight(center);
			if (float.IsNaN(num))
			{
				num = _lastGroundY;
			}
			else
			{
				_lastGroundY = num;
			}
			float num2 = num + WindPlugin.HoverHeight.Value - center.y;
			float y = 0f;
			if (Mathf.Abs(num2) > 1.2f)
			{
				y = Mathf.Clamp(num2 * 4f, -6f, 6f);
			}
			foreach (Bodypart part in _character.refs.ragdoll.partList)
			{
				Rigidbody val = (((Object)(object)part != (Object)null) ? part.Rig : null);
				if (!((Object)(object)val == (Object)null) && !val.isKinematic)
				{
					Vector3 linearVelocity = val.linearVelocity;
					linearVelocity.y = y;
					val.linearVelocity = linearVelocity;
				}
			}
		}

		private float GetGroundHeight(Vector3 position)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//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_001b: 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_0032: 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_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: 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_0060: 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_0077: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				RaycastHit groundPosRaycast = HelperFunctions.GetGroundPosRaycast(position + Vector3.up * 400f, (LayerType)2, 0f);
				if ((Object)(object)((RaycastHit)(ref groundPosRaycast)).transform != (Object)null)
				{
					return ((RaycastHit)(ref groundPosRaycast)).point.y;
				}
			}
			catch
			{
			}
			try
			{
				RaycastHit groundPosRaycast2 = HelperFunctions.GetGroundPosRaycast(position + Vector3.up * 400f, (LayerType)1, 0f);
				if ((Object)(object)((RaycastHit)(ref groundPosRaycast2)).transform != (Object)null)
				{
					return ((RaycastHit)(ref groundPosRaycast2)).point.y;
				}
			}
			catch
			{
			}
			return float.NaN;
		}

		private void ApplySpinningMotion()
		{
			//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_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: 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_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: 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_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: 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_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: 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_00f0: 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_00fb: 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_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: 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_016c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_character == (Object)null || _character.refs == null || (Object)(object)_character.refs.ragdoll == (Object)null)
			{
				return;
			}
			Vector3 center = _character.Center;
			float num = 3.2f;
			foreach (Bodypart part in _character.refs.ragdoll.partList)
			{
				Rigidbody val = (((Object)(object)part != (Object)null) ? part.Rig : null);
				if (!((Object)(object)val == (Object)null) && !val.isKinematic)
				{
					Vector3 val2 = val.position - center;
					val2.y = 0f;
					if (((Vector3)(ref val2)).sqrMagnitude > 0.0001f)
					{
						Vector3 val3 = Vector3.Cross(Vector3.up, ((Vector3)(ref val2)).normalized);
						Vector3 val4 = ((Vector3)(ref val3)).normalized * num;
						Vector3 angularVelocity = val.angularVelocity;
						angularVelocity.y = Mathf.Lerp(angularVelocity.y, val4.y + num, Time.fixedDeltaTime * 2f);
						angularVelocity.x = Mathf.Lerp(angularVelocity.x, val4.x, Time.fixedDeltaTime * 2f);
						angularVelocity.z = Mathf.Lerp(angularVelocity.z, val4.z, Time.fixedDeltaTime * 2f);
						val.angularVelocity = Vector3.ClampMagnitude(angularVelocity, 10f);
					}
					else
					{
						val.angularVelocity = Vector3.Lerp(val.angularVelocity, Vector3.up * num, Time.fixedDeltaTime * 2f);
					}
				}
			}
		}

		private void StabilizeRagdoll()
		{
			//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_007f: 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_0094: 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_00bf: 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_00b4: 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_00d6: 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)
			if ((Object)(object)_character.refs.ragdoll == (Object)null)
			{
				return;
			}
			foreach (Bodypart part in _character.refs.ragdoll.partList)
			{
				Rigidbody val = (((Object)(object)part != (Object)null) ? part.Rig : null);
				if (!((Object)(object)val == (Object)null) && !val.isKinematic)
				{
					val.useGravity = false;
					part.forcesToAdd = Vector3.zero;
					val.angularVelocity *= 0.92f;
					Vector3 angularVelocity = val.angularVelocity;
					if (((Vector3)(ref angularVelocity)).magnitude > 10f)
					{
						val.angularVelocity = Vector3.ClampMagnitude(val.angularVelocity, 10f);
					}
					if (val.linearVelocity.y < -34f)
					{
						Vector3 linearVelocity = val.linearVelocity;
						linearVelocity.y = -34f;
						val.linearVelocity = linearVelocity;
					}
				}
			}
		}

		private void SyncCharacterData()
		{
			//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_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: 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)
			//IL_0040: 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_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: 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_009b: 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_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_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_00c3: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_character == (Object)null) && !((Object)(object)_character.data == (Object)null))
			{
				Vector3 center = _character.Center;
				Vector3 avarageVelocity = ((((Vector3)(ref _prevCenter)).sqrMagnitude > 0f) ? ((center - _prevCenter) / Mathf.Max(Time.deltaTime, 0.0001f)) : Vector3.zero);
				_prevCenter = center;
				_character.data.avarageLastFrameVelocity = _character.data.avarageVelocity;
				_character.data.avarageVelocity = avarageVelocity;
				_character.data.worldMovementInput = (_character.data.worldMovementInput_Grounded = Vector3.zero);
				_character.data.sinceGrounded = Mathf.Min(_character.data.sinceGrounded, 0.1f);
			}
		}

		private void BuildTornadoVisual()
		{
			if ((Object)(object)_tornadoVisualRoot != (Object)null || (Object)(object)_character == (Object)null)
			{
				return;
			}
			try
			{
				GameObject val = Resources.Load<GameObject>("Tornado");
				if ((Object)(object)val == (Object)null)
				{
					LogInfo("Resources.Load(\"Tornado\") returned null; no tornado visual will be shown.");
				}
				else if (PhotonNetwork.InRoom && (Object)(object)((MonoBehaviourPun)_character).photonView != (Object)null && ((MonoBehaviourPun)_character).photonView.ViewID > 0)
				{
					BuildNetworkedTornado(val);
				}
				else
				{
					BuildLocalTornado(val);
				}
			}
			catch (Exception ex)
			{
				LogError("TornadoController.BuildTornadoVisual", ex);
				DestroyTornadoVisual();
			}
		}

		private void BuildNetworkedTornado(GameObject prefab)
		{
			//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_006c: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = PhotonNetwork.Instantiate("Tornado", _character.Center, Quaternion.identity, (byte)0, new object[1] { "ImTornado.Visual" });
			((Object)val).name = "WindTornadoNetworked";
			_tornadoVisualRoot = val;
			_tornadoIsNetworked = true;
			_tornadoAI = val.GetComponent<Tornado>();
			ActiveTornadoAI = _tornadoAI;
			_tornadoPhotonView = val.GetComponent<PhotonView>();
			val.transform.localScale = Vector3.one;
			val.SetActive(WindPlugin.ShowTornadoVisual.Value);
			SyncNetworkTornadoVisual(force: true);
			LogInfo("Spawned networked tornado visual with vanilla Tornado prefab.");
		}

		private void BuildLocalTornado(GameObject prefab)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: 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_00bc: 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)
			GameObject val = Object.Instantiate<GameObject>(prefab, _character.Center, Quaternion.identity);
			((Object)val).name = "WindTornadoVisual";
			MonoBehaviour[] componentsInChildren = val.GetComponentsInChildren<MonoBehaviour>(true);
			foreach (MonoBehaviour val2 in componentsInChildren)
			{
				if (!((Object)(object)val2 == (Object)null))
				{
					Type type = ((object)val2).GetType();
					if (!(type == typeof(Animator)) && !(type == typeof(ParticleSystem)))
					{
						Object.DestroyImmediate((Object)(object)val2);
					}
				}
			}
			Collider[] componentsInChildren2 = val.GetComponentsInChildren<Collider>(true);
			for (int i = 0; i < componentsInChildren2.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren2[i]);
			}
			val.transform.localScale = Vector3.one;
			ParticleSystem[] componentsInChildren3 = val.GetComponentsInChildren<ParticleSystem>(true);
			foreach (ParticleSystem obj in componentsInChildren3)
			{
				MainModule main = obj.main;
				((MainModule)(ref main)).playOnAwake = true;
				obj.Play();
			}
			_tornadoVisualRoot = val;
			_tornadoIsNetworked = false;
			val.SetActive(WindPlugin.ShowTornadoVisual.Value);
			LogInfo("Spawned local-only tornado visual (offline / single-player).");
		}

		private void UpdateTornadoVisual()
		{
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: 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)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_tornadoVisualRoot == (Object)null || (Object)(object)_character == (Object)null)
			{
				return;
			}
			if (_tornadoVisualRoot.activeSelf != WindPlugin.ShowTornadoVisual.Value)
			{
				_tornadoVisualRoot.SetActive(WindPlugin.ShowTornadoVisual.Value);
			}
			if (_tornadoIsNetworked)
			{
				_tornadoVisualRoot.transform.position = _character.Center;
				_tornadoVisualRoot.transform.localScale = Vector3.one;
				SyncNetworkTornadoVisual();
				if ((Object)(object)_tornadoAI != (Object)null && TornadoLifeTimeField != null)
				{
					TornadoLifeTimeField.SetValue(_tornadoAI, 9999f);
				}
			}
			else
			{
				_tornadoVisualRoot.transform.position = _character.Center;
				_tornadoVisualRoot.transform.localScale = Vector3.one;
			}
		}

		private void DestroyTornadoVisual()
		{
			ActiveTornadoAI = null;
			_tornadoAI = null;
			_tornadoPhotonView = null;
			if ((Object)(object)_tornadoVisualRoot != (Object)null)
			{
				if (_tornadoIsNetworked && PhotonNetwork.InRoom)
				{
					try
					{
						PhotonNetwork.Destroy(_tornadoVisualRoot);
					}
					catch
					{
					}
				}
				else
				{
					Object.Destroy((Object)(object)_tornadoVisualRoot);
				}
			}
			_tornadoVisualRoot = null;
			_tornadoIsNetworked = false;
		}

		private void SyncNetworkTornadoVisual(bool force = false)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_tornadoPhotonView == (Object)null || (Object)(object)_character == (Object)null || !PhotonNetwork.InRoom || (!force && Time.unscaledTime < _nextTornadoVisualSync))
			{
				return;
			}
			_nextTornadoVisualSync = Time.unscaledTime + 0.25f;
			try
			{
				_tornadoPhotonView.RPC("RPCA_SyncTornado", (RpcTarget)0, new object[1] { _character.Center });
			}
			catch (Exception ex)
			{
				LogError("TornadoController.SyncNetworkTornadoVisual", ex);
			}
		}

		private void RefreshCamera()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: 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_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_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: 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_0086: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: 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_003d: 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_0049: 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_004f: 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_00c0: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Camera main = Camera.main;
				if (!((Object)(object)main == (Object)null))
				{
					Vector3 thirdPersonCameraLookTarget = GetThirdPersonCameraLookTarget(_character);
					Vector3 val = ResolveCameraCollision(thirdPersonCameraLookTarget, GetThirdPersonCameraPosition(_character));
					if (!_cameraHasSmoothedPosition)
					{
						_cameraSmoothedPosition = val;
						_cameraSmoothedRotation = GetCameraRotation(_cameraSmoothedPosition, thirdPersonCameraLookTarget);
						_cameraHasSmoothedPosition = true;
					}
					else
					{
						_cameraSmoothedPosition = Vector3.SmoothDamp(_cameraSmoothedPosition, val, ref _cameraVelocity, 0.08f);
						Quaternion cameraRotation = GetCameraRotation(_cameraSmoothedPosition, thirdPersonCameraLookTarget);
						float num = 1f - Mathf.Exp(-12f * Time.deltaTime);
						_cameraSmoothedRotation = Quaternion.Slerp(_cameraSmoothedRotation, cameraRotation, num);
					}
					((Component)main).transform.SetPositionAndRotation(_cameraSmoothedPosition, _cameraSmoothedRotation);
					main.fieldOfView = Mathf.Lerp(main.fieldOfView, GetCameraFov(), Time.deltaTime * 4f);
				}
			}
			catch (Exception ex)
			{
				LogError("TornadoController.RefreshCamera", ex);
			}
		}

		private static Vector3 GetThirdPersonCameraPosition(Character character)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: 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_0032: Unknown result type (might be due to invalid IL or missing references)
			Vector3 cameraForward = GetCameraForward(character);
			return character.Center + Vector3.up * (GetCameraHeight() + 2f) - cameraForward * GetCameraDistance();
		}

		private static Vector3 GetThirdPersonCameraLookTarget(Character character)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: 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_003e: 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_0055: 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)
			Vector3 cameraForward = GetCameraForward(character);
			float num = Mathf.Clamp((((Object)(object)character.data != (Object)null) ? ((Vector3)(ref character.data.lookDirection)).normalized : cameraForward).y, -0.35f, 0.65f);
			return character.Center + Vector3.up * (GetCameraHeight() + num * 3f) + cameraForward * 5f;
		}

		private static float GetCameraDistance()
		{
			return Mathf.Clamp((WindPlugin.CameraDistance != null) ? WindPlugin.CameraDistance.Value : 18f, 8f, 30f);
		}

		private static float GetCameraHeight()
		{
			return Mathf.Clamp((WindPlugin.CameraHeight != null) ? WindPlugin.CameraHeight.Value : 6f, 2f, 14f);
		}

		private static float GetCameraFov()
		{
			return Mathf.Clamp((WindPlugin.CameraFov != null) ? WindPlugin.CameraFov.Value : 82f, 60f, 110f);
		}

		private static Vector3 GetCameraForward(Character character)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: 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_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: 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_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: 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_0094: 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)
			Vector3 val = (((Object)(object)character.data != (Object)null) ? character.data.lookDirection_Flat : Vector3.zero);
			val = Vector3.ProjectOnPlane(val, Vector3.up);
			if (((Vector3)(ref val)).sqrMagnitude < 0.0001f && (Object)(object)Camera.main != (Object)null)
			{
				val = Vector3.ProjectOnPlane(((Component)Camera.main).transform.forward, Vector3.up);
			}
			if (((Vector3)(ref val)).sqrMagnitude < 0.0001f)
			{
				val = Vector3.ProjectOnPlane(((Component)character).transform.forward, Vector3.up);
			}
			if (((Vector3)(ref val)).sqrMagnitude < 0.0001f)
			{
				val = Vector3.forward;
			}
			return ((Vector3)(ref val)).normalized;
		}

		private Vector3 ResolveCameraCollision(Vector3 lookTarget, Vector3 desiredPosition)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: 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_003b: 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_004d: Unknown result type (might be due to invalid IL or missing references)
			RaycastHit val = HelperFunctions.LineCheck(lookTarget, desiredPosition, (LayerType)1, 0.35f, (QueryTriggerInteraction)1);
			if ((Object)(object)((RaycastHit)(ref val)).transform != (Object)null)
			{
				desiredPosition = ((RaycastHit)(ref val)).point + ((RaycastHit)(ref val)).normal * 0.8f;
			}
			float groundHeight = GetGroundHeight(desiredPosition);
			if (!float.IsNaN(groundHeight) && desiredPosition.y < groundHeight + 0.8f)
			{
				desiredPosition.y = groundHeight + 0.8f;
			}
			return desiredPosition;
		}

		private static Quaternion GetCameraRotation(Vector3 cameraPosition, Vector3 lookTarget)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//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_0007: 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_0023: 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_0016: 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)
			Vector3 val = lookTarget - cameraPosition;
			if (((Vector3)(ref val)).sqrMagnitude < 0.0001f)
			{
				val = Vector3.forward;
			}
			return Quaternion.LookRotation(((Vector3)(ref val)).normalized, Vector3.up);
		}
	}
	[HarmonyPatch]
	public static class WindHarmonyPatches
	{
		private static readonly FieldInfo BananaPeelItemField = typeof(BananaPeel).GetField("item", BindingFlags.Instance | BindingFlags.NonPublic);

		private static readonly FieldInfo ItemVfxItemField = typeof(ItemVFX).GetField("item", BindingFlags.Instance | BindingFlags.NonPublic);

		private static readonly FieldInfo TornadoIgnoredCharactersField = typeof(Tornado).GetField("ignoredCharacters", BindingFlags.Instance | BindingFlags.NonPublic);

		private static bool IsTornado(Character character)
		{
			return TornadoController.IsLocalTornadoCharacter(character);
		}

		private static bool HasUsableLocalCharacter()
		{
			Character localCharacter = Character.localCharacter;
			if ((Object)(object)localCharacter != (Object)null && (Object)(object)localCharacter.data != (Object)null && localCharacter.refs != null && (Object)(object)localCharacter.refs.view != (Object)null)
			{
				return (Object)(object)((MonoBehaviourPun)localCharacter).photonView != (Object)null;
			}
			return false;
		}

		private static Item GetOrCacheBananaItem(BananaPeel banana)
		{
			if ((Object)(object)banana == (Object)null || BananaPeelItemField == null)
			{
				return null;
			}
			object? value = BananaPeelItemField.GetValue(banana);
			Item val = (Item)((value is Item) ? value : null);
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			val = ((Component)banana).GetComponent<Item>();
			if ((Object)(object)val != (Object)null)
			{
				BananaPeelItemField.SetValue(banana, val);
			}
			return val;
		}

		private static Item GetOrCacheItemVfxItem(ItemVFX itemVfx)
		{
			if ((Object)(object)itemVfx == (Object)null || ItemVfxItemField == null)
			{
				return null;
			}
			object? value = ItemVfxItemField.GetValue(itemVfx);
			Item val = (Item)((value is Item) ? value : null);
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			val = ((Component)itemVfx).GetComponent<Item>();
			if ((Object)(object)val != (Object)null)
			{
				ItemVfxItemField.SetValue(itemVfx, val);
			}
			return val;
		}

		private static bool IsWindNetworkVisual(Tornado tornado)
		{
			if ((Object)(object)tornado == (Object)null)
			{
				return false;
			}
			PhotonView component = ((Component)tornado).GetComponent<PhotonView>();
			object[] array = (((Object)(object)component != (Object)null) ? component.InstantiationData : null);
			if (array != null && array.Length != 0 && array[0] is string text)
			{
				return text == "ImTornado.Visual";
			}
			return false;
		}

		[HarmonyPatch(typeof(Tornado), "Update")]
		[HarmonyPrefix]
		private static bool TornadoUpdatePrefix(Tornado __instance)
		{
			//IL_0016: 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_002b: Unknown result type (might be due to invalid IL or missing references)
			if (!IsWindNetworkVisual(__instance))
			{
				return true;
			}
			((Component)__instance).transform.localScale = Vector3.Lerp(((Component)__instance).transform.localScale, Vector3.one, Time.deltaTime * 0.25f);
			return false;
		}

		[HarmonyPatch(typeof(Tornado), "FixedUpdate")]
		[HarmonyPrefix]
		private static bool TornadoFixedUpdatePrefix(Tornado __instance)
		{
			if (!IsWindNetworkVisual(__instance))
			{
				return true;
			}
			Character activeTornadoCharacter = TornadoController.ActiveTornadoCharacter;
			if ((Object)(object)activeTornadoCharacter != (Object)null && TornadoIgnoredCharactersField != null && TornadoIgnoredCharactersField.GetValue(__instance) is List<Character> list && !list.Contains(activeTornadoCharacter))
			{
				list.Add(activeTornadoCharacter);
			}
			return true;
		}

		[HarmonyPatch(typeof(Tornado), "RPCA_TornadoDie")]
		[HarmonyPrefix]
		private static bool TornadoDiePrefix(Tornado __instance)
		{
			return !IsWindNetworkVisual(__instance);
		}

		[HarmonyPatch(typeof(Tornado), "RPCA_SyncTornado")]
		[HarmonyPostfix]
		private static void TornadoSyncPostfix(Tornado __instance, Vector3 syncVel)
		{
			//IL_000f: 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)
			if (IsWindNetworkVisual(__instance))
			{
				((Component)__instance).transform.position = syncVel;
				((Component)__instance).transform.localScale = Vector3.one;
			}
		}

		[HarmonyPatch(typeof(BananaPeel), "Update")]
		[HarmonyPrefix]
		private static bool BananaPeelUpdatePrefix(BananaPeel __instance)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			Item orCacheBananaItem = GetOrCacheBananaItem(__instance);
			if ((Object)(object)orCacheBananaItem == (Object)null)
			{
				return false;
			}
			if ((int)orCacheBananaItem.itemState != 0)
			{
				return false;
			}
			return HasUsableLocalCharacter();
		}

		[HarmonyPatch(typeof(VineShooter), "Update")]
		[HarmonyPrefix]
		private static bool VineShooterUpdatePrefix(VineShooter __instance)
		{
			if ((Object)(object)__instance != (Object)null && (Object)(object)((ItemComponent)__instance).item != (Object)null && HasUsableLocalCharacter())
			{
				return (Object)(object)MainCamera.instance != (Object)null;
			}
			return false;
		}

		[HarmonyPatch(typeof(DispelFogField), "Update")]
		[HarmonyPrefix]
		private static bool DispelFogFieldUpdatePrefix()
		{
			if ((Object)(object)Object.FindAnyObjectByType<OrbFogHandler>() == (Object)null)
			{
				return false;
			}
			Character observedCharacter = Character.observedCharacter;
			if ((Object)(object)observedCharacter != (Object)null)
			{
				return (Object)(object)observedCharacter.data != (Object)null;
			}
			return false;
		}

		[HarmonyPatch(typeof(WarpCompassVFX), "OnUpdatedFeedData")]
		[HarmonyPrefix]
		private static bool WarpCompassOnUpdatedFeedDataPrefix(WarpCompassVFX __instance)
		{
			if ((Object)(object)GameUtils.instance != (Object)null && (Object)(object)GetOrCacheItemVfxItem((ItemVFX)(object)__instance) != (Object)null)
			{
				return HasUsableLocalCharacter();
			}
			return false;
		}

		internal static bool CharacterRpcDiePrefix(Character __instance)
		{
			return !IsTornado(__instance);
		}

		internal static bool CharacterRpcSetDeadPrefix(Character __instance)
		{
			return !IsTornado(__instance);
		}

		internal static bool CharacterRpcPassOutPrefix(Character __instance)
		{
			return !IsTornado(__instance);
		}

		internal static bool CharacterDieInstantlyPrefix(Character __instance)
		{
			return !IsTornado(__instance);
		}

		internal static bool CharacterHandleDeathPrefix(Character __instance)
		{
			return !IsTornado(__instance);
		}

		internal static bool CharacterWarpPlayerRpcPrefix(Character __instance)
		{
			return !IsTornado(__instance);
		}

		internal static bool CharacterWarpPlayerPrefix(Character __instance)
		{
			return !IsTornado(__instance);
		}
	}
}