Decompiled source of Empress GraveStones v1.0.1

EmpressGraveStones.dll

Decompiled 17 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Photon.Realtime;
using TMPro;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[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("Empress")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("EmpressGraveStones")]
[assembly: AssemblyTitle("EmpressGraveStones")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Empress.REPO.GraveStones
{
	[BepInPlugin("com.empress.repo.gravestones", "Empress GraveStones", "1.0.0")]
	public sealed class EmpressGraveStonesPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.empress.repo.gravestones";

		public const string PluginName = "Empress GraveStones";

		public const string PluginVersion = "1.0.0";

		private Harmony _harmony;

		internal static EmpressGraveStonesPlugin Instance { get; private set; }

		internal static ManualLogSource Log { get; private set; }

		internal static GraveSettings Settings { get; private set; }

		internal static string PluginDirectory { get; private set; }

		private void Awake()
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			Settings = new GraveSettings(((BaseUnityPlugin)this).Config);
			PluginDirectory = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location) ?? string.Empty;
			((Component)this).gameObject.transform.parent = null;
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			_harmony = new Harmony("com.empress.repo.gravestones");
			_harmony.PatchAll(typeof(EmpressGraveStonesPlugin).Assembly);
			GraveManager.EnsureHost();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Empress GraveStones v1.0.0 loaded.");
		}
	}
	internal sealed class GraveSettings
	{
		public readonly ConfigEntry<KeyCode> PrayKey;

		public readonly ConfigEntry<float> PrayDistance;

		public readonly ConfigEntry<float> ReviveChance;

		public readonly ConfigEntry<bool> HidePlayerHeads;

		public readonly ConfigEntry<bool> DisableHeadControl;

		public readonly ConfigEntry<float> ExplosionSize;

		public readonly ConfigEntry<int> ExplosionDamage;

		public readonly ConfigEntry<float> RitualSeconds;

		public readonly ConfigEntry<float> AudioVolume;

		public readonly ConfigEntry<float> AudioMaxDistance;

		public GraveSettings(ConfigFile config)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Expected O, but got Unknown
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Expected O, but got Unknown
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Expected O, but got Unknown
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Expected O, but got Unknown
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Expected O, but got Unknown
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Expected O, but got Unknown
			PrayKey = config.Bind<KeyCode>("Prayer", "PrayKey", (KeyCode)102, "Key pressed near a gravestone to pray.");
			PrayDistance = config.Bind<float>("Prayer", "PrayDistance", 2.5f, new ConfigDescription("How close you must be to a gravestone to pray.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 6f), Array.Empty<object>()));
			ReviveChance = config.Bind<float>("Prayer", "ReviveChance", 0.5f, new ConfigDescription("Chance a prayer revives the fallen player (the rest explode).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			RitualSeconds = config.Bind<float>("Prayer", "RitualSeconds", 5.5f, new ConfigDescription("Seconds the ritual plays before the outcome happens.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 20f), Array.Empty<object>()));
			HidePlayerHeads = config.Bind<bool>("Death", "HidePlayerHeads", true, "Hide the vanilla floating death head (and make it non-grabbable) so the gravestone replaces it.");
			DisableHeadControl = config.Bind<bool>("Death", "DisableHeadControl", true, "Stop dead players from taking control of their floating death head (they spectate instead).");
			ExplosionSize = config.Bind<float>("Explosion", "ExplosionSize", 2.2f, new ConfigDescription("Size of the failed-prayer explosion.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 6f), Array.Empty<object>()));
			ExplosionDamage = config.Bind<int>("Explosion", "ExplosionDamage", 130, new ConfigDescription("Damage dealt to the one who prayed on a failed prayer.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 1000), Array.Empty<object>()));
			AudioVolume = config.Bind<float>("Audio", "Volume", 0.3f, new ConfigDescription("Ritual audio volume.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			AudioMaxDistance = config.Bind<float>("Audio", "MaxDistance", 13f, new ConfigDescription("How far the ritual audio can be heard.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(3f, 50f), Array.Empty<object>()));
		}
	}
	internal static class GraveAccess
	{
		private static readonly FieldInfo GameDirectorPlayerListField = AccessTools.Field(typeof(GameDirector), "PlayerList");

		private static readonly FieldInfo EnemyDirectorEnemiesSpawnedField = AccessTools.Field(typeof(EnemyDirector), "enemiesSpawned");

		private static readonly FieldInfo EnemyParentNameField = AccessTools.Field(typeof(EnemyParent), "enemyName");

		private static readonly FieldInfo PlayerAvatarNameField = AccessTools.Field(typeof(PlayerAvatar), "playerName");

		private static readonly FieldInfo PlayerAvatarPhotonViewField = AccessTools.Field(typeof(PlayerAvatar), "photonView");

		private static readonly FieldInfo PlayerAvatarDeathHeadField = AccessTools.Field(typeof(PlayerAvatar), "playerDeathHead");

		private static readonly FieldInfo PlayerAvatarHealthField = AccessTools.Field(typeof(PlayerAvatar), "playerHealth");

		private static readonly FieldInfo DeathHeadCollidersField = AccessTools.Field(typeof(PlayerDeathHead), "colliders");

		private static readonly FieldInfo DeathHeadPhysGrabObjectField = AccessTools.Field(typeof(PlayerDeathHead), "physGrabObject");

		private static readonly FieldInfo PhysGrabObjectPlayerGrabbingField = AccessTools.Field(typeof(PhysGrabObject), "playerGrabbing");

		private static readonly FieldInfo PhysGrabObjectPhotonViewField = AccessTools.Field(typeof(PhysGrabObject), "photonView");

		private static readonly FieldInfo PhysGrabObjectRigidbodyField = AccessTools.Field(typeof(PhysGrabObject), "rb");

		private static readonly MethodInfo DeathHeadSetCollidersMethod = AccessTools.Method(typeof(PlayerDeathHead), "SetColliders", new Type[1] { typeof(bool) }, (Type[])null);

		private static readonly MethodInfo PhysGrabObjectTeleportMethod = AccessTools.Method(typeof(PhysGrabObject), "Teleport", new Type[2]
		{
			typeof(Vector3),
			typeof(Quaternion)
		}, (Type[])null);

		private static readonly MethodInfo PhysGrabberReleaseObjectMethod = AccessTools.Method(typeof(PhysGrabber), "ReleaseObject", new Type[2]
		{
			typeof(int),
			typeof(float)
		}, (Type[])null);

		private static readonly MethodInfo ReviveMethod = AccessTools.Method(typeof(PlayerAvatar), "Revive", new Type[1] { typeof(bool) }, (Type[])null);

		private static readonly MethodInfo HurtMethod = AccessTools.Method(typeof(PlayerHealth), "Hurt", new Type[4]
		{
			typeof(int),
			typeof(bool),
			typeof(int),
			typeof(bool)
		}, (Type[])null);

		private static readonly MethodInfo ExplosionSpawnMethod = AccessTools.Method(typeof(ParticleScriptExplosion), "Spawn", new Type[8]
		{
			typeof(Vector3),
			typeof(float),
			typeof(int),
			typeof(int),
			typeof(float),
			typeof(bool),
			typeof(bool),
			typeof(float)
		}, (Type[])null);

		private static readonly MethodInfo MasterOrSinglePlayerMethod = AccessTools.Method(typeof(SemiFunc), "IsMasterClientOrSingleplayer", (Type[])null, (Type[])null);

		private static readonly MethodInfo MultiplayerMethod = AccessTools.Method(typeof(SemiFunc), "IsMultiplayer", (Type[])null, (Type[])null);

		private static readonly MethodInfo LocalAvatarMethod = AccessTools.Method(typeof(SemiFunc), "PlayerAvatarLocal", (Type[])null, (Type[])null);

		private static ParticleScriptExplosion _explosion;

		public static bool IsMasterOrSingleplayer()
		{
			if (MasterOrSinglePlayerMethod != null)
			{
				return (bool)MasterOrSinglePlayerMethod.Invoke(null, null);
			}
			return false;
		}

		public static bool IsMultiplayer()
		{
			if (MultiplayerMethod != null)
			{
				return (bool)MultiplayerMethod.Invoke(null, null);
			}
			return false;
		}

		public static PlayerAvatar GetLocalAvatar()
		{
			if (!(LocalAvatarMethod != null))
			{
				return null;
			}
			object? obj = LocalAvatarMethod.Invoke(null, null);
			return (PlayerAvatar)((obj is PlayerAvatar) ? obj : null);
		}

		public static List<PlayerAvatar> GetPlayerList()
		{
			if (GameDirectorPlayerListField == null || (Object)(object)GameDirector.instance == (Object)null)
			{
				return null;
			}
			return GameDirectorPlayerListField.GetValue(GameDirector.instance) as List<PlayerAvatar>;
		}

		public static PhotonView GetPhotonView(PlayerAvatar avatar)
		{
			if ((Object)(object)avatar == (Object)null || PlayerAvatarPhotonViewField == null)
			{
				return null;
			}
			object? value = PlayerAvatarPhotonViewField.GetValue(avatar);
			return (PhotonView)((value is PhotonView) ? value : null);
		}

		public static int GetViewID(PlayerAvatar avatar)
		{
			PhotonView photonView = GetPhotonView(avatar);
			if (!((Object)(object)photonView != (Object)null))
			{
				return -1;
			}
			return photonView.ViewID;
		}

		public static int GetLocalViewID()
		{
			return GetViewID(GetLocalAvatar());
		}

		public static PlayerAvatar GetAvatarByViewID(int viewID)
		{
			List<PlayerAvatar> playerList = GetPlayerList();
			if (playerList == null || viewID < 0)
			{
				return null;
			}
			for (int i = 0; i < playerList.Count; i++)
			{
				if ((Object)(object)playerList[i] != (Object)null && GetViewID(playerList[i]) == viewID)
				{
					return playerList[i];
				}
			}
			return null;
		}

		public static string GetPlayerName(PlayerAvatar avatar)
		{
			if ((Object)(object)avatar == (Object)null || PlayerAvatarNameField == null)
			{
				return "Player";
			}
			string text = PlayerAvatarNameField.GetValue(avatar) as string;
			if (!string.IsNullOrWhiteSpace(text))
			{
				return text;
			}
			return "Player";
		}

		public static Vector3 GetAvatarPosition(PlayerAvatar avatar)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)avatar != (Object)null))
			{
				return Vector3.zero;
			}
			return ((Component)avatar).transform.position;
		}

		public static Vector3 GetAvatarForward(PlayerAvatar avatar)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)avatar != (Object)null))
			{
				return Vector3.forward;
			}
			return ((Component)avatar).transform.forward;
		}

		public static PlayerDeathHead GetDeathHead(PlayerAvatar avatar)
		{
			if ((Object)(object)avatar == (Object)null || PlayerAvatarDeathHeadField == null)
			{
				return null;
			}
			object? value = PlayerAvatarDeathHeadField.GetValue(avatar);
			return (PlayerDeathHead)((value is PlayerDeathHead) ? value : null);
		}

		public static void DisableHeadGrab(PlayerDeathHead head, Transform graveTransform, Vector3 parkPosition)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)head == (Object)null)
			{
				return;
			}
			PhysGrabObject headPhysGrabObject = GetHeadPhysGrabObject(head);
			ReleaseHeadGrabbers(headPhysGrabObject);
			TeleportHead(headPhysGrabObject, parkPosition);
			HideHeadRenderers(head, graveTransform);
			if (DeathHeadSetCollidersMethod != null)
			{
				try
				{
					DeathHeadSetCollidersMethod.Invoke(head, new object[1] { false });
				}
				catch
				{
				}
			}
			if (DeathHeadCollidersField != null && DeathHeadCollidersField.GetValue(head) is Collider[] array)
			{
				for (int i = 0; i < array.Length; i++)
				{
					if ((Object)(object)array[i] != (Object)null)
					{
						array[i].enabled = false;
					}
				}
			}
			Collider[] componentsInChildren = ((Component)head).GetComponentsInChildren<Collider>(true);
			for (int j = 0; j < componentsInChildren.Length; j++)
			{
				if ((Object)(object)componentsInChildren[j] != (Object)null)
				{
					componentsInChildren[j].enabled = false;
				}
			}
			if (!((Object)(object)headPhysGrabObject != (Object)null))
			{
				return;
			}
			Collider[] componentsInChildren2 = ((Component)headPhysGrabObject).GetComponentsInChildren<Collider>(true);
			for (int k = 0; k < componentsInChildren2.Length; k++)
			{
				if ((Object)(object)componentsInChildren2[k] != (Object)null)
				{
					componentsInChildren2[k].enabled = false;
				}
			}
		}

		private static void HideHeadRenderers(PlayerDeathHead head, Transform graveTransform)
		{
			Renderer[] componentsInChildren = ((Component)head).GetComponentsInChildren<Renderer>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				if ((Object)(object)componentsInChildren[i] != (Object)null && !IsChildOf(((Component)componentsInChildren[i]).transform, graveTransform))
				{
					componentsInChildren[i].enabled = false;
				}
			}
		}

		private static bool IsChildOf(Transform child, Transform parent)
		{
			if ((Object)(object)child == (Object)null || (Object)(object)parent == (Object)null)
			{
				return false;
			}
			Transform val = child;
			while ((Object)(object)val != (Object)null)
			{
				if ((Object)(object)val == (Object)(object)parent)
				{
					return true;
				}
				val = val.parent;
			}
			return false;
		}

		private static PhysGrabObject GetHeadPhysGrabObject(PlayerDeathHead head)
		{
			if ((Object)(object)head == (Object)null || DeathHeadPhysGrabObjectField == null)
			{
				return null;
			}
			object? value = DeathHeadPhysGrabObjectField.GetValue(head);
			return (PhysGrabObject)((value is PhysGrabObject) ? value : null);
		}

		private static void ReleaseHeadGrabbers(PhysGrabObject physGrabObject)
		{
			if ((Object)(object)physGrabObject == (Object)null || PhysGrabObjectPlayerGrabbingField == null || PhysGrabberReleaseObjectMethod == null || !(PhysGrabObjectPlayerGrabbingField.GetValue(physGrabObject) is IList list))
			{
				return;
			}
			int physGrabObjectViewID = GetPhysGrabObjectViewID(physGrabObject);
			object[] array = new object[list.Count];
			list.CopyTo(array, 0);
			foreach (object obj in array)
			{
				PhysGrabber val = (PhysGrabber)((obj is PhysGrabber) ? obj : null);
				if (val != null)
				{
					try
					{
						PhysGrabberReleaseObjectMethod.Invoke(val, new object[2] { physGrabObjectViewID, 0.25f });
					}
					catch
					{
					}
				}
			}
			list.Clear();
		}

		private static int GetPhysGrabObjectViewID(PhysGrabObject physGrabObject)
		{
			if ((Object)(object)physGrabObject == (Object)null || PhysGrabObjectPhotonViewField == null)
			{
				return -1;
			}
			object? value = PhysGrabObjectPhotonViewField.GetValue(physGrabObject);
			PhotonView val = (PhotonView)((value is PhotonView) ? value : null);
			if (!((Object)(object)val != (Object)null))
			{
				return -1;
			}
			return val.ViewID;
		}

		private static void TeleportHead(PhysGrabObject physGrabObject, Vector3 parkPosition)
		{
			//IL_005e: 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_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: 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_0044: 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_00a5: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)physGrabObject == (Object)null)
			{
				return;
			}
			Vector3 val = parkPosition + Vector3.up * 0.25f;
			if (PhysGrabObjectTeleportMethod != null)
			{
				try
				{
					PhysGrabObjectTeleportMethod.Invoke(physGrabObject, new object[2]
					{
						val,
						Quaternion.identity
					});
				}
				catch
				{
					((Component)physGrabObject).transform.SetPositionAndRotation(val, Quaternion.identity);
				}
			}
			else
			{
				((Component)physGrabObject).transform.SetPositionAndRotation(val, Quaternion.identity);
			}
			if (PhysGrabObjectRigidbodyField != null)
			{
				object? value = PhysGrabObjectRigidbodyField.GetValue(physGrabObject);
				Rigidbody val2 = (Rigidbody)((value is Rigidbody) ? value : null);
				if (val2 != null)
				{
					val2.position = val;
					val2.rotation = Quaternion.identity;
					val2.useGravity = false;
					val2.detectCollisions = false;
					val2.isKinematic = true;
					val2.Sleep();
				}
			}
		}

		public static string GetEnemyNameByIndex(int enemyIndex)
		{
			if (enemyIndex < 0 || EnemyDirectorEnemiesSpawnedField == null || (Object)(object)EnemyDirector.instance == (Object)null)
			{
				return null;
			}
			if (!(EnemyDirectorEnemiesSpawnedField.GetValue(EnemyDirector.instance) is List<EnemyParent> list))
			{
				return null;
			}
			if (enemyIndex >= list.Count || (Object)(object)list[enemyIndex] == (Object)null || EnemyParentNameField == null)
			{
				return null;
			}
			return EnemyParentNameField.GetValue(list[enemyIndex]) as string;
		}

		public static void RevivePlayer(PlayerAvatar avatar)
		{
			if ((Object)(object)avatar != (Object)null && ReviveMethod != null)
			{
				ReviveMethod.Invoke(avatar, new object[1] { false });
			}
		}

		public static void HurtPlayer(PlayerAvatar avatar, int damage)
		{
			if (!((Object)(object)avatar == (Object)null) && !(PlayerAvatarHealthField == null) && !(HurtMethod == null))
			{
				object value = PlayerAvatarHealthField.GetValue(avatar);
				if (value != null)
				{
					HurtMethod.Invoke(value, new object[4] { damage, false, -1, false });
				}
			}
		}

		public static void SpawnExplosionVisual(Vector3 position, float size)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_explosion == (Object)null)
			{
				_explosion = Object.FindObjectOfType<ParticleScriptExplosion>(true);
			}
			if (!((Object)(object)_explosion == (Object)null) && !(ExplosionSpawnMethod == null))
			{
				ExplosionSpawnMethod.Invoke(_explosion, new object[8] { position, size, 0, 0, 1f, true, false, 1.5f });
			}
		}
	}
	internal static class GraveAudio
	{
		private const string FileName = "EmpressGrave.ogg";

		private static AudioClip _clip;

		private static bool _loading;

		public static IEnumerator Load()
		{
			if ((Object)(object)_clip != (Object)null || _loading)
			{
				yield break;
			}
			_loading = true;
			string text = Path.Combine(EmpressGraveStonesPlugin.PluginDirectory, "EmpressGrave.ogg");
			if (!File.Exists(text))
			{
				EmpressGraveStonesPlugin.Log.LogWarning((object)("Empress GraveStones audio not found at " + text));
				_loading = false;
				yield break;
			}
			string absoluteUri = new Uri(text).AbsoluteUri;
			UnityWebRequest request = UnityWebRequestMultimedia.GetAudioClip(absoluteUri, (AudioType)14);
			try
			{
				yield return request.SendWebRequest();
				if ((int)request.result == 1)
				{
					_clip = DownloadHandlerAudioClip.GetContent(request);
				}
				else
				{
					EmpressGraveStonesPlugin.Log.LogWarning((object)("Empress GraveStones audio load failed: " + request.error));
				}
			}
			finally
			{
				((IDisposable)request)?.Dispose();
			}
			_loading = false;
		}

		public static GameObject PlayAt(Vector3 position)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Expected O, but got Unknown
			//IL_00a4: Expected O, but got Unknown
			if ((Object)(object)_clip == (Object)null)
			{
				return null;
			}
			GameObject val = new GameObject("Empress Grave Audio");
			val.transform.position = position;
			AudioSource obj = val.AddComponent<AudioSource>();
			obj.clip = _clip;
			obj.volume = EmpressGraveStonesPlugin.Settings.AudioVolume.Value;
			obj.spatialBlend = 1f;
			obj.dopplerLevel = 0f;
			obj.rolloffMode = (AudioRolloffMode)1;
			obj.minDistance = 1.5f;
			obj.maxDistance = EmpressGraveStonesPlugin.Settings.AudioMaxDistance.Value;
			obj.Play();
			Object.Destroy((Object)val, _clip.length + 0.5f);
			return val;
		}
	}
	internal static class GraveEffects
	{
		public static void PlayHoly(Vector3 position)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0011: 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_0033: 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_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: 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_015a: 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_016b: 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_0180: 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_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Empress Holy Effect");
			val.transform.position = position;
			GameObject val2 = new GameObject("Holy Light");
			val2.transform.SetParent(val.transform, false);
			val2.transform.localPosition = new Vector3(0f, 1.6f, 0f);
			Light obj = val2.AddComponent<Light>();
			obj.type = (LightType)2;
			obj.color = new Color(1f, 0.92f, 0.62f);
			obj.range = 15f;
			obj.intensity = 20f;
			obj.shadows = (LightShadows)0;
			GameObject obj2 = GameObject.CreatePrimitive((PrimitiveType)2);
			obj2.transform.SetParent(val.transform, false);
			obj2.transform.localPosition = new Vector3(0f, 3f, 0f);
			obj2.transform.localScale = new Vector3(0.55f, 3f, 0.55f);
			DestroyCollider(obj2);
			GraveMaterials.Glow(obj2.GetComponent<Renderer>(), new Color(1f, 0.9f, 0.55f), 6f);
			for (int i = 0; i < 10; i++)
			{
				GameObject obj3 = GameObject.CreatePrimitive((PrimitiveType)0);
				obj3.transform.SetParent(val.transform, false);
				float num = (float)i * 36f;
				Vector3 val3 = Quaternion.Euler(0f, num, 0f) * new Vector3(0.55f, 0f, 0f);
				obj3.transform.localPosition = val3 + new Vector3(0f, 0.25f, 0f);
				obj3.transform.localScale = Vector3.one * 0.16f;
				DestroyCollider(obj3);
				GraveMaterials.Glow(obj3.GetComponent<Renderer>(), new Color(1f, 0.95f, 0.72f), 5f);
			}
			val.AddComponent<GraveEffectController>().Begin(3.5f, rise: true);
		}

		public static void PlayRitual(Vector3 position, float duration)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0011: 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_0033: 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_006f: 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_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Expected O, but got Unknown
			//IL_0149: 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_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: 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_01e4: 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)
			GameObject val = new GameObject("Empress Ritual");
			val.transform.position = position;
			GameObject val2 = new GameObject("Ritual Light");
			val2.transform.SetParent(val.transform, false);
			val2.transform.localPosition = new Vector3(0f, 1f, 0f);
			Light val3 = val2.AddComponent<Light>();
			val3.type = (LightType)2;
			val3.color = new Color(0.65f, 0.35f, 1f);
			val3.range = 11f;
			val3.intensity = 3f;
			val3.shadows = (LightShadows)0;
			GameObject val4 = GameObject.CreatePrimitive((PrimitiveType)2);
			val4.transform.SetParent(val.transform, false);
			val4.transform.localPosition = new Vector3(0f, 0.05f, 0f);
			val4.transform.localScale = new Vector3(1.7f, 0.02f, 1.7f);
			DestroyCollider(val4);
			GraveMaterials.Glow(val4.GetComponent<Renderer>(), new Color(0.4f, 0.9f, 1f), 4f);
			GameObject val5 = new GameObject("Ritual Spinner");
			val5.transform.SetParent(val.transform, false);
			val5.transform.localPosition = new Vector3(0f, 0.3f, 0f);
			for (int i = 0; i < 8; i++)
			{
				GameObject obj = GameObject.CreatePrimitive((PrimitiveType)3);
				obj.transform.SetParent(val5.transform, false);
				float num = (float)i * 45f;
				obj.transform.localPosition = Quaternion.Euler(0f, num, 0f) * new Vector3(0.85f, 0f, 0f);
				obj.transform.localScale = new Vector3(0.12f, 0.12f, 0.12f);
				obj.transform.localRotation = Quaternion.Euler(0f, num, 45f);
				DestroyCollider(obj);
				GraveMaterials.Glow(obj.GetComponent<Renderer>(), new Color(0.72f, 0.42f, 1f), 5f);
			}
			val.AddComponent<RitualController>().Begin(duration, val3, val5.transform, val4.transform);
		}

		public static void PlayExplosion(Vector3 position, float size)
		{
			//IL_0000: 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_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: 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_004e: Unknown result type (might be due to invalid IL or missing references)
			GraveAccess.SpawnExplosionVisual(position, size);
			GameObject val = new GameObject("Empress Explosion Flash");
			val.transform.position = position + Vector3.up * 0.5f;
			Light obj = val.AddComponent<Light>();
			obj.type = (LightType)2;
			obj.color = new Color(1f, 0.55f, 0.25f);
			obj.range = 17f;
			obj.intensity = 26f;
			obj.shadows = (LightShadows)0;
			val.AddComponent<GraveEffectController>().Begin(0.5f, rise: false);
		}

		private static void DestroyCollider(GameObject part)
		{
			Collider component = part.GetComponent<Collider>();
			if ((Object)(object)component != (Object)null)
			{
				Object.Destroy((Object)(object)component);
			}
		}
	}
	internal sealed class RitualController : MonoBehaviour
	{
		private float _duration;

		private float _time;

		private Light _light;

		private float _baseIntensity;

		private Transform _spinner;

		private Transform _ring;

		public void Begin(float duration, Light light, Transform spinner, Transform ring)
		{
			_duration = Mathf.Max(0.1f, duration);
			_light = light;
			_baseIntensity = (((Object)(object)light != (Object)null) ? light.intensity : 0f);
			_spinner = spinner;
			_ring = ring;
		}

		private void Update()
		{
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			_time += Time.deltaTime;
			float num = Mathf.Clamp01(_time / _duration);
			if ((Object)(object)_spinner != (Object)null)
			{
				_spinner.Rotate(0f, (120f + 420f * num) * Time.deltaTime, 0f, (Space)1);
				_spinner.localPosition = new Vector3(0f, 0.3f + num * 0.8f, 0f);
				_spinner.localScale = Vector3.one * (1f - 0.45f * num);
			}
			if ((Object)(object)_ring != (Object)null)
			{
				_ring.Rotate(0f, -90f * Time.deltaTime, 0f, (Space)1);
			}
			if ((Object)(object)_light != (Object)null)
			{
				_light.intensity = _baseIntensity + Mathf.Sin(_time * 12f) + num * 14f;
			}
			if (_time >= _duration)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
		}
	}
	internal sealed class GraveEffectController : MonoBehaviour
	{
		private float _duration;

		private float _time;

		private bool _rise;

		private Light _light;

		private float _baseIntensity;

		public void Begin(float duration, bool rise)
		{
			_duration = Mathf.Max(0.05f, duration);
			_rise = rise;
			_light = ((Component)this).GetComponentInChildren<Light>();
			_baseIntensity = (((Object)(object)_light != (Object)null) ? _light.intensity : 0f);
		}

		private void Update()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			_time += Time.deltaTime;
			float num = _time / _duration;
			if (_rise)
			{
				Transform transform = ((Component)this).transform;
				transform.position += Vector3.up * (0.6f * Time.deltaTime);
				((Component)this).transform.Rotate(0f, 70f * Time.deltaTime, 0f, (Space)0);
			}
			if ((Object)(object)_light != (Object)null)
			{
				_light.intensity = Mathf.Lerp(_baseIntensity, 0f, num);
			}
			if (_time >= _duration)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
		}
	}
	internal sealed class GraveManager : MonoBehaviour, IOnEventCallback
	{
		private const byte PrayRequestEvent = 190;

		private const byte PrayResultEvent = 191;

		private const byte RitualStartEvent = 192;

		private readonly Dictionary<int, Gravestone> _graves = new Dictionary<int, Gravestone>();

		private readonly Dictionary<int, GameObject> _ritualAudio = new Dictionary<int, GameObject>();

		private readonly HashSet<int> _deadPlayers = new HashSet<int>();

		private readonly HashSet<int> _ritualsInProgress = new HashSet<int>();

		private int _sceneHandle = -1;

		private bool _eventsRegistered;

		private bool _nearGrave;

		private int _nearestOwnerId = -1;

		private string _nearestName = string.Empty;

		private GUIStyle _promptStyle;

		private Texture2D _promptBackground;

		public static GraveManager Instance { get; private set; }

		public static GraveManager EnsureHost()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: 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_0037: Expected O, but got Unknown
			if ((Object)(object)Instance != (Object)null)
			{
				return Instance;
			}
			GameObject val = new GameObject("Empress GraveStones Manager");
			val.transform.parent = null;
			((Object)val).hideFlags = (HideFlags)61;
			Object.DontDestroyOnLoad((Object)val);
			Instance = val.AddComponent<GraveManager>();
			return Instance;
		}

		private void Awake()
		{
			Instance = this;
		}

		private void Start()
		{
			((MonoBehaviour)this).StartCoroutine(GraveAudio.Load());
		}

		private void OnDisable()
		{
			if (_eventsRegistered)
			{
				PhotonNetwork.RemoveCallbackTarget((object)this);
				_eventsRegistered = false;
			}
		}

		private void Update()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			UpdateEventRegistration();
			HandleSceneChange();
			UpdateNearestGrave();
			if (_nearGrave && Input.GetKeyDown(EmpressGraveStonesPlugin.Settings.PrayKey.Value))
			{
				RequestPray(_nearestOwnerId);
			}
		}

		private void UpdateEventRegistration()
		{
			bool inRoom = PhotonNetwork.InRoom;
			if (inRoom && !_eventsRegistered)
			{
				PhotonNetwork.AddCallbackTarget((object)this);
				_eventsRegistered = true;
			}
			else if (!inRoom && _eventsRegistered)
			{
				PhotonNetwork.RemoveCallbackTarget((object)this);
				_eventsRegistered = false;
			}
		}

		public void OnPlayerDeath(PlayerAvatar avatar, int enemyIndex)
		{
			//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_003c: 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_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: 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_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: 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_00d0: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)avatar == (Object)null)
			{
				return;
			}
			int viewID = GraveAccess.GetViewID(avatar);
			if (viewID >= 0)
			{
				_deadPlayers.Add(viewID);
				string playerName = GraveAccess.GetPlayerName(avatar);
				string cause = ResolveCause(enemyIndex);
				Vector3 val = GroundPosition(GraveAccess.GetAvatarPosition(avatar));
				Vector3 avatarForward = GraveAccess.GetAvatarForward(avatar);
				avatarForward.y = 0f;
				Quaternion rotation = ((((Vector3)(ref avatarForward)).sqrMagnitude > 0.001f) ? Quaternion.LookRotation(((Vector3)(ref avatarForward)).normalized, Vector3.up) : Quaternion.identity);
				if (!_graves.TryGetValue(viewID, out var value))
				{
					value = new GameObject("Empress Gravestone").AddComponent<Gravestone>();
					value.Init(viewID, playerName, cause, val, rotation);
					_graves[viewID] = value;
				}
				if (EmpressGraveStonesPlugin.Settings.HidePlayerHeads.Value)
				{
					((MonoBehaviour)this).StartCoroutine(HideHead(avatar, ((Component)value).transform, val));
				}
			}
		}

		public void OnPlayerRevived(PlayerAvatar avatar)
		{
			if (!((Object)(object)avatar == (Object)null))
			{
				int viewID = GraveAccess.GetViewID(avatar);
				_deadPlayers.Remove(viewID);
				RemoveGrave(viewID);
			}
		}

		private void RequestPray(int ownerViewID)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected O, but got Unknown
			if (ownerViewID >= 0 && IsLocalAlive() && !_ritualsInProgress.Contains(ownerViewID) && _graves.ContainsKey(ownerViewID))
			{
				int localViewID = GraveAccess.GetLocalViewID();
				BeginRitual(ownerViewID);
				if (GraveAccess.IsMultiplayer())
				{
					PhotonNetwork.RaiseEvent((byte)192, (object)new object[1] { ownerViewID }, new RaiseEventOptions
					{
						Receivers = (ReceiverGroup)0
					}, SendOptions.SendReliable);
				}
				((MonoBehaviour)this).StartCoroutine(ResolveAfterRitual(ownerViewID, localViewID));
			}
		}

		private void BeginRitual(int ownerViewID)
		{
			//IL_0027: 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)
			_ritualsInProgress.Add(ownerViewID);
			if (_graves.TryGetValue(ownerViewID, out var value) && (Object)(object)value != (Object)null)
			{
				GraveEffects.PlayRitual(value.Position, EmpressGraveStonesPlugin.Settings.RitualSeconds.Value);
				GameObject val = GraveAudio.PlayAt(value.Position);
				if ((Object)(object)val != (Object)null)
				{
					_ritualAudio[ownerViewID] = val;
				}
			}
		}

		private void StopRitualAudio(int ownerViewID)
		{
			if (_ritualAudio.TryGetValue(ownerViewID, out var value))
			{
				if ((Object)(object)value != (Object)null)
				{
					Object.Destroy((Object)(object)value);
				}
				_ritualAudio.Remove(ownerViewID);
			}
		}

		private IEnumerator ResolveAfterRitual(int ownerViewID, int prayingViewID)
		{
			yield return (object)new WaitForSeconds(EmpressGraveStonesPlugin.Settings.RitualSeconds.Value);
			if (_graves.ContainsKey(ownerViewID))
			{
				if (GraveAccess.IsMasterOrSingleplayer())
				{
					ResolvePray(ownerViewID, prayingViewID);
					yield break;
				}
				PhotonNetwork.RaiseEvent((byte)190, (object)new object[2] { ownerViewID, prayingViewID }, new RaiseEventOptions
				{
					Receivers = (ReceiverGroup)2
				}, SendOptions.SendReliable);
			}
		}

		private void ResolvePray(int ownerViewID, int prayingViewID)
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			if (_graves.ContainsKey(ownerViewID))
			{
				bool flag = Random.value < EmpressGraveStonesPlugin.Settings.ReviveChance.Value;
				if (flag)
				{
					GraveAccess.RevivePlayer(GraveAccess.GetAvatarByViewID(ownerViewID));
				}
				if (GraveAccess.IsMultiplayer())
				{
					PhotonNetwork.RaiseEvent((byte)191, (object)new object[3] { ownerViewID, flag, prayingViewID }, new RaiseEventOptions
					{
						Receivers = (ReceiverGroup)1
					}, SendOptions.SendReliable);
				}
				ApplyPrayResult(ownerViewID, flag, prayingViewID);
			}
		}

		private void ApplyPrayResult(int ownerViewID, bool revived, int prayingViewID)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			StopRitualAudio(ownerViewID);
			if (_graves.TryGetValue(ownerViewID, out var value) && (Object)(object)value != (Object)null)
			{
				if (revived)
				{
					GraveEffects.PlayHoly(value.Position);
				}
				else
				{
					GraveEffects.PlayExplosion(value.Position, EmpressGraveStonesPlugin.Settings.ExplosionSize.Value);
				}
			}
			if (!revived && GraveAccess.GetLocalViewID() == prayingViewID)
			{
				GraveAccess.HurtPlayer(GraveAccess.GetLocalAvatar(), EmpressGraveStonesPlugin.Settings.ExplosionDamage.Value);
			}
			if (revived)
			{
				_deadPlayers.Remove(ownerViewID);
			}
			RemoveGrave(ownerViewID);
		}

		public void OnEvent(EventData photonEvent)
		{
			if (photonEvent.Code != 190 && photonEvent.Code != 191 && photonEvent.Code != 192)
			{
				return;
			}
			try
			{
				if (photonEvent.Code == 190)
				{
					if (GraveAccess.IsMasterOrSingleplayer() && photonEvent.CustomData is object[] array && array.Length >= 2)
					{
						ResolvePray((int)array[0], (int)array[1]);
					}
				}
				else if (photonEvent.Code == 191)
				{
					if (photonEvent.CustomData is object[] array2 && array2.Length >= 3)
					{
						ApplyPrayResult((int)array2[0], (bool)array2[1], (int)array2[2]);
					}
				}
				else if (photonEvent.Code == 192 && photonEvent.CustomData is object[] array3 && array3.Length >= 1 && !_ritualsInProgress.Contains((int)array3[0]))
				{
					BeginRitual((int)array3[0]);
				}
			}
			catch (Exception ex)
			{
				EmpressGraveStonesPlugin.Log.LogError((object)("Empress GraveStones event error: " + ex));
			}
		}

		private void RemoveGrave(int ownerViewID)
		{
			if (_graves.TryGetValue(ownerViewID, out var value))
			{
				if ((Object)(object)value != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)value).gameObject);
				}
				_graves.Remove(ownerViewID);
				_ritualsInProgress.Remove(ownerViewID);
				StopRitualAudio(ownerViewID);
			}
		}

		private void ClearGraves()
		{
			foreach (KeyValuePair<int, Gravestone> grafe in _graves)
			{
				if ((Object)(object)grafe.Value != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)grafe.Value).gameObject);
				}
			}
			foreach (KeyValuePair<int, GameObject> item in _ritualAudio)
			{
				if ((Object)(object)item.Value != (Object)null)
				{
					Object.Destroy((Object)(object)item.Value);
				}
			}
			_graves.Clear();
			_ritualAudio.Clear();
			_deadPlayers.Clear();
			_ritualsInProgress.Clear();
		}

		private bool IsLocalAlive()
		{
			int localViewID = GraveAccess.GetLocalViewID();
			if (localViewID >= 0)
			{
				return !_deadPlayers.Contains(localViewID);
			}
			return false;
		}

		private void UpdateNearestGrave()
		{
			//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_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			_nearGrave = false;
			_nearestOwnerId = -1;
			if (_graves.Count == 0 || !IsLocalAlive())
			{
				return;
			}
			PlayerAvatar localAvatar = GraveAccess.GetLocalAvatar();
			if ((Object)(object)localAvatar == (Object)null)
			{
				return;
			}
			Vector3 avatarPosition = GraveAccess.GetAvatarPosition(localAvatar);
			float num = EmpressGraveStonesPlugin.Settings.PrayDistance.Value;
			foreach (KeyValuePair<int, Gravestone> grafe in _graves)
			{
				if (!((Object)(object)grafe.Value == (Object)null) && !_ritualsInProgress.Contains(grafe.Key))
				{
					float num2 = Vector3.Distance(avatarPosition, grafe.Value.Position);
					if (num2 <= num)
					{
						num = num2;
						_nearGrave = true;
						_nearestOwnerId = grafe.Key;
						_nearestName = grafe.Value.OwnerName;
					}
				}
			}
		}

		private static string ResolveCause(int enemyIndex)
		{
			string enemyNameByIndex = GraveAccess.GetEnemyNameByIndex(enemyIndex);
			if (!string.IsNullOrWhiteSpace(enemyNameByIndex))
			{
				return "Slain by " + enemyNameByIndex;
			}
			return "Met an untimely end";
		}

		private static Vector3 GroundPosition(Vector3 from)
		{
			//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_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_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			RaycastHit val = default(RaycastHit);
			if (Physics.Raycast(from + Vector3.up * 1.5f, Vector3.down, ref val, 8f, -1, (QueryTriggerInteraction)1))
			{
				return ((RaycastHit)(ref val)).point;
			}
			return from;
		}

		private IEnumerator HideHead(PlayerAvatar avatar, Transform graveTransform, Vector3 parkPosition)
		{
			//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)
			for (int attempt = 0; attempt < 30; attempt++)
			{
				PlayerDeathHead deathHead = GraveAccess.GetDeathHead(avatar);
				if ((Object)(object)deathHead != (Object)null)
				{
					GraveAccess.DisableHeadGrab(deathHead, graveTransform, parkPosition);
					break;
				}
				yield return null;
			}
		}

		private void HandleSceneChange()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			Scene activeScene = SceneManager.GetActiveScene();
			int handle = ((Scene)(ref activeScene)).handle;
			if (handle != _sceneHandle)
			{
				_sceneHandle = handle;
				ClearGraves();
			}
		}

		private void OnGUI()
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Expected O, but got Unknown
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			if (_nearGrave)
			{
				EnsurePromptStyle();
				string[] obj = new string[5] { "[", null, null, null, null };
				KeyCode value = EmpressGraveStonesPlugin.Settings.PrayKey.Value;
				obj[1] = ((object)(KeyCode)(ref value)).ToString();
				obj[2] = "]  Pray at ";
				obj[3] = _nearestName;
				obj[4] = "'s grave";
				string text = string.Concat(obj);
				Vector2 val = _promptStyle.CalcSize(new GUIContent(text));
				float num = val.x + 30f;
				float num2 = val.y + 18f;
				Rect val2 = new Rect(((float)Screen.width - num) * 0.5f, (float)Screen.height * 0.62f, num, num2);
				GUI.color = new Color(0f, 0f, 0f, 0.65f);
				GUI.DrawTexture(val2, (Texture)(object)PromptBackground());
				GUI.color = Color.white;
				GUI.Label(val2, text, _promptStyle);
			}
		}

		private void EnsurePromptStyle()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: 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: Expected O, but got Unknown
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			if (_promptStyle == null)
			{
				_promptStyle = new GUIStyle(GUI.skin.label)
				{
					fontSize = 20,
					fontStyle = (FontStyle)1,
					alignment = (TextAnchor)4
				};
				_promptStyle.normal.textColor = new Color(0.95f, 0.9f, 0.7f);
			}
		}

		private Texture2D PromptBackground()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_promptBackground == (Object)null)
			{
				_promptBackground = new Texture2D(1, 1, (TextureFormat)4, false);
				_promptBackground.SetPixel(0, 0, Color.white);
				_promptBackground.Apply();
			}
			return _promptBackground;
		}
	}
	internal static class GraveMaterials
	{
		public static void Tint(Renderer renderer, Color baseColor)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)renderer == (Object)null))
			{
				Material material = renderer.material;
				material.color = baseColor;
				if (material.HasProperty("_BaseColor"))
				{
					material.SetColor("_BaseColor", baseColor);
				}
			}
		}

		public static void Glow(Renderer renderer, Color color, float intensity)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)renderer == (Object)null))
			{
				Material material = renderer.material;
				material.color = color;
				if (material.HasProperty("_BaseColor"))
				{
					material.SetColor("_BaseColor", color);
				}
				material.EnableKeyword("_EMISSION");
				if (material.HasProperty("_EmissionColor"))
				{
					material.SetColor("_EmissionColor", color * intensity);
				}
			}
		}
	}
	[HarmonyPatch(typeof(PlayerAvatar), "PlayerDeath")]
	internal static class GravePatchPlayerDeath
	{
		private static void Postfix(PlayerAvatar __instance, int enemyIndex)
		{
			GraveManager.Instance?.OnPlayerDeath(__instance, enemyIndex);
		}
	}
	[HarmonyPatch(typeof(PlayerAvatar), "PlayerDeathRPC")]
	internal static class GravePatchPlayerDeathRpc
	{
		private static void Postfix(PlayerAvatar __instance, int enemyIndex)
		{
			GraveManager.Instance?.OnPlayerDeath(__instance, enemyIndex);
		}
	}
	[HarmonyPatch(typeof(PlayerAvatar), "Revive")]
	internal static class GravePatchRevive
	{
		private static void Postfix(PlayerAvatar __instance)
		{
			GraveManager.Instance?.OnPlayerRevived(__instance);
		}
	}
	[HarmonyPatch(typeof(PlayerAvatar), "ReviveRPC")]
	internal static class GravePatchReviveRpc
	{
		private static void Postfix(PlayerAvatar __instance)
		{
			GraveManager.Instance?.OnPlayerRevived(__instance);
		}
	}
	[HarmonyPatch(typeof(SpectateCamera), "UpdateState")]
	internal static class GravePatchSpectateState
	{
		private static void Prefix(ref State _state)
		{
			if (EmpressGraveStonesPlugin.Settings != null && EmpressGraveStonesPlugin.Settings.DisableHeadControl.Value && (int)_state == 2)
			{
				_state = (State)1;
			}
		}
	}
	internal sealed class Gravestone : MonoBehaviour
	{
		private static readonly Color StoneColor = new Color(0.34f, 0.35f, 0.38f);

		private static readonly Color EngraveColor = new Color(0.93f, 0.9f, 0.82f);

		private static readonly Color CauseColor = new Color(0.82f, 0.78f, 0.68f);

		public int OwnerViewID { get; private set; }

		public string OwnerName { get; private set; }

		public Vector3 Position => ((Component)this).transform.position;

		public void Init(int ownerViewID, string ownerName, string cause, Vector3 position, Quaternion rotation)
		{
			//IL_0014: 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)
			OwnerViewID = ownerViewID;
			OwnerName = ownerName;
			((Component)this).transform.position = position;
			((Component)this).transform.rotation = rotation;
			Build(ownerName, cause);
		}

		private void Build(string ownerName, string cause)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			AddBlock((PrimitiveType)3, new Vector3(0f, 0.06f, 0f), new Vector3(0.95f, 0.12f, 0.6f));
			AddBlock((PrimitiveType)3, new Vector3(0f, 0.62f, 0f), new Vector3(0.74f, 1f, 0.16f));
			AddBlock((PrimitiveType)0, new Vector3(0f, 1.08f, 0f), new Vector3(0.74f, 0.66f, 0.16f));
			AddText(new Vector3(0f, 1f, 0.12f), "R.I.P.", new Vector2(13f, 3f), 6f, 16f, EngraveColor);
			AddText(new Vector3(0f, 0.72f, 0.12f), Shorten(ownerName, 12), new Vector2(15f, 4f), 9f, 32f, EngraveColor);
			AddText(new Vector3(0f, 0.42f, 0.12f), Shorten(cause, 24), new Vector2(20f, 4f), 5f, 15f, CauseColor);
		}

		private void AddBlock(PrimitiveType type, Vector3 localPosition, Vector3 scale)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: 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)
			GameObject obj = GameObject.CreatePrimitive(type);
			obj.transform.SetParent(((Component)this).transform, false);
			obj.transform.localPosition = localPosition;
			obj.transform.localScale = scale;
			Collider component = obj.GetComponent<Collider>();
			if ((Object)(object)component != (Object)null)
			{
				Object.Destroy((Object)(object)component);
			}
			GraveMaterials.Tint(obj.GetComponent<Renderer>(), StoneColor);
		}

		private void AddText(Vector3 localPosition, string value, Vector2 rectSize, float minFontSize, float maxFontSize, Color color)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: 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_0028: 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_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: 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)
			GameObject val = new GameObject("Engraving");
			val.transform.SetParent(((Component)this).transform, false);
			val.transform.localPosition = localPosition;
			val.transform.localRotation = Quaternion.Euler(0f, 180f, 0f);
			val.transform.localScale = Vector3.one * 0.05f;
			TextMeshPro val2 = val.AddComponent<TextMeshPro>();
			((TMP_Text)val2).text = value;
			((Graphic)val2).color = color;
			((TMP_Text)val2).alignment = (TextAlignmentOptions)514;
			((TMP_Text)val2).enableWordWrapping = false;
			((TMP_Text)val2).overflowMode = (TextOverflowModes)1;
			((TMP_Text)val2).enableAutoSizing = true;
			((TMP_Text)val2).fontSizeMin = minFontSize;
			((TMP_Text)val2).fontSizeMax = maxFontSize;
			((TMP_Text)val2).rectTransform.sizeDelta = rectSize;
			TMP_FontAsset val3 = GraveFont.Get();
			if ((Object)(object)val3 != (Object)null)
			{
				((TMP_Text)val2).font = val3;
			}
		}

		private static string Shorten(string value, int max)
		{
			if (string.IsNullOrEmpty(value))
			{
				return string.Empty;
			}
			value = value.Trim();
			if (value.Length > max)
			{
				return value.Substring(0, max - 1) + "…";
			}
			return value;
		}
	}
	internal static class GraveFont
	{
		private static TMP_FontAsset _font;

		public static TMP_FontAsset Get()
		{
			if ((Object)(object)_font != (Object)null)
			{
				return _font;
			}
			_font = TMP_Settings.defaultFontAsset;
			if ((Object)(object)_font == (Object)null)
			{
				TMP_FontAsset[] array = Resources.FindObjectsOfTypeAll<TMP_FontAsset>();
				if (array != null && array.Length != 0)
				{
					_font = array[0];
				}
			}
			return _font;
		}
	}
}