Decompiled source of SnakeWood v1.23.109

SnakeWood.dll

Decompiled 2 days 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 System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_guiutils")]
[assembly: IgnoresAccessChecksTo("assembly_utils")]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 SnakeWood
{
	public class HoverLog : MonoBehaviour, Interactable, Hoverable, IDoodadController, IRemoved, IDestructible
	{
		private enum ShiftAction
		{
			None,
			Feed,
			Repair,
			Core,
			Fuel
		}

		public string m_variant = "";

		public Transform m_attachPoint;

		public Transform m_frame;

		private Quaternion m_disguiseOffset = Quaternion.identity;

		private float m_offsetCheckTimer;

		private int m_sizedFor;

		public Vector3 m_detachOffset = new Vector3(0f, 0.6f, -1f);

		public float m_maxUseRange = 4f;

		private const float FreeFallMargin = 1.5f;

		private const float RamCooldown = 0.6f;

		private static readonly RaycastHit[] s_hits = (RaycastHit[])(object)new RaycastHit[16];

		private static int s_groundMask;

		private static int s_terrainMask;

		private ZNetView m_nview;

		private Rigidbody m_body;

		private ZSyncTransform? m_sync;

		private HoverSled? m_sled;

		private HoverLogVariant m_v;

		private Vector3 m_moveInput;

		private Vector3 m_lookDir;

		private bool m_boost;

		private bool m_brake;

		private bool m_crouchHeld;

		private bool m_hopQueued;

		private float m_yaw;

		private float m_roll;

		private float m_swimPhase;

		public float m_seatLift;

		private Transform? m_fishModel;

		private Transform? m_fishSaddle;

		private Vector3 m_fishModelPos;

		private Vector3 m_fishSaddlePos;

		private Quaternion m_fishModelRot;

		private Vector3 m_lastSwimPos;

		private bool m_exhausted;

		private bool m_freeLook;

		private Vector3 m_smoothUp = Vector3.up;

		private float m_pitch;

		private bool m_airborne;

		private bool m_wasInAir;

		private float m_cushion;

		private float m_cushionLength = 1f;

		private Vector3 m_driveVelocity;

		private int m_airHopsUsed;

		private readonly List<(Vector3 pos, float time)> m_cloud = new List<(Vector3, float)>();

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

		private float m_cloudTimer;

		private static readonly List<Character> s_inCloud = new List<Character>();

		private float m_validUserTimer;

		private bool m_haveValidUser;

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

		private static readonly int s_fuelKey = StringExtensionMethods.GetStableHashCode("SnakeWood_fuel");

		private static readonly int s_coreKey = StringExtensionMethods.GetStableHashCode("SnakeWood_core");

		private static readonly int s_wearKey = StringExtensionMethods.GetStableHashCode("SnakeWood_wear");

		private static readonly int s_wreckedKey = StringExtensionMethods.GetStableHashCode("SnakeWood_wrecked");

		private bool m_wreckSettled;

		private bool m_showingWreck;

		private float m_wreckCheckTimer;

		private static MaterialPropertyBlock? s_block;

		private float m_load;

		private float m_loadTimer;

		private static int s_passThroughLayer = -1;

		private int m_solidLayer = -1;

		private float m_controlRequestedAt;

		private float m_unstickUntil;

		private float m_unstickTimer;

		private int m_overlapChecks;

		private bool m_ghost;

		private static readonly Collider[] s_overlaps = (Collider[])(object)new Collider[16];

		private long m_lastRevision = -1L;

		private float m_lastRevisionTime;

		private float m_syncLogTimer;

		private int m_updates;

		private float m_longestGap;

		private float m_worstError;

		private static EffectList? s_hitEffect;

		private static EffectList? s_breakEffect;

		private float m_shakeUntil;

		private float m_lastSeenYaw = float.NaN;

		private bool m_holdingPassenger;

		private Vector3 m_passengerSpot;

		private float m_lastOnDeck = -10f;

		private float m_lastSeenY = float.NaN;

		private BoxCollider? m_deck;

		public Transform Frame => m_frame;

		internal bool HasRider
		{
			get
			{
				CalculateHaveValidUser();
				return m_haveValidUser;
			}
		}

		public HoverLogVariant Variant => m_v;

		private static bool FuelEnabled => SnakeWoodPlugin.FuelPerMinute.Value > 0f;

		private bool NeedsFuel
		{
			get
			{
				if (FuelEnabled)
				{
					return !HasCore();
				}
				return false;
			}
		}

		private bool TakesCore
		{
			get
			{
				if (FuelEnabled && m_v.CoreFuelCfg.Value)
				{
					return !HasCore();
				}
				return false;
			}
		}

		private static bool WearEnabled => SnakeWoodPlugin.WearEnabled.Value;

		private float LoadCapacity => Mathf.Max(1f, ((Object)(object)m_sled != (Object)null) ? m_sled.Strength() : m_v.LoadCapacityCfg.Value);

		public float Speed
		{
			get
			{
				//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)
				Vector3 linearVelocity = m_body.linearVelocity;
				return ((Vector3)(ref linearVelocity)).magnitude;
			}
		}

		internal ZDOID Id
		{
			get
			{
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				if (!m_nview.IsValid())
				{
					return ZDOID.None;
				}
				return m_nview.GetZDO().m_uid;
			}
		}

		internal void SetDisguiseOffset(Quaternion offset)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: 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)
			m_disguiseOffset = offset;
			m_frame.localRotation = Quaternion.Inverse(offset);
			MatchDisguiseSize();
		}

		private void MatchDisguiseSize()
		{
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: 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_0150: Unknown result type (might be due to invalid IL or missing references)
			if (m_v == null || !m_nview.IsValid())
			{
				return;
			}
			int prefab = m_nview.GetZDO().GetPrefab();
			if (prefab == m_sizedFor)
			{
				return;
			}
			m_sizedFor = prefab;
			(float, float)? tuple = HoverLogDisguise.SizeOf(prefab);
			if (!tuple.HasValue)
			{
				m_frame.localScale = Vector3.one;
				return;
			}
			float num = Mathf.Max(1f, tuple.Value.Item1 * 0.9f / m_v.Length);
			float num2 = Mathf.Max(1f, tuple.Value.Item2 * 0.9f / (0.45f * m_v.Thickness));
			m_frame.localScale = new Vector3(num2, num2, num);
			CapsuleCollider component = ((Component)m_frame).GetComponent<CapsuleCollider>();
			if (component != null)
			{
				component.radius = 0.225f * m_v.Thickness / num2;
				component.height = 0.9f * m_v.Length / num;
			}
			Transform obj = m_frame.Find("deck");
			BoxCollider val = ((obj != null) ? ((Component)obj).GetComponent<BoxCollider>() : null);
			if (val != null)
			{
				Vector3 size = val.size;
				size.z = 0.8f * m_v.Length / num;
				val.size = size;
			}
		}

		private float MovingHeightFactor(Vector3 vel)
		{
			//IL_0000: 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_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)
			Vector3 val = new Vector3(vel.x, 0f, vel.z);
			float num = Mathf.Clamp01(((Vector3)(ref val)).magnitude / Mathf.Max(1f, 0.5f * TopSpeedAt(onWater: false)));
			return Mathf.Lerp(SnakeWoodPlugin.RestHoverHeight.Value, 1f, num);
		}

		private float TopSpeedAt(bool onWater)
		{
			if (!((Object)(object)m_sled != (Object)null))
			{
				return m_v.MaxSpeedCfg.Value;
			}
			return m_sled.TopSpeed(onWater);
		}

		private void Awake()
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			m_nview = ((Component)this).GetComponent<ZNetView>();
			m_body = ((Component)this).GetComponent<Rigidbody>();
			m_sync = ((Component)this).GetComponent<ZSyncTransform>();
			m_sled = ((Component)this).GetComponent<HoverSled>();
			HoverLogVariant hoverLogVariant = HoverLogVariant.Get(m_variant);
			if (m_nview.GetZDO() == null || hoverLogVariant == null)
			{
				m_frame.localRotation = Quaternion.identity;
				m_body.isKinematic = true;
				((Behaviour)this).enabled = false;
				return;
			}
			m_v = hoverLogVariant;
			m_attachPoint.localPosition = (m_v.Sled ? new Vector3(0f, 0.25f, 0.55f) : new Vector3(0f, SnakeWoodPlugin.SeatHeight.Value + m_seatLift, -0.2f * m_v.Length));
			if (m_nview.IsOwner())
			{
				HoverLogDisguise.Apply(this, m_nview.GetZDO());
			}
			else
			{
				SetDisguiseOffset(HoverLogDisguise.StoredOffset(m_nview.GetZDO()));
			}
			m_yaw = FrameYaw();
			if (s_groundMask == 0)
			{
				s_groundMask = LayerMask.GetMask(new string[5] { "Default", "static_solid", "Default_small", "piece", "terrain" });
			}
			HoverLogFx.Attach(this, m_v);
			m_nview.Register<long>("SnakeWood_RequestControl", (Action<long, long>)RPC_RequestControl);
			m_nview.Register<long>("SnakeWood_ReleaseControl", (Action<long, long>)RPC_ReleaseControl);
			m_nview.Register<bool>("SnakeWood_RequestResponse", (Action<long, bool>)RPC_RequestResponse);
			m_nview.Register<int>("SnakeWood_AddFuel", (Action<long, int>)RPC_AddFuel);
			m_nview.Register<float>("SnakeWood_Repair", (Action<long, float>)RPC_Repair);
			m_nview.Register<Vector3, bool>("SnakeWood_Hit", (Action<long, Vector3, bool>)RPC_Hit);
			m_nview.Register("SnakeWood_AddCore", (Action<long>)RPC_AddCore);
			m_nview.Register<float, Vector3>("SnakeWood_Damage", (Action<long, float, Vector3>)RPC_Damage);
		}

		private float GetFuel()
		{
			if (!m_nview.IsValid())
			{
				return 0f;
			}
			return m_nview.GetZDO().GetFloat(s_fuelKey, 0f);
		}

		private static ItemData? FuelItemData()
		{
			ObjectDB instance = ObjectDB.instance;
			if (instance == null)
			{
				return null;
			}
			GameObject itemPrefab = instance.GetItemPrefab(SnakeWoodPlugin.FuelItem.Value);
			if (itemPrefab == null)
			{
				return null;
			}
			return itemPrefab.GetComponent<ItemDrop>()?.m_itemData;
		}

		private static string FuelName()
		{
			return FuelItemData()?.m_shared.m_name ?? SnakeWoodPlugin.FuelItem.Value;
		}

		private bool HasCore()
		{
			if (m_nview.IsValid())
			{
				return m_nview.GetZDO().GetBool(s_coreKey, false);
			}
			return false;
		}

		private static ItemData? CoreItemData()
		{
			ObjectDB instance = ObjectDB.instance;
			if (instance == null)
			{
				return null;
			}
			GameObject itemPrefab = instance.GetItemPrefab(SnakeWoodPlugin.CoreFuelItem.Value);
			if (itemPrefab == null)
			{
				return null;
			}
			return itemPrefab.GetComponent<ItemDrop>()?.m_itemData;
		}

		private static string CoreName()
		{
			return CoreItemData()?.m_shared.m_name ?? SnakeWoodPlugin.CoreFuelItem.Value;
		}

		private bool AddCoreFrom(Player player)
		{
			string text = CoreName();
			if (!TakesCore || ((Humanoid)player).GetInventory().CountItems(text, -1, true) <= 0)
			{
				return false;
			}
			((Humanoid)player).GetInventory().RemoveItem(text, 1, -1, true);
			m_nview.InvokeRPC("SnakeWood_AddCore", Array.Empty<object>());
			((Character)player).Message((MessageType)2, Localization.instance.Localize("Fitted a " + text + ": it never needs fuel again"), 0, (Sprite)null, false);
			return true;
		}

		private void RPC_AddCore(long sender)
		{
			if (m_nview.IsOwner())
			{
				m_nview.GetZDO().Set(s_coreKey, true);
			}
		}

		private ShiftAction NextShiftAction(Player? player)
		{
			Inventory inventory = ((player != null) ? ((Humanoid)player).GetInventory() : null);
			bool flag = WearEnabled && GetWear() > 0f;
			if ((Object)(object)m_sled != (Object)null && (Object)(object)player != (Object)null && m_sled.AnyHungry(player))
			{
				return ShiftAction.Feed;
			}
			if (flag && Has(RepairName()))
			{
				return ShiftAction.Repair;
			}
			if (TakesCore && Has(CoreName()))
			{
				return ShiftAction.Core;
			}
			bool flag2 = GetFuel() < (float)SnakeWoodPlugin.FuelCapacity.Value - 0.5f;
			if (NeedsFuel && flag2 && Has(FuelName()))
			{
				return ShiftAction.Fuel;
			}
			if (!flag)
			{
				if (!NeedsFuel)
				{
					return ShiftAction.None;
				}
				return ShiftAction.Fuel;
			}
			return ShiftAction.Repair;
			bool Has(string name)
			{
				if (inventory != null)
				{
					return inventory.CountItems(name, -1, true) > 0;
				}
				return false;
			}
		}

		private bool AddFuelFrom(Player player, int max)
		{
			string text = FuelName();
			int num = SnakeWoodPlugin.FuelCapacity.Value - Mathf.CeilToInt(GetFuel());
			int num2 = Mathf.Min(new int[3]
			{
				max,
				num,
				((Humanoid)player).GetInventory().CountItems(text, -1, true)
			});
			if (num <= 0)
			{
				((Character)player).Message((MessageType)2, "It's full", 0, (Sprite)null, false);
				return false;
			}
			if (num2 <= 0)
			{
				((Character)player).Message((MessageType)2, Localization.instance.Localize("You have no " + text), 0, (Sprite)null, false);
				return false;
			}
			((Humanoid)player).GetInventory().RemoveItem(text, num2, -1, true);
			m_nview.InvokeRPC("SnakeWood_AddFuel", new object[1] { num2 });
			((Character)player).Message((MessageType)2, Localization.instance.Localize($"Added {num2} {text}"), 0, (Sprite)null, false);
			return true;
		}

		private void RPC_AddFuel(long sender, int amount)
		{
			if (m_nview.IsOwner())
			{
				m_nview.GetZDO().Set(s_fuelKey, Mathf.Clamp(GetFuel() + (float)amount, 0f, (float)SnakeWoodPlugin.FuelCapacity.Value));
			}
		}

		private void TakeFuelOut(Player player)
		{
			//IL_0086: 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_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_00a5: 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_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)
			int num = Mathf.FloorToInt(GetFuel());
			ItemData val = FuelItemData();
			if (num <= 0 || val == null)
			{
				((Character)player).Message((MessageType)2, Localization.instance.Localize("There's no whole " + FuelName() + " left in it"), 0, (Sprite)null, false);
				return;
			}
			m_nview.InvokeRPC("SnakeWood_AddFuel", new object[1] { -num });
			ItemData val2 = val.Clone();
			val2.m_stack = num;
			if (!((Humanoid)player).GetInventory().AddItem(val2))
			{
				ItemDrop.DropItem(val, num, ((Component)player).transform.position + ((Component)player).transform.forward * 0.5f + Vector3.up * 0.5f, Quaternion.identity);
			}
			((Character)player).Message((MessageType)2, Localization.instance.Localize($"Took out {num} {FuelName()}"), 0, (Sprite)null, false);
		}

		public void OnRemoved()
		{
			if ((Object)(object)m_nview != (Object)null && m_nview.IsValid())
			{
				DropFuel();
				((Component)this).GetComponent<HoverSled>()?.OnRemoved();
			}
		}

		private void DropFuel()
		{
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: 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_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			if (HasCore())
			{
				ObjectDB instance = ObjectDB.instance;
				object obj;
				if (instance == null)
				{
					obj = null;
				}
				else
				{
					GameObject itemPrefab = instance.GetItemPrefab(SnakeWoodPlugin.CoreFuelItem.Value);
					obj = ((itemPrefab != null) ? itemPrefab.GetComponent<ItemDrop>() : null);
				}
				ItemDrop val = (ItemDrop)obj;
				if (val != null)
				{
					m_nview.GetZDO().Set(s_coreKey, false);
					ItemDrop.DropItem(val.m_itemData, 1, ((Component)this).transform.position + Vector3.up * 0.5f, Quaternion.identity);
				}
			}
			int num = Mathf.FloorToInt(GetFuel());
			ItemData val2 = FuelItemData();
			if (num > 0 && val2 != null)
			{
				m_nview.GetZDO().Set(s_fuelKey, 0f);
				ItemDrop.DropItem(val2, num, ((Component)this).transform.position + Vector3.up * 0.5f, Quaternion.identity);
			}
		}

		private float GetWear()
		{
			if (!m_nview.IsValid())
			{
				return 0f;
			}
			return m_nview.GetZDO().GetFloat(s_wearKey, 0f);
		}

		private float Condition()
		{
			return Mathf.Clamp01(1f - GetWear() / Mathf.Max(1f, m_v.DurabilityCfg.Value));
		}

		private string RepairName()
		{
			ObjectDB instance = ObjectDB.instance;
			object obj;
			if (instance == null)
			{
				obj = null;
			}
			else
			{
				GameObject itemPrefab = instance.GetItemPrefab(m_v.RepairItemCfg.Value);
				obj = ((itemPrefab == null) ? null : itemPrefab.GetComponent<ItemDrop>()?.m_itemData.m_shared.m_name);
			}
			if (obj == null)
			{
				obj = m_v.RepairItemCfg.Value;
			}
			return (string)obj;
		}

		public DestructibleType GetDestructibleType()
		{
			return (DestructibleType)1;
		}

		public void Damage(HitData hit)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			if (m_nview.IsValid())
			{
				Character attacker = hit.GetAttacker();
				if (attacker != null && !attacker.IsPlayer())
				{
					m_nview.InvokeRPC("SnakeWood_Damage", new object[2]
					{
						hit.GetTotalDamage(),
						hit.m_point
					});
				}
			}
		}

		private void RPC_Damage(long sender, float amount, Vector3 point)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			AddWear(amount, point);
		}

		private void AddWear(float amount, Vector3? point = null)
		{
			//IL_006e: 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_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)m_sled != (Object)null)
			{
				if (amount >= 1f && m_nview.IsValid() && m_nview.IsOwner())
				{
					m_sled.Hurt(amount);
					m_nview.InvokeRPC(ZNetView.Everybody, "SnakeWood_Hit", new object[2]
					{
						(object)(Vector3)(((??)point) ?? ((Component)this).transform.position),
						false
					});
				}
			}
			else if (WearEnabled && !(amount <= 0f) && m_nview.IsValid() && m_nview.IsOwner() && !IsWrecked())
			{
				float num = Mathf.Min(m_v.DurabilityCfg.Value, GetWear() + amount);
				m_nview.GetZDO().Set(s_wearKey, num);
				bool flag = num >= m_v.DurabilityCfg.Value;
				if (amount >= 1f || flag)
				{
					m_nview.InvokeRPC(ZNetView.Everybody, "SnakeWood_Hit", new object[2]
					{
						(object)(Vector3)(((??)point) ?? ((Component)this).transform.position),
						flag
					});
				}
				if (flag)
				{
					m_nview.GetZDO().Set(s_wreckedKey, true);
					ThrowRider($"Your log is wrecked! Bring {RepairsNeeded()} {RepairName()} to repair it");
				}
			}
		}

		private bool RepairFrom(Player player)
		{
			string text = RepairName();
			int num = Mathf.CeilToInt(GetWear() / SnakeWoodPlugin.RepairPerItem.Value);
			int num2 = Mathf.Min(num, ((Humanoid)player).GetInventory().CountItems(text, -1, true));
			if (num2 <= 0)
			{
				((Character)player).Message((MessageType)2, Localization.instance.Localize("You have no " + text + " to repair it"), 0, (Sprite)null, false);
				return false;
			}
			((Humanoid)player).GetInventory().RemoveItem(text, num2, -1, true);
			m_nview.InvokeRPC("SnakeWood_Repair", new object[1] { (float)num2 * SnakeWoodPlugin.RepairPerItem.Value });
			int num3 = num - num2;
			((Character)player).Message((MessageType)2, Localization.instance.Localize((num3 > 0 && IsWrecked()) ? $"Repaired with {num2} {text}. {num3} more to get it flying" : $"Repaired with {num2} {text}"), 0, (Sprite)null, false);
			return true;
		}

		private void RPC_Repair(long sender, float amount)
		{
			if (m_nview.IsOwner())
			{
				float num = Mathf.Max(0f, GetWear() - amount);
				m_nview.GetZDO().Set(s_wearKey, num);
				if (num <= 0f)
				{
					m_nview.GetZDO().Set(s_wreckedKey, false);
				}
			}
		}

		private bool IsWrecked()
		{
			if (WearEnabled && m_nview.IsValid())
			{
				return m_nview.GetZDO().GetBool(s_wreckedKey, false);
			}
			return false;
		}

		private int RepairsNeeded()
		{
			return Mathf.CeilToInt(GetWear() / SnakeWoodPlugin.RepairPerItem.Value);
		}

		private void HoldWreck()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: 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_0074: 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_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: 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_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: 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_00e3: 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)
			if (!m_wreckSettled)
			{
				m_wreckSettled = true;
				Vector3 position = m_body.position;
				GetSurface(position, out var height, out var _, out var _, out var _);
				if (!float.IsNegativeInfinity(height))
				{
					position.y = height + 0.2f * m_v.Thickness * m_frame.localScale.x;
				}
				m_body.linearVelocity = Vector3.zero;
				m_body.angularVelocity = Vector3.zero;
				m_body.isKinematic = true;
				Quaternion val = Quaternion.Euler(0f, m_yaw, 0f) * Quaternion.Euler(-6f, 0f, 28f) * m_disguiseOffset;
				m_body.position = position;
				m_body.rotation = val;
				((Component)this).transform.SetPositionAndRotation(position, val);
			}
		}

		private void UpdateWreckLook()
		{
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Expected O, but got Unknown
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			if ((m_wreckCheckTimer -= Time.deltaTime) > 0f)
			{
				return;
			}
			m_wreckCheckTimer = 0.5f;
			bool flag = IsWrecked();
			if (flag == m_showingWreck)
			{
				return;
			}
			m_showingWreck = flag;
			Light[] componentsInChildren = ((Component)m_frame).GetComponentsInChildren<Light>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				((Behaviour)componentsInChildren[i]).enabled = !flag;
			}
			ParticleSystem[] componentsInChildren2 = ((Component)m_frame).GetComponentsInChildren<ParticleSystem>(true);
			foreach (ParticleSystem val in componentsInChildren2)
			{
				if (flag)
				{
					val.Stop(true, (ParticleSystemStopBehavior)1);
				}
				else
				{
					val.Play();
				}
			}
			if (s_block == null)
			{
				s_block = new MaterialPropertyBlock();
			}
			Renderer[] componentsInChildren3 = ((Component)m_frame).GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val2 in componentsInChildren3)
			{
				if (val2 is ParticleSystemRenderer)
				{
					continue;
				}
				if (!flag)
				{
					val2.SetPropertyBlock((MaterialPropertyBlock)null);
					continue;
				}
				Material sharedMaterial = val2.sharedMaterial;
				if (!((Object)(object)sharedMaterial == (Object)null) && sharedMaterial.HasProperty("_Color"))
				{
					val2.GetPropertyBlock(s_block);
					s_block.SetColor("_Color", sharedMaterial.color * new Color(0.35f, 0.32f, 0.3f, 1f));
					val2.SetPropertyBlock(s_block);
				}
			}
		}

		private float LoadOf(Player player)
		{
			return (((Humanoid)player).GetInventory().GetTotalWeight() + (((Object)(object)m_sled != (Object)null) ? m_sled.CargoWeight() : 0f)) / LoadCapacity;
		}

		private static float Performance(float load)
		{
			float value = SnakeWoodPlugin.LoadAtCapacity.Value;
			return Mathf.Clamp((load <= 1f) ? (1f - (1f - value) * load) : (value - SnakeWoodPlugin.OverloadFalloff.Value * (load - 1f)), 0.08f, 1f);
		}

		private static bool CarriesMetal(Player player)
		{
			if (SnakeWoodPlugin.NoMetal.Value)
			{
				return !((Humanoid)player).GetInventory().IsTeleportable(false);
			}
			return false;
		}

		private bool UpdateLoad(float dt)
		{
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || (m_loadTimer -= dt) > 0f)
			{
				return true;
			}
			m_loadTimer = 0.5f;
			if (CarriesMetal(localPlayer))
			{
				ThrowRider("The log won't carry ore or metal");
				return false;
			}
			bool flag = m_load > 1f;
			m_load = LoadOf(localPlayer);
			if (m_load > 1f && !flag)
			{
				((Character)localPlayer).Message((MessageType)2, "Overloaded! The log is sinking and sluggish", 0, (Sprite)null, false);
			}
			return true;
		}

		private bool BurnFuel(float dt)
		{
			if (!NeedsFuel)
			{
				return true;
			}
			float fuel = GetFuel();
			if (fuel <= 0f)
			{
				return false;
			}
			fuel = Mathf.Max(0f, fuel - SnakeWoodPlugin.FuelPerMinute.Value / 60f * dt);
			m_nview.GetZDO().Set(s_fuelKey, fuel);
			if (fuel <= 0f)
			{
				Player localPlayer = Player.m_localPlayer;
				if (localPlayer != null)
				{
					((Character)localPlayer).Message((MessageType)2, Localization.instance.Localize("Out of " + FuelName() + "! The log sputters"), 0, (Sprite)null, false);
				}
			}
			return fuel > 0f;
		}

		internal static HoverLog? BeginRiderPassThrough()
		{
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || !(localPlayer.GetDoodadController() is HoverLog hoverLog))
			{
				return null;
			}
			if (s_passThroughLayer < 0)
			{
				s_passThroughLayer = LayerMask.NameToLayer("Ignore Raycast");
			}
			hoverLog.m_solidLayer = ((Component)hoverLog).gameObject.layer;
			hoverLog.SetColliderLayer(s_passThroughLayer);
			return hoverLog;
		}

		internal void ArriveUnder(Player rider)
		{
			//IL_002a: 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_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: 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_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: 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_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			if (m_nview.IsValid())
			{
				m_nview.ClaimOwnership();
				ZDO zDO = m_nview.GetZDO();
				int s_user = ZDOVars.s_user;
				ZDOID zDOID = ((Character)rider).GetZDOID();
				zDO.Set(s_user, ((ZDOID)(ref zDOID)).UserID);
				float y = ((Component)rider).transform.eulerAngles.y;
				Quaternion val = Quaternion.Euler(0f, y, 0f);
				Vector3 val2 = ((Component)rider).transform.position + val * new Vector3(0f, 0f, 0.2f * m_v.Length * m_frame.localScale.z) - Vector3.up * (SnakeWoodPlugin.SeatHeight.Value + m_seatLift);
				Quaternion val3 = val * m_disguiseOffset;
				m_body.linearVelocity = Vector3.zero;
				m_body.angularVelocity = Vector3.zero;
				m_body.position = val2;
				m_body.rotation = val3;
				((Component)this).transform.SetPositionAndRotation(val2, val3);
				m_nview.GetZDO().SetPosition(val2);
				m_nview.GetZDO().SetRotation(val3);
				m_yaw = y;
				m_pitch = 0f;
				m_roll = 0f;
				m_unstickUntil = Time.time + 3f;
				if ((object)rider.GetDoodadController() != this)
				{
					rider.m_doodadController = null;
					((Character)rider).AttachStop();
					ResetControls();
					RidingControlsPatch.ResetStance();
					rider.StartDoodadControl((IDoodadController)(object)this);
					((Character)rider).AttachStart(m_attachPoint, ((Component)this).gameObject, false, false, false, SnakeWoodPlugin.AttachAnimation, m_detachOffset, (Transform)null);
				}
			}
		}

		private void Start()
		{
			if ((Object)(object)m_nview != (Object)null && m_nview.IsValid() && (Object)(object)Player.m_localPlayer != (Object)null)
			{
				MountedPortal.OnLogLoaded(this, Player.m_localPlayer);
			}
		}

		internal void EndRiderPassThrough()
		{
			if (m_solidLayer >= 0)
			{
				SetColliderLayer(m_solidLayer);
			}
		}

		private void SetColliderLayer(int layer)
		{
			Collider[] componentsInChildren = ((Component)this).GetComponentsInChildren<Collider>();
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				((Component)componentsInChildren[i]).gameObject.layer = layer;
			}
		}

		public string GetHoverName()
		{
			return m_v?.Name ?? "";
		}

		public string GetHoverText()
		{
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			if (!m_nview.IsValid() || m_v == null || (Object)(object)Player.m_localPlayer == (Object)null)
			{
				return "";
			}
			string text = (((Object)(object)m_sled != (Object)null) ? m_sled.TeamText() : "");
			if (WearEnabled && (Object)(object)m_sled == (Object)null)
			{
				text += (IsWrecked() ? $"\n<color=red>Wrecked</color>: needs {RepairsNeeded()} {RepairName()} to fly again" : $"\nCondition: {Condition() * 100f:0}%");
			}
			if (HasCore())
			{
				text = text + "\nFuelled for good (" + CoreName() + ")";
			}
			else if (FuelEnabled)
			{
				text += $"\n{FuelName()}: {Mathf.CeilToInt(GetFuel())}/{SnakeWoodPlugin.FuelCapacity.Value}";
				if (TakesCore)
				{
					text = text + " <color=#aaaaaa>(or a " + CoreName() + " for good)</color>";
				}
			}
			string text2 = NextShiftAction(Player.m_localPlayer) switch
			{
				ShiftAction.Feed => "Feed the team", 
				ShiftAction.Repair => "Repair (" + RepairName() + ")", 
				ShiftAction.Core => "Fit " + CoreName() + " (fuel for good)", 
				ShiftAction.Fuel => "Add " + FuelName(), 
				_ => "", 
			};
			if (text2.Length > 0)
			{
				text = text + "\n[<color=yellow><b>$KEY_AltPlace + $KEY_Use</b></color>] " + text2;
			}
			if (FuelEnabled && GetFuel() >= 1f)
			{
				text += $"\n[<color=yellow><b>{SnakeWoodPlugin.TakeFuelKey.Value}</b></color>] Take out {FuelName()}";
			}
			if (IsLocalUser())
			{
				return Localization.instance.Localize(m_v.Name + text + "\n[<color=yellow><b>$KEY_Use</b></color>] Get off");
			}
			if (!InUseDistance((Humanoid)(object)Player.m_localPlayer))
			{
				return Localization.instance.Localize("<color=#888888>$piece_toofar</color>");
			}
			string text3 = (((Object)(object)m_sled != (Object)null && GetUser() != 0L && HasRider) ? "Sit as passenger" : "Ride");
			return Localization.instance.Localize(m_v.Name + text + "\n[<color=yellow><b>$KEY_Use</b></color>] " + text3);
		}

		public bool Interact(Humanoid character, bool hold, bool alt)
		{
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			if (!hold && m_nview.IsValid())
			{
				Player val = (Player)(object)((character is Player) ? character : null);
				if (val != null)
				{
					if (alt)
					{
						switch (NextShiftAction(val))
						{
						case ShiftAction.Feed:
							m_sled.TryFeed(val);
							return false;
						case ShiftAction.Repair:
							RepairFrom(val);
							return false;
						case ShiftAction.Core:
							AddCoreFrom(val);
							return false;
						case ShiftAction.Fuel:
							AddFuelFrom(val, int.MaxValue);
							return false;
						}
					}
					if ((object)val.GetDoodadController() == this)
					{
						val.StopDoodadControl();
						return false;
					}
					if (!InUseDistance((Humanoid)(object)val) || ((Character)val).IsAttached() || val.GetDoodadController() != null)
					{
						return false;
					}
					if ((Object)(object)m_sled != (Object)null)
					{
						if (GetUser() != 0L && HasRider)
						{
							m_sled.SeatPassenger(val);
							return false;
						}
						if (!m_sled.CanPull)
						{
							((Character)val).Message((MessageType)2, "The sled needs a team that can pull: hitch animals (or feed exhausted ones)", 0, (Sprite)null, false);
							return false;
						}
					}
					if (NeedsFuel && GetFuel() <= 0f)
					{
						((Character)val).Message((MessageType)2, Localization.instance.Localize("It needs " + FuelName() + " to fly (Shift+E to add)"), 0, (Sprite)null, false);
						return false;
					}
					if (IsWrecked())
					{
						((Character)val).Message((MessageType)2, Localization.instance.Localize($"It's wrecked. Repair it with {RepairsNeeded()} {RepairName()} (Shift+E)"), 0, (Sprite)null, false);
						return false;
					}
					if (CarriesMetal(val))
					{
						((Character)val).Message((MessageType)2, "It won't carry ore or metal", 0, (Sprite)null, false);
						return false;
					}
					if (LoadOf(val) > 1f)
					{
						((Character)val).Message((MessageType)2, string.Format("Overloaded: this {0} struggles past {1:0} weight", ((Object)(object)m_sled != (Object)null) ? "sled" : "log", LoadCapacity), 0, (Sprite)null, false);
					}
					ZNetView nview = m_nview;
					object[] array = new object[1];
					ZDOID zDOID = ((Character)val).GetZDOID();
					array[0] = ((ZDOID)(ref zDOID)).UserID;
					nview.InvokeRPC("SnakeWood_RequestControl", array);
					m_controlRequestedAt = Time.time;
					return false;
				}
			}
			return false;
		}

		private void CheckUnansweredRequest()
		{
			//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)
			if (!(m_controlRequestedAt <= 0f) && !(Time.time - m_controlRequestedAt < 1.5f))
			{
				m_controlRequestedAt = 0f;
				Player localPlayer = Player.m_localPlayer;
				if (!((Object)(object)localPlayer == (Object)null) && localPlayer.GetDoodadController() == null && m_nview.IsValid())
				{
					m_nview.ClaimOwnership();
					long uID = ZNet.GetUID();
					ZDOID zDOID = ((Character)localPlayer).GetZDOID();
					RPC_RequestControl(uID, ((ZDOID)(ref zDOID)).UserID);
				}
			}
		}

		public bool UseItem(Humanoid user, ItemData item)
		{
			Player val = (Player)(object)((user is Player) ? user : null);
			if (val != null)
			{
				if (!(item.m_shared.m_name == CoreName()))
				{
					if (NeedsFuel && item.m_shared.m_name == FuelName())
					{
						return AddFuelFrom(val, 1);
					}
					return false;
				}
				return AddCoreFrom(val);
			}
			return false;
		}

		public float GetHoverOffset()
		{
			return 0f;
		}

		private bool InUseDistance(Humanoid human)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			return Vector3.Distance(((Component)human).transform.position, ((Component)this).transform.position) < m_maxUseRange;
		}

		private void RPC_RequestControl(long sender, long userID)
		{
			if (m_nview.IsOwner())
			{
				CalculateHaveValidUser();
				if (GetUser() == userID || !m_haveValidUser)
				{
					m_nview.GetZDO().Set(ZDOVars.s_user, userID);
					m_nview.InvokeRPC(sender, "SnakeWood_RequestResponse", new object[1] { true });
					m_nview.GetZDO().SetOwner(sender);
				}
				else
				{
					m_nview.InvokeRPC(sender, "SnakeWood_RequestResponse", new object[1] { false });
				}
			}
		}

		private void RPC_ReleaseControl(long sender, long userID)
		{
			if (m_nview.IsOwner() && GetUser() == userID)
			{
				m_nview.GetZDO().Set(ZDOVars.s_user, 0L);
			}
		}

		private void RPC_RequestResponse(long sender, bool granted)
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			m_controlRequestedAt = 0f;
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer == (Object)null))
			{
				if (!granted)
				{
					((Character)localPlayer).Message((MessageType)2, "$msg_inuse", 0, (Sprite)null, false);
					return;
				}
				ResetControls();
				RidingControlsPatch.ResetStance();
				m_yaw = FrameYaw();
				m_load = LoadOf(localPlayer);
				m_loadTimer = 0.5f;
				localPlayer.StartDoodadControl((IDoodadController)(object)this);
				((Character)localPlayer).AttachStart(m_attachPoint, ((Component)this).gameObject, false, false, false, SnakeWoodPlugin.AttachAnimation, m_detachOffset, (Transform)null);
			}
		}

		public void ApplyControlls(Vector3 moveDir, Vector3 lookDir, bool run, bool autoRun, bool block)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: 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)
			m_moveInput = moveDir;
			m_lookDir = lookDir;
			m_boost = run;
			m_brake = block && !SnakeWoodPlugin.MountedCombat.Value;
		}

		private void Update()
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			CheckUnansweredRequest();
			if (m_nview.IsValid() && !m_nview.IsOwner() && (m_offsetCheckTimer -= Time.deltaTime) <= 0f)
			{
				m_offsetCheckTimer = 1f;
				SetDisguiseOffset(HoverLogDisguise.StoredOffset(m_nview.GetZDO()));
			}
			m_crouchHeld = IsLocallyDriven() && (ZInput.GetButton("Crouch") || ZInput.GetButton("JoyCrouch"));
			int freeLook;
			if (IsLocallyDriven())
			{
				KeyboardShortcut value = SnakeWoodPlugin.FreeLookKey.Value;
				freeLook = (((KeyboardShortcut)(ref value)).IsPressed() ? 1 : 0);
			}
			else
			{
				freeLook = 0;
			}
			m_freeLook = (byte)freeLook != 0;
			CheckTakeFuelKey();
			CheckHitchKey();
			CheckUnhitchKey();
			UpdateWreckLook();
			UpdateShake();
			UpdateCombatFacing();
			UpdateFishSwim();
			LogSync();
		}

		private void UpdateFishSwim()
		{
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: 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_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: 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_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: 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)
			if (m_v == null || !m_v.IsFish)
			{
				return;
			}
			if ((Object)(object)m_fishModel == (Object)null)
			{
				m_fishModel = m_frame.Find("visual");
				m_fishSaddle = m_frame.Find("saddle");
				if ((Object)(object)m_fishModel == (Object)null)
				{
					return;
				}
				m_fishModelPos = m_fishModel.localPosition;
				m_fishModelRot = m_fishModel.localRotation;
				m_fishSaddlePos = (((Object)(object)m_fishSaddle != (Object)null) ? m_fishSaddle.localPosition : Vector3.zero);
				m_lastSwimPos = ((Component)this).transform.position;
			}
			float deltaTime = Time.deltaTime;
			float num = ((deltaTime > 0f) ? (Vector3.Distance(((Component)this).transform.position, m_lastSwimPos) / deltaTime) : 0f);
			m_lastSwimPos = ((Component)this).transform.position;
			float num2 = Mathf.Clamp01(num / Mathf.Max(1f, m_v.MaxSpeedCfg.Value));
			m_swimPhase += deltaTime * (1.2f + 5f * num2);
			float num3 = SnakeWoodPlugin.FishWiggle.Value / 7f;
			float num4 = Mathf.Sin(m_swimPhase) * 0.05f * num3;
			float num5 = Mathf.Sin(m_swimPhase * 0.5f) * SnakeWoodPlugin.FishWiggle.Value * (0.3f + 0.7f * num2);
			m_fishModel.localPosition = m_fishModelPos + Vector3.up * num4;
			m_fishModel.localRotation = Quaternion.Euler(Mathf.Cos(m_swimPhase) * 1.5f * num3, num5, 0f) * m_fishModelRot;
			if ((Object)(object)m_fishSaddle != (Object)null)
			{
				m_fishSaddle.localPosition = m_fishSaddlePos + Vector3.up * num4;
			}
		}

		private void UpdateCombatFacing()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0021: 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_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			bool flag = IsLocallyDriven() && RidingControlsPatch.InCombat;
			Quaternion val = Quaternion.identity;
			if (flag)
			{
				Vector3 val2 = Vector3.ProjectOnPlane(((Character)localPlayer).GetLookDir(), m_frame.up);
				if (((Vector3)(ref val2)).sqrMagnitude > 0.001f)
				{
					val = Quaternion.Inverse(m_frame.rotation) * Quaternion.LookRotation(val2, m_frame.up);
				}
			}
			m_attachPoint.localRotation = Quaternion.Slerp(m_attachPoint.localRotation, val, (flag ? 18f : 5f) * Time.deltaTime);
		}

		private void UpdateUnstick(float dt)
		{
			if (!((m_unstickTimer -= dt) > 0f))
			{
				m_unstickTimer = 0.25f;
				bool flag = Embedded();
				m_overlapChecks = (flag ? (m_overlapChecks + 1) : 0);
				if (!flag)
				{
					SetGhost(ghost: false);
				}
				else if (m_overlapChecks >= 3 || Time.time < m_unstickUntil)
				{
					SetGhost(ghost: true);
				}
			}
		}

		private bool Embedded()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: 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_006c: 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_0078: 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_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_0086: 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_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)
			CapsuleCollider component = ((Component)m_frame).GetComponent<CapsuleCollider>();
			if (component == null)
			{
				return false;
			}
			Vector3 forward = m_frame.forward;
			float num = component.radius * m_frame.lossyScale.x * 0.8f;
			float num2 = Mathf.Max(0f, component.height * m_frame.lossyScale.z * 0.5f - num);
			Vector3 val = m_frame.TransformPoint(component.center);
			int num3 = Physics.OverlapCapsuleNonAlloc(val - forward * num2, val + forward * num2, num, s_overlaps, s_groundMask & ~LayerMask.GetMask(new string[1] { "terrain" }), (QueryTriggerInteraction)1);
			for (int i = 0; i < num3; i++)
			{
				Collider val2 = s_overlaps[i];
				if ((Object)(object)val2.attachedRigidbody != (Object)(object)m_body && (Object)(object)((Component)val2).GetComponentInParent<Character>() == (Object)null)
				{
					return true;
				}
			}
			return false;
		}

		private void SetGhost(bool ghost)
		{
			if (ghost != m_ghost)
			{
				m_ghost = ghost;
				Collider[] componentsInChildren = ((Component)m_frame).GetComponentsInChildren<Collider>();
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					componentsInChildren[i].isTrigger = ghost;
				}
			}
		}

		private void FollowOwner()
		{
			//IL_0013: 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)
			if (!m_body.isKinematic)
			{
				m_body.linearVelocity = Vector3.zero;
				m_body.angularVelocity = Vector3.zero;
				m_body.isKinematic = true;
			}
			if ((Object)(object)m_sync != (Object)null)
			{
				m_sync.m_isKinematicBody = true;
			}
		}

		private void LogSync()
		{
			//IL_0092: 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_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			if (!SnakeWoodPlugin.SyncDebug.Value || !m_nview.IsValid())
			{
				return;
			}
			ZDO zDO = m_nview.GetZDO();
			if (zDO.DataRevision != m_lastRevision)
			{
				if (m_lastRevisionTime > 0f)
				{
					m_longestGap = Mathf.Max(m_longestGap, Time.time - m_lastRevisionTime);
				}
				m_lastRevision = zDO.DataRevision;
				m_lastRevisionTime = Time.time;
				m_updates++;
			}
			m_worstError = Mathf.Max(m_worstError, Vector3.Distance(((Component)this).transform.position, zDO.GetPosition()));
			if (!((m_syncLogTimer += Time.deltaTime) < 2f))
			{
				ManualLogSource log = SnakeWoodPlugin.Log;
				string text = string.Format("Sync {0} {1}: {2}, ", m_v.Name, ((ZDOID)(ref zDO.m_uid)).ID, m_nview.IsOwner() ? "owner" : "watching");
				string text2 = $"{(float)m_updates / m_syncLogTimer:0.#} updates/s, longest gap {m_longestGap * 1000f:0} ms, ";
				object arg = m_worstError;
				Vector3 linearVelocity = m_body.linearVelocity;
				log.LogInfo((object)(text + text2 + $"worst offset from latest update {arg:0.00} m, speed {((Vector3)(ref linearVelocity)).magnitude:0.#} m/s, kinematic {m_body.isKinematic}"));
				m_syncLogTimer = 0f;
				m_updates = 0;
				m_longestGap = 0f;
				m_worstError = 0f;
			}
		}

		private static void FindCartEffects()
		{
			if (s_hitEffect == null)
			{
				ZNetScene instance = ZNetScene.instance;
				object obj;
				if (instance == null)
				{
					obj = null;
				}
				else
				{
					GameObject prefab = instance.GetPrefab("Cart");
					obj = ((prefab != null) ? prefab.GetComponent<WearNTear>() : null);
				}
				WearNTear val = (WearNTear)obj;
				if (val != null)
				{
					s_hitEffect = val.m_hitEffect;
					s_breakEffect = val.m_destroyedEffect;
				}
			}
		}

		private void RPC_Hit(long sender, Vector3 point, bool wrecked)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: 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)
			FindCartEffects();
			EffectList? obj = (wrecked ? s_breakEffect : s_hitEffect);
			if (obj != null)
			{
				obj.Create(point, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID));
			}
			m_shakeUntil = Time.time + (wrecked ? 0.6f : 0.3f);
		}

		private void UpdateShake()
		{
			//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_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			if (Time.time < m_shakeUntil)
			{
				m_frame.localPosition = Random.insideUnitSphere * 0.05f;
			}
			else if (m_frame.localPosition != Vector3.zero)
			{
				m_frame.localPosition = Vector3.zero;
			}
		}

		private void CheckHitchKey()
		{
			//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)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)m_sled == (Object)null || (Object)(object)localPlayer == (Object)null || !m_nview.IsValid())
			{
				return;
			}
			KeyboardShortcut value = SnakeWoodPlugin.HitchKey.Value;
			if (((KeyboardShortcut)(ref value)).IsDown() && ((Character)localPlayer).TakeInput())
			{
				GameObject hoverObject = ((Humanoid)localPlayer).GetHoverObject();
				if (hoverObject != null && !((Object)(object)hoverObject.GetComponentInParent<HoverLog>() != (Object)(object)this) && InUseDistance((Humanoid)(object)localPlayer))
				{
					m_sled.Hitch(localPlayer);
				}
			}
		}

		private void CheckUnhitchKey()
		{
			//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)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)m_sled == (Object)null || (Object)(object)localPlayer == (Object)null || !m_nview.IsValid())
			{
				return;
			}
			KeyboardShortcut value = SnakeWoodPlugin.UnhitchKey.Value;
			if (((KeyboardShortcut)(ref value)).IsDown() && ((Character)localPlayer).TakeInput())
			{
				GameObject hoverObject = ((Humanoid)localPlayer).GetHoverObject();
				if (hoverObject != null && !((Object)(object)hoverObject.GetComponentInParent<HoverLog>() != (Object)(object)this) && InUseDistance((Humanoid)(object)localPlayer))
				{
					m_sled.Unhitch(localPlayer);
				}
			}
		}

		private void CheckTakeFuelKey()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || !FuelEnabled || !m_nview.IsValid())
			{
				return;
			}
			KeyboardShortcut value = SnakeWoodPlugin.TakeFuelKey.Value;
			if (((KeyboardShortcut)(ref value)).IsDown() && ((Character)localPlayer).TakeInput())
			{
				GameObject hoverObject = ((Humanoid)localPlayer).GetHoverObject();
				if (hoverObject != null && !((Object)(object)hoverObject.GetComponentInParent<HoverLog>() != (Object)(object)this) && InUseDistance((Humanoid)(object)localPlayer))
				{
					TakeFuelOut(localPlayer);
				}
			}
		}

		public void OnUseStop(Player player)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			if (m_nview.IsValid())
			{
				ZNetView nview = m_nview;
				object[] array = new object[1];
				ZDOID zDOID = ((Character)player).GetZDOID();
				array[0] = ((ZDOID)(ref zDOID)).UserID;
				nview.InvokeRPC("SnakeWood_ReleaseControl", array);
				RidingControlsPatch.ResetStance();
				((Character)player).AttachStop();
				ResetControls();
			}
		}

		public Component GetControlledComponent()
		{
			return (Component)(object)m_frame;
		}

		internal float FrameYaw()
		{
			//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_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: 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)
			Vector3 forward = m_frame.forward;
			forward.y = 0f;
			if (!(((Vector3)(ref forward)).sqrMagnitude > 0.0001f))
			{
				return ((Component)this).transform.eulerAngles.y;
			}
			Quaternion val = Quaternion.LookRotation(forward);
			return ((Quaternion)(ref val)).eulerAngles.y;
		}

		public Vector3 GetPosition()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return m_attachPoint.position;
		}

		public bool IsValid()
		{
			return Object.op_Implicit((Object)(object)this);
		}

		public void QueueHop()
		{
			m_hopQueued = true;
		}

		private void ResetControls()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			m_exhausted = false;
			m_moveInput = Vector3.zero;
			m_lookDir = m_frame.forward;
			m_boost = false;
			m_brake = false;
			m_crouchHeld = false;
			m_hopQueued = false;
		}

		private long GetUser()
		{
			if (!m_nview.IsValid())
			{
				return 0L;
			}
			return m_nview.GetZDO().GetLong(ZDOVars.s_user, 0L);
		}

		private bool IsLocalUser()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return false;
			}
			long user = GetUser();
			if (user != 0L)
			{
				ZDOID zDOID = ((Character)localPlayer).GetZDOID();
				return user == ((ZDOID)(ref zDOID)).UserID;
			}
			return false;
		}

		private bool IsLocallyDriven()
		{
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer != (Object)null && (object)localPlayer.GetDoodadController() == this)
			{
				return IsLocalUser();
			}
			return false;
		}

		private void CalculateHaveValidUser()
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			m_haveValidUser = false;
			long user = GetUser();
			if (user == 0L)
			{
				return;
			}
			foreach (ZDO allCharacterZDO in ZNet.instance.GetAllCharacterZDOS())
			{
				if (((ZDOID)(ref allCharacterZDO.m_uid)).UserID == user)
				{
					m_haveValidUser = Vector3.Distance(allCharacterZDO.GetPosition(), ((Component)this).transform.position) < 10f;
					break;
				}
			}
		}

		private void CarryPassenger()
		{
			//IL_0042: 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_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: 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_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_025a: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: 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_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			float num = FrameYaw();
			float num2 = (float.IsNaN(m_lastSeenYaw) ? 0f : Mathf.DeltaAngle(m_lastSeenYaw, num));
			m_lastSeenYaw = num;
			float num3 = (float.IsNaN(m_lastSeenY) ? 0f : (m_body.position.y - m_lastSeenY));
			m_lastSeenY = m_body.position.y;
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsAttached() || ((Character)localPlayer).IsTeleporting())
			{
				m_holdingPassenger = false;
				return;
			}
			bool flag = (Object)(object)((Character)localPlayer).m_lastGroundBody == (Object)(object)m_body && ((Character)localPlayer).IsOnGround();
			Vector3 pointVelocity = m_body.GetPointVelocity(((Character)localPlayer).m_body.position);
			if (((Character)localPlayer).m_body.linearVelocity.y - pointVelocity.y > 2.5f)
			{
				m_lastOnDeck = -10f;
				m_holdingPassenger = false;
				return;
			}
			if (flag)
			{
				m_lastOnDeck = Time.time;
			}
			else if (Time.time - m_lastOnDeck > SnakeWoodPlugin.PassengerGrip.Value || !OverDeck(((Character)localPlayer).m_body.position))
			{
				m_holdingPassenger = false;
				return;
			}
			Quaternion val = Quaternion.Euler(0f, num2, 0f);
			((Component)localPlayer).transform.rotation = val * ((Component)localPlayer).transform.rotation;
			Vector3 val2;
			if (((Vector3)(ref ((Character)localPlayer).m_moveDir)).sqrMagnitude > 0.01f)
			{
				m_holdingPassenger = false;
				Vector3 position = m_body.position;
				val2 = position + val * (((Character)localPlayer).m_body.position - position) + Vector3.up * num3;
				if (!flag)
				{
					((Character)localPlayer).m_body.linearVelocity = new Vector3(((Character)localPlayer).m_body.linearVelocity.x, pointVelocity.y, ((Character)localPlayer).m_body.linearVelocity.z);
				}
			}
			else
			{
				if (!m_holdingPassenger)
				{
					m_holdingPassenger = true;
					m_passengerSpot = m_frame.InverseTransformPoint(((Character)localPlayer).m_body.position);
				}
				val2 = m_frame.TransformPoint(m_passengerSpot);
				((Character)localPlayer).m_body.linearVelocity = m_body.GetPointVelocity(val2);
			}
			((Character)localPlayer).m_body.position = val2;
			((Component)localPlayer).transform.position = val2;
		}

		private bool OverDeck(Vector3 point)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_005b: 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_006c: 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_0072: 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_008a: 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_00a1: 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_00ba: Unknown result type (might be due to invalid IL or missing references)
			if (m_deck == null)
			{
				Transform obj = m_frame.Find("deck");
				m_deck = ((obj != null) ? ((Component)obj).GetComponent<BoxCollider>() : null);
			}
			if ((Object)(object)m_deck == (Object)null)
			{
				return false;
			}
			Vector3 val = ((Component)m_deck).transform.InverseTransformPoint(point) - m_deck.center;
			Vector3 val2 = m_deck.size * 0.5f;
			float num = (val.y - val2.y) * ((Component)m_deck).transform.lossyScale.y;
			if (Mathf.Abs(val.x) <= val2.x + 0.1f && Mathf.Abs(val.z) <= val2.z + 0.1f && num > -0.3f)
			{
				return num < 1.2f;
			}
			return false;
		}

		private void FixedUpdate()
		{
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: 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_0104: 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_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_027d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cb: 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_02d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_044f: Unknown result type (might be due to invalid IL or missing references)
			//IL_045a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0460: Unknown result type (might be due to invalid IL or missing references)
			//IL_0465: Unknown result type (might be due to invalid IL or missing references)
			//IL_0471: 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_049b: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0367: Unknown result type (might be due to invalid IL or missing references)
			//IL_035a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0549: Unknown result type (might be due to invalid IL or missing references)
			//IL_0600: Unknown result type (might be due to invalid IL or missing references)
			//IL_0557: Unknown result type (might be due to invalid IL or missing references)
			//IL_077e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0783: Unknown result type (might be due to invalid IL or missing references)
			//IL_0785: Unknown result type (might be due to invalid IL or missing references)
			//IL_0787: Unknown result type (might be due to invalid IL or missing references)
			//IL_078c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0791: Unknown result type (might be due to invalid IL or missing references)
			//IL_0793: Unknown result type (might be due to invalid IL or missing references)
			//IL_0795: Unknown result type (might be due to invalid IL or missing references)
			//IL_079a: Unknown result type (might be due to invalid IL or missing references)
			//IL_079f: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0711: Unknown result type (might be due to invalid IL or missing references)
			//IL_0713: Unknown result type (might be due to invalid IL or missing references)
			//IL_0718: Unknown result type (might be due to invalid IL or missing references)
			//IL_071c: Unknown result type (might be due to invalid IL or missing references)
			//IL_08f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_08f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0902: Unknown result type (might be due to invalid IL or missing references)
			//IL_0903: Unknown result type (might be due to invalid IL or missing references)
			//IL_099a: Unknown result type (might be due to invalid IL or missing references)
			//IL_099e: Unknown result type (might be due to invalid IL or missing references)
			//IL_09a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_09a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_09ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_09b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_09b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_09c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_09c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_09cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_09de: Unknown result type (might be due to invalid IL or missing references)
			//IL_09e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0969: Unknown result type (might be due to invalid IL or missing references)
			//IL_096c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0975: Unknown result type (might be due to invalid IL or missing references)
			//IL_0aba: Unknown result type (might be due to invalid IL or missing references)
			//IL_0abf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ad8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0add: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ae1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ae6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b18: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b1d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b1f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b24: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b26: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b3d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b42: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b47: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b55: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b5a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b5d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b62: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b6e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b7e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0af8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0afd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b06: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b0b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b11: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b16: Unknown result type (might be due to invalid IL or missing references)
			if (!m_nview.IsValid())
			{
				return;
			}
			CarryPassenger();
			if (!m_nview.IsOwner())
			{
				FollowOwner();
				return;
			}
			if ((Object)(object)m_sync != (Object)null)
			{
				m_sync.m_isKinematicBody = false;
			}
			float fixedDeltaTime = Time.fixedDeltaTime;
			m_validUserTimer -= fixedDeltaTime;
			if (m_validUserTimer <= 0f)
			{
				m_validUserTimer = 1f;
				CalculateHaveValidUser();
			}
			bool flag = IsLocallyDriven();
			if (MountedPortal.Holds(this))
			{
				m_body.linearVelocity = Vector3.zero;
				return;
			}
			if (!flag)
			{
				ResetControls();
			}
			if (IsWrecked())
			{
				HoldWreck();
				return;
			}
			m_wreckSettled = false;
			m_body.isKinematic = false;
			m_body.useGravity = false;
			if (flag || Time.time < m_unstickUntil)
			{
				UpdateUnstick(fixedDeltaTime);
			}
			else
			{
				SetGhost(ghost: false);
			}
			Vector3 position = m_body.position;
			Vector3 vel = m_body.linearVelocity;
			GetSurface(position, out var height, out var normal, out var overWater, out var waterDepth);
			bool flag2 = overWater && waterDepth > SnakeWoodPlugin.DeepWaterDepth.Value;
			if (flag && !UpdateRiderStamina(fixedDeltaTime))
			{
				flag = false;
			}
			if (flag && !UpdateLoad(fixedDeltaTime))
			{
				flag = false;
			}
			float num = (flag ? Performance(m_load) : 1f);
			bool flag3 = flag && !BurnFuel(fixedDeltaTime);
			bool flag4 = flag && flag3;
			if (flag4)
			{
				m_boost = false;
				m_hopQueued = false;
			}
			if (flag && overWater && m_v.IsFish && m_attachPoint.position.y < height + 0.05f)
			{
				Player localPlayer = Player.m_localPlayer;
				if (localPlayer != null)
				{
					((Character)localPlayer).GetSEMan().AddStatusEffect(SEMan.s_statusEffectWet, true, 0, 0f, (short)(-1));
				}
			}
			if (flag && overWater && m_attachPoint.position.y < height - (m_v.IsFish ? 0.9f : 0.3f))
			{
				ThrowRider("You went under and lost your grip");
				flag = false;
			}
			float num2 = Mathf.Sqrt(num);
			float num3 = num;
			bool flag5 = m_crouchHeld && SnakeWoodPlugin.Crouch.Value == CrouchAction.Lower;
			float value = m_v.MaxClimbCfg.Value;
			float num4 = ((overWater && (!flag || flag2)) ? 0.15f : ((flag4 || flag5) ? 0.25f : Mathf.Max(0.25f, m_v.HoverHeightCfg.Value * num2 * MovingHeightFactor(vel))));
			bool flag6 = m_v.IsFish && overWater;
			if (flag6)
			{
				float num5 = SnakeWoodPlugin.SeatHeight.Value + m_seatLift;
				normal = new Vector3(vel.x, 0f, vel.z);
				float num6 = Mathf.Clamp01(((Vector3)(ref normal)).magnitude / Mathf.Max(1f, 0.6f * m_v.MaxSpeedCfg.Value));
				num4 = Mathf.Lerp(-0.3f, 0.05f, num6) - num5;
			}
			float num7 = 0f;
			if (flag && SnakeWoodPlugin.PitchControl.Value && !flag5 && (Object)(object)m_sled == (Object)null)
			{
				float y = ((((Vector3)(ref m_lookDir)).sqrMagnitude > 0.001f) ? ((Vector3)(ref m_lookDir)).normalized : Vector3.zero).y;
				num7 = ((Mathf.Abs(y) <= 0.15f) ? 0f : Mathf.Clamp((y - Mathf.Sign(y) * 0.15f) / 0.45f, -1f, 1f));
			}
			float num8 = Mathf.Max(0f, Vector3.Dot(vel, Quaternion.Euler(0f, m_yaw, 0f) * Vector3.forward));
			if (num7 > 0f)
			{
				num4 += Mathf.Min(3f, num7 * num8 * 0.25f);
			}
			else if (num7 < 0f && flag6)
			{
				num4 += num7 * 0.3f;
			}
			else if (num7 < 0f)
			{
				num4 = Mathf.Max(Mathf.Min(0.3f, num4), num4 * (1f + num7 * 0.4f));
			}
			normal = new Vector3(vel.x, 0f, vel.z);
			float magnitude = ((Vector3)(ref normal)).magnitude;
			FitToGround(position, height, Quaternion.Euler(0f, m_yaw, 0f), magnitude, value, out var baseY, out var up);
			float num9 = baseY + num4 - position.y;
			float num10 = Physics.gravity.y * m_v.FallGravityCfg.Value * (1f + Mathf.Max(0f, 0f - num7) * 1.5f);
			if (m_airborne && vel.y <= 0f && num9 > -0.2f)
			{
				m_airborne = false;
			}
			bool flag7 = m_airborne || num9 < -1.5f;
			if (!flag7)
			{
				m_airHopsUsed = 0;
			}
			float num11 = (((Object)(object)m_sled != (Object)null) ? 16f : 30f);
			if (m_wasInAir && !flag7 && vel.y < -1.5f)
			{
				m_cushion = Mathf.Clamp((0f - vel.y) * 0.08f, 0.35f, 0.8f);
				m_cushionLength = m_cushion;
			}
			m_wasInAir = flag7;
			float num12 = 60f;
			if (m_cushion > 0f)
			{
				m_cushion -= fixedDeltaTime;
				float num13 = 1f - Mathf.Clamp01(m_cushion / m_cushionLength);
				num11 = Mathf.Lerp(6f, num11, num13 * num13);
				num12 = Mathf.Lerp(18f, 60f, num13);
			}
			vel.y += (flag7 ? num10 : Mathf.Clamp(num9 * num11 - vel.y * 2f * Mathf.Sqrt(num11), -60f, num12)) * fixedDeltaTime;
			if (m_hopQueued)
			{
				m_hopQueued = false;
				TryHop(ref vel, flag7, num10, num);
			}
			float num14 = Mathf.Clamp(m_moveInput.z, -1f, 1f);
			float num15 = Mathf.Clamp(m_moveInput.x, -1f, 1f);
			float num16 = m_v.TurnSpeedCfg.Value * num3;
			float num17 = 0f;
			float num18;
			if (SnakeWoodPlugin.Steering.Value == SteeringMode.Keys || !flag || (Object)(object)m_sled != (Object)null)
			{
				num18 = num15;
			}
			else
			{
				Vector3 lookDir = m_lookDir;
				lookDir.y = 0f;
				float num19;
				if ((num14 == 0f && Speed < 1f) || m_freeLook || !(((Vector3)(ref lookDir)).sqrMagnitude > 0.001f))
				{
					num19 = 0f;
				}
				else
				{
					float yaw = m_yaw;
					Quaternion val = Quaternion.LookRotation(lookDir);
					num19 = Mathf.DeltaAngle(yaw, ((Quaternion)(ref val)).eulerAngles.y);
				}
				num18 = Mathf.Clamp(num19 / (m_v.IsFish ? 75f : 30f), -1f, 1f);
				num17 = num15;
			}
			m_yaw += num18 * num16 * fixedDeltaTime;
			Quaternion val2 = Quaternion.Euler(0f, m_yaw, 0f);
			Vector3 val3 = val2 * Vector3.forward;
			Vector3 val4 = val2 * Vector3.right;
			bool flag8 = flag && m_exhausted;
			float num20 = TopSpeedAt(overWater) * (flag2 ? m_v.DeepWaterSpeedCfg.Value : 1f) * ((flag4 || flag8) ? 0.3f : 1f) * num * (flag5 ? 0.35f : 1f);
			bool flag9 = m_boost && num14 > 0f && flag && UseBoostStamina(fixedDeltaTime);
			float num21 = num20 * (flag9 ? m_v.BoostCfg.Value : 1f);
			float num22 = ((num14 >= 0f) ? (num14 * num21) : (num14 * num20 * 0.4f));
			float num23 = num17 * num20 * 0.5f;
			bool flag10 = m_brake || (m_crouchHeld && SnakeWoodPlugin.Crouch.Value == CrouchAction.Brake);
			if (flag10)
			{
				num22 = 0f;
				num23 = 0f;
			}
			float num24 = (((Object)(object)m_sled != (Object)null) ? m_sled.Acceleration() : m_v.AccelerationCfg.Value) * num3;
			float num25 = num24 * (flag10 ? 3f : 1.5f) * (flag2 ? 2f : 1f);
			float num26 = Vector3.Dot(vel, val3);
			float num27 = Vector3.Dot(vel, val4);
			num26 = Mathf.MoveTowards(num26, num22, ((Mathf.Abs(num22) > Mathf.Abs(num26) && Mathf.Sign(num22) == Mathf.Sign(num26)) ? num24 : num25) * fixedDeltaTime);
			num27 = Mathf.MoveTowards(num27, num23, ((num23 != 0f) ? num24 : m_v.Grip) * fixedDeltaTime);
			if (!flag7 && TooSteepAhead(position, height, val3 * Mathf.Sign(num26), Mathf.Abs(num26), value))
			{
				num26 = (0f - Mathf.Sign(num26)) * 0.5f;
			}
			Vector3 val5 = val3 * num26 + val4 * num27;
			m_body.linearVelocity = new Vector3(val5.x, vel.y, val5.z);
			m_driveVelocity = m_body.linearVelocity;
			float num28 = (0f - num18) * Mathf.Clamp01(Mathf.Abs(num26) / Mathf.Max(1f, m_v.MaxSpeedCfg.Value)) * 18f;
			m_roll = Mathf.Lerp(m_roll, num28, 4f * fixedDeltaTime);
			float num29 = Mathf.Min(SnakeWoodPlugin.MaxPitch.Value * (m_v.IsFish ? 1.5f : 1f), value);
			m_pitch = Mathf.Lerp(m_pitch, num7 * num29, (m_v.IsFish ? 2.5f : 4f) * fixedDeltaTime);
			float num30 = (flag7 ? 0f : (((Object)(object)m_sled != (Object)null) ? 0.4f : 1f));
			float num31 = Vector3.Angle(Vector3.up, up);
			if (num31 * num30 > value)
			{
				num30 = value / num31;
			}
			Vector3 val6 = Vector3.Slerp(Vector3.up, up, num30);
			if ((Object)(object)m_sled != (Object)null)
			{
				m_smoothUp = Vector3.Slerp(m_smoothUp, val6, 2.5f * fixedDeltaTime);
				val6 = m_smoothUp;
			}
			Quaternion val7 = Quaternion.FromToRotation(Vector3.up, val6) * val2 * Quaternion.Euler(0f - m_pitch, 0f, m_roll);
			m_body.MoveRotation(Quaternion.Slerp(m_body.rotation, val7 * m_disguiseOffset, 8f * fixedDeltaTime));
			m_body.angularVelocity = Vector3.zero;
			if (flag)
			{
				UpdatePoisonCloud(fixedDeltaTime);
				MakeNoise(Mathf.Abs(num26));
			}
		}

		private void MakeNoise(float speed)
		{
			Player localPlayer = Player.m_localPlayer;
			float value = m_v.NoiseCfg.Value;
			if (!((Object)(object)localPlayer == (Object)null) && !(value <= 0f))
			{
				float num = Mathf.Clamp01(speed / Mathf.Max(1f, m_v.MaxSpeedCfg.Value));
				float num2 = Mathf.Lerp(SnakeWoodPlugin.NoiseAtRest.Value, SnakeWoodPlugin.NoiseAtSpeed.Value, num) * value;
				if (num2 > 0f)
				{
					((Character)localPlayer).AddNoise(num2);
				}
			}
		}

		private bool TooSteepAhead(Vector3 pos, float surfaceY, Vector3 direction, float speed, float climb)
		{
			//IL_0034: 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_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: 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)
			if (speed < 0.2f || float.IsNegativeInfinity(surfaceY))
			{
				return false;
			}
			float num = 1.2f + 0.5f * m_v.Length + speed * 0.1f;
			Vector3 val = pos + direction * num;
			val.y = surfaceY + num * 4f + 1f;
			if (s_terrainMask == 0)
			{
				s_terrainMask = LayerMask.GetMask(new string[1] { "terrain" });
			}
			RaycastHit val2 = default(RaycastHit);
			float num2 = (Physics.Raycast(val, Vector3.down, ref val2, num * 8f + 2f, s_terrainMask, (QueryTriggerInteraction)1) ? ((RaycastHit)(ref val2)).point.y : float.NegativeInfinity);
			if (float.IsNegativeInfinity(num2) || ((Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.m_waterLevel >= num2))
			{
				return false;
			}
			return Mathf.Atan2(num2 - surfaceY, num) * 57.29578f > climb;
		}

		private void TryHop(ref Vector3 vel, bool inAir, float airGravity, float heightFactor)
		{
			float num = m_v.HopHeightCfg.Value * heightFactor;
			if (num <= 0f || (inAir && m_airHopsUsed >= m_v.AirHopsCfg.Value))
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			float value = SnakeWoodPlugin.HopStamina.Value;
			if ((Object)(object)localPlayer != (Object)null && value > 0f)
			{
				if (!((Character)localPlayer).HaveStamina(value))
				{
					Hud instance = Hud.instance;
					if (instance != null)
					{
						instance.StaminaBarEmptyFlash();
					}
					return;
				}
				((Character)localPlayer).UseStamina(value);
			}
			if (inAir)
			{
				m_airHopsUsed++;
			}
			vel.y = Mathf.Max(vel.y, Mathf.Sqrt(2f * (0f - airGravity) * num));
			m_airborne = true;
		}

		private bool UpdateRiderStamina(float dt)
		{
			Player localPlayer = Player.m_localPlayer;
			float num = m_v.RideStaminaCfg.Value;
			if ((Object)(object)localPlayer == (Object)null || num <= 0f)
			{
				return true;
			}
			if (m_exhausted)
			{
				if (localPlayer.GetStamina() < 0.25f * ((Character)localPlayer).GetMaxStamina())
				{
					return true;
				}
				m_exhausted = false;
			}
			if (((Object)(object)m_sled != (Object)null || !SnakeWoodPlugin.DrainWhenStill.Value) && Speed < 0.5f)
			{
				return true;
			}
			if (localPlayer.GetStamina() <= 0f)
			{
				if ((Object)(object)m_sled != (Object)null || m_v.IsFish)
				{
					m_exhausted = true;
					((Character)localPlayer).Message((MessageType)2, "Too tired: crawling along until you catch your breath", 0, (Sprite)null, false);
					return true;
				}
				ThrowRider("You're too tired to hold on");
				return false;
			}
			float num2 = SnakeWoodPlugin.EitrPerSecond.Value * dt;
			if (num2 > 0f && ((Character)localPlayer).GetMaxEitr() > 0f && ((Character)localPlayer).HaveEitr(num2))
			{
				((Character)localPlayer).UseEitr(num2);
				num *= SnakeWoodPlugin.EitrStaminaFactor.Value;
			}
			((Character)localPlayer).UseStamina(num * dt);
			return true;
		}

		private bool UseBoostStamina(float dt)
		{
			Player localPlayer = Player.m_localPlayer;
			float value = SnakeWoodPlugin.BoostStamina.Value;
			if ((Object)(object)localPlayer == (Object)null || value <= 0f)
			{
				return true;
			}
			if (localPlayer.GetStamina() <= value * dt)
			{
				return false;
			}
			((Character)localPlayer).UseStamina(value * dt);
			return true;
		}

		private void ThrowRider(string message)
		{
			//IL_001f: 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_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer == (Object)null) && (object)localPlayer.GetDoodadController() == this)
			{
				Vector3 linearVelocity = m_body.linearVelocity;
				localPlayer.StopDoodadControl();
				((Character)localPlayer).AttachStop();
				((Character)localPlayer).m_body.linearVelocity = linearVelocity * 0.7f + Vector3.up * 3f;
				((Character)localPlayer).Message((MessageType)2, message, 0, (Sprite)null, false);
			}
		}

		private void FitToGround(Vector3 pos, float centreY, Quaternion heading, float speed, float climb, out float baseY, out Vector3 up)
		{
			//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_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_0057: 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_00da: 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_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: 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_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: 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_023f: 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_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			baseY = centreY;
			up = Vector3.up;
			float maxSlope;
			Vector3 forward;
			Vector3 right;
			if (!float.IsNegativeInfinity(centreY))
			{
				float num = 0.45f * m_v.Length * Mathf.Max(1f, m_frame.localScale.z);
				float num2 = (((Object)(object)m_sled != (Object)null) ? 0.7f : Mathf.Max(0.3f, 0.225f * m_v.Thickness * Mathf.Max(1f, m_frame.localScale.x)));
				maxSlope = Mathf.Tan(Mathf.Min(climb + 10f, 80f) * (MathF.PI / 180f));
				forward = heading * Vector3.forward;
				right = heading * Vector3.right;
				float num3 = Sample(0f - num, 0f);
				float num4 = Sample(num, 0f);
				float num5 = Sample(0f, 0f - num2);
				float num6 = Sample(0f, num2);
				float num7 = num + Mathf.Min(3f, speed * 0.15f);
				float num8 = Sample(num7, 0f);
				float num9 = Mathf.Tan(climb * (MathF.PI / 180f));
				float num10 = Mathf.Clamp((num4 - num3) / (2f * num), 0f - num9, num9);
				float num11 = Mathf.Clamp((num6 - num5) / (2f * num2), 0f - num9, num9) * 0.7f;
				baseY = Mathf.Max(new float[6]
				{
					centreY,
					num3 + num10 * num,
					num4 - num10 * num,
					num5 + num11 * num2,
					num6 - num11 * num2,
					num8 - num10 * num7 - 0.15f
				});
				Vector3 val = forward + Vector3.up * num10;
				Vector3 normalized = ((Vector3)(ref val)).normalized;
				val = right + Vector3.up * num11;
				Vector3 normalized2 = ((Vector3)(ref val)).normalized;
				val = Vector3.Cross(normalized, normalized2);
				up = ((Vector3)(ref val)).normalized;
			}
			float Sample(float along, float across)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				float num12 = GroundAt(pos + forward * along + right * across, pos.y + 1.5f);
				float num13 = Mathf.Abs(along) + Mathf.Abs(across);
				if (!float.IsNegativeInfinity(num12) && !(Mathf.Abs(num12 - centreY) > num13 * maxSlope + 0.3f))
				{
					return num12;
				}
				return centreY;
			}
		}

		private float GroundAt(Vector3 point, float fromY)
		{
			//IL_000e: 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_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_0070: 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)
			point.y = fromY;
			float num = float.NegativeInfinity;
			int num2 = Physics.RaycastNonAlloc(point, Vector3.down, s_hits, 60f, s_groundMask, (QueryTriggerInteraction)1);
			float num3 = float.MaxValue;
			for (int i = 0; i < num2; i++)
			{
				RaycastHit val = s_hits[i];
				if (!((Object)(object)((RaycastHit)(ref val)).collider.attachedRigidbody == (Object)(object)m_body) && !(((RaycastHit)(ref val)).distance >= num3))
				{
					num3 = ((RaycastHit)(ref val)).distance;
					num = ((RaycastHit)(ref val)).point.y;
				}
			}
			ZoneSystem instance = ZoneSystem.instance;
			if (instance != null)
			{
				if (float.IsNegativeInfinity(num))
				{
					num = instance.GetGroundHeight(point);
				}
				num = Mathf.Max(num, instance.m_waterLevel);
			}
			return num;
		}

		private void GetSurface(Vector3 pos, out float height, out Vector3 normal, out bool overWater, out float waterDepth)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: 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_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			height = float.NegativeInfinity;
			normal = Vector3.up;
			int num = Physics.RaycastNonAlloc(pos + Vector3.up * 1f, Vector3.down, s_hits, 60f, s_groundMask, (QueryTriggerInteraction)1);
			float num2 = float.MaxValue;
			for (int i = 0; i < num; i++)
			{
				RaycastHit val = s_hits[i];
				if (!((Object)(object)((RaycastHit)(ref val)).collider.attachedRigidbody == (Object)(object)m_body) && !(((RaycastHit)(ref val)).distance >= num2))
				{
					num2 = ((RaycastHit)(ref val)).distance;
					height = ((RaycastHit)(ref val)).point.y;
					normal = ((RaycastHit)(ref val)).normal;
				}
			}
			overWater = false;
			waterDepth = 0f;
			ZoneSystem instance = ZoneSystem.instance;
			if (!((Object)(object)instance == (Object)null))
			{
				float groundHeight = instance.GetGroundHeight(pos);
				if (float.IsNegativeInfinity(height))
				{
					height = groundHeight;
				}
				if (instance.m_waterLevel > height)
				{
					overWater = true;
					waterDepth = instance.m_waterLevel - Mathf.Min(groundHeight, height);
					height = instance.m_waterLevel;
					normal = Vector3.up;
				}
			}
		}

		private void UpdatePoisonCloud(float dt)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: 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_00fc: 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_019a: Expected O, but got Unknown
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			if (m_v.Fx != TrailFx.Poison || m_v.PoisonCloudCfg == null || m_v.PoisonCloudCfg.Value <= 0f)
			{
				return;
			}
			Vector3 position = ((Component)this).transform.position;
			if (m_cloud.Count == 0 || Vector3.Distance(m_cloud[m_cloud.Count -