Decompiled source of Weeping Angel Renewed v1.1.0

EmpressWeepingAngel.dll

Decompiled 17 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Omniscye.Empress.WeepingAngel;
using Photon.Pun;
using REPOLib.Modules;
using REPOLib.Objects.Sdk;
using UnityEngine;
using UnityEngine.AI;

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

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
public sealed class EmpressAngelBrain : MonoBehaviourPunCallbacks
{
	private enum EmpressState
	{
		Sleeping,
		Spawning,
		Holding,
		Roaming,
		Pursuing,
		Striking
	}

	private const float SpawnRecoverDuration = 1.25f;

	private const float HoldGraceDuration = 0.16f;

	private const float RoamSpeed = 3.2f;

	private const float RoamAcceleration = 14f;

	private const float HuntSpeed = 5.25f;

	private const float HuntAcceleration = 22f;

	private const float AttackDistance = 1.9f;

	private const float AttackResolveDelay = 0.18f;

	private const float AttackDuration = 0.52f;

	private const float RoamRefreshDelay = 3.4f;

	private const float RepathDelay = 0.2f;

	private Enemy enemy;

	private EnemyParent enemyParent;

	private EnemyNavMeshAgent? navMeshAgent;

	private EnemyOnScreen? onScreen;

	private EnemyHealth? enemyHealth;

	private EnemyRigidbody? enemyRigidbody;

	private EmpressAngelController? compatibility;

	private EmpressState state;

	private float stateTimer;

	private float holdTimer;

	private float repathTimer;

	private Vector3 roamDestination;

	private int targetViewId = -1;

	private void Awake()
	{
		enemy = ((Component)this).GetComponent<Enemy>();
		enemyParent = ((Component)this).GetComponentInParent<EnemyParent>();
		navMeshAgent = (enemy.HasNavMeshAgent ? enemy.NavMeshAgent : ((Component)this).GetComponent<EnemyNavMeshAgent>());
		onScreen = (enemy.HasOnScreen ? enemy.OnScreen : ((Component)this).GetComponent<EnemyOnScreen>());
		enemyHealth = (enemy.HasHealth ? enemy.Health : ((Component)this).GetComponent<EnemyHealth>());
		enemyRigidbody = (enemy.HasRigidbody ? enemy.Rigidbody : ((Component)this).GetComponentInChildren<EnemyRigidbody>(true));
		compatibility = ((Component)this).GetComponent<EmpressAngelController>();
		ResetState(EmpressState.Sleeping, 0f);
	}

	public void HandleSpawn()
	{
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		ResetState(EmpressState.Spawning, 1.25f);
		targetViewId = -1;
		roamDestination = GetBodyPosition();
		SyncEnemyTarget(null);
		SyncNavAgentToBody(forceWarp: true);
		StopAgent(0.2f);
	}

	public void HandleVision(PlayerAvatar? player)
	{
		if (!((Object)(object)player == (Object)null) && !player.isDisabled)
		{
			targetViewId = player.photonView.ViewID;
			stateTimer = Mathf.Max(stateTimer, 1.2f);
			if (state != EmpressState.Striking)
			{
				ResetState(EmpressState.Pursuing, stateTimer);
			}
		}
	}

	public void HandleInvestigate(Vector3 position)
	{
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		if (state != EmpressState.Pursuing && state != EmpressState.Striking)
		{
			roamDestination = ProjectToNav(position);
			ResetState(EmpressState.Roaming, 3.4f);
		}
	}

	public void HandleDeath()
	{
		ResetState(EmpressState.Sleeping, 0f);
		StopAgent(0.5f);
	}

	public void HandleDespawn()
	{
		ResetState(EmpressState.Sleeping, 0f);
		targetViewId = -1;
		SyncEnemyTarget(null);
	}

	public void Update()
	{
		if ((Object)(object)enemyParent == (Object)null || (Object)(object)enemy == (Object)null || !HasAuthority())
		{
			return;
		}
		if (!IsActive())
		{
			if (state != 0)
			{
				HandleDespawn();
			}
			return;
		}
		if ((Object)(object)enemyHealth != (Object)null && (enemyHealth.dead || enemyHealth.deadImpulse))
		{
			HandleDeath();
			return;
		}
		if (IsObserved())
		{
			holdTimer = 0.16f;
		}
		else if (holdTimer > 0f)
		{
			holdTimer -= Time.deltaTime;
		}
		if (state == EmpressState.Spawning)
		{
			stateTimer -= Time.deltaTime;
			StopAgent(0.1f);
			if (stateTimer <= 0f)
			{
				ResetState(EmpressState.Roaming, 3.4f);
			}
			return;
		}
		if (enemy.IsStunned() || enemy.FreezeTimer > 0f || holdTimer > 0f)
		{
			HoldPosition();
			return;
		}
		PlayerAvatar val = ResolveTarget();
		if (state == EmpressState.Striking)
		{
			UpdateStrike(val);
		}
		else if ((Object)(object)val != (Object)null)
		{
			UpdatePursuit(val);
		}
		else
		{
			UpdateRoam();
		}
	}

	private void UpdatePursuit(PlayerAvatar target)
	{
		//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_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_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)
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: 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_006e: Unknown result type (might be due to invalid IL or missing references)
		SyncEnemyTarget(target);
		enemyParent.SpawnedTimerPause(3f);
		enemy.SetChaseTimer();
		Vector3 targetNavPoint = GetTargetNavPoint(target);
		Vector3 targetLookPoint = GetTargetLookPoint(target);
		if (Vector3.Distance(GetBodyPosition(), targetNavPoint) <= 1.9f)
		{
			BeginStrike(target);
			return;
		}
		ResetState(EmpressState.Pursuing, 5f);
		Vector3 travelPoint = GetTravelPoint(targetNavPoint);
		RotateMotionAnchor(targetLookPoint, 13f);
		DriveAgent(travelPoint, 5.25f, 22f, 0.24f, 5f, 30f);
		if ((Object)(object)enemyRigidbody != (Object)null && enemyRigidbody.notMovingTimer > 2.5f)
		{
			SyncNavAgentToBody(forceWarp: true);
			repathTimer = 0f;
		}
	}

	private void UpdateRoam()
	{
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		SyncEnemyTarget(null);
		stateTimer -= Time.deltaTime;
		if (state != EmpressState.Roaming || stateTimer <= 0f || Vector3.Distance(GetBodyPosition(), roamDestination) < 1.8f)
		{
			RefreshRoamDestination();
			ResetState(EmpressState.Roaming, 3.4f);
		}
		RotateMotionAnchor(roamDestination, 9f);
		DriveAgent(roamDestination, 3.2f, 14f, 0.22f, 3.2f, 18f);
	}

	private void BeginStrike(PlayerAvatar target)
	{
		ResetState(EmpressState.Striking, 0.52f);
		SyncEnemyTarget(target);
		StopAgent(0.08f);
		compatibility?.TriggerAttackImpulse();
	}

	private void UpdateStrike(PlayerAvatar? target)
	{
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_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)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d7: 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)
		stateTimer -= Time.deltaTime;
		if ((Object)(object)target == (Object)null || target.isDisabled)
		{
			ResetState(EmpressState.Roaming, 0.25f);
			return;
		}
		Vector3 targetNavPoint = GetTargetNavPoint(target);
		Vector3 targetLookPoint = GetTargetLookPoint(target);
		RotateMotionAnchor(targetLookPoint, 18f);
		if ((Object)(object)enemyRigidbody != (Object)null)
		{
			enemyRigidbody.OverrideFollowPosition(0.16f, 8f, 40f);
			enemyRigidbody.OverrideFollowRotation(0.16f, 8f);
		}
		Transform motionAnchor = GetMotionAnchor();
		Vector3 val = targetNavPoint;
		Vector3 val2 = val - motionAnchor.position;
		if (((Vector3)(ref val2)).sqrMagnitude > 0.01f)
		{
			motionAnchor.position = Vector3.MoveTowards(motionAnchor.position, val - ((Vector3)(ref val2)).normalized * 0.35f, 8f * Time.deltaTime);
		}
		if (stateTimer <= 0.33999997f && Vector3.Distance(GetBodyPosition(), targetNavPoint) <= 2.1f)
		{
			KillTarget(target);
			ResetState(EmpressState.Roaming, 0.4f);
		}
		else if (stateTimer <= 0f)
		{
			ResetState(EmpressState.Pursuing, 0.65f);
		}
	}

	private void HoldPosition()
	{
		ResetState(EmpressState.Holding, Mathf.Max(stateTimer, 0.1f));
		StopAgent(0.15f);
		SyncNavAgentToBody(forceWarp: false);
	}

	private void DriveAgent(Vector3 point, float speed, float acceleration, float followTime, float followSpeed, float followLerp)
	{
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)navMeshAgent != (Object)null)
		{
			navMeshAgent.Enable();
			navMeshAgent.Stop(0f);
			SyncNavAgentToBody(forceWarp: false);
			navMeshAgent.UpdateAgent(speed, acceleration);
			repathTimer -= Time.deltaTime;
			if (repathTimer <= 0f || Vector3.Distance(navMeshAgent.GetDestination(), point) > 1f)
			{
				navMeshAgent.SetDestination(point);
				repathTimer = 0.2f;
			}
		}
		else
		{
			Transform motionAnchor = GetMotionAnchor();
			motionAnchor.position = Vector3.MoveTowards(motionAnchor.position, point, speed * Time.deltaTime);
		}
		if ((Object)(object)enemyRigidbody != (Object)null)
		{
			enemyRigidbody.OverrideFollowPosition(followTime, followSpeed, followLerp);
			enemyRigidbody.OverrideFollowRotation(followTime, followSpeed);
		}
	}

	private void StopAgent(float time)
	{
		if ((Object)(object)navMeshAgent != (Object)null)
		{
			navMeshAgent.Stop(time);
		}
	}

	private void SyncNavAgentToBody(bool forceWarp)
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: 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)
		if (!((Object)(object)navMeshAgent == (Object)null))
		{
			Vector3 bodyPosition = GetBodyPosition();
			if (forceWarp || Vector3.Distance(((Component)navMeshAgent).transform.position, bodyPosition) > 0.75f)
			{
				navMeshAgent.Warp(bodyPosition, true);
			}
		}
	}

	private void RotateMotionAnchor(Vector3 point, float speed)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0009: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		Transform motionAnchor = GetMotionAnchor();
		Vector3 val = point - motionAnchor.position;
		val.y = 0f;
		if (!(((Vector3)(ref val)).sqrMagnitude <= 0.001f))
		{
			Quaternion val2 = Quaternion.LookRotation(((Vector3)(ref val)).normalized, Vector3.up);
			motionAnchor.rotation = Quaternion.Slerp(motionAnchor.rotation, val2, speed * Time.deltaTime);
		}
	}

	private void RefreshRoamDestination()
	{
		//IL_001e: 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_0023: 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_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: 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)
		PlayerAvatar val = FindNearestPlayer();
		Vector3 val2 = (((Object)(object)val != (Object)null) ? val.playerTransform.position : GetBodyPosition());
		LevelPoint val3 = SemiFunc.LevelPointGet(val2, 5f, 14f);
		if (!Object.op_Implicit((Object)(object)val3))
		{
			val3 = SemiFunc.LevelPointGet(val2, 0f, 999f);
		}
		if (Object.op_Implicit((Object)(object)val3))
		{
			roamDestination = ProjectToNav(((Component)val3).transform.position + Random.insideUnitSphere * 3f);
		}
		else
		{
			roamDestination = ProjectToNav(val2);
		}
	}

	private Vector3 GetTravelPoint(Vector3 chasePoint)
	{
		//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_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		if (Vector3.Distance(GetBodyPosition(), chasePoint) <= 6f)
		{
			return chasePoint;
		}
		LevelPoint levelPointAhead = enemy.GetLevelPointAhead(chasePoint);
		if (Object.op_Implicit((Object)(object)levelPointAhead))
		{
			return ProjectToNav(((Component)levelPointAhead).transform.position);
		}
		return chasePoint;
	}

	private void KillTarget(PlayerAvatar target)
	{
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		if (!target.isDisabled && !((Object)(object)target.playerHealth == (Object)null))
		{
			int num = Mathf.Max(target.playerHealth.maxHealth + 25, 150);
			target.playerHealth.HurtOther(num, ((Component)target).transform.position, false, -1);
			enemyParent.SpawnedTimerPause(2f);
		}
	}

	private PlayerAvatar? ResolveTarget()
	{
		PlayerAvatar val = FindPlayerByViewId(targetViewId);
		if (IsValidTarget(val))
		{
			return val;
		}
		PlayerAvatar val2 = FindNearestPlayer();
		targetViewId = (((Object)(object)val2 != (Object)null) ? val2.photonView.ViewID : (-1));
		return val2;
	}

	private PlayerAvatar? FindNearestPlayer()
	{
		//IL_0009: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		PlayerAvatar result = null;
		float num = float.MaxValue;
		Vector3 bodyPosition = GetBodyPosition();
		foreach (PlayerAvatar item in SemiFunc.PlayerGetList())
		{
			if (IsValidTarget(item))
			{
				float num2 = Vector3.Distance(bodyPosition, GetTargetNavPoint(item));
				if (num2 < num)
				{
					num = num2;
					result = item;
				}
			}
		}
		return result;
	}

	private PlayerAvatar? FindPlayerByViewId(int viewId)
	{
		if (viewId <= 0)
		{
			return null;
		}
		foreach (PlayerAvatar item in SemiFunc.PlayerGetList())
		{
			if ((Object)(object)item != (Object)null && (Object)(object)item.photonView != (Object)null && item.photonView.ViewID == viewId)
			{
				return item;
			}
		}
		return null;
	}

	private static bool IsValidTarget(PlayerAvatar? player)
	{
		if ((Object)(object)player != (Object)null && !player.isDisabled && (Object)(object)player.photonView != (Object)null && (Object)(object)player.playerHealth != (Object)null)
		{
			return (Object)(object)player.playerTransform != (Object)null;
		}
		return false;
	}

	private bool IsObserved()
	{
		//IL_0077: 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_0087: 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_00ab: 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_00c4: 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)
		if ((Object)(object)onScreen != (Object)null)
		{
			if (onScreen.OnScreenAny)
			{
				return !onScreen.CulledAny;
			}
			return false;
		}
		RaycastHit val3 = default(RaycastHit);
		foreach (PlayerAvatar item in SemiFunc.PlayerGetList())
		{
			if (IsValidTarget(item))
			{
				Transform val = (((Object)(object)item.PlayerVisionTarget != (Object)null) ? item.PlayerVisionTarget.VisionTransform : ((Component)item).transform);
				Vector3 val2 = ((Component)this).transform.position - val.position;
				float magnitude = ((Vector3)(ref val2)).magnitude;
				if (!(magnitude > 28f) && !(magnitude <= 0.01f) && !(Vector3.Dot(val.forward, ((Vector3)(ref val2)).normalized) < 0.55f) && (!Physics.Raycast(val.position, ((Vector3)(ref val2)).normalized, ref val3, magnitude, LayerMask.op_Implicit(enemy.VisionMask), (QueryTriggerInteraction)1) || ((RaycastHit)(ref val3)).transform.IsChildOf(((Component)this).transform)))
				{
					return true;
				}
			}
		}
		return false;
	}

	private Vector3 GetTargetNavPoint(PlayerAvatar player)
	{
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: 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_0023: Unknown result type (might be due to invalid IL or missing references)
		Vector3 point = ((player.LastNavMeshPositionTimer <= 0.4f) ? player.LastNavmeshPosition : ((Component)player).transform.position);
		return ProjectToNav(point);
	}

	private Vector3 GetTargetLookPoint(PlayerAvatar player)
	{
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)player.PlayerVisionTarget != (Object)null && (Object)(object)player.PlayerVisionTarget.VisionTransform != (Object)null)
		{
			return player.PlayerVisionTarget.VisionTransform.position;
		}
		return ((Component)player).transform.position + Vector3.up * 1.1f;
	}

	private Vector3 ProjectToNav(Vector3 point)
	{
		//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_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: 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)
		RaycastHit val = default(RaycastHit);
		if (Physics.Raycast(point + Vector3.up, Vector3.down, ref val, 4f, LayerMask.GetMask(new string[3] { "Default", "NavmeshOnly", "PlayerOnlyCollision" }), (QueryTriggerInteraction)1))
		{
			point = ((RaycastHit)(ref val)).point;
		}
		NavMeshHit val2 = default(NavMeshHit);
		if (NavMesh.SamplePosition(point, ref val2, 3f, -1))
		{
			return ((NavMeshHit)(ref val2)).position;
		}
		return point;
	}

	private void SyncEnemyTarget(PlayerAvatar? target)
	{
		enemy.TargetPlayerAvatar = target;
		enemy.TargetPlayerViewID = (((Object)(object)target != (Object)null && (Object)(object)target.photonView != (Object)null) ? target.photonView.ViewID : (-1));
	}

	private Vector3 GetBodyPosition()
	{
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)enemyRigidbody != (Object)null))
		{
			return ((Component)this).transform.position;
		}
		return ((Component)enemyRigidbody).transform.position;
	}

	private Transform GetMotionAnchor()
	{
		if ((Object)(object)enemyRigidbody != (Object)null && (Object)(object)enemyRigidbody.followTarget != (Object)null)
		{
			return enemyRigidbody.followTarget;
		}
		return ((Component)this).transform;
	}

	private bool HasAuthority()
	{
		if (GameManager.Multiplayer())
		{
			return PhotonNetwork.IsMasterClient;
		}
		return true;
	}

	private bool IsActive()
	{
		if (enemyParent.Spawned && (Object)(object)enemyParent.EnableObject != (Object)null)
		{
			return enemyParent.EnableObject.activeInHierarchy;
		}
		return false;
	}

	private void ResetState(EmpressState nextState, float timer)
	{
		state = nextState;
		stateTimer = timer;
	}
}
public sealed class EmpressAngelVisuals : MonoBehaviour
{
	private Animator[] animators = Array.Empty<Animator>();

	private Transform visualRoot;

	private Vector3 visualBasePosition;

	private Quaternion visualBaseRotation;

	private bool frozen;

	private bool attackPose;

	private bool closePose;

	private bool previousAttackPose;

	private float motionBlend;

	private float motionTime;

	private float lungeTime;

	private void Awake()
	{
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		animators = ((Component)this).GetComponentsInChildren<Animator>(true);
		Animator[] array = animators;
		foreach (Animator obj in array)
		{
			obj.keepAnimatorStateOnDisable = true;
			obj.applyRootMotion = false;
		}
		visualRoot = FindVisualRoot();
		visualBasePosition = visualRoot.localPosition;
		visualBaseRotation = visualRoot.localRotation;
	}

	private void LateUpdate()
	{
		//IL_0067: 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_00f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: Unknown result type (might be due to invalid IL or missing references)
		//IL_010b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0110: Unknown result type (might be due to invalid IL or missing references)
		//IL_0130: Unknown result type (might be due to invalid IL or missing references)
		//IL_0135: Unknown result type (might be due to invalid IL or missing references)
		//IL_013e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0143: Unknown result type (might be due to invalid IL or missing references)
		//IL_0144: Unknown result type (might be due to invalid IL or missing references)
		//IL_0155: Unknown result type (might be due to invalid IL or missing references)
		//IL_015a: Unknown result type (might be due to invalid IL or missing references)
		//IL_015c: Unknown result type (might be due to invalid IL or missing references)
		motionTime += Time.deltaTime * Mathf.Lerp(0.4f, 2.2f, motionBlend);
		lungeTime = Mathf.MoveTowards(lungeTime, attackPose ? 1f : 0f, Time.deltaTime * 4.8f);
		if (frozen)
		{
			visualRoot.localPosition = visualBasePosition;
			visualRoot.localRotation = visualBaseRotation;
			return;
		}
		float num = Mathf.Sin(motionTime * 5.2f) * 0.012f * motionBlend;
		float num2 = Mathf.Sin(motionTime * 2.7f) * 2.1f * motionBlend;
		float num3 = (closePose ? 0.018f : 0f);
		Vector3 val = new Vector3(0f, num3 + Mathf.Abs(num) * 0.35f, num * 1.4f) + Vector3.forward * (lungeTime * 0.18f);
		Quaternion val2 = Quaternion.Euler(lungeTime * -8f, 0f, num2 + lungeTime * 3.5f);
		visualRoot.localPosition = visualBasePosition + val;
		visualRoot.localRotation = visualBaseRotation * val2;
	}

	public void ApplyState(bool isFrozen, bool isAttacking, bool isClose, float moveAmount)
	{
		frozen = isFrozen;
		attackPose = isAttacking;
		closePose = isClose;
		motionBlend = Mathf.Clamp01(moveAmount);
		Animator[] array = animators;
		foreach (Animator val in array)
		{
			if (!((Object)(object)val == (Object)null))
			{
				val.speed = (frozen ? 0f : 1f);
				if (HasBool(val, "IsClose"))
				{
					val.SetBool("IsClose", isClose);
				}
				if (isAttacking && !previousAttackPose && HasTrigger(val, "Attack"))
				{
					val.SetTrigger("Attack");
				}
			}
		}
		previousAttackPose = isAttacking;
	}

	private Transform FindVisualRoot()
	{
		Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>(true);
		Transform result = ((Component)this).transform;
		int num = int.MaxValue;
		Renderer[] array = componentsInChildren;
		for (int i = 0; i < array.Length; i++)
		{
			Transform val = ((Component)array[i]).transform;
			while ((Object)(object)val.parent != (Object)null && (Object)(object)val.parent != (Object)(object)((Component)this).transform)
			{
				val = val.parent;
			}
			int num2 = Depth(val);
			if (num2 < num)
			{
				num = num2;
				result = val;
			}
		}
		return result;
	}

	private static int Depth(Transform transform)
	{
		int num = 0;
		Transform val = transform;
		while ((Object)(object)val.parent != (Object)null)
		{
			num++;
			val = val.parent;
		}
		return num;
	}

	private static bool HasBool(Animator animator, string name)
	{
		string name2 = name;
		return animator.parameters.Any((AnimatorControllerParameter parameter) => parameter.name == name2 && (int)parameter.type == 4);
	}

	private static bool HasTrigger(Animator animator, string name)
	{
		string name2 = name;
		return animator.parameters.Any((AnimatorControllerParameter parameter) => parameter.name == name2 && (int)parameter.type == 9);
	}
}
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInPlugin("Omniscye.EmpressWeepingAngel", "Empress Weeping Angel", "1.0.0")]
public sealed class EmpressWeepingAngelPlugin : BaseUnityPlugin
{
	public const string PluginGuid = "Omniscye.EmpressWeepingAngel";

	public const string PluginName = "Empress Weeping Angel";

	public const string PluginVersion = "1.0.0";

	private static readonly FieldInfo SetupField = AccessTools.Field(typeof(EnemyContent), "_setup");

	private static readonly FieldInfo SpawnObjectsField = AccessTools.Field(typeof(EnemyContent), "_spawnObjects");

	private AssetBundle? loadedBundle;

	private EnemyContent? enemyContent;

	private EnemySetup? runtimeSetup;

	internal static EmpressWeepingAngelPlugin Instance { get; private set; } = null;


	internal static ManualLogSource Log => ((BaseUnityPlugin)Instance).Logger;

	private void Awake()
	{
		Instance = this;
		((Component)this).transform.parent = null;
		((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
		Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
		RegisterEmpressAngel();
	}

	private void RegisterEmpressAngel()
	{
		string text = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location) ?? string.Empty, "angel");
		if (!File.Exists(text))
		{
			((BaseUnityPlugin)this).Logger.LogError((object)"Empress angel bundle was not found next to the plugin DLL.");
			return;
		}
		loadedBundle = AssetBundle.LoadFromFile(text);
		if ((Object)(object)loadedBundle == (Object)null)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)"Empress angel bundle failed to load.");
			return;
		}
		((Object)loadedBundle).hideFlags = (HideFlags)61;
		EnemySetup[] array = loadedBundle.LoadAllAssets<EnemySetup>();
		GameObject[] array2 = loadedBundle.LoadAllAssets<GameObject>();
		((BaseUnityPlugin)this).Logger.LogInfo((object)$"Empress bundle loaded with {array.Length} enemy setups and {array2.Length} prefabs.");
		List<GameObject> list = array2.Where(IsEnemyPrefab).ToList();
		if (list.Count == 0)
		{
			string text2 = string.Join(", ", loadedBundle.GetAllAssetNames());
			((BaseUnityPlugin)this).Logger.LogError((object)("No enemy prefabs were discovered in the angel bundle. Assets: " + text2));
			return;
		}
		for (int i = 0; i < list.Count; i++)
		{
			PrepareEnemyPrefab(list[i], i);
		}
		runtimeSetup = BuildRuntimeSetup(array);
		((Object)runtimeSetup).hideFlags = (HideFlags)61;
		((Object)runtimeSetup).name = "Enemy - Empress Angel";
		runtimeSetup.spawnObjects = new List<PrefabRef>();
		enemyContent = ScriptableObject.CreateInstance<EnemyContent>();
		((Object)enemyContent).hideFlags = (HideFlags)61;
		((Object)enemyContent).name = "EnemyContentEmpressAngel";
		SetupField.SetValue(enemyContent, runtimeSetup);
		SpawnObjectsField.SetValue(enemyContent, list);
		Enemies.RegisterEnemy(enemyContent);
		((BaseUnityPlugin)this).Logger.LogInfo((object)$"Empress angel registered with {list.Count} spawn object(s).");
	}

	private static bool IsEnemyPrefab(GameObject prefab)
	{
		if ((Object)(object)prefab == (Object)null)
		{
			return false;
		}
		EnemyParent componentInChildren = prefab.GetComponentInChildren<EnemyParent>(true);
		Enemy componentInChildren2 = prefab.GetComponentInChildren<Enemy>(true);
		PhotonView componentInChildren3 = prefab.GetComponentInChildren<PhotonView>(true);
		if ((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren2 != (Object)null)
		{
			return (Object)(object)componentInChildren3 != (Object)null;
		}
		return false;
	}

	private EnemySetup BuildRuntimeSetup(IReadOnlyList<EnemySetup> bundleSetups)
	{
		EnemySetup val = ((IEnumerable<EnemySetup>)bundleSetups).FirstOrDefault((Func<EnemySetup, bool>)((EnemySetup setup) => (Object)(object)setup != (Object)null)) ?? CreateFallbackSetup();
		EnemySetup val2 = (EnemySetup)(((Object)(object)val == (Object)null) ? ((object)CreateFallbackSetup()) : ((object)Object.Instantiate<EnemySetup>(val)));
		if ((Object)(object)val2.rarityPreset == (Object)null)
		{
			RarityPreset val3 = ScriptableObject.CreateInstance<RarityPreset>();
			((Object)val3).hideFlags = (HideFlags)61;
			((Object)val3).name = "Rarity - Empress Angel";
			val3.chance = 14f;
			val2.rarityPreset = val3;
		}
		return val2;
	}

	private static EnemySetup CreateFallbackSetup()
	{
		EnemySetup obj = ScriptableObject.CreateInstance<EnemySetup>();
		((Object)obj).hideFlags = (HideFlags)61;
		obj.levelsCompletedCondition = false;
		obj.levelsCompletedMin = 0;
		obj.levelsCompletedMax = 10;
		obj.runsPlayed = 0;
		RarityPreset val = ScriptableObject.CreateInstance<RarityPreset>();
		((Object)val).hideFlags = (HideFlags)61;
		((Object)val).name = "Rarity - Empress Angel";
		val.chance = 14f;
		obj.rarityPreset = val;
		return obj;
	}

	private void PrepareEnemyPrefab(GameObject prefab, int index)
	{
		((Object)prefab).hideFlags = (HideFlags)61;
		((Object)prefab).name = ((index == 0) ? "EmpressAngelPrefab" : $"EmpressAngelPrefab{index + 1}");
		EnemyParent componentInChildren = prefab.GetComponentInChildren<EnemyParent>(true);
		Enemy componentInChildren2 = prefab.GetComponentInChildren<Enemy>(true);
		if ((Object)(object)componentInChildren != (Object)null)
		{
			componentInChildren.enemyName = "Empress Angel";
		}
		if (!((Object)(object)componentInChildren2 == (Object)null))
		{
			EnemyOnScreen val = ((Component)componentInChildren2).GetComponent<EnemyOnScreen>() ?? ((Component)componentInChildren2).gameObject.AddComponent<EnemyOnScreen>();
			Transform val2 = (((Object)(object)componentInChildren2.CenterTransform != (Object)null) ? componentInChildren2.CenterTransform : ((Component)componentInChildren2).transform);
			Transform val3 = FindHeadPoint(val2);
			val.points = (Transform[])(object)((!((Object)(object)val3 != (Object)null) || !((Object)(object)val3 != (Object)(object)val2)) ? new Transform[1] { val2 } : new Transform[2] { val2, val3 });
			val.maxDistance = Mathf.Max(val.maxDistance, 28f);
			val.paddingWidth = Mathf.Min((val.paddingWidth <= 0f) ? 0.08f : val.paddingWidth, 0.08f);
			val.paddingHeight = Mathf.Min((val.paddingHeight <= 0f) ? 0.08f : val.paddingHeight, 0.08f);
			if ((Object)(object)((Component)componentInChildren2).gameObject.GetComponent<EmpressAngelBrain>() == (Object)null)
			{
				((Object)((Component)componentInChildren2).gameObject.AddComponent<EmpressAngelBrain>()).hideFlags = (HideFlags)61;
			}
		}
	}

	private static Transform FindHeadPoint(Transform origin)
	{
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		string[] source = new string[4] { "head", "neck", "face", "eye" };
		Transform[] componentsInChildren = ((Component)origin).GetComponentsInChildren<Transform>(true);
		Transform[] array = componentsInChildren;
		foreach (Transform val in array)
		{
			string @object = ((Object)val).name.ToLowerInvariant();
			if (source.Any(@object.Contains))
			{
				return val;
			}
		}
		Transform val2 = origin;
		array = componentsInChildren;
		foreach (Transform val3 in array)
		{
			if (val3.position.y > val2.position.y)
			{
				val2 = val3;
			}
		}
		return val2;
	}
}
namespace Omniscye.Empress.WeepingAngel
{
	public sealed class EmpressAngelController : MonoBehaviour
	{
		public enum State
		{
			Spawn,
			Idle,
			Roam,
			Investigate,
			SeekPlayer,
			Attack,
			Despawn,
			TargetPlayer
		}

		public PhotonView photonView;

		public Enemy enemy;

		public State currentState;

		public bool attackImpulse;

		public float stateTimer;

		public Vector3 agentDestination = Vector3.zero;

		public Vector3 targetPosition = Vector3.zero;

		public PlayerAvatar? targetPlayer;

		public float sightingTimer;

		public AudioSource? sightingSoundSource;

		public AudioClip[] sightingSounds = Array.Empty<AudioClip>();

		public float angelFindDistance = 400f;

		public float angelCloseThreshold = 4f;

		private EmpressAngelBrain brain;

		private void Awake()
		{
			photonView = ((Component)this).GetComponent<PhotonView>();
			enemy = ((Component)this).GetComponent<Enemy>();
			brain = ((Component)this).GetComponent<EmpressAngelBrain>() ?? ((Component)this).gameObject.AddComponent<EmpressAngelBrain>();
			((Object)brain).hideFlags = (HideFlags)61;
			if ((Object)(object)sightingSoundSource == (Object)null)
			{
				sightingSoundSource = ((Component)this).GetComponentsInChildren<AudioSource>(true).FirstOrDefault();
			}
		}

		private void Update()
		{
			targetPlayer = (((Object)(object)enemy != (Object)null) ? enemy.TargetPlayerAvatar : null);
			if (sightingTimer > 0f)
			{
				sightingTimer -= Time.deltaTime;
			}
			if (!((Object)(object)enemy == (Object)null) && !(sightingTimer > 0f) && !((Object)(object)sightingSoundSource == (Object)null) && sightingSounds != null && sightingSounds.Length != 0 && enemy.HasOnScreen && enemy.OnScreen.OnScreenLocal && enemy.HasPlayerDistance && enemy.PlayerDistance.PlayerDistanceLocal <= 10f)
			{
				PlaySightingAudio();
			}
		}

		public void PlaySightingAudio()
		{
			if (!((Object)(object)sightingSoundSource == (Object)null) && sightingSounds != null && sightingSounds.Length != 0)
			{
				AudioClip val = sightingSounds[Random.Range(0, sightingSounds.Length)];
				if (!((Object)(object)val == (Object)null))
				{
					sightingSoundSource.clip = val;
					sightingSoundSource.Play();
					GameDirector.instance.CameraImpact.Shake(2f, 0.1f);
					GameDirector.instance.CameraShake.Shake(2f, 1f);
					sightingTimer = 20f;
				}
			}
		}

		public void TriggerAttackImpulse()
		{
			attackImpulse = true;
			if (GameManager.Multiplayer())
			{
				photonView.RPC("AttackImpulseRPC", (RpcTarget)1, Array.Empty<object>());
			}
		}

		public bool ConsumeAttackImpulse()
		{
			if (!attackImpulse)
			{
				return false;
			}
			attackImpulse = false;
			return true;
		}

		public bool ShouldUseClosePose()
		{
			if ((Object)(object)enemy != (Object)null && (!enemy.HasOnScreen || !enemy.OnScreen.OnScreenAny) && enemy.HasPlayerDistance)
			{
				return enemy.PlayerDistance.PlayerDistanceClosest <= angelCloseThreshold;
			}
			return false;
		}

		[PunRPC]
		public void AttackImpulseRPC()
		{
			attackImpulse = true;
		}

		public void UpdateState(State state)
		{
			currentState = state;
		}

		[PunRPC]
		public void UpdateStateRPC(State state)
		{
			currentState = state;
		}

		[PunRPC]
		public void TargetPlayerRPC(int playerId)
		{
			targetPlayer = ((IEnumerable<PlayerAvatar>)SemiFunc.PlayerGetList()).FirstOrDefault((Func<PlayerAvatar, bool>)((PlayerAvatar player) => (Object)(object)player != (Object)null && (Object)(object)player.photonView != (Object)null && player.photonView.ViewID == playerId));
		}

		public void OnSpawn()
		{
			brain.HandleSpawn();
		}

		public void OnHurt()
		{
		}

		public void OnDeath()
		{
			brain.HandleDeath();
		}

		public void OnVision()
		{
			brain.HandleVision(((Object)(object)enemy != (Object)null && enemy.HasVision) ? enemy.Vision.onVisionTriggeredPlayer : null);
		}

		public void OnInvestigate()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)enemy != (Object)null && enemy.HasStateInvestigate)
			{
				brain.HandleInvestigate(enemy.StateInvestigate.onInvestigateTriggeredPosition);
			}
		}

		public void OnGrabbed()
		{
		}
	}
	public sealed class EmpressAngelAnimator : MonoBehaviour
	{
		public EmpressAngelController? controller;

		public Animator? animator;

		private void Awake()
		{
			animator = ((Component)this).GetComponent<Animator>();
			if ((Object)(object)animator != (Object)null)
			{
				animator.keepAnimatorStateOnDisable = true;
			}
			if (controller == null)
			{
				controller = ((Component)this).GetComponentInParent<EmpressAngelController>();
			}
		}

		private void Update()
		{
			if ((Object)(object)controller == (Object)null)
			{
				controller = ((Component)this).GetComponentInParent<EmpressAngelController>();
				return;
			}
			if ((Object)(object)animator == (Object)null)
			{
				animator = ((Component)this).GetComponent<Animator>();
				return;
			}
			if (controller.ConsumeAttackImpulse())
			{
				animator.SetTrigger("Attack");
			}
			animator.SetBool("IsClose", controller.ShouldUseClosePose());
		}
	}
}