Decompiled source of ScissorLift v1.3.1

plugins/ScissorLift.dll

Decompiled an hour ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace ScissorLift;

internal static class LiftClock
{
	private static double s_offset;

	private static double s_last = double.NaN;

	private static bool s_has;

	internal static double FixedNow => Time.fixedTimeAsDouble + Offset(Time.fixedTimeAsDouble);

	internal static double Now => Time.timeAsDouble + Offset(Time.timeAsDouble);

	internal static void Tick()
	{
		double fixedTimeAsDouble = Time.fixedTimeAsDouble;
		if (fixedTimeAsDouble != s_last)
		{
			s_last = fixedTimeAsDouble;
			if (!((Object)(object)ZNet.instance == (Object)null))
			{
				s_offset = LiftDesign.SmoothOffset(s_offset, ZNet.instance.GetTimeSeconds() - fixedTimeAsDouble, !s_has, 0.02);
				s_has = true;
			}
		}
	}

	private static double Offset(double local)
	{
		if (!s_has && (Object)(object)ZNet.instance != (Object)null)
		{
			s_offset = ZNet.instance.GetTimeSeconds() - local;
			s_has = true;
		}
		return s_offset;
	}
}
public class Lift : MonoBehaviour, Hoverable, Interactable, TextReceiver, IDoodadController
{
	internal enum Part
	{
		Lift,
		Lever,
		Pump,
		Drive
	}

	private struct Fall
	{
		internal int State;

		internal double Start;

		internal double StandStart;

		internal float Dur;

		internal float Angle;

		internal Vector3 Pivot;

		internal Vector3 Axis;

		internal Vector3 Shift;

		internal Vector3 Pos;

		internal Quaternion Rot;
	}

	private struct State
	{
		internal bool Set;

		internal float From;

		internal float Vel;

		internal float To;

		internal float Speed;

		internal float Accel;

		internal double Start;

		internal int Dir;

		internal int Seq;

		internal int Blocked;
	}

	internal static readonly int KeyTop = StringExtensionMethods.GetStableHashCode("anwo_sl_top");

	internal static readonly int KeyFrom = StringExtensionMethods.GetStableHashCode("anwo_sl_from");

	internal static readonly int KeyVel = StringExtensionMethods.GetStableHashCode("anwo_sl_vel");

	internal static readonly int KeyTo = StringExtensionMethods.GetStableHashCode("anwo_sl_to");

	internal static readonly int KeySpeed = StringExtensionMethods.GetStableHashCode("anwo_sl_speed");

	internal static readonly int KeyAccel = StringExtensionMethods.GetStableHashCode("anwo_sl_accel");

	internal static readonly int KeyStart = StringExtensionMethods.GetStableHashCode("anwo_sl_start");

	internal static readonly int KeyDir = StringExtensionMethods.GetStableHashCode("anwo_sl_dir");

	internal static readonly int KeySeq = StringExtensionMethods.GetStableHashCode("anwo_sl_seq");

	internal static readonly int KeyBlocked = StringExtensionMethods.GetStableHashCode("anwo_sl_blocked");

	internal static readonly int KeyFuel = StringExtensionMethods.GetStableHashCode("anwo_sl_fuel");

	internal static readonly int KeyDriver = StringExtensionMethods.GetStableHashCode("anwo_sl_driver");

	internal static readonly int KeySteer = StringExtensionMethods.GetStableHashCode("anwo_sl_steer");

	internal static readonly int KeyFall = StringExtensionMethods.GetStableHashCode("anwo_sl_fall");

	internal static readonly int KeyFallTime = StringExtensionMethods.GetStableHashCode("anwo_sl_fall_time");

	internal static readonly int KeyFallDur = StringExtensionMethods.GetStableHashCode("anwo_sl_fall_dur");

	internal static readonly int KeyFallPivot = StringExtensionMethods.GetStableHashCode("anwo_sl_fall_pivot");

	internal static readonly int KeyFallAxis = StringExtensionMethods.GetStableHashCode("anwo_sl_fall_axis");

	internal static readonly int KeyFallAngle = StringExtensionMethods.GetStableHashCode("anwo_sl_fall_angle");

	internal static readonly int KeyFallShift = StringExtensionMethods.GetStableHashCode("anwo_sl_fall_shift");

	internal static readonly int KeyFallPos = StringExtensionMethods.GetStableHashCode("anwo_sl_fall_pos");

	internal static readonly int KeyFallRot = StringExtensionMethods.GetStableHashCode("anwo_sl_fall_rot");

	internal static readonly int KeyStandTime = StringExtensionMethods.GetStableHashCode("anwo_sl_stand_time");

	internal const string RpcMove = "anwo_ScissorLift_Move";

	internal const string RpcTop = "anwo_ScissorLift_Top";

	internal const string RpcSay = "anwo_ScissorLift_Say";

	internal const string RpcFuel = "anwo_ScissorLift_Fuel";

	internal const string RpcLetGo = "anwo_ScissorLift_LetGo";

	internal const string RpcStand = "anwo_ScissorLift_Stand";

	internal const string RpcHold = "anwo_ScissorLift_Hold";

	internal static readonly string[] WheelNames = new string[4] { "front left", "front right", "back left", "back right" };

	private ZNetView m_nview;

	private bool m_setUp;

	private Transform m_deck;

	private Transform m_lever;

	private Transform m_groundLever;

	private Transform m_stick;

	private Transform m_face;

	private Rigidbody m_body;

	private MeshFilter m_armsFilter;

	private MeshFilter m_ramsBronzeFilter;

	private MeshFilter m_ramsSteelFilter;

	private Mesh m_armsMesh;

	private Mesh m_ramsBronzeMesh;

	private Mesh m_ramsSteelMesh;

	private readonly LiftShape m_armsShape = new LiftShape();

	private readonly LiftShape m_bronzeShape = new LiftShape();

	private readonly LiftShape m_steelShape = new LiftShape();

	private readonly Dictionary<Collider, Part> m_parts = new Dictionary<Collider, Part>();

	private float m_builtHeight = float.NaN;

	private int m_builtStages = -1;

	private uint m_rev = uint.MaxValue;

	private State m_state;

	private LiftDesign.Plan m_plan;

	private int m_seenSeq = int.MinValue;

	private float m_lastTarget = float.NaN;

	private bool m_wasMoving;

	private bool m_ownerWasMoving;

	private float m_nextIdleCheck;

	private float m_nextWake;

	private float m_moveVelocity;

	private float m_fuelUsed;

	private float m_fuelPrevH = float.NaN;

	private float m_nextFuelWrite;

	private bool m_wasOwner;

	private Vector3 m_driveInput;

	private Vector3 m_rootVel;

	private bool m_driveRun;

	private bool m_wasFast;

	private float m_driveInputTime = -100f;

	private float m_offDeckSince = -1f;

	private float m_foreignDriverSince = -1f;

	private float m_otherDriverSince = -1f;

	private float m_nextWearReset;

	private float m_speed;

	private float m_steer;

	private float m_yaw;

	private float m_writtenSteer;

	private float m_nextSteerWrite;

	private bool m_drove;

	private bool m_haveYaw;

	private Quaternion m_lastSetRot = Quaternion.identity;

	private Quaternion m_stickTilt = Quaternion.identity;

	private readonly Transform[] m_wheelTurn = (Transform[])(object)new Transform[4];

	private readonly Transform[] m_wheelSpin = (Transform[])(object)new Transform[4];

	private float m_shownSteer;

	private float m_spin;

	private Vector3 m_lastWheelPos;

	private Fall m_fall;

	private bool m_fallShown;

	private bool m_fallMoving;

	private double m_fallSeen = double.NaN;

	private double m_stillFor = double.NaN;

	private readonly List<Collider> m_offColliders = new List<Collider>();

	private RigidbodyInterpolation m_interpolation = (RigidbodyInterpolation)1;

	private float m_lastLean = float.NaN;

	private float m_nextLeanCheck;

	private AudioSource m_loop;

	private float m_loopVolume;

	private float m_baseVolume = 0.6f;

	private float m_leverAngle;

	private const int LogLimit = 6;

	private int m_logged;

	private static int s_logged;

	private static int s_loadsLogged;

	private static int s_failLogged;

	private Vector3 m_lastDeckAt;

	private Quaternion m_lastDeckRot = Quaternion.identity;

	private static int s_charMask;

	private static int s_solidMask;

	private static int s_downMask;

	private static int s_itemMask;

	private static readonly Collider[] s_found = (Collider[])(object)new Collider[48];

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

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

	private static int s_leanLogs;

	private static int s_stageLogs;

	private GameObject m_ramps;

	private readonly List<BoxCollider> m_rampBoxes = new List<BoxCollider>();

	private float m_rampsFor = float.NaN;

	private bool m_rampsOn;

	private static int s_rampLogs;

	private static int s_rampLayer = -2;

	private float m_nextCheck;

	private static int s_mismatches;

	private static int s_highLogs;

	private static int s_reports;

	private float m_reportAt = float.MaxValue;

	private AudioSource m_beep;

	private float m_nextBeep;

	private float m_nextWheelCheck;

	private bool m_wheelOff;

	private string m_wheelOffText = "";

	private int m_beepMode;

	private static int s_beepLogs;

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

	private float m_chestFuelAt = -10f;

	private int m_chestFuel = -1;

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

	private static readonly Collider[] s_itemsFound = (Collider[])(object)new Collider[32];

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

	private static readonly Collider[] s_boxNow = (Collider[])(object)new Collider[128];

	private static readonly Collider[] s_boxNext = (Collider[])(object)new Collider[128];

	private static readonly HashSet<Collider> s_already = new HashSet<Collider>();

	private static int s_boxLogs;

	private static readonly float[] s_wheelY = new float[4];

	private static int s_groundMask;

	private static int s_blockMask;

	private static FieldInfo s_wearColliders;

	private static MethodInfo s_clearSupport;

	private static bool s_wearLooked;

	private static bool s_toldHowToDrive;

	private int m_holdSent;

	private bool m_heldMove;

	private static int s_holdLogs;

	private int m_holdDir;

	private long m_holdSender;

	private bool m_holdNew;

	private bool m_holdWaitLogged;

	private static int s_keptOn;

	private float m_nextDriverReport;

	private static int s_driverReports;

	private float m_nextBlockSay;

	private float m_nextDriveLog;

	private float m_nextDeckWaitSay;

	private static int s_driveLogs;

	private static int s_fastLogs;

	private static int s_deckWaitLogs;

	private static int s_carryLogged;

	private static readonly float[] s_wheelCur = new float[4];

	private static readonly float[] s_wheelNow = new float[4];

	private static readonly float[] s_wheelNext = new float[4];

	private static readonly string[] s_wheelWhy = new string[4];

	private bool Valid
	{
		get
		{
			if ((Object)(object)m_nview != (Object)null)
			{
				return m_nview.IsValid();
			}
			return false;
		}
	}

	private ZDO Zdo => m_nview.GetZDO();

	internal float Top => LiftDesign.ClampTop(Valid ? Zdo.GetFloat(KeyTop, 4f) : 4f, ScissorLiftPlugin.Highest);

	internal int Stages => LiftDesign.Stages(Top);

	internal float Bottom => LiftDesign.Lowest(Stages);

	private bool Fallen => m_fall.State != 0;

	private static bool Dedicated
	{
		get
		{
			if ((Object)(object)ZNet.instance != (Object)null)
			{
				return ZNet.instance.IsDedicated();
			}
			return false;
		}
	}

	private float RemoteSlack => 0.1f + Math.Abs(m_moveVelocity) * 0.3f;

	internal float FuelNow
	{
		get
		{
			if (!Valid)
			{
				return 0f;
			}
			return Math.Max(0f, Zdo.GetFloat(KeyFuel, 0f) - m_fuelUsed);
		}
	}

	internal long Driver
	{
		get
		{
			if (!Valid)
			{
				return 0L;
			}
			return Zdo.GetLong(KeyDriver, 0L);
		}
	}

	private bool LogMore()
	{
		if (m_logged++ < 8)
		{
			return s_logged++ < 60;
		}
		return false;
	}

	private void Awake()
	{
		m_nview = ((Component)this).GetComponent<ZNetView>();
		SetUp();
	}

	private void Start()
	{
		SetUp();
	}

	private void SetUp()
	{
		//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01dd: Expected O, but got Unknown
		//IL_0269: Unknown result type (might be due to invalid IL or missing references)
		//IL_026e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0287: Unknown result type (might be due to invalid IL or missing references)
		//IL_0295: Unknown result type (might be due to invalid IL or missing references)
		//IL_029a: Unknown result type (might be due to invalid IL or missing references)
		if (m_setUp || !Valid)
		{
			return;
		}
		m_setUp = true;
		m_deck = ((Component)this).transform.Find("anwo_sl_deck");
		m_lever = (((Object)(object)m_deck != (Object)null) ? m_deck.Find("anwo_sl_lever") : null);
		m_stick = (((Object)(object)m_deck != (Object)null) ? m_deck.Find("anwo_sl_stick") : null);
		Transform val = ((Component)this).transform.Find("anwo_sl_groundpost");
		m_groundLever = (((Object)(object)val != (Object)null) ? val.Find("anwo_sl_groundlever") : null);
		m_body = (((Object)(object)m_deck != (Object)null) ? ((Component)m_deck).GetComponent<Rigidbody>() : null);
		Transform val2 = ((Component)this).transform.Find("anwo_sl_arms");
		m_armsFilter = (((Object)(object)val2 != (Object)null) ? ((Component)val2).GetComponent<MeshFilter>() : null);
		Transform val3 = ((Component)this).transform.Find("anwo_sl_rams_bronze");
		Transform val4 = ((Component)this).transform.Find("anwo_sl_rams_steel");
		m_ramsBronzeFilter = (((Object)(object)val3 != (Object)null) ? ((Component)val3).GetComponent<MeshFilter>() : null);
		m_ramsSteelFilter = (((Object)(object)val4 != (Object)null) ? ((Component)val4).GetComponent<MeshFilter>() : null);
		Collider[] componentsInChildren = ((Component)this).GetComponentsInChildren<Collider>(true);
		foreach (Collider val5 in componentsInChildren)
		{
			if (!((Object)(object)val5 == (Object)null))
			{
				string name = ((Object)((Component)val5).gameObject).name;
				Dictionary<Collider, Part> parts = m_parts;
				int value;
				switch (name)
				{
				default:
					value = 0;
					break;
				case "anwo_sl_post":
				case "anwo_sl_groundpost":
					value = 1;
					break;
				case "anwo_sl_drive":
					value = 3;
					break;
				case "anwo_sl_pump":
					value = 2;
					break;
				}
				parts[val5] = (Part)value;
			}
		}
		GameObject val6 = new GameObject("anwo_sl_face");
		val6.transform.SetParent(((Component)this).transform, false);
		m_face = val6.transform;
		for (int j = 0; j < 4; j++)
		{
			m_wheelTurn[j] = ((Component)this).transform.Find("anwo_sl_wheel" + j);
			m_wheelSpin[j] = (((Object)(object)m_wheelTurn[j] != (Object)null) ? m_wheelTurn[j].Find("anwo_sl_spin") : null);
		}
		m_lastWheelPos = ((Component)this).transform.position;
		if ((Object)(object)m_body != (Object)null && (int)m_body.interpolation != 0)
		{
			m_interpolation = m_body.interpolation;
		}
		LiftLook.Refresh();
		LiftLook.Dress(((Component)this).transform);
		if (s_reports < 2)
		{
			m_reportAt = Time.time + 2f;
		}
		m_nview.Register<int>("anwo_ScissorLift_Move", (Action<long, int>)RPC_Move);
		m_nview.Register("anwo_ScissorLift_Stand", (Action<long>)RPC_Stand);
		m_nview.Register<float>("anwo_ScissorLift_Top", (Action<long, float>)RPC_Top);
		m_nview.Register<string>("anwo_ScissorLift_Say", (Action<long, string>)RPC_Say);
		m_nview.Register<int>("anwo_ScissorLift_Fuel", (Action<long, int>)RPC_Fuel);
		m_nview.Register<long>("anwo_ScissorLift_LetGo", (Action<long, long>)RPC_LetGo);
		m_nview.Register<int>("anwo_ScissorLift_Hold", (Action<long, int>)RPC_Hold);
		ReadState(first: true);
		HeightAt(LiftClock.Now, out var h, out var v);
		PlaceDeck((float)h, jump: true);
		if (m_fall.State != 0)
		{
			ShowFall(LiftClock.Now);
		}
		m_wasMoving = Math.Abs(v) > 0.0001;
		m_ownerWasMoving = m_wasMoving;
		if (s_loadsLogged < 3 && h > (double)Bottom + 0.3)
		{
			s_loadsLogged++;
			ScissorLiftPlugin.Log.LogInfo((object)("Lift at " + Where() + " loaded with its deck at " + LiftDesign.Format((float)h) + " (top " + LiftDesign.Format(Top) + ", " + Stages + " stages, highest allowed " + LiftDesign.Format(ScissorLiftPlugin.Highest) + ", " + (m_nview.IsOwner() ? "run by this game" : "run by another game") + (m_state.Set ? "" : ", never moved") + ((m_fall.State != 0) ? ", fallen over" : "") + ")."));
		}
		else if (m_fall.State != 0 && s_loadsLogged < 3)
		{
			s_loadsLogged++;
			ScissorLiftPlugin.Log.LogInfo((object)("Lift at " + Where() + " loaded " + ((m_fall.State == 2) ? "being stood up again" : "lying where it fell over") + " (turned " + m_fall.Angle.ToString("0", CultureInfo.InvariantCulture) + " degrees)."));
		}
	}

	private void OnDestroy()
	{
		Mesh[] array = (Mesh[])(object)new Mesh[3] { m_armsMesh, m_ramsBronzeMesh, m_ramsSteelMesh };
		foreach (Mesh val in array)
		{
			if ((Object)(object)val != (Object)null)
			{
				Object.Destroy((Object)(object)val);
			}
		}
		m_armsMesh = (m_ramsBronzeMesh = (m_ramsSteelMesh = null));
		if ((Object)(object)m_ramps != (Object)null)
		{
			Object.Destroy((Object)(object)m_ramps);
		}
		m_ramps = null;
	}

	private void ReadState(bool first = false)
	{
		//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_0215: Unknown result type (might be due to invalid IL or missing references)
		//IL_0222: Unknown result type (might be due to invalid IL or missing references)
		//IL_0227: Unknown result type (might be due to invalid IL or missing references)
		//IL_022c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0258: Unknown result type (might be due to invalid IL or missing references)
		//IL_025d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0262: Unknown result type (might be due to invalid IL or missing references)
		//IL_0275: Unknown result type (might be due to invalid IL or missing references)
		//IL_027a: Unknown result type (might be due to invalid IL or missing references)
		//IL_027f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0292: Unknown result type (might be due to invalid IL or missing references)
		//IL_0297: Unknown result type (might be due to invalid IL or missing references)
		//IL_029c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0246: Unknown result type (might be due to invalid IL or missing references)
		//IL_024b: Unknown result type (might be due to invalid IL or missing references)
		if (!Valid)
		{
			return;
		}
		ZDO zdo = Zdo;
		if (!first && zdo.DataRevision == m_rev)
		{
			return;
		}
		m_rev = zdo.DataRevision;
		State state = default(State);
		state.To = zdo.GetFloat(KeyTo, -1f);
		state.Set = state.To >= 0f;
		state.From = zdo.GetFloat(KeyFrom, state.To);
		state.Vel = zdo.GetFloat(KeyVel, 0f);
		state.Speed = zdo.GetFloat(KeySpeed, 1f);
		state.Accel = zdo.GetFloat(KeyAccel, 1.6f);
		state.Start = (double)zdo.GetLong(KeyStart, 0L) / 1000.0;
		state.Dir = zdo.GetInt(KeyDir, 0);
		state.Seq = zdo.GetInt(KeySeq, 0);
		state.Blocked = zdo.GetInt(KeyBlocked, 0);
		m_state = state;
		m_plan = (state.Set ? LiftDesign.MakePlan(state.From, state.Vel, state.To, state.Speed, state.Accel) : default(LiftDesign.Plan));
		Fall fall = new Fall
		{
			State = zdo.GetInt(KeyFall, 0)
		};
		if (fall.State != 0)
		{
			fall.Start = (double)zdo.GetLong(KeyFallTime, 0L) / 1000.0;
			fall.StandStart = (double)zdo.GetLong(KeyStandTime, 0L) / 1000.0;
			fall.Dur = Math.Max(0.1f, zdo.GetFloat(KeyFallDur, 1.4f));
			fall.Angle = zdo.GetFloat(KeyFallAngle, 90f);
			fall.Pivot = zdo.GetVec3(KeyFallPivot, ((Component)this).transform.position);
			fall.Axis = zdo.GetVec3(KeyFallAxis, Vector3.right);
			if (((Vector3)(ref fall.Axis)).sqrMagnitude < 1E-06f)
			{
				fall.Axis = Vector3.right;
			}
			fall.Shift = zdo.GetVec3(KeyFallShift, Vector3.zero);
			fall.Pos = zdo.GetVec3(KeyFallPos, ((Component)this).transform.position);
			fall.Rot = zdo.GetQuaternion(KeyFallRot, ((Component)this).transform.rotation);
		}
		m_fall = fall;
		if (m_seenSeq != state.Seq)
		{
			bool num = m_seenSeq != int.MinValue && !first;
			m_seenSeq = state.Seq;
			if (num)
			{
				OnNewMove(state);
			}
		}
	}

	private void HeightAt(double now, out double h, out double v)
	{
		if (!m_state.Set)
		{
			h = Bottom;
			v = 0.0;
		}
		else
		{
			LiftDesign.Evaluate(m_plan, Since(now), out h, out v);
		}
	}

	private double Since(double now)
	{
		double num = now - m_state.Start;
		if (!(num < -2.0))
		{
			return num;
		}
		return double.MaxValue;
	}

	private bool MovingAt(double now)
	{
		if (m_state.Set && m_plan.Dir != 0)
		{
			return Since(now) < m_plan.End;
		}
		return false;
	}

	private int Going(float h, float v)
	{
		if (!(v > 0.0001f))
		{
			if (!(v < -0.0001f))
			{
				return Math.Sign(m_state.To - h);
			}
			return -1;
		}
		return 1;
	}

	private void FixedUpdate()
	{
		//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0188: Unknown result type (might be due to invalid IL or missing references)
		//IL_018d: Unknown result type (might be due to invalid IL or missing references)
		//IL_018f: Unknown result type (might be due to invalid IL or missing references)
		//IL_019f: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
		if (!Valid)
		{
			return;
		}
		if (!m_setUp)
		{
			SetUp();
		}
		if ((Object)(object)m_body == (Object)null)
		{
			return;
		}
		try
		{
			LiftClock.Tick();
			ReadState();
			double fixedNow = LiftClock.FixedNow;
			float fixedDeltaTime = Time.fixedDeltaTime;
			HeightAt(fixedNow, out var h, out var v);
			bool flag = m_nview.IsOwner();
			if (flag && !m_wasOwner)
			{
				m_fuelPrevH = (float)h;
				m_fuelUsed = 0f;
				m_haveYaw = false;
				m_steer = (m_writtenSteer = Zdo.GetFloat(KeySteer, 0f));
			}
			if (!flag && m_wasOwner)
			{
				m_fuelUsed = 0f;
				m_speed = 0f;
			}
			m_wasOwner = flag;
			if (m_fall.State != 0)
			{
				if (flag)
				{
					FallOwnerStep(fixedNow);
				}
				return;
			}
			Vector3 position = ((Component)this).transform.position;
			if (flag)
			{
				OwnerStep(fixedNow, (float)h, (float)v, fixedDeltaTime);
				ReadState();
				HeightAt(fixedNow, out h, out v);
				OwnerHold(fixedNow, (float)h, (float)v);
				ReadState();
				HeightAt(fixedNow, out h, out v);
				float num = DriveStep((float)h, fixedDeltaTime, MovingAt(fixedNow));
				BurnFuel((float)h, num);
				CheckTip(fixedNow, (float)h, (float)v, num > 0f);
				if (m_fall.State != 0)
				{
					return;
				}
			}
			else
			{
				FollowPosition((float)h, fixedDeltaTime);
			}
			m_rootVel = (((Component)this).transform.position - position) / Math.Max(0.0001f, fixedDeltaTime);
			LocalDriver((float)h);
			HeightAt(fixedNow + (double)fixedDeltaTime, out var h2, out var _);
			m_moveVelocity = (float)((h2 - h) / Math.Max(0.0001, fixedDeltaTime));
			PlaceDeck((float)h2, jump: false);
			bool flag2 = MovingAt(fixedNow);
			if (flag2 || Math.Abs(m_moveVelocity) > 0.0001f)
			{
				CarryRiders(m_moveVelocity, (float)h);
				if (Time.time >= m_nextWake)
				{
					m_nextWake = Time.time + 0.25f;
					WakeItems((float)h);
				}
			}
			if (m_wasMoving && !flag2)
			{
				OnStopped();
			}
			m_wasMoving = flag2;
		}
		catch (Exception ex)
		{
			if (s_failLogged++ < 3)
			{
				ScissorLiftPlugin.Log.LogWarning((object)("Moving a lift failed: " + ex));
			}
		}
	}

	private void PlaceDeck(float height, bool jump)
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: 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_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: 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_0097: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00de: 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_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)m_deck == (Object)null)
		{
			return;
		}
		Vector3 val = ((Component)this).transform.TransformPoint(new Vector3(0f, height, 0f));
		Quaternion rotation = ((Component)this).transform.rotation;
		if (!jump && height == m_lastTarget && val == m_lastDeckAt && rotation == m_lastDeckRot)
		{
			return;
		}
		m_lastTarget = height;
		m_lastDeckAt = val;
		m_lastDeckRot = rotation;
		if (jump || (Object)(object)m_body == (Object)null)
		{
			m_deck.localPosition = new Vector3(0f, height, 0f);
			m_deck.localRotation = Quaternion.identity;
			if ((Object)(object)m_body != (Object)null)
			{
				m_body.position = val;
				m_body.rotation = rotation;
			}
		}
		else
		{
			m_body.MovePosition(val);
			m_body.MoveRotation(rotation);
		}
	}

	private static long Ms(double seconds)
	{
		return (long)Math.Round(seconds * 1000.0);
	}

	private void CheckTip(double now, float h, float v, bool drove)
	{
		//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)
		if (ScissorLiftPlugin.TippingOn && !Fallen && (drove || !(v <= 0.001f)) && !(LiftDesign.TipRatio(((Component)this).transform.InverseTransformDirection(Vector3.down), h, out var side) < 1f))
		{
			StartFall(now, h, v, side, drove ? "driven onto ground too steep" : "its deck went up too high for the slope");
		}
	}

	private void StartFall(double now, float h, float v, int side, string why)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: 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_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ba: 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_00cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0103: Unknown result type (might be due to invalid IL or missing references)
		//IL_0119: Unknown result type (might be due to invalid IL or missing references)
		//IL_0129: Unknown result type (might be due to invalid IL or missing references)
		//IL_0136: Unknown result type (might be due to invalid IL or missing references)
		//IL_014f: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val = LiftDesign.TipSides[side];
		Vector3 val2 = ((Component)this).transform.InverseTransformDirection(Vector3.down);
		float bottom = Bottom;
		LiftDesign.Topple(LiftDesign.Outline(bottom), val, LiftDesign.WeightHeight(bottom), new Vector2(Vector3.Dot(val2, val), val2.y), out var angle, out var pivot, out var shift, out var rolls);
		Vector3 val3 = ((Component)this).transform.TransformPoint(val * pivot.x + Vector3.up * pivot.y);
		Vector3 val4 = ((Component)this).transform.TransformDirection(Vector3.Cross(Vector3.up, val));
		Vector3 normalized = ((Vector3)(ref val4)).normalized;
		Vector3 val5 = ((Component)this).transform.TransformDirection(val * shift.x + Vector3.up * shift.y);
		float num = LiftDesign.FallTime(h);
		float num2 = Vector3.Angle(((Component)this).transform.up, Vector3.up);
		ZDO zdo = Zdo;
		zdo.Set(KeyFallPos, ((Component)this).transform.position);
		zdo.Set(KeyFallRot, ((Component)this).transform.rotation);
		zdo.Set(KeyFallPivot, val3);
		zdo.Set(KeyFallAxis, normalized);
		zdo.Set(KeyFallAngle, angle);
		zdo.Set(KeyFallShift, val5);
		zdo.Set(KeyFallDur, num);
		zdo.Set(KeyFallTime, Ms(now));
		zdo.Set(KeyFall, 1, false);
		zdo.Set(KeyDriver, 0L);
		m_speed = 0f;
		if (h > bottom + 0.01f)
		{
			Write(now, h, v, bottom, Math.Max(2f, (h - bottom) / (num * 0.6f)), 12f, -1, blocked: false);
		}
		ReadState();
		ScissorLiftPlugin.Log.LogInfo((object)("Scissor lift at " + Where() + " FALLS OVER to its " + LiftDesign.TipSideNames[side] + ": " + why + " (leaning " + num2.ToString("0.0", CultureInfo.InvariantCulture) + " degrees with its deck at " + LiftDesign.Format(h) + "; it stands on up to " + LiftDesign.SteepestFor(h, side).ToString("0", CultureInfo.InvariantCulture) + " degrees that way at that height). It turns " + angle.ToString("0", CultureInfo.InvariantCulture) + " degrees over " + rolls + " edge" + ((rolls == 1) ? "" : "s") + " in " + num.ToString("0.0", CultureInfo.InvariantCulture) + " s."));
	}

	private static double FallSince(double now, double start)
	{
		double num = now - start;
		if (!(num < -2.0))
		{
			return Math.Max(0.0, num);
		}
		return double.MaxValue;
	}

	private void FallPose(double now, out Vector3 pos, out Quaternion rot)
	{
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: 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_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d5: 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_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
		float num = ((m_fall.State == 2) ? (1f - LiftDesign.StandEase((float)Math.Min(1.0, FallSince(now, m_fall.StandStart) / 2.0))) : LiftDesign.FallEase((float)Math.Min(1.0, FallSince(now, m_fall.Start) / (double)m_fall.Dur)));
		Quaternion val = Quaternion.AngleAxis(m_fall.Angle * num, m_fall.Axis);
		rot = val * m_fall.Rot;
		pos = m_fall.Pivot + val * (m_fall.Pos - m_fall.Pivot) + m_fall.Shift * num;
	}

	private bool FallMoving(double now)
	{
		if (m_fall.State != 1)
		{
			if (m_fall.State == 2)
			{
				return FallSince(now, m_fall.StandStart) < 2.0;
			}
			return false;
		}
		return FallSince(now, m_fall.Start) < (double)m_fall.Dur;
	}

	private void FallOwnerStep(double now)
	{
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		if (m_fall.State == 1)
		{
			if (!FallMoving(now))
			{
				FallPose(now, out var pos, out var rot);
				Vector3 val = Zdo.GetPosition() - pos;
				if (((Vector3)(ref val)).sqrMagnitude > 1E-06f || Quaternion.Angle(Zdo.GetRotation(), rot) > 0.05f)
				{
					Zdo.SetPosition(pos);
					Zdo.SetRotation(rot);
				}
			}
		}
		else if (m_fall.State == 2 && !FallMoving(now))
		{
			Vector3 pos2 = m_fall.Pos;
			Quaternion rot2 = m_fall.Rot;
			Zdo.Set(KeyFall, 0, false);
			Zdo.SetPosition(pos2);
			Zdo.SetRotation(rot2);
			ReadState();
			if (LogMore())
			{
				ScissorLiftPlugin.Log.LogInfo((object)("Scissor lift at " + Where() + " stands on its wheels again."));
			}
		}
	}

	private void Update()
	{
		if (!Valid || !m_setUp || (Object)(object)m_body == (Object)null || (m_fall.State == 0 && !m_fallShown))
		{
			return;
		}
		try
		{
			double now = LiftClock.Now;
			if (m_fall.State == 0 || m_stillFor != m_fall.Start + m_fall.StandStart * 3.0 + (double)m_fall.State || FallMoving(now) || MovingAt(now))
			{
				ShowFall(now);
			}
		}
		catch (Exception ex)
		{
			if (s_failLogged++ < 3)
			{
				ScissorLiftPlugin.Log.LogWarning((object)("Showing a lift falling over failed: " + ex));
			}
		}
	}

	private void ShowFall(double now)
	{
		//IL_004b: 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_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_0140: Unknown result type (might be due to invalid IL or missing references)
		//IL_0141: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0214: Unknown result type (might be due to invalid IL or missing references)
		//IL_0207: 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_0220: Unknown result type (might be due to invalid IL or missing references)
		//IL_0237: Unknown result type (might be due to invalid IL or missing references)
		if (m_fall.State == 0)
		{
			m_fallShown = false;
			m_fallMoving = false;
			m_stillFor = double.NaN;
			m_wasMoving = (m_ownerWasMoving = false);
			((Component)this).transform.SetPositionAndRotation(Zdo.GetPosition(), Zdo.GetRotation());
			SyncRamps();
			SetColliders(on: true);
			if ((Object)(object)m_body != (Object)null)
			{
				m_body.interpolation = m_interpolation;
			}
			m_haveYaw = false;
			HeightAt(now, out var h, out var _);
			PlaceDeck((float)h, jump: true);
			ResetWear();
			return;
		}
		if (!m_fallShown)
		{
			m_fallShown = true;
			if ((Object)(object)m_body != (Object)null)
			{
				if ((int)m_body.interpolation != 0)
				{
					m_interpolation = m_body.interpolation;
				}
				m_body.interpolation = (RigidbodyInterpolation)0;
			}
		}
		if (m_fall.State == 1 && m_fallSeen != m_fall.Start)
		{
			m_fallSeen = m_fall.Start;
			OnFallStart(now);
		}
		FallPose(now, out var pos, out var rot);
		((Component)this).transform.SetPositionAndRotation(pos, rot);
		SyncRamps();
		HeightAt(now, out var h2, out var _);
		PlaceDeck((float)h2, jump: true);
		m_moveVelocity = 0f;
		bool flag = FallMoving(now);
		SetColliders(!flag);
		m_stillFor = ((flag || MovingAt(now)) ? double.NaN : (m_fall.Start + m_fall.StandStart * 3.0 + (double)m_fall.State));
		if (m_fallMoving && !flag)
		{
			ResetWear();
			if (m_fall.State == 1 && !Dedicated)
			{
				Vector3 at = (((Object)(object)m_deck != (Object)null) ? m_deck.position : ((Component)this).transform.position);
				LiftLook.Play(LiftLook.StopEffect, at, ScissorLiftPlugin.SoundVolume);
				LiftLook.Play(LiftLook.StopEffect, ((Component)this).transform.position, ScissorLiftPlugin.SoundVolume);
			}
		}
		m_fallMoving = flag;
	}

	private void OnFallStart(double now)
	{
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d3: 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_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_00f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0113: Unknown result type (might be due to invalid IL or missing references)
		//IL_0118: Unknown result type (might be due to invalid IL or missing references)
		//IL_011f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0124: Unknown result type (might be due to invalid IL or missing references)
		//IL_012e: 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)
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer == (Object)null || FallSince(now, m_fall.Start) > (double)m_fall.Dur)
		{
			return;
		}
		if ((object)localPlayer.GetDoodadController() == this)
		{
			localPlayer.StopDoodadControl();
		}
		Vector3 localFeet = Quaternion.Inverse(m_fall.Rot) * (((Component)localPlayer).transform.position - m_fall.Pos);
		HeightAt(m_fall.Start, out var h, out var _);
		float num = Vector3.Distance(((Component)localPlayer).transform.position, m_fall.Pos);
		if (!LiftDesign.StandsOn(localFeet, (float)h, 0.3f))
		{
			if (num < 15f)
			{
				((Character)localPlayer).Message((MessageType)1, "A scissor lift falls over!", 0, (Sprite)null, false);
			}
			return;
		}
		Rigidbody component = ((Component)localPlayer).GetComponent<Rigidbody>();
		Vector3 val = Vector3.Cross(m_fall.Axis, m_fall.Rot * Vector3.up);
		Vector3 normalized = ((Vector3)(ref val)).normalized;
		if ((Object)(object)component != (Object)null && !component.isKinematic)
		{
			component.linearVelocity += normalized * 2.5f + Vector3.up * 2f;
		}
		Tell(localPlayer, "The lift falls over!");
	}

	private void SetColliders(bool on)
	{
		if (!on)
		{
			if (m_offColliders.Count > 0)
			{
				return;
			}
			Collider[] componentsInChildren = ((Component)this).GetComponentsInChildren<Collider>(false);
			foreach (Collider val in componentsInChildren)
			{
				if ((Object)(object)val != (Object)null && val.enabled)
				{
					val.enabled = false;
					m_offColliders.Add(val);
				}
			}
		}
		else
		{
			if (m_offColliders.Count == 0)
			{
				return;
			}
			foreach (Collider offCollider in m_offColliders)
			{
				if ((Object)(object)offCollider != (Object)null)
				{
					offCollider.enabled = true;
				}
			}
			m_offColliders.Clear();
		}
	}

	private void RPC_Stand(long sender)
	{
		if (!Valid || !m_nview.IsOwner())
		{
			return;
		}
		try
		{
			ReadState();
			if (m_fall.State != 1)
			{
				return;
			}
			double now = LiftClock.Now;
			if (!FallMoving(now))
			{
				Zdo.Set(KeyStandTime, Ms(now));
				Zdo.Set(KeyFall, 2, false);
				ReadState();
				if (LogMore())
				{
					ScissorLiftPlugin.Log.LogInfo((object)("Scissor lift at " + Where() + " is stood up again."));
				}
			}
		}
		catch (Exception ex)
		{
			ScissorLiftPlugin.Log.LogWarning((object)("Standing a lift up failed: " + ex.Message));
		}
	}

	private void OwnerStep(double now, float h, float v, float dt)
	{
		bool flag = MovingAt(now);
		if (flag)
		{
			int num = Going(h, v);
			if (num != 0)
			{
				float num2 = Math.Abs(v);
				float num3 = LiftDesign.StoppingDistance(num2, m_state.Accel) + num2 * dt * 2f + 0.12f;
				string what;
				float clear = Clearance(h, num, num3 + 0.05f, out what);
				if (LiftDesign.StopShort(h, num, clear, num3, m_state.To, out var stopAt))
				{
					Write(now, h, v, stopAt, m_state.Speed, m_state.Accel, num, blocked: true);
					if (LogMore())
					{
						ScissorLiftPlugin.Log.LogInfo((object)("Scissor lift at " + Where() + " stops at " + LiftDesign.Format(stopAt) + " going " + ((num > 0) ? "up" : "down") + ": something is in the way (" + what + ")."));
					}
				}
			}
		}
		else if (Time.time >= m_nextIdleCheck)
		{
			m_nextIdleCheck = Time.time + 1f + (float)(((Object)this).GetInstanceID() & 3) * 0.1f;
			float top = Top;
			float bottom = Bottom;
			if (h > top + 0.02f)
			{
				StartMove(now, h, 0f, top, 0L);
			}
			else if (h < bottom - 0.02f)
			{
				StartMove(now, h, 0f, bottom, 0L, free: true);
			}
		}
		if (m_ownerWasMoving && !flag && m_state.Blocked == 0 && LogMore())
		{
			ScissorLiftPlugin.Log.LogInfo((object)("Scissor lift at " + Where() + " stopped at " + LiftDesign.Format(m_state.To) + "."));
		}
		m_ownerWasMoving = flag;
	}

	private bool StartMove(double now, float h, float v, float target, long sender, bool free = false)
	{
		int num = Math.Sign(target - h);
		if (num == 0)
		{
			return false;
		}
		if (num > 0 && !free && ScissorLiftPlugin.NeedsFuel)
		{
			float fuelNow = FuelNow;
			float num2 = LiftDesign.FuelTarget(h, target, fuelNow, ScissorLiftPlugin.MetresPerFuel);
			if (num2 < h + 0.05f)
			{
				Say(sender, "The pump has no fuel: put " + ScissorLiftPlugin.FuelName + " in it.");
				if (LogMore())
				{
					ScissorLiftPlugin.Log.LogInfo((object)("Scissor lift at " + Where() + " can't go up from " + LiftDesign.Format(h) + ": no fuel in its pump (" + fuelNow.ToString("0.###", CultureInfo.InvariantCulture) + ")."));
				}
				return false;
			}
			if (num2 < target - 0.01f)
			{
				Say(sender, "Fuel left for " + LiftDesign.Format(num2 - h) + " up: put " + ScissorLiftPlugin.FuelName + " in the pump.");
				if (LogMore())
				{
					ScissorLiftPlugin.Log.LogInfo((object)("Scissor lift at " + Where() + " goes up only to " + LiftDesign.Format(num2) + " of " + LiftDesign.Format(target) + ": fuel for " + LiftDesign.Format(num2 - h) + " left (" + fuelNow.ToString("0.###", CultureInfo.InvariantCulture) + ")."));
				}
				target = num2;
			}
		}
		float liftSpeed = ScissorLiftPlugin.LiftSpeed;
		float accel = LiftDesign.AccelFor(liftSpeed);
		if (Clearance(h, num, 0.1f, out var what) < 0.03f)
		{
			if (Math.Abs(v) > 0.001f)
			{
				Write(now, h, v, h, liftSpeed, accel, num, blocked: true);
			}
			Say(sender, "Something is in the way.");
			if (LogMore())
			{
				ScissorLiftPlugin.Log.LogInfo((object)("Scissor lift at " + Where() + " can't go " + ((num > 0) ? "up" : "down") + " from " + LiftDesign.Format(h) + ": something is in the way (" + what + ")."));
			}
			return false;
		}
		Write(now, h, v, target, liftSpeed, accel, num, blocked: false);
		if (LogMore())
		{
			ScissorLiftPlugin.Log.LogInfo((object)("Scissor lift at " + Where() + " going " + ((num > 0) ? "up" : "down") + " from " + LiftDesign.Format(h) + " to " + LiftDesign.Format(target) + " at " + liftSpeed.ToString("0.##", CultureInfo.InvariantCulture) + " m/s (" + Stages + " stages)."));
		}
		return true;
	}

	private void Write(double now, float from, float vel, float to, float speed, float accel, int dir, bool blocked)
	{
		ZDO zdo = Zdo;
		zdo.Set(KeyFrom, from);
		zdo.Set(KeyVel, vel);
		zdo.Set(KeyTo, Math.Max(0f, to));
		zdo.Set(KeySpeed, speed);
		zdo.Set(KeyAccel, accel);
		zdo.Set(KeyStart, (long)Math.Round(now * 1000.0));
		zdo.Set(KeyDir, dir, false);
		zdo.Set(KeyBlocked, blocked ? 1 : 0, false);
		zdo.Set(KeySeq, zdo.GetInt(KeySeq, 0) + 1, false);
		ReadState();
	}

	private void RPC_Move(long sender, int dir)
	{
		if (!Valid || !m_nview.IsOwner())
		{
			return;
		}
		try
		{
			ReadState();
			if (Fallen)
			{
				Say(sender, "The lift has fallen over.");
				return;
			}
			double now = LiftClock.Now;
			HeightAt(now, out var h, out var v);
			float num = (float)h;
			float v2 = (float)v;
			if (MovingAt(now))
			{
				StopSoon(now, num, v2, sender);
				return;
			}
			float num2 = ((dir > 0) ? Top : Bottom);
			if ((dir > 0) ? (num >= num2 - 0.02f) : (num <= num2 + 0.02f))
			{
				Say(sender, (dir > 0) ? "The deck is at its top." : "The deck is all the way down.");
			}
			else
			{
				StartMove(now, num, v2, num2, sender);
			}
		}
		catch (Exception ex)
		{
			ScissorLiftPlugin.Log.LogWarning((object)("Using a lift failed: " + ex.Message));
		}
	}

	private void StopSoon(double now, float h, float v, long sender)
	{
		int num = Going(h, v);
		float accel = ((m_state.Accel > 0.01f) ? m_state.Accel : LiftDesign.AccelFor(ScissorLiftPlugin.LiftSpeed));
		float num2 = LiftDesign.StopTarget(h, v, accel, Bottom, Top);
		Write(now, h, v, num2, m_state.Speed, accel, num, blocked: false);
		if (LogMore())
		{
			ScissorLiftPlugin.Log.LogInfo((object)("Scissor lift at " + Where() + " told to stop at " + LiftDesign.Format(h) + " going " + ((num > 0) ? "up" : "down") + " at " + Math.Abs(v).ToString("0.00", CultureInfo.InvariantCulture) + " m/s: it stops at " + LiftDesign.Format(num2) + "."));
		}
	}

	private void RPC_Top(long sender, float top)
	{
		if (!Valid || !m_nview.IsOwner())
		{
			return;
		}
		try
		{
			top = LiftDesign.ClampTop(top, ScissorLiftPlugin.Highest);
			ReadState();
			if (Fallen)
			{
				Say(sender, "The lift has fallen over.");
				return;
			}
			double now = LiftClock.Now;
			HeightAt(now, out var h, out var v);
			float num = (float)h;
			float v2 = (float)v;
			float bottom = Bottom;
			bool flag = MovingAt(now);
			bool num2 = flag && Going(num, v2) > 0;
			Zdo.Set(KeyTop, top);
			ReadState();
			float top2 = Top;
			float bottom2 = Bottom;
			if (num2 || num > top2 + 0.02f)
			{
				StartMove(now, num, v2, top2, 0L);
			}
			else if (num < bottom2 - 0.02f)
			{
				StartMove(now, num, v2, bottom2, 0L);
			}
			else if (!flag && Math.Abs(num - bottom) < 0.02f && Math.Abs(bottom2 - bottom) > 0.005f)
			{
				StartMove(now, num, v2, bottom2, 0L);
			}
		}
		catch (Exception ex)
		{
			ScissorLiftPlugin.Log.LogWarning((object)("Setting a lift's top failed: " + ex.Message));
		}
	}

	private void RPC_Say(long sender, string text)
	{
		Tell(Player.m_localPlayer, text);
	}

	internal static void Tell(Player p, string text)
	{
		if (!((Object)(object)p == (Object)null) && !string.IsNullOrEmpty(text))
		{
			((Character)p).Message((MessageType)((!ScissorLiftPlugin.MiddleMessages) ? 1 : 2), text, 0, (Sprite)null, false);
		}
	}

	private void Say(long sender, string text)
	{
		if (sender != 0L && Valid)
		{
			m_nview.InvokeRPC(sender, "anwo_ScissorLift_Say", new object[1] { text });
		}
	}

	private void OnNewMove(State s)
	{
		//IL_0029: 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_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_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)
		if (Dedicated)
		{
			return;
		}
		Vector3 val = (((Object)(object)m_deck != (Object)null) ? m_deck.position : ((Component)this).transform.position);
		if (s.Blocked != 0)
		{
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer != (Object)null && Vector3.Distance(((Component)localPlayer).transform.position, val) < 10f)
			{
				((Character)localPlayer).Message((MessageType)1, "The lift stops: something is in the way.", 0, (Sprite)null, false);
			}
		}
		else if (MovingAt(LiftClock.Now))
		{
			LiftLook.Play(LiftLook.StartEffect, val, ScissorLiftPlugin.SoundVolume);
		}
	}

	private void OnStopped()
	{
		//IL_0029: 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_002e: 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)
		if (!Dedicated)
		{
			Vector3 at = (((Object)(object)m_deck != (Object)null) ? m_deck.position : ((Component)this).transform.position);
			LiftLook.Play(LiftLook.StopEffect, at, ScissorLiftPlugin.SoundVolume);
		}
	}

	private static void Masks()
	{
		if (s_solidMask == 0)
		{
			s_charMask = LayerMask.GetMask(new string[3] { "character", "character_net", "character_noenv" });
			s_solidMask = LayerMask.GetMask(new string[6] { "Default", "static_solid", "Default_small", "piece", "terrain", "vehicle" });
			s_downMask = LayerMask.GetMask(new string[8] { "Default", "static_solid", "Default_small", "piece", "vehicle", "character", "character_net", "character_noenv" });
			s_itemMask = LayerMask.GetMask(new string[1] { "item" });
		}
	}

	private List<Character> Riders(float height, float slack = 0f)
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: 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)
		Masks();
		s_riders.Clear();
		Vector3 val = ((Component)this).transform.TransformPoint(new Vector3(0f, height, 0f));
		Vector3 val2 = default(Vector3);
		((Vector3)(ref val2))..ctor(1.08f, 0.5f + slack, 1.08f);
		int num = Physics.OverlapBoxNonAlloc(val + ((Component)this).transform.up * 0.4f, val2, s_found, ((Component)this).transform.rotation, s_charMask, (QueryTriggerInteraction)1);
		for (int i = 0; i < num; i++)
		{
			Collider val3 = s_found[i];
			if (!((Object)(object)val3 == (Object)null))
			{
				Character val4 = (((Object)(object)val3.attachedRigidbody != (Object)null) ? ((Component)val3.attachedRigidbody).GetComponent<Character>() : null);
				if ((Object)(object)val4 == (Object)null)
				{
					val4 = ((Component)val3).GetComponentInParent<Character>();
				}
				if (!((Object)(object)val4 == (Object)null) && !s_riders.Contains(val4) && !val4.IsDead() && LiftDesign.StandsOn(((Component)this).transform.InverseTransformPoint(((Component)val4).transform.position), height, val4.IsOwner() ? 0f : slack))
				{
					s_riders.Add(val4);
				}
			}
		}
		return s_riders;
	}

	internal bool HasRiders()
	{
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		if (!Valid || (Object)(object)m_deck == (Object)null)
		{
			return false;
		}
		return Riders(m_deck.localPosition.y, RemoteSlack + 0.2f).Count > 0;
	}

	private void CarryRiders(float deckV, float height)
	{
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: 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)
		foreach (Character item in Riders(height))
		{
			if (!item.IsOwner() || item.IsAttached() || item.IsFlying())
			{
				continue;
			}
			Rigidbody component = ((Component)item).GetComponent<Rigidbody>();
			if (!((Object)(object)component == (Object)null) && !component.isKinematic)
			{
				Vector3 linearVelocity = component.linearVelocity;
				float above = ((Component)this).transform.InverseTransformPoint(component.position).y - height;
				if (LiftDesign.RideSpeed(linearVelocity.y, deckV, above, out var newV))
				{
					linearVelocity.y = newV;
					component.linearVelocity = linearVelocity;
				}
			}
		}
	}

	private void WakeItems(float height)
	{
		//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_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: 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)
		Masks();
		Vector3 val = ((Component)this).transform.TransformPoint(new Vector3(0f, height, 0f));
		Vector3 val2 = default(Vector3);
		((Vector3)(ref val2))..ctor(0.98f, 0.4f, 0.98f);
		int num = Physics.OverlapBoxNonAlloc(val + ((Component)this).transform.up * 0.3f, val2, s_found, ((Component)this).transform.rotation, s_itemMask, (QueryTriggerInteraction)1);
		for (int i = 0; i < num; i++)
		{
			Rigidbody val3 = (((Object)(object)s_found[i] != (Object)null) ? s_found[i].attachedRigidbody : null);
			if ((Object)(object)val3 != (Object)null && !val3.isKinematic && val3.IsSleeping())
			{
				val3.WakeUp();
			}
		}
	}

	internal float Clearance(float height, int dir, float dist, out string what)
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: 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_0235: 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_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_0247: 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_0249: Unknown result type (might be due to invalid IL or missing references)
		//IL_008d: 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_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0115: Unknown result type (might be due to invalid IL or missing references)
		//IL_011a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0124: Unknown result type (might be due to invalid IL or missing references)
		//IL_0129: Unknown result type (might be due to invalid IL or missing references)
		//IL_012e: 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_013e: Unknown result type (might be due to invalid IL or missing references)
		//IL_017c: Unknown result type (might be due to invalid IL or missing references)
		//IL_019d: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ee: 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_015e: Unknown result type (might be due to invalid IL or missing references)
		Masks();
		what = "";
		Quaternion rotation = ((Component)this).transform.rotation;
		Vector3 up = ((Component)this).transform.up;
		Vector3 val = ((Component)this).transform.TransformPoint(new Vector3(0f, height, 0f));
		float dist2 = dist;
		if (dir > 0)
		{
			List<Character> list = Riders(height, RemoteSlack);
			float num = 1.3f;
			foreach (Character item in list)
			{
				num = Math.Max(num, item.IsOwner() ? (RiderTop(item) - val.y + 0.1f) : 2f);
			}
			Vector3 half = default(Vector3);
			((Vector3)(ref half))..ctor(0.95f, num * 0.5f, 0.95f);
			dist2 = Cast(val + up * (0.02f + num * 0.5f), half, rotation, up, dist2, s_solidMask, ref what);
			Vector3 half2 = default(Vector3);
			foreach (Character item2 in list)
			{
				Bounds val2 = RiderBounds(item2);
				Vector3 val3 = ((Component)this).transform.InverseTransformPoint(((Bounds)(ref val2)).center);
				if (!(Math.Abs(val3.x) + ((Bounds)(ref val2)).extents.x <= 0.95f) || !(Math.Abs(val3.z) + ((Bounds)(ref val2)).extents.z <= 0.95f))
				{
					((Vector3)(ref half2))..ctor(Math.Max(0.05f, ((Bounds)(ref val2)).extents.x - 0.03f), 0.05f, Math.Max(0.05f, ((Bounds)(ref val2)).extents.z - 0.03f));
					dist2 = Cast(new Vector3(((Bounds)(ref val2)).center.x, ((Bounds)(ref val2)).max.y + 0.06f, ((Bounds)(ref val2)).center.z), half2, Quaternion.identity, Vector3.up, dist2, s_solidMask, ref what);
				}
			}
		}
		else
		{
			Vector3 half3 = default(Vector3);
			((Vector3)(ref half3))..ctor(0.95f, 0.03f, 0.95f);
			dist2 = Cast(val - up * 0.13f, half3, rotation, -up, dist2, s_downMask, ref what);
		}
		return Math.Max(0f, dist2);
	}

	private float Cast(Vector3 center, Vector3 half, Quaternion rot, Vector3 dir, float dist, int mask, ref string what)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0009: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		int num = Physics.BoxCastNonAlloc(center, half, dir, s_hits, rot, dist, mask, (QueryTriggerInteraction)1);
		float num2 = dist;
		for (int i = 0; i < num; i++)
		{
			RaycastHit val = s_hits[i];
			Collider collider = ((RaycastHit)(ref val)).collider;
			if (!((Object)(object)collider == (Object)null) && !Own(collider))
			{
				Rigidbody attachedRigidbody = collider.attachedRigidbody;
				Character componentInParent = ((Component)collider).GetComponentInParent<Character>();
				if ((!((Object)(object)componentInParent == (Object)null) || !((Object)(object)attachedRigidbody != (Object)null) || attachedRigidbody.isKinematic) && (!((Object)(object)componentInParent != (Object)null) || !(dir.y > 0f)) && ((RaycastHit)(ref val)).distance < num2)
				{
					num2 = ((RaycastHit)(ref val)).distance;
					what = (((Object)(object)componentInParent != (Object)null) ? componentInParent.GetHoverName() : Utils.GetPrefabName(((Component)((Component)collider).transform.root).gameObject));
				}
			}
		}
		return num2;
	}

	private bool Own(Collider c)
	{
		if (!((Component)c).transform.IsChildOf(((Component)this).transform))
		{
			if ((Object)(object)m_ramps != (Object)null)
			{
				return ((Component)c).transform.IsChildOf(m_ramps.transform);
			}
			return false;
		}
		return true;
	}

	private static Bounds RiderBounds(Character c)
	{
		//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_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: 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)
		CapsuleCollider component = ((Component)c).GetComponent<CapsuleCollider>();
		if ((Object)(object)component != (Object)null)
		{
			return ((Collider)component).bounds;
		}
		return new Bounds(((Component)c).transform.position + Vector3.up * 0.9f, new Vector3(0.8f, 1.8f, 0.8f));
	}

	private static float RiderTop(Character c)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0009: Unknown result type (might be due to invalid IL or missing references)
		Bounds val = RiderBounds(c);
		return ((Bounds)(ref val)).max.y;
	}

	private string Where()
	{
		//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_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		return "(" + ((Component)this).transform.position.x.ToString("0", CultureInfo.InvariantCulture) + ", " + ((Component)this).transform.position.z.ToString("0", CultureInfo.InvariantCulture) + ")";
	}

	private void LateUpdate()
	{
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_011a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0149: Unknown result type (might be due to invalid IL or missing references)
		//IL_016d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0178: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_0209: Unknown result type (might be due to invalid IL or missing references)
		//IL_0238: Unknown result type (might be due to invalid IL or missing references)
		//IL_023d: Unknown result type (might be due to invalid IL or missing references)
		if (!Valid || !m_setUp || (Object)(object)m_deck == (Object)null || Dedicated)
		{
			return;
		}
		try
		{
			float y = m_deck.localPosition.y;
			int num = LiftDesign.DrawStages(Stages, y);
			if (num != m_builtStages || float.IsNaN(m_builtHeight) || Math.Abs(y - m_builtHeight) > 0.0008f)
			{
				BuildArms(y, num);
			}
			if (s_reports < 2 && Time.time >= m_reportAt)
			{
				Report(y);
			}
			if (Time.time >= m_nextCheck)
			{
				CheckArms(y);
			}
			Ramps(y);
			float moveVelocity = m_moveVelocity;
			float num2 = ((moveVelocity > 0.02f) ? (-26f) : ((moveVelocity < -0.02f) ? 26f : 0f));
			m_leverAngle = Mathf.MoveTowards(m_leverAngle, num2, 160f * Time.deltaTime);
			if ((Object)(object)m_lever != (Object)null)
			{
				m_lever.localRotation = Quaternion.Euler(m_leverAngle, 0f, 0f);
			}
			if ((Object)(object)m_groundLever != (Object)null)
			{
				m_groundLever.localRotation = Quaternion.Euler(0f - m_leverAngle, 0f, 0f);
			}
			float num3 = Math.Max(0.05f, ScissorLiftPlugin.DriveSpeed);
			float num4 = (Fallen ? 0f : Vector3.Dot(m_rootVel, ((Component)this).transform.forward));
			float num5 = Wheels();
			Quaternion val = Quaternion.Euler(22f * Mathf.Clamp(num4 / num3, -1f, 1f), 0f, -22f * Mathf.Clamp(num5 / LiftDesign.MaxSteer, -1f, 1f));
			m_stickTilt = Quaternion.RotateTowards(m_stickTilt, val, 90f * Time.deltaTime);
			if ((Object)(object)m_stick != (Object)null)
			{
				m_stick.localRotation = m_stickTilt;
			}
			float speed;
			if (!Fallen)
			{
				float val2 = Math.Abs(moveVelocity);
				Vector2 val3 = new Vector2(m_rootVel.x, m_rootVel.z);
				speed = Math.Max(val2, ((Vector2)(ref val3)).magnitude);
			}
			else
			{
				speed = 0f;
			}
			UpdateSound(speed);
			UpdateBeep(moveVelocity);
			WarnLean(y);
			LocalDeckKeys();
		}
		catch (Exception ex)
		{
			if (s_failLogged++ < 3)
			{
				ScissorLiftPlugin.Log.LogWarning((object)("Drawing a lift failed: " + ex));
			}
		}
	}

	private float Wheels()
	{
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_012c: 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)
		float num = (Fallen ? m_shownSteer : (m_nview.IsOwner() ? m_steer : Zdo.GetFloat(KeySteer, 0f)));
		m_shownSteer = Mathf.MoveTowards(m_shownSteer, num, 150f * Time.deltaTime);
		Vector3 val = ((Component)this).transform.position - m_lastWheelPos;
		m_lastWheelPos = ((Component)this).transform.position;
		if (!Fallen && ((Vector3)(ref val)).sqrMagnitude < 1f)
		{
			m_spin = (m_spin + Vector3.Dot(val, ((Component)this).transform.forward) / 0.1f * 57.29578f) % 360f;
		}
		for (int i = 0; i < 4; i++)
		{
			if (LiftDesign.FrontWheel(i) && (Object)(object)m_wheelTurn[i] != (Object)null)
			{
				m_wheelTurn[i].localRotation = Quaternion.Euler(0f, m_shownSteer, 0f);
			}
			if ((Object)(object)m_wheelSpin[i] != (Object)null)
			{
				m_wheelSpin[i].localRotation = Quaternion.Euler(m_spin, 0f, 0f);
			}
		}
		return m_shownSteer;
	}

	private void WarnLean(float h)
	{
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_011e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0123: Unknown result type (might be due to invalid IL or missing references)
		if (Time.time < m_nextLeanCheck)
		{
			return;
		}
		m_nextLeanCheck = Time.time + 0.25f;
		if (Fallen || !ScissorLiftPlugin.TippingOn)
		{
			m_lastLean = float.NaN;
			return;
		}
		int side;
		float num = LiftDesign.TipRatio(((Component)this).transform.InverseTransformDirection(Vector3.down), h, out side);
		bool num2 = !float.IsNaN(m_lastLean) && num > m_lastLean + 0.005f;
		m_lastLean = num;
		if (!num2 || num < 0.8f || num >= 1f)
		{
			return;
		}
		Player localPlayer = Player.m_localPlayer;
		if (!((Object)(object)localPlayer == (Object)null) && !(Vector3.Distance(((Component)localPlayer).transform.position, ((Component)this).transform.position) > 15f))
		{
			((Character)localPlayer).Message((MessageType)1, "The lift is leaning dangerously!", 0, (Sprite)null, false);
			m_nextLeanCheck = Time.time + 3f;
			if (s_leanLogs++ < 4)
			{
				ScissorLiftPlugin.Log.LogInfo((object)("Lift at " + Where() + " leans " + Vector3.Angle(((Component)this).transform.up, Vector3.up).ToString("0.0", CultureInfo.InvariantCulture) + " degrees to its " + LiftDesign.TipSideNames[side] + " with its deck at " + LiftDesign.Format(h) + ": " + (num * 100f).ToString("0", CultureInfo.InvariantCulture) + "% of the way to falling over."));
			}
		}
	}

	private void BuildArms(float height, int stages)
	{
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Expected O, but got Unknown
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: Expected O, but got Unknown
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d2: Expected O, but got Unknown
		if ((Object)(object)m_armsFilter == (Object)null)
		{
			return;
		}
		if ((Object)(object)m_armsMesh == (Object)null)
		{
			m_armsMesh = new Mesh();
			m_armsMesh.MarkDynamic();
		}
		m_armsShape.Clear();
		LiftDesign.BuildArms(m_armsShape, height, stages);
		LiftLook.ToMesh(m_armsShape, "anwo_scissorlift_arms", m_armsMesh);
		m_armsFilter.sharedMesh = m_armsMesh;
		if ((Object)(object)m_ramsBronzeFilter != (Object)null && (Object)(object)m_ramsSteelFilter != (Object)null)
		{
			if ((Object)(object)m_ramsBronzeMesh == (Object)null)
			{
				m_ramsBronzeMesh = new Mesh();
				m_ramsBronzeMesh.MarkDynamic();
			}
			if ((Object)(object)m_ramsSteelMesh == (Object)null)
			{
				m_ramsSteelMesh = new Mesh();
				m_ramsSteelMesh.MarkDynamic();
			}
			m_bronzeShape.Clear();
			m_steelShape.Clear();
			LiftDesign.BuildRams(m_bronzeShape, m_steelShape, height, stages);
			LiftLook.ToMesh(m_bronzeShape, "anwo_scissorlift_rams_bronze", m_ramsBronzeMesh);
			LiftLook.ToMesh(m_steelShape, "anwo_scissorlift_rams_steel", m_ramsSteelMesh);
			m_ramsBronzeFilter.sharedMesh = m_ramsBronzeMesh;
			m_ramsSteelFilter.sharedMesh = m_ramsSteelMesh;
		}
		if (stages != m_builtStages && m_builtStages > 0 && stages != Stages && s_stageLogs++ < 3)
		{
			ScissorLiftPlugin.Log.LogInfo((object)("Lift at " + Where() + " drawn with " + stages + " stages (its own " + Stages + ") while its deck is at " + LiftDesign.Format(height) + ", above what its own stages reach (" + LiftDesign.Format(LiftDesign.Highest(Stages)) + ")."));
		}
		m_builtHeight = height;
		m_builtStages = stages;
	}

	private void Ramps(float h)
	{
		Player localPlayer = Player.m_localPlayer;
		float bottom = Bottom;
		bool flag = ScissorLiftPlugin.RampsOn && !Fallen && h <= bottom + 0.03f && (!((Object)(object)localPlayer != (Object)null) || !((Character)localPlayer).InPlaceMode()) && Driver == 0L && ((Vector3)(ref m_rootVel)).sqrMagnitude < 0.0001f;
		if (flag && (Object)(object)m_ramps == (Object)null)
		{
			MakeRamps();
		}
		if ((Object)(object)m_ramps == (Object)null)
		{
			return;
		}
		SyncRamps();
		if (flag && Math.Abs(m_rampsFor - bottom) > 0.001f)
		{
			PlaceRamps(bottom);
		}
		if (flag == m_rampsOn)
		{
			return;
		}
		m_rampsOn = flag;
		foreach (BoxCollider rampBox in m_rampBoxes)
		{
			if ((Object)(object)rampBox != (Object)null)
			{
				((Collider)rampBox).enabled = flag;
			}
		}
	}

	private void SyncRamps()
	{
		//IL_001c: 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_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)m_ramps == (Object)null))
		{
			Transform transform = m_ramps.transform;
			if (transform.position != ((Component)this).transform.position || transform.rotation != ((Component)this).transform.rotation)
			{
				transform.SetPositionAndRotation(((Component)this).transform.position, ((Component)this).transform.rotation);
			}
		}
	}

	private int RampLayer()
	{
		if (s_rampLayer == -2)
		{
			int num = LayerMask.NameToLayer("blocker");
			int num2 = LayerMask.NameToLayer("character");
			if (num >= 0 && num2 >= 0 && !Physics.GetIgnoreLayerCollision(num, num2))
			{
				s_rampLayer = num;
				ScissorLiftPlugin.Log.LogInfo((object)("Lift ramps are on the game's blocker layer (" + num + "): walked on, but not looked at or hit."));
			}
			else
			{
				s_rampLayer = -1;
				ScissorLiftPlugin.Log.LogWarning((object)("The game's blocker layer (" + num + ") doesn't stop players (character layer " + num2 + "), so lift ramps are on the lift's own layer and can catch the crosshair."));
			}
		}
		if (s_rampLayer < 0)
		{
			return ((Component)this).gameObject.layer;
		}
		return s_rampLayer;
	}

	private void MakeRamps()
	{
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Expected O, but got Unknown
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0084: Unknown result type (might be due to invalid IL or missing references)
		int layer = RampLayer();
		m_ramps = new GameObject("anwo_sl_ramps");
		m_ramps.layer = layer;
		m_ramps.transform.SetPositionAndRotation(((Component)this).transform.position, ((Component)this).transform.rotation);
		Rigidbody obj = m_ramps.AddComponent<Rigidbody>();
		obj.isKinematic = true;
		obj.useGravity = false;
		Vector3[] rampSides = LiftDesign.RampSides;
		for (int i = 0; i < rampSides.Length; i++)
		{
			_ = ref rampSides[i];
			GameObject val = new GameObject("anwo_sl_ramp")
			{
				layer = layer
			};
			val.transform.SetParent(m_ramps.transform, false);
			BoxCollider val2 = val.AddComponent<BoxCollider>();
			((Collider)val2).enabled = false;
			m_rampBoxes.Add(val2);
		}
		m_rampsOn = false;
	}

	private void PlaceRamps(float top)
	{
		//IL_001a: 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_0030: 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_0052: 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_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		m_rampsFor = top;
		float num = 0f;
		for (int i = 0; i < m_rampBoxes.Count && i < LiftDesign.RampSides.Length; i++)
		{
			LiftDesign.Ramp(LiftDesign.RampSides[i], top, out var inner, out var outer, out var along, out var normal, out var centre);
			Vector3 val = outer - inner;
			num = ((Vector3)(ref val)).magnitude;
			Transform transform = ((Component)m_rampBoxes[i]).transform;
			transform.localPosition = centre;
			transform.localRotation = Quaternion.LookRotation(along, normal);
			m_rampBoxes[i].size = new Vector3(1.8f, 0.1f, num);
			m_rampBoxes[i].center = Vector3.zero;
		}
		if (s_rampLogs++ < 2)
		{
			ScissorLiftPlugin.Log.LogInfo((object)("Lift at " + Where() + ": " + m_rampBoxes.Count + " invisible ramps onto its folded deck (" + LiftDesign.Format(top) + " up, " + num.ToString("0.00", CultureInfo.InvariantCulture) + " m long, " + 26f.ToString("0") + " degrees); gone while the deck is up or you build."));
		}
	}

	private void CheckArms(float h)
	{
		//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_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f0: 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_0114: Unknown result type (might be due to invalid IL or missing references)
		//IL_011b: Unknown result type (might be due to invalid IL or missing references)
		//IL_012e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0141: Unknown result type (might be due to invalid IL or missing references)
		//IL_0404: Unknown result type (might be due to invalid IL or missing references)
		//IL_0409: Unknown result type (might be due to invalid IL or missing references)
		//IL_042a: Unknown result type (might be due to invalid IL or missing references)
		//IL_042f: Unknown result type (might be due to invalid IL or missing references)
		m_nextCheck = Time.time + 1f;
		if ((Object)(object)m_armsFilter == (Object)null || (Object)(object)m_deck == (Object)null)
		{
			return;
		}
		float topPinY = LiftDesign.PoseAt(m_builtHeight, m_builtStages).TopPinY;
		float num = h - 0.125f;
		Vector3 localPosition = m_deck.localPosition;
		Vector3 val = (((Object)(object)m_body != (Object)null) ? ((Component)this).transform.InverseTransformPoint(m_body.position) : localPosition);
		HeightAt(LiftClock.Now, out var h2, out var _);
		Renderer component = ((Component)m_armsFilter).GetComponent<Renderer>();
		float num2;
		if (!((Object)(object)component != (Object)null))
		{
			num2 = float.NaN;
		}
		else
		{
			Bounds bounds = component.bounds;
			num2 = ((Bounds)(ref bounds)).max.y;
		}
		float num3 = num2;
		float num4 = m_deck.position.y - 0.09f;
		bool flag = Math.Abs(topPinY - num) > 0.05f || Math.Abs(localPosition.x) > 0.1f || Math.Abs(localPosition.z) > 0.1f || Math.Abs(val.y - localPosition.y) > 0.15f || Math.Abs(val.x) > 0.15f || Math.Abs(val.z) > 0.15f || (!float.IsNaN(num3) && num3 < num4 - 0.1f);
		bool flag2 = h > 4f && s_highLogs < 2;
		if ((flag || flag2) && (!flag || s_mismatches < 6))
		{
			if (flag)
			{
				s_mismatches++;
			}
			else
			{
				s_highLogs++;
			}
			string[] obj = new string[42]
			{
				"Lift at ",
				Where(),
				flag ? ": THE ARMS DON'T MEET THE DECK. " : " above 4 m: ",
				"deck ",
				localPosition.y.ToString("0.00", CultureInfo.InvariantCulture),
				" m (sideways ",
				localPosition.x.ToString("0.00", CultureInfo.InvariantCulture),
				"/",
				localPosition.z.ToString("0.00", CultureInfo.InvariantCulture),
				"), its body ",
				val.y.ToString("0.00", CultureInfo.InvariantCulture),
				" m (",
				val.x.ToString("0.00", CultureInfo.InvariantCulture),
				"/",
				val.z.ToString("0.00", CultureInfo.InvariantCulture),
				"), its motion says ",
				h2.ToString("0.00", CultureInfo.InvariantCulture),
				" m; arms built for ",
				m_builtHeight.ToString("0.00", CultureInfo.InvariantCulture),
				" m with ",
				m_builtStages.ToString(),
				" stages reach ",
				topPinY.ToString("0.00", CultureInfo.InvariantCulture),
				" (want ",
				num.ToString("0.00", CultureInfo.InvariantCulture),
				"); in the world arms top ",
				num3.ToString("0.00", CultureInfo.InvariantCulture),
				", deck underside ",
				num4.ToString("0.00", CultureInfo.InvariantCulture),
				"; top ",
				LiftDesign.Format(Top),
				" (",
				Stages.ToString(),
				" stages), highest allowed ",
				LiftDesign.Format(ScissorLiftPlugin.Highest),
				", ",
				m_nview.IsOwner() ? "run by this game" : "run by another game",
				", turned ",
				null,
				null,
				null,
				null
			};
			Vector3 val2 = ((Component)this).transform.eulerAngles;
			obj[38] = ((Vector3)(ref val2)).ToString("0");
			obj[39] = ", scale ";
			val2 = ((Component)this).transform.lossyScale;
			obj[40] = ((Vector3)(ref val2)).ToString("0.###");
			obj[41] = ".";
			string text = string.Concat(obj);
			if (flag)
			{
				ScissorLiftPlugin.Log.LogWarning((object)text);
			}
			else
			{
				ScissorLiftPlugin.Log.LogInfo((object)text);
			}
		}
	}

	private void Report(float height)
	{
		bool flag = Math.Abs(height - Bottom) > 0.5f;
		if (s_reports == 1 && !flag)
		{
			m_reportAt = Time.time + 1f;
			return;
		}
		s_reports++;
		m_reportAt = ((s_reports < 2) ? (Time.time + 1f) : float.MaxValue);
		bool odd;
		string text = LiftLook.Report(((Component)this).transform, Top, out odd);
		string text2 = "Lift at " + Where() + " drawn at " + height.ToString("0.00", CultureInfo.InvariantCulture) + " m (" + m_builtStages + " stages): " + text;
		if (odd)
		{
			ScissorLiftPlugin.Log.LogWarning((object)text2);
		}
		else
		{
			ScissorLiftPlugin.Log.LogInfo((object)text2);
		}
	}

	private void UpdateSound(float speed)
	{
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Expected O, but got Unknown
		//IL_0076: 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_00cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d3: Invalid comparison between Unknown and I4
		float soundVolume = ScissorLiftPlugin.SoundVolume;
		if ((Object)(object)m_loop == (Object)null)
		{
			if (soundVolume <= 0.001f || speed < 0.01f)
			{
				return;
			}
			AudioSource loopSource = LiftLook.LoopSource;
			AudioClip val = LiftLook.LoopClip(loopSource);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			GameObject val2 = new GameObject("anwo_sl_creak");
			val2.transform.SetParent(m_deck, false);
			val2.transform.localPosition = new Vector3(0f, -0.3f, 0f);
			m_loop = val2.AddComponent<AudioSource>();
			m_loop.clip = val;
			m_loop.outputAudioMixerGroup = loopSource.outputAudioMixerGroup;
			m_loop.spatialBlend = 1f;
			m_loop.rolloffMode = loopSource.rolloffMode;
			if ((int)loopSource.rolloffMode == 2)
			{
				m_loop.SetCustomCurve((AudioSourceCurveType)0, loopSource.GetCustomCurve((AudioSourceCurveType)0));
			}
			m_loop.minDistance = loopSource.minDistance;
			m_loop.maxDistance = loopSource.maxDistance;
			m_loop.dopplerLevel = 0f;
			m_loop.loop = true;
			m_loop.playOnAwake = false;
			m_loop.volume = 0f;
			ZSFX component = ((Component)loopSource).GetComponent<ZSFX>();
			m_baseVolume = Mathf.Clamp(((Object)(object)component != (Object)null && component.m_maxVol > 0f) ? component.m_maxVol : loopSource.volume, 0.3f, 1f);
		}
		float num = Math.Max(0.1f, ScissorLiftPlugin.LiftSpeed);
		float num2 = soundVolume * m_baseVolume * Mathf.Clamp01(speed / num * 1.5f);
		m_loopVolume = Mathf.MoveTowards(m_loopVolume, num2, Time.deltaTime * 1.5f);
		if (m_loopVolume > 0.002f)
		{
			if (!m_loop.isPlaying)
			{
				m_loop.Play();
			}
			m_loop.volume = m_loopVolume;
			m_loop.pitch = 0.8f + 0.2f * Mathf.Clamp01(speed / num);
		}
		else if (m_loop.isPlaying)
		{
			m_loop.Stop();
		}
	}

	private void UpdateBeep(float v)
	{
		//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_0124: Unknown result type (might be due to invalid IL or missing references)
		//IL_012b: Expected O, but got Unknown
		//IL_0154: Unknown result type (might be due to invalid IL or missing references)
		//IL_0196: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a8: Invalid comparison between Unknown and I4
		float beepVolumeValue = ScissorLiftPlugin.BeepVolumeValue;
		bool beepWhileDriving = ScissorLiftPlugin.BeepWhileDriving;
		bool beepWheelOff = ScissorLiftPlugin.BeepWheelOff;
		if (Fallen || beepVolumeValue <= 0.001f || (!beepWhileDriving && !beepWheelOff))
		{
			SetBeepMode(0, 0f);
			return;
		}
		Vector2 val = new Vector2(m_rootVel.x, m_rootVel.z);
		float magnitude = ((Vector2)(ref val)).magnitude;
		bool flag = magnitude > 0.03f || Math.Abs(v) > 0.02f || Driver != 0;
		if (!flag || !beepWheelOff)
		{
			m_wheelOff = false;
		}
		else if (Time.time >= m_nextWheelCheck)
		{
			m_nextWheelCheck = Time.time + 0.2f;
			m_wheelOff = WheelOff(out m_wheelOffText);
		}
		int num = LiftDesign.BeepMode(beepWhileDriving, beepWheelOff, magnitude, flag, m_wheelOff);
		SetBeepMode(num, magnitude);
		if (num == 0 || Time.time < m_nextBeep)
		{
			return;
		}
		bool flag2 = num == 2;
		m_nextBeep = Time.time + (flag2 ? 0.35f : 1f);
		if ((Object)(object)m_beep == (Object)null)
		{
			GameObject val2 = new GameObject("anwo_sl_beep");
			val2.transform.SetParent(((Component)this).transform, false);
			val2.transform.localPosition = new Vector3(0f, 0.4f, 0f);
			m_beep = val2.AddComponent<AudioSource>();
			AudioSource loopSource = LiftLook.LoopSource;
			if ((Object)(object)loopSource != (Object)null)
			{
				m_beep.outputAudioMixerGroup = loopSource.outputAudioMixerGroup;
				m_beep.rolloffMode = loopSource.rolloffMode;
				if ((int)loopSource.rolloffMode == 2)
				{
					m_beep.SetCustomCurve((AudioSourceCurveType)0, loopSource.GetCustomCurve((AudioSourceCurveType)0));
				}
				m_beep.minDistance = loopSource.minDistance;
				m_beep.maxDistance = Math.Max(loopSource.maxDistance, 30f);
			}
			else
			{
				m_beep.rolloffMode = (AudioRolloffMode)1;
				m_beep.minDistance = 3f;
				m_beep.maxDistance = 35f;
			}
			m_beep.spatialBlend = 1f;
			m_beep.dopplerLevel = 0f;
			m_beep.playOnAwake = false;
			m_beep.loop = false;
		}
		m_beep.PlayOneShot(LiftLook.BeepClip(flag2), beepVolumeValue);
	}

	private void SetBeepMode(int mode, float ground)
	{
		if (mode != m_beepMode)
		{
			int beepMode = m_beepMode;
			m_beepMode = mode;
			if (mode > beepMode)
			{
				m_nextBeep = 0f;
			}
			if (s_beepLogs < 12)
			{
				s_beepLogs++;
				string text = mode switch
				{
					1 => "beeps: driving at " + ground.ToString("0.00", CultureInfo.InvariantCulture) + " m/s", 
					2 => "beeps fast: " + m_wheelOffText, 
					_ => "stops beeping", 
				};
				ScissorLiftPlugin.Log.LogInfo((object)("Scissor lift at " + Where() + " " + text + "."));
			}
		}
	}

	private bool WheelOff(out string text)
	{
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: 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_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f8: 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)
		text = "";
		DriveMasks();
		bool result = false;
		StringBuilder stringBuilder = new StringBuilder();
		for (int i = 0; i < 4; i++)
		{
			Vector3 val = ((Component)this).transform.TransformPoint(LiftDesign.WheelAt(i));
			float num = float.PositiveInfinity;
			Vector3[] wheelFeel = LiftDesign.WheelFeel;
			foreach (Vector3 val2 in wheelFeel)
			{
				int num2 = Physics.RaycastNonAlloc(((Component)this).transform.TransformPoint(LiftDesign.WheelAt(i) + val2) + Vector3.up * 0.6f, Vector3.down, s_beepHits, 1.6f, s_groundMask, (QueryTriggerInteraction)1);
				for (int k = 0; k < num2; k++)
				{
					Collider collider = ((RaycastHit)(ref s_beepHits[k])).collider;
					if (!((Object)(object)collider == (Object)null) && !Own(collider) && (!((Object)(object)collider.attachedRigidbody != (Object)null) || collider.attachedRigidbody.isKinematic) && !((Object)(object)((Component)collider).GetComponentInParent<Character>() != (Object)null))
					{
						num = Math.Min(num, Math.Max(0f, val.y - ((RaycastHit)(ref s_beepHits[k])).point.y));
					}
				}
			}
			if (num >= 0.1f)
			{
				result = true;
				stringBuilder.Append((stringBuilder.Length > 0) ? ", " : "").Append("the " + WheelNames[i] + " wheel " + (float.IsInfinity(num) ? "over nothing" : (num.ToString("0.00", CultureInfo.InvariantCulture) + " m off the ground")));
			}
		}
		text = stringBuilder.ToString();
		return result;
	}

	public string GetHoverName()
	{
		return "Scissor lift";
	}

	public float GetHoverOffset()
	{
		return 0f;
	}

	public string GetHoverText()
	{
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		if (!Valid)
		{
			return "";
		}
		ReadState();
		bool flag = PrivateArea.CheckAccess(((Component)this).transform.position, 0f, false, false);
		string text;
		if (Fallen)
		{
			text = "Scissor lift\nFallen over";
			if (!flag)
			{
				return Localize(text + "\n$piece_noaccess");
			}
			if (m_fall.State == 1 && !FallMoving(LiftClock.Now))
			{
				text += "\n[<color=yellow><b>$KEY_Use</b></color>] Stand it up";
			}
			return Localize(text);
		}
		double now = LiftClock.Now;
		HeightAt(now, out var h, out var v);
		float num = (float)h;
		float top = Top;
		float bottom = Bottom;
		bool flag2 = MovingAt(now);
		int num2 = Going(num, (float)v);
		Part part = LookedAt();
		if (part == Part.Drive && !ScissorLiftPlugin.DriveAllowed)
		{
			part = Part.Lever;
		}
		object obj;
		switch (part)
		{
		case Part.Pump:
			text = "Lift pump";
			if (ScissorLiftPlugin.NeedsFuel)
			{
				text = text + "\n" + FuelLine();
			}
			text = text + "\nTop height " + LiftDesign.Format(top);
			if (!flag)
			{
				return Localize(text + "\n$piece_noaccess");
			}
			if (ScissorLiftPlugin.NeedsFuel)
			{
				Player localPlayer2 = Player.m_localPlayer;
				int carried = (((Object)(object)localPlayer2 != (Object)null) ? ((Humanoid)localPlayer2).GetInventory().CountItems(ScissorLiftPlugin.FuelSharedName, -1, true) : 0);
				text = text + "\n[<color=yellow><b>$KEY_Use</b></color>] Put in " + ScissorLiftPlugin.FuelName + " (" + LiftDesign.HaveText(carried, ChestFuelNear()) + ")";
				text += "\n[<color=yellow><b>$KEY_AltPlace + $KEY_Use</b></color>] Set the top height";
			}
			else
			{
				text += "\n[<color=yellow><b>$KEY_Use</b></color>] Set the top height";
			}
			return Localize(text);
		case Part.Drive:
		{
			text = "Drive stick";
			long driver = Driver;
			Player localPlayer = Player.m_localPlayer;
			if (driver != 0L && ((Object)(object)localPlayer == (Object)null || driver != localPlayer.GetPlayerID()))
			{
				Player player = Player.GetPlayer(driver);
				if ((Object)(object)player != (Object)null)
				{
					text = text + "\n" + player.GetPlayerName() + " is driving";
				}
			}
			if (ScissorLiftPlugin.NeedsFuel)
			{
				text = text + "\n" + FuelLine();
			}
			if (!flag)
			{
				return Localize(text + "\n$piece_noaccess");
			}
			text = text + "\n[<color=yellow><b>$KEY_Use</b></color>] Drive (" + ScissorLiftPlugin.DriveKeysText() + ")";
			if (flag2)
			{
				text += "\n[<color=yellow><b>$KEY_AltPlace + $KEY_Use</b></color>] Stop the deck";
			}
			else if (num > bottom + 0.02f)
			{
				text += "\n[<color=yellow><b>$KEY_AltPlace + $KEY_Use</b></color>] Go down";
			}
			return Localize(text);
		}
		default:
			obj = "Scissor lift";
			break;
		case Part.Lever:
			obj = "Lift lever";
			break;
		}
		text = (string)obj;
		text = (flag2 ? (text + "\n" + ((num2 > 0) ? ("Going up: " + LiftDesign.Format(num) + " of " + LiftDesign.Format(m_state.To)) : ("Going down: " + LiftDesign.Format(num)))) : ((m_state.Blocked == 0) ? (text + "\nDeck at " + LiftDesign.Format(num) + ", top " + LiftDesign.Format(top)) : (text + "\nStopped at " + LiftDesign.Format(num) + ": something is in the way")));
		if (ScissorLiftPlugin.NeedsFuel)
		{
			text = text + "\n" + FuelLine();
		}
		if (!flag)
		{
			return Localize(text + "\n$piece_noaccess");
		}
		if (flag2)
		{
			text += "\n[<color=yellow><b>$KEY_Use</b></color>] Stop";
		}
		else
		{
			if (num < top - 0.02f)
			{
				text += "\n[<color=yellow><b>$KEY_Use</b></color>] Go up";
			}
			if (num > bottom + 0.02f)
			{
				text += "\n[<color=yellow><b>$KEY_AltPlace + $KEY_Use</b></color>] Go down";
			}
		}
		return Localize(text);
	}

	private string FuelLine()
	{
		float fuelNow = FuelNow;
		float metres = LiftDesign.MetresOn(fuelNow, ScissorLiftPlugin.MetresPerFuel);
		return ScissorLiftPlugin.FuelName + ": " + fuelNow.ToString((fuelNow > 0f && fuelNow < 9.95f && Math.Abs((double)fuelNow - Math.Round(fuelNow)) > 0.05000000074505806) ? "0.0" : "0", CultureInfo.InvariantCulture) + " of " + ScissorLiftPlugin.FuelTank + ((fuelNow > 0f) ? (", for about " + LiftDesign.Format(metres)) : ", empty");
	}

	internal Part LookedAt()
	{
		//IL_0023: 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_007f: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if ((Object)(object)GameCamera.instance == (Object)null)
			{
				return Part.Lift;
			}
			Transform transform = ((Component)GameCamera.instance).transform;
			Ray val = default(Ray);
			((Ray)(ref val))..ctor(transform.position, transform.forward);
			float num = 50f;
			Part result = Part.Lift;
			RaycastHit val2 = default(RaycastHit);
			foreach (KeyValuePair<Collider, Part> part in m_parts)
			{
				Collider key = part.Key;
				if (!((Object)(object)key == (Object)null) && key.enabled && ((Component)key).gameObject.activeInHierarchy && key.Raycast(val, ref val2, num))
				{
					num = ((RaycastHit)(ref val2)).distance;
					result = part.Value;
				}
			}
			return result;
		}
		catch (Exception)
		{
			return Part.Lift;
		}
	}

	internal static string Localize(string text)
	{
		try
		{
			return (Localization.instance != null) ? Localization.instance.Localize(text) : text;
		}
		catch
		{
			return text;
		}
	}

	public bool Interact(Humanoid user, bool hold, bool alt)
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		if (hold || !Valid)
		{
			return false;
		}
		if (!PrivateArea.CheckAccess(((Component)this).transform.position, 0f, true, false))
		{
			return true;
		}
		ReadState();
		if (Fallen)
		{
			if (m_fall.State != 1 || FallMoving(LiftClock.Now))
			{
				return true;
			}
			if (!Zdo.HasOwner())
			{
				m_nview.ClaimOwnership();
			}
			m_nview.InvokeRPC("anwo_ScissorLift_Stand", Array.Empty<object>());
			return true;
		}
		switch (LookedAt())
		{
		case Part.Pump:
			if (!alt && ScissorLiftPlugin.NeedsFuel)
			{
				return AddFuel(user, null);
			}
			return AskTop();
		case Part.Drive:
			if (!alt && ScissorLiftPlugin.DriveAllowed)
			{
				return StartDriving((Player)(object)((user is Player) ? user : null));
			}
			break;
		}
		if (!Zdo.HasOwner())
		{
			m_nview.ClaimOwnership();
		}
		m_nview.InvokeRPC("anwo_ScissorLift_Move", new object[1] { (!alt) ? 1 : (-1) });
		return true;
	}

	private bool AskTop()
	{
		if ((Object)(object)TextInput.instance == (Object)null)
		{
			return false;
		}
		TextInput.instance.RequestText((TextReceiver)(object)this, "Top height in metres (" + 1f.ToString("0", CultureInfo.InvariantCulture) + " to " + ScissorLiftPlugin.Highest.ToString("0.#", CultureInfo.Inv