Decompiled source of HowToFish v1.2.0

JohnFister.HowToFish.dll

Decompiled 13 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using BepInEx.Unity.Mono;
using HarmonyLib;
using JohnFister.Body;
using JohnFister.Core;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.Networking;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("JohnFister.HowToFish")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("JohnFister.HowToFish")]
[assembly: AssemblyTitle("JohnFister.HowToFish")]
[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 JohnFister
{
	internal static class Units
	{
		internal const float S = 1f;

		internal const float AvatarOrigin = 1f;

		internal const float DrawnHeight = 2.9665f;
	}
	internal static class Assets
	{
		private static readonly Dictionary<string, Texture2D> Textures = new Dictionary<string, Texture2D>();

		private static Shader _unlit;

		private static Texture2D _white;

		internal static string Dir => Path.Combine(FisterPlugin.PluginDir, "assets");

		internal static Texture2D White
		{
			get
			{
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				//IL_0021: Expected O, but got Unknown
				//IL_002e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0033: Unknown result type (might be due to invalid IL or missing references)
				//IL_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_0046: Unknown result type (might be due to invalid IL or missing references)
				//IL_004b: Unknown result type (might be due to invalid IL or missing references)
				//IL_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)
				if ((Object)(object)_white != (Object)null)
				{
					return _white;
				}
				_white = new Texture2D(2, 2, (TextureFormat)4, false);
				_white.SetPixels((Color[])(object)new Color[4]
				{
					Color.white,
					Color.white,
					Color.white,
					Color.white
				});
				_white.Apply();
				Object.DontDestroyOnLoad((Object)(object)_white);
				return _white;
			}
		}

		private static Shader Unlit
		{
			get
			{
				if ((Object)(object)_unlit != (Object)null)
				{
					return _unlit;
				}
				string[] obj = new string[5] { "Universal Render Pipeline/Particles/Unlit", "Particles/Standard Unlit", "Universal Render Pipeline/Unlit", "Unlit/Texture", "Sprites/Default" };
				Shader[] source = Resources.FindObjectsOfTypeAll<Shader>();
				string[] array = obj;
				foreach (string name in array)
				{
					_unlit = ((IEnumerable<Shader>)source).FirstOrDefault((Func<Shader, bool>)((Shader s) => (Object)(object)s != (Object)null && ((Object)s).name == name));
					if ((Object)(object)_unlit == (Object)null)
					{
						_unlit = Shader.Find(name);
					}
					if ((Object)(object)_unlit != (Object)null)
					{
						FisterPlugin.Log.LogInfo((object)("John Fister body shader: " + ((Object)_unlit).name));
						break;
					}
				}
				return _unlit;
			}
		}

		internal static Texture2D Tex(string name)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			if (Textures.TryGetValue(name, out var value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			string text = Path.Combine(Dir, "tex", name + ".png");
			value = new Texture2D(2, 2, (TextureFormat)4, true);
			if (File.Exists(text))
			{
				ImageConversion.LoadImage(value, File.ReadAllBytes(text));
			}
			else
			{
				FisterPlugin.Log.LogError((object)("Missing texture: " + text));
			}
			((Object)value).name = "fister_" + name;
			((Texture)value).wrapMode = (TextureWrapMode)1;
			((Texture)value).filterMode = (FilterMode)1;
			Object.DontDestroyOnLoad((Object)(object)value);
			Textures[name] = value;
			return value;
		}

		internal static Material Material(Texture2D texture, int cull, bool transparent)
		{
			Material obj = Material(texture, cull);
			SetSurface(obj, transparent);
			return obj;
		}

		internal static Material Material(Texture2D texture, int cull)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_007a: 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)
			Shader unlit = Unlit;
			if ((Object)(object)unlit == (Object)null)
			{
				throw new InvalidOperationException("No supported unlit shader is available in the game.");
			}
			Material val = new Material(unlit);
			((Object)val).name = "fister_" + ((Object)texture).name;
			if (val.HasProperty("_BaseMap"))
			{
				val.SetTexture("_BaseMap", (Texture)(object)texture);
			}
			if (val.HasProperty("_MainTex"))
			{
				val.SetTexture("_MainTex", (Texture)(object)texture);
			}
			if (val.HasProperty("_BaseColor"))
			{
				val.SetColor("_BaseColor", Color.white);
			}
			if (val.HasProperty("_Color"))
			{
				val.SetColor("_Color", Color.white);
			}
			if (val.HasProperty("_Cull"))
			{
				val.SetFloat("_Cull", (float)cull);
			}
			SetSurface(val, transparent: false);
			Object.DontDestroyOnLoad((Object)(object)val);
			return val;
		}

		private static void SetSurface(Material material, bool transparent)
		{
			if (material.HasProperty("_Surface"))
			{
				material.SetFloat("_Surface", transparent ? 1f : 0f);
			}
			if (material.HasProperty("_ZWrite"))
			{
				material.SetFloat("_ZWrite", 1f);
			}
			if (material.HasProperty("_SrcBlend"))
			{
				material.SetFloat("_SrcBlend", (float)((!transparent) ? 1 : 5));
			}
			if (material.HasProperty("_DstBlend"))
			{
				material.SetFloat("_DstBlend", (float)(transparent ? 10 : 0));
			}
			if (transparent)
			{
				material.EnableKeyword("_SURFACE_TYPE_TRANSPARENT");
				material.EnableKeyword("_ALPHABLEND_ON");
				material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
				material.renderQueue = 3000;
			}
			else
			{
				material.DisableKeyword("_SURFACE_TYPE_TRANSPARENT");
				material.DisableKeyword("_ALPHABLEND_ON");
				material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
				material.renderQueue = 2000;
			}
		}
	}
	internal sealed class ContactProbe : MonoBehaviour
	{
		private readonly List<Vector3> normals = new List<Vector3>(8);

		private readonly List<Vector3> points = new List<Vector3>(8);

		private void Record(Collision collision)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			if (collision == null || (Object)(object)collision.collider == (Object)null || collision.collider.isTrigger || (Object)(object)((Component)collision.collider).GetComponentInParent<Player>() != (Object)null)
			{
				return;
			}
			for (int i = 0; i < collision.contactCount; i++)
			{
				if (normals.Count >= 8)
				{
					break;
				}
				ContactPoint contact = collision.GetContact(i);
				normals.Add(((ContactPoint)(ref contact)).normal);
				points.Add(((ContactPoint)(ref contact)).point);
			}
		}

		private void OnCollisionEnter(Collision collision)
		{
			Record(collision);
		}

		private void OnCollisionStay(Collision collision)
		{
			Record(collision);
		}

		internal void Consume(List<Vector3> outNormals, List<Vector3> outPoints)
		{
			outNormals.Clear();
			outPoints.Clear();
			outNormals.AddRange(normals);
			outPoints.AddRange(points);
			normals.Clear();
			points.Clear();
		}
	}
	internal static class FisterAudio
	{
		private struct PendingSound
		{
			internal string name;

			internal Vector3 at;

			internal float volume;

			internal float pitch;
		}

		private const float Master = 0.5f;

		private static readonly string[] SoundNames = new string[21]
		{
			"crack", "criticalhit", "damage-taken", "disintegrated", "explode", "fail-100-punch", "footstep", "grab-lunge", "groundpoundscream", "kill",
			"kill2", "lunge", "overcharge-dash-loop", "overcharge-dash-screech", "parry-success", "punch", "railing-sonic-boom", "reload", "shieldbreak", "successful-100-punch",
			"uppercutcounter"
		};

		private static readonly Dictionary<string, AudioClip> clips = new Dictionary<string, AudioClip>();

		private static readonly List<AudioSource> pool = new List<AudioSource>();

		private static readonly Dictionary<string, AudioSource> loops = new Dictionary<string, AudioSource>();

		private static readonly List<PendingSound> pending = new List<PendingSound>();

		private static readonly List<UnityWebRequest> activeRequests = new List<UnityWebRequest>();

		private static GameObject host;

		private static bool loading;

		private static bool loaded;

		private static int loadGeneration;

		private static int punchCombo;

		private static float lastPunchTime;

		internal static void Initialize(MonoBehaviour coroutineOwner, string pluginDirectory)
		{
			if (!loading && !loaded && !((Object)(object)coroutineOwner == (Object)null))
			{
				loading = true;
				int generation = ++loadGeneration;
				EnsureHost();
				coroutineOwner.StartCoroutine(LoadSounds(pluginDirectory, generation));
			}
		}

		private static IEnumerator LoadSounds(string pluginDirectory, int generation)
		{
			List<UnityWebRequest> requests = new List<UnityWebRequest>(SoundNames.Length);
			try
			{
				string path = Path.Combine(pluginDirectory, "assets", "sounds");
				string[] soundNames = SoundNames;
				foreach (string text in soundNames)
				{
					UnityWebRequest audioClip = UnityWebRequestMultimedia.GetAudioClip(new Uri(Path.GetFullPath(Path.Combine(path, text + ".mp3"))).AbsoluteUri, (AudioType)13);
					requests.Add(audioClip);
					activeRequests.Add(audioClip);
					audioClip.SendWebRequest();
				}
				while (true)
				{
					if (generation != loadGeneration)
					{
						yield break;
					}
					bool flag = true;
					for (int j = 0; j < requests.Count; j++)
					{
						if (!requests[j].isDone)
						{
							flag = false;
							break;
						}
					}
					if (flag)
					{
						break;
					}
					yield return null;
				}
				for (int k = 0; k < requests.Count; k++)
				{
					UnityWebRequest val = requests[k];
					string text2 = SoundNames[k];
					AudioClip val2 = null;
					if ((int)val.result == 1)
					{
						try
						{
							val2 = DownloadHandlerAudioClip.GetContent(val);
							if ((Object)(object)val2 != (Object)null)
							{
								((Object)val2).name = "fister_" + text2;
								Object.DontDestroyOnLoad((Object)(object)val2);
							}
						}
						catch (Exception ex)
						{
							FisterPlugin.Log.LogWarning((object)("Could not decode Fister sound " + text2 + ": " + ex.Message));
						}
					}
					else
					{
						FisterPlugin.Log.LogWarning((object)("Could not load Fister sound " + text2 + ": " + val.error));
					}
					clips[text2] = val2;
				}
				if (generation == loadGeneration)
				{
					loaded = true;
					loading = false;
					for (int l = 0; l < pending.Count; l++)
					{
						PendingSound pendingSound = pending[l];
						PlayLoaded(pendingSound.name, pendingSound.at, pendingSound.volume, pendingSound.pitch);
					}
					pending.Clear();
					FisterPlugin.Log.LogInfo((object)("Loaded " + clips.Count + " original Fister sounds."));
				}
			}
			finally
			{
				foreach (UnityWebRequest item in requests)
				{
					activeRequests.Remove(item);
					item.Dispose();
				}
				if (generation == loadGeneration)
				{
					loading = false;
				}
			}
		}

		internal static void PlayPunch(Vector3 at)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			if (Time.unscaledTime - lastPunchTime > 0.65f)
			{
				punchCombo = 0;
			}
			punchCombo = Mathf.Min(12, punchCombo + 1);
			lastPunchTime = Time.unscaledTime;
			Play("punch", at, 1f, 1f + (float)(punchCombo - 1) * 0.08f);
		}

		internal static void Play(string name, Vector3 at, float volume, float pitch = 1f)
		{
			//IL_004a: 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_002d: Unknown result type (might be due to invalid IL or missing references)
			if (!loaded)
			{
				if (pending.Count < 32)
				{
					pending.Add(new PendingSound
					{
						name = name,
						at = at,
						volume = volume,
						pitch = pitch
					});
				}
			}
			else
			{
				PlayLoaded(name, at, volume, pitch);
			}
		}

		private static void PlayLoaded(string name, Vector3 at, float volume, float pitch)
		{
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			if (!clips.TryGetValue(name, out var value) || (Object)(object)value == (Object)null)
			{
				return;
			}
			EnsureHost();
			AudioSource val = null;
			foreach (AudioSource item in pool)
			{
				if ((Object)(object)item != (Object)null && !item.isPlaying)
				{
					val = item;
					break;
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				if (pool.Count >= 24)
				{
					return;
				}
				val = NewSource();
				pool.Add(val);
			}
			ApplyEffectsMixer(val);
			val.pitch = Mathf.Clamp(pitch, 0.5f, 2.5f);
			val.PlayOneShot(value, Mathf.Clamp01(volume * 0.5f * DistanceFalloff(at)));
		}

		internal static void Loop(string name, float volume, float pitch)
		{
			AudioClip value2;
			if (volume <= 0.001f)
			{
				if (loops.TryGetValue(name, out var value) && (Object)(object)value != (Object)null && value.isPlaying)
				{
					value.Stop();
				}
			}
			else if (loaded && clips.TryGetValue(name, out value2) && !((Object)(object)value2 == (Object)null))
			{
				EnsureHost();
				if (!loops.TryGetValue(name, out var value3) || (Object)(object)value3 == (Object)null)
				{
					value3 = NewSource();
					value3.loop = true;
					value3.clip = value2;
					loops[name] = value3;
				}
				ApplyEffectsMixer(value3);
				value3.volume = Mathf.Clamp01(volume * 0.5f);
				value3.pitch = Mathf.Clamp(pitch, 0.5f, 2.5f);
				if (!value3.isPlaying)
				{
					value3.Play();
				}
			}
		}

		internal static void StopLoops()
		{
			foreach (AudioSource value in loops.Values)
			{
				if ((Object)(object)value != (Object)null)
				{
					value.Stop();
				}
			}
		}

		internal static void Shutdown()
		{
			loadGeneration++;
			foreach (UnityWebRequest activeRequest in activeRequests)
			{
				if (activeRequest != null && !activeRequest.isDone)
				{
					activeRequest.Abort();
				}
			}
			StopLoops();
			if ((Object)(object)host != (Object)null)
			{
				Object.Destroy((Object)(object)host);
				host = null;
			}
			foreach (AudioClip value in clips.Values)
			{
				if ((Object)(object)value != (Object)null)
				{
					Object.Destroy((Object)(object)value);
				}
			}
			clips.Clear();
			pool.Clear();
			loops.Clear();
			pending.Clear();
			loading = false;
			loaded = false;
			punchCombo = 0;
		}

		private static void EnsureHost()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			if ((Object)(object)host == (Object)null)
			{
				host = new GameObject("JohnFisterAudio");
				Object.DontDestroyOnLoad((Object)(object)host);
			}
		}

		private static AudioSource NewSource()
		{
			AudioSource obj = host.AddComponent<AudioSource>();
			obj.playOnAwake = false;
			obj.spatialBlend = 0f;
			ApplyEffectsMixer(obj);
			return obj;
		}

		private static void ApplyEffectsMixer(AudioSource source)
		{
			try
			{
				Type type = typeof(Player).Assembly.GetType("AudioManager");
				FieldInfo fieldInfo = ((type != null) ? type.GetField("_instance", BindingFlags.Static | BindingFlags.NonPublic) : null);
				object obj = ((fieldInfo != null) ? fieldInfo.GetValue(null) : null);
				FieldInfo fieldInfo2 = ((type != null) ? type.GetField("_fxGroup", BindingFlags.Instance | BindingFlags.NonPublic) : null);
				AudioMixerGroup val = (AudioMixerGroup)((fieldInfo2 != null) ? /*isinst with value type is only supported in some contexts*/: null);
				if ((Object)(object)val != (Object)null)
				{
					source.outputAudioMixerGroup = val;
				}
			}
			catch (Exception ex)
			{
				FisterPlugin.Log.LogDebug((object)("Fister audio is using the default mixer route: " + ex.Message));
			}
		}

		private static float DistanceFalloff(Vector3 at)
		{
			//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)
			Camera main = Camera.main;
			if ((Object)(object)main == (Object)null)
			{
				return 1f;
			}
			float num = Vector3.Distance(((Component)main).transform.position, at) / Mathf.Max(0.01f, ((Object)(object)FisterPlugin.Instance != (Object)null && (Object)(object)FisterPlugin.Instance.Controller != (Object)null) ? FisterPlugin.Instance.Controller.Scale : 1f);
			return Mathf.Clamp(1f - Mathf.Max(0f, num - 20f) / 100f, 0.3f, 1f);
		}
	}
	internal sealed class FisterCombat
	{
		private readonly FisterController owner;

		private readonly RaycastHit[] castHits = (RaycastHit[])(object)new RaycastHit[64];

		private readonly Collider[] overlapHits = (Collider[])(object)new Collider[96];

		private readonly HashSet<Rigidbody> affected = new HashSet<Rigidbody>();

		private readonly HashSet<Component> damagedCreatures = new HashSet<Component>();

		private static readonly Type CreatureType = Type.GetType("Creature, Assembly-CSharp");

		private static readonly Type ServerType = Type.GetType("Server, Assembly-CSharp");

		private static readonly MethodInfo CreatureLocalHit = FindMethod(CreatureType, "LocalHit", 10);

		private static readonly MethodInfo ServerHitCreature = FindMethod(ServerType, "HitCreature", 5);

		private Rigidbody grabbed;

		private Rigidbody lastAirKickTarget;

		private Component lastAirKickCreature;

		private Rigidbody airKickLockCandidate;

		private float railingChargeProgress;

		private bool diveHit;

		internal FisterCombat(FisterController owner)
		{
			this.owner = owner;
		}

		internal void Reset()
		{
			grabbed = null;
			lastAirKickTarget = null;
			lastAirKickCreature = null;
			airKickLockCandidate = null;
			railingChargeProgress = 0f;
			diveHit = false;
			affected.Clear();
			damagedCreatures.Clear();
		}

		internal void HandleEvents()
		{
			int num = 0;
			while (owner.Sim.Events().Count > 0 && num++ < 64)
			{
				List<Event> list = new List<Event>(owner.Sim.Events());
				owner.Sim.Events().Clear();
				foreach (Event item in list)
				{
					try
					{
						HandleEvent(item);
					}
					catch (Exception ex)
					{
						FisterPlugin.Log.LogError((object)("Fister event " + item.type.ToString() + " failed: " + ex.Message));
					}
				}
			}
			owner.Sim.Events().Clear();
		}

		internal void Tick()
		{
			//IL_0050: 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_0071: 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_0091: 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_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_023b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0359: Unknown result type (might be due to invalid IL or missing references)
			//IL_035b: Unknown result type (might be due to invalid IL or missing references)
			//IL_036a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0388: Unknown result type (might be due to invalid IL or missing references)
			//IL_038d: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a8: Unknown result type (might be due to invalid IL or missing references)
			if (owner.Sim.IsGrabbing() && (Object)(object)grabbed == (Object)null)
			{
				TryCatchGrabbedTarget();
			}
			if (owner.Sim.IsHoldingGrabbed() && (Object)(object)grabbed != (Object)null)
			{
				Vector3 val = owner.BodyCentre + owner.CameraForward * (owner.Scale * 0.9f) + Vector3.up * (owner.Scale * 0.12f);
				if (!grabbed.isKinematic)
				{
					grabbed.linearVelocity = Vector3.zero;
				}
				grabbed.MovePosition(val);
			}
			else if ((Object)(object)grabbed != (Object)null && !owner.Sim.IsHoldingGrabbed())
			{
				grabbed = null;
			}
			Vector3 val2;
			if (owner.Sim.IsAirKickDashing())
			{
				val2 = FisterUnits.DirToUnity(owner.Sim.AirKickDirection());
				Vector3 normalized = ((Vector3)(ref val2)).normalized;
				float range = Mathf.Max(owner.Scale * 1.35f, owner.Sim.AirKickSpeed() * owner.Scale * (1f / 60f) + owner.Scale * 0.55f);
				if (TryFindDamageTarget(owner.BodyCentre, normalized, range, owner.Scale * 0.65f, out var target, out var creature, out var point) && (((Object)(object)target != (Object)null && (Object)(object)target != (Object)(object)lastAirKickTarget) || ((Object)(object)creature != (Object)null && (Object)(object)creature != (Object)(object)lastAirKickCreature)))
				{
					lastAirKickTarget = target;
					lastAirKickCreature = creature;
					DamageCreature(creature, point, normalized, 50);
					Launch(target, normalized * (owner.Sim.AirKickSpeed() * owner.Scale) + Vector3.up * (3.5f * owner.Scale));
					FisterAudio.Play("criticalhit", point, 1f);
					owner.Sim.OnAirKickHit();
					owner.Animator.TriggerImpactFrame(0.07f);
					diveHit = true;
				}
			}
			else
			{
				lastAirKickTarget = null;
				lastAirKickCreature = null;
			}
			if (owner.Sim.IsOverchargeDashing())
			{
				val2 = FisterUnits.DirToUnity(owner.Sim.OverchargeDashDirection());
				Vector3 normalized2 = ((Vector3)(ref val2)).normalized;
				float range2 = owner.Sim.OverchargeDashSpeed() * owner.Scale * (1f / 60f) + owner.Scale * 0.7f;
				if (TryFindDamageTarget(owner.BodyCentre, normalized2, range2, owner.Scale * 0.65f, out var target2, out var creature2, out var point2) && (((Object)(object)target2 != (Object)null && affected.Add(target2)) || ((Object)(object)creature2 != (Object)null && damagedCreatures.Add(creature2))))
				{
					DamageCreature(creature2, point2, normalized2, RushingDamage());
					Launch(target2, normalized2 * (owner.Sim.OverchargeDashSpeed() * owner.Scale) + Vector3.up * (4f * owner.Scale));
					owner.Sim.OnRailingHit(flatten: false);
				}
			}
		}

		internal void UpdateAirKickLockCandidate()
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: 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_005d: 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_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_0082: 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)
			if (owner.Sim.Charge() < 1f || !owner.Sim.IsAirborneForFullChargePunch())
			{
				airKickLockCandidate = null;
				owner.Sim.SetAirKickLockCandidate(onTarget: false);
				return;
			}
			Vector3 point = owner.CameraForward;
			Vector3 normalized = ((Vector3)(ref point)).normalized;
			Vector3 origin = owner.BodyCentre + Vector3.up * (owner.Scale * 0.9f);
			float range = owner.Scale * 192f;
			if (TryFindTarget(origin, normalized, range, owner.Scale * 1.2f, out var target, out point))
			{
				owner.Sim.SetAirKickLockCandidate((Object)(object)target == (Object)(object)airKickLockCandidate);
				airKickLockCandidate = target;
			}
			else
			{
				owner.Sim.SetAirKickLockCandidate(onTarget: false);
				airKickLockCandidate = null;
			}
		}

		private void HandleEvent(Event e)
		{
			//IL_0011: 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_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: 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_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: 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_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0338: Unknown result type (might be due to invalid IL or missing references)
			//IL_034e: Unknown result type (might be due to invalid IL or missing references)
			//IL_038b: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_047f: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_052a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0564: Unknown result type (might be due to invalid IL or missing references)
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0311: Unknown result type (might be due to invalid IL or missing references)
			//IL_0429: Unknown result type (might be due to invalid IL or missing references)
			//IL_042e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0432: Unknown result type (might be due to invalid IL or missing references)
			//IL_0437: Unknown result type (might be due to invalid IL or missing references)
			//IL_057e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0458: Unknown result type (might be due to invalid IL or missing references)
			//IL_046c: Unknown result type (might be due to invalid IL or missing references)
			//IL_05dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_05bd: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = FisterUnits.PosToUnity(e.position, owner.Scale);
			Vector3 val2;
			switch (e.type)
			{
			case EventType.ChargeReady:
				FisterAudio.Play("reload", owner.BodyCentre, 0.75f);
				owner.Animator.TriggerChargeReady();
				break;
			case EventType.PunchThrown:
				FisterAudio.PlayPunch(owner.BodyCentre);
				owner.Animator.TriggerPunch(e.strength, owner.Pitch);
				ResolvePunch(e);
				break;
			case EventType.DiveStart:
				diveHit = false;
				break;
			case EventType.DiveImpact:
			case EventType.DiveObstacle:
			{
				bool flag = Shockwave(val, owner.Scale * (4f + 4f * Mathf.Clamp01(e.value)), owner.Scale * (8f + 12f * e.value), 35);
				FisterAudio.Play("crack", val, Mathf.Clamp(0.8f + 0.4f * e.value, 0f, 1.2f));
				diveHit |= flag;
				owner.Sim.ResolveDiveImpact(diveHit);
				owner.Animator.TriggerImpactFrame(0.08f);
				break;
			}
			case EventType.AirKickStart:
			{
				lastAirKickTarget = null;
				lastAirKickCreature = null;
				val2 = FisterUnits.DirToUnity(e.direction);
				Vector3 normalized = ((Vector3)(ref val2)).normalized;
				if (TryFindTarget(owner.BodyCentre, normalized, owner.Scale * 3f, owner.Scale * 0.75f, out var _, out var point))
				{
					owner.Sim.SetAirKickHomingTarget(valid: true, FisterUnits.PosToSim(point, owner.Scale));
					lastAirKickTarget = null;
				}
				break;
			}
			case EventType.AirKickWhiff:
				owner.Animator.TriggerImpactFrame(0.05f);
				break;
			case EventType.RailingStart:
				affected.Clear();
				railingChargeProgress = Mathf.Clamp01(e.strength);
				FisterAudio.Play("overcharge-dash-screech", owner.BodyCentre, 1.2f);
				break;
			case EventType.RailingBounce:
				Shockwave(val, owner.Scale * 2.5f, owner.Scale * Mathf.Max(5f, e.value * 0.3f), RushingDamage());
				FisterAudio.Play("crack", val, 1f, 0.9f);
				if (e.flag)
				{
					FisterAudio.Play("criticalhit", val, 1f);
				}
				break;
			case EventType.RailingMegaBoost:
				affected.Clear();
				FisterAudio.Play("railing-sonic-boom", owner.BodyCentre, 1f);
				break;
			case EventType.GroundPunchHop:
				Shockwave(val, owner.Scale * 3f, owner.Scale * (5f + 7f * e.strength), 35);
				FisterAudio.Play("crack", val, 0.8f + 0.4f * Mathf.Clamp01(e.strength));
				break;
			case EventType.ParrySuccess:
				FisterAudio.Play("parry-success", owner.BodyCentre, 1.8f);
				owner.Animator.TriggerImpactFrame(0.08f);
				break;
			case EventType.GrabStart:
				FisterAudio.Play("grab-lunge", owner.BodyCentre, 0.8f);
				TryCatchGrabbedTarget();
				break;
			case EventType.GrabMiss:
			case EventType.GrabCancel:
				grabbed = null;
				break;
			case EventType.GrabThrow:
				if ((Object)(object)grabbed != (Object)null)
				{
					val2 = FisterUnits.DirToUnity(e.direction);
					Vector3 normalized2 = ((Vector3)(ref val2)).normalized;
					if (grabbed.isKinematic)
					{
						grabbed.isKinematic = false;
					}
					Launch(grabbed, normalized2 * (e.value * owner.Scale));
					grabbed = null;
				}
				break;
			case EventType.PiledriverImpact:
				Shockwave(val, owner.Scale * 7f, owner.Scale * (8f + 10f * e.value), 35);
				FisterAudio.Play("crack", val, Mathf.Clamp(0.8f + 0.4f * e.value, 0f, 1.2f));
				break;
			case EventType.OverchargeExplode:
				Shockwave(owner.BodyCentre, owner.Scale * 7.5f, owner.Scale * 22f, 35);
				FisterAudio.Play("explode", owner.BodyCentre, 1f);
				owner.Animator.TriggerImpactFrame(0.09f);
				owner.ApplySelfDamage(200f, owner.BodyCentre);
				break;
			case EventType.RagdollImpact:
			case EventType.SelfDamage:
				if (e.type == EventType.RagdollImpact)
				{
					FisterAudio.Play("crack", val, Mathf.Min(1f, 0.3f + e.value / 20f));
				}
				if (e.value >= 2f)
				{
					FisterAudio.Play("damage-taken", owner.BodyCentre, 0.8f);
				}
				owner.ApplySelfDamage(e.value, val);
				break;
			case EventType.AirKickStop:
				lastAirKickTarget = null;
				lastAirKickCreature = null;
				break;
			case EventType.Ragdoll:
				grabbed = null;
				break;
			case EventType.RocketPunchLaunch:
			case EventType.RailingStop:
			case EventType.ParryStart:
			case EventType.ParryEndlag:
			case EventType.SlideStart:
			case EventType.SlideStop:
			case EventType.AirTech:
			case EventType.Flip:
			case EventType.OverchargeWarning:
			case EventType.Recover:
				break;
			}
		}

		private void ResolvePunch(Event e)
		{
			//IL_0006: 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_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0091: 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_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0279: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: 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_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = FisterUnits.DirToUnity(e.direction);
			Vector3 normalized = ((Vector3)(ref val)).normalized;
			float num = Mathf.Clamp01(e.strength);
			float num2 = owner.Scale * ((e.kind == 2) ? 7.5f : 5.5f);
			float radius = owner.Scale * ((e.kind == 2) ? 0.8f : 0.6f);
			Vector3 val2 = FisterUnits.PosToUnity(e.position, owner.Scale) + Vector3.up * (owner.Scale * 0.18f);
			RaycastHit val4 = default(RaycastHit);
			if (TryFindDamageTarget(val2, normalized, num2, radius, out var target, out var creature, out var point))
			{
				float volume = Mathf.Max((0.5f + 0.5f * num) * 0.6f, Mathf.Min(1f, 0.3f + 0.45f * num));
				float num3 = 8f + 34f * num;
				Vector3 val3 = normalized * (num3 * owner.Scale);
				if (e.flag)
				{
					val3.y = Mathf.Max(val3.y, owner.Scale * (9f + 18f * num));
				}
				if (e.kind == 2)
				{
					val3 *= 1.35f;
				}
				DamageCreature(creature, point, normalized, PunchDamage(e.value));
				Launch(target, val3);
				FisterAudio.Play("crack", point, volume);
				if (e.critical)
				{
					FisterAudio.Play("criticalhit", point, 1f);
				}
				if (e.flag && point.y > owner.BodyCentre.y + owner.Scale * 0.5f)
				{
					FisterAudio.Play("successful-100-punch", point, 1f);
				}
				if (num >= 0.95f)
				{
					owner.Sim.GrantInstantPunchCharge();
				}
				owner.Animator.TriggerImpactFrame(0.07f);
			}
			else if (Physics.Raycast(val2, normalized, ref val4, num2, -1, (QueryTriggerInteraction)1) && !owner.IsOwnCollider(((RaycastHit)(ref val4)).collider))
			{
				float volume2 = Mathf.Max((0.5f + 0.5f * num) * 0.6f, Mathf.Min(1f, 0.3f + 0.45f * num));
				FisterAudio.Play("crack", ((RaycastHit)(ref val4)).point, volume2);
				owner.Sim.ApplyWallPunchRecoil(num);
				owner.Animator.TriggerImpactFrame(0.045f);
			}
		}

		private bool Shockwave(Vector3 centre, float radius, float speed, int damageScale)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: 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_0098: 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_00a0: 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_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: 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_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_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: 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_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			int num = Physics.OverlapSphereNonAlloc(centre, radius, overlapHits, -1, (QueryTriggerInteraction)1);
			affected.Clear();
			damagedCreatures.Clear();
			bool result = false;
			for (int i = 0; i < num; i++)
			{
				Collider val = overlapHits[i];
				if ((Object)(object)val == (Object)null || owner.IsOwnCollider(val) || owner.IsPlayerCollider(val))
				{
					continue;
				}
				Rigidbody attachedRigidbody = val.attachedRigidbody;
				Component val2 = FindCreature(val);
				if ((Object)(object)val2 != (Object)null && damagedCreatures.Add(val2))
				{
					Vector3 val3 = val.ClosestPoint(centre);
					Vector3 val4 = val3 - centre;
					if (((Vector3)(ref val4)).sqrMagnitude < 0.001f)
					{
						val4 = Vector3.up;
					}
					DamageCreature(val2, val3, ((Vector3)(ref val4)).normalized, damageScale);
					result = true;
				}
				if (!((Object)(object)attachedRigidbody == (Object)null) && !((Object)(object)attachedRigidbody == (Object)(object)owner.Rigidbody) && !attachedRigidbody.isKinematic && affected.Add(attachedRigidbody))
				{
					Vector3 val5 = attachedRigidbody.worldCenterOfMass - centre;
					if (((Vector3)(ref val5)).sqrMagnitude < 0.001f)
					{
						val5 = Vector3.up;
					}
					Vector3 velocity = ((Vector3)(ref val5)).normalized * speed + Vector3.up * speed * 0.28f;
					Launch(attachedRigidbody, velocity);
					result = true;
				}
			}
			return result;
		}

		private bool TryFindDamageTarget(Vector3 origin, Vector3 direction, float range, float radius, out Rigidbody target, out Component creature, out Vector3 point)
		{
			//IL_000a: 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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: 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_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			target = null;
			creature = null;
			point = origin;
			direction = ((((Vector3)(ref direction)).sqrMagnitude > 0.001f) ? ((Vector3)(ref direction)).normalized : owner.CameraForward);
			int num = Physics.SphereCastNonAlloc(origin, Mathf.Max(0.02f, radius), direction, castHits, range, -1, (QueryTriggerInteraction)1);
			float num2 = float.MaxValue;
			for (int i = 0; i < num; i++)
			{
				RaycastHit val = castHits[i];
				Collider collider = ((RaycastHit)(ref val)).collider;
				if ((Object)(object)collider == (Object)null || owner.IsOwnCollider(collider) || owner.IsPlayerCollider(collider))
				{
					continue;
				}
				Rigidbody attachedRigidbody = collider.attachedRigidbody;
				Component val2 = FindCreature(collider);
				if ((!((Object)(object)attachedRigidbody == (Object)null) && !((Object)(object)attachedRigidbody == (Object)(object)owner.Rigidbody) && !attachedRigidbody.isKinematic) || !((Object)(object)val2 == (Object)null))
				{
					Vector3 point2 = ((RaycastHit)(ref val)).point;
					float distance = ((RaycastHit)(ref val)).distance;
					if (distance < num2)
					{
						num2 = distance;
						target = (((Object)(object)attachedRigidbody == (Object)(object)owner.Rigidbody) ? null : attachedRigidbody);
						creature = val2;
						point = point2;
					}
				}
			}
			if (!((Object)(object)target != (Object)null))
			{
				return (Object)(object)creature != (Object)null;
			}
			return true;
		}

		private bool TryFindTarget(Vector3 origin, Vector3 direction, float range, float radius, out Rigidbody target, out Vector3 point)
		{
			//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)
			if (TryFindDamageTarget(origin, direction, range, radius, out target, out var _, out point))
			{
				return (Object)(object)target != (Object)null;
			}
			return false;
		}

		private bool TryCatchGrabbedTarget()
		{
			//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_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_0083: 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_008c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)grabbed != (Object)null || !owner.Sim.IsGrabbing())
			{
				return (Object)(object)grabbed != (Object)null;
			}
			float range = owner.Scale * (owner.Sim.GrabStartedAirborne() ? 4.75f : 4f);
			Vector3 origin = owner.BodyCentre + Vector3.up * (owner.Scale * 0.25f);
			if (!TryFindGrabTarget(origin, owner.CameraForward, range, owner.Scale * 0.85f, out var target))
			{
				return false;
			}
			grabbed = target;
			owner.Sim.OnGrabCaught();
			return true;
		}

		private bool TryFindGrabTarget(Vector3 origin, Vector3 direction, float range, float radius, out Rigidbody target)
		{
			//IL_0021: 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_0026: 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_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			target = null;
			direction = ((((Vector3)(ref direction)).sqrMagnitude > 0.001f) ? ((Vector3)(ref direction)).normalized : owner.CameraForward);
			int num = Physics.SphereCastNonAlloc(origin, Mathf.Max(0.03f, radius), direction, castHits, range, -1, (QueryTriggerInteraction)2);
			float num2 = float.MaxValue;
			for (int i = 0; i < num; i++)
			{
				RaycastHit val = castHits[i];
				Collider collider = ((RaycastHit)(ref val)).collider;
				if (!((Object)(object)collider == (Object)null) && !owner.IsOwnCollider(collider) && !owner.IsPlayerCollider(collider))
				{
					Rigidbody attachedRigidbody = collider.attachedRigidbody;
					if (!((Object)(object)attachedRigidbody == (Object)null) && !((Object)(object)attachedRigidbody == (Object)(object)owner.Rigidbody) && ((RaycastHit)(ref val)).distance < num2)
					{
						num2 = ((RaycastHit)(ref val)).distance;
						target = attachedRigidbody;
					}
				}
			}
			return (Object)(object)target != (Object)null;
		}

		private static int PunchDamage(float chargeTime)
		{
			float num = Mathf.Max(0f, chargeTime);
			float num2 = Mathf.Clamp01(num / 1f);
			float num3 = Mathf.Clamp01((num - 1f) / Mathf.Max(0.01f, 8f));
			return 15 + Mathf.RoundToInt(35f * num2) + Mathf.RoundToInt(50f * num3);
		}

		private int RushingDamage()
		{
			return 35 + Mathf.RoundToInt(65f * railingChargeProgress);
		}

		private static Component FindCreature(Collider collider)
		{
			if (!(CreatureType != null))
			{
				return null;
			}
			return ((Component)collider).GetComponentInParent(CreatureType);
		}

		private static MethodInfo FindMethod(Type type, string name, int parameterCount)
		{
			if (type == null)
			{
				return null;
			}
			MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (MethodInfo methodInfo in methods)
			{
				if (methodInfo.Name == name && methodInfo.GetParameters().Length == parameterCount)
				{
					return methodInfo;
				}
			}
			return null;
		}

		private void DamageCreature(Component creature, Vector3 point, Vector3 direction, int damage)
		{
			//IL_007c: 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_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: 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_00b7: 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_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: 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_020a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)creature == (Object)null || CreatureType == null || (Object)(object)owner.Player == (Object)null)
			{
				return;
			}
			try
			{
				PropertyInfo property = CreatureType.GetProperty("IsDead", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (property != null && property.PropertyType == typeof(bool) && (bool)property.GetValue(creature))
				{
					return;
				}
				damage = Mathf.Max(1, damage);
				Vector3 val = ((Vector3)(ref direction)).normalized * (24f * owner.Scale) + Vector3.up * (5f * owner.Scale);
				object obj = CreatureType.GetProperty("Owner", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(creature);
				bool flag = obj != null && (bool)(obj.GetType().GetProperty("IsLocalClient")?.GetValue(obj) ?? ((object)false));
				if (CreatureLocalHit != null)
				{
					CreatureLocalHit.Invoke(creature, new object[10]
					{
						creature.transform,
						point,
						((Vector3)(ref direction)).normalized,
						owner.Player,
						damage,
						false,
						val,
						false,
						false,
						false
					});
					if (flag)
					{
						return;
					}
				}
				object obj2 = ServerType?.GetProperty("Instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null);
				if (obj2 != null && ServerHitCreature != null)
				{
					ServerHitCreature.Invoke(obj2, new object[5]
					{
						creature,
						owner.Player,
						damage,
						point,
						((Vector3)(ref direction)).normalized
					});
				}
			}
			catch (Exception ex)
			{
				FisterPlugin.Log.LogWarning((object)("Could not apply Fister hit to fish: " + ex.GetBaseException().Message));
			}
		}

		private static void Launch(Rigidbody target, Vector3 velocity)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)target != (Object)null && !target.isKinematic)
			{
				target.AddForce(velocity, (ForceMode)2);
			}
		}
	}
	internal sealed class FisterController : MonoBehaviour
	{
		private const float SimulationDt = 1f / 60f;

		private const float CameraDistance = 6f;

		private const float CameraTargetHeight = 1.45f;

		private const float InteractionHeadHeight = 1.45f;

		private const float StepHeight = 1.1f;

		private static readonly FieldInfo GroundedField = MovementField("<Grounded>k__BackingField");

		private static readonly FieldInfo SprintingField = MovementField("<Sprinting>k__BackingField");

		private static readonly FieldInfo VelocityField = MovementField("<Velocity>k__BackingField");

		private static readonly FieldInfo VelocityMagnitudeField = MovementField("<VelMagSqr>k__BackingField");

		private static readonly FieldInfo FeetField = MovementField("<CurFeetWorldPos>k__BackingField");

		private static readonly FieldInfo OriginalCapsuleHeightField = MovementField("_origColHeight");

		private static readonly FieldInfo MaximumHealthField = typeof(PlayerVitals).GetField("_maxHealth", BindingFlags.Instance | BindingFlags.NonPublic);

		private static readonly MethodInfo UnderwaterCheck = typeof(PlayerMovement).GetMethod("UnderWaterCheck", BindingFlags.Instance | BindingFlags.NonPublic);

		private readonly Dictionary<Renderer, bool> rendererStates = new Dictionary<Renderer, bool>();

		private readonly List<Vector3> contactNormals = new List<Vector3>(8);

		private readonly List<Vector3> contactPoints = new List<Vector3>(8);

		private readonly RaycastHit[] groundHits = (RaycastHit[])(object)new RaycastHit[48];

		private readonly RaycastHit[] travelHits = (RaycastHit[])(object)new RaycastHit[48];

		private readonly Sim sim = new Sim();

		private readonly Buttons buttons = new Buttons();

		private readonly PoseAnimator animator = new PoseAnimator();

		private FisterCombat combat;

		private Player player;

		private PlayerMovement movement;

		private Rigidbody bodyRigidbody;

		private CapsuleCollider capsule;

		private PlayerCamera playerCamera;

		private ContactProbe contactProbe;

		private BodyRenderer bodyRenderer;

		private Pose pose;

		private SimEnvironment lastEnvironment = new SimEnvironment();

		private Vector3 blockedNormal;

		private bool hasBlockedNormal;

		private bool stepUp;

		private bool modeEnabled = true;

		private bool active;

		private bool warnedMissingBody;

		private bool waitForCombatButtonsToRelease;

		private bool fisterAbilitiesBlocked;

		private bool savedUseGravity;

		private bool savedViewBob;

		private bool haveSavedViewBob;

		private float savedCapsuleHeight;

		private Vector3 savedCapsuleCenter;

		private bool changedCapsuleShape;

		private Vector3 waterHeadLocalOffset;

		private bool hasWaterHeadOffset;

		private float accumulator;

		private float animationTime;

		private float yaw;

		private float pitch;

		private float scale = 1f;

		private double clock;

		private int lastToggleFrame = -1;

		internal Sim Sim => sim;

		internal PoseAnimator Animator => animator;

		internal Player Player => player;

		internal bool HasHeldItem
		{
			get
			{
				if ((Object)(object)player != (Object)null && (Object)(object)player.Holding != (Object)null)
				{
					return (Object)(object)player.Holding.HeldItem != (Object)null;
				}
				return false;
			}
		}

		internal Rigidbody Rigidbody => bodyRigidbody;

		internal float Scale => scale;

		internal float Pitch => pitch;

		internal Vector3 InteractionOrigin => Feet + Vector3.up * (1.45f * scale);

		internal Vector3 Feet
		{
			get
			{
				//IL_0034: Unknown result type (might be due to invalid IL or missing references)
				//IL_0039: Unknown result type (might be due to invalid IL or missing references)
				//IL_003c: 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_0054: 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_0069: 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)
				//IL_0076: 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_001c: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)capsule != (Object)null))
				{
					if (!((Object)(object)bodyRigidbody != (Object)null))
					{
						return Vector3.zero;
					}
					return bodyRigidbody.position;
				}
				Bounds bounds = ((Collider)capsule).bounds;
				float x = ((Bounds)(ref bounds)).center.x;
				bounds = ((Collider)capsule).bounds;
				float y = ((Bounds)(ref bounds)).min.y;
				bounds = ((Collider)capsule).bounds;
				return new Vector3(x, y, ((Bounds)(ref bounds)).center.z);
			}
		}

		internal Vector3 BodyCentre => Feet + Vector3.up * (0.8f * scale);

		internal Vector3 CameraForward
		{
			get
			{
				//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_0064: 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_0058: 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_0041: 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)
				Transform val = (((Object)(object)playerCamera != (Object)null) ? playerCamera.CamTransform : null);
				if ((Object)(object)val != (Object)null)
				{
					Vector3 forward = val.forward;
					if (((Vector3)(ref forward)).sqrMagnitude > 0.001f)
					{
						forward = val.forward;
						return ((Vector3)(ref forward)).normalized;
					}
				}
				if (!((Object)(object)player != (Object)null))
				{
					return Vector3.forward;
				}
				return player.CurPlayerRot * Vector3.forward;
			}
		}

		private void Awake()
		{
			combat = new FisterCombat(this);
		}

		private void Start()
		{
			FisterAudio.Initialize((MonoBehaviour)(object)this, FisterPlugin.PluginDir);
		}

		private static FieldInfo MovementField(string name)
		{
			return typeof(PlayerMovement).GetField(name, BindingFlags.Instance | BindingFlags.NonPublic);
		}

		private void Update()
		{
			Keyboard current = Keyboard.current;
			if (current != null && ((ButtonControl)current.f8Key).wasPressedThisFrame && lastToggleFrame != Time.frameCount)
			{
				lastToggleFrame = Time.frameCount;
				modeEnabled = !modeEnabled;
			}
			Player localPlayer = Player.LocalPlayer;
			if (player != localPlayer)
			{
				ExitMode();
				player = localPlayer;
				BindPlayerParts();
			}
			if (modeEnabled && IsReadyForFister())
			{
				if (!active)
				{
					EnterMode();
				}
				HidePlayerRenderers();
				SampleInput();
				FisterSounds.Update(sim, this);
				return;
			}
			if (active)
			{
				ExitMode();
			}
			buttons.Update(fist: false, parry: false, grab: false, Time.timeAsDouble);
			FisterSounds.Stop();
			if (bodyRenderer != null)
			{
				bodyRenderer.Visible = false;
			}
		}

		private void BindPlayerParts()
		{
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: 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)
			movement = (((Object)(object)player != (Object)null) ? player.Movement : null);
			bodyRigidbody = (((Object)(object)player != (Object)null) ? player.Rigidbody : null);
			playerCamera = (((Object)(object)player != (Object)null) ? player.Camera : null);
			capsule = (((Object)(object)movement != (Object)null) ? ((Component)movement).GetComponent<CapsuleCollider>() : null);
			if ((Object)(object)capsule == (Object)null && (Object)(object)player != (Object)null)
			{
				capsule = ((Component)player).GetComponentInChildren<CapsuleCollider>(true);
			}
			hasWaterHeadOffset = (Object)(object)player != (Object)null && (Object)(object)player.Transform != (Object)null && (Object)(object)player.CamObject != (Object)null;
			if (hasWaterHeadOffset)
			{
				waterHeadLocalOffset = player.Transform.InverseTransformPoint(player.CamObject.position);
			}
		}

		private bool IsReadyForFister()
		{
			if ((Object)(object)player == (Object)null || (Object)(object)movement == (Object)null || !((Behaviour)movement).isActiveAndEnabled || (Object)(object)bodyRigidbody == (Object)null || (Object)(object)capsule == (Object)null)
			{
				return false;
			}
			if (Player.LocalPlayerEnabled)
			{
				return !movement.OnBoat;
			}
			return false;
		}

		private void EnterMode()
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: 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_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null || (Object)(object)bodyRigidbody == (Object)null)
			{
				return;
			}
			active = true;
			savedUseGravity = bodyRigidbody.useGravity;
			bodyRigidbody.useGravity = false;
			savedCapsuleHeight = capsule.height;
			savedCapsuleCenter = capsule.center;
			changedCapsuleShape = false;
			if (OriginalCapsuleHeightField != null)
			{
				float num = (float)OriginalCapsuleHeightField.GetValue(movement);
				if (num > capsule.height + 0.01f)
				{
					capsule.height = num;
					CapsuleCollider obj = capsule;
					obj.center += Vector3.up * ((num - savedCapsuleHeight) * 0.5f);
					changedCapsuleShape = true;
				}
			}
			scale = FisterUnits.Scale(capsule);
			sim.Reset();
			animator.Reset();
			combat.Reset();
			FisterSounds.Reset();
			accumulator = 0f;
			animationTime = 0f;
			clock = Time.timeAsDouble;
			lastEnvironment = new SimEnvironment();
			blockedNormal = Vector3.zero;
			hasBlockedNormal = false;
			contactProbe = ((Component)movement).GetComponent<ContactProbe>() ?? ((Component)movement).gameObject.AddComponent<ContactProbe>();
			if ((Object)(object)playerCamera != (Object)null)
			{
				FieldInfo field = typeof(PlayerCamera).GetField("_viewBobbingEnabled", BindingFlags.Instance | BindingFlags.NonPublic);
				if (field != null && field.FieldType == typeof(bool))
				{
					savedViewBob = (bool)field.GetValue(playerCamera);
					haveSavedViewBob = true;
				}
				PlayerCamera.SetViewBobbing(false);
			}
			HidePlayerRenderers();
			FisterPlugin.Log.LogInfo((object)"John Fister mode enabled locally. LMB fist/charge, RMB parry, G grab; F8 restores How to Fish.");
		}

		private void ExitMode()
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			if (!active)
			{
				RestorePlayerRenderers();
				if (bodyRenderer != null)
				{
					bodyRenderer.Visible = false;
				}
				return;
			}
			active = false;
			FisterSounds.Stop();
			if ((Object)(object)bodyRigidbody != (Object)null)
			{
				bodyRigidbody.useGravity = savedUseGravity;
			}
			if ((Object)(object)capsule != (Object)null && changedCapsuleShape)
			{
				capsule.height = savedCapsuleHeight;
				capsule.center = savedCapsuleCenter;
			}
			changedCapsuleShape = false;
			if ((Object)(object)playerCamera != (Object)null && haveSavedViewBob)
			{
				PlayerCamera.SetViewBobbing(savedViewBob);
			}
			haveSavedViewBob = false;
			RestorePlayerRenderers();
			if (bodyRenderer != null)
			{
				bodyRenderer.Visible = false;
			}
			FisterPlugin.Log.LogInfo((object)"John Fister mode disabled; How to Fish movement and visuals restored.");
		}

		private void HidePlayerRenderers()
		{
			if ((Object)(object)player == (Object)null)
			{
				return;
			}
			Renderer[] componentsInChildren = ((Component)player).GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null))
				{
					if (!rendererStates.ContainsKey(val))
					{
						rendererStates.Add(val, val.enabled);
					}
					val.enabled = false;
				}
			}
		}

		private void RestorePlayerRenderers()
		{
			foreach (KeyValuePair<Renderer, bool> rendererState in rendererStates)
			{
				if ((Object)(object)rendererState.Key != (Object)null)
				{
					rendererState.Key.enabled = rendererState.Value;
				}
			}
			rendererStates.Clear();
		}

		private void SampleInput()
		{
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: 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)
			bool flag = (Object)(object)player != (Object)null && !player.BlockInputs;
			Mouse current = Mouse.current;
			Keyboard current2 = Keyboard.current;
			bool hasHeldItem = HasHeldItem;
			bool flag2 = (current == null || (!current.leftButton.isPressed && !current.rightButton.isPressed)) && (current2 == null || !((ButtonControl)current2.gKey).isPressed);
			if (hasHeldItem)
			{
				waitForCombatButtonsToRelease = true;
			}
			else if (waitForCombatButtonsToRelease && flag2)
			{
				waitForCombatButtonsToRelease = false;
			}
			fisterAbilitiesBlocked = hasHeldItem || waitForCombatButtonsToRelease;
			if (fisterAbilitiesBlocked)
			{
				buttons.BlockForItemUse();
			}
			else
			{
				bool fist = flag && current != null && current.leftButton.isPressed;
				bool parry = flag && current != null && current.rightButton.isPressed;
				bool grab = flag && current2 != null && ((ButtonControl)current2.gKey).isPressed;
				buttons.Update(fist, parry, grab, Time.timeAsDouble);
			}
			Vector3 cameraForward = CameraForward;
			if (((Vector3)(ref cameraForward)).sqrMagnitude > 0.001f)
			{
				yaw = Mathf.Atan2(cameraForward.x, cameraForward.z);
				pitch = Mathf.Asin(Mathf.Clamp(cameraForward.y, -1f, 1f));
			}
		}

		internal bool FixedStepIfOwned(PlayerMovement target)
		{
			if (!Owns(target))
			{
				return false;
			}
			try
			{
				bodyRigidbody.WakeUp();
				bodyRigidbody.useGravity = false;
				contactProbe = ((Component)movement).GetComponent<ContactProbe>() ?? ((Component)movement).gameObject.AddComponent<ContactProbe>();
				contactProbe.Consume(contactNormals, contactPoints);
				UpdateBlockedContact();
				accumulator += Mathf.Min(Time.fixedDeltaTime, 0.1f);
				int num = 0;
				while (accumulator >= 0.016665667f && num < 4)
				{
					SimTick();
					accumulator -= 1f / 60f;
					num++;
				}
				if (num >= 4)
				{
					accumulator = 0f;
				}
				ApplyVelocity();
				UnderwaterCheck?.Invoke(movement, null);
				return true;
			}
			catch (Exception ex)
			{
				FisterPlugin.Log.LogError((object)("Fister movement update failed; handing control back to How to Fish: " + ex));
				modeEnabled = false;
				ExitMode();
				return false;
			}
		}

		internal bool Owns(PlayerMovement target)
		{
			if (active && (Object)(object)target != (Object)null && target == movement && (Object)(object)player != (Object)null && player.Movement == target && !target.OnBoat)
			{
				return (Object)(object)bodyRigidbody != (Object)null;
			}
			return false;
		}

		internal bool TryGetPhysicalWaterHead(PlayerMovement target, out Transform cameraTransform, out Vector3 savedCameraPosition, out Vector3 physicalHeadPosition)
		{
			//IL_0004: 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_0010: 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_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_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)
			cameraTransform = null;
			savedCameraPosition = Vector3.zero;
			physicalHeadPosition = Vector3.zero;
			if (!Owns(target) || !hasWaterHeadOffset || (Object)(object)player.Transform == (Object)null || (Object)(object)player.CamObject == (Object)null)
			{
				return false;
			}
			cameraTransform = player.CamObject;
			savedCameraPosition = cameraTransform.position;
			physicalHeadPosition = player.Transform.TransformPoint(waterHeadLocalOffset);
			return true;
		}

		internal bool Owns(Component target)
		{
			if (!active || (Object)(object)player == (Object)null || (Object)(object)target == (Object)null)
			{
				return false;
			}
			return target.GetComponentInParent<Player>() == player;
		}

		internal bool IsHeldItemComponent(Component target)
		{
			Item val = (((Object)(object)player != (Object)null && (Object)(object)player.Holding != (Object)null) ? player.Holding.HeldItem : null);
			if ((Object)(object)val != (Object)null)
			{
				if ((object)val != target && (object)val.FishingRod != target)
				{
					return (object)val.Weapon == target;
				}
				return true;
			}
			return false;
		}

		internal bool TryGetInteractionCamera(Component target, out Transform cameraTransform, out Vector3 savedCameraPosition, out Vector3 interactionPosition)
		{
			//IL_0004: 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_0010: 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_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			cameraTransform = null;
			savedCameraPosition = Vector3.zero;
			interactionPosition = Vector3.zero;
			if (!Owns(target) || (Object)(object)player.CamObject == (Object)null)
			{
				return false;
			}
			cameraTransform = player.CamObject;
			savedCameraPosition = cameraTransform.position;
			interactionPosition = InteractionOrigin;
			return true;
		}

		private void SimTick()
		{
			//IL_001c: 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_0088: 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)
			clock += 0.01666666753590107;
			Vector2 input = movement.Input;
			bool flag = (Object)(object)player != (Object)null && !player.BlockInputs;
			if (HasHeldItem)
			{
				waitForCombatButtonsToRelease = true;
				fisterAbilitiesBlocked = true;
				buttons.BlockForItemUse();
			}
			if (fisterAbilitiesBlocked)
			{
				sim.CancelAbilitiesForItemUse();
			}
			Input aInput = buttons.ToInput(yaw, pitch, input.x, input.y, flag, flag && !fisterAbilitiesBlocked);
			combat.UpdateAirKickLockCandidate();
			SimEnvironment aEnv = (lastEnvironment = BuildEnvironment());
			sim.Tick(aInput, aEnv);
			combat.HandleEvents();
			combat.Tick();
		}

		private void UpdateBlockedContact()
		{
			//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_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_0029: 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_003c: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			hasBlockedNormal = false;
			Vector3 val = FisterUnits.DirToUnity(sim.Velocity());
			for (int i = 0; i < contactNormals.Count; i++)
			{
				Vector3 val2 = contactNormals[i];
				if (Mathf.Abs(val2.y) < 0.7f && Vector3.Dot(val, val2) < -0.5f)
				{
					blockedNormal = val2;
					hasBlockedNormal = true;
					break;
				}
			}
		}

		private SimEnvironment BuildEnvironment()
		{
			//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_000e: 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_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: 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_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: 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_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02be: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0306: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0319: Unknown result type (might be due to invalid IL or missing references)
			//IL_031e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0531: Unknown result type (might be due to invalid IL or missing references)
			//IL_0537: Unknown result type (might be due to invalid IL or missing references)
			//IL_0391: Unknown result type (might be due to invalid IL or missing references)
			//IL_0551: Unknown result type (might be due to invalid IL or missing references)
			//IL_0373: Unknown result type (might be due to invalid IL or missing references)
			//IL_0375: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0429: Unknown result type (might be due to invalid IL or missing references)
			//IL_043a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0441: Unknown result type (might be due to invalid IL or missing references)
			//IL_0448: Unknown result type (might be due to invalid IL or missing references)
			//IL_044d: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_045f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0470: Unknown result type (might be due to invalid IL or missing references)
			//IL_0475: Unknown result type (might be due to invalid IL or missing references)
			//IL_0477: Unknown result type (might be due to invalid IL or missing references)
			//IL_0479: Unknown result type (might be due to invalid IL or missing references)
			//IL_047b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0480: Unknown result type (might be due to invalid IL or missing references)
			//IL_0482: Unknown result type (might be due to invalid IL or missing references)
			//IL_0484: Unknown result type (might be due to invalid IL or missing references)
			//IL_0494: Unknown result type (might be due to invalid IL or missing references)
			//IL_0496: Unknown result type (might be due to invalid IL or missing references)
			//IL_0498: Unknown result type (might be due to invalid IL or missing references)
			//IL_049d: Unknown result type (might be due to invalid IL or missing references)
			//IL_049f: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c4: Unknown result type (might be due to invalid IL or missing references)
			SimEnvironment simEnvironment = new SimEnvironment();
			Vector3 feet = Feet;
			simEnvironment.position = FisterUnits.BodyCentreFromFeet(feet, scale);
			simEnvironment.dead = (Object)(object)player != (Object)null && (Object)(object)player.Vitals != (Object)null && player.Vitals.Health <= 0;
			simEnvironment.gravity = -9.82f;
			float num = Mathf.Max(0.05f, capsule.radius * Mathf.Max(((Component)capsule).transform.lossyScale.x, ((Component)capsule).transform.lossyScale.z));
			int num2 = Physics.SphereCastNonAlloc(feet + Vector3.up * (num + 0.05f), num * 0.9f, Vector3.down, groundHits, 6f, -1, (QueryTriggerInteraction)1);
			float num3 = float.MaxValue;
			for (int i = 0; i < num2; i++)
			{
				RaycastHit val = groundHits[i];
				if (!((Object)(object)((RaycastHit)(ref val)).collider == (Object)null) && !IsOwnCollider(((RaycastHit)(ref val)).collider))
				{
					Rigidbody attachedRigidbody = ((RaycastHit)(ref val)).collider.attachedRigidbody;
					if ((!((Object)(object)attachedRigidbody != (Object)null) || attachedRigidbody.isKinematic) && ((RaycastHit)(ref val)).distance < num3)
					{
						num3 = ((RaycastHit)(ref val)).distance;
						simEnvironment.groundNormal = FisterUnits.DirToSim(((RaycastHit)(ref val)).normal);
					}
				}
			}
			if (num3 < float.MaxValue)
			{
				float num4 = Mathf.Max(0f, num3 - 0.05f - num * 0.1f);
				simEnvironment.groundClearance = num4 / scale;
				if (num4 < 0.12f * scale && simEnvironment.groundNormal.z >= 0.5f)
				{
					simEnvironment.groundSupport = true;
					simEnvironment.groundClearance = 0f;
				}
			}
			else
			{
				simEnvironment.groundClearance = 6f / scale;
			}
			stepUp = false;
			Vec3 vec = sim.Velocity();
			float num5 = vec.Length();
			if (num5 > 0.5f)
			{
				Vector3 val2 = FisterUnits.DirToUnity(vec) * scale;
				Vector3 normalized = ((Vector3)(ref val2)).normalized;
				float num6 = num5 * scale * (1f / 60f) * 2f + 0.05f;
				Vector3 val3 = ((Component)capsule).transform.TransformPoint(capsule.center);
				float num7 = Mathf.Max(0f, capsule.height * 0.5f - capsule.radius) * ((Component)capsule).transform.lossyScale.y;
				float num8 = Mathf.Max(0.05f, num * 0.95f);
				Vector3 val4 = val3 + Vector3.up * num7;
				Vector3 val5 = val3 - Vector3.up * num7;
				int num9 = Physics.CapsuleCastNonAlloc(val4, val5, num8, normalized, travelHits, num6, -1, (QueryTriggerInteraction)1);
				float num10 = float.MaxValue;
				RaycastHit val6 = default(RaycastHit);
				for (int j = 0; j < num9; j++)
				{
					RaycastHit val7 = travelHits[j];
					if (!((Object)(object)((RaycastHit)(ref val7)).collider == (Object)null) && !IsOwnCollider(((RaycastHit)(ref val7)).collider))
					{
						Rigidbody attachedRigidbody2 = ((RaycastHit)(ref val7)).collider.attachedRigidbody;
						if ((!((Object)(object)attachedRigidbody2 != (Object)null) || attachedRigidbody2.isKinematic) && ((RaycastHit)(ref val7)).distance < num10)
						{
							num10 = ((RaycastHit)(ref val7)).distance;
							val6 = val7;
						}
					}
				}
				if (num10 < float.MaxValue)
				{
					bool flag = Mathf.Abs(((RaycastHit)(ref val6)).normal.y) < 0.7f;
					bool flag2 = simEnvironment.groundSupport || sim.IsGrounded();
					Vector2 val8;
					int num11;
					if (!flag && ((RaycastHit)(ref val6)).normal.y > 0f && flag2)
					{
						float y = val2.y;
						val8 = new Vector2(val2.x, val2.z);
						num11 = ((y <= 0.5f * ((Vector2)(ref val8)).magnitude + 0.01f) ? 1 : 0);
					}
					else
					{
						num11 = 0;
					}
					bool flag3 = (byte)num11 != 0;
					if (!flag3 && flag && flag2)
					{
						float num12 = Mathf.Abs(val2.y);
						val8 = new Vector2(val2.x, val2.z);
						if (num12 < 0.5f * ((Vector2)(ref val8)).magnitude + 0.01f)
						{
							Vector3 val9 = Vector3.up * (1.1f * scale);
							if (!Physics.CheckCapsule(val4 + val9, val5 + val9, num8, -1, (QueryTriggerInteraction)1))
							{
								Vector3 val10 = val4 + val9;
								Vector3 val11 = val5 + val9;
								Vector3 val12 = new Vector3(normalized.x, 0f, normalized.z);
								if (!Physics.CapsuleCast(val10, val11, num8, ((Vector3)(ref val12)).normalized, num6, -1, (QueryTriggerInteraction)1))
								{
									flag3 = true;
									stepUp = true;
								}
							}
						}
					}
					if (!flag3)
					{
						simEnvironment.contact = true;
						simEnvironment.contactNormal = FisterUnits.DirToSim(((RaycastHit)(ref val6)).normal);
						simEnvironment.contactPoint = FisterUnits.PosToSim(((RaycastHit)(ref val6)).point, scale);
					}
				}
			}
			if (!simEnvironment.contact && hasBlockedNormal && num5 > 0.5f && Vector3.Dot(FisterUnits.DirToUnity(vec), blockedNormal) < 0f)
			{
				simEnvironment.contact = true;
				simEnvironment.contactNormal = FisterUnits.DirToSim(blockedNormal);
				simEnvironment.contactPoint = simEnvironment.position.Sub(new Vec3(simEnvironment.contactNormal.x * num / scale, simEnvironment.contactNormal.y * num / scale, 0f));
			}
			return simEnvironment;
		}

		private void ApplyVelocity()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: 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_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: 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_00ea: 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_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_02de: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: 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_01e2: 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_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = FisterUnits.DirToUnity((sim.HitFreezeTimer() > 0f) ? new Vec3() : sim.Velocity()) * scale;
			if (sim.IsGrounded() && lastEnvironment.groundSupport && val.y <= 0.01f)
			{
				Vector3 val2 = FisterUnits.DirToUnity(lastEnvironment.groundNormal);
				if (val2.y > 0.5f)
				{
					val = Vector3.ProjectOnPlane(val, val2);
				}
				val.y -= 2f * scale;
			}
			if (stepUp)
			{
				stepUp = false;
				Vector3 val3 = default(Vector3);
				((Vector3)(ref val3))..ctor(val.x, 0f, val.z);
				if (((Vector3)(ref val3)).sqrMagnitude > 0.01f)
				{
					float num = capsule.radius * Mathf.Max(((Component)capsule).transform.lossyScale.x, ((Component)capsule).transform.lossyScale.z);
					Vector3 val4 = ((Component)capsule).transform.TransformPoint(capsule.center);
					float num2 = Mathf.Max(0f, capsule.height * 0.5f - capsule.radius) * ((Component)capsule).transform.lossyScale.y;
					RaycastHit val5 = default(RaycastHit);
					if (Physics.Raycast(val4 + Vector3.up * (num2 + 1.1f * scale) + ((Vector3)(ref val3)).normalized * (num + 0.2f * scale), Vector3.down, ref val5, num2 * 2f + (1.1f + num) * scale, -1, (QueryTriggerInteraction)1) && !IsOwnCollider(((RaycastHit)(ref val5)).collider))
					{
						float num3 = ((RaycastHit)(ref val5)).point.y - Feet.y;
						if (num3 > 0.02f && num3 <= 1.1f * scale)
						{
							Rigidbody obj = bodyRigidbody;
							obj.position += Vector3.up * (num3 + 0.02f);
						}
					}
				}
			}
			bodyRigidbody.linearVelocity = val;
			bool flag = sim.IsGrounded() && lastEnvironment.groundSupport;
			SetBacking(GroundedField, movement, flag);
			SetBacking(SprintingField, movement, sim.SprintChargeTimer() > 0f);
			SetBacking(VelocityField, movement, val);
			SetBacking(VelocityMagnitudeField, movement, ((Vector3)(ref val)).sqrMagnitude);
			SetBacking(FeetField, movement, Feet);
			if ((Object)(object)playerCamera != (Object)null)
			{
				playerCamera.SetMoveValues(0f, 0f, 0f);
			}
		}

		private static void SetBacking(FieldInfo field, object target, object value)
		{
			if (field != null && target != null)
			{
				field.SetValue(target, value);
			}
		}

		internal bool IsOwnCollider(Collider collider)
		{
			if ((Object)(object)collider != (Object)null && (Object)(object)player != (Object)null)
			{
				if (!((Object)(object)((Component)collider).transform == (Object)(object)((Component)player).transform))
				{
					return ((Component)collider).transform.IsChildOf(((Component)player).transform);
				}
				return true;
			}
			return false;
		}

		internal bool IsPlayerCollider(Collider collider)
		{
			if ((Object)(object)collider != (Object)null)
			{
				return (Object)(object)((Component)collider).GetComponentInParent<Player>() != (Object)null;
			}
			return false;
		}

		internal void ApplySelfDamage(float amount, Vector3 at)
		{
			//IL_007f: 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_0092: Unknown result type (might be due to invalid IL or missing references)
			if (!(amount <= 0f) && !((Object)(object)player == (Object)null) && !((Object)(object)player.Vitals == (Object)null))
			{
				int num = ((MaximumHealthField != null) ? ((int)MaximumHealthField.GetValue(player.Vitals)) : 100);
				float num2 = (float)Mathf.Max(1, num) / 200f;
				int num3 = Mathf.RoundToInt(amount * num2);
				if (num3 > 0)
				{
					player.Vitals.TakeDamage(num3, at, CameraForward * (4f * scale), false);
				}
			}
		}

		internal bool ResolveIncomingDamage(int amount, Vector3 position, Vector3 force, bool ignoreInvulnerability)
		{
			if (!active)
			{
				return false;
			}
			if (!sim.IsParrying() && (ignoreInvulnerability || !sim.IsInvulnerable()))
			{
				return false;
			}
			if (sim.IsParrying())
			{
				sim.MarkParrySuccessful(0);
				animator.TriggerImpactFrame(0.08f);
				combat.HandleEvents();
			}
			return true;
		}

		internal bool ResolveKnockback(Vector3 force)
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			if (!active)
			{
				return false;
			}
			if (sim.IsParrying() || sim.IsInvulnerable())
			{
				if (sim.IsParrying())
				{
					sim.MarkParrySuccessful(0);
					animator.TriggerImpactFrame(0.08f);
					combat.HandleEvents();
				}
				return true;
			}
			Vec3 impulseVelocity = FisterUnits.VelocityToSim(force, scale);
			float strength = Mathf.Clamp01(((Vector3)(ref force)).magnitude / Mathf.Max(1f, 20f * scale));
			sim.OnHitByAttack(strength, impulseVelocity);
			return true;
		}

		internal void OnCameraLateUpdate(PlayerCamera camera)
		{
			//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_00d5: 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_00e0: 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_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: 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_028c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: Unknown result type (might be due to invalid IL or missing references)
			//IL_02af: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
			if (!active || (Object)(object)player == (Object)null || (Object)(object)camera == (Object)null || (Object)(object)camera != (Object)(object)playerCamera)
			{
				return;
			}
			try
			{
				Camera cam = camera.Cam;
				if ((Object)(object)cam == (Object)null)
				{
					return;
				}
				Quaternion rotation = ((Component)cam).transform.rotation;
				if (ShouldUseItemFirstPersonView())
				{
					Vector3 val = (((Object)(object)player.Transform != (Object)null && hasWaterHeadOffset) ? player.Transform.TransformPoint(waterHeadLocalOffset) : (Feet + Vector3.up * (scale * 1.65f)));
					((Component)cam).transform.SetPositionAndRotation(val, rotation);
					if (bodyRenderer != null)
					{
						bodyRenderer.Visible = false;
					}
					return;
				}
				Vector3 val2 = rotation * Vector3.forward;
				Vector3 feet = Feet;
				Vector3 val3 = feet + Vector3.up * (scale * 1.45f);
				((Component)cam).transform.SetPositionAndRotation(val3 - val2 * (scale * 6f), rotation);
				if (bodyRenderer == null)
				{
					bodyRenderer = new BodyRenderer("JohnFisterBody");
				}
				PoseInput inp = new PoseInput
				{
					dt = Mathf.Clamp(Time.deltaTime, 0f, 0.1f),
					time = (animationTime += Mathf.Clamp(Time.deltaTime, 0f, 0.1f)),
					yaw = yaw,
					pitch = pitch,
					velocity = sim.Velocity(),
					position = FisterUnits.BodyCentreFromFeet(feet, scale),
					forceRagdoll = sim.IsLimp(),
					hasGround = lastEnvironment.groundSupport,
					groundZ = lastEnvironment.position.z - 0.8f,
					hasWall = (lastEnvironment.contact && Mathf.Abs(lastEnvironment.contactNormal.z) < 0.7f),
					wallPoint = lastEnvironment.contactPoint.Copy(),
					wallNormal = lastEnvironment.contactNormal.Copy()
				};
				pose = animator.Update(sim, inp);
				bodyRenderer.Draw(pose, feet, yaw, cam, rotation);
				bodyRenderer.go.transform.localScale = Vector3.one * scale;
				bodyRenderer.Visible = true;
			}
			catch (Exception ex)
			{
				if (!warnedMissingBody)
				{
					FisterPlugin.Log.LogError((object)("Fister body update failed; restoring How to Fish appearance: " + ex));
					warnedMissingBody = true;
				}
				modeEnabled = false;
				ExitMode();
			}
		}

		private bool ShouldUseItemFirstPersonView()
		{
			if (!HasHeldItem)
			{
				return false;
			}
			Item heldItem = player.Holding.HeldItem;
			if ((Object)(object)heldItem.FishingRod != (Object)null || heldItem is FishingRod)
			{
				return true;
			}
			return (Object)(object)heldItem.Weapon != (Object)null;
		}

		internal void Shutdown()
		{
			ExitMode();
			if (bodyRenderer != null)
			{
				bodyRenderer.Destroy();
				bodyRenderer = null;
			}
		}

		private void OnGUI()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			if (active)
			{
				GUI.Label(new Rect(12f, 12f, 520f, 24f), "John Fister  |  LMB fist/charge  RMB parry  G grab/throw  F8 toggle");
			}
		}

		private void OnDestroy()
		{
			Shutdown();
		}
	}
	[HarmonyPatch(typeof(PlayerMovement), "FixedUpdate")]
	internal static class PlayerMovementFixedPatch
	{
		private static bool Prefix(PlayerMovement __instance)
		{
			FisterController fisterController = (((Object)(object)FisterPlugin.Instance != (Object)null) ? FisterPlugin.Instance.Controller : null);
			if (!((Object)(object)fisterController == (Object)null))
			{
				return !fisterController.FixedStepIfOwned(__instance);
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(PlayerMovement), "UnderWaterCheck")]
	internal static class PlayerMovementUnderWaterPatch
	{
		private struct CameraState
		{
			internal Transform camera;

			internal Vector3 savedPosition;

			internal bool restore;
		}

		[HarmonyPrefix]
		private static void Prefix(PlayerMovement __instance, out CameraState __state)
		{
			//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_005e: Unknown result type (might be due to invalid IL or missing references)
			__state = default(CameraState);
			FisterController fisterController = (((Object)(object)FisterPlugin.Instance != (Object)null) ? FisterPlugin.Instance.Controller : null);
			if ((Object)(object)fisterController != (Object)null && fisterController.TryGetPhysicalWaterHead(__instance, out var cameraTransform, out var savedCameraPosition, out var physicalHeadPosition))
			{
				__state.camera = cameraTransform;
				__state.savedPosition = savedCameraPosition;
				__state.restore = (Object)(object)cameraTransform != (Object)null;
				if (__state.restore)
				{
					cameraTransform.position = physicalHeadPosition;
				}
			}
		}

		[HarmonyPostfix]
		private static void Postfix(CameraState __state)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			if (__state.restore && (Object)(object)__state.camera != (Object)null)
			{
				__state.camera.position = __state.savedPosition;
			}
		}
	}
	[HarmonyPatch]
	internal static class PlayerHoldingInteractionOriginPatch
	{
		private struct CameraState
		{
			internal Transform camera;

			internal Vector3 savedPosition;

			internal bool restore;
		}

		private static IEnumerable<MethodBase> TargetMethods()
		{
			MethodBase methodBase = AccessTools.Method(typeof(PlayerHolding), "ScanForGrabbableItem", (Type[])null, (Type[])null);
			MethodBase interactableScan = AccessTools.Method(typeof(PlayerHolding), "ScanForInteractable", (Type[])null, (Type[])null);
			if (methodBase != null)
			{
				yield return methodBase;
			}
			if (interactableScan != null)
			{
				yield return interactableScan;
			}
		}

		[HarmonyPrefix]
		private static void Prefix(Component __instance, out CameraState __state)
		{
			//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_005e: Unknown result type (might be due to invalid IL or missing references)
			__state = default(CameraState);
			FisterController fisterController =