Decompiled source of FindTomb v1.0.8

FindTomb.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Splatform;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 FindTomb
{
	[BepInPlugin("captain.FindTomb", "Find Tomb", "1.0.8")]
	public class Plugin : BaseUnityPlugin
	{
		public static Plugin Instance;

		public static ConfigEntry<bool> ModEnabled;

		public static ConfigEntry<int> MaxTrackedGraves;

		public static ConfigEntry<bool> ShowMinimapPins;

		public static ConfigEntry<bool> ShowDirectionVFX;

		public static ConfigEntry<KeyboardShortcut> CancelTrackingKey;

		public static ConfigEntry<KeyboardShortcut> CycleNextGraveKey;

		public static ManualLogSource Log { get; private set; }

		private void Awake()
		{
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			ModEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable this mod");
			MaxTrackedGraves = ((BaseUnityPlugin)this).Config.Bind<int>("General", "MaxTrackedGraves", 5, "Number of recent graves to track and color (1-5)");
			ShowMinimapPins = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowMinimapPins", true, "Color-code recent grave pins on the map");
			ShowDirectionVFX = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowDirectionVFX", true, "Show a compass VFX pointing to your oldest unrecovered grave");
			bool flag = IsKoreanLanguage();
			CancelTrackingKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Controls", "CancelTrackingKey", new KeyboardShortcut((KeyCode)120, (KeyCode[])(object)new KeyCode[1] { (KeyCode)306 }), flag ? "다음 죽음 전까지 무덤 방향 표시를 숨깁니다" : "Hides the grave direction indicator until your next death");
			CycleNextGraveKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Controls", "CycleNextGraveKey", new KeyboardShortcut((KeyCode)46, (KeyCode[])(object)new KeyCode[1] { (KeyCode)306 }), flag ? "무덤 방향 표시를 다음 무덤으로 전환합니다" : "Points the direction indicator at the next grave");
			if (ModEnabled.Value)
			{
				Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null);
				((MonoBehaviour)this).InvokeRepeating("ReconcileTick", 2f, 2f);
				DebugCommands.Register();
				Log.LogMessage((object)"[FindTomb] FindTomb 1.0.7 Loaded!");
			}
		}

		private void ReconcileTick()
		{
			if (ModEnabled.Value && ShowMinimapPins.Value)
			{
				MinimapPinReconciler.Reconcile();
			}
		}

		private static bool IsKoreanLanguage()
		{
			return PlayerPrefs.GetString("language", "English") == "Korean";
		}
	}
	public static class DebugCommands
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static ConsoleEvent <>9__0_0;

			public static ConsoleEvent <>9__0_1;

			public static ConsoleEvent <>9__0_2;

			public static ConsoleEvent <>9__0_3;

			internal void <Register>b__0_0(ConsoleEventArgs args)
			{
				Terminal context = args.Context;
				if ((Object)(object)context == (Object)null || (Object)(object)ZNetScene.instance == (Object)null)
				{
					return;
				}
				string text = ((args.Length >= 2) ? args[1].ToLowerInvariant() : "");
				int num = 0;
				foreach (GameObject prefab in ZNetScene.instance.m_prefabs)
				{
					if ((Object)(object)prefab == (Object)null)
					{
						continue;
					}
					string name = ((Object)prefab).name;
					if (text.Length == 0 || name.ToLowerInvariant().Contains(text))
					{
						context.AddString(name);
						num++;
						if (num >= 80)
						{
							context.AddString("[FindTomb] ...80개 이상, 더 구체적인 키워드로 다시 검색");
							break;
						}
					}
				}
				context.AddString($"[FindTomb] {num}개 발견 (keyword='{text}')");
			}

			internal void <Register>b__0_1(ConsoleEventArgs args)
			{
				//IL_009b: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
				//IL_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_00ba: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d0: 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_00dc: Unknown result type (might be due to invalid IL or missing references)
				Terminal context = args.Context;
				Player localPlayer = Player.m_localPlayer;
				if ((Object)(object)context == (Object)null || (Object)(object)localPlayer == (Object)null || (Object)(object)ZNetScene.instance == (Object)null)
				{
					return;
				}
				if (args.Length < 2)
				{
					context.AddString("[FindTomb] 사용법: findtomb_previewvfx <prefabName>");
					return;
				}
				GameObject prefab = ZNetScene.instance.GetPrefab(args[1]);
				if ((Object)(object)prefab == (Object)null)
				{
					context.AddString("[FindTomb] 프리팹을 찾을 수 없음: " + args[1]);
					return;
				}
				Vector3 val = ((Component)localPlayer).transform.position + ((Component)localPlayer).transform.forward * 2f + Vector3.up * 1.5f;
				GameObject val2 = Object.Instantiate<GameObject>(prefab, val, Quaternion.LookRotation(((Component)localPlayer).transform.forward));
				Object.Destroy((Object)(object)val2, 5f);
				context.AddString("[FindTomb] 미리보기 생성: " + args[1]);
			}

			internal void <Register>b__0_2(ConsoleEventArgs args)
			{
				Terminal context = args.Context;
				if ((Object)(object)context == (Object)null || (Object)(object)ZNetScene.instance == (Object)null)
				{
					return;
				}
				if (args.Length < 2)
				{
					context.AddString("[FindTomb] 사용법: findtomb_dumpcomponents <prefabName>");
					return;
				}
				GameObject prefab = ZNetScene.instance.GetPrefab(args[1]);
				if ((Object)(object)prefab == (Object)null)
				{
					context.AddString("[FindTomb] 프리팹을 찾을 수 없음: " + args[1]);
					return;
				}
				Piece component = prefab.GetComponent<Piece>();
				if ((Object)(object)component != (Object)null)
				{
					context.AddString("[FindTomb] 이름: " + component.m_name + " -> " + Localization.instance.Localize(component.m_name));
				}
				Transform[] componentsInChildren = prefab.GetComponentsInChildren<Transform>(true);
				foreach (Transform val in componentsInChildren)
				{
					Component[] components = ((Component)val).GetComponents<Component>();
					string text = string.Empty;
					Component[] array = components;
					foreach (Component val2 in array)
					{
						if ((Object)(object)val2 != (Object)null)
						{
							text = text + ((object)val2).GetType().Name + ", ";
						}
					}
					context.AddString("[FindTomb] " + ((Object)val).name + ": " + text);
				}
				StationExtension componentInChildren = prefab.GetComponentInChildren<StationExtension>(true);
				if ((Object)(object)componentInChildren != (Object)null)
				{
					string text2 = (((Object)(object)componentInChildren.m_connectionPrefab != (Object)null) ? ((Object)componentInChildren.m_connectionPrefab).name : "null");
					context.AddString("[FindTomb] StationExtension 발견: m_connectionPrefab=" + text2);
				}
				else
				{
					context.AddString("[FindTomb] StationExtension 컴포넌트 없음");
				}
			}

			internal void <Register>b__0_3(ConsoleEventArgs args)
			{
				//IL_00df: 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_0098: Unknown result type (might be due to invalid IL or missing references)
				//IL_0166: Unknown result type (might be due to invalid IL or missing references)
				Terminal context = args.Context;
				if ((Object)(object)context == (Object)null)
				{
					return;
				}
				IReadOnlyList<TombRecord> current = TombTrackerManager.Current;
				context.AddString($"[FindTomb] 추적 중인 무덤 {current.Count}개");
				TombStone[] array = Object.FindObjectsOfType<TombStone>();
				for (int i = 0; i < current.Count; i++)
				{
					TombRecord tombRecord = current[i];
					TombStone val = null;
					TombStone[] array2 = array;
					foreach (TombStone val2 in array2)
					{
						if ((Object)(object)val2.m_nview != (Object)null && val2.m_nview.IsValid() && val2.m_nview.GetZDO().m_uid == tombRecord.ZdoId)
						{
							val = val2;
							break;
						}
					}
					if ((Object)(object)val == (Object)null)
					{
						context.AddString($"[FindTomb] [{i}] {tombRecord.ZdoId} - 씬에서 TombStone을 못 찾음(로드 안 된 구역이거나 이미 파괴됨)");
						continue;
					}
					bool flag = val.m_nview.IsOwner();
					bool flag2 = (Object)(object)val.m_container != (Object)null && val.m_container.IsInUse();
					int num = (((Object)(object)val.m_container != (Object)null) ? val.m_container.GetInventory().NrOfItems() : (-1));
					context.AddString($"[FindTomb] [{i}] {tombRecord.ZdoId} - IsOwner={flag}, IsInUse={flag2}, NrOfItems={num}");
				}
			}
		}

		public static void Register()
		{
			//IL_0034: 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_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			//IL_00a6: 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_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Expected O, but got Unknown
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Expected O, but got Unknown
			object obj = <>c.<>9__0_0;
			if (obj == null)
			{
				ConsoleEvent val = delegate(ConsoleEventArgs args)
				{
					Terminal context = args.Context;
					if (!((Object)(object)context == (Object)null) && !((Object)(object)ZNetScene.instance == (Object)null))
					{
						string text = ((args.Length >= 2) ? args[1].ToLowerInvariant() : "");
						int num = 0;
						foreach (GameObject prefab2 in ZNetScene.instance.m_prefabs)
						{
							if (!((Object)(object)prefab2 == (Object)null))
							{
								string name = ((Object)prefab2).name;
								if (text.Length == 0 || name.ToLowerInvariant().Contains(text))
								{
									context.AddString(name);
									num++;
									if (num >= 80)
									{
										context.AddString("[FindTomb] ...80개 이상, 더 구체적인 키워드로 다시 검색");
										break;
									}
								}
							}
						}
						context.AddString($"[FindTomb] {num}개 발견 (keyword='{text}')");
					}
				};
				<>c.<>9__0_0 = val;
				obj = (object)val;
			}
			new ConsoleCommand("findtomb_dumpprefabs", "[keyword] - FindTomb: ZNetScene 프리팹 중 이름에 keyword가 포함된 항목을 나열", (ConsoleEvent)obj, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
			object obj2 = <>c.<>9__0_1;
			if (obj2 == null)
			{
				ConsoleEvent val2 = delegate(ConsoleEventArgs args)
				{
					//IL_009b: Unknown result type (might be due to invalid IL or missing references)
					//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
					//IL_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_00ba: Unknown result type (might be due to invalid IL or missing references)
					//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
					//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
					//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
					//IL_00d0: 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_00dc: Unknown result type (might be due to invalid IL or missing references)
					Terminal context = args.Context;
					Player localPlayer = Player.m_localPlayer;
					if (!((Object)(object)context == (Object)null) && !((Object)(object)localPlayer == (Object)null) && !((Object)(object)ZNetScene.instance == (Object)null))
					{
						if (args.Length < 2)
						{
							context.AddString("[FindTomb] 사용법: findtomb_previewvfx <prefabName>");
						}
						else
						{
							GameObject prefab = ZNetScene.instance.GetPrefab(args[1]);
							if ((Object)(object)prefab == (Object)null)
							{
								context.AddString("[FindTomb] 프리팹을 찾을 수 없음: " + args[1]);
							}
							else
							{
								Vector3 val5 = ((Component)localPlayer).transform.position + ((Component)localPlayer).transform.forward * 2f + Vector3.up * 1.5f;
								GameObject val6 = Object.Instantiate<GameObject>(prefab, val5, Quaternion.LookRotation(((Component)localPlayer).transform.forward));
								Object.Destroy((Object)(object)val6, 5f);
								context.AddString("[FindTomb] 미리보기 생성: " + args[1]);
							}
						}
					}
				};
				<>c.<>9__0_1 = val2;
				obj2 = (object)val2;
			}
			new ConsoleCommand("findtomb_previewvfx", "[prefabName] - FindTomb: 지정한 프리팹을 플레이어 앞에 5초간 생성해 미리보기", (ConsoleEvent)obj2, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
			object obj3 = <>c.<>9__0_2;
			if (obj3 == null)
			{
				ConsoleEvent val3 = delegate(ConsoleEventArgs args)
				{
					Terminal context = args.Context;
					if (!((Object)(object)context == (Object)null) && !((Object)(object)ZNetScene.instance == (Object)null))
					{
						if (args.Length < 2)
						{
							context.AddString("[FindTomb] 사용법: findtomb_dumpcomponents <prefabName>");
						}
						else
						{
							GameObject prefab = ZNetScene.instance.GetPrefab(args[1]);
							if ((Object)(object)prefab == (Object)null)
							{
								context.AddString("[FindTomb] 프리팹을 찾을 수 없음: " + args[1]);
							}
							else
							{
								Piece component = prefab.GetComponent<Piece>();
								if ((Object)(object)component != (Object)null)
								{
									context.AddString("[FindTomb] 이름: " + component.m_name + " -> " + Localization.instance.Localize(component.m_name));
								}
								Transform[] componentsInChildren = prefab.GetComponentsInChildren<Transform>(true);
								foreach (Transform val5 in componentsInChildren)
								{
									Component[] components = ((Component)val5).GetComponents<Component>();
									string text = string.Empty;
									Component[] array = components;
									foreach (Component val6 in array)
									{
										if ((Object)(object)val6 != (Object)null)
										{
											text = text + ((object)val6).GetType().Name + ", ";
										}
									}
									context.AddString("[FindTomb] " + ((Object)val5).name + ": " + text);
								}
								StationExtension componentInChildren = prefab.GetComponentInChildren<StationExtension>(true);
								if ((Object)(object)componentInChildren != (Object)null)
								{
									string text2 = (((Object)(object)componentInChildren.m_connectionPrefab != (Object)null) ? ((Object)componentInChildren.m_connectionPrefab).name : "null");
									context.AddString("[FindTomb] StationExtension 발견: m_connectionPrefab=" + text2);
								}
								else
								{
									context.AddString("[FindTomb] StationExtension 컴포넌트 없음");
								}
							}
						}
					}
				};
				<>c.<>9__0_2 = val3;
				obj3 = (object)val3;
			}
			new ConsoleCommand("findtomb_dumpcomponents", "[prefabName] - FindTomb: 지정한 프리팹의 루트+자식 컴포넌트 목록을 출력", (ConsoleEvent)obj3, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
			object obj4 = <>c.<>9__0_3;
			if (obj4 == null)
			{
				ConsoleEvent val4 = delegate(ConsoleEventArgs args)
				{
					//IL_00df: 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_0098: Unknown result type (might be due to invalid IL or missing references)
					//IL_0166: Unknown result type (might be due to invalid IL or missing references)
					Terminal context = args.Context;
					if (!((Object)(object)context == (Object)null))
					{
						IReadOnlyList<TombRecord> current = TombTrackerManager.Current;
						context.AddString($"[FindTomb] 추적 중인 무덤 {current.Count}개");
						TombStone[] array = Object.FindObjectsOfType<TombStone>();
						for (int i = 0; i < current.Count; i++)
						{
							TombRecord tombRecord = current[i];
							TombStone val5 = null;
							TombStone[] array2 = array;
							foreach (TombStone val6 in array2)
							{
								if ((Object)(object)val6.m_nview != (Object)null && val6.m_nview.IsValid() && val6.m_nview.GetZDO().m_uid == tombRecord.ZdoId)
								{
									val5 = val6;
									break;
								}
							}
							if ((Object)(object)val5 == (Object)null)
							{
								context.AddString($"[FindTomb] [{i}] {tombRecord.ZdoId} - 씬에서 TombStone을 못 찾음(로드 안 된 구역이거나 이미 파괴됨)");
							}
							else
							{
								bool flag = val5.m_nview.IsOwner();
								bool flag2 = (Object)(object)val5.m_container != (Object)null && val5.m_container.IsInUse();
								int num = (((Object)(object)val5.m_container != (Object)null) ? val5.m_container.GetInventory().NrOfItems() : (-1));
								context.AddString($"[FindTomb] [{i}] {tombRecord.ZdoId} - IsOwner={flag}, IsInUse={flag2}, NrOfItems={num}");
							}
						}
					}
				};
				<>c.<>9__0_3 = val4;
				obj4 = (object)val4;
			}
			new ConsoleCommand("findtomb_status", "FindTomb: 추적 중인 무덤 목록과 각 TombStone의 소유권/컨테이너 상태를 출력", (ConsoleEvent)obj4, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
		}
	}
	public class GraveDirectionVFX : MonoBehaviour
	{
		private static readonly Vector3 AnchorOffset = new Vector3(0f, 1.7f, 0.3f);

		private const float MinVfxLength = 1f;

		private const float MaxVfxLength = 8f;

		private const float DistanceToLengthDivisor = 5f;

		private const string SourceStationPieceName = "piece_workbench_ext1";

		private static GameObject _cachedConnectionPrefab;

		private static bool _resolveFailed;

		private GameObject _vfxInstance;

		private void OnDestroy()
		{
			DestroyVfxInstance();
		}

		private void Update()
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: 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_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: 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_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			IReadOnlyList<TombRecord> current = TombTrackerManager.Current;
			HandleHotkeys(current.Count);
			if (!Plugin.ModEnabled.Value || !Plugin.ShowDirectionVFX.Value || GraveTrackingState.IsCancelled)
			{
				DestroyVfxInstance();
				return;
			}
			int num = GraveTrackingState.ResolveIndex(current.Count);
			if (num < 0)
			{
				DestroyVfxInstance();
				return;
			}
			Vector3 position = current[num].Position;
			Vector3 val = ((Component)this).transform.TransformPoint(AnchorOffset);
			Vector3 val2 = position - val;
			val2.y = 0f;
			float magnitude = ((Vector3)(ref val2)).magnitude;
			if (!(magnitude < 0.1f))
			{
				EnsureVfxInstance();
				if (!((Object)(object)_vfxInstance == (Object)null))
				{
					float num2 = Mathf.Clamp(magnitude / 5f, 1f, 8f);
					_vfxInstance.transform.position = val;
					_vfxInstance.transform.rotation = Quaternion.LookRotation(val2 / magnitude);
					_vfxInstance.transform.localScale = new Vector3(1f, 1f, num2);
				}
			}
		}

		private static void HandleHotkeys(int graveCount)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			if (graveCount != 0)
			{
				KeyboardShortcut value = Plugin.CancelTrackingKey.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					GraveTrackingState.Cancel();
				}
				value = Plugin.CycleNextGraveKey.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					GraveTrackingState.CycleNext(graveCount);
				}
			}
		}

		private void EnsureVfxInstance()
		{
			if (!((Object)(object)_vfxInstance != (Object)null))
			{
				GameObject val = ResolveConnectionVfxPrefab();
				if (!((Object)(object)val == (Object)null))
				{
					_vfxInstance = Object.Instantiate<GameObject>(val);
				}
			}
		}

		public static void ResetPrefabCache()
		{
			_cachedConnectionPrefab = null;
			_resolveFailed = false;
		}

		private static GameObject ResolveConnectionVfxPrefab()
		{
			if ((Object)(object)_cachedConnectionPrefab != (Object)null)
			{
				return _cachedConnectionPrefab;
			}
			if (_resolveFailed || (Object)(object)ZNetScene.instance == (Object)null)
			{
				return null;
			}
			GameObject prefab = ZNetScene.instance.GetPrefab("piece_workbench_ext1");
			StationExtension val = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<StationExtension>() : null);
			if ((Object)(object)val == (Object)null || (Object)(object)val.m_connectionPrefab == (Object)null)
			{
				Plugin.Log.LogWarning((object)"[FindTomb] 'piece_workbench_ext1'에서 연결 VFX 프리팹을 찾지 못함.");
				_resolveFailed = true;
				return null;
			}
			_cachedConnectionPrefab = val.m_connectionPrefab;
			return _cachedConnectionPrefab;
		}

		private void DestroyVfxInstance()
		{
			if ((Object)(object)_vfxInstance != (Object)null)
			{
				Object.Destroy((Object)(object)_vfxInstance);
				_vfxInstance = null;
			}
		}
	}
	public static class GraveTrackingState
	{
		private static bool _cancelled;

		private static int _manualIndex = -1;

		public static bool IsCancelled => _cancelled;

		public static void Cancel()
		{
			_cancelled = true;
		}

		public static void CycleNext(int graveCount)
		{
			if (graveCount > 0)
			{
				_cancelled = false;
				int num = ResolveIndex(graveCount);
				_manualIndex = (num - 1 + graveCount) % graveCount;
			}
		}

		public static int ResolveIndex(int graveCount)
		{
			if (graveCount <= 0)
			{
				return -1;
			}
			if (_manualIndex < 0 || _manualIndex >= graveCount)
			{
				return graveCount - 1;
			}
			return _manualIndex;
		}

		public static int ResolveRank(int graveCount)
		{
			return TombTier.DeathOrderRank(ResolveIndex(graveCount), graveCount);
		}

		public static void ResetOnNewDeath()
		{
			_cancelled = false;
			_manualIndex = -1;
		}
	}
	public static class MinimapPinReconciler
	{
		private const float MatchToleranceXZ = 2f;

		private const float FallbackTimeoutSeconds = 8f;

		private const float NumberLabelFontSize = 22f;

		private static readonly Vector2 NumberLabelSize = new Vector2(28f, 28f);

		private static readonly Vector2 NumberLabelOffset = new Vector2(0f, 2f);

		private static readonly Dictionary<ZDOID, PinData> _linked = new Dictionary<ZDOID, PinData>();

		private static readonly Dictionary<ZDOID, float> _unlinkedSince = new Dictionary<ZDOID, float>();

		private static readonly Dictionary<ZDOID, GameObject> _numberLabels = new Dictionary<ZDOID, GameObject>();

		private static bool _subscribed;

		private static Font _numberLabelFont;

		private static void EnsureSubscribed()
		{
			if (!_subscribed)
			{
				TombTrackerManager.OnGraveListChanged += PruneStaleLinks;
				_subscribed = true;
			}
		}

		public static void TryLinkFromAddPin(Vector3 pos, PinData pinData)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			EnsureSubscribed();
			IReadOnlyList<TombRecord> current = TombTrackerManager.Current;
			for (int i = 0; i < current.Count; i++)
			{
				TombRecord tombRecord = current[i];
				if (!_linked.ContainsKey(tombRecord.ZdoId) && IsCloseXZ(tombRecord.Position, pos))
				{
					_linked[tombRecord.ZdoId] = pinData;
					_unlinkedSince.Remove(tombRecord.ZdoId);
					break;
				}
			}
		}

		public static void ResetForNewSession()
		{
			_linked.Clear();
			_unlinkedSince.Clear();
			foreach (KeyValuePair<ZDOID, GameObject> numberLabel in _numberLabels)
			{
				if ((Object)(object)numberLabel.Value != (Object)null)
				{
					Object.Destroy((Object)(object)numberLabel.Value);
				}
			}
			_numberLabels.Clear();
		}

		public static void Reconcile()
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: 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_020d: 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_012e: 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_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			EnsureSubscribed();
			if ((Object)(object)Minimap.instance == (Object)null)
			{
				return;
			}
			IReadOnlyList<TombRecord> current = TombTrackerManager.Current;
			List<ZDOID> list = null;
			for (int i = 0; i < current.Count; i++)
			{
				TombRecord tombRecord = current[i];
				if (_linked.TryGetValue(tombRecord.ZdoId, out var value))
				{
					if (value != null && Minimap.instance.m_pins.Contains(value))
					{
						continue;
					}
					_linked.Remove(tombRecord.ZdoId);
				}
				PinData val = FindNearbyUnlinkedDeathPin(tombRecord.Position);
				float value2;
				if (val != null)
				{
					_linked[tombRecord.ZdoId] = val;
					_unlinkedSince.Remove(tombRecord.ZdoId);
				}
				else if (!_unlinkedSince.TryGetValue(tombRecord.ZdoId, out value2))
				{
					_unlinkedSince[tombRecord.ZdoId] = Time.time;
				}
				else
				{
					if (!(Time.time - value2 >= 8f))
					{
						continue;
					}
					if (ZDOMan.instance != null && ZDOMan.instance.GetZDO(tombRecord.ZdoId) == null)
					{
						if (list == null)
						{
							list = new List<ZDOID>();
						}
						list.Add(tombRecord.ZdoId);
						_unlinkedSince.Remove(tombRecord.ZdoId);
						Plugin.Log.LogMessage((object)$"[FindTomb] ZDO가 더 이상 존재하지 않음(이미 회수됨) - 추적 해제: {tombRecord.ZdoId}");
					}
					else
					{
						PinData value3 = Minimap.instance.AddPin(tombRecord.Position, (PinType)4, "", true, false, 0L, default(PlatformUserID));
						_linked[tombRecord.ZdoId] = value3;
						_unlinkedSince.Remove(tombRecord.ZdoId);
					}
				}
			}
			if (list != null)
			{
				for (int j = 0; j < list.Count; j++)
				{
					TombTrackerManager.RemoveByZdoId(list[j]);
				}
			}
		}

		public static void ApplyTierColors()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: 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_0053: Unknown result type (might be due to invalid IL or missing references)
			IReadOnlyList<TombRecord> current = TombTrackerManager.Current;
			for (int i = 0; i < current.Count; i++)
			{
				ZDOID zdoId = current[i].ZdoId;
				if (_linked.TryGetValue(zdoId, out var value) && value != null && (Object)(object)value.m_iconElement != (Object)null)
				{
					((Graphic)value.m_iconElement).color = TombTier.GetColor(i);
					ApplyNumberLabel(zdoId, value, TombTier.DeathOrderRank(i, current.Count));
				}
			}
		}

		private static void ApplyNumberLabel(ZDOID id, PinData pin, int rank)
		{
			//IL_0019: 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)
			if (!((Object)(object)pin.m_uiElement == (Object)null))
			{
				if (!_numberLabels.TryGetValue(id, out var value) || (Object)(object)value == (Object)null || (Object)(object)value.transform.parent != (Object)(object)pin.m_uiElement)
				{
					value = CreateNumberLabel(pin.m_uiElement);
					_numberLabels[id] = value;
				}
				Text component = value.GetComponent<Text>();
				if ((Object)(object)component != (Object)null)
				{
					component.text = rank.ToString();
				}
			}
		}

		private static Font GetNumberLabelFont()
		{
			if ((Object)(object)_numberLabelFont != (Object)null)
			{
				return _numberLabelFont;
			}
			_numberLabelFont = Font.CreateDynamicFontFromOSFont("Arial", 22);
			if ((Object)(object)_numberLabelFont == (Object)null)
			{
				_numberLabelFont = Resources.GetBuiltinResource<Font>("Arial.ttf");
			}
			return _numberLabelFont;
		}

		private static GameObject CreateNumberLabel(RectTransform parent)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			//IL_0061: 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_008d: 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_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: 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_011e: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("FindTombPinNumber", new Type[4]
			{
				typeof(RectTransform),
				typeof(CanvasRenderer),
				typeof(Text),
				typeof(Outline)
			});
			RectTransform component = val.GetComponent<RectTransform>();
			((Transform)component).SetParent((Transform)(object)parent, false);
			component.anchorMin = new Vector2(0.5f, 1f);
			component.anchorMax = new Vector2(0.5f, 1f);
			component.pivot = new Vector2(0.5f, 0f);
			component.anchoredPosition = NumberLabelOffset;
			component.sizeDelta = NumberLabelSize;
			Text component2 = val.GetComponent<Text>();
			component2.font = GetNumberLabelFont();
			component2.fontSize = 22;
			component2.fontStyle = (FontStyle)1;
			((Graphic)component2).color = Color.white;
			component2.alignment = (TextAnchor)4;
			component2.verticalOverflow = (VerticalWrapMode)1;
			component2.horizontalOverflow = (HorizontalWrapMode)1;
			((Graphic)component2).raycastTarget = false;
			Outline component3 = val.GetComponent<Outline>();
			((Shadow)component3).effectColor = Color.black;
			((Shadow)component3).effectDistance = new Vector2(1.2f, -1.2f);
			return val;
		}

		private static PinData FindNearbyUnlinkedDeathPin(Vector3 pos)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Invalid comparison between Unknown and I4
			//IL_003b: 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)
			List<PinData> pins = Minimap.instance.m_pins;
			for (int i = 0; i < pins.Count; i++)
			{
				PinData val = pins[i];
				if ((int)val.m_type == 4 && !IsLinkedToOther(val) && IsCloseXZ(pos, val.m_pos))
				{
					return val;
				}
			}
			return null;
		}

		private static bool IsLinkedToOther(PinData pin)
		{
			foreach (KeyValuePair<ZDOID, PinData> item in _linked)
			{
				if (item.Value == pin)
				{
					return true;
				}
			}
			return false;
		}

		private static bool IsCloseXZ(Vector3 a, Vector3 b)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: 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)
			float num = a.x - b.x;
			float num2 = a.z - b.z;
			return num * num + num2 * num2 <= 4f;
		}

		private static void PruneStaleLinks()
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			IReadOnlyList<TombRecord> current = TombTrackerManager.Current;
			List<ZDOID> list = new List<ZDOID>();
			foreach (KeyValuePair<ZDOID, PinData> item in _linked)
			{
				bool flag = false;
				for (int i = 0; i < current.Count; i++)
				{
					if (current[i].ZdoId == item.Key)
					{
						flag = true;
						break;
					}
				}
				if (!flag)
				{
					list.Add(item.Key);
				}
			}
			foreach (ZDOID item2 in list)
			{
				_linked.Remove(item2);
				_unlinkedSince.Remove(item2);
				if (_numberLabels.TryGetValue(item2, out var value))
				{
					if ((Object)(object)value != (Object)null)
					{
						Object.Destroy((Object)(object)value);
					}
					_numberLabels.Remove(item2);
				}
			}
		}
	}
	public struct TombRecord
	{
		public ZDOID ZdoId;

		public Vector3 Position;

		public long DeathTimeTicks;

		public TombRecord(ZDOID zdoId, Vector3 position, long deathTimeTicks)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: 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_000a: Unknown result type (might be due to invalid IL or missing references)
			ZdoId = zdoId;
			Position = position;
			DeathTimeTicks = deathTimeTicks;
		}
	}
	public static class TombTier
	{
		public static readonly Color[] Colors = (Color[])(object)new Color[5]
		{
			new Color(1f, 0.231f, 0.188f),
			new Color(1f, 0.498f, 0.769f),
			new Color(1f, 0.584f, 0f),
			new Color(1f, 0.839f, 0.039f),
			new Color(1f, 1f, 1f)
		};

		public static Color GetColor(int tierIndex)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0030: Unknown result type (might be due to invalid IL or missing references)
			if (tierIndex < 0 || tierIndex >= Colors.Length)
			{
				return Color.white;
			}
			return Colors[tierIndex];
		}

		public static int DeathOrderRank(int index, int count)
		{
			if (index < 0 || count <= 0 || index >= count)
			{
				return 0;
			}
			return count - index;
		}
	}
	public static class TombTrackerManager
	{
		public const int MaxGraves = 5;

		private static readonly List<TombRecord> _records = new List<TombRecord>();

		private static long _loadedWorldUID = long.MinValue;

		private static bool _hasLoadedWorld = false;

		public static IReadOnlyList<TombRecord> Current
		{
			get
			{
				EnsureLoadedForCurrentWorld();
				return _records;
			}
		}

		public static event Action OnGraveListChanged;

		public static void RegisterDeath(ZDOID zdoId, Vector3 position, long deathTimeTicks)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			EnsureLoadedForCurrentWorld();
			_records.RemoveAll((TombRecord r) => r.ZdoId == zdoId);
			_records.Insert(0, new TombRecord(zdoId, position, deathTimeTicks));
			while (_records.Count > 5)
			{
				_records.RemoveAt(_records.Count - 1);
			}
			Save();
			GraveTrackingState.ResetOnNewDeath();
			TombTrackerManager.OnGraveListChanged?.Invoke();
		}

		public static bool RemoveByZdoId(ZDOID zdoId)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			EnsureLoadedForCurrentWorld();
			int num = _records.RemoveAll((TombRecord r) => r.ZdoId == zdoId);
			if (num <= 0)
			{
				return false;
			}
			Save();
			TombTrackerManager.OnGraveListChanged?.Invoke();
			return true;
		}

		public static int IndexOf(ZDOID zdoId)
		{
			//IL_0017: 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)
			EnsureLoadedForCurrentWorld();
			for (int i = 0; i < _records.Count; i++)
			{
				if (_records[i].ZdoId == zdoId)
				{
					return i;
				}
			}
			return -1;
		}

		private static void EnsureLoadedForCurrentWorld()
		{
			if (WorldContext.TryGetWorldUID(out var worldUID) && (!_hasLoadedWorld || worldUID != _loadedWorldUID))
			{
				_records.Clear();
				Load(worldUID);
				_loadedWorldUID = worldUID;
				_hasLoadedWorld = true;
				TombTrackerManager.OnGraveListChanged?.Invoke();
			}
		}

		private static void Load(long worldUID)
		{
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return;
			}
			string saveKey = WorldContext.GetSaveKey(worldUID);
			if (!localPlayer.m_customData.TryGetValue(saveKey, out var value) || string.IsNullOrEmpty(value))
			{
				return;
			}
			string[] array = value.Split(';');
			string[] array2 = array;
			foreach (string text in array2)
			{
				if (!string.IsNullOrEmpty(text))
				{
					string[] array3 = text.Split(',');
					if (array3.Length == 5 && WorldContext.TryParseZdoId(array3[0], out var id) && float.TryParse(array3[1], out var result) && float.TryParse(array3[2], out var result2) && float.TryParse(array3[3], out var result3) && long.TryParse(array3[4], out var result4))
					{
						_records.Add(new TombRecord(id, new Vector3(result, result2, result3), result4));
					}
				}
			}
			if (_records.Count > 5)
			{
				_records.RemoveRange(5, _records.Count - 5);
			}
		}

		private static void Save()
		{
			//IL_008c: 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_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || !_hasLoadedWorld)
			{
				return;
			}
			string saveKey = WorldContext.GetSaveKey(_loadedWorldUID);
			if (_records.Count == 0)
			{
				localPlayer.m_customData.Remove(saveKey);
				return;
			}
			StringBuilder stringBuilder = new StringBuilder();
			for (int i = 0; i < _records.Count; i++)
			{
				TombRecord tombRecord = _records[i];
				if (i > 0)
				{
					stringBuilder.Append(';');
				}
				stringBuilder.Append(WorldContext.SerializeZdoId(tombRecord.ZdoId)).Append(',').Append(tombRecord.Position.x)
					.Append(',')
					.Append(tombRecord.Position.y)
					.Append(',')
					.Append(tombRecord.Position.z)
					.Append(',')
					.Append(tombRecord.DeathTimeTicks);
			}
			localPlayer.m_customData[saveKey] = stringBuilder.ToString();
		}
	}
	public static class WorldContext
	{
		public static bool TryGetWorldUID(out long worldUID)
		{
			worldUID = 0L;
			if ((Object)(object)ZNet.instance == (Object)null)
			{
				return false;
			}
			World world = ZNet.m_world;
			if (world == null)
			{
				return false;
			}
			worldUID = world.m_uid;
			return true;
		}

		public static string GetSaveKey(long worldUID)
		{
			return "FindTomb.W" + worldUID;
		}

		public static string SerializeZdoId(ZDOID id)
		{
			return ((ZDOID)(ref id)).UserID + ":" + ((ZDOID)(ref id)).ID;
		}

		public static bool TryParseZdoId(string text, out ZDOID id)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: 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)
			id = ZDOID.None;
			if (string.IsNullOrEmpty(text))
			{
				return false;
			}
			int num = text.IndexOf(':');
			if (num < 0)
			{
				return false;
			}
			if (!long.TryParse(text.Substring(0, num), out var result))
			{
				return false;
			}
			if (!uint.TryParse(text.Substring(num + 1), out var result2))
			{
				return false;
			}
			id = new ZDOID(result, result2);
			return true;
		}
	}
}
namespace FindTomb.Patches
{
	[HarmonyPatch(typeof(Minimap))]
	internal static class MinimapPatches
	{
		[HarmonyPatch("AddPin")]
		[HarmonyPostfix]
		private static void AddPin_Postfix(Vector3 pos, PinType type, PinData __result)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Invalid comparison between Unknown and I4
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			if (Plugin.ModEnabled.Value && Plugin.ShowMinimapPins.Value && (int)type == 4)
			{
				MinimapPinReconciler.TryLinkFromAddPin(pos, __result);
			}
		}

		[HarmonyPatch("UpdatePins")]
		[HarmonyPostfix]
		private static void UpdatePins_Postfix()
		{
			if (Plugin.ModEnabled.Value && Plugin.ShowMinimapPins.Value)
			{
				MinimapPinReconciler.ApplyTierColors();
			}
		}
	}
	[HarmonyPatch(typeof(Player))]
	internal static class PlayerPatches
	{
		[HarmonyPatch("SetLocalPlayer")]
		[HarmonyPostfix]
		private static void SetLocalPlayer_Postfix(Player __instance)
		{
			GraveDirectionVFX.ResetPrefabCache();
			MinimapPinReconciler.ResetForNewSession();
			if ((Object)(object)((Component)__instance).GetComponent<GraveDirectionVFX>() == (Object)null)
			{
				((Component)__instance).gameObject.AddComponent<GraveDirectionVFX>();
			}
		}
	}
	[HarmonyPatch(typeof(TombStone))]
	internal static class TombStonePatches
	{
		[HarmonyPatch("Setup")]
		[HarmonyPostfix]
		private static void Setup_Postfix(TombStone __instance, long ownerUID)
		{
			//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_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			if (Plugin.ModEnabled.Value)
			{
				ZNetView nview = __instance.m_nview;
				if (!((Object)(object)nview == (Object)null) && nview.IsValid())
				{
					ZDOID uid = nview.GetZDO().m_uid;
					long deathTimeTicks = (((Object)(object)ZNet.instance != (Object)null) ? ZNet.instance.GetTime().Ticks : 0);
					TombTrackerManager.RegisterDeath(uid, ((Component)__instance).transform.position, deathTimeTicks);
					Plugin.Log.LogMessage((object)$"[FindTomb] Grave registered: {uid} at {((Component)__instance).transform.position}");
				}
			}
		}

		[HarmonyPatch("UpdateDespawn")]
		[HarmonyPrefix]
		private static void UpdateDespawn_Prefix(TombStone __instance)
		{
			//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_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			if (Plugin.ModEnabled.Value && !((Object)(object)__instance.m_nview == (Object)null) && __instance.m_nview.IsValid() && __instance.m_nview.IsOwner() && !((Object)(object)__instance.m_container == (Object)null) && !__instance.m_container.IsInUse() && __instance.m_container.GetInventory().NrOfItems() <= 0)
			{
				ZDOID uid = __instance.m_nview.GetZDO().m_uid;
				if (TombTrackerManager.RemoveByZdoId(uid))
				{
					Plugin.Log.LogMessage((object)$"[FindTomb] Grave emptied and removed: {uid}");
				}
			}
		}
	}
}