Decompiled source of I am Zombie v0.1.0

plugins/Thanks.I_am_a_Zombie.dll

Decompiled 9 hours 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 Peak.Afflictions;
using Photon.Pun;
using Photon.Realtime;
using TMPro;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Thanks.ImZombie")]
[assembly: AssemblyDescription("Client-side controllable zombie form for PEAK.")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Thanks")]
[assembly: AssemblyProduct("I'm Zombie")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("4fe3df28-2f61-446e-839f-56e4d41c6f0a")]
[assembly: AssemblyFileVersion("0.0.4.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("0.0.4.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 ImZombie
{
	[BepInPlugin("com.github.Thanks.ImZombie", "I'm Zombie", "0.0.4")]
	public sealed class Plugin : BaseUnityPlugin
	{
		private enum ConfigKey
		{
			ToggleKey,
			MoveForwardKey,
			MoveBackwardKey,
			MoveLeftKey,
			MoveRightKey,
			JumpKey,
			SprintKey,
			ClimbKey,
			PounceKey,
			ChaseToggleKey,
			ViewToggleKey,
			PounceDuration,
			PounceCooldown,
			PounceForwardVelocity,
			PounceUpVelocity,
			PounceSfxEnabled,
			ZombieMushroomAppearance,
			SprintStaminaRefill,
			ControlledJitterChance,
			ControlledJitterIntensity,
			ControlledJitterDuration,
			FirstPersonHeightOffset,
			ThirdPersonHeightOffset,
			ThirdPersonDistance,
			StartInThirdPerson,
			SourceStashDistance,
			RestoreAtZombiePosition,
			RestoreGroundOffset,
			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 ImZombiePrefabPool : IPunPrefabPool
		{
			private readonly IPunPrefabPool _inner;

			private GameObject _playerZombiePrefab;

			public IPunPrefabPool Inner => _inner;

			public ImZombiePrefabPool(IPunPrefabPool inner)
			{
				_inner = inner;
			}

			public bool TryGetCachedPrefab(string prefabId, out GameObject prefab)
			{
				prefab = null;
				if (string.Equals(prefabId, "MushroomZombie_Player", StringComparison.Ordinal))
				{
					if ((Object)(object)_playerZombiePrefab != (Object)null)
					{
						prefab = _playerZombiePrefab;
						return true;
					}
					_playerZombiePrefab = null;
				}
				return false;
			}

			public GameObject Instantiate(string prefabId, Vector3 position, Quaternion rotation)
			{
				//IL_021a: Unknown result type (might be due to invalid IL or missing references)
				//IL_021b: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
				//IL_004a: Unknown result type (might be due to invalid IL or missing references)
				//IL_004b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0031: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_018a: Unknown result type (might be due to invalid IL or missing references)
				//IL_018b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0153: Unknown result type (might be due to invalid IL or missing references)
				//IL_0154: Unknown result type (might be due to invalid IL or missing references)
				//IL_0111: Unknown result type (might be due to invalid IL or missing references)
				//IL_0112: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
				//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
				//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
				bool flag = string.Equals(prefabId, "MushroomZombie_Player", StringComparison.Ordinal);
				bool flag2 = string.Equals(prefabId, "Character", StringComparison.Ordinal);
				if (!flag && !flag2)
				{
					if (_inner == null)
					{
						return null;
					}
					return _inner.Instantiate(prefabId, position, rotation);
				}
				GameObject instance;
				if (flag)
				{
					if (TryGetRuntimeOrKnownPrefab(prefabId, out var prefab))
					{
						GameObject val = InstantiateCachedPlayerZombiePrefab(prefab, position, rotation);
						if ((Object)(object)val != (Object)null)
						{
							LogVerbose("Instantiated " + prefabId + " through ImZombie stable prefab backup.");
							return val;
						}
						ManualLogSource log = Log;
						if (log != null)
						{
							log.LogWarning((object)("[I'm Zombie] Stable prefab backup for " + prefabId + " was present but could not be cloned; falling back to inner prefab pool."));
						}
					}
					if (TryCapturePrefabFromPool(_inner, prefabId, new HashSet<object>(), out var prefab2) && (Object)(object)prefab2 != (Object)null)
					{
						RegisterRuntimeNetworkPrefabBackupFromPrefab(prefabId, prefab2, !HasAliveRuntimeNetworkPrefabBackup(prefabId));
						GameObject val2 = InstantiateCachedPlayerZombiePrefab(prefab2, position, rotation);
						if ((Object)(object)val2 != (Object)null)
						{
							_playerZombiePrefab = prefab2;
							LogVerbose("Instantiated " + prefabId + " through ImZombie prefab pool wrapper.");
							return val2;
						}
					}
					if (TryGetCachedPrefab(prefabId, out var prefab3) || TryGetRuntimeOrKnownPrefab(prefabId, out prefab3))
					{
						GameObject val3 = InstantiateCachedPlayerZombiePrefab(prefab3, position, rotation);
						if ((Object)(object)val3 != (Object)null)
						{
							LogVerbose("Instantiated " + prefabId + " through ImZombie prefab pool wrapper.");
							return val3;
						}
					}
				}
				else if (flag2 && ShouldRecoverOriginalCharacterSpawnFromBackup() && !TryCaptureOriginalCharacterPrefabFromInnerPool(_inner) && TryInstantiateOriginalPlayerCharacterBackup(position, rotation, out instance))
				{
					ManualLogSource log2 = Log;
					if (log2 != null)
					{
						log2.LogWarning((object)"[I'm Zombie] Inner prefab pool has no usable Character prefab during level spawn; instantiated cached original Character backup before exception fallback.");
					}
					return instance;
				}
				GameObject val4 = null;
				try
				{
					val4 = ((_inner != null) ? _inner.Instantiate(prefabId, position, rotation) : null);
				}
				catch (Exception ex)
				{
					if (flag && (TryGetCachedPrefab(prefabId, out var prefab4) || TryGetRuntimeOrKnownPrefab(prefabId, out prefab4)))
					{
						GameObject val5 = InstantiateCachedNetworkPrefab(prefabId, prefab4, position, rotation);
						if ((Object)(object)val5 != (Object)null)
						{
							ManualLogSource log3 = Log;
							if (log3 != null)
							{
								log3.LogWarning((object)("[I'm Zombie] Inner prefab pool failed for " + prefabId + "; instantiated cached prefab through ImZombie wrapper instead: " + ex.Message));
							}
							return val5;
						}
					}
					if (_inner != null)
					{
						try
						{
							ClearInvalidPrefabPoolResourceCache(_inner, prefabId, new HashSet<object>());
							val4 = _inner.Instantiate(prefabId, position, rotation);
							if ((Object)(object)val4 != (Object)null)
							{
								ManualLogSource log4 = Log;
								if (log4 != null)
								{
									log4.LogWarning((object)("[I'm Zombie] Inner prefab pool failed for " + prefabId + "; cleared invalid cache and retried successfully: " + ex.Message));
								}
								return val4;
							}
						}
						catch (Exception ex2)
						{
							ManualLogSource log5 = Log;
							if (log5 != null)
							{
								log5.LogWarning((object)("[I'm Zombie] Inner prefab pool failed for " + prefabId + " and cache retry did not recover:\n" + ex2));
							}
						}
					}
					ManualLogSource log6 = Log;
					if (log6 != null)
					{
						log6.LogWarning((object)("[I'm Zombie] Inner prefab pool failed for " + prefabId + ":\n" + ex));
					}
					if (flag2 && TryInstantiateOriginalPlayerCharacterBackup(position, rotation, out var instance2))
					{
						ManualLogSource log7 = Log;
						if (log7 != null)
						{
							log7.LogWarning((object)"[I'm Zombie] Inner prefab pool failed for Character; instantiated cached original Character backup as a last-resort fallback.");
						}
						return instance2;
					}
					throw;
				}
				if (flag)
				{
					CapturePlayerZombiePrefabFromInnerPool(prefabId);
				}
				else if (flag2)
				{
					CaptureOriginalPlayerCharacterPrefabBackup(prefabId);
				}
				return val4;
			}

			public void Destroy(GameObject gameObject)
			{
				if ((Object)(object)gameObject == (Object)null)
				{
					return;
				}
				try
				{
					if (_inner != null)
					{
						_inner.Destroy(gameObject);
						return;
					}
				}
				catch (Exception ex)
				{
					LogVerbose("Inner prefab pool destroy failed for " + ((Object)gameObject).name + ": " + ex.Message);
				}
				Object.Destroy((Object)(object)gameObject);
			}

			private static GameObject InstantiateCachedPlayerZombiePrefab(GameObject prefab, Vector3 position, Quaternion rotation)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				return InstantiateCachedNetworkPrefab("MushroomZombie_Player", prefab, position, rotation);
			}

			private static GameObject InstantiateCachedNetworkPrefab(string prefabId, GameObject prefab, Vector3 position, Quaternion rotation)
			{
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Unknown result type (might be due to invalid IL or missing references)
				//IL_0037: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)prefab == (Object)null)
				{
					return null;
				}
				try
				{
					GameObject val = InstantiateInactivePrefabCopy(prefab, position, rotation);
					if ((Object)(object)val == (Object)null)
					{
						return null;
					}
					((Object)val).name = prefabId;
					ResetRuntimeNetworkPrefabObject(val, keepInactive: true);
					val.transform.SetPositionAndRotation(position, rotation);
					return val;
				}
				catch (Exception ex)
				{
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogWarning((object)("[I'm Zombie] Failed to instantiate cached " + prefabId + " prefab: " + ex.Message));
					}
					return null;
				}
			}

			private void CapturePlayerZombiePrefabFromInnerPool(string prefabId)
			{
				if ((Object)(object)_playerZombiePrefab != (Object)null)
				{
					return;
				}
				try
				{
					if (TryCapturePrefabFromPool(_inner, prefabId, new HashSet<object>(), out var prefab) && (Object)(object)prefab != (Object)null)
					{
						_playerZombiePrefab = prefab;
						_knownPhotonPrefabCache[prefabId] = prefab;
						RegisterRuntimeNetworkPrefabBackupFromPrefab(prefabId, prefab, !HasAliveRuntimeNetworkPrefabBackup(prefabId));
						ManualLogSource log = Log;
						if (log != null)
						{
							log.LogInfo((object)("[I'm Zombie] Captured " + prefabId + " prefab in ImZombie prefab pool wrapper."));
						}
					}
				}
				catch (Exception ex)
				{
					LogVerbose("Failed to capture " + prefabId + " prefab from inner Photon pool: " + ex.Message);
				}
			}
		}

		[StructLayout(LayoutKind.Sequential, Size = 1)]
		internal readonly struct ControlledZombieOriginalBehaviorScope : IDisposable
		{
			public void Dispose()
			{
				EndControlledZombieOriginalBehavior();
			}
		}

		private sealed class ActiveZombieSession
		{
			private enum SessionState
			{
				Created,
				Entering,
				Active,
				Exiting,
				Exited
			}

			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__33 : IEnumerator<object>, IDisposable, IEnumerator
			{
				private int <>1__state;

				private object <>2__current;

				public ActiveZombieSession <>4__this;

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

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

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

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

				private bool MoveNext()
				{
					int num = <>1__state;
					ActiveZombieSession activeZombieSession = <>4__this;
					switch (num)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						if (activeZombieSession._state != 0)
						{
							return false;
						}
						activeZombieSession._state = SessionState.Entering;
						activeZombieSession.PreconfigureZombieForLocalControl();
						activeZombieSession._controller = activeZombieSession._zombieObject.GetComponent<PlayerZombieController>() ?? activeZombieSession._zombieObject.AddComponent<PlayerZombieController>();
						activeZombieSession._controller.Initialize(activeZombieSession._sourceCharacter, activeZombieSession._zombie, activeZombieSession._zombieCharacter);
						RegisterControlledZombie(activeZombieSession._zombie);
						Character.localCharacter = activeZombieSession._zombieCharacter;
						ForcePlayerCharacterLookup(activeZombieSession._zombieCharacter);
						activeZombieSession._localCharacterSwapped = true;
						BeginNativeAriseSuppressionByViewId(activeZombieSession._sourceViewId);
						ExtendNativeAriseSuppressionByViewId(activeZombieSession._sourceViewId);
						SetGameObjectActive(activeZombieSession._zombieObject, active: true);
						activeZombieSession.AlignZombieBodyToSource();
						<>2__current = null;
						<>1__state = 1;
						return true;
					case 1:
						<>1__state = -1;
						activeZombieSession.AlignZombieBodyToSource();
						activeZombieSession.PrepareZombie();
						ApplyControlledZombieNativePresentation(activeZombieSession._zombie, activeZombieSession._zombieCharacter, activeZombieSession._sourceCharacter);
						SetCameraOverride(activeZombieSession._zombieCharacter);
						_viewZombieObject = activeZombieSession._zombieObject;
						HideHudForZombie();
						SetZombieRenderersVisible(activeZombieSession._zombieObject, visible: true);
						activeZombieSession._controller.ActivateDynamicRagdollControl();
						activeZombieSession._controller.ForceGroundSnap();
						Character.localCharacter = activeZombieSession._zombieCharacter;
						ForcePlayerCharacterLookup(activeZombieSession._zombieCharacter);
						activeZombieSession._localCharacterSwapped = true;
						activeZombieSession._state = SessionState.Active;
						activeZombieSession.HideSourceCharacter();
						LogVerbose("Entered zombie 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 int _sourceViewId;

			private readonly GameObject _zombieObject;

			private readonly MushroomZombie _zombie;

			private readonly Character _zombieCharacter;

			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 PlayerZombieController _controller;

			private bool _sourcePhysicsSuspended;

			private bool _sourceStatusRestoredThisExit;

			private Vector3 _lastStableRestorePosition;

			private bool _hasLastStableRestorePosition;

			private SessionState _state;

			private bool _sourceLossLogged;

			private bool _localCharacterSwapped;

			private bool _sourceHidden;

			public bool IsActive
			{
				get
				{
					if (_state == SessionState.Active)
					{
						return HasControlledZombieObjects;
					}
					return false;
				}
			}

			private bool HasRequiredObjects
			{
				get
				{
					if ((Object)(object)_sourceCharacter != (Object)null)
					{
						return HasControlledZombieObjects;
					}
					return false;
				}
			}

			private bool HasControlledZombieObjects
			{
				get
				{
					if ((Object)(object)_zombieObject != (Object)null && (Object)(object)_zombie != (Object)null)
					{
						return (Object)(object)_zombieCharacter != (Object)null;
					}
					return false;
				}
			}

			public ActiveZombieSession(Character sourceCharacter, GameObject zombieObject, MushroomZombie zombie, Character zombieCharacter, bool sourceWasActive)
			{
				//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_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_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)
				_sourceCharacter = sourceCharacter;
				_sourceViewId = GetCharacterViewId(sourceCharacter);
				_zombieObject = zombieObject;
				_zombie = zombie;
				_zombieCharacter = zombieCharacter;
				_sourceStartPosition = sourceCharacter.Center;
				_sourceStashPosition = BuildSourceStashPosition(_sourceStartPosition);
				_sourceStartRotation = GetSpawnRotation(sourceCharacter);
				_sourceWasActive = sourceWasActive;
			}

			internal bool IsSourceCharacter(Character character)
			{
				if ((Object)(object)character != (Object)null)
				{
					return (Object)(object)character == (Object)(object)_sourceCharacter;
				}
				return false;
			}

			internal bool IsSourceViewId(int viewId)
			{
				if (viewId > 0)
				{
					return viewId == _sourceViewId;
				}
				return false;
			}

			internal bool TryGetControlledCharacter(out Character character)
			{
				character = null;
				if ((_state != SessionState.Entering && _state != SessionState.Active) || !HasControlledZombieObjects)
				{
					return false;
				}
				character = _zombieCharacter;
				return true;
			}

			internal bool TryTriggerFaint()
			{
				if (!IsActive || (Object)(object)_controller == (Object)null)
				{
					return false;
				}
				return _controller.TryTriggerFaint();
			}

			private static Vector3 BuildSourceStashPosition(Vector3 sourcePosition)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_0017: 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_0022: 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)
				float effectiveSourceStashDistance = GetEffectiveSourceStashDistance();
				Vector3 val = sourcePosition + Vector3.down * effectiveSourceStashDistance;
				if (!IsFiniteVector(val))
				{
					return sourcePosition;
				}
				return val;
			}

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

			private void SendNativeArise()
			{
				if ((Object)(object)_sourceCharacter == (Object)null || (Object)(object)((MonoBehaviourPun)_sourceCharacter).photonView == (Object)null || (Object)(object)_zombie == (Object)null)
				{
					return;
				}
				int viewID = ((MonoBehaviourPun)_sourceCharacter).photonView.ViewID;
				if (viewID <= 0)
				{
					return;
				}
				try
				{
					BeginControlledZombieOriginalBehavior();
					try
					{
						PhotonView photonView = ((MonoBehaviourPun)_zombie).photonView;
						if (HasNetworkView(photonView))
						{
							photonView.RPC("RPC_Arise", (RpcTarget)0, new object[1] { viewID });
						}
						else if (PhotonNetwork.InRoom)
						{
							LogVerbose("Skipped native arise RPC for local-only zombie in a network room.");
						}
						else if (!PhotonNetwork.OfflineMode)
						{
							InvokeNativeAriseReflectively(viewID);
						}
					}
					finally
					{
						EndControlledZombieOriginalBehavior();
					}
				}
				catch (Exception ex)
				{
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogWarning((object)("[I'm Zombie] Native RPC_Arise failed: " + ex.Message));
					}
				}
			}

			private void InvokeNativeAriseReflectively(int sourceViewId)
			{
				MethodBase methodBase = FindMushroomZombieAriseMethod();
				if (!(methodBase == null))
				{
					ParameterInfo[] parameters = methodBase.GetParameters();
					object[] array = new object[parameters.Length];
					if (array.Length != 0)
					{
						array[0] = sourceViewId;
					}
					for (int i = 1; i < array.Length; i++)
					{
						Type parameterType = parameters[i].ParameterType;
						array[i] = (parameterType.IsValueType ? Activator.CreateInstance(parameterType) : null);
					}
					methodBase.Invoke(_zombie, array);
				}
			}

			public void AbortEnter()
			{
				//IL_0067: Unknown result type (might be due to invalid IL or missing references)
				//IL_006d: Unknown result type (might be due to invalid IL or missing references)
				if (_state == SessionState.Exited)
				{
					return;
				}
				_state = SessionState.Exiting;
				try
				{
					if ((Object)(object)_controller != (Object)null)
					{
						((Behaviour)_controller).enabled = false;
					}
				}
				catch
				{
				}
				try
				{
					ClearCameraOverride();
					_viewZombieObject = null;
					RestoreHudAfterZombie();
					ForceClearSpectatorState();
				}
				catch
				{
				}
				try
				{
					if ((Object)(object)_sourceCharacter != (Object)null)
					{
						if (_sourceHidden)
						{
							RestoreSourceCharacter(_sourceStartPosition, _sourceStartRotation);
						}
						else if (_sourceWasActive && !((Component)_sourceCharacter).gameObject.activeSelf)
						{
							((Component)_sourceCharacter).gameObject.SetActive(true);
						}
						if (_localCharacterSwapped || (Object)(object)Character.localCharacter == (Object)(object)_zombieCharacter || (Object)(object)Character.localCharacter == (Object)null)
						{
							Character.localCharacter = _sourceCharacter;
						}
						ForcePlayerCharacterLookup(_sourceCharacter);
					}
				}
				catch (Exception ex)
				{
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogWarning((object)("[I'm Zombie] Failed to restore source after aborted zombie transform: " + ex.Message));
					}
				}
				try
				{
					EndNativeAriseSuppressionByViewId(_sourceViewId);
					UnregisterStashedSourceCharacter(_sourceCharacter);
					ClearLocalSourceProxyCharacter(_sourceCharacter);
					RegisterStatusUiSuppressedCharacter(_zombieCharacter, 1.5f);
					UnregisterControlledZombie(_zombie);
					BeginPeakStatsCleanupGraceWindow();
					RequestThirdPartyStatusUiCleanup(aggressive: true);
					CompleteSessionCleanup(restorePlayer: true);
					DestroyZombieObject(_zombieObject);
				}
				catch (Exception ex2)
				{
					ManualLogSource log2 = Log;
					if (log2 != null)
					{
						log2.LogWarning((object)("[I'm Zombie] Failed to clean up aborted zombie transform: " + ex2.Message));
					}
				}
				_state = SessionState.Exited;
			}

			private void PreconfigureZombieForLocalControl()
			{
				EnsureMushroomZombieNativeFields(_zombie);
				PrepareControlledZombieCharacterRefs(_zombieCharacter);
				_zombie.isNPCZombie = false;
				_zombie.targetForcedUntil = 0f;
				_zombie.initialWakeUpTime = 0f;
				_zombie.lifetime = float.PositiveInfinity;
				_zombie.currentTarget = null;
				SetMushroomZombieStateSilently(_zombie, (State)2);
				_zombieCharacter.isZombie = true;
				ConfigureControlledZombieCustomization(_zombieCharacter, _sourceCharacter);
				EnableZombiePhysics();
			}

			private void AlignZombieBodyToSource()
			{
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_0037: Unknown result type (might be due to invalid IL or missing references)
				//IL_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_005b: 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_00e5: 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)
				if ((Object)(object)_sourceCharacter == (Object)null || (Object)(object)_zombieCharacter == (Object)null || (Object)(object)_zombieObject == (Object)null)
				{
					return;
				}
				try
				{
					Quaternion spawnRotation = GetSpawnRotation(_sourceCharacter);
					SetCharacterPositionImmediate(_zombieCharacter, _sourceCharacter.Center, spawnRotation);
					CopyLookStateForZombieEnter(_sourceCharacter, _zombieCharacter, spawnRotation);
					_zombieCharacter.data.currentRagdollControll = 1f;
					_zombieCharacter.data.fallSeconds = 0f;
					_zombieCharacter.data.isGrounded = (Object)(object)_sourceCharacter.data != (Object)null && _sourceCharacter.data.isGrounded;
					_zombieCharacter.data.groundPos = (((Object)(object)_sourceCharacter.data != (Object)null) ? _sourceCharacter.data.groundPos : _sourceCharacter.Center);
					EnableZombiePhysics();
				}
				catch (Exception ex)
				{
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogWarning((object)("[I'm Zombie] Failed to align controlled zombie body: " + ex.Message));
					}
				}
			}

			private void EnableZombiePhysics()
			{
				if ((Object)(object)_zombieCharacter == (Object)null || _zombieCharacter.refs?.ragdoll?.partList == null)
				{
					return;
				}
				try
				{
					foreach (Bodypart part in _zombieCharacter.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 Zombie] Failed to enable controlled zombie physics: " + ex.Message));
					}
				}
			}

			private static void CopyBodypartPose(Bodypart sourcePart, Bodypart targetPart)
			{
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				//IL_003d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0055: Unknown result type (might be due to invalid IL or missing references)
				//IL_004d: 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_008f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0090: Unknown result type (might be due to invalid IL or missing references)
				//IL_0065: Unknown result type (might be due to invalid IL or missing references)
				//IL_006c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0073: Unknown result type (might be due to invalid IL or missing references)
				//IL_007e: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)sourcePart == (Object)null) && !((Object)(object)targetPart == (Object)null))
				{
					Rigidbody rig = sourcePart.Rig;
					Rigidbody rig2 = targetPart.Rig;
					Vector3 val = (((Object)(object)rig != (Object)null) ? rig.position : ((Component)sourcePart).transform.position);
					Quaternion val2 = (((Object)(object)rig != (Object)null) ? rig.rotation : ((Component)sourcePart).transform.rotation);
					if ((Object)(object)rig2 != (Object)null)
					{
						rig2.position = val;
						rig2.rotation = val2;
						rig2.linearVelocity = Vector3.zero;
						rig2.angularVelocity = Vector3.zero;
					}
					else
					{
						((Component)targetPart).transform.SetPositionAndRotation(val, val2);
					}
				}
			}

			public void Tick()
			{
				if (_state != SessionState.Active)
				{
					return;
				}
				if ((Object)(object)_sourceCharacter == (Object)null && !_sourceLossLogged)
				{
					_sourceLossLogged = true;
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogWarning((object)"[I'm Zombie] Source character was destroyed while transformed; keeping controlled zombie active and blocking source restore until a valid source exists.");
					}
				}
				if (!HasControlledZombieObjects)
				{
					ManualLogSource log2 = Log;
					if (log2 != null)
					{
						log2.LogWarning((object)("[I'm Zombie] Zombie session became inactive: " + GetInactiveReason()));
					}
					Instance?.ExitZombieForm(restorePlayer: true);
					return;
				}
				Character.localCharacter = _zombieCharacter;
				ForcePlayerCharacterLookup(_zombieCharacter);
				KeepZombieAwake();
				if ((Object)(object)_sourceCharacter != (Object)null)
				{
					KeepSourceOutOfPlay();
					UpdateRestoreAnchorCache();
				}
			}

			private string GetInactiveReason()
			{
				if ((Object)(object)_zombieObject == (Object)null)
				{
					return "zombie object missing";
				}
				if ((Object)(object)_zombie == (Object)null)
				{
					return "MushroomZombie missing";
				}
				if ((Object)(object)_zombieCharacter == (Object)null)
				{
					return "zombie character missing";
				}
				if ((Object)(object)_sourceCharacter == (Object)null)
				{
					return "source character missing";
				}
				return "unknown";
			}

			public void Exit(bool restorePlayer)
			{
				//IL_0092: Unknown result type (might be due to invalid IL or missing references)
				//IL_0097: Unknown result type (might be due to invalid IL or missing references)
				//IL_013e: 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_014b: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
				if (_state == SessionState.Exiting || _state == SessionState.Exited)
				{
					return;
				}
				if (restorePlayer && (Object)(object)_sourceCharacter == (Object)null && HasControlledZombieObjects)
				{
					_state = SessionState.Active;
					Character.localCharacter = _zombieCharacter;
					SetCameraOverride(_zombieCharacter);
					_viewZombieObject = _zombieObject;
					if ((Object)(object)_controller != (Object)null)
					{
						((Behaviour)_controller).enabled = true;
					}
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogWarning((object)"[I'm Zombie] Cannot restore the original player model because the source character no longer exists; keeping zombie form active.");
					}
					return;
				}
				_state = SessionState.Exiting;
				_sourceStatusRestoredThisExit = false;
				Vector3 position = ResolveRestorePosition();
				Quaternion rotation = (((Object)(object)_zombieCharacter != (Object)null) ? GetCharacterYaw(_zombieCharacter) : _sourceStartRotation);
				if ((Object)(object)_controller != (Object)null)
				{
					try
					{
						((Behaviour)_controller).enabled = false;
					}
					catch
					{
					}
				}
				SetZombieRenderersVisible(_zombieObject, visible: true);
				ClearCameraOverride();
				_viewZombieObject = null;
				RestoreHudAfterZombie();
				ForceClearSpectatorState();
				if (restorePlayer && (Object)(object)_sourceCharacter != (Object)null)
				{
					UnregisterStashedSourceCharacter(_sourceCharacter);
					Character.localCharacter = _sourceCharacter;
					ForcePlayerCharacterLookup(_sourceCharacter);
					CopyLookStateForRestore(_zombieCharacter, _sourceCharacter);
					RestoreSourceCharacter(position, rotation);
					ApplyLookStateFromRotation(_sourceCharacter, rotation);
					BeginCameraRestoreAssist(_sourceCharacter);
				}
				EndNativeAriseSuppressionByViewId(_sourceViewId);
				UnregisterStashedSourceCharacter(_sourceCharacter);
				ClearLocalSourceProxyCharacter(_sourceCharacter);
				RegisterStatusUiSuppressedCharacter(_zombieCharacter, 1.5f);
				UnregisterControlledZombie(_zombie);
				BeginPeakStatsCleanupGraceWindow();
				RequestThirdPartyStatusUiCleanup(aggressive: true);
				if (restorePlayer && (Object)(object)_sourceCharacter != (Object)null && !_sourceStatusRestoredThisExit)
				{
					RestoreOriginalPlayerStatusProcessing(_sourceCharacter);
					_sourceStatusRestoredThisExit = true;
				}
				CompleteSessionCleanup(restorePlayer);
				DestroyZombieObject(_zombieObject);
				_state = SessionState.Exited;
				LogVerbose("Exited zombie form.");
			}

			private void CompleteSessionCleanup(bool restorePlayer)
			{
				try
				{
					EndNativeAriseSuppressionByViewId(_sourceViewId);
					UnregisterControlledZombie(_zombie);
					UnregisterControlledZombieIds(_zombie, _zombieCharacter);
					RegisterStatusUiSuppressedCharacter(_zombieCharacter, 1.5f);
					RequestThirdPartyStatusUiCleanup(aggressive: true);
					_controlledClimbStartCooldownUntil.Remove(((Object)(object)_zombieCharacter != (Object)null) ? ((Object)_zombieCharacter).GetInstanceID() : 0);
					if ((Object)(object)_zombie != (Object)null)
					{
						_localMushroomGrowthInitializedZombieIds.Remove(((Object)_zombie).GetInstanceID());
					}
					if ((Object)(object)_cameraOverrideCharacter == (Object)(object)_zombieCharacter)
					{
						ClearCameraOverride();
					}
					if ((Object)(object)_cameraRestoreCharacter == (Object)(object)_zombieCharacter)
					{
						_cameraRestoreCharacter = null;
						_cameraRestoreUntil = 0f;
					}
					if ((Object)(object)_viewZombieObject == (Object)(object)_zombieObject)
					{
						_viewZombieObject = null;
					}
					_controlledZombieOriginalBehaviorDepth = 0;
					if ((Object)(object)_sourceCharacter != (Object)null)
					{
						UnregisterStashedSourceCharacter(_sourceCharacter);
						ClearLocalSourceProxyCharacter(_sourceCharacter);
						if (restorePlayer && !_sourceStatusRestoredThisExit)
						{
							RestoreOriginalPlayerStatusProcessing(_sourceCharacter);
							_sourceStatusRestoredThisExit = true;
						}
					}
					RestoreHudAfterZombie();
					ForceClearSpectatorState();
					Instance?.BeginLocalZombieSessionResidualCleanupWindow();
					LogZombieSessionCleanupResult(restorePlayer);
				}
				catch (Exception ex)
				{
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogWarning((object)("[I'm Zombie] Failed to complete zombie session cleanup: " + ex.Message));
					}
				}
			}

			private void LogZombieSessionCleanupResult(bool restorePlayer)
			{
				try
				{
					bool flag = IsStashedSourceCharacter(_sourceCharacter);
					bool flag2 = (Object)(object)_sourceCharacter != (Object)null && (Object)(object)_sourceCharacter == (Object)(object)Character.localCharacter;
					bool flag3 = (Object)(object)_sourceCharacter != (Object)null && _sourceCharacter.isZombie;
					bool flag4 = (Object)(object)_sourceCharacter?.data != (Object)null && _sourceCharacter.data.zombified;
					bool flag5 = (Object)(object)_zombie != (Object)null && _controlledZombieInstanceIds.Contains(((Object)_zombie).GetInstanceID());
					bool flag6 = (Object)(object)_zombieCharacter != (Object)null && _controlledZombieCharacterInstanceIds.Contains(((Object)_zombieCharacter).GetInstanceID());
					bool flag7 = (Object)(object)_zombieCharacter != (Object)null && _statusUiSuppressedCharacterUntilById.ContainsKey(((Object)_zombieCharacter).GetInstanceID());
					bool flag8 = (Object)(object)_cameraOverrideCharacter != (Object)(object)_zombieCharacter;
					bool flag9 = !_hudHiddenForZombie;
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogInfo((object)("[I'm Zombie] Zombie session cleanup complete: restorePlayer=" + restorePlayer + ", sourceLocal=" + flag2 + ", sourceZombie=" + flag3 + ", sourceZombified=" + flag4 + ", sourceStashed=" + flag + ", zombieTracked=" + flag5 + ", zombieCharacterTracked=" + flag6 + ", zombieStatusSuppressed=" + flag7 + ", cameraCleared=" + flag8 + ", hudRestored=" + flag9));
					}
				}
				catch
				{
				}
			}

			private Vector3 ResolveRestorePosition()
			{
				//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_0009: 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_0029: Unknown result type (might be due to invalid IL or missing references)
				Vector3 preferredRestoreAnchor = GetPreferredRestoreAnchor();
				return ResolveSafeRestorePosition(GetInsuredRestoreAnchor(preferredRestoreAnchor), extraLift: GetRestoreExtraLift(), zombieCharacter: _zombieCharacter, sourceCharacter: _sourceCharacter, fallbackPosition: _sourceStartPosition, logResult: true);
			}

			private Vector3 GetPreferredRestoreAnchor()
			{
				//IL_000f: 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_0024: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)_zombieCharacter == (Object)null)
				{
					return _sourceStartPosition;
				}
				if (TryGetStableRestoreAnchor(_zombieCharacter, out var anchor))
				{
					return anchor;
				}
				return GetRestoreAnchor(_zombieCharacter);
			}

			private Vector3 GetInsuredRestoreAnchor(Vector3 requestedPosition)
			{
				//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_0017: 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_0020: 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_003a: Unknown result type (might be due to invalid IL or missing references)
				if (!_hasLastStableRestorePosition || !IsFiniteVector(_lastStableRestorePosition))
				{
					return requestedPosition;
				}
				if (!IsFiniteVector(requestedPosition))
				{
					return _lastStableRestorePosition;
				}
				if (ShouldPreferCachedRestorePosition(requestedPosition))
				{
					LogVerbose("Using cached stable restore anchor instead of current zombie anchor.");
					return _lastStableRestorePosition;
				}
				return requestedPosition;
			}

			private bool ShouldPreferCachedRestorePosition(Vector3 requestedPosition)
			{
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				//IL_0023: Unknown result type (might be due to invalid IL or missing references)
				//IL_0035: 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)
				if (!_hasLastStableRestorePosition || !IsFiniteVector(_lastStableRestorePosition))
				{
					return false;
				}
				if (!IsFiniteVector(requestedPosition))
				{
					return true;
				}
				Vector2 val = default(Vector2);
				((Vector2)(ref val))..ctor(requestedPosition.x - _lastStableRestorePosition.x, requestedPosition.z - _lastStableRestorePosition.z);
				float num = Mathf.Abs(requestedPosition.y - _lastStableRestorePosition.y);
				if (!(((Vector2)(ref val)).sqrMagnitude > 64f))
				{
					return num > 4f;
				}
				return true;
			}

			private bool IsAggressiveRestoreState()
			{
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: Invalid comparison between Unknown and I4
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: Invalid comparison between Unknown and I4
				if ((Object)(object)_zombie == (Object)null)
				{
					return false;
				}
				if ((int)_zombie.currentState != 4)
				{
					return (int)_zombie.currentState == 3;
				}
				return true;
			}

			private float GetRestoreExtraLift()
			{
				float num = 0.55f;
				if (IsAggressiveRestoreState())
				{
					num += 0.45f;
				}
				return num;
			}

			private static Vector3 GetRestoreAnchor(Character character)
			{
				//IL_0009: 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_0019: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_0037: Unknown result type (might be due to invalid IL or missing references)
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0043: Unknown result type (might be due to invalid IL or missing references)
				//IL_0048: 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_0040: 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_0051: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)character == (Object)null)
				{
					return Vector3.zero;
				}
				if (TryGetStableRestoreAnchor(character, out var anchor))
				{
					return anchor;
				}
				Vector3 position = ((Component)character).transform.position;
				if (IsFiniteVector(position))
				{
					return position;
				}
				Vector3 center = character.Center;
				if (IsFiniteVector(center))
				{
					return center;
				}
				Vector3 head = character.Head;
				if (IsFiniteVector(head))
				{
					return head;
				}
				return ((Component)character).transform.position;
			}

			private void UpdateRestoreAnchorCache()
			{
				//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_0016: 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_002d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				//IL_003d: Unknown result type (might be due to invalid IL or missing references)
				//IL_003e: 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_0049: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)_zombieCharacter == (Object)null)
				{
					return;
				}
				Vector3 preferredRestoreAnchor = GetPreferredRestoreAnchor();
				if (IsFiniteVector(preferredRestoreAnchor))
				{
					Vector3 val = ResolveSafeRestorePosition(preferredRestoreAnchor, _zombieCharacter, _sourceCharacter, _sourceStartPosition, 0.55f, logResult: false);
					if (IsFiniteVector(val))
					{
						_lastStableRestorePosition = val;
						_hasLastStableRestorePosition = true;
					}
				}
			}

			private static Vector3 ResolveSafeRestorePosition(Vector3 requestedPosition, Character zombieCharacter, Character sourceCharacter, Vector3 fallbackPosition, float extraLift, bool logResult)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				//IL_0037: Unknown result type (might be due to invalid IL or missing references)
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				//IL_0042: 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_004d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0057: Unknown result type (might be due to invalid IL or missing references)
				//IL_005c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0061: Unknown result type (might be due to invalid IL or missing references)
				//IL_0067: Unknown result type (might be due to invalid IL or missing references)
				//IL_008a: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
				//IL_0073: Unknown result type (might be due to invalid IL or missing references)
				//IL_0079: Unknown result type (might be due to invalid IL or missing references)
				//IL_0031: Unknown result type (might be due to invalid IL or missing references)
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_0129: Unknown result type (might be due to invalid IL or missing references)
				//IL_012a: 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_012d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Unknown result type (might be due to invalid IL or missing references)
				//IL_0126: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
				//IL_0135: Unknown result type (might be due to invalid IL or missing references)
				//IL_0136: Unknown result type (might be due to invalid IL or missing references)
				//IL_0138: Unknown result type (might be due to invalid IL or missing references)
				//IL_0183: Unknown result type (might be due to invalid IL or missing references)
				//IL_0163: Unknown result type (might be due to invalid IL or missing references)
				//IL_0165: Unknown result type (might be due to invalid IL or missing references)
				float num = 1.35f;
				Vector3 val = (IsFiniteVector(requestedPosition) ? requestedPosition : fallbackPosition);
				if (!IsFiniteVector(val))
				{
					val = (((Object)(object)sourceCharacter != (Object)null) ? ((Component)sourceCharacter).transform.position : Vector3.zero);
				}
				Vector3 origin = val + Vector3.up * 3f;
				Vector3 origin2 = val + Vector3.up * 8f;
				Vector3 val3;
				if (TryFindRestoreGround(origin, 24f, val, zombieCharacter, sourceCharacter, out var groundHit) || TryFindRestoreGround(origin2, 72f, val, zombieCharacter, sourceCharacter, out groundHit))
				{
					float num2 = ((RaycastHit)(ref groundHit)).point.y + num + Mathf.Max(0f, extraLift);
					Vector3 val2 = val;
					if (val2.y < num2)
					{
						val2.y = num2;
					}
					if (logResult)
					{
						string[] obj = new string[7] { "Resolved safe restore position at ", null, null, null, null, null, null };
						val3 = val2;
						obj[1] = ((object)(Vector3)(ref val3)).ToString();
						obj[2] = " from requested zombie anchor ";
						val3 = val;
						obj[3] = ((object)(Vector3)(ref val3)).ToString();
						obj[4] = " using ground hit ";
						obj[5] = ((Object)((RaycastHit)(ref groundHit)).collider).name;
						obj[6] = ".";
						LogVerbose(string.Concat(obj));
					}
					return val2;
				}
				Vector3 val4 = val;
				if (IsUnsafeRestoreAnchorWithoutGround(val, fallbackPosition))
				{
					val4 = fallbackPosition;
					if (IsFiniteVector(val4))
					{
						val4.y += num + Mathf.Max(0f, extraLift);
					}
				}
				if (logResult)
				{
					val3 = val4;
					LogVerbose("No ground hit found for restore; using requested zombie anchor " + ((object)(Vector3)(ref val3)).ToString() + ".");
				}
				return val4;
			}

			private static bool IsUnsafeRestoreAnchorWithoutGround(Vector3 anchor, Vector3 fallbackPosition)
			{
				//IL_0000: 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_0012: 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_002a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				//IL_0037: Unknown result type (might be due to invalid IL or missing references)
				//IL_003d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0057: Unknown result type (might be due to invalid IL or missing references)
				//IL_005d: Unknown result type (might be due to invalid IL or missing references)
				if (!IsFiniteVector(anchor) || !IsFiniteVector(fallbackPosition))
				{
					return false;
				}
				if (anchor.y < fallbackPosition.y - 10f)
				{
					return true;
				}
				Vector2 val = default(Vector2);
				((Vector2)(ref val))..ctor(anchor.x - fallbackPosition.x, anchor.z - fallbackPosition.z);
				if (((Vector2)(ref val)).sqrMagnitude > 16f)
				{
					return Mathf.Abs(anchor.y - fallbackPosition.y) > 8f;
				}
				return false;
			}

			private static bool TryFindRestoreGround(Vector3 origin, float distance, Vector3 anchor, Character zombieCharacter, 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_00a8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
				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, zombieCharacter, sourceCharacter) && IsRestoreGroundCandidateNearAnchor(((RaycastHit)(ref val)).point, anchor))
					{
						groundHit = val;
						return true;
					}
				}
				return false;
			}

			private static bool IsRestoreIgnoredCollider(Collider collider, Character zombieCharacter, Character sourceCharacter)
			{
				if ((Object)(object)collider == (Object)null)
				{
					return true;
				}
				Transform transform = ((Component)collider).transform;
				if (!IsColliderOwnedBy(transform, zombieCharacter))
				{
					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 IsRestoreGroundCandidateNearAnchor(Vector3 hitPoint, Vector3 anchor)
			{
				//IL_0000: 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_0012: 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_002a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				//IL_0037: Unknown result type (might be due to invalid IL or missing references)
				//IL_003d: Unknown result type (might be due to invalid IL or missing references)
				if (!IsFiniteVector(hitPoint) || !IsFiniteVector(anchor))
				{
					return false;
				}
				if (hitPoint.y - anchor.y < -8f)
				{
					return false;
				}
				Vector2 val = default(Vector2);
				((Vector2)(ref val))..ctor(hitPoint.x - anchor.x, hitPoint.z - anchor.z);
				return ((Vector2)(ref val)).sqrMagnitude <= 36f;
			}

			private static bool TryGetStableRestoreAnchor(Character character, out Vector3 anchor)
			{
				//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_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_004d: 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_0034: Unknown result type (might be due to invalid IL or missing references)
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				//IL_003f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0075: Unknown result type (might be due to invalid IL or missing references)
				//IL_0076: Unknown result type (might be due to invalid IL or missing references)
				//IL_0056: 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_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_006d: Unknown result type (might be due to invalid IL or missing references)
				anchor = Vector3.zero;
				if ((Object)(object)character == (Object)null)
				{
					return false;
				}
				if (!TryGetCharacterBodyHorizontalAnchor(character, out var anchor2))
				{
					return false;
				}
				if (TryGetRestoreFootAnchorY(character, out var footY))
				{
					anchor = new Vector3(anchor2.x, footY, anchor2.z);
					return true;
				}
				Vector3 center = character.Center;
				if (IsFiniteVector(center))
				{
					anchor = new Vector3(anchor2.x, center.y, anchor2.z);
					return true;
				}
				anchor = anchor2;
				return true;
			}

			private static bool TryGetCharacterBodyHorizontalAnchor(Character character, out Vector3 anchor)
			{
				//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_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00de: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
				//IL_0108: Unknown result type (might be due to invalid IL or missing references)
				//IL_010d: Unknown result type (might be due to invalid IL or missing references)
				//IL_010f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0119: Unknown result type (might be due to invalid IL or missing references)
				//IL_011b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0090: Unknown result type (might be due to invalid IL or missing references)
				//IL_0082: Unknown result type (might be due to invalid IL or missing references)
				//IL_0095: Unknown result type (might be due to invalid IL or missing references)
				//IL_0097: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
				anchor = Vector3.zero;
				if ((Object)(object)character == (Object)null)
				{
					return false;
				}
				Vector3 val = Vector3.zero;
				int num = 0;
				try
				{
					if (character.refs?.ragdoll?.partList != null)
					{
						foreach (Bodypart part in character.refs.ragdoll.partList)
						{
							if (!((Object)(object)part == (Object)null))
							{
								Vector3 val2 = (((Object)(object)part.Rig != (Object)null) ? part.Rig.position : ((Component)part).transform.position);
								if (IsFiniteVector(val2))
								{
									val += val2;
									num++;
								}
							}
						}
					}
				}
				catch
				{
				}
				if (num > 0)
				{
					anchor = val / (float)num;
					return IsFiniteVector(anchor);
				}
				Vector3 center = character.Center;
				if (IsFiniteVector(center))
				{
					anchor = center;
					return true;
				}
				try
				{
					Vector3 position = ((Component)character).transform.position;
					if (IsFiniteVector(position))
					{
						anchor = position;
						return true;
					}
				}
				catch
				{
				}
				return false;
			}

			private static bool TryGetRestoreFootAnchorY(Character character, out float footY)
			{
				footY = float.PositiveInfinity;
				if (character?.refs?.ragdoll?.partList == null)
				{
					return false;
				}
				if (false | TryUpdateRestoreAnchorY(character, (BodypartType)13, ref footY) | TryUpdateRestoreAnchorY(character, (BodypartType)16, ref footY) | TryUpdateRestoreAnchorY(character, (BodypartType)27, ref footY) | TryUpdateRestoreAnchorY(character, (BodypartType)28, ref footY))
				{
					return IsFiniteFloat(footY);
				}
				return false;
			}

			private static bool TryUpdateRestoreAnchorY(Character character, BodypartType bodypartType, ref float anchorY)
			{
				//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_0055: 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_005a: 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_006b: Unknown result type (might be due to invalid IL or missing references)
				bool result = false;
				foreach (Bodypart part in character.refs.ragdoll.partList)
				{
					if (!((Object)(object)part == (Object)null) && part.partType == bodypartType)
					{
						Vector3 val = (((Object)(object)part.Rig != (Object)null) ? part.Rig.position : ((Component)part).transform.position);
						if (IsFiniteFloat(val.y))
						{
							anchorY = Mathf.Min(anchorY, val.y);
							result = true;
						}
					}
				}
				return result;
			}

			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 PrepareZombie()
			{
				EnsureMushroomZombieNativeFields(_zombie);
				PrepareControlledZombieCharacterRefs(_zombieCharacter);
				_zombie.isNPCZombie = false;
				_zombie.initialWakeUpTime = 0f;
				_zombie.distanceBeforeChase = 0f;
				_zombie.chaseTimeBeforeSprint = 0f;
				_zombie.zombieSprintDistance = 9999f;
				_zombie.lifetime = float.PositiveInfinity;
				_zombie.currentTarget = null;
				SetMushroomZombieStateSilently(_zombie, (State)2);
				_zombieCharacter.isZombie = true;
				_zombieCharacter.data.dead = false;
				_zombieCharacter.data.passedOut = false;
				_zombieCharacter.data.fullyPassedOut = false;
				_zombieCharacter.data.fallSeconds = 0f;
				_zombieCharacter.data.currentRagdollControll = 1f;
				float effectiveSprintStaminaRefill = GetEffectiveSprintStaminaRefill();
				_zombieCharacter.data.currentStamina = effectiveSprintStaminaRefill;
				_zombieCharacter.data.extraStamina = effectiveSprintStaminaRefill;
				ClearAssistJumpState(_zombieCharacter);
				ResetDisabledInventoryState(_zombieCharacter.refs?.items, _zombieCharacter);
				SetGameObjectActive(_zombie.biteColliderObject, active: false);
				ApplyMushroomAppearance(_zombie);
				ApplyControlledZombieNativePresentation(_zombie, _zombieCharacter, _sourceCharacter);
			}

			private void HideSourceCharacter()
			{
				//IL_009a: 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_00c9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)_sourceCharacter == (Object)null)
				{
					return;
				}
				try
				{
					RegisterStashedSourceCharacter(_sourceCharacter);
					_sourceHidden = true;
					_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);
					}
					Quaternion rotation = ((Component)_sourceCharacter).transform.rotation;
					HideSourceRenderers(((Component)_sourceCharacter).gameObject);
					ResetCharacterFallState(_sourceCharacter, _sourceStashPosition, grounded: true);
					SetCharacterPositionImmediate(_sourceCharacter, _sourceStashPosition, rotation);
					SuspendSourcePhysics();
					ZeroCharacterBodyVelocity(_sourceCharacter, wake: false);
					SyncPhysicsTransforms();
					SendSourceCharacterOutOfPlay(_sourceStashPosition, rotation);
				}
				catch (Exception ex)
				{
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogWarning((object)("[I'm Zombie] Failed to stash source character: " + ex.Message));
					}
				}
			}

			private void RestoreSourceCharacter(Vector3 position, Quaternion rotation)
			{
				//IL_005d: 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_0086: Unknown result type (might be due to invalid IL or missing references)
				//IL_0087: Unknown result type (might be due to invalid IL or missing references)
				//IL_0093: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00be: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
				//IL_0100: Unknown result type (might be due to invalid IL or missing references)
				//IL_0101: Unknown result type (might be due to invalid IL or missing references)
				//IL_013e: Unknown result type (might be due to invalid IL or missing references)
				//IL_014f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0160: Unknown result type (might be due to invalid IL or missing references)
				//IL_0161: Unknown result type (might be due to invalid IL or missing references)
				UnregisterStashedSourceCharacter(_sourceCharacter);
				Character.localCharacter = _sourceCharacter;
				ForcePlayerCharacterLookup(_sourceCharacter);
				try
				{
					if (_sourceWasActive && !((Component)_sourceCharacter).gameObject.activeSelf)
					{
						((Component)_sourceCharacter).gameObject.SetActive(true);
					}
					TryRunLocalRevive(_sourceCharacter);
					ResetCharacterFallState(_sourceCharacter, GetRestoreGroundPosition(position), grounded: true);
					ClearAssistJumpState(_sourceCharacter);
					RefreshCharacterAfflictionSceneState(_sourceCharacter, clearTransientCampfireAfflictions: true);
					SetCharacterPositionImmediate(_sourceCharacter, position, rotation);
					LiftCharacterBodyAbovePosition(_sourceCharacter, position);
					RestoreSourcePhysics();
					ZeroCharacterBodyVelocity(_sourceCharacter, wake: true);
					SyncPhysicsTransforms();
					Vector3 centerPosition = FinalizeRestoredSourcePosition(_sourceCharacter, position, rotation);
					ResetCharacterFallState(_sourceCharacter, GetRestoreGroundPosition(centerPosition), grounded: true);
					ZeroCharacterBodyVelocity(_sourceCharacter, wake: true);
					SyncPhysicsTransforms();
					Vector3 center = _sourceCharacter.Center;
					Quaternion rotation2 = ((Component)_sourceCharacter).transform.rotation;
					SendSourceCharacterRestore(center, rotation2);
					RestoreSourceRenderers(((Component)_sourceCharacter).gameObject);
					RestoreCharacterHumanPresentation(_sourceCharacter, resetCamera: false);
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogInfo((object)("[I'm Zombie] Restored source character position: requested=" + FormatVector(position) + ", final=" + FormatVector(center) + ", ground=" + FormatVector(GetRestoreGroundPosition(center)) + "."));
					}
				}
				catch (Exception ex)
				{
					ManualLogSource log2 = Log;
					if (log2 != null)
					{
						log2.LogWarning((object)("[I'm Zombie] Failed to restore source character: " + ex.Message));
					}
				}
				finally
				{
					RestoreOriginalPlayerStatusProcessing(_sourceCharacter);
					_sourceStatusRestoredThisExit = true;
				}
			}

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

			private Vector3 FinalizeRestoredSourcePosition(Character character, Vector3 requestedPosition, Quaternion rotation)
			{
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_0012: 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_001d: 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_0025: 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_002e: 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_005b: 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_0053: 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_0065: 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)
				if ((Object)(object)character == (Object)null)
				{
					return requestedPosition;
				}
				Vector3 center = character.Center;
				Vector3 val = ResolveSafeRestorePosition(IsFiniteVector(center) ? center : requestedPosition, _zombieCharacter, character, IsFiniteVector(requestedPosition) ? requestedPosition : _sourceStartPosition, 0.55f, logResult: false);
				if (IsFiniteVector(val))
				{
					SetCharacterPositionImmediate(character, val, rotation);
					LiftCharacterBodyAbovePosition(character, val);
					return val;
				}
				if (!IsFiniteVector(center))
				{
					return requestedPosition;
				}
				return center;
			}

			private static Vector3 GetRestoreGroundPosition(Vector3 centerPosition)
			{
				//IL_0000: 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_001c: 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)
				if (!IsFiniteVector(centerPosition))
				{
					return centerPosition;
				}
				Vector3 result = centerPosition;
				result.y -= 1.35f;
				return result;
			}

			private static string FormatVector(Vector3 value)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				if (!IsFiniteVector(value))
				{
					return "(invalid)";
				}
				return "(" + value.x.ToString("0.00", CultureInfo.InvariantCulture) + ", " + value.y.ToString("0.00", CultureInfo.InvariantCulture) + ", " + value.z.ToString("0.00", CultureInfo.InvariantCulture) + ")";
			}

			private void SendSourceCharacterRestore(Vector3 restorePosition, Quaternion rotation)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				SendSourceCharacterStateRpc(restorePosition, "[I'm Zombie] 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 Zombie] 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 Zombie] Failed to restore source physics: " + ex.Message));
					}
				}
				finally
				{
					_sourceBodypartPhysicsStates.Clear();
					_sourcePhysicsSuspended = false;
				}
			}

			private static void TryRunLocalRevive(Character character)
			{
				if ((Object)(object)character == (Object)null)
				{
					return;
				}
				try
				{
					InvokeCharacterUnFall(character);
					CharacterReviveRpcMethod?.Invoke(character, new object[1] { false });
				}
				catch
				{
				}
			}

			private static void InvokeCharacterUnFall(Character character)
			{
				if (!((Object)(object)character == (Object)null) && !(CharacterUnFallRpcMethod == null))
				{
					ParameterInfo[] parameters = CharacterUnFallRpcMethod.GetParameters();
					object[] array = new object[parameters.Length];
					for (int i = 0; i < parameters.Length; i++)
					{
						Type parameterType = parameters[i].ParameterType;
						array[i] = (parameterType.IsValueType ? Activator.CreateInstance(parameterType) : null);
					}
					CharacterUnFallRpcMethod.Invoke(character, array);
				}
			}

			private static void ResetCharacterFallState(Character character, Vector3 groundPosition, bool grounded)
			{
				//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
				//IL_0119: Unknown result type (might be due to invalid IL or missing references)
				//IL_011e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0129: Unknown result type (might be due to invalid IL or missing references)
				//IL_012e: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)character == (Object)null) && !((Object)(object)character.data == (Object)null))
				{
					character.data.dead = false;
					character.data.zombified = false;
					character.isZombie = false;
					character.data.passedOut = false;
					character.data.fullyPassedOut = false;
					character.data.fallSeconds = 0f;
					character.data.deathTimer = 0f;
					character.data.currentRagdollControll = 1f;
					character.data.isGrounded = grounded;
					character.data.isJumping = false;
					character.data.sinceGrounded = 0f;
					character.data.groundedFor = (grounded ? Mathf.Max(character.data.groundedFor, Time.fixedDeltaTime) : 0f);
					character.data.groundPos = groundPosition;
					character.data.lastGroundedHeight = character.Center.y;
					character.data.sinceJump = 0f;
					character.data.sinceFallSlide = 0f;
					character.data.avarageVelocity = Vector3.zero;
					character.data.avarageLastFrameVelocity = Vector3.zero;
				}
			}

			private static void ZeroCharacterBodyVelocity(Character character, bool wake)
			{
				//IL_006d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0078: Unknown result type (might be due to invalid IL or missing references)
				if (character?.refs?.ragdoll?.partList == null)
				{
					return;
				}
				try
				{
					foreach (Bodypart part in character.refs.ragdoll.partList)
					{
						Rigidbody val = (((Object)(object)part != (Object)null) ? part.Rig : null);
						if (!((Object)(object)val == (Object)null))
						{
							if (!val.isKinematic)
							{
								val.linearVelocity = Vector3.zero;
								val.angularVelocity = Vector3.zero;
							}
							if (wake)
							{
								val.WakeUp();
							}
						}
					}
				}
				catch
				{
				}
			}

			private static void SyncPhysicsTransforms()
			{
				try
				{
					Physics.SyncTransforms();
				}
				catch
				{
				}
			}

			private static void SetCharacterPositionImmediate(Character character, Vector3 position, Quaternion rotation)
			{
				//IL_0199: Unknown result type (might be due to invalid IL or missing references)
				//IL_019a: Unknown result type (might be due to invalid IL or missing references)
				//IL_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_002b: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				//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_012f: 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_013d: Unknown result type (might be due to invalid IL or missing references)
				//IL_013e: Unknown result type (might be due to invalid IL or missing references)
				//IL_013f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0141: Unknown result type (might be due to invalid IL or missing references)
				//IL_0142: Unknown result type (might be due to invalid IL or missing references)
				//IL_0147: Unknown result type (might be due to invalid IL or missing references)
				//IL_014c: Unknown result type (might be due to invalid IL or missing references)
				//IL_015d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0165: Unknown result type (might be due to invalid IL or missing references)
				//IL_016a: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
				//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_00c1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
				//IL_00df: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
				//IL_010b: Unknown result type (might be due to invalid IL or missing references)
				//IL_011c: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)character == (Object)null)
				{
					return;
				}
				try
				{
					Transform transform = ((Component)character).transform;
					Vector3 center = character.Center;
					Quaternion rotation2 = transform.rotation;
					Quaternion val = rotation * Quaternion.Inverse(rotation2);
					Vector3 val2 = position - center;
					transform.SetPositionAndRotation(transform.position + val2, 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)
						{
							Vector3 position2 = part.Rig.position;
							part.Rig.position = position + val * (position2 - center);
							part.Rig.rotation = val * part.Rig.rotation;
							if (!part.Rig.isKinematic)
							{
								part.Rig.linearVelocity = Vector3.zero;
								part.Rig.angularVelocity = Vector3.zero;
							}
						}
						else
						{
							Vector3 position3 = ((Component)part).transform.position;
							((Component)part).transform.position = position + val * (position3 - center);
							((Component)part).transform.rotation = val * ((Component)part).transform.rotation;
						}
					}
				}
				catch
				{
					((Component)character).transform.SetPositionAndRotation(position, rotation);
				}
			}

			private static void LiftCharacterBodyAbovePosition(Character character, Vector3 minimumBodyPosition)
			{
				//IL_0009: 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_0044: 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_0069: Unknown result type (might be due to invalid IL or missing references)
				//IL_006e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0074: Unknown result type (might be due to invalid IL or missing references)
				//IL_0079: Unknown result type (might be due to invalid IL or missing references)
				//IL_007e: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)character == (Object)null || !IsFiniteVector(minimumBodyPosition) || !TryGetCharacterLowestY(character, out var lowestY))
				{
					return;
				}
				float num = minimumBodyPosition.y - 1.35f + 0.18f - lowestY;
				if (!(num <= 0f) && !(num > 5f))
				{
					TranslateCharacterImmediate(character, Vector3.up * num);
					if ((Object)(object)character.data != (Object)null)
					{
						CharacterData data = character.data;
						data.groundPos += Vector3.up * num;
					}
					LogVerbose("Lifted restored source character by " + num.ToString("0.00", CultureInfo.InvariantCulture) + " to keep body above restore position.");
				}
			}

			private static bool TryGetCharacterLowestY(Character character, out float lowestY)
			{
				//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
				//IL_0082: Unknown result type (might be due to invalid IL or missing references)
				//IL_0075: Unknown result type (might be due to invalid IL or missing references)
				//IL_0087: Unknown result type (might be due to invalid IL or missing references)
				//IL_0088: 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)
				lowestY = float.PositiveInfinity;
				bool flag = false;
				if ((Object)(object)character == (Object)null)
				{
					return false;
				}
				try
				{
					if (character.refs?.ragdoll?.partList != null)
					{
						foreach (Bodypart part in character.refs.ragdoll.partList)
						{
							if (!((Object)(object)part == (Object)null))
							{
								Vector3 val = (((Object)(object)part.Rig != (Object)null) ? part.Rig.position : ((Component)part).transform.position);
								if (IsFiniteFloat(val.y))
								{
									lowestY = Mathf.Min(lowestY, val.y);
									flag = true;
								}
							}
						}
					}
					Collider[] componentsInChildren = ((Component)character).GetComponentsInChildren<Collider>(true);
					foreach (Collider val2 in componentsInChildren)
					{
						if (!((Object)(object)val2 == (Object)null) && !val2.isTrigger)
						{
							Bounds bounds = val2.bounds;
							float y = ((Bounds)(ref bounds)).min.y;
							if (IsFiniteFloat(y))
							{
								lowestY = Mathf.Min(lowestY, y);
								flag = true;
							}
						}
					}
				}
				catch
				{
				}
				if (flag)
				{
					return IsFiniteFloat(lowestY);
				}
				return false;
			}

			private static void TranslateCharacterImmediate(Character character, Vector3 delta)
			{
				//IL_0115: Unknown result type (might be due to invalid IL or missing references)
				//IL_011a: Unknown result type (might be due to invalid IL or missing references)
				//IL_011b: 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_0028: Unknown result type (might be due to invalid IL or missing references)
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Unknown result type (might be due to invalid IL or missing references)
				//IL_00df: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
				//IL_0099: Unknown result type (might be due to invalid IL or missing references)
				//IL_009e: 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_00bc: 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)
				if ((Object)(object)character == (Object)null || !IsFiniteVector(delta) || ((Vector3)(ref delta)).sqrMagnitude <= 0f)
				{
					return;
				}
				try
				{
					Transform transform = ((Component)character).transform;
					transform.position += delta;
					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)
						{
							Rigidbody rig = part.Rig;
							rig.position += delta;
							if (!part.Rig.isKinematic)
							{
								part.Rig.linearVelocity = Vector3.zero;
								part.Rig.angularVelocity = Vector3.zero;
							}
						}
						else
						{
							Transform transform2 = ((Component)part).transform;
							transform2.position += delta;
						}
					}
				}
				catch
				{
					Transform transform3 = ((Component)character).transform;
					transform3.position += delta;
				}
			}

			private void KeepZombieAwake()
			{
				RefreshCharacterAfflictionSceneState(_zombieCharacter);
				_zombie.lifetime = float.PositiveInfinity;
				_zombieCharacter.data.dead = false;
				_zombieCharacter.data.passedOut = false;
				_zombieCharacter.data.fullyPassedOut = false;
				_zombieCharacter.data.fallSeconds = 0f;
				_zombieCharacter.data.currentRagdollControll = 1f;
				float effectiveSprintStaminaRefill = GetEffectiveSprintStaminaRefill();
				_zombieCharacter.data.currentStamina = effectiveSprintStaminaRefill;
				_zombieCharacter.data.extraStamina = effectiveSprintStaminaRefill;
				ClearAssistJumpState(_zombieCharacter);
				ResetDisabledInventoryState(_zombieCharacter.refs?.items, _zombieCharacter);
			}

			private void KeepSourceOutOfPlay()
			{
				//IL_0104: Unknown result type (might be due to invalid IL or missing references)
				//IL_0109: Unknown result type (might be due to invalid IL or missing references)
				//IL_0115: Unknown result type (might be due to invalid IL or missing references)
				//IL_0125: Unknown result type (might be due to invalid IL or missing references)
				//IL_011e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0126: Unknown result type (might be due to invalid IL or missing references)
				//IL_015b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0160: Unknown result type (might be due to invalid IL or missing references)
				//IL_0170: Unknown result type (might be due to invalid IL or missing references)
				//IL_0175: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)_sourceCharacter == (Object)null))
				{
					if ((Object)(object)_sourceCharacter == (Object)(object)Character.localCharacter && (Object)(object)_zombieCharacter != (Object)null)
					{
						Character.localCharacter = _zombieCharacter;
					}
					_sourceCharacter.data.dead = false;
					_sourceCharacter.data.zombified = false;
					_sourceCharacter.data.passedOut = false;
					_sourceCharacter.data.fullyPassedOut = false;
					_sourceCharacter.data.fallSeconds = 0f;
					_sourceCharacter.data.deathTimer = 0f;
					_sourceCharacter.data.isGrounded = true;
					_sourceCharacter.data.sinceGrounded = 0f;
					_sourceCharacter.data.groundedFor = Mathf.Max(_sourceCharacter.data.groundedFor, Time.fixedDeltaTime);
					PinSourceAtStashPosition();
					Vector3 center = _sourceCharacter.Center;
					_sourceCharacter.data.groundPos = (IsFiniteVector(center) ? center : _sourceStartPosition);
					_sourceCharacter.data.lastGroundedHeight = _sourceCharacter.data.groundPos.y;
					_sourceCharacter.data.avarageVelocity = Vector3.zero;
					_sourceCharacter.data.avarageLastFrameVelocity = Vector3.zero;
					ClearAssistJumpState(_sourceCharacter);
					RefreshCharacterAfflictionSceneState(_sourceCharacter);
					HideSourceRenderers(((Component)_sourceCharacter).gameObject);
					SuspendSourcePhysics();
					ZeroCharacterBodyVelocity(_sourceCharacter, wake: false);
				}
			}

			private void PinSourceAtStashPosition()
			{
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_0028: 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_005a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)_sourceCharacter == (Object)null) && IsFiniteVector(_sourceStashPosition))
				{
					Vector3 center = _sourceCharacter.Center;
					if (!IsFiniteVector(center) || Vector3.Distance(center, _sourceStashPosition) > 0.5f)
					{
						SetCharacterPositionImmediate(_sourceCharacter, _sourceStashPosition, ((Component)_sourceCharacter).transform.rotation);
					}
				}
			}

			private void SyncZombieState(State state, bool sprinting)
			{
				//IL_0058: Unknown result type (might be due to invalid IL or missing references)
				//IL_005e: Expected I4, but got Unknown
				if (_state != SessionState.Active)
				{
					return;
				}
				PhotonView val = ResolveCharacterPhotonView(_zombieCharacter);
				if ((Object)(object)val == (Object)null && (Object)(object)_zombieObject != (Object)null)
				{
					try
					{
						val = _zombieObject.GetComponent<PhotonView>();
					}
					catch
					{
						val = null;
					}
				}
				if (HasNetworkView(val))
				{
					val.RPC("RPC_SyncState", (RpcTarget)1, new object[4]
					{
						(int)state,
						sprinting,
						0f,
						false
					});
				}
			}
		}

		[CompilerGenerated]
		private sealed class <EnterZombieFormRoutine>d__366 : 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 <zombieObject>5__4;

			private ActiveZombieSession <pendingSession>5__5;

			private IEnumerator <enterRoutine>5__6;

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

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

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

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

			private bool MoveNext()
			{
				//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_008b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0090: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
				int num = <>1__state;
				Plugin plugin = <>4__this;
				MushroomZombie component;
				Character component2;
				switch (num)
				{
				default:
					return false;
				case 0:
				{
					<>1__state = -1;
					plugin._switching = true;
					plugin.SuppressExpensiveMaintenance(0.65f);
					if (plugin._session != null)
					{
						plugin.ExitZombieForm(restorePlayer: true);
					}
					<sourceCharacter>5__2 = Character.localCharacter;
					if (!CanTransform(<sourceCharacter>5__2))
					{
						plugin._enteringZombieForm = false;
						plugin._switching = false;
						return false;
					}
					plugin.SetConflictingZombieRebornPluginsSuppressed(suppress: true);
					Vector3 center = <sourceCharacter>5__2.Center;
					Quaternion s