Decompiled source of IamScoutmaster v0.6.3

plugins/Thanks.I_am_Scoutmaster.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Thanks.I_am_Scoutmaster")]
[assembly: AssemblyDescription("Control the PEAK Scoutmaster as the local player.")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Thanks")]
[assembly: AssemblyProduct("I'm Scoutmaster")]
[assembly: AssemblyCopyright("Copyright 2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("0ee091f4-9b49-4593-a95d-af67533313c8")]
[assembly: AssemblyFileVersion("0.7.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("0.7.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ImScoutmaster
{
	public sealed class ControlledScoutmasterVisualSync : MonoBehaviour
	{
		private Character _character;

		private PhotonView _view;

		public void Initialize(Character character, PhotonView view)
		{
			_character = (((Object)(object)character != (Object)null) ? character : ((Component)this).GetComponent<Character>());
			_view = (((Object)(object)view != (Object)null) ? view : ((Component)this).GetComponent<PhotonView>());
		}

		private void Awake()
		{
			Initialize(_character, _view);
		}

		private void Update()
		{
			if ((Object)(object)_character == (Object)null)
			{
				_character = ((Component)this).GetComponent<Character>();
			}
			if ((Object)(object)_character != (Object)null)
			{
				Plugin.EnsureControlledScoutmasterRegistered(_character);
			}
		}

		private void OnDestroy()
		{
			Plugin.UnregisterControlledScoutmasterInstance(_character, _view);
		}
	}
	[BepInPlugin("com.github.Thanks.ImScoutmaster", "I'm Scoutmaster", "0.7.0")]
	public sealed class Plugin : BaseUnityPlugin
	{
		private enum ConfigKey
		{
			ToggleKey,
			StaminaRefill,
			ThrowForce,
			ThrowUpBias,
			ThrowFallSeconds,
			ThirdPersonHeightOffset,
			ThirdPersonDistance,
			SourceStashDistance,
			RestoreAtScoutmasterPosition,
			RestoreGroundOffset,
			HideHudWhileTransformed,
			VerboseLogs
		}

		private readonly struct RendererVisualState
		{
			public readonly bool Enabled;

			public readonly bool ForceRenderingOff;

			public RendererVisualState(bool enabled, bool forceRenderingOff)
			{
				Enabled = enabled;
				ForceRenderingOff = forceRenderingOff;
			}
		}

		private sealed class ActiveScoutmasterSession
		{
			private readonly struct BodypartPhysicsState
			{
				public readonly Rigidbody Rig;

				public readonly bool IsKinematic;

				public readonly bool DetectCollisions;

				public readonly bool UseGravity;

				public BodypartPhysicsState(Rigidbody rig)
				{
					Rig = rig;
					IsKinematic = (Object)(object)rig != (Object)null && rig.isKinematic;
					DetectCollisions = (Object)(object)rig != (Object)null && rig.detectCollisions;
					UseGravity = (Object)(object)rig != (Object)null && rig.useGravity;
				}
			}

			[CompilerGenerated]
			private sealed class <Enter>d__15 : IEnumerator<object>, IDisposable, IEnumerator
			{
				private int <>1__state;

				private object <>2__current;

				public ActiveScoutmasterSession <>4__this;

				object IEnumerator<object>.Current
				{
					[DebuggerHidden]
					get
					{
						return <>2__current;
					}
				}

				object IEnumerator.Current
				{
					[DebuggerHidden]
					get
					{
						return <>2__current;
					}
				}

				[DebuggerHidden]
				public <Enter>d__15(int <>1__state)
				{
					this.<>1__state = <>1__state;
				}

				[DebuggerHidden]
				void IDisposable.Dispose()
				{
					<>1__state = -2;
				}

				private bool MoveNext()
				{
					int num = <>1__state;
					ActiveScoutmasterSession activeScoutmasterSession = <>4__this;
					switch (num)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						activeScoutmasterSession.PreconfigureScoutmasterForLocalControl();
						activeScoutmasterSession._controller = activeScoutmasterSession._scoutmasterObject.GetComponent<PlayerScoutmasterController>() ?? activeScoutmasterSession._scoutmasterObject.AddComponent<PlayerScoutmasterController>();
						activeScoutmasterSession._controller.Initialize(activeScoutmasterSession._sourceCharacter, activeScoutmasterSession._scoutmaster, activeScoutmasterSession._scoutmasterCharacter);
						RegisterControlledScoutmaster(activeScoutmasterSession._scoutmaster);
						Character.localCharacter = activeScoutmasterSession._scoutmasterCharacter;
						SetGameObjectActive(activeScoutmasterSession._scoutmasterObject, active: true);
						activeScoutmasterSession.AlignScoutmasterBodyToSource();
						<>2__current = null;
						<>1__state = 1;
						return true;
					case 1:
						<>1__state = -1;
						activeScoutmasterSession.AlignScoutmasterBodyToSource();
						activeScoutmasterSession.PrepareScoutmaster();
						SetCameraOverride(activeScoutmasterSession._scoutmasterCharacter);
						_viewScoutmasterObject = activeScoutmasterSession._scoutmasterObject;
						UpdateScoutmasterHudState();
						RestoreRendererVisibility(activeScoutmasterSession._scoutmasterObject);
						activeScoutmasterSession._controller.ActivateDynamicRagdollControl();
						activeScoutmasterSession.HideSourceCharacter();
						Character.localCharacter = activeScoutmasterSession._scoutmasterCharacter;
						LogVerbose("Entered Scoutmaster form.");
						return false;
					}
				}

				bool IEnumerator.MoveNext()
				{
					//ILSpy generated this explicit interface implementation from .override directive in MoveNext
					return this.MoveNext();
				}

				[DebuggerHidden]
				void IEnumerator.Reset()
				{
					throw new NotSupportedException();
				}
			}

			private readonly Character _sourceCharacter;

			private readonly GameObject _scoutmasterObject;

			private readonly Scoutmaster _scoutmaster;

			private readonly Character _scoutmasterCharacter;

			private readonly Vector3 _sourceStartPosition;

			private readonly Vector3 _sourceStashPosition;

			private readonly Quaternion _sourceStartRotation;

			private readonly bool _sourceWasActive;

			private readonly List<BodypartPhysicsState> _sourceBodypartPhysicsStates = new List<BodypartPhysicsState>();

			private PlayerScoutmasterController _controller;

			private bool _sourcePhysicsSuspended;

			public bool IsActive
			{
				get
				{
					if ((Object)(object)_sourceCharacter != (Object)null && (Object)(object)_scoutmasterObject != (Object)null && (Object)(object)_scoutmaster != (Object)null)
					{
						return (Object)(object)_scoutmasterCharacter != (Object)null;
					}
					return false;
				}
			}

			public ActiveScoutmasterSession(Character sourceCharacter, GameObject scoutmasterObject, Scoutmaster scoutmaster, Character scoutmasterCharacter, bool sourceWasActive)
			{
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				//IL_0035: Unknown result type (might be due to invalid IL or missing references)
				//IL_003c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0041: Unknown result type (might be due to invalid IL or missing references)
				//IL_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_0064: Unknown result type (might be due to invalid IL or missing references)
				//IL_0070: Unknown result type (might be due to invalid IL or missing references)
				//IL_0075: Unknown result type (might be due to invalid IL or missing references)
				_sourceCharacter = sourceCharacter;
				_scoutmasterObject = scoutmasterObject;
				_scoutmaster = scoutmaster;
				_scoutmasterCharacter = scoutmasterCharacter;
				_sourceStartPosition = sourceCharacter.Center;
				_sourceStashPosition = _sourceStartPosition + Vector3.down * Mathf.Max(SourceStashDistance.Value, 10f);
				_sourceStartRotation = ((Component)sourceCharacter).transform.rotation;
				_sourceWasActive = sourceWasActive;
			}

			[IteratorStateMachine(typeof(<Enter>d__15))]
			public IEnumerator Enter()
			{
				//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
				return new <Enter>d__15(0)
				{
					<>4__this = this
				};
			}

			private void PreconfigureScoutmasterForLocalControl()
			{
				_scoutmasterCharacter.isScoutmaster = true;
				_scoutmasterCharacter.isZombie = false;
				EnableScoutmasterPhysics();
			}

			private void AlignScoutmasterBodyToSource()
			{
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				//IL_003e: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
				//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)_sourceCharacter == (Object)null || (Object)(object)_scoutmasterCharacter == (Object)null || (Object)(object)_scoutmasterObject == (Object)null)
				{
					return;
				}
				try
				{
					SetCharacterPositionImmediate(_scoutmasterCharacter, _sourceCharacter.Center, _sourceStartRotation);
					AlignCharacterFeetToGround(_scoutmasterCharacter, _sourceCharacter);
					_scoutmasterCharacter.data.currentRagdollControll = 1f;
					_scoutmasterCharacter.data.fallSeconds = 0f;
					_scoutmasterCharacter.data.isGrounded = (Object)(object)_sourceCharacter.data != (Object)null && _sourceCharacter.data.isGrounded;
					_scoutmasterCharacter.data.groundPos = (((Object)(object)_sourceCharacter.data != (Object)null) ? _sourceCharacter.data.groundPos : _sourceCharacter.Center);
					EnableScoutmasterPhysics();
				}
				catch (Exception ex)
				{
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogWarning((object)("[I'm Scoutmaster] Failed to align controlled body: " + ex.Message));
					}
				}
			}

			private void EnableScoutmasterPhysics()
			{
				if ((Object)(object)_scoutmasterCharacter == (Object)null || _scoutmasterCharacter.refs?.ragdoll?.partList == null)
				{
					return;
				}
				try
				{
					foreach (Bodypart part in _scoutmasterCharacter.refs.ragdoll.partList)
					{
						Rigidbody val = (((Object)(object)part != (Object)null) ? part.Rig : null);
						if (!((Object)(object)val == (Object)null))
						{
							val.isKinematic = false;
							val.detectCollisions = true;
							val.useGravity = true;
							val.WakeUp();
						}
					}
				}
				catch (Exception ex)
				{
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogWarning((object)("[I'm Scoutmaster] Failed to enable controlled physics: " + ex.Message));
					}
				}
			}

			public void Tick()
			{
				if (!IsActive)
				{
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogWarning((object)"[I'm Scoutmaster] Session became inactive.");
					}
					Instance?.ExitScoutmasterForm(restorePlayer: true);
				}
				else
				{
					Character.localCharacter = _scoutmasterCharacter;
					KeepScoutmasterAwake();
					KeepSourceOutOfPlay();
				}
			}

			public void Exit(bool restorePlayer)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0060: Unknown result type (might be due to invalid IL or missing references)
				//IL_0067: Unknown result type (might be due to invalid IL or missing references)
				//IL_0068: Unknown result type (might be due to invalid IL or missing references)
				Vector3 position = ResolveRestorePosition();
				Quaternion val = ResolveRestoreRotation();
				if ((Object)(object)_controller != (Object)null)
				{
					((Behaviour)_controller).enabled = false;
				}
				RestoreRendererVisibility(_scoutmasterObject);
				ClearCameraOverride();
				_viewScoutmasterObject = null;
				RestoreHudAfterScoutmaster();
				if (restorePlayer && (Object)(object)_sourceCharacter != (Object)null)
				{
					CopyLookStateForRestore(_scoutmasterCharacter, _sourceCharacter, val);
					RestoreSourceCharacter(position, val);
					ForcePlayerCharacterLookup(_sourceCharacter);
					Character.localCharacter = _sourceCharacter;
					BeginCameraRestoreAssist(_sourceCharacter);
				}
				UnregisterStashedSourceCharacter(_sourceCharacter);
				UnregisterControlledScoutmaster(_scoutmaster);
				BeginPeakStatsCleanupGraceWindow();
				CleanupPeakStatsUi(aggressive: true);
				DestroyScoutmasterObject(_scoutmasterObject);
				LogVerbose("Exited Scoutmaster form.");
			}

			private Vector3 ResolveRestorePosition()
			{
				//IL_0040: 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_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				//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_0034: Unknown result type (might be due to invalid IL or missing references)
				//IL_0035: Unknown result type (might be due to invalid IL or missing references)
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_003d: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)_scoutmasterCharacter != (Object)null)
				{
					Vector3 center = _scoutmasterCharacter.Center;
					if (IsFiniteVector(center))
					{
						return center;
					}
					Vector3 position = ((Component)_scoutmasterCharacter).transform.position;
					if (IsFiniteVector(position))
					{
						return position;
					}
				}
				return ResolveSafeRestorePosition(_sourceStartPosition, _scoutmasterCharacter, _sourceCharacter, _sourceStartPosition);
			}

			private Quaternion ResolveRestoreRotation()
			{
				//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_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_0039: Unknown result type (might be due to invalid IL or missing references)
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0066: Unknown result type (might be due to invalid IL or missing references)
				//IL_006b: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
				//IL_0098: Unknown result type (might be due to invalid IL or missing references)
				//IL_009d: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)_scoutmasterCharacter == (Object)null)
				{
					return _sourceStartRotation;
				}
				Vector3 val = Vector3.ProjectOnPlane(((Component)_scoutmasterCharacter).transform.rotation * Vector3.forward, Vector3.up);
				if (((Vector3)(ref val)).sqrMagnitude < 0.0001f && (Object)(object)_scoutmasterCharacter.data != (Object)null)
				{
					val = _scoutmasterCharacter.data.lookDirection_Flat;
				}
				if (((Vector3)(ref val)).sqrMagnitude < 0.0001f && (Object)(object)_scoutmasterCharacter.data != (Object)null)
				{
					val = Vector3.ProjectOnPlane(_scoutmasterCharacter.data.lookDirection, Vector3.up);
				}
				if (((Vector3)(ref val)).sqrMagnitude < 0.0001f)
				{
					return _sourceStartRotation;
				}
				return Quaternion.LookRotation(((Vector3)(ref val)).normalized, Vector3.up);
			}

			private static Vector3 GetRestoreAnchor(Character character)
			{
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				//IL_0009: 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_002a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0088: Unknown result type (might be due to invalid IL or missing references)
				//IL_008d: Unknown result type (might be due to invalid IL or missing references)
				//IL_008e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0085: Unknown result type (might be due to invalid IL or missing references)
				//IL_003c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0041: Unknown result type (might be due to invalid IL or missing references)
				//IL_0042: Unknown result type (might be due to invalid IL or missing references)
				//IL_0043: Unknown result type (might be due to invalid IL or missing references)
				//IL_0044: Unknown result type (might be due to invalid IL or missing references)
				//IL_0049: Unknown result type (might be due to invalid IL or missing references)
				//IL_004e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0053: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
				//IL_009c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0062: Unknown result type (might be due to invalid IL or missing references)
				//IL_0068: Unknown result type (might be due to invalid IL or missing references)
				//IL_007b: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)character == (Object)null)
				{
					return Vector3.zero;
				}
				Vector3 center = character.Center;
				if ((Object)(object)character.data != (Object)null && IsFiniteVector(character.data.groundPos))
				{
					Vector3 groundPos = character.data.groundPos;
					Vector3 val = Vector3.ProjectOnPlane(groundPos - center, Vector3.up);
					if (((Vector3)(ref val)).sqrMagnitude <= 64f && Mathf.Abs(groundPos.y - center.y) <= 12f)
					{
						return groundPos;
					}
				}
				if (IsFiniteVector(center))
				{
					return center;
				}
				Vector3 head = character.Head;
				if (!IsFiniteVector(head))
				{
					return ((Component)character).transform.position;
				}
				return head;
			}

			private static void AlignCharacterFeetToGround(Character controlledCharacter, Character sourceCharacter)
			{
				//IL_005a: Unknown result type (might be due to invalid IL or missing references)
				//IL_005f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0065: Unknown result type (might be due to invalid IL or missing references)
				//IL_006a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0075: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)controlledCharacter == (Object)null) && !((Object)(object)sourceCharacter == (Object)null) && TryGetCharacterGroundY(sourceCharacter, out var groundY) && TryGetCharacterGroundY(controlledCharacter, out var groundY2))
				{
					float num = groundY - groundY2;
					if (!float.IsNaN(num) && !float.IsInfinity(num) && !(Mathf.Abs(num) > 3f) && !(Mathf.Abs(num) <= 0.001f))
					{
						SetCharacterPositionImmediate(controlledCharacter, controlledCharacter.Center + Vector3.up * num, ((Component)controlledCharacter).transform.rotation);
					}
				}
			}

			private static bool TryGetCharacterGroundY(Character character, out float groundY)
			{
				//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_002d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0093: Unknown result type (might be due to invalid IL or missing references)
				//IL_003f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0044: Unknown result type (might be due to invalid IL or missing references)
				//IL_0045: Unknown result type (might be due to invalid IL or missing references)
				//IL_0046: Unknown result type (might be due to invalid IL or missing references)
				//IL_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_0051: Unknown result type (might be due to invalid IL or missing references)
				//IL_0056: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
				//IL_009c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0065: Unknown result type (might be due to invalid IL or missing references)
				//IL_006b: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
				//IL_007f: Unknown result type (might be due to invalid IL or missing references)
				groundY = 0f;
				if ((Object)(object)character == (Object)null)
				{
					return false;
				}
				Vector3 center = character.Center;
				if ((Object)(object)character.data != (Object)null && IsFiniteVector(character.data.groundPos))
				{
					Vector3 groundPos = character.data.groundPos;
					Vector3 val = Vector3.ProjectOnPlane(groundPos - center, Vector3.up);
					if (((Vector3)(ref val)).sqrMagnitude <= 64f && Mathf.Abs(groundPos.y - center.y) <= 12f)
					{
						groundY = groundPos.y;
						return true;
					}
				}
				if (TryGetCharacterColliderBottomY(character, out groundY))
				{
					return true;
				}
				if (IsFiniteVector(center))
				{
					groundY = center.y;
					return true;
				}
				Vector3 position = ((Component)character).transform.position;
				if (!IsFiniteVector(position))
				{
					return false;
				}
				groundY = position.y;
				return true;
			}

			private static bool TryGetCharacterColliderBottomY(Character character, out float bottomY)
			{
				//IL_00f0: 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_00f5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
				//IL_010f: 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_008f: 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_0098: 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_009f: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
				bottomY = 0f;
				if (character?.refs?.ragdoll?.partList == null)
				{
					return false;
				}
				bool flag = false;
				foreach (Bodypart part in character.refs.ragdoll.partList)
				{
					if ((Object)(object)part == (Object)null)
					{
						continue;
					}
					Collider[] componentsInChildren = ((Component)part).GetComponentsInChildren<Collider>(true);
					if (componentsInChildren != null)
					{
						Collider[] array = componentsInChildren;
						foreach (Collider val in array)
						{
							if (!((Object)(object)val == (Object)null) && val.enabled)
							{
								Bounds bounds = val.bounds;
								Vector3 min = ((Bounds)(ref bounds)).min;
								if (IsFiniteVector(min) && (!flag || min.y < bottomY))
								{
									bottomY = min.y;
									flag = true;
								}
							}
						}
					}
					Vector3 val2 = (((Object)(object)part.Rig != (Object)null) ? part.Rig.position : ((Component)part).transform.position);
					if (IsFiniteVector(val2) && (!flag || val2.y < bottomY))
					{
						bottomY = val2.y;
						flag = true;
					}
				}
				return flag;
			}

			private static Vector3 ResolveSafeRestorePosition(Vector3 requestedPosition, Character scoutmasterCharacter, Character sourceCharacter, Vector3 fallbackPosition)
			{
				//IL_001a: 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_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: 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_004c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0056: Unknown result type (might be due to invalid IL or missing references)
				//IL_005b: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
				//IL_0070: Unknown result type (might be due to invalid IL or missing references)
				//IL_0071: Unknown result type (might be due to invalid IL or missing references)
				//IL_007b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0080: Unknown result type (might be due to invalid IL or missing references)
				//IL_0045: Unknown result type (might be due to invalid IL or missing references)
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				//IL_0095: Unknown result type (might be due to invalid IL or missing references)
				//IL_0096: Unknown result type (might be due to invalid IL or missing references)
				//IL_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_004a: 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_00d3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d9: 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)
				float num = Mathf.Clamp(RestoreGroundOffset.Value, 0.2f, 5f);
				Vector3 val = (IsFiniteVector(requestedPosition) ? requestedPosition : fallbackPosition);
				if (!IsFiniteVector(val))
				{
					val = (((Object)(object)sourceCharacter != (Object)null) ? ((Component)sourceCharacter).transform.position : Vector3.zero);
				}
				if (TryFindRestoreGround(val + Vector3.up * 5f, 30f, scoutmasterCharacter, sourceCharacter, out var groundHit) || TryFindRestoreGround(val + Vector3.up * 12f, 80f, scoutmasterCharacter, sourceCharacter, out groundHit) || TryFindRestoreGround(fallbackPosition + Vector3.up * 5f, 30f, scoutmasterCharacter, sourceCharacter, out groundHit))
				{
					return ((RaycastHit)(ref groundHit)).point + Vector3.up * num;
				}
				return val + Vector3.up * num;
			}

			private static bool TryFindRestoreGround(Vector3 origin, float distance, Character scoutmasterCharacter, Character sourceCharacter, out RaycastHit groundHit)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_0059: Unknown result type (might be due to invalid IL or missing references)
				//IL_005e: Unknown result type (might be due to invalid IL or missing references)
				//IL_007f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0084: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a7: 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)
				groundHit = default(RaycastHit);
				if (!IsFiniteVector(origin))
				{
					return false;
				}
				RaycastHit[] array;
				try
				{
					array = Physics.RaycastAll(origin, Vector3.down, distance, -1, (QueryTriggerInteraction)1);
				}
				catch
				{
					return false;
				}
				Array.Sort(array, (RaycastHit left, RaycastHit right) => ((RaycastHit)(ref left)).distance.CompareTo(((RaycastHit)(ref right)).distance));
				RaycastHit[] array2 = array;
				for (int i = 0; i < array2.Length; i++)
				{
					RaycastHit val = array2[i];
					if (!((Object)(object)((RaycastHit)(ref val)).collider == (Object)null) && !((RaycastHit)(ref val)).collider.isTrigger && !(Vector3.Dot(((RaycastHit)(ref val)).normal, Vector3.up) < 0.2f) && !IsRestoreIgnoredCollider(((RaycastHit)(ref val)).collider, scoutmasterCharacter, sourceCharacter))
					{
						groundHit = val;
						return true;
					}
				}
				return false;
			}

			private static bool IsRestoreIgnoredCollider(Collider collider, Character scoutmasterCharacter, Character sourceCharacter)
			{
				if ((Object)(object)collider == (Object)null)
				{
					return true;
				}
				Transform transform = ((Component)collider).transform;
				if (!IsColliderOwnedBy(transform, scoutmasterCharacter))
				{
					return IsColliderOwnedBy(transform, sourceCharacter);
				}
				return true;
			}

			private static bool IsColliderOwnedBy(Transform colliderTransform, Character character)
			{
				if ((Object)(object)colliderTransform == (Object)null || (Object)(object)character == (Object)null)
				{
					return false;
				}
				Transform transform = ((Component)character).transform;
				if (!((Object)(object)colliderTransform == (Object)(object)transform))
				{
					return colliderTransform.IsChildOf(transform);
				}
				return true;
			}

			private static bool IsFiniteVector(Vector3 value)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				if (IsFiniteFloat(value.x) && IsFiniteFloat(value.y))
				{
					return IsFiniteFloat(value.z);
				}
				return false;
			}

			private static bool IsFiniteFloat(float value)
			{
				if (!float.IsNaN(value))
				{
					return !float.IsInfinity(value);
				}
				return false;
			}

			private void PrepareScoutmaster()
			{
				ClearScoutmasterAiState(_scoutmaster);
				_scoutmasterCharacter.isScoutmaster = true;
				_scoutmasterCharacter.isZombie = false;
				_scoutmasterCharacter.data.isScoutmaster = true;
				SetCharacterDeadWithoutReconnect(_scoutmasterCharacter, dead: false);
				_scoutmasterCharacter.data.zombified = false;
				_scoutmasterCharacter.data.passedOut = false;
				_scoutmasterCharacter.data.fullyPassedOut = false;
				_scoutmasterCharacter.data.fallSeconds = 0f;
				_scoutmasterCharacter.data.currentRagdollControll = 1f;
				_scoutmasterCharacter.data.currentStamina = Mathf.Max(_scoutmasterCharacter.data.currentStamina, GetControlledStaminaFill());
				_scoutmasterCharacter.data.extraStamina = 0f;
				ClearAssistJumpState(_scoutmasterCharacter);
			}

			private void HideSourceCharacter()
			{
				//IL_009a: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)_sourceCharacter == (Object)null)
				{
					return;
				}
				try
				{
					RegisterStashedSourceCharacter(_sourceCharacter);
					_sourceCharacter.data.fallSeconds = 0f;
					_sourceCharacter.data.passedOut = false;
					_sourceCharacter.data.fullyPassedOut = false;
					ClearAssistJumpState(_sourceCharacter);
					if (_sourceWasActive && !((Component)_sourceCharacter).gameObject.activeSelf)
					{
						((Component)_sourceCharacter).gameObject.SetActive(true);
					}
					HideSourceRenderers(((Component)_sourceCharacter).gameObject);
					SendSourceCharacterOutOfPlay(_sourceStashPosition);
					SetCharacterPositionImmediate(_sourceCharacter, _sourceStashPosition, ((Component)_sourceCharacter).transform.rotation);
					SuspendSourcePhysics();
				}
				catch (Exception ex)
				{
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogWarning((object)("[I'm Scoutmaster] Failed to stash source character: " + ex.Message));
					}
				}
			}

			private void RestoreSourceCharacter(Vector3 position, Quaternion rotation)
			{
				//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
				//IL_010c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0111: Unknown result type (might be due to invalid IL or missing references)
				//IL_0121: Unknown result type (might be due to invalid IL or missing references)
				//IL_0126: Unknown result type (might be due to invalid IL or missing references)
				//IL_0137: Unknown result type (might be due to invalid IL or missing references)
				//IL_0143: Unknown result type (might be due to invalid IL or missing references)
				//IL_0144: Unknown result type (might be due to invalid IL or missing references)
				try
				{
					if (_sourceWasActive && !((Component)_sourceCharacter).gameObject.activeSelf)
					{
						((Component)_sourceCharacter).gameObject.SetActive(true);
					}
					SetCharacterDeadWithoutReconnect(_sourceCharacter, dead: false);
					_sourceCharacter.data.zombified = false;
					_sourceCharacter.isZombie = false;
					_sourceCharacter.data.passedOut = false;
					_sourceCharacter.data.fullyPassedOut = false;
					_sourceCharacter.data.fallSeconds = 0f;
					_sourceCharacter.data.deathTimer = 0f;
					_sourceCharacter.data.currentRagdollControll = 1f;
					_sourceCharacter.data.isGrounded = false;
					_sourceCharacter.data.sinceGrounded = 0f;
					_sourceCharacter.data.groundedFor = 0f;
					_sourceCharacter.data.groundPos = position;
					_sourceCharacter.data.avarageVelocity = Vector3.zero;
					_sourceCharacter.data.avarageLastFrameVelocity = Vector3.zero;
					ClearAssistJumpState(_sourceCharacter);
					SendSourceCharacterRestore(position);
					SetCharacterPositionImmediate(_sourceCharacter, position, rotation);
					RestoreSourcePhysics();
					RestoreSourceRenderers(((Component)_sourceCharacter).gameObject);
					UnregisterStashedSourceCharacter(_sourceCharacter);
				}
				catch (Exception ex)
				{
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogWarning((object)("[I'm Scoutmaster] Failed to restore source character: " + ex.Message));
					}
				}
			}

			private void SendSourceCharacterOutOfPlay(Vector3 stashPosition)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				SendSourceCharacterStateRpc(stashPosition, "[I'm Scoutmaster] Failed to move source character out of play: ");
			}

			private void SendSourceCharacterRestore(Vector3 restorePosition)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				SendSourceCharacterStateRpc(restorePosition, "[I'm Scoutmaster] Failed to restore source character over network: ");
			}

			private void SendSourceCharacterStateRpc(Vector3 position, string warningPrefix)
			{
				//IL_0078: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)_sourceCharacter == (Object)null || (Object)(object)((MonoBehaviourPun)_sourceCharacter).photonView == (Object)null || (!PhotonNetwork.InRoom && !PhotonNetwork.OfflineMode))
				{
					return;
				}
				try
				{
					PhotonView photonView = ((MonoBehaviourPun)_sourceCharacter).photonView;
					photonView.RPC("RPCA_UnFall", (RpcTarget)1, Array.Empty<object>());
					photonView.RPC("RPCA_Revive", (RpcTarget)1, new object[1] { false });
					photonView.RPC("WarpPlayerRPC", (RpcTarget)1, new object[2] { position, false });
				}
				catch (Exception ex)
				{
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogWarning((object)(warningPrefix + ex.Message));
					}
				}
			}

			private void SuspendSourcePhysics()
			{
				//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)_sourceCharacter == (Object)null || _sourceCharacter.refs?.ragdoll?.partList == null)
				{
					return;
				}
				try
				{
					if (!_sourcePhysicsSuspended)
					{
						_sourceBodypartPhysicsStates.Clear();
					}
					foreach (Bodypart part in _sourceCharacter.refs.ragdoll.partList)
					{
						Rigidbody val = (((Object)(object)part != (Object)null) ? part.Rig : null);
						if (!((Object)(object)val == (Object)null))
						{
							if (!_sourcePhysicsSuspended)
							{
								_sourceBodypartPhysicsStates.Add(new BodypartPhysicsState(val));
							}
							if (!val.isKinematic)
							{
								val.linearVelocity = Vector3.zero;
								val.angularVelocity = Vector3.zero;
							}
							val.detectCollisions = false;
							val.useGravity = false;
							val.isKinematic = true;
						}
					}
					_sourcePhysicsSuspended = true;
				}
				catch (Exception ex)
				{
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogWarning((object)("[I'm Scoutmaster] Failed to suspend source physics: " + ex.Message));
					}
				}
			}

			private void RestoreSourcePhysics()
			{
				//IL_0045: 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)
				if (!_sourcePhysicsSuspended)
				{
					return;
				}
				try
				{
					foreach (BodypartPhysicsState sourceBodypartPhysicsState in _sourceBodypartPhysicsStates)
					{
						Rigidbody rig = sourceBodypartPhysicsState.Rig;
						if (!((Object)(object)rig == (Object)null))
						{
							rig.isKinematic = sourceBodypartPhysicsState.IsKinematic;
							if (!rig.isKinematic)
							{
								rig.linearVelocity = Vector3.zero;
								rig.angularVelocity = Vector3.zero;
							}
							rig.detectCollisions = sourceBodypartPhysicsState.DetectCollisions;
							rig.useGravity = sourceBodypartPhysicsState.UseGravity;
						}
					}
				}
				catch (Exception ex)
				{
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogWarning((object)("[I'm Scoutmaster] Failed to restore source physics: " + ex.Message));
					}
				}
				finally
				{
					_sourceBodypartPhysicsStates.Clear();
					_sourcePhysicsSuspended = false;
				}
			}

			private static void SetCharacterPositionImmediate(Character character, Vector3 position, Quaternion rotation)
			{
				//IL_0185: Unknown result type (might be due to invalid IL or missing references)
				//IL_0186: Unknown result type (might be due to invalid IL or missing references)
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				//IL_0021: Unknown result type (might be due to invalid IL or missing references)
				//IL_0026: 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_0028: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0033: Unknown result type (might be due to invalid IL or missing references)
				//IL_0035: Unknown result type (might be due to invalid IL or missing references)
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				//IL_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_012b: 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_0134: Unknown result type (might be due to invalid IL or missing references)
				//IL_0139: Unknown result type (might be due to invalid IL or missing references)
				//IL_013a: Unknown result type (might be due to invalid IL or missing references)
				//IL_013f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0144: 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_0151: Unknown result type (might be due to invalid IL or missing references)
				//IL_0156: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b2: 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_00bf: 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_00c5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
				//IL_00db: 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_0107: 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)
				if ((Object)(object)character == (Object)null)
				{
					return;
				}
				try
				{
					Transform transform = ((Component)character).transform;
					Vector3 center = character.Center;
					Quaternion rotation2 = transform.rotation;
					Vector3 val = position - center;
					Quaternion val2 = rotation * Quaternion.Inverse(rotation2);
					transform.SetPositionAndRotation(transform.position + val, rotation);
					if (character.refs?.ragdoll?.partList == null)
					{
						return;
					}
					foreach (Bodypart part in character.refs.ragdoll.partList)
					{
						if ((Object)(object)part == (Object)null)
						{
							continue;
						}
						if ((Object)(object)part.Rig != (Object)null)
						{
							part.Rig.position = position + val2 * (part.Rig.position - center);
							part.Rig.rotation = val2 * part.Rig.rotation;
							if (!part.Rig.isKinematic)
							{
								part.Rig.linearVelocity = Vector3.zero;
								part.Rig.angularVelocity = Vector3.zero;
							}
						}
						else
						{
							((Component)part).transform.SetPositionAndRotation(position + val2 * (((Component)part).transform.position - center), val2 * ((Component)part).transform.rotation);
						}
					}
				}
				catch
				{
					((Component)character).transform.SetPositionAndRotation(position, rotation);
				}
			}

			private void KeepScoutmasterAwake()
			{
				if (!((Object)(object)_scoutmasterCharacter?.data == (Object)null))
				{
					ClearScoutmasterAiState(_scoutmaster);
					SetCharacterDeadWithoutReconnect(_scoutmasterCharacter, dead: false);
					_scoutmasterCharacter.isScoutmaster = true;
					_scoutmasterCharacter.isZombie = false;
					_scoutmasterCharacter.data.isScoutmaster = true;
					_scoutmasterCharacter.data.zombified = false;
					if (!IsControlledScoutmasterIncapacitated(_scoutmasterCharacter))
					{
						_scoutmasterCharacter.data.passedOut = false;
						_scoutmasterCharacter.data.fullyPassedOut = false;
						_scoutmasterCharacter.data.fallSeconds = 0f;
						_scoutmasterCharacter.data.currentRagdollControll = 1f;
						_scoutmasterCharacter.data.currentStamina = Mathf.Max(_scoutmasterCharacter.data.currentStamina, GetControlledStaminaFill());
						_scoutmasterCharacter.data.extraStamina = 0f;
						ClearAssistJumpState(_scoutmasterCharacter);
					}
				}
			}

			private void KeepSourceOutOfPlay()
			{
				if (!((Object)(object)_sourceCharacter == (Object)null) && !((Object)(object)_sourceCharacter.data == (Object)null))
				{
					if ((Object)(object)_sourceCharacter == (Object)(object)Character.localCharacter && (Object)(object)_scoutmasterCharacter != (Object)null)
					{
						Character.localCharacter = _scoutmasterCharacter;
					}
					SetCharacterDeadWithoutReconnect(_sourceCharacter, dead: false);
					_sourceCharacter.data.zombified = false;
					_sourceCharacter.data.passedOut = false;
					_sourceCharacter.data.fullyPassedOut = false;
					_sourceCharacter.data.fallSeconds = 0f;
					ClearAssistJumpState(_sourceCharacter);
					HideSourceRenderers(((Component)_sourceCharacter).gameObject);
					SuspendSourcePhysics();
				}
			}
		}

		[CompilerGenerated]
		private sealed class <EnterScoutmasterFormRoutine>d__198 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public Plugin <>4__this;

			private Character <sourceCharacter>5__2;

			private bool <sourceWasActive>5__3;

			private GameObject <scoutmasterObject>5__4;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <EnterScoutmasterFormRoutine>d__198(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<sourceCharacter>5__2 = null;
				<scoutmasterObject>5__4 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//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_0063: Unknown result type (might be due to invalid IL or missing references)
				//IL_0068: Unknown result type (might be due to invalid IL or missing references)
				//IL_0080: Unknown result type (might be due to invalid IL or missing references)
				//IL_0081: Unknown result type (might be due to invalid IL or missing references)
				int num = <>1__state;
				Plugin plugin = <>4__this;
				Scoutmaster component;
				Character component2;
				switch (num)
				{
				default:
					return false;
				case 0:
				{
					<>1__state = -1;
					plugin._switching = true;
					<sourceCharacter>5__2 = Character.localCharacter;
					if (!CanTransform(<sourceCharacter>5__2))
					{
						plugin._switching = false;
						return false;
					}
					Vector3 center = <sourceCharacter>5__2.Center;
					Quaternion spawnRotation = GetSpawnRotation(<sourceCharacter>5__2);
					<sourceWasActive>5__3 = ((Component)<sourceCharacter>5__2).gameObject.activeSelf;
					<scoutmasterObject>5__4 = CreateScoutmaster(center, spawnRotation);
					if ((Object)(object)<scoutmasterObject>5__4 == (Object)null)
					{
						((BaseUnityPlugin)plugin).Logger.LogWarning((object)"[I'm Scoutmaster] Could not create Character_Scoutmaster prefab.");
						plugin._switching = false;
						return false;
					}
					component = <scoutmasterObject>5__4.GetComponent<Scoutmaster>();
					component2 = <scoutmasterObject>5__4.GetComponent<Character>();
					if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null)
					{
						<>2__current = null;
						<>1__state = 1;
						return true;
					}
					goto IL_0112;
				}
				case 1:
					<>1__state = -1;
					component = <scoutmasterObject>5__4.GetComponent<Scoutmaster>();
					component2 = <scoutmasterObject>5__4.GetComponent<Character>();
					goto IL_0112;
				case 2:
					{
						<>1__state = -1;
						plugin._switching = false;
						return false;
					}
					IL_0112:
					if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null)
					{
						((BaseUnityPlugin)plugin).Logger.LogWarning((object)"[I'm Scoutmaster] Created object is missing Scoutmaster or Character.");
						DestroyScoutmasterObject(<scoutmasterObject>5__4);
						plugin._switching = false;
						return false;
					}
					if (!CanTransform(<sourceCharacter>5__2))
					{
						DestroyScoutmasterObject(<scoutmasterObject>5__4);
						plugin._switching = false;
						return false;
					}
					plugin._session = new ActiveScoutmasterSession(<sourceCharacter>5__2, <scoutmasterObject>5__4, component, component2, <sourceWasActive>5__3);
					<>2__current = plugin._session.Enter();
					<>1__state = 2;
					return true;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <EnumerateCandidateTransforms>d__371 : IEnumerable<Transform>, IEnumerable, IEnumerator<Transform>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private Transform <>2__current;

			private int <>l__initialThreadId;

			private object menuInstance;

			public object <>3__menuInstance;

			private Type menuType;

			public Type <>3__menuType;

			Transform IEnumerator<Transform>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <EnumerateCandidateTransforms>d__371(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				object? obj2;
				Transform val2;
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
				{
					<>1__state = -1;
					object obj = menuInstance;
					Component val = (Component)((obj is Component) ? obj : null);
					if (val != null)
					{
						<>2__current = val.transform;
						<>1__state = 1;
						return true;
					}
					goto IL_004d;
				}
				case 1:
					<>1__state = -1;
					goto IL_004d;
				case 2:
					{
						<>1__state = -1;
						break;
					}
					IL_004d:
					obj2 = menuType?.GetProperty("Content", InstanceFlags)?.GetValue(menuInstance);
					val2 = (Transform)((obj2 is Transform) ? obj2 : null);
					if (val2 != null)
					{
						<>2__current = val2;
						<>1__state = 2;
						return true;
					}
					break;
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<Transform> IEnumerable<Transform>.GetEnumerator()
			{
				<EnumerateCandidateTransforms>d__371 <EnumerateCandidateTransforms>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<EnumerateCandidateTransforms>d__ = this;
				}
				else
				{
					<EnumerateCandidateTransforms>d__ = new <EnumerateCandidateTransforms>d__371(0);
				}
				<EnumerateCandidateTransforms>d__.menuInstance = <>3__menuInstance;
				<EnumerateCandidateTransforms>d__.menuType = <>3__menuType;
				return <EnumerateCandidateTransforms>d__;
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<Transform>)this).GetEnumerator();
			}
		}

		[CompilerGenerated]
		private sealed class <EnumerateModConfigUiRoots>d__370 : IEnumerable<Transform>, IEnumerable, IEnumerator<Transform>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private Transform <>2__current;

			private int <>l__initialThreadId;

			private object menuInstance;

			public object <>3__menuInstance;

			private Type menuType;

			public Type <>3__menuType;

			private HashSet<int> <visited>5__2;

			private IEnumerator<Transform> <>7__wrap2;

			Transform IEnumerator<Transform>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <EnumerateModConfigUiRoots>d__370(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || num == 1)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<visited>5__2 = null;
				<>7__wrap2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<visited>5__2 = new HashSet<int>();
						<>7__wrap2 = EnumerateCandidateTransforms(menuInstance, menuType).GetEnumerator();
						<>1__state = -3;
						break;
					case 1:
						<>1__state = -3;
						break;
					}
					while (<>7__wrap2.MoveNext())
					{
						Transform current = <>7__wrap2.Current;
						if ((Object)(object)current != (Object)null && <visited>5__2.Add(((Object)current).GetInstanceID()))
						{
							<>2__current = current;
							<>1__state = 1;
							return true;
						}
					}
					<>m__Finally1();
					<>7__wrap2 = null;
					return false;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<>7__wrap2 != null)
				{
					<>7__wrap2.Dispose();
				}
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<Transform> IEnumerable<Transform>.GetEnumerator()
			{
				<EnumerateModConfigUiRoots>d__370 <EnumerateModConfigUiRoots>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<EnumerateModConfigUiRoots>d__ = this;
				}
				else
				{
					<EnumerateModConfigUiRoots>d__ = new <EnumerateModConfigUiRoots>d__370(0);
				}
				<EnumerateModConfigUiRoots>d__.menuInstance = <>3__menuInstance;
				<EnumerateModConfigUiRoots>d__.menuType = <>3__menuType;
				return <EnumerateModConfigUiRoots>d__;
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<Transform>)this).GetEnumerator();
			}
		}

		[CompilerGenerated]
		private sealed class <GetAliasDefinitions>d__350 : IEnumerable<ConfigDefinition>, IEnumerable, IEnumerator<ConfigDefinition>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private ConfigDefinition <>2__current;

			private int <>l__initialThreadId;

			private ConfigKey configKey;

			public ConfigKey <>3__configKey;

			private string <canonicalKey>5__2;

			private string <chineseKey>5__3;

			private string <canonicalSection>5__4;

			private string <chineseSection>5__5;

			ConfigDefinition IEnumerator<ConfigDefinition>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <GetAliasDefinitions>d__350(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<canonicalKey>5__2 = null;
				<chineseKey>5__3 = null;
				<canonicalSection>5__4 = null;
				<chineseSection>5__5 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_007d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0087: 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_00cb: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d5: Expected O, but got Unknown
				//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fc: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<canonicalKey>5__2 = GetConfigKeyName(configKey);
					<chineseKey>5__3 = GetKeyName(configKey, isChineseLanguage: true);
					<canonicalSection>5__4 = GetConfigSectionName(configKey);
					<chineseSection>5__5 = GetSectionName(configKey, isChineseLanguage: true);
					<>2__current = new ConfigDefinition(<canonicalSection>5__4, <canonicalKey>5__2);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<>2__current = new ConfigDefinition(<canonicalSection>5__4, <chineseKey>5__3);
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					<>2__current = new ConfigDefinition(<chineseSection>5__5, <canonicalKey>5__2);
					<>1__state = 3;
					return true;
				case 3:
					<>1__state = -1;
					<>2__current = new ConfigDefinition(<chineseSection>5__5, <chineseKey>5__3);
					<>1__state = 4;
					return true;
				case 4:
					<>1__state = -1;
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<ConfigDefinition> IEnumerable<ConfigDefinition>.GetEnumerator()
			{
				<GetAliasDefinitions>d__350 <GetAliasDefinitions>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<GetAliasDefinitions>d__ = this;
				}
				else
				{
					<GetAliasDefinitions>d__ = new <GetAliasDefinitions>d__350(0);
				}
				<GetAliasDefinitions>d__.configKey = <>3__configKey;
				return <GetAliasDefinitions>d__;
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<ConfigDefinition>)this).GetEnumerator();
			}
		}

		public const string Id = "com.github.Thanks.ImScoutmaster";

		public const string Name = "I'm Scoutmaster";

		public const string Version = "0.7.0";

		private const string ScoutmasterResourceName = "Character_Scoutmaster";

		private const float ToggleHoldSeconds = 1f;

		private const float ManualFallShortPressMaxSeconds = 0.3f;

		private const float ToggleDebounceSeconds = 0.35f;

		private const int SimplifiedChineseLanguageIndex = 9;

		private const string ControlsConfigSectionName = "Controls";

		private const string ScoutmasterControlConfigSectionName = "Scoutmaster Control";

		private const string CameraConfigSectionName = "Camera";

		private const string PlayerRestoreConfigSectionName = "Player Restore";

		private const string HudConfigSectionName = "HUD";

		private const string DiagnosticsConfigSectionName = "Diagnostics";

		private const string ModConfigPluginGuid = "com.github.PEAKModding.PEAKLib.ModConfig";

		private const float ModConfigUiLocalizationIntervalSeconds = 0.25f;

		private const float CameraRestoreAssistSeconds = 0.4f;

		private const float ThirdPersonHeadTargetLiftMin = 0.35f;

		private const float ThirdPersonHeadTargetLiftMax = 1.35f;

		private const float ThirdPersonConfiguredTargetBlend = 0.25f;

		private const float ThirdPersonGroundMinHeight = 1.55f;

		private const float ThirdPersonCrouchGroundMinHeight = 1.15f;

		private const float ThirdPersonBodyFrameBlendStart = 0.45f;

		private const float ThirdPersonBodyFrameBlendFull = 0.95f;

		private const float ThirdPersonBodyFrameDownMaxBlend = 0.42f;

		private const float ThirdPersonBodyFrameUpMaxBlend = 0.3f;

		private const float ThirdPersonFocusForwardMin = 1.75f;

		private const float ThirdPersonFocusForwardMax = 4.25f;

		private const float ThirdPersonDownFocusDropMax = 1.15f;

		private const float ThirdPersonUpFocusLiftMax = 0.8f;

		private const float ThirdPartyCompatibilityRetryIntervalSeconds = 1f;

		private const float ClearBoostReticleTimer = 10f;

		private const float ControlledScoutmasterJumpVelocity = 10.5f;

		private const float ControlledScoutmasterJumpGroundClearance = 0.12f;

		private const float ControlledScoutmasterManualFallSeconds = 1.25f;

		private const float ControlledGrabAttachPointMaxHandDistance = 3.5f;

		private const string ControlledScoutmasterInstantiationMarker = "ImScoutmaster.ControlledScoutmaster";

		private const int ControlledScoutmasterNetworkProtocol = 1;

		private static readonly BindingFlags InstanceFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

		private static readonly BindingFlags StaticFlags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;

		private static readonly PropertyInfo ConfigFileEntriesProperty = typeof(ConfigFile).GetProperty("Entries", InstanceFlags);

		private static readonly FieldInfo CharacterViewField = typeof(Character).GetField("view", InstanceFlags);

		private static readonly FieldInfo CharacterStartedField = typeof(Character).GetField("started", InstanceFlags);

		private static readonly FieldInfo CharacterSmoothedCamPosField = typeof(Character).GetField("smoothedCamPos", InstanceFlags);

		private static readonly MethodInfo CharacterGetBodypartMethod = typeof(Character).GetMethod("GetBodypart", InstanceFlags);

		private static readonly MethodInfo CharacterGetPartTypeMethod = typeof(Character).GetMethod("GetPartType", InstanceFlags);

		private static readonly FieldInfo CharacterDataCharacterField = typeof(CharacterData).GetField("character", InstanceFlags);

		private static readonly FieldInfo CharacterDataDeadField = typeof(CharacterData).GetField("_dead", InstanceFlags);

		private static readonly FieldInfo CharacterDataGrabbedPlayerField = typeof(CharacterData).GetField("grabbedPlayer", InstanceFlags);

		private static readonly MethodInfo CharacterFallMethod = typeof(Character).GetMethod("Fall", InstanceFlags, null, new Type[2]
		{
			typeof(float),
			typeof(float)
		}, null);

		private static readonly FieldInfo CharacterCustomizationCharacterField = typeof(CharacterCustomization).GetField("_character", InstanceFlags);

		private static readonly FieldInfo BodypartCharacterField = typeof(Bodypart).GetField("character", InstanceFlags);

		private static readonly FieldInfo ScoutmasterCurrentTargetField = typeof(Scoutmaster).GetField("_currentTarget", InstanceFlags);

		private static readonly FieldInfo ScoutmasterTargetForcedUntilField = typeof(Scoutmaster).GetField("targetForcedUntil", InstanceFlags);

		private static readonly FieldInfo ScoutmasterChillForSecondsField = typeof(Scoutmaster).GetField("chillForSeconds", InstanceFlags);

		private static readonly FieldInfo ScoutmasterIsThrowingField = typeof(Scoutmaster).GetField("isThrowing", InstanceFlags);

		private static readonly PropertyInfo MainCameraSpecCharacterProperty = typeof(MainCameraMovement).GetProperty("specCharacter", StaticFlags);

		private static readonly FieldInfo MainCameraIsSpectatingField = typeof(MainCameraMovement).GetField("isSpectating", InstanceFlags);

		private static readonly FieldInfo MainCameraRagdollCamField = typeof(MainCameraMovement).GetField("ragdollCam", InstanceFlags);

		private static readonly FieldInfo MainCameraCurrentForwardOffsetField = typeof(MainCameraMovement).GetField("currentForwardOffset", InstanceFlags);

		private static readonly FieldInfo MainCameraTargetPlayerPovPositionField = typeof(MainCameraMovement).GetField("targetPlayerPovPosition", InstanceFlags);

		private static readonly FieldInfo MainCameraPhysicsRotField = typeof(MainCameraMovement).GetField("physicsRot", InstanceFlags);

		private static readonly MethodInfo FindObjectsOfTypeByTypeMethod = typeof(Object).GetMethod("FindObjectsOfType", new Type[1] { typeof(Type) });

		private static readonly MethodInfo CharacterClimbingCanClimbMethod = typeof(CharacterClimbing).GetMethod("CanClimb", InstanceFlags, null, Type.EmptyTypes, null);

		private static readonly MethodInfo CharacterClimbingStartClimbRpcMethod = FindCharacterClimbingStartClimbRpcMethod();

		private static readonly FieldInfo CharacterClimbingClimbToggledOnField = typeof(CharacterClimbing).GetField("climbToggledOn", InstanceFlags);

		private static readonly FieldInfo CharacterClimbingSinceLastClimbStartedField = typeof(CharacterClimbing).GetField("sinceLastClimbStarted", InstanceFlags);

		private static readonly FieldInfo CharacterClimbingPlayerSlideField = typeof(CharacterClimbing).GetField("playerSlide", InstanceFlags);

		private static readonly MethodInfo CharacterGrabbingGrabAttachMethod = typeof(CharacterGrabbing).GetMethod("RPCA_GrabAttach", InstanceFlags);

		private static readonly PropertyInfo PlayerHandlerInstanceProperty = typeof(PlayerHandler).GetProperty("Instance", StaticFlags);

		private static readonly FieldInfo PlayerHandlerCharacterLookupField = typeof(PlayerHandler).GetField("m_playerCharacterLookup", InstanceFlags);

		private static readonly FieldInfo CharacterItemsCurrentSelectedSlotField = typeof(CharacterItems).GetField("currentSelectedSlot", InstanceFlags);

		private static readonly FieldInfo CharacterItemsLastSelectedSlotField = typeof(CharacterItems).GetField("lastSelectedSlot", InstanceFlags);

		private static readonly FieldInfo CharacterAfflictionsCharacterField = typeof(CharacterAfflictions).GetField("character", InstanceFlags);

		private static readonly object CharacterItemsNoneSlotValue = CreateOptionableNoneValue(CharacterItemsCurrentSelectedSlotField?.FieldType);

		private static FieldInfo PeakStatsStaminaBarsField;

		private static FieldInfo PeakStatsObservedCharacterField;

		private static FieldInfo PeakStatsAfflictionBarField;

		private static Type PeakStatsStaminaBarType;

		private static Type PeakStatsAfflictionType;

		private static float _peakStatsCleanupGraceUntil;

		private static bool _skipControlledCharacterFixedUpdate;

		private bool _characterFixedUpdateCompatibilityConfigured;

		private bool _loggedWaitingForPeakerHook;

		private float _nextPeakerGuardAttemptTime;

		private bool _peakStatsCompatibilityConfigured;

		private float _nextThirdPartyCompatibilityAttemptTime;

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

		private ActiveScoutmasterSession _session;

		private bool _switching;

		private float _lastToggleTime;

		private float _toggleHoldStartTime = -1f;

		private bool _toggleHoldTriggered;

		private bool _lastDetectedChineseLanguage;

		private bool _isRefreshingLanguage;

		private bool _pendingConfigFileLocalizationRefresh;

		private bool _pendingConfigFileLocalizationSave;

		private float _nextModConfigUiLocalizationTime;

		private static Transform _controlledScoutmasterCreationRoot;

		private static readonly HashSet<int> _controlledScoutmasterInstanceIds = new HashSet<int>();

		private static readonly HashSet<int> _controlledScoutmasterViewIds = new HashSet<int>();

		private static readonly HashSet<int> _controlledScoutmasterCharacterInstanceIds = new HashSet<int>();

		private static readonly Dictionary<int, int> _controlledScoutmasterOwnerActorNumbersByViewId = new Dictionary<int, int>();

		private static readonly HashSet<int> _stashedSourceCharacterIds = new HashSet<int>();

		private static readonly Dictionary<int, RendererVisualState> _rendererVisualStates = new Dictionary<int, RendererVisualState>();

		private static readonly Dictionary<int, RendererVisualState> _sourceRendererVisualStates = new Dictionary<int, RendererVisualState>();

		private static Character _cameraOverrideCharacter;

		private static Character _cameraRestoreCharacter;

		private static float _cameraRestoreUntil;

		private static GameObject _viewScoutmasterObject;

		private static bool _hasSmoothedThirdPersonCameraPose;

		private static Vector3 _smoothedThirdPersonCameraPosition;

		private static Quaternion _smoothedThirdPersonCameraRotation = Quaternion.identity;

		private static GameObject _hudCanvasObject;

		private static GameObject _namesCanvasObject;

		private static bool _hudPreviousKnown;

		private static bool _namesPreviousKnown;

		private static bool _hudPreviousActive;

		private static bool _namesPreviousActive;

		private static bool _hudHiddenForScoutmaster;

		internal static Plugin Instance { get; private set; }

		internal static ManualLogSource Log { get; private set; }

		internal static ConfigEntry<KeyCode> ToggleKey { get; private set; }

		internal static ConfigEntry<float> StaminaRefill { get; private set; }

		internal static ConfigEntry<float> ThrowForce { get; private set; }

		internal static ConfigEntry<float> ThrowUpBias { get; private set; }

		internal static ConfigEntry<float> ThrowFallSeconds { get; private set; }

		internal static ConfigEntry<float> ThirdPersonHeightOffset { get; private set; }

		internal static ConfigEntry<float> ThirdPersonDistance { get; private set; }

		internal static ConfigEntry<float> SourceStashDistance { get; private set; }

		internal static ConfigEntry<bool> RestoreAtScoutmasterPosition { get; private set; }

		internal static ConfigEntry<float> RestoreGroundOffset { get; private set; }

		internal static ConfigEntry<bool> HideHudWhileTransformed { get; private set; }

		internal static ConfigEntry<bool> VerboseLogs { get; private set; }

		private void Awake()
		{
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			_lastDetectedChineseLanguage = DetectChineseLanguage();
			BindConfig(_lastDetectedChineseLanguage);
			RegisterConfigChangeHandlers();
			MarkConfigFileLocalizationDirty(saveConfigFile: true);
			_harmony.PatchAll(typeof(ScoutmasterHarmonyPatches).Assembly);
			ConfigureCharacterFixedUpdateCompatibility();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"[I'm Scoutmaster] Loaded version 0.7.0.");
			((BaseUnityPlugin)this).Logger.LogInfo((object)("[I'm Scoutmaster] Config language: " + BuildLanguageDetectionSummary(_lastDetectedChineseLanguage)));
		}

		private void OnDestroy()
		{
			try
			{
				ExitScoutmasterForm(restorePlayer: true);
				RestoreHudAfterScoutmaster();
				UnregisterConfigChangeHandlers();
				_harmony.UnpatchSelf();
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("[I'm Scoutmaster] Cleanup failed: " + ex.Message));
			}
			finally
			{
				if ((Object)(object)Instance == (Object)(object)this)
				{
					Instance = null;
				}
			}
		}

		private void Update()
		{
			if (!_characterFixedUpdateCompatibilityConfigured && Time.unscaledTime >= _nextPeakerGuardAttemptTime)
			{
				_nextPeakerGuardAttemptTime = Time.unscaledTime + 0.5f;
				ConfigureCharacterFixedUpdateCompatibility();
			}
			if (!_peakStatsCompatibilityConfigured && Time.unscaledTime >= _nextThirdPartyCompatibilityAttemptTime)
			{
				_nextThirdPartyCompatibilityAttemptTime = Time.unscaledTime + 1f;
				ConfigureThirdPartyCompatibility();
			}
			HandleLanguageChangeIfNeeded();
			HandlePendingConfigFileLocalizationRefresh();
			TryLocalizeVisibleModConfigUiThrottled();
			RefreshRestoredPlayerCamera();
			ActiveScoutmasterSession session = _session;
			if (session != null && session.IsActive)
			{
				_session.Tick();
				UpdateScoutmasterHudState();
			}
			else
			{
				RestoreHudAfterScoutmaster();
			}
			HandleToggleHold();
		}

		private void ConfigureCharacterFixedUpdateCompatibility()
		{
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Expected O, but got Unknown
			if (_characterFixedUpdateCompatibilityConfigured)
			{
				return;
			}
			try
			{
				Type type = FindLoadedType("PEAKER.Testing");
				if (type == null)
				{
					if (!_loggedWaitingForPeakerHook)
					{
						_loggedWaitingForPeakerHook = true;
						((BaseUnityPlugin)this).Logger.LogInfo((object)"[I'm Scoutmaster] Waiting for PEAKER ragdoll hook; controlled Scoutmaster Character.FixedUpdate remains enabled.");
					}
					return;
				}
				MethodInfo method = type.GetMethod("PostCharacterGetTargetRagdollControll", StaticFlags, null, new Type[2]
				{
					typeof(CharacterData),
					typeof(float).MakeByRefType()
				}, null);
				MethodInfo methodInfo = AccessTools.Method(typeof(Plugin), "PeakerRagdollControlPostfixPrefix", (Type[])null, (Type[])null);
				if (method == null || methodInfo == null)
				{
					_skipControlledCharacterFixedUpdate = false;
					_characterFixedUpdateCompatibilityConfigured = true;
					((BaseUnityPlugin)this).Logger.LogWarning((object)"[I'm Scoutmaster] Could not install PEAKER ragdoll guard; controlled Scoutmaster Character.FixedUpdate remains enabled.");
				}
				else
				{
					_harmony.Patch((MethodBase)method, new HarmonyMethod(methodInfo), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					_skipControlledCharacterFixedUpdate = false;
					_characterFixedUpdateCompatibilityConfigured = true;
					((BaseUnityPlugin)this).Logger.LogInfo((object)"[I'm Scoutmaster] Installed PEAKER ragdoll guard; controlled Scoutmaster Character.FixedUpdate enabled.");
				}
			}
			catch (Exception ex)
			{
				_skipControlledCharacterFixedUpdate = false;
				((BaseUnityPlugin)this).Logger.LogWarning((object)("[I'm Scoutmaster] Failed to install PEAKER ragdoll guard; will retry while keeping controlled Scoutmaster Character.FixedUpdate enabled: " + ex.Message));
			}
		}

		private static Type FindLoadedType(string fullName)
		{
			if (string.IsNullOrEmpty(fullName))
			{
				return null;
			}
			try
			{
				Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
				for (int i = 0; i < assemblies.Length; i++)
				{
					Type type = assemblies[i].GetType(fullName, throwOnError: false);
					if (type != null)
					{
						return type;
					}
				}
			}
			catch
			{
			}
			return null;
		}

		private static MethodInfo FindMethod(Type type, string name, bool preferStatic, params Type[] parameterTypes)
		{
			if (type == null || string.IsNullOrEmpty(name))
			{
				return null;
			}
			BindingFlags bindingAttr = BindingFlags.Public | BindingFlags.NonPublic | (preferStatic ? BindingFlags.Static : BindingFlags.Instance);
			try
			{
				MethodInfo method = type.GetMethod(name, bindingAttr, null, parameterTypes ?? Type.EmptyTypes, null);
				if (method != null)
				{
					return method;
				}
			}
			catch
			{
			}
			try
			{
				MethodInfo[] methods = type.GetMethods(bindingAttr);
				foreach (MethodInfo methodInfo in methods)
				{
					if (methodInfo == null || methodInfo.Name != name)
					{
						continue;
					}
					ParameterInfo[] parameters = methodInfo.GetParameters();
					int num = ((parameterTypes != null) ? parameterTypes.Length : 0);
					if (parameters.Length != num)
					{
						continue;
					}
					bool flag = true;
					for (int j = 0; j < num; j++)
					{
						Type type2 = parameterTypes[j];
						Type parameterType = parameters[j].ParameterType;
						if (!(type2 == null) && !(parameterType == type2) && !string.Equals(parameterType.FullName, type2.FullName, StringComparison.Ordinal))
						{
							flag = false;
							break;
						}
					}
					if (flag)
					{
						return methodInfo;
					}
				}
			}
			catch
			{
			}
			return null;
		}

		private void ConfigureThirdPartyCompatibility()
		{
			//IL_0305: Unknown result type (might be due to invalid IL or missing references)
			//IL_0313: Expected O, but got Unknown
			//IL_034b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0359: Expected O, but got Unknown
			//IL_0364: Unknown result type (might be due to invalid IL or missing references)
			//IL_0372: Expected O, but got Unknown
			//IL_0332: Unknown result type (might be due to invalid IL or missing references)
			//IL_0340: Expected O, but got Unknown
			if (_peakStatsCompatibilityConfigured)
			{
				return;
			}
			try
			{
				Type type = FindLoadedType("PeakStats.MonoBehaviours.ProximityStaminaManager");
				Type type2 = FindLoadedType("PeakStats.MonoBehaviours.CharacterStaminaBar");
				Type type3 = FindLoadedType("PeakStats.MonoBehaviours.CharacterBarAffliction");
				if (type == null || type2 == null || type3 == null)
				{
					LogVerbose("[I'm Scoutmaster] PeakStats types not found yet, will retry. ProximityManager=" + (type != null) + " StaminaBar=" + (type2 != null) + " BarAffliction=" + (type3 != null));
					return;
				}
				MethodInfo methodInfo = FindMethod(type, "Update", preferStatic: false, Type.EmptyTypes);
				MethodInfo methodInfo2 = FindMethod(type, "CreateStaminaBar", true, typeof(Character));
				MethodInfo methodInfo3 = FindMethod(type2, "Update", preferStatic: false, Type.EmptyTypes);
				MethodInfo methodInfo4 = FindMethod(type3, "FetchReferences", preferStatic: false, Type.EmptyTypes);
				FieldInfo field = type.GetField("staminaBars", InstanceFlags);
				FieldInfo field2 = type2.GetField("_observedCharacter", InstanceFlags);
				FieldInfo field3 = type3.GetField("characterStaminaBar", InstanceFlags);
				MethodInfo methodInfo5 = AccessTools.Method(typeof(Plugin), "PeakStatsProximityManagerUpdatePrefix", (Type[])null, (Type[])null);
				MethodInfo methodInfo6 = AccessTools.Method(typeof(Plugin), "PeakStatsCreateStaminaBarPrefix", (Type[])null, (Type[])null);
				MethodInfo methodInfo7 = AccessTools.Method(typeof(Plugin), "PeakStatsCharacterStaminaBarUpdatePrefix", (Type[])null, (Type[])null);
				MethodInfo methodInfo8 = AccessTools.Method(typeof(Plugin), "PeakStatsCharacterBarAfflictionFetchReferencesPrefix", (Type[])null, (Type[])null);
				if (methodInfo == null || methodInfo3 == null || methodInfo4 == null || field == null || field2 == null || field3 == null || methodInfo5 == null || methodInfo7 == null || methodInfo8 == null)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("[I'm Scoutmaster] PeakStats types found but some members missing. Update=" + (methodInfo != null) + " CreateStaminaBar=" + (methodInfo2 != null) + " StaminaBarUpdate=" + (methodInfo3 != null) + " FetchReferences=" + (methodInfo4 != null) + " staminaBars=" + (field != null) + " _observedCharacter=" + (field2 != null) + " characterStaminaBar=" + (field3 != null)));
				}
				else
				{
					PeakStatsStaminaBarsField = field;
					PeakStatsObservedCharacterField = field2;
					PeakStatsAfflictionBarField = field3;
					PeakStatsStaminaBarType = type2;
					PeakStatsAfflictionType = type3;
					_harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(methodInfo5), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					if (methodInfo2 != null && methodInfo6 != null)
					{
						_harmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(methodInfo6), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					}
					_harmony.Patch((MethodBase)methodInfo3, new HarmonyMethod(methodInfo7), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					_harmony.Patch((MethodBase)methodInfo4, new HarmonyMethod(methodInfo8), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					CleanupPeakStatsUi();
					_peakStatsCompatibilityConfigured = true;
					((BaseUnityPlugin)this).Logger.LogInfo((object)"[I'm Scoutmaster] Installed PeakStats compatibility guard for controlled Scoutmaster.");
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("[I'm Scoutmaster] Failed to install PeakStats compatibility guard: " + ex.Message));
			}
		}

		private static bool PeakerRagdollControlPostfixPrefix([HarmonyArgument("__instance")] CharacterData data, [HarmonyArgument("__result")] ref float ragdollControl)
		{
			try
			{
				object? obj = CharacterDataCharacterField?.GetValue(data);
				Character val = (Character)((obj is Character) ? obj : null);
				if ((Object)(object)val == (Object)null && (Object)(object)data != (Object)null)
				{
					val = ((Component)data).GetComponent<Character>();
				}
				if (IsStashedSourceCharacter(val) || (IsControlledScoutmasterCharacter(val) && !IsControlledScoutmasterIncapacitated(val)))
				{
					ragdollControl = 1f;
					return false;
				}
			}
			catch
			{
			}
			return true;
		}

		internal static void SetCharacterDeadWithoutReconnect(Character character, bool dead)
		{
			if ((Object)(object)character?.data == (Object)null)
			{
				return;
			}
			try
			{
				if (CharacterDataDeadField != null)
				{
					CharacterDataDeadField.SetValue(character.data, dead);
					return;
				}
			}
			catch
			{
			}
			try
			{
				if (character.data.dead != dead)
				{
					character.data.dead = dead;
				}
			}
			catch
			{
			}
		}

		internal static bool ShouldSkipReconnectDataUpdate(Character character)
		{
			if ((Object)(object)character == (Object)null)
			{
				return true;
			}
			if (IsControlledScoutmasterCharacter(character) || IsStashedSourceCharacter(character) || IsCharacterInControlledCreationRoot(character))
			{
				return true;
			}
			try
			{
				if ((Object)(object)character.data == (Object)null || character.refs == null || (Object)(object)character.refs.afflictions == (Object)null || (Object)(object)character.refs.stats == (Object)null)
				{
					return true;
				}
				return (Object)(object)character.player == (Object)null;
			}
			catch
			{
				return true;
			}
		}

		internal static bool ShouldSuppressSlipperyJellyfishSend(Collider other)
		{
			if ((Object)(object)other == (Object)null)
			{
				return false;
			}
			try
			{
				Character val = default(Character);
				if (!CharacterRagdoll.TryGetCharacterFromCollider(other, ref val))
				{
					return false;
				}
				if (IsStashedSourceCharacter(val) || IsCharacterInControlledCreationRoot(val))
				{
					return true;
				}
				if ((Object)(object)val == (Object)(object)Character.localCharacter && ((Object)(object)val.refs?.view == (Object)null || val.refs.view.ViewID <= 0))
				{
					return true;
				}
			}
			catch
			{
			}
			return false;
		}

		internal static bool ShouldSkipSlipperyJellyfishTrigger(int targetID)
		{
			if (targetID <= 0)
			{
				return true;
			}
			try
			{
				PhotonView val = PhotonView.Find(targetID);
				if ((Object)(object)val == (Object)null)
				{
					return true;
				}
				Character component = ((Component)val).GetComponent<Character>();
				if ((Object)(object)component == (Object)null || (Object)(object)component.data == (Object)null || component.refs == null || (Object)(object)component.refs.afflictions == (Object)null)
				{
					return true;
				}
				if (IsStashedSourceCharacter(component) || IsCharacterInControlledCreationRoot(component))
				{
					return true;
				}
				Bodypart bodypart = GetBodypart(component, (BodypartType)16);
				int result;
				if (!((Object)(object)((bodypart != null) ? bodypart.Rig : null) == (Object)null))
				{
					Bodypart bodypart2 = GetBodypart(component, (BodypartType)13);
					if (!((Object)(object)((bodypart2 != null) ? bodypart2.Rig : null) == (Object)null))
					{
						Bodypart bodypart3 = GetBodypart(component, (BodypartType)0);
						if (!((Object)(object)((bodypart3 != null) ? bodypart3.Rig : null) == (Object)null))
						{
							Bodypart bodypart4 = GetBodypart(component, (BodypartType)4);
							result = (((Object)(object)((bodypart4 != null) ? bodypart4.Rig : null) == (Object)null) ? 1 : 0);
							goto IL_00e1;
						}
					}
				}
				result = 1;
				goto IL_00e1;
				IL_00e1:
				return (byte)result != 0;
			}
			catch
			{
				return true;
			}
		}

		private void LateUpdate()
		{
			RefreshControlledScoutmasterVisuals();
			ActiveScoutmasterSession session = _session;
			if (session != null && session.IsActive)
			{
				UpdateScoutmasterHudState();
			}
			RefreshRestoredPlayerCamera();
		}

		private void BindConfig(bool isChineseLanguage)
		{
			ToggleKey = BindEntry<KeyCode>(ConfigKey.ToggleKey, (KeyCode)103, isChineseLanguage);
			StaminaRefill = BindEntry(ConfigKey.StaminaRefill, 1f, isChineseLanguage);
			ThrowForce = BindEntry(ConfigKey.ThrowForce, 1500f, isChineseLanguage);
			ThrowUpBias = BindEntry(ConfigKey.ThrowUpBias, 0.3f, isChineseLanguage);
			ThrowFallSeconds = BindEntry(ConfigKey.ThrowFallSeconds, 3f, isChineseLanguage);
			ThirdPersonHeightOffset = BindEntry(ConfigKey.ThirdPersonHeightOffset, 1.35f, isChineseLanguage);
			ThirdPersonDistance = BindEntry(ConfigKey.ThirdPersonDistance, 7.5f, isChineseLanguage);
			SourceStashDistance = BindEntry(ConfigKey.SourceStashDistance, 30f, isChineseLanguage);
			RestoreAtScoutmasterPosition = BindEntry(ConfigKey.RestoreAtScoutmasterPosition, defaultValue: true, isChineseLanguage);
			RestoreGroundOffset = BindEntry(ConfigKey.RestoreGroundOffset, 1.2f, isChineseLanguage);
			HideHudWhileTransformed = BindEntry(ConfigKey.HideHudWhileTransformed, defaultValue: true, isChineseLanguage);
			VerboseLogs = BindEntry(ConfigKey.VerboseLogs, defaultValue: false, isChineseLanguage);
			MigrateLocalizedConfigEntries();
			ClampConfigValues();
		}

		private ConfigEntry<T> BindEntry<T>(ConfigKey configKey, T defaultValue, bool isChineseLanguage)
		{
			return ((BaseUnityPlugin)this).Config.Bind<T>(GetSectionName(configKey, isChineseLanguage), GetKeyName(configKey, isChineseLanguage), defaultValue, CreateConfigDescription(configKey, isChineseLanguage));
		}

		private ConfigDescription CreateConfigDescription(ConfigKey configKey, bool isChineseLanguage)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected O, but got Unknown
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Expected O, but got Unknown
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Expected O, but got Unknown
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Expected O, but got Unknown
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Expected O, but got Unknown
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Expected O, but got Unknown
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Expected O, but got Unknown
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Expected O, but got Unknown
			string localizedDescription = GetLocalizedDescription(configKey, isChineseLanguage);
			return (ConfigDescription)(configKey switch
			{
				ConfigKey.StaminaRefill => (object)new ConfigDescription(localizedDescription, (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 1f), Array.Empty<object>()), 
				ConfigKey.ThrowForce => (object)new ConfigDescription(localizedDescription, (AcceptableValueBase)(object)new AcceptableValueRange<float>(100f, 5000f), Array.Empty<object>()), 
				ConfigKey.ThrowUpBias => (object)new ConfigDescription(localizedDescription, (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>()), 
				ConfigKey.ThrowFallSeconds => (object)new ConfigDescription(localizedDescription, (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>()), 
				ConfigKey.ThirdPersonHeightOffset => (object)new ConfigDescription(localizedDescription, (AcceptableValueBase)(object)new AcceptableValueRange<float>(-2f, 6f), Array.Empty<object>()), 
				ConfigKey.ThirdPersonDistance => (object)new ConfigDescription(localizedDescription, (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 16f), Array.Empty<object>()), 
				ConfigKey.SourceStashDistance => (object)new ConfigDescription(localizedDescription, (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 200f), Array.Empty<object>()), 
				ConfigKey.RestoreGroundOffset => (object)new ConfigDescription(localizedDescription, (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 5f), Array.Empty<object>()), 
				_ => (object)new ConfigDescription(localizedDescription, (AcceptableValueBase)null, Array.Empty<object>()), 
			});
		}

		internal static float GetControlledStaminaFill()
		{
			return Mathf.Clamp(StaminaRefill?.Value ?? 1f, 0.1f, 1f);
		}

		private void ToggleScoutmasterForm()
		{
			if (!_switching)
			{
				ActiveScoutmasterSession session = _session;
				if (session != null && session.IsActive)
				{
					ExitScoutmasterForm(restorePlayer: true);
				}
				else
				{
					((MonoBehaviour)this).StartCoroutine(EnterScoutmasterFormRoutine());
				}
			}
		}

		private void HandleToggleHold()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			KeyCode value = ToggleKey.Value;
			if (Input.GetKeyDown(value))
			{
				_toggleHoldStartTime = Time.unscaledTime;
				_toggleHoldTriggered = false;
			}
			if (Input.GetKeyUp(value))
			{
				float num = ((_toggleHoldStartTime >= 0f) ? (Time.unscaledTime - _toggleHoldStartTime) : 0f);
				bool num2 = !_toggleHoldTriggered && num > 0f && num <= 0.3f;
				_toggleHoldStartTime = -1f;
				_toggleHoldTriggered = false;
				if (num2)
				{
					ActiveScoutmasterSession session = _session;
					if (session != null && session.IsActive && Time.unscaledTime - _lastToggleTime >= 0.35f)
					{
						_lastToggleTime = Time.unscaledTime;
						TriggerControlledScoutmasterManualFall();
					}
				}
			}
			else if (!Input.GetKey(value))
			{
				_toggleHoldStartTime = -1f;
				_toggleHoldTriggered = false;
			}
			else if (!_toggleHoldTriggered && !(_toggleHoldStartTime < 0f) && !(Time.unscaledTime - _toggleHoldStartTime < 1f) && !(Time.unscaledTime - _lastToggleTime < 0.35f))
			{
				_toggleHoldTriggered = true;
				_lastToggleTime = Time.unscaledTime;
				ToggleScoutmasterForm();
			}
		}

		private void TriggerControlledScoutmasterManualFall()
		{
			Character controlledScoutmasterCharacter = GetControlledScoutmasterCharacter();
			if (!((Object)(object)controlledScoutmasterCharacter == (Object)null))
			{
				TriggerControlledScoutmasterManualFall(controlledScoutmasterCharacter);
			}
		}

		[IteratorStateMachine(typeof(<EnterScoutmasterFormRoutine>d__198))]
		private IEnumerator EnterScoutmasterFormRoutine()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <EnterScoutmasterFormRoutine>d__198(0)
			{
				<>4__this = this
			};
		}

		private static bool CanTransform(Character sourceCharacter)
		{
			if ((Object)(object)sourceCharacter == (Object)null)
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogWarning((object)"[I'm Scoutmaster] No local character found.");
				}
				return false;
			}
			if ((Object)(object)sourceCharacter.data == (Object)null || sourceCharacter.refs == null || (Object)(object)((MonoBehaviourPun)sourceCharacter).photonView == (Object)null)
			{
				ManualLogSource log2 = Log;
				if (log2 != null)
				{
					log2.LogWarning((object)"[I'm Scoutmaster] Local character is not ready yet.");
				}
				return false;
			}
			if (IsDeadForTransform(sourceCharacter))
			{
				ManualLogSource log3 = Log;
				if (log3 != null)
				{
					log3.LogWarning((object)"[I'm Scoutmaster] Cannot transform after the player has died.");
				}
				return false;
			}
			if (IsControlledScoutmasterCharacter(sourceCharacter))
			{
				ManualLogSource log4 = Log;
				if (log4 != null)
				{
					log4.LogWarning((object)"[I'm Scoutmaster] Already controlling Scoutmaster.");
				}
				return false;
			}
			return true;
		}

		private static bool IsDeadForTransform(Character character)
		{
			if ((Object)(object)character?.data == (Object)null)
			{
				return false;
			}
			try
			{
				if (character.data.dead)
				{
					return true;
				}
			}
			catch
			{
			}
			try
			{
				return character.data.fullyPassedOut && character.data.deathTimer >= 1f;
			}
			catch
			{
				return false;
			}
		}

		private static Quaternion GetSpawnRotation(Character sourceCharacter)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: 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_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: 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_0045: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = sourceCharacter.data.lookDirection_Flat;
			if (((Vector3)(ref val)).sqrMagnitude < 0.0001f)
			{
				val = ((Component)sourceCharacter).transform.forward;
			}
			val = Vector3.ProjectOnPlane(val, Vector3.up);
			if (((Vector3)(ref val)).sqrMagnitude < 0.0001f)
			{
				val = Vector3.forward;
			}
			return Quaternion.LookRotation(((Vector3)(ref val)).normalized, Vector3.up);
		}

		private static GameObject CreateScoutmaster(Vector3 position, Quaternion rotation)
		{
			//IL_0005: 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_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = TryCreateNetworkScoutmaster("Character_Scoutmaster", position, rotation);
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			return TryCreateLocalScoutmaster("Character_Scoutmaster", position, rotation);
		}

		private static GameObject TryCreateNetworkScoutmaster(string resourceName, Vector3 position, Quaternion rotation)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			if (string.IsNullOrWhiteSpace(resourceName) || (!PhotonNetwork.InRoom && !PhotonNetwork.OfflineMode))
			{
				return null;
			}
			try
			{
				return PhotonNetwork.Instantiate(resourceName, position, rotation, (byte)0, BuildControlledScoutmasterInstantiationData());
			}
			catch (Exception ex)
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogWarning((object)("[I'm Scoutmaster] Photon instantiate failed for " + resourceName + ": " + ex.Message));
				}
				return null;
			}
		}

		private static object[] BuildControlledScoutmasterInstantiationData()
		{
			int num = 0;
			try
			{
				Player localPlayer = Player.localPlayer;
				if ((Object)(object)((localPlayer != null) ? ((MonoBehaviourPun)localPlayer).photonView : null) != (Object)null)
				{
					num = ((MonoBehaviourPun)Player.localPlayer).photonView.OwnerActorNr;
				}
				else if (PhotonNetwork.LocalPlayer != null)
				{
					num = PhotonNetwork.LocalPlayer.ActorNumber;
				}
			}
			catch
			{
				num = 0;
			}
			return new object[3] { "ImScoutmaster.ControlledScoutmaster", 1, num };
		}

		private static GameObject TryCreateLocalScoutmaster(string resourceName, Vector3 position, Quaternion rotation)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//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)
			try
			{
				GameObject val = Resources.Load<GameObject>(resourceName);
				if ((Object)(object)val == (Object)null)
				{
					return null;
				}
				GameObject val2 = new GameObject("ImScoutmaster_LocalScoutmaster_Staging");
				val2.SetActive(false);
				_controlledScoutmasterCreationRoot = val2.transform;
				try
				{
					GameObject obj = Object.Instantiate<GameObject>(val, position, rotation, val2.transform);
					obj.SetActive(false);
					obj.transform.SetParent((Transform)null, true);
					return obj;
				}
				finally
				{
					_controlledScoutmasterCreationRoot = null;
					Object.Destroy((Object)(object)val2);
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogWarning((object)("[I'm Scoutmaster] Local instantiate failed for " + resourceName + ": " + ex.Message));
				}
				return null;
			}
		}

		internal void ExitScoutmasterForm(bool restorePlayer)
		{
			if (_session == null)
			{
				return;
			}
			_switching = true;
			try
			{
				_session.Exit(restorePlayer);
			}
			finally
			{
				_session = null;
				ClearCameraOverride();
				_viewScoutmasterObject = null;
				RestoreHudAfterScoutmaster();
				_switching = false;
			}
		}

		internal static bool ShouldUseIsolatedCharacterLifecycle(Character character)
		{
			if ((Object)(object)character != (Object)null && HasScoutmasterComponent(character))
			{
				if (!IsCharacterInControlledCreationRoot(character))
				{
					return IsControlledScoutmasterCharacter(character);
				}
				return true;
			}
			return false;
		}

		internal static bool ShouldSkipCharacterRegistration(Character character)
		{
			if ((Object)(object)character == (Object)null || !HasScoutmasterComponent(character))
			{
				return false;
			}
			if (!IsCharacterInControlledCreationRoot(character) && !IsControlledScoutmasterCharacter(character))
			{
				return false;
			}
			LogVerbose("Skipped PlayerHandler registra