Decompiled source of Luigi Enemy v1.0.3

LuigiEnemy.Standalone.Runtime.dll

Decompiled 3 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Photon.Pun;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Events;
using UnityEngine.SceneManagement;

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

public sealed class LuigiWalkAnimation : MonoBehaviour
{
	public Animator animator;

	public Transform movementRoot;

	public float referenceSpeed = 2.2f;

	private Vector3 previousPosition;

	private float smoothSpeed;

	private Enemy enemy;

	private LuigiFallRagdoll fallRagdoll;

	private LuigiChaseEnemy brain;

	private EnemyHealth health;

	private Transform head;

	private Transform neck;

	private Transform spine;

	private Transform leftArm;

	private Transform rightArm;

	private Vector3 restPosition;

	private Vector3 restScale;

	private Quaternion restRotation;

	private float spawnedAt;

	private float hurtUntil;

	private float diedAt = -1f;

	private float attackUntil;

	private float jumpUntil;

	private float yaw;

	private float pitch;

	private int attackSequence;

	private string animationState;

	public float attackClipLength = 1f;

	public float jumpClipLength = 1f;

	public float maxHeadYaw = 70f;

	public float maxHeadPitch = 60f;

	public AudioSource voice;

	public AudioClip spawnVoice;

	public AudioClip spotVoice;

	public AudioClip attackVoice;

	public AudioClip hurtVoice;

	public AudioClip deathVoice;

	public AudioClip patrolVoice;

	private bool wasSeeingPlayer;

	private float nextVoice;

	private float nextSpotVoice;

	private void Awake()
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_010c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0116: Expected O, but got Unknown
		//IL_0128: Unknown result type (might be due to invalid IL or missing references)
		//IL_0132: Expected O, but got Unknown
		restPosition = ((Component)this).transform.localPosition;
		fallRagdoll = ((Component)this).GetComponent<LuigiFallRagdoll>();
		restRotation = ((Component)this).transform.localRotation;
		restScale = ((Component)this).transform.localScale;
		EnemyParent componentInParent = ((Component)this).GetComponentInParent<EnemyParent>();
		if (Object.op_Implicit((Object)(object)componentInParent))
		{
			enemy = ((Component)componentInParent).GetComponentInChildren<Enemy>(true);
			brain = ((Component)componentInParent).GetComponentInChildren<LuigiChaseEnemy>(true);
			health = ((Component)componentInParent).GetComponentInChildren<EnemyHealth>(true);
		}
		if (Object.op_Implicit((Object)(object)animator) && animator.isHuman)
		{
			head = animator.GetBoneTransform((HumanBodyBones)10);
			neck = animator.GetBoneTransform((HumanBodyBones)9);
			spine = animator.GetBoneTransform((HumanBodyBones)7);
			leftArm = animator.GetBoneTransform((HumanBodyBones)13);
			rightArm = animator.GetBoneTransform((HumanBodyBones)14);
		}
		if (Object.op_Implicit((Object)(object)health))
		{
			health.onHurt.AddListener(new UnityAction(Hurt));
			health.onDeathStart.AddListener(new UnityAction(Die));
		}
	}

	private void OnEnable()
	{
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		if (!Object.op_Implicit((Object)(object)movementRoot))
		{
			movementRoot = ((Component)this).transform.parent;
		}
		previousPosition = movementRoot.position;
		smoothSpeed = 0f;
		spawnedAt = Time.time;
		diedAt = -1f;
		hurtUntil = (attackUntil = (jumpUntil = 0f));
		attackSequence = 0;
		yaw = (pitch = 0f);
		animationState = null;
		wasSeeingPlayer = false;
		nextVoice = Time.time + 18f;
		nextSpotVoice = 0f;
		Speak(spawnVoice, interrupt: true);
		if (Object.op_Implicit((Object)(object)animator))
		{
			animator.Rebind();
		}
	}

	private void Update()
	{
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_00d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dd: Invalid comparison between Unknown and I4
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ec: Invalid comparison between Unknown and I4
		if (!Object.op_Implicit((Object)(object)animator) || !Object.op_Implicit((Object)(object)movementRoot) || Time.deltaTime <= 0f)
		{
			return;
		}
		if (Object.op_Implicit((Object)(object)fallRagdoll) && fallRagdoll.Active)
		{
			previousPosition = movementRoot.position;
			animationState = null;
			return;
		}
		Vector3 val = movementRoot.position - previousPosition;
		previousPosition = movementRoot.position;
		float num = val.y / Time.deltaTime;
		val.y = 0f;
		float num2 = ((Vector3)(ref val)).magnitude / Time.deltaTime;
		if (((Vector3)(ref val)).magnitude > 1f || (Object.op_Implicit((Object)(object)enemy) && (enemy.IsStunned() || (int)enemy.CurrentState == 1 || (int)enemy.CurrentState == 11)))
		{
			num2 = 0f;
		}
		smoothSpeed = Mathf.Lerp(smoothSpeed, num2, 1f - Mathf.Exp(-12f * Time.deltaTime));
		bool flag = Object.op_Implicit((Object)(object)enemy) && enemy.IsStunned();
		if (Object.op_Implicit((Object)(object)brain) && brain.HasVisibleTarget && !wasSeeingPlayer && Time.time >= nextSpotVoice)
		{
			Speak(spotVoice);
			nextSpotVoice = Time.time + 8f;
		}
		wasSeeingPlayer = Object.op_Implicit((Object)(object)brain) && brain.HasVisibleTarget;
		if (Object.op_Implicit((Object)(object)brain) && !brain.IsDead && !flag && brain.currentState == LuigiChaseEnemy.BrainState.Roam && Time.time >= nextVoice)
		{
			Speak(patrolVoice);
			nextVoice = Time.time + 25f;
		}
		if (Object.op_Implicit((Object)(object)brain) && brain.IsDead && diedAt < 0f)
		{
			Die();
		}
		if (flag || diedAt >= 0f)
		{
			attackUntil = (jumpUntil = 0f);
		}
		if (Object.op_Implicit((Object)(object)brain) && brain.AttackSequence != attackSequence)
		{
			attackSequence = brain.AttackSequence;
			if (!flag && diedAt < 0f && brain.currentState == LuigiChaseEnemy.BrainState.Windup)
			{
				float num3 = attackClipLength * 0.45f / Mathf.Max(0.1f, brain.attackWindup);
				animator.SetFloat("AttackRate", num3);
				attackUntil = Time.time + attackClipLength / num3;
				Play("Attack", 0.06f, restart: true);
				Speak(attackVoice);
			}
		}
		if (!flag && diedAt < 0f && Time.time - spawnedAt > 2f && num > 2.5f && jumpUntil <= Time.time)
		{
			jumpUntil = Time.time + Mathf.Min(jumpClipLength, 0.8f);
		}
		string text = ((diedAt >= 0f || flag || Time.time - spawnedAt < 1.2f) ? "Idle" : ((attackUntil > Time.time) ? "Attack" : ((jumpUntil > Time.time) ? "Jump" : ((smoothSpeed > 2.4f) ? "Run" : ((smoothSpeed > 0.12f) ? "Walk" : "Idle")))));
		animator.SetFloat("MoveRate", Mathf.Clamp(smoothSpeed / ((text == "Run") ? 3.8f : referenceSpeed), 0.5f, 2f));
		Play(text, 0.14f, restart: false);
	}

	private void Play(string state, float fade, bool restart)
	{
		if (restart || !(animationState == state))
		{
			animationState = state;
			animator.CrossFadeInFixedTime(state, fade, 0, 0f);
		}
	}

	private void LateUpdate()
	{
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d3: 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_011a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0132: Unknown result type (might be due to invalid IL or missing references)
		//IL_0137: Unknown result type (might be due to invalid IL or missing references)
		//IL_022d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0247: Unknown result type (might be due to invalid IL or missing references)
		//IL_024c: Unknown result type (might be due to invalid IL or missing references)
		//IL_015b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0180: Unknown result type (might be due to invalid IL or missing references)
		//IL_0185: Unknown result type (might be due to invalid IL or missing references)
		//IL_026a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0281: Unknown result type (might be due to invalid IL or missing references)
		//IL_0286: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01da: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0402: Unknown result type (might be due to invalid IL or missing references)
		//IL_0407: Unknown result type (might be due to invalid IL or missing references)
		//IL_041e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0423: Unknown result type (might be due to invalid IL or missing references)
		//IL_0428: Unknown result type (might be due to invalid IL or missing references)
		//IL_0433: Unknown result type (might be due to invalid IL or missing references)
		//IL_0438: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_02eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_031f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0326: Unknown result type (might be due to invalid IL or missing references)
		//IL_032d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0334: Unknown result type (might be due to invalid IL or missing references)
		//IL_0339: Unknown result type (might be due to invalid IL or missing references)
		//IL_0472: Unknown result type (might be due to invalid IL or missing references)
		//IL_0477: Unknown result type (might be due to invalid IL or missing references)
		//IL_048b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0490: Unknown result type (might be due to invalid IL or missing references)
		//IL_0495: Unknown result type (might be due to invalid IL or missing references)
		//IL_04a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_04a5: Unknown result type (might be due to invalid IL or missing references)
		if (!Object.op_Implicit((Object)(object)animator) || !Object.op_Implicit((Object)(object)head) || (Object.op_Implicit((Object)(object)fallRagdoll) && fallRagdoll.Active))
		{
			return;
		}
		bool flag = Object.op_Implicit((Object)(object)enemy) && enemy.IsStunned();
		bool flag2 = diedAt >= 0f;
		float num = Mathf.SmoothStep(0f, 1f, (Time.time - spawnedAt) / 1.2f);
		((Component)this).transform.localPosition = restPosition - Vector3.up * ((1f - num) * (Object.op_Implicit((Object)(object)brain) ? brain.bodyHeight : 2.6f));
		((Component)this).transform.localScale = restScale;
		((Component)this).transform.localRotation = restRotation;
		float num2 = Mathf.Clamp01((hurtUntil - Time.time) / 0.35f);
		if (Object.op_Implicit((Object)(object)spine))
		{
			Transform obj = spine;
			obj.localRotation *= Quaternion.Euler(-24f * num2, 0f, 8f * num2);
		}
		if (flag)
		{
			if (Object.op_Implicit((Object)(object)spine))
			{
				Transform obj2 = spine;
				obj2.localRotation *= Quaternion.Euler(28f, 0f, Mathf.Sin(Time.time * 4f) * 7f);
			}
			if (Object.op_Implicit((Object)(object)leftArm))
			{
				Transform obj3 = leftArm;
				obj3.localRotation *= Quaternion.Euler(0f, 0f, 18f);
			}
			if (Object.op_Implicit((Object)(object)rightArm))
			{
				Transform obj4 = rightArm;
				obj4.localRotation *= Quaternion.Euler(0f, 0f, -18f);
			}
		}
		if (flag2)
		{
			float num3 = Mathf.SmoothStep(0f, 1f, (Time.time - diedAt) / 1.3f);
			((Component)this).transform.localRotation = restRotation * Quaternion.Euler(82f * num3, 0f, 8f * num3);
			if (Object.op_Implicit((Object)(object)spine))
			{
				Transform obj5 = spine;
				obj5.localRotation *= Quaternion.Euler(18f * num3, 0f, 0f);
			}
		}
		float num4 = 0f;
		float num5 = 0f;
		if (!flag2 && !flag && Object.op_Implicit((Object)(object)brain) && brain.HasVisibleTarget)
		{
			Vector3 val = ((Component)this).transform.InverseTransformDirection(brain.VisibleTargetPoint - head.position);
			num4 = Mathf.Clamp(Mathf.Atan2(val.x, val.z) * 57.29578f, 0f - maxHeadYaw, maxHeadYaw);
			float y = val.y;
			Vector2 val2 = new Vector2(val.x, val.z);
			num5 = Mathf.Clamp((0f - Mathf.Atan2(y, ((Vector2)(ref val2)).magnitude)) * 57.29578f, -30f, maxHeadPitch);
		}
		else if (!flag2 && !flag && Object.op_Implicit((Object)(object)brain) && brain.currentState == LuigiChaseEnemy.BrainState.Search)
		{
			num4 = Mathf.Sin(Time.time * 1.6f) * 38f;
		}
		float num6 = 1f - Mathf.Exp(-8f * Time.deltaTime);
		yaw = Mathf.LerpAngle(yaw, num4, num6);
		pitch = Mathf.LerpAngle(pitch, num5, num6);
		if (Object.op_Implicit((Object)(object)neck))
		{
			neck.rotation = Quaternion.AngleAxis(yaw * 0.25f, ((Component)this).transform.up) * Quaternion.AngleAxis(pitch * 0.25f, ((Component)this).transform.right) * neck.rotation;
		}
		float num7 = (Object.op_Implicit((Object)(object)neck) ? 0.75f : 1f);
		head.rotation = Quaternion.AngleAxis(yaw * num7, ((Component)this).transform.up) * Quaternion.AngleAxis(pitch * num7, ((Component)this).transform.right) * head.rotation;
	}

	private void Speak(AudioClip clip, bool interrupt = false)
	{
		if (Object.op_Implicit((Object)(object)voice) && Object.op_Implicit((Object)(object)clip) && (interrupt || !voice.isPlaying))
		{
			voice.clip = clip;
			voice.Play();
		}
	}

	private void Hurt()
	{
		if (diedAt < 0f)
		{
			hurtUntil = Time.time + 0.35f;
			Speak(hurtVoice);
		}
	}

	private void Die()
	{
		if (diedAt < 0f)
		{
			diedAt = Time.time;
			Speak(deathVoice, interrupt: true);
		}
	}

	private void OnDisable()
	{
		//IL_0007: 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_0029: Unknown result type (might be due to invalid IL or missing references)
		((Component)this).transform.localPosition = restPosition;
		((Component)this).transform.localRotation = restRotation;
		((Component)this).transform.localScale = restScale;
	}

	private void OnDestroy()
	{
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Expected O, but got Unknown
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Expected O, but got Unknown
		if (Object.op_Implicit((Object)(object)health))
		{
			health.onHurt.RemoveListener(new UnityAction(Hurt));
			health.onDeathStart.RemoveListener(new UnityAction(Die));
		}
	}
}
[BepInPlugin("brckv2.luigienemy.standalone", "Luigi Enemy", "1.2.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public sealed class LuigiEnemyPlugin : BaseUnityPlugin
{
	internal static ConfigEntry<int> SpawnRate;

	private Harmony harmony;

	private void Awake()
	{
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Expected O, but got Unknown
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Expected O, but got Unknown
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Expected O, but got Unknown
		SpawnRate = ((BaseUnityPlugin)this).Config.Bind<int>("Spawning", "SpawnRate", 1, new ConfigDescription("Luigi spawn-weight multiplier. 1 = default, 2 = 2x, 3 = 3x, 4 = 4x, 5 = 5x. Host's setting applies when the next level generates enemies; this changes selection weight, not a guaranteed number of spawns.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 5), Array.Empty<object>()));
		harmony = new Harmony("brckv2.luigienemy.standalone.spawnrate");
		harmony.Patch((MethodBase)AccessTools.Method(typeof(EnemyDirector), "PickEnemies", (Type[])null, (Type[])null), new HarmonyMethod(typeof(LuigiSpawnRate), "BeforePick", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		((BaseUnityPlugin)this).Logger.LogInfo((object)("Luigi enemy loaded. Spawn-rate config: " + ((BaseUnityPlugin)this).Config.ConfigFilePath));
	}

	private void OnDestroy()
	{
		Harmony obj = harmony;
		if (obj != null)
		{
			obj.UnpatchSelf();
		}
		LuigiSpawnRate.Restore();
	}
}
internal static class LuigiSpawnRate
{
	private sealed class Entry
	{
		public RarityPreset Original;

		public RarityPreset Adjusted;

		public float BaseChance;
	}

	private static readonly Dictionary<EnemySetup, Entry> entries = new Dictionary<EnemySetup, Entry>();

	public static void BeforePick(List<EnemySetup> __0)
	{
		if (__0 == null || LuigiEnemyPlugin.SpawnRate == null)
		{
			return;
		}
		int num = Mathf.Clamp(LuigiEnemyPlugin.SpawnRate.Value, 1, 5);
		foreach (EnemySetup item in __0)
		{
			if (!Object.op_Implicit((Object)(object)item))
			{
				continue;
			}
			if (!entries.TryGetValue(item, out var value))
			{
				if (item.spawnObjects == null || !item.spawnObjects.Any((PrefabRef p) => p != null && ((PrefabRef<GameObject>)(object)p).PrefabName == "Enemy - Luigi" && Object.op_Implicit((Object)(object)((PrefabRef<GameObject>)(object)p).Prefab) && Object.op_Implicit((Object)(object)((PrefabRef<GameObject>)(object)p).Prefab.GetComponentInChildren<LuigiChaseEnemy>(true))))
				{
					continue;
				}
				value = new Entry
				{
					Original = item.rarityPreset,
					BaseChance = (Object.op_Implicit((Object)(object)item.rarityPreset) ? item.rarityPreset.chance : 100f)
				};
				value.Adjusted = ScriptableObject.CreateInstance<RarityPreset>();
				((Object)value.Adjusted).name = "Luigi standalone configured rarity";
				entries.Add(item, value);
			}
			value.Adjusted.chance = value.BaseChance * (float)num;
			item.rarityPreset = ((num == 1) ? value.Original : value.Adjusted);
		}
	}

	public static void Restore()
	{
		foreach (KeyValuePair<EnemySetup, Entry> entry in entries)
		{
			if (Object.op_Implicit((Object)(object)entry.Key) && (Object)(object)entry.Key.rarityPreset == (Object)(object)entry.Value.Adjusted)
			{
				entry.Key.rarityPreset = entry.Value.Original;
			}
			if (Object.op_Implicit((Object)(object)entry.Value.Adjusted))
			{
				Object.Destroy((Object)(object)entry.Value.Adjusted);
			}
		}
		entries.Clear();
	}
}
public sealed class LuigiChaseEnemy : MonoBehaviour, IPunObservable
{
	public enum BrainState
	{
		Roam,
		Chase,
		Investigate,
		Search,
		Windup,
		Recover
	}

	[Header("Perception")]
	public float detectionRange = 22f;

	public float memoryDuration = 6f;

	public float searchDuration = 8f;

	[Header("Movement")]
	public float chaseSpeed = 3.8f;

	public float roamSpeed = 1.4f;

	public float acceleration = 10f;

	public float repathInterval = 0.2f;

	public float stoppingDistance = 1.15f;

	public float bodyHeight = 2.6f;

	[Header("Attack")]
	public float attackRange = 1.75f;

	public int attackDamage = 75;

	public GameObject shellVisualPrefab;

	public float attackWindup = 0.4f;

	public float attackCooldown = 1.1f;

	[Header("Runtime debug")]
	public BrainState currentState;

	private Enemy enemy;

	private EnemyParent parent;

	private EnemyNavMeshAgent movement;

	private NavMeshAgent agent;

	private EnemyRigidbody body;

	private EnemyHealth health;

	private EnemyStateSpawn spawn;

	private EnemyVision vision;

	private bool movementStatesDisabled;

	private LuigiFallRagdoll falling;

	private PlayerAvatar target;

	private Vector3 lastKnownPosition;

	private Vector3 wanderDestination;

	private Vector3 progressPosition;

	private float nextTick;

	private float nextPath;

	private float stateUntil;

	private float nextWander;

	private float nextProgressCheck;

	private float spawnGraceUntil;

	private int stuckChecks;

	private bool dead;

	private bool hasWanderDestination;

	private List<PlayerAvatar> livingPlayers = new List<PlayerAvatar>();

	private NavMeshPath path;

	private readonly Dictionary<PlayerAvatar, float> exposure = new Dictionary<PlayerAvatar, float>();

	private readonly Dictionary<LevelPoint, float> visited = new Dictionary<LevelPoint, float>();

	private Vector3 lastSeenVelocity;

	private float lastSeenTime;

	private float senseTime;

	private bool rangedWindup;

	private float nextShell;

	private int shellSequence;

	private readonly Dictionary<int, LuigiShellProjectile> shells = new Dictionary<int, LuigiShellProjectile>();

	public bool HasVisibleTarget { get; private set; }

	public Vector3 VisibleTargetPoint { get; private set; }

	public bool IsDead => dead;

	public int AttackSequence { get; private set; }

	private Vector3 Position
	{
		get
		{
			//IL_0024: 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)
			if (!Object.op_Implicit((Object)(object)body))
			{
				return ((Component)this).transform.position;
			}
			return ((Component)body).transform.position;
		}
	}

	private void LateUpdate()
	{
		KeyValuePair<int, LuigiShellProjectile>[] array = shells.ToArray();
		for (int i = 0; i < array.Length; i++)
		{
			KeyValuePair<int, LuigiShellProjectile> keyValuePair = array[i];
			if (!Object.op_Implicit((Object)(object)keyValuePair.Value) || keyValuePair.Value.Finished)
			{
				if (Object.op_Implicit((Object)(object)keyValuePair.Value))
				{
					Object.Destroy((Object)(object)((Component)keyValuePair.Value).gameObject);
				}
				shells.Remove(keyValuePair.Key);
			}
		}
	}

	private void OnDisable()
	{
		foreach (LuigiShellProjectile value in shells.Values)
		{
			if (Object.op_Implicit((Object)(object)value))
			{
				Object.Destroy((Object)(object)((Component)value).gameObject);
			}
		}
		shells.Clear();
	}

	private void Awake()
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Expected O, but got Unknown
		//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Expected O, but got Unknown
		//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d5: Expected O, but got Unknown
		//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f1: Expected O, but got Unknown
		path = new NavMeshPath();
		enemy = ((Component)this).GetComponent<Enemy>();
		parent = ((Component)this).GetComponentInParent<EnemyParent>();
		movement = ((Component)this).GetComponent<EnemyNavMeshAgent>();
		agent = ((Component)this).GetComponent<NavMeshAgent>();
		body = ((Component)parent).GetComponentInChildren<EnemyRigidbody>(true);
		falling = ((Component)parent).GetComponentInChildren<LuigiFallRagdoll>(true);
		health = ((Component)this).GetComponent<EnemyHealth>();
		spawn = ((Component)this).GetComponent<EnemyStateSpawn>();
		vision = ((Component)this).GetComponent<EnemyVision>();
		if (Object.op_Implicit((Object)(object)spawn))
		{
			spawn.OnSpawn.AddListener(new UnityAction(OnSpawn));
		}
		if (Object.op_Implicit((Object)(object)health))
		{
			health.onDeathStart.AddListener(new UnityAction(OnDeathStart));
			health.onDeath.AddListener(new UnityAction(OnDeath));
		}
	}

	private void OnEnable()
	{
		//IL_0033: 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)
		dead = false;
		HasVisibleTarget = false;
		AttackSequence = 0;
		target = null;
		exposure.Clear();
		visited.Clear();
		lastSeenVelocity = Vector3.zero;
		lastSeenTime = 0f;
		senseTime = Time.time;
		currentState = BrainState.Roam;
		nextTick = (nextPath = (nextWander = 0f));
		hasWanderDestination = false;
		stuckChecks = 0;
		nextProgressCheck = Time.time + 2f;
		spawnGraceUntil = Time.time + 2f;
		nextShell = Time.time + 3f;
		rangedWindup = false;
	}

	private void OnSpawn()
	{
		if (SemiFunc.IsMasterClientOrSingleplayer())
		{
			SemiFunc.EnemySpawn(enemy);
		}
	}

	private void Update()
	{
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: Invalid comparison between Unknown and I4
		//IL_0126: Unknown result type (might be due to invalid IL or missing references)
		//IL_012c: Invalid comparison between Unknown and I4
		if (!Object.op_Implicit((Object)(object)GameManager.instance) || !SemiFunc.IsMasterClientOrSingleplayer() || !Object.op_Implicit((Object)(object)enemy) || !Object.op_Implicit((Object)(object)parent) || !Object.op_Implicit((Object)(object)GameDirector.instance))
		{
			return;
		}
		if (!movementStatesDisabled)
		{
			MonoBehaviour[] components = ((Component)this).GetComponents<MonoBehaviour>();
			foreach (MonoBehaviour val in components)
			{
				string name = ((object)val).GetType().Name;
				if (name.StartsWith("EnemyState") && name != "EnemyStateSpawn" && name != "EnemyStateStunned" && name != "EnemyStateDespawn")
				{
					((Behaviour)val).enabled = false;
				}
			}
			movementStatesDisabled = true;
		}
		if ((int)enemy.CurrentState == 11)
		{
			parent.Despawn();
		}
		else if (Object.op_Implicit((Object)(object)falling) && falling.Active)
		{
			HasVisibleTarget = false;
			movement.Stop(0.3f);
			if (currentState == BrainState.Windup)
			{
				currentState = BrainState.Recover;
				stateUntil = Time.time + attackCooldown;
			}
		}
		else if (dead || (int)enemy.CurrentState == 1 || enemy.IsStunned() || enemy.FreezeTimer > 0f || Time.time < spawnGraceUntil)
		{
			HasVisibleTarget = false;
			movement.Stop(0.3f);
			if (currentState == BrainState.Windup)
			{
				currentState = BrainState.Recover;
				stateUntil = Time.time + attackCooldown;
			}
		}
		else if (Object.op_Implicit((Object)(object)agent) && ((Behaviour)agent).enabled && agent.isOnNavMesh)
		{
			if (Time.time >= nextTick)
			{
				nextTick = Time.time + Mathf.Max(0.05f, repathInterval);
				Sense();
				Think();
			}
			FaceMovementOrTarget();
		}
	}

	private void Sense()
	{
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_010a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0116: 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_0170: Unknown result type (might be due to invalid IL or missing references)
		//IL_021c: Unknown result type (might be due to invalid IL or missing references)
		//IL_029f: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0251: Unknown result type (might be due to invalid IL or missing references)
		//IL_0257: Unknown result type (might be due to invalid IL or missing references)
		//IL_025c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0277: Unknown result type (might be due to invalid IL or missing references)
		//IL_027c: Unknown result type (might be due to invalid IL or missing references)
		//IL_028b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0292: Unknown result type (might be due to invalid IL or missing references)
		//IL_0297: Unknown result type (might be due to invalid IL or missing references)
		livingPlayers = SemiFunc.PlayerGetAllPlayerAvatarWithinRange(detectionRange, Position, false, default(LayerMask));
		if (Object.op_Implicit((Object)(object)target) && !livingPlayers.Contains(target))
		{
			target = null;
		}
		PlayerAvatar val = ((Object.op_Implicit((Object)(object)target) && CanSee(target, tracking: true)) ? target : null);
		bool flag = Object.op_Implicit((Object)(object)val);
		float num = Mathf.Clamp(Time.time - senseTime, 0f, 0.3f);
		senseTime = Time.time;
		PlayerAvatar[] array = exposure.Keys.Where((PlayerAvatar p) => !livingPlayers.Contains(p)).ToArray();
		foreach (PlayerAvatar key in array)
		{
			exposure.Remove(key);
		}
		float num3 = float.MaxValue;
		foreach (PlayerAvatar livingPlayer in livingPlayers)
		{
			float num4 = HorizontalDistance(Position, ((Component)livingPlayer).transform.position);
			exposure.TryGetValue(livingPlayer, out var value);
			bool flag2 = CanSee(livingPlayer, tracking: false);
			exposure[livingPlayer] = (flag2 ? (value + num) : 0f);
			float num5 = livingPlayer.PlayerVisionTarget.VisionTransform.position.y - (Position.y - bodyHeight * 0.5f);
			float num6 = ((num4 < 3f) ? 0.15f : ((num5 < 1f) ? 0.6f : 0.35f));
			if (!flag && flag2 && exposure[livingPlayer] >= num6 && num4 < num3)
			{
				val = livingPlayer;
				num3 = num4;
			}
		}
		HasVisibleTarget = Object.op_Implicit((Object)(object)val);
		if (Object.op_Implicit((Object)(object)val))
		{
			target = val;
			VisibleTargetPoint = val.PlayerVisionTarget.VisionTransform.position;
			if (lastSeenTime > 0f && Time.time - lastSeenTime < 0.6f)
			{
				Vector3 val2 = (((Component)target).transform.position - lastKnownPosition) / Mathf.Max(0.05f, Time.time - lastSeenTime);
				val2.y = 0f;
				lastSeenVelocity = Vector3.ClampMagnitude(val2, 5f);
			}
			else
			{
				lastSeenVelocity = Vector3.zero;
			}
			lastSeenTime = Time.time;
			lastKnownPosition = ((Component)target).transform.position;
			if (currentState != BrainState.Windup && currentState != BrainState.Recover)
			{
				currentState = BrainState.Chase;
			}
		}
		else if (currentState != BrainState.Windup && currentState != BrainState.Recover && currentState == BrainState.Chase)
		{
			currentState = BrainState.Investigate;
			stateUntil = Time.time + memoryDuration;
			hasWanderDestination = false;
		}
	}

	private bool CanSee(PlayerAvatar player, bool tracking)
	{
		//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_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		if (!Object.op_Implicit((Object)(object)vision) || !Object.op_Implicit((Object)(object)player))
		{
			return false;
		}
		Vector3 position = player.PlayerVisionTarget.VisionTransform.position;
		Vector3 val = position - vision.VisionTransform.position;
		if (((Vector3)(ref val)).magnitude > detectionRange || Mathf.Abs(val.y) > 3.5f)
		{
			return false;
		}
		val.y = 0f;
		Vector3 forward = vision.VisionTransform.forward;
		forward.y = 0f;
		if (((Vector3)(ref val)).sqrMagnitude > 0.04f && Vector3.Angle(forward, val) > (tracking ? 85f : 65f))
		{
			return false;
		}
		return HasClearSight(vision.VisionTransform.position, position);
	}

	private void Think()
	{
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_040f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0478: Unknown result type (might be due to invalid IL or missing references)
		//IL_0422: Unknown result type (might be due to invalid IL or missing references)
		//IL_0428: Unknown result type (might be due to invalid IL or missing references)
		//IL_04b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_04ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_04c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_04c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_04e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_04ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_0446: Unknown result type (might be due to invalid IL or missing references)
		//IL_0136: Unknown result type (might be due to invalid IL or missing references)
		//IL_013c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0146: Unknown result type (might be due to invalid IL or missing references)
		//IL_014b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0168: 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_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01de: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0208: Unknown result type (might be due to invalid IL or missing references)
		//IL_020d: Unknown result type (might be due to invalid IL or missing references)
		//IL_020f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0210: Unknown result type (might be due to invalid IL or missing references)
		//IL_0226: Unknown result type (might be due to invalid IL or missing references)
		//IL_0227: Unknown result type (might be due to invalid IL or missing references)
		//IL_0228: Unknown result type (might be due to invalid IL or missing references)
		//IL_0229: Unknown result type (might be due to invalid IL or missing references)
		//IL_022e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0232: Unknown result type (might be due to invalid IL or missing references)
		//IL_023c: Unknown result type (might be due to invalid IL or missing references)
		//IL_02eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0327: Unknown result type (might be due to invalid IL or missing references)
		//IL_032d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0332: Unknown result type (might be due to invalid IL or missing references)
		//IL_0337: Unknown result type (might be due to invalid IL or missing references)
		//IL_0379: Unknown result type (might be due to invalid IL or missing references)
		//IL_0383: Unknown result type (might be due to invalid IL or missing references)
		//IL_0388: Unknown result type (might be due to invalid IL or missing references)
		//IL_0392: Unknown result type (might be due to invalid IL or missing references)
		//IL_0397: Unknown result type (might be due to invalid IL or missing references)
		//IL_0359: Unknown result type (might be due to invalid IL or missing references)
		//IL_035e: Unknown result type (might be due to invalid IL or missing references)
		switch (currentState)
		{
		case BrainState.Chase:
			enemy.CurrentState = (EnemyState)4;
			enemy.SetChaseTimer();
			if (!Object.op_Implicit((Object)(object)target))
			{
				BeginSearch();
			}
			else if (CanAttack(target))
			{
				rangedWindup = false;
				currentState = BrainState.Windup;
				AttackSequence++;
				stateUntil = Time.time + attackWindup;
				Hold();
			}
			else if (Time.time >= nextShell && HasVisibleTarget && HorizontalDistance(Position, ((Component)target).transform.position) >= 5f && CanSee(target, tracking: true))
			{
				rangedWindup = true;
				currentState = BrainState.Windup;
				AttackSequence++;
				stateUntil = Time.time + 0.65f;
				nextShell = Time.time + 4.5f;
				Hold();
			}
			else if (!MoveTo(lastKnownPosition + lastSeenVelocity * 0.25f, chaseSpeed, stoppingDistance))
			{
				MoveTo(lastKnownPosition, chaseSpeed, stoppingDistance);
			}
			break;
		case BrainState.Windup:
			Hold();
			if (!(Time.time >= stateUntil))
			{
				break;
			}
			if (rangedWindup && Object.op_Implicit((Object)(object)target) && livingPlayers.Contains(target) && CanSee(target, tracking: true))
			{
				Vector3 val = Position + Vector3.up * 0.35f;
				Vector3 position = target.PlayerVisionTarget.VisionTransform.position;
				if (HasClearLine(val, position))
				{
					Transform transform = ((Component)parent).transform;
					Vector3 val2 = position - val;
					LuigiShellProjectile luigiShellProjectile = LuigiShellProjectile.Create(transform, val, ((Vector3)(ref val2)).normalized * 12f, authority: true, shellVisualPrefab);
					luigiShellProjectile.Id = ++shellSequence;
					shells.Add(luigiShellProjectile.Id, luigiShellProjectile);
				}
			}
			else if (!rangedWindup && Object.op_Implicit((Object)(object)target) && livingPlayers.Contains(target) && CanAttack(target))
			{
				PlayerHealth component = ((Component)target).GetComponent<PlayerHealth>();
				if (Object.op_Implicit((Object)(object)component))
				{
					component.HurtOther(attackDamage, ((Component)target).transform.position, false, -1, false);
				}
				PlayerTumble val3 = ((IEnumerable<PlayerTumble>)Object.FindObjectsOfType<PlayerTumble>()).FirstOrDefault((Func<PlayerTumble, bool>)((PlayerTumble t) => (Object)(object)t.playerAvatar == (Object)(object)target));
				if (Object.op_Implicit((Object)(object)val3))
				{
					Vector3 val4 = ((Component)target).transform.position - Position;
					val4.y = 0f;
					if (((Vector3)(ref val4)).sqrMagnitude < 0.01f)
					{
						val4 = ((Component)this).transform.forward;
					}
					val3.TumbleRequest(true, false);
					val3.TumbleOverrideTime(1.5f);
					val3.TumbleForce(((Vector3)(ref val4)).normalized * 35f + Vector3.up * 16f);
				}
			}
			currentState = BrainState.Recover;
			stateUntil = Time.time + attackCooldown;
			break;
		case BrainState.Recover:
			Hold();
			if (Time.time >= stateUntil)
			{
				if (Object.op_Implicit((Object)(object)target) && CanSee(target, tracking: true))
				{
					currentState = BrainState.Chase;
				}
				else
				{
					BeginSearch();
				}
			}
			break;
		case BrainState.Investigate:
			enemy.CurrentState = (EnemyState)2;
			if (Time.time >= stateUntil || HorizontalDistance(Position, lastKnownPosition) < 1f)
			{
				BeginSearch();
			}
			else if (!MoveTo(lastKnownPosition, chaseSpeed * 0.75f, 0.3f))
			{
				BeginSearch();
			}
			break;
		case BrainState.Search:
			enemy.CurrentState = (EnemyState)2;
			if (Time.time >= stateUntil)
			{
				target = null;
				currentState = BrainState.Roam;
				hasWanderDestination = false;
				nextWander = Time.time + 1f;
			}
			else
			{
				Wander(lastKnownPosition + lastSeenVelocity * 0.6f, 6f);
			}
			break;
		default:
			enemy.CurrentState = (EnemyState)2;
			Wander(((Component)this).transform.position, 18f);
			break;
		}
		CheckProgress();
	}

	private void BeginSearch()
	{
		currentState = BrainState.Search;
		stateUntil = Time.time + searchDuration;
		nextWander = 0f;
		hasWanderDestination = false;
	}

	private bool CanAttack(PlayerAvatar player)
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: 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_004b: 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_005c: Unknown result type (might be due to invalid IL or missing references)
		Vector3 position = player.PlayerVisionTarget.VisionTransform.position;
		if (!CanSee(player, tracking: true) || !WithinAttackReach(Position, position, bodyHeight, attackRange))
		{
			return false;
		}
		Vector3 val = default(Vector3);
		((Vector3)(ref val))..ctor(Position.x, position.y, Position.z);
		return HasClearLine(val, position);
	}

	public static bool WithinAttackReach(Vector3 bodyCenter, Vector3 playerPoint, float height, float range)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: 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)
		if (HorizontalDistance(bodyCenter, playerPoint) <= range && playerPoint.y >= bodyCenter.y - height * 0.5f - 0.25f)
		{
			return playerPoint.y <= bodyCenter.y + height * 0.5f + 0.25f;
		}
		return false;
	}

	private bool HasClearLine(Vector3 from, Vector3 to)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: 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_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)
		int num = LayerMask.op_Implicit(SemiFunc.LayerMaskGetVisionObstruct()) & ~LayerMask.GetMask(new string[2] { "Player", "PlayerOnlyCollision" });
		Vector3 val = to - from;
		RaycastHit[] array = Physics.RaycastAll(from, ((Vector3)(ref val)).normalized, ((Vector3)(ref val)).magnitude, num, (QueryTriggerInteraction)1);
		for (int i = 0; i < array.Length; i++)
		{
			RaycastHit val2 = array[i];
			if ((!Object.op_Implicit((Object)(object)parent) || !((RaycastHit)(ref val2)).transform.IsChildOf(((Component)parent).transform)) && !Object.op_Implicit((Object)(object)((Component)((RaycastHit)(ref val2)).collider).GetComponentInParent<PlayerAvatar>()) && !Object.op_Implicit((Object)(object)((Component)((RaycastHit)(ref val2)).collider).GetComponentInParent<PlayerController>()))
			{
				return false;
			}
		}
		return true;
	}

	private bool HasClearSight(Vector3 from, Vector3 to)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: 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_0044: 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_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val = to - from;
		int num = (LayerMask.op_Implicit(SemiFunc.LayerMaskGetVisionObstruct()) | LayerMask.GetMask(new string[1] { "HideTriggers" })) & ~LayerMask.GetMask(new string[2] { "Player", "PlayerOnlyCollision" });
		RaycastHit[] array = Physics.RaycastAll(from, ((Vector3)(ref val)).normalized, ((Vector3)(ref val)).magnitude, num, (QueryTriggerInteraction)1);
		for (int i = 0; i < array.Length; i++)
		{
			RaycastHit val2 = array[i];
			if ((!Object.op_Implicit((Object)(object)parent) || !((RaycastHit)(ref val2)).transform.IsChildOf(((Component)parent).transform)) && !Object.op_Implicit((Object)(object)((Component)((RaycastHit)(ref val2)).collider).GetComponentInParent<PlayerAvatar>()) && !Object.op_Implicit((Object)(object)((Component)((RaycastHit)(ref val2)).collider).GetComponentInParent<PlayerController>()))
			{
				return false;
			}
		}
		return true;
	}

	public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
	{
		//IL_0105: 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_0160: 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_01bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0199: Unknown result type (might be due to invalid IL or missing references)
		//IL_019b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
		if (stream.IsWriting)
		{
			stream.SendNext((object)(int)currentState);
			stream.SendNext((object)HasVisibleTarget);
			stream.SendNext((object)VisibleTargetPoint);
			stream.SendNext((object)AttackSequence);
			stream.SendNext((object)dead);
			stream.SendNext((object)shells.Count);
			{
				foreach (KeyValuePair<int, LuigiShellProjectile> shell in shells)
				{
					stream.SendNext((object)shell.Key);
					stream.SendNext((object)((Component)shell.Value).transform.position);
				}
				return;
			}
		}
		currentState = (BrainState)(int)stream.ReceiveNext();
		HasVisibleTarget = (bool)stream.ReceiveNext();
		VisibleTargetPoint = (Vector3)stream.ReceiveNext();
		AttackSequence = (int)stream.ReceiveNext();
		dead = (bool)stream.ReceiveNext();
		int num = (int)stream.ReceiveNext();
		HashSet<int> received = new HashSet<int>();
		for (int i = 0; i < num; i++)
		{
			int num2 = (int)stream.ReceiveNext();
			Vector3 position = (Vector3)stream.ReceiveNext();
			received.Add(num2);
			if (!shells.TryGetValue(num2, out var value))
			{
				value = (shells[num2] = LuigiShellProjectile.Create(((Component)parent).transform, position, Vector3.zero, authority: false, shellVisualPrefab));
			}
			((Component)value).transform.position = position;
		}
		int[] array = shells.Keys.Where((int id) => !received.Contains(id)).ToArray();
		foreach (int key in array)
		{
			Object.Destroy((Object)(object)((Component)shells[key]).gameObject);
			shells.Remove(key);
		}
	}

	private bool MoveTo(Vector3 destination, float speed, float stopDistance)
	{
		//IL_0021: 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_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		if (Time.time < nextPath)
		{
			return true;
		}
		nextPath = Time.time + repathInterval;
		NavMeshHit val = default(NavMeshHit);
		if (!NavMesh.SamplePosition(destination, ref val, 2f, agent.areaMask) || !agent.CalculatePath(((NavMeshHit)(ref val)).position, path) || (int)path.status != 0)
		{
			Hold();
			return false;
		}
		agent.stoppingDistance = stopDistance;
		movement.OverrideAgent(speed, acceleration, repathInterval + 0.2f);
		movement.Stop(0f);
		movement.SetDestination(((NavMeshHit)(ref val)).position);
		return true;
	}

	private void Hold()
	{
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		movement.Stop(repathInterval + 0.3f);
		if (((Behaviour)agent).enabled && agent.isOnNavMesh)
		{
			agent.ResetPath();
		}
		NavMeshHit val = default(NavMeshHit);
		if (NavMesh.SamplePosition(Position - Vector3.up * (bodyHeight * 0.5f), ref val, 0.8f, agent.areaMask))
		{
			movement.Warp(((NavMeshHit)(ref val)).position, true);
		}
		nextPath = 0f;
	}

	private void Wander(Vector3 center, float radius)
	{
		//IL_0007: 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_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_020d: 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_015f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0164: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ee: 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)
		//IL_017a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0186: Unknown result type (might be due to invalid IL or missing references)
		//IL_018d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0192: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0114: Unknown result type (might be due to invalid IL or missing references)
		//IL_0119: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01da: Unknown result type (might be due to invalid IL or missing references)
		//IL_01df: Unknown result type (might be due to invalid IL or missing references)
		if (Time.time < nextWander)
		{
			Hold();
			return;
		}
		if (hasWanderDestination && HorizontalDistance(Position, wanderDestination) < 0.7f)
		{
			hasWanderDestination = false;
			nextWander = Time.time + ((currentState == BrainState.Search) ? 0.8f : 0.4f);
			Hold();
			return;
		}
		if (!hasWanderDestination)
		{
			List<LevelPoint> list = (Object.op_Implicit((Object)(object)LevelGenerator.Instance) ? LevelGenerator.Instance.LevelPathPoints : null);
			if (list != null)
			{
				foreach (LevelPoint item in (from p in list
					where Object.op_Implicit((Object)(object)p) && !p.Truck && HorizontalDistance(((Component)p).transform.position, center) < radius && HorizontalDistance(((Component)p).transform.position, Position) > 2f && Mathf.Abs(((Component)p).transform.position.y - ((Component)this).transform.position.y) < 2f
					orderby PatrolScore(p, center) descending
					select p).Take(12))
				{
					if (agent.CalculatePath(((Component)item).transform.position, path) && (int)path.status == 0)
					{
						wanderDestination = ((Component)item).transform.position;
						visited[item] = Time.time;
						hasWanderDestination = true;
						break;
					}
				}
			}
			int num = 0;
			NavMeshHit val2 = default(NavMeshHit);
			while (!hasWanderDestination && num < 8)
			{
				Vector2 val = Random.insideUnitCircle * radius;
				if (!(((Vector2)(ref val)).magnitude < 2f) && NavMesh.SamplePosition(center + new Vector3(val.x, 0f, val.y), ref val2, 2f, agent.areaMask) && agent.CalculatePath(((NavMeshHit)(ref val2)).position, path) && (int)path.status == 0)
				{
					wanderDestination = ((NavMeshHit)(ref val2)).position;
					hasWanderDestination = true;
					break;
				}
				num++;
			}
		}
		if (!hasWanderDestination || !MoveTo(wanderDestination, roamSpeed, 0.3f))
		{
			hasWanderDestination = false;
			nextWander = Time.time + 1f;
			Hold();
		}
	}

	private float PatrolScore(LevelPoint point, Vector3 center)
	{
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: 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)
		float value;
		float num = (visited.TryGetValue(point, out value) ? Mathf.Min(30f, Time.time - value) : 35f);
		Vector3 val = ((Component)point).transform.position - Position;
		val.y = 0f;
		float num2 = Vector3.Dot(((Component)this).transform.forward, ((Vector3)(ref val)).normalized) * 4f;
		float num3 = HorizontalDistance(((Component)point).transform.position, center);
		return num + num2 - num3 * ((currentState == BrainState.Search) ? 1.5f : 0.2f);
	}

	private void CheckProgress()
	{
		//IL_002d: 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_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		if (Time.time < nextProgressCheck)
		{
			return;
		}
		nextProgressCheck = Time.time + 2f;
		if (agent.hasPath && HorizontalDistance(progressPosition, Position) < 0.2f)
		{
			stuckChecks++;
		}
		else
		{
			stuckChecks = 0;
		}
		progressPosition = Position;
		if (stuckChecks >= 2)
		{
			Hold();
			hasWanderDestination = false;
			nextWander = 0f;
			if (currentState == BrainState.Chase || currentState == BrainState.Investigate)
			{
				BeginSearch();
			}
			stuckChecks = 0;
		}
	}

	private void FaceMovementOrTarget()
	{
		//IL_0020: 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_0028: 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_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: 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)
		Vector3 val = ((HasVisibleTarget && (currentState == BrainState.Windup || currentState == BrainState.Recover)) ? (VisibleTargetPoint - Position) : agent.desiredVelocity);
		val.y = 0f;
		if (((Vector3)(ref val)).sqrMagnitude > 0.01f)
		{
			((Component)this).transform.rotation = Quaternion.RotateTowards(((Component)this).transform.rotation, Quaternion.LookRotation(val), 240f * Time.deltaTime);
		}
		else if (currentState == BrainState.Search)
		{
			((Component)this).transform.Rotate(0f, 35f * Time.deltaTime, 0f);
		}
	}

	private static float HorizontalDistance(Vector3 a, Vector3 b)
	{
		//IL_0016: 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)
		a.y = (b.y = 0f);
		return Vector3.Distance(a, b);
	}

	private void OnDeathStart()
	{
		dead = true;
	}

	private void OnDeath()
	{
		if (SemiFunc.IsMasterClientOrSingleplayer())
		{
			parent.Despawn();
		}
	}

	private void OnDestroy()
	{
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Expected O, but got Unknown
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Expected O, but got Unknown
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Expected O, but got Unknown
		if (Object.op_Implicit((Object)(object)spawn))
		{
			spawn.OnSpawn.RemoveListener(new UnityAction(OnSpawn));
		}
		if (Object.op_Implicit((Object)(object)health))
		{
			health.onDeathStart.RemoveListener(new UnityAction(OnDeathStart));
			health.onDeath.RemoveListener(new UnityAction(OnDeath));
		}
	}
}
[DefaultExecutionOrder(100)]
public sealed class LuigiFallRagdoll : MonoBehaviour, IPunObservable
{
	public float fallSpeed = 2.5f;

	public float airborneDelay = 0.25f;

	private Animator animator;

	private Enemy enemy;

	private EnemyRigidbody body;

	private Rigidbody rootBody;

	private EnemyStateStunned stun;

	private EnemyNavMeshAgent movement;

	private LuigiChaseEnemy brain;

	private Rigidbody[] limbs;

	private Collider[] shapes;

	private CharacterJoint[] joints;

	private Rigidbody[] connections;

	private Vector3[] receivedPositions;

	private Vector3[] recoverPositions;

	private Quaternion[] receivedRotations;

	private Quaternion[] recoverRotations;

	private float airborne;

	private float settled;

	private float entered;

	private float recoverUntil;

	private bool initialized;

	private CapsuleCollider[] rootCapsules;

	private Vector3[] capsuleCenters;

	private float[] capsuleHeights;

	private float[] capsuleRadii;

	private float lastDownwardMotion = -100f;

	private Vector3 supportPoint;

	private readonly RaycastHit[] supportHits = (RaycastHit[])(object)new RaycastHit[32];

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

	private float nextRecoveryTry;

	private static readonly HumanBodyBones[] Bones;

	private static readonly HumanBodyBones[] Ends;

	private static readonly int[] Parents;

	public bool Active { get; private set; }

	private bool TryFindRecoveryPosition(out Vector3 position)
	{
		//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_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: 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_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_010c: Unknown result type (might be due to invalid IL or missing references)
		//IL_012d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0132: Unknown result type (might be due to invalid IL or missing references)
		//IL_013c: 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_0146: 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_0156: Unknown result type (might be due to invalid IL or missing references)
		//IL_015f: 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_0172: Unknown result type (might be due to invalid IL or missing references)
		//IL_0174: Unknown result type (might be due to invalid IL or missing references)
		//IL_0176: Unknown result type (might be due to invalid IL or missing references)
		//IL_017b: Unknown result type (might be due to invalid IL or missing references)
		//IL_017f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0186: Unknown result type (might be due to invalid IL or missing references)
		//IL_0188: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01de: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_020a: Unknown result type (might be due to invalid IL or missing references)
		//IL_020f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0214: Unknown result type (might be due to invalid IL or missing references)
		//IL_0218: Unknown result type (might be due to invalid IL or missing references)
		//IL_021a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0277: Unknown result type (might be due to invalid IL or missing references)
		//IL_027c: Unknown result type (might be due to invalid IL or missing references)
		position = Vector3.zero;
		NavMeshAgent component = ((Component)enemy).GetComponent<NavMeshAgent>();
		PhysicsScene physicsScene = PhysicsSceneExtensions.GetPhysicsScene(((Component)this).gameObject.scene);
		int mask = LayerMask.GetMask(new string[4] { "Default", "PhysGrabObject", "PhysGrabObjectHinge", "PhysGrabObjectCart" });
		float num = Mathf.Max(0.3f, component.radius);
		NavMeshHit val = default(NavMeshHit);
		Vector3 val3 = default(Vector3);
		RaycastHit val5 = default(RaycastHit);
		for (int i = 0; i <= 7; i++)
		{
			for (int j = 0; j < ((i == 0) ? 1 : 12); j++)
			{
				for (int k = 0; k <= 3; k++)
				{
					float num2 = (float)j * (float)Math.PI / 6f;
					if (!NavMesh.SamplePosition(supportPoint + new Vector3(Mathf.Cos(num2), 0f, Mathf.Sin(num2)) * ((float)i * 0.5f) - Vector3.up * (float)k, ref val, 0.65f, component.areaMask) || ((NavMeshHit)(ref val)).position.y > supportPoint.y + 0.5f || ((NavMeshHit)(ref val)).position.y < supportPoint.y - 3.5f)
					{
						continue;
					}
					Vector3 val2 = supportPoint + Vector3.up * 0.25f;
					((Vector3)(ref val3))..ctor(((NavMeshHit)(ref val)).position.x, val2.y, ((NavMeshHit)(ref val)).position.z);
					Vector3 val4 = val3 - val2;
					if (((PhysicsScene)(ref physicsScene)).Raycast(val2, ((Vector3)(ref val4)).normalized, ref val5, Vector3.Distance(val2, val3), LayerMask.GetMask(new string[1] { "Default" }), (QueryTriggerInteraction)1) && !((RaycastHit)(ref val5)).transform.IsChildOf(((Component)body).transform))
					{
						continue;
					}
					Vector3 val6 = ((NavMeshHit)(ref val)).position + Vector3.up * (num + 0.06f);
					Vector3 val7 = ((NavMeshHit)(ref val)).position + Vector3.up * Mathf.Max(num + 0.06f, brain.bodyHeight - num);
					int num3 = ((PhysicsScene)(ref physicsScene)).OverlapCapsule(val6, val7, num, recoveryOverlaps, mask, (QueryTriggerInteraction)1);
					bool flag = num3 == recoveryOverlaps.Length;
					for (int l = 0; l < num3; l++)
					{
						if (!((Component)recoveryOverlaps[l]).transform.IsChildOf(((Component)body).transform))
						{
							flag = true;
							break;
						}
					}
					if (!flag)
					{
						position = ((NavMeshHit)(ref val)).position;
						return true;
					}
				}
			}
		}
		return false;
	}

	private void Start()
	{
		Initialize();
	}

	private void Initialize()
	{
		//IL_0148: Unknown result type (might be due to invalid IL or missing references)
		//IL_014d: Unknown result type (might be due to invalid IL or missing references)
		//IL_028b: Unknown result type (might be due to invalid IL or missing references)
		//IL_029c: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_0312: Unknown result type (might be due to invalid IL or missing references)
		//IL_0317: Unknown result type (might be due to invalid IL or missing references)
		//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_0307: Unknown result type (might be due to invalid IL or missing references)
		//IL_031c: Unknown result type (might be due to invalid IL or missing references)
		//IL_032e: Unknown result type (might be due to invalid IL or missing references)
		//IL_033b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0347: Unknown result type (might be due to invalid IL or missing references)
		//IL_034e: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_041d: Unknown result type (might be due to invalid IL or missing references)
		//IL_042f: Unknown result type (might be due to invalid IL or missing references)
		//IL_043a: Unknown result type (might be due to invalid IL or missing references)
		//IL_044c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0457: Unknown result type (might be due to invalid IL or missing references)
		//IL_0475: Unknown result type (might be due to invalid IL or missing references)
		//IL_0480: Unknown result type (might be due to invalid IL or missing references)
		//IL_049e: Unknown result type (might be due to invalid IL or missing references)
		if (initialized)
		{
			return;
		}
		animator = ((Component)this).GetComponent<Animator>();
		EnemyParent componentInParent = ((Component)this).GetComponentInParent<EnemyParent>();
		enemy = ((Component)componentInParent).GetComponentInChildren<Enemy>(true);
		body = ((Component)componentInParent).GetComponentInChildren<EnemyRigidbody>(true);
		rootBody = ((Component)body).GetComponent<Rigidbody>();
		brain = ((Component)enemy).GetComponent<LuigiChaseEnemy>();
		stun = ((Component)enemy).GetComponent<EnemyStateStunned>();
		movement = ((Component)enemy).GetComponent<EnemyNavMeshAgent>();
		int num = Bones.Length;
		limbs = (Rigidbody[])(object)new Rigidbody[num];
		shapes = (Collider[])(object)new Collider[num];
		joints = (CharacterJoint[])(object)new CharacterJoint[num];
		connections = (Rigidbody[])(object)new Rigidbody[num];
		receivedPositions = (Vector3[])(object)new Vector3[num];
		receivedRotations = (Quaternion[])(object)new Quaternion[num];
		recoverPositions = (Vector3[])(object)new Vector3[num];
		recoverRotations = (Quaternion[])(object)new Quaternion[num];
		Collider[] componentsInChildren = ((Component)componentInParent).GetComponentsInChildren<Collider>(true);
		rootCapsules = ((Component)body).GetComponentsInChildren<CapsuleCollider>(true);
		capsuleCenters = (Vector3[])(object)new Vector3[rootCapsules.Length];
		capsuleHeights = new float[rootCapsules.Length];
		capsuleRadii = new float[rootCapsules.Length];
		for (int i = 0; i < rootCapsules.Length; i++)
		{
			capsuleCenters[i] = rootCapsules[i].center;
			capsuleHeights[i] = rootCapsules[i].height;
			capsuleRadii[i] = rootCapsules[i].radius;
		}
		for (int j = 0; j < num; j++)
		{
			Transform boneTransform = animator.GetBoneTransform(Bones[j]);
			if (!Object.op_Implicit((Object)(object)boneTransform) && (int)Bones[j] == 8)
			{
				boneTransform = animator.GetBoneTransform((HumanBodyBones)7);
			}
			if (!Object.op_Implicit((Object)(object)boneTransform))
			{
				throw new InvalidOperationException("Missing Luigi ragdoll bone: " + ((object)Unsafe.As<HumanBodyBones, HumanBodyBones>(ref Bones[j])/*cast due to .constrained prefix*/).ToString());
			}
			Rigidbody val = ((Component)boneTransform).gameObject.AddComponent<Rigidbody>();
			val.isKinematic = true;
			val.useGravity = true;
			val.mass = ((j < 2) ? 2f : ((j == 2) ? 0.7f : 0.45f));
			val.drag = 0.15f;
			val.angularDrag = 1.8f;
			val.solverIterations = 10;
			val.solverVelocityIterations = 4;
			val.collisionDetectionMode = (CollisionDetectionMode)3;
			val.maxAngularVelocity = 12f;
			limbs[j] = val;
			float num2 = Mathf.Max(0.01f, Mathf.Max(Mathf.Abs(boneTransform.lossyScale.x), Mathf.Max(Mathf.Abs(boneTransform.lossyScale.y), Mathf.Abs(boneTransform.lossyScale.z))));
			Transform val2 = (((int)Ends[j] == 55) ? null : animator.GetBoneTransform(Ends[j]));
			Vector3 val3 = (Object.op_Implicit((Object)(object)val2) ? boneTransform.InverseTransformPoint(val2.position) : (Vector3.up * (0.18f / num2)));
			BoxCollider val4 = ((Component)boneTransform).gameObject.AddComponent<BoxCollider>();
			val4.size = Vector3.one * (0.2f / num2);
			val4.center = val3 * 0.5f;
			((Collider)val4).contactOffset = 0.02f;
			((Collider)val4).enabled = false;
			shapes[j] = (Collider)(object)val4;
			CharacterJoint val5 = ((Component)boneTransform).gameObject.AddComponent<CharacterJoint>();
			((Joint)val5).connectedBody = ((Parents[j] < 0) ? rootBody : limbs[Parents[j]]);
			connections[j] = ((Joint)val5).connectedBody;
			((Joint)val5).autoConfigureConnectedAnchor = false;
			((Joint)val5).anchor = Vector3.zero;
			((Joint)val5).connectedAnchor = ((Component)((Joint)val5).connectedBody).transform.InverseTransformPoint(boneTransform.position);
			((Joint)val5).enableCollision = false;
			val5.enableProjection = true;
			val5.projectionDistance = 0.08f;
			val5.projectionAngle = 15f;
			SoftJointLimit val6 = default(SoftJointLimit);
			((SoftJointLimit)(ref val6)).limit = -30f;
			val5.lowTwistLimit = val6;
			val6 = default(SoftJointLimit);
			((SoftJointLimit)(ref val6)).limit = 30f;
			val5.highTwistLimit = val6;
			val6 = default(SoftJointLimit);
			((SoftJointLimit)(ref val6)).limit = ((j < 3) ? 35f : 65f);
			val5.swing1Limit = val6;
			val6 = default(SoftJointLimit);
			((SoftJointLimit)(ref val6)).limit = ((j < 3) ? 25f : 40f);
			val5.swing2Limit = val6;
			joints[j] = val5;
			((Joint)val5).connectedBody = null;
			Collider[] array = componentsInChildren;
			foreach (Collider val7 in array)
			{
				Physics.IgnoreCollision((Collider)(object)val4, val7);
			}
			for (int l = 0; l < j; l++)
			{
				Physics.IgnoreCollision((Collider)(object)val4, shapes[l]);
			}
		}
		FitLimbColliders();
		initialized = true;
	}

	private void FitLimbColliders()
	{
		//IL_00da: 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_01de: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_0200: Unknown result type (might be due to invalid IL or missing references)
		//IL_020a: Unknown result type (might be due to invalid IL or missing references)
		//IL_020f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0219: Unknown result type (might be due to invalid IL or missing references)
		//IL_021e: Unknown result type (might be due to invalid IL or missing references)
		//IL_016f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0174: Unknown result type (might be due to invalid IL or missing references)
		//IL_0179: Unknown result type (might be due to invalid IL or missing references)
		//IL_017e: 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_01b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0190: Unknown result type (might be due to invalid IL or missing references)
		//IL_0192: Unknown result type (might be due to invalid IL or missing references)
		//IL_0197: Unknown result type (might be due to invalid IL or missing references)
		//IL_019c: Unknown result type (might be due to invalid IL or missing references)
		SkinnedMeshRenderer componentInChildren = ((Component)this).GetComponentInChildren<SkinnedMeshRenderer>();
		Vector3[] vertices = componentInChildren.sharedMesh.vertices;
		Matrix4x4[] bindposes = componentInChildren.sharedMesh.bindposes;
		BoneWeight[] boneWeights = componentInChildren.sharedMesh.boneWeights;
		int[] array = new int[componentInChildren.bones.Length];
		for (int i = 0; i < array.Length; i++)
		{
			array[i] = -1;
			Transform val = componentInChildren.bones[i];
			while (Object.op_Implicit((Object)(object)val) && array[i] < 0)
			{
				for (int j = 0; j < limbs.Length; j++)
				{
					if ((Object)(object)((Component)limbs[j]).transform == (Object)(object)val)
					{
						array[i] = j;
						break;
					}
				}
				val = val.parent;
			}
		}
		Bounds[] array2 = (Bounds[])(object)new Bounds[limbs.Length];
		bool[] array3 = new bool[limbs.Length];
		for (int k = 0; k < vertices.Length; k++)
		{
			BoneWeight val2 = boneWeights[k];
			int num = ((BoneWeight)(ref val2)).boneIndex0;
			float num2 = ((BoneWeight)(ref val2)).weight0;
			if (((BoneWeight)(ref val2)).weight1 > num2)
			{
				num = ((BoneWeight)(ref val2)).boneIndex1;
				num2 = ((BoneWeight)(ref val2)).weight1;
			}
			if (((BoneWeight)(ref val2)).weight2 > num2)
			{
				num = ((BoneWeight)(ref val2)).boneIndex2;
				num2 = ((BoneWeight)(ref val2)).weight2;
			}
			if (((BoneWeight)(ref val2)).weight3 > num2)
			{
				num = ((BoneWeight)(ref val2)).boneIndex3;
			}
			int num3 = array[num];
			if (num3 >= 0)
			{
				Vector3 val3 = ((Component)limbs[num3]).transform.InverseTransformPoint(componentInChildren.bones[num].TransformPoint(((Matrix4x4)(ref bindposes[num])).MultiplyPoint3x4(vertices[k])));
				if (!array3[num3])
				{
					array2[num3] = new Bounds(val3, Vector3.zero);
					array3[num3] = true;
				}
				else
				{
					((Bounds)(ref array2[num3])).Encapsulate(val3);
				}
			}
		}
		for (int l = 0; l < limbs.Length; l++)
		{
			if (array3[l])
			{
				BoxCollider val4 = (BoxCollider)shapes[l];
				val4.center = ((Bounds)(ref array2[l])).center;
				val4.size = Vector3.Max(((Bounds)(ref array2[l])).size * 1.02f, Vector3.one * 0.03f);
			}
		}
	}

	private bool Supported()
	{
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: 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_0096: Unknown result type (might be due to invalid IL or missing references)
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_0114: Unknown result type (might be due to invalid IL or missing references)
		//IL_0119: Unknown result type (might be due to invalid IL or missing references)
		int mask = LayerMask.GetMask(new string[4] { "Default", "PhysGrabObject", "PhysGrabObjectHinge", "PhysGrabObjectCart" });
		Vector3 val = (Active ? (limbs[0].worldCenterOfMass + Vector3.up * 0.5f) : rootBody.position);
		float num = (Active ? 2.5f : (brain.bodyHeight * 0.5f + 0.18f));
		float num2 = float.MaxValue;
		PhysicsScene physicsScene = PhysicsSceneExtensions.GetPhysicsScene(((Component)this).gameObject.scene);
		int num3 = ((PhysicsScene)(ref physicsScene)).SphereCast(val, 0.12f, Vector3.down, supportHits, num, mask, (QueryTriggerInteraction)1);
		for (int i = 0; i < num3; i++)
		{
			RaycastHit val2 = supportHits[i];
			if (!((RaycastHit)(ref val2)).transform.IsChildOf(((Component)body).transform) && ((RaycastHit)(ref val2)).normal.y > 0.45f && ((RaycastHit)(ref val2)).distance < num2)
			{
				num2 = ((RaycastHit)(ref val2)).distance;
				supportPoint = ((RaycastHit)(ref val2)).point;
			}
		}
		if (num2 < float.MaxValue)
		{
			return true;
		}
		return false;
	}

	private void FixedUpdate()
	{
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Invalid comparison between Unknown and I4
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Invalid comparison between Unknown and I4
		//IL_0054: 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_01d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01da: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0221: Unknown result type (might be due to invalid IL or missing references)
		//IL_0299: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_02eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0306: Unknown result type (might be due to invalid IL or missing references)
		//IL_030b: Unknown result type (might be due to invalid IL or missing references)
		//IL_030f: Unknown result type (might be due to invalid IL or missing references)
		//IL_031e: Unknown result type (might be due to invalid IL or missing references)
		if (!initialized || !Object.op_Implicit((Object)(object)GameManager.instance) || !SemiFunc.IsMasterClientOrSingleplayer() || brain.IsDead || (int)enemy.CurrentState == 1 || (int)enemy.CurrentState == 11)
		{
			return;
		}
		bool flag = Supported();
		if (rootBody.velocity.y < -2f)
		{
			lastDownwardMotion = Time.time;
		}
		if (!Active)
		{
			if (!(Time.time < recoverUntil + 0.5f))
			{
				airborne = ((!flag && rootBody.velocity.y < 0f - fallSpeed) ? (airborne + Time.fixedDeltaTime) : 0f);
				bool flag2 = enemy.IsStunned() && (Time.time - lastDownwardMotion < 1f || Vector3.Dot(((Component)body).transform.up, Vector3.up) < 0.7f);
				if (airborne >= airborneDelay || flag2)
				{
					SetActive(value: true);
				}
			}
			return;
		}
		body.DisableFollowPosition(0.3f, 5f);
		body.DisableFollowRotation(0.3f, 5f);
		body.DisableNoGravity(0.3f);
		body.WarpDisable(0.5f);
		movement.Stop(0.3f);
		if (Object.op_Implicit((Object)(object)stun))
		{
			stun.Set(0.5f);
		}
		PhysGrabObject component = ((Component)rootBody).GetComponent<PhysGrabObject>();
		bool flag3 = Object.op_Implicit((Object)(object)component) && component.playerGrabbing.Count > 0;
		float num;
		if (flag && !flag3)
		{
			Vector3 velocity = rootBody.velocity;
			if (((Vector3)(ref velocity)).sqrMagnitude < 2.25f)
			{
				num = settled + Time.fixedDeltaTime;
				goto IL_01fd;
			}
		}
		num = 0f;
		goto IL_01fd;
		IL_01fd:
		settled = num;
		bool flag4 = flag && !flag3 && Time.time - entered > 6f && Mathf.Abs(rootBody.velocity.y) < 2.5f;
		if (!(Time.time >= nextRecoveryTry) || !((Time.time - entered > 1.2f && settled > 0.6f) || flag4))
		{
			return;
		}
		nextRecoveryTry = Time.time + 0.4f;
		if (TryFindRecoveryPosition(out var position))
		{
			movement.Warp(position, true);
			rootBody.angularVelocity = Vector3.zero;
			rootBody.velocity = Vector3.zero;
			SetActive(value: false);
			rootBody.position = position + Vector3.up * (brain.bodyHeight * 0.5f);
			Rigidbody obj = rootBody;
			Quaternion rotation = rootBody.rotation;
			obj.rotation = Quaternion.Euler(0f, ((Quaternion)(ref rotation)).eulerAngles.y, 0f);
			if (Object.op_Implicit((Object)(object)stun))
			{
				stun.Reset();
			}
			body.DisableFollowPosition(0f, 5f);
			body.DisableFollowRotation(0f, 5f);
		}
	}

	private void SetActive(bool value)
	{
		bool flag = SemiFunc.IsMasterClientOrSingleplayer();
		ApplyPhysicsState(value, flag);
		if (value && flag && Object.op_Implicit((Object)(object)stun))
		{
			stun.Set(1.5f);
		}
	}

	private void ApplyPhysicsState(bool value, bool host)
	{
		//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_0213: Unknown result type (might be due to invalid IL or missing references)
		//IL_0218: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		//IL_0283: Unknown result type (might be due to invalid IL or missing references)
		//IL_011f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0124: Unknown result type (might be due to invalid IL or missing references)
		//IL_0138: 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_0101: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: Unknown result type (might be due to invalid IL or missing references)
		//IL_017a: Unknown result type (might be due to invalid IL or missing references)
		//IL_017f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0197: Unknown result type (might be due to invalid IL or missing references)
		Initialize();
		if (Active == value)
		{
			return;
		}
		Active = value;
		if (value)
		{
			entered = Time.time;
			airborne = (settled = 0f);
			recoverUntil = (nextRecoveryTry = 0f);
			((Behaviour)animator).enabled = false;
			for (int i = 0; i < rootCapsules.Length; i++)
			{
				rootCapsules[i].center = ((Component)rootCapsules[i]).transform.InverseTransformPoint(limbs[0].position);
				rootCapsules[i].radius = 0.22f;
				rootCapsules[i].height = 0.44f;
			}
			for (int j = 0; j < limbs.Length; j++)
			{
				((Joint)joints[j]).connectedBody = (host ? connections[j] : null);
				if (host)
				{
					((Joint)joints[j]).connectedAnchor = ((Component)connections[j]).transform.InverseTransformPoint(limbs[j].position);
				}
				receivedPositions[j] = limbs[j].position;
				receivedRotations[j] = limbs[j].rotation;
				shapes[j].enabled = host;
				limbs[j].isKinematic = !host;
				if (host)
				{
					limbs[j].velocity = rootBody.GetPointVelocity(limbs[j].position);
					limbs[j].angularVelocity = rootBody.angularVelocity;
				}
			}
			Debug.Log((object)"Luigi fall ragdoll activated: 13 physical limbs.");
		}
		else
		{
			lastDownwardMotion = -100f;
			airborne = (settled = 0f);
			for (int k = 0; k < limbs.Length; k++)
			{
				recoverPositions[k] = ((Component)limbs[k]).transform.localPosition;
				recoverRotations[k] = ((Component)limbs[k]).transform.localRotation;
				shapes[k].enabled = false;
				limbs[k].isKinematic = true;
				((Joint)joints[k]).connectedBody = null;
			}
			((Behaviour)animator).enabled = true;
			animator.Rebind();
			for (int l = 0; l < rootCapsules.Length; l++)
			{
				rootCapsules[l].center = capsuleCenters[l];
				rootCapsules[l].radius = capsuleRadii[l];
				rootCapsules[l].height = capsuleHeights[l];
			}
			recoverUntil = Time.time + 0.4f;
		}
	}

	private void LateUpdate()
	{
		//IL_004b: 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)
		//IL_006a: 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_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ea: 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_0103: Unknown result type (might be due to invalid IL or missing references)
		//IL_010a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0110: Unknown result type (might be due to invalid IL or missing references)
		if (!initialized)
		{
			return;
		}
		if (Active && !SemiFunc.IsMasterClientOrSingleplayer())
		{
			float num = 1f - Mathf.Exp(-25f * Time.deltaTime);
			for (int i = 0; i < limbs.Length; i++)
			{
				((Component)limbs[i]).transform.SetPositionAndRotation(Vector3.Lerp(limbs[i].position, receivedPositions[i], num), Quaternion.Slerp(limbs[i].rotation, receivedRotations[i], num));
			}
		}
		else if (!Active && recoverUntil > Time.time)
		{
			float num2 = 1f - (recoverUntil - Time.time) / 0.4f;
			for (int j = 0; j < limbs.Length; j++)
			{
				Transform transform = ((Component)limbs[j]).transform;
				transform.localPosition = Vector3.Lerp(recoverPositions[j], transform.localPosition, num2);
				transform.localRotation = Quaternion.Slerp(recoverRotations[j], transform.localRotation, num2);
			}
		}
	}

	public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
	{
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: 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)
		Initialize();
		if (stream.IsWriting)
		{
			stream.SendNext((object)Active);
			if (Active)
			{
				Rigidbody[] array = limbs;
				foreach (Rigidbody val in array)
				{
					stream.SendNext((object)val.position);
					stream.SendNext((object)val.rotation);
				}
			}
			return;
		}
		SetActive((bool)stream.ReceiveNext());
		if (Active)
		{
			for (int j = 0; j < limbs.Length; j++)
			{
				receivedPositions[j] = (Vector3)stream.ReceiveNext();
				receivedRotations[j] = (Quaternion)stream.ReceiveNext();
			}
		}
	}

	private void OnDisable()
	{
		if (initialized && Active)
		{
			SetActive(value: false);
		}
		airborne = (settled = 0f);
	}

	static LuigiFallRagdoll()
	{
		HumanBodyBones[] array = new HumanBodyBones[13];
		RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
		Bones = (HumanBodyBones[])(object)array;
		HumanBodyBones[] array2 = new HumanBodyBones[13];
		RuntimeHelpers.InitializeArray(array2, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
		Ends = (HumanBodyBones[])(object)array2;
		Parents = new int[13]
		{
			-1, 0, 1, 1, 3, 1, 5, 0, 7, 8,
			0, 10, 11
		};
	}
}
public sealed class LuigiShellProjectile : MonoBehaviour
{
	public const float Radius = 0.22f;

	public int Id;

	private Transform owner;

	private Vector3 velocity;

	private bool authority;

	private float age;

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

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

	public bool Finished { get; private set; }

	public static LuigiShellProjectile Create(Transform owner, Vector3 position, Vector3 velocity, bool authority, GameObject visualPrefab = null)
	{
		//IL_002b: 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_0050: 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_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = (Object.op_Implicit((Object)(object)visualPrefab) ? Object.Instantiate<GameObject>(visualPrefab) : GameObject.CreatePrimitive((PrimitiveType)0));
		((Object)val).name = "Luigi Green Shell";
		SceneManager.MoveGameObjectToScene(val, ((Component)owner).gameObject.scene);
		val.transform.position = position;
		if (!Object.op_Implicit((Object)(object)visualPrefab))
		{
			val.transform.localScale = Vector3.one * 0.44f;
		}
		Collider[] componentsInChildren = val.GetComponentsInChildren<Collider>(true);
		for (int i = 0; i < componentsInChildren.Length; i++)
		{
			componentsInChildren[i].enabled = false;
		}
		LuigiShellProjectile luigiShellProjectile = val.AddComponent<LuigiShellProjectile>();
		luigiShellProjectile.owner = owner;
		luigiShellProjectile.velocity = velocity;
		luigiShellProjectile.authority = authority;
		return luigiShellProjectile;
	}

	private bool Ignore(Collider collider)
	{
		if (!((Component)collider).transform.IsChildOf(owner) && !Object.op_Implicit((Object)(object)((Component)collider).GetComponent<LuigiShellProjectile>()))
		{
			if (collider.isTrigger && !Object.op_Implicit((Object)(object)((Component)collider).GetComponentInParent<PlayerAvatar>()))
			{
				return !Object.op_Implicit((Object)(object)((Component)collider).GetComponentInParent<PlayerController>());
			}
			return false;
		}
		return true;
	}

	private void FixedUpdate()
	{
		if (authority)
		{
			SimulateStep(Time.fixedDeltaTime);
		}
	}

	private void Update()
	{
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		if (!Finished)
		{
			((Component)this).transform.Rotate(Vector3.up, 720f * Time.deltaTime, (Space)0);
		}
	}

	private void SimulateStep(float dt)
	{
		//IL_006e: 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_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_0101: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: Unknown result type (might be due to invalid IL or missing references)
		//IL_0110: 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_0135: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0178: Unknown result type (might be due to invalid IL or missing references)
		//IL_017d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0222: Unknown result type (might be due to invalid IL or missing references)
		//IL_0229: Unknown result type (might be due to invalid IL or missing references)
		//IL_0233: Unknown result type (might be due to invalid IL or missing references)
		//IL_0238: Unknown result type (might be due to invalid IL or missing references)
		//IL_0244: Unknown result type (might be due to invalid IL or missing references)
		//IL_024b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0250: Unknown result type (might be due to invalid IL or missing references)
		//IL_0255: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
		if (Finished)
		{
			return;
		}
		age += dt;
		if (age >= 8f)
		{
			Finished = true;
			return;
		}
		int mask = LayerMask.GetMask(new string[6] { "Default", "PhysGrabObject", "PhysGrabObjectHinge", "PhysGrabObjectCart", "Player", "PlayerOnlyCollision" });
		PhysicsScene physicsScene = PhysicsSceneExtensions.GetPhysicsScene(((Component)this).gameObject.scene);
		int num = ((PhysicsScene)(ref physicsScene)).OverlapSphere(((Component)this).transform.position, 0.20899999f, overlaps, mask, (QueryTriggerInteraction)2);
		if (num == overlaps.Length)
		{
			Finished = true;
			return;
		}
		for (int i = 0; i < num; i++)
		{
			if (!Ignore(overlaps[i]))
			{
				HitPlayer(overlaps[i]);
				Finished = true;
				return;
			}
		}
		float num2 = ((Vector3)(ref velocity)).magnitude * dt;
		for (int j = 0; j < 6; j++)
		{
			if (!(num2 > 0.001f))
			{
				break;
			}
			Vector3 normalized = ((Vector3)(ref velocity)).normalized;
			int num3 = ((PhysicsScene)(ref physicsScene)).SphereCast(((Component)this).transform.position, 0.22f, normalized, hits, num2, mask, (QueryTriggerInteraction)2);
			float num4 = float.MaxValue;
			RaycastHit val = default(RaycastHit);
			for (int k = 0; k < num3; k++)
			{
				if (!Ignore(((RaycastHit)(ref hits[k])).collider) && ((RaycastHit)(ref hits[k])).distance < num4)
				{
					val = hits[k];
					num4 = ((RaycastHit)(ref val)).distance;
				}
			}
			if (num4 == float.MaxValue)
			{
				if (num3 == hits.Length)
				{
					Finished = true;
					break;
				}
				Transform transform = ((Component)this).transform;
				transform.position += normalized * num2;
				break;
			}
			Transform transform2 = ((Component)this).transform;
			transform2.position += normalized * Mathf.Max(0f, num4 - 0.005f);
			if (HitPlayer(((RaycastHit)(ref val)).collider))
			{
				Finished = true;
				break;
			}
			num2 -= num4;
			Transform transform3 = ((Component)this).transform;
			transform3.position += ((RaycastHit)(ref val)).normal * 0.01f;
			velocity = Vector3.Reflect(velocity, ((RaycastHit)(ref val)).normal);
		}
	}

	private bool HitPlayer(Collider collider)
	{
		//IL_008a: 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_00bc: 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_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_00f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
		PlayerAvatar player = ((Component)collider).GetComponentInParent<PlayerAvatar>();
		if (!Object.op_Implicit((Object)(object)player) && Object.op_Implicit((Object)(object)((Component)collider).GetComponentInParent<PlayerController>()))
		{
			player = Object.FindObjectsOfType<PlayerAvatar>().OrderBy(delegate(PlayerAvatar p)
			{
				//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_0016: 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)
				Vector3 position = ((Component)p).transform.position;
				Bounds bounds = collider.bounds;
				return Vector3.SqrMagnitude(position - ((Bounds)(ref bounds)).center);
			}).FirstOrDefault();
		}
		if (!Object.op_Implicit((Object)(object)player))
		{
			return false;
		}
		PlayerHealth component = ((Component)player).GetComponent<PlayerHealth>();
		if (Object.op_Implicit((Object)(object)component))
		{
			component.HurtOther(25, ((Component)this).transform.position, false, -1, false);
		}
		PlayerTumble val = ((IEnumerable<PlayerTumble>)Object.FindObjectsOfType<PlayerTumble>()).FirstOrDefault((Func<PlayerTumble, bool>)((PlayerTumble t) => (Object)(object)t.playerAvatar == (Object)(object)player));
		if (Object.op_Implicit((Object)(object)val))
		{
			Vector3 val2 = velocity;
			val2.y = 0f;
			val.TumbleRequest(true, false);
			val.TumbleOverrideTime(0.8f);
			val.TumbleForce(((Vector3)(ref val2)).normalized * 14f + Vector3.up * 6f);
		}
		return true;
	}
}