Decompiled source of Venture Location Reset v0.8.2

Plugins/VentureValheim.LocationReset.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using SoftReferenceableAssets;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("VentureValheim.LocationReset")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("VentureValheim.LocationReset")]
[assembly: AssemblyCopyright("Copyright ©  2022")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("5839B48D-2903-47E1-99CE-754FEF597DF7")]
[assembly: AssemblyFileVersion("0.8.2")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.8.2.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace VentureValheim.LocationReset
{
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("com.orianaventure.mod.LocationReset", "LocationReset", "0.8.2")]
	public class LocationResetPlugin : BaseUnityPlugin
	{
		private static readonly LocationResetPlugin _instance;

		private const string ModName = "LocationReset";

		private const string ModVersion = "0.8.2";

		private const string Author = "com.orianaventure.mod";

		private const string ModGUID = "com.orianaventure.mod.LocationReset";

		private static string ConfigFileName;

		private static string ConfigFileFullPath;

		private readonly Harmony HarmonyInstance = new Harmony("com.orianaventure.mod.LocationReset");

		public static readonly ManualLogSource LocationResetLogger;

		private const string DungeonSplitterName = "dungeon_splitter";

		public static bool DungeonSplitterInstalled;

		private static ConfigEntry<int> CE_ResetTime;

		private static ConfigEntry<bool> CE_SkipPlayerGroundPieceCheck;

		private static ConfigEntry<bool> CE_ResetGroundLocations;

		private static ConfigEntry<bool> CE_OverrideResetTimes;

		private static ConfigEntry<int> CE_FarmResetTime;

		private static ConfigEntry<int> CE_VillageResetTime;

		private static ConfigEntry<int> CE_TrollResetTime;

		private static ConfigEntry<int> CE_BurialResetTime;

		private static ConfigEntry<int> CE_CryptResetTime;

		private static ConfigEntry<int> CE_CaveResetTime;

		private static ConfigEntry<int> CE_CampResetTime;

		private static ConfigEntry<int> CE_MineResetTime;

		private static ConfigEntry<int> CE_QueenResetTime;

		private static ConfigEntry<int> CE_HildirBurialResetTime;

		private static ConfigEntry<int> CE_HildirCaveResetTime;

		private static ConfigEntry<int> CE_HildirTowerResetTime;

		private static ConfigEntry<int> CE_CopperTinCaveResetTime;

		private static ConfigEntry<int> CE_SilverCaveResetTime;

		private static ConfigEntry<bool> CE_EnableLeviathanReset;

		private static ConfigEntry<int> CE_LeviathanResetTime;

		private static readonly int Hash_TrollCave02;

		private static readonly int Hash_Village;

		private static readonly int Hash_Farm;

		private static readonly int Hash_Burial2;

		private static readonly int Hash_Burial3;

		private static readonly int Hash_Burial4;

		private static readonly int Hash_Crypt;

		private static readonly int Hash_Cave;

		private static readonly int Hash_Camp;

		private static readonly int Hash_Mine1;

		private static readonly int Hash_Mine2;

		private static readonly int Hash_Queen;

		private static readonly int Hash_HildirBurial;

		private static readonly int Hash_HildirCave;

		private static readonly int Hash_HildirTower;

		private static readonly int Hash_SilverCave;

		private static readonly int Hash_CopperTinCave;

		private readonly ConfigurationManagerAttributes AdminConfig = new ConfigurationManagerAttributes
		{
			IsAdminOnly = true
		};

		private readonly ConfigurationManagerAttributes ClientConfig = new ConfigurationManagerAttributes
		{
			IsAdminOnly = false
		};

		public static LocationResetPlugin Instance => _instance;

		static LocationResetPlugin()
		{
			_instance = new LocationResetPlugin();
			ConfigFileName = "com.orianaventure.mod.LocationReset.cfg";
			string configPath = Paths.ConfigPath;
			char directorySeparatorChar = Path.DirectorySeparatorChar;
			ConfigFileFullPath = configPath + directorySeparatorChar + ConfigFileName;
			LocationResetLogger = Logger.CreateLogSource("LocationReset");
			DungeonSplitterInstalled = false;
			CE_ResetTime = null;
			CE_SkipPlayerGroundPieceCheck = null;
			CE_ResetGroundLocations = null;
			CE_OverrideResetTimes = null;
			CE_FarmResetTime = null;
			CE_VillageResetTime = null;
			CE_TrollResetTime = null;
			CE_BurialResetTime = null;
			CE_CryptResetTime = null;
			CE_CaveResetTime = null;
			CE_CampResetTime = null;
			CE_MineResetTime = null;
			CE_QueenResetTime = null;
			CE_HildirBurialResetTime = null;
			CE_HildirCaveResetTime = null;
			CE_HildirTowerResetTime = null;
			CE_CopperTinCaveResetTime = null;
			CE_SilverCaveResetTime = null;
			CE_EnableLeviathanReset = null;
			CE_LeviathanResetTime = null;
			Hash_TrollCave02 = StringExtensionMethods.GetStableHashCode("TrollCave02");
			Hash_Village = StringExtensionMethods.GetStableHashCode("WoodVillage1");
			Hash_Farm = StringExtensionMethods.GetStableHashCode("WoodFarm1");
			Hash_Burial2 = StringExtensionMethods.GetStableHashCode("Crypt2");
			Hash_Burial3 = StringExtensionMethods.GetStableHashCode("Crypt3");
			Hash_Burial4 = StringExtensionMethods.GetStableHashCode("Crypt4");
			Hash_Crypt = StringExtensionMethods.GetStableHashCode("SunkenCrypt4");
			Hash_Cave = StringExtensionMethods.GetStableHashCode("MountainCave02");
			Hash_Camp = StringExtensionMethods.GetStableHashCode("GoblinCamp2");
			Hash_Mine1 = StringExtensionMethods.GetStableHashCode("Mistlands_DvergrTownEntrance1");
			Hash_Mine2 = StringExtensionMethods.GetStableHashCode("Mistlands_DvergrTownEntrance2");
			Hash_Queen = StringExtensionMethods.GetStableHashCode("Mistlands_DvergrBossEntrance1");
			Hash_HildirBurial = StringExtensionMethods.GetStableHashCode("Hildir_crypt");
			Hash_HildirCave = StringExtensionMethods.GetStableHashCode("Hildir_cave");
			Hash_HildirTower = StringExtensionMethods.GetStableHashCode("Hildir_plainsfortress");
			Hash_SilverCave = StringExtensionMethods.GetStableHashCode("VV_SilverCave");
			Hash_CopperTinCave = StringExtensionMethods.GetStableHashCode("VV_CopperTinCave");
		}

		private LocationResetPlugin()
		{
		}//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Expected O, but got Unknown
		//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_0022: Expected O, but got Unknown
		//IL_0023: 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


		public static int GetResetTime(int hash)
		{
			if (CE_OverrideResetTimes.Value)
			{
				if (hash == Hash_TrollCave02)
				{
					return CE_TrollResetTime.Value;
				}
				if (hash == Hash_Village)
				{
					return CE_VillageResetTime.Value;
				}
				if (hash == Hash_Farm)
				{
					return CE_FarmResetTime.Value;
				}
				if (hash == Hash_Burial2 || hash == Hash_Burial3 || hash == Hash_Burial4)
				{
					return CE_BurialResetTime.Value;
				}
				if (hash == Hash_Crypt)
				{
					return CE_CryptResetTime.Value;
				}
				if (hash == Hash_Cave)
				{
					return CE_CaveResetTime.Value;
				}
				if (hash == Hash_Camp)
				{
					return CE_CampResetTime.Value;
				}
				if (hash == Hash_Mine1 || hash == Hash_Mine2)
				{
					return CE_MineResetTime.Value;
				}
				if (hash == Hash_Queen)
				{
					return CE_QueenResetTime.Value;
				}
				if (hash == Hash_HildirBurial)
				{
					return CE_HildirBurialResetTime.Value;
				}
				if (hash == Hash_HildirCave)
				{
					return CE_HildirCaveResetTime.Value;
				}
				if (hash == Hash_HildirTower)
				{
					return CE_HildirTowerResetTime.Value;
				}
				if (hash == Hash_CopperTinCave)
				{
					return CE_CopperTinCaveResetTime.Value;
				}
				if (hash == Hash_SilverCave)
				{
					return CE_SilverCaveResetTime.Value;
				}
			}
			return CE_ResetTime.Value;
		}

		public static bool GetSkipPlayerGroundPieceCheck()
		{
			return CE_SkipPlayerGroundPieceCheck.Value;
		}

		public static bool GetResetGroundLocations()
		{
			return CE_ResetGroundLocations.Value;
		}

		public static bool GetEnableLeviathanReset()
		{
			return CE_EnableLeviathanReset.Value;
		}

		public static int GetLeviathanResetTime()
		{
			return CE_LeviathanResetTime.Value;
		}

		private void AddConfig<T>(string key, string section, string description, bool synced, T value, ref ConfigEntry<T> configEntry)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			string extendedDescription = GetExtendedDescription(description, synced);
			configEntry = ((BaseUnityPlugin)this).Config.Bind<T>(section, key, value, new ConfigDescription(extendedDescription, (AcceptableValueBase)null, new object[1] { synced ? AdminConfig : ClientConfig }));
		}

		public string GetExtendedDescription(string description, bool synchronizedSetting)
		{
			return description + (synchronizedSetting ? " [Synced with Server]" : " [Not Synced with Server]");
		}

		public void Awake()
		{
			AddConfig("ResetTime", "General", "Default number of in-game days for reset, one day is about 30 minutes (int).", synced: true, 30, ref CE_ResetTime);
			AddConfig("SkipPlayerGroundPieceCheck", "General", "When True will reset locations even if player placed pieces and tombstones are on the ground outside the entrance to sky locations (boolean).", synced: true, value: false, ref CE_SkipPlayerGroundPieceCheck);
			AddConfig("ResetGroundLocations", "Advanced", "True to reset all misc locations found on the ground (not including meadow farms/villages or fuling camps) (boolean).", synced: true, value: true, ref CE_ResetGroundLocations);
			AddConfig("OverrideResetTimes", "Advanced", "True to use all the values below rather than the default when applicable (boolean).", synced: true, value: false, ref CE_OverrideResetTimes);
			AddConfig("FarmResetTime", "Advanced", "Number of in-game days for resetting meadow farms (int).", synced: true, 30, ref CE_FarmResetTime);
			AddConfig("VillageResetTime", "Advanced", "Number of in-game days for resetting meadow draugr villages (int).", synced: true, 30, ref CE_VillageResetTime);
			AddConfig("TrollResetTime", "Advanced", "Number of in-game days for resetting black forest troll caves (int).", synced: true, 30, ref CE_TrollResetTime);
			AddConfig("BurialResetTime", "Advanced", "Number of in-game days for resetting black forest burial chambers (int).", synced: true, 30, ref CE_BurialResetTime);
			AddConfig("CryptResetTime", "Advanced", "Number of in-game days for resetting swamp crypts (int).", synced: true, 30, ref CE_CryptResetTime);
			AddConfig("CaveResetTime", "Advanced", "Number of in-game days for resetting mountain caves (int).", synced: true, 30, ref CE_CaveResetTime);
			AddConfig("CampResetTime", "Advanced", "Number of in-game days for resetting plain fuling camps (int).", synced: true, 30, ref CE_CampResetTime);
			AddConfig("MineResetTime", "Advanced", "Number of in-game days for resetting mistland infested mines (int).", synced: true, 30, ref CE_MineResetTime);
			AddConfig("QueenResetTime", "Advanced", "Number of in-game days for resetting mistland infested citadel (int).", synced: true, 30, ref CE_QueenResetTime);
			AddConfig("HildirCryptResetTime", "Advanced", "Number of in-game days for resetting hildir's black forest crypts (int).", synced: true, 30, ref CE_HildirBurialResetTime);
			AddConfig("HildirCaveResetTime", "Advanced", "Number of in-game days for resetting hildir's mountain caves (int).", synced: true, 30, ref CE_HildirCaveResetTime);
			AddConfig("HildirTowerResetTime", "Advanced", "Number of in-game days for resetting hildir's plain towers (int).", synced: true, 30, ref CE_HildirTowerResetTime);
			AddConfig("CopperTinCaveResetTime", "Advanced", "Number of in-game days for resetting copper & tin mining caves (int).", synced: true, 30, ref CE_CopperTinCaveResetTime);
			AddConfig("SilverCaveResetTime", "Advanced", "Number of in-game days for resetting silver mining caves (int).", synced: true, 30, ref CE_SilverCaveResetTime);
			AddConfig("EnableLeviathanReset", "Leviathans", "True to enable resetting Leviathans (boolean).", synced: true, value: true, ref CE_EnableLeviathanReset);
			AddConfig("LeviathanResetTime", "Leviathans", "Default number of in-game days for reset, one day is about 30 minutes (int).", synced: true, 30, ref CE_LeviathanResetTime);
			LocationResetLogger.LogInfo((object)"LocationReset getting ready for mass destruction. Consider making backups before using this mod!");
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			HarmonyInstance.PatchAll(executingAssembly);
			SetupWatcher();
			DungeonSplitterInstalled = Chainloader.PluginInfos.ContainsKey("dungeon_splitter");
			if (DungeonSplitterInstalled)
			{
				LocationResetLogger.LogInfo((object)"Detected Dungeon Splitter, this mod will NOT reset sky locations!");
			}
		}

		private void OnDestroy()
		{
			((BaseUnityPlugin)this).Config.Save();
		}

		private void SetupWatcher()
		{
			FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Paths.ConfigPath, ConfigFileName);
			fileSystemWatcher.Changed += ReadConfigValues;
			fileSystemWatcher.Created += ReadConfigValues;
			fileSystemWatcher.Renamed += ReadConfigValues;
			fileSystemWatcher.IncludeSubdirectories = true;
			fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject;
			fileSystemWatcher.EnableRaisingEvents = true;
		}

		private void ReadConfigValues(object sender, FileSystemEventArgs e)
		{
			if (!File.Exists(ConfigFileFullPath))
			{
				return;
			}
			try
			{
				LocationResetLogger.LogDebug((object)"Attempting to reload configuration...");
				((BaseUnityPlugin)this).Config.Reload();
			}
			catch
			{
				LocationResetLogger.LogError((object)("There was an issue loading " + ConfigFileName));
			}
		}
	}
	public static class LeviathanExtension
	{
		[HarmonyPatch(typeof(Leviathan), "FixedUpdate")]
		public static class Patch_Leviathan_FixedUpdate
		{
			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
			{
				//IL_0087: Unknown result type (might be due to invalid IL or missing references)
				//IL_0091: Expected O, but got Unknown
				List<CodeInstruction> list = new List<CodeInstruction>(instructions);
				MethodInfo obj = AccessTools.Method(typeof(ZNetView), "Destroy", (Type[])null, (Type[])null);
				for (int i = 1; i < list.Count; i++)
				{
					if (list[i].opcode == OpCodes.Callvirt)
					{
						object operand = list[i].operand;
						if (operand != null && operand.Equals(obj))
						{
							list[i - 1].opcode = OpCodes.Nop;
							MethodInfo methodInfo = AccessTools.Method(typeof(LeviathanExtension), "MoveUnderwater", (Type[])null, (Type[])null);
							list[i] = new CodeInstruction(OpCodes.Call, (object)methodInfo);
							break;
						}
					}
				}
				return list.AsEnumerable();
			}
		}

		[HarmonyPatch(typeof(Leviathan), "Leave")]
		public static class Patch_Leviathan_Leave
		{
			private static void Postfix(Leviathan __instance)
			{
				if (LocationResetPlugin.GetEnableLeviathanReset() && (Object)(object)__instance != (Object)null && __instance.m_left)
				{
					int gameDay = LocationReset.GetGameDay();
					int lastSubmerged = __instance.GetLastSubmerged();
					if (lastSubmerged == -1 || gameDay - lastSubmerged >= LocationResetPlugin.GetLeviathanResetTime())
					{
						__instance.SetLastSubmerged(gameDay);
					}
				}
			}
		}

		private const string LEVIATHAN_TIME = "VV_LeviathanTime";

		public static int GetLastSubmerged(this Leviathan leviathan)
		{
			if ((Object)(object)leviathan.m_nview != (Object)null && leviathan.m_nview.GetZDO() != null)
			{
				return leviathan.m_nview.GetZDO().GetInt("VV_LeviathanTime", -1);
			}
			return -1;
		}

		public static void SetLastSubmerged(this Leviathan leviathan, int day)
		{
			if ((Object)(object)leviathan.m_nview != (Object)null && leviathan.m_nview.GetZDO() != null && leviathan.m_nview.IsOwner())
			{
				leviathan.m_nview.GetZDO().Set("VV_LeviathanTime", day);
			}
		}

		private static void MoveUnderwater(this Leviathan leviathan)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			if (LocationResetPlugin.GetEnableLeviathanReset())
			{
				if (leviathan.m_body.position.y > 1f)
				{
					Vector3 position = leviathan.m_body.position;
					position.y = 0f;
					leviathan.m_body.MovePosition(position);
				}
			}
			else if ((Object)(object)leviathan.m_nview != (Object)null)
			{
				leviathan.m_nview.Destroy();
			}
		}

		public static bool CheckDelete(this Leviathan leviathan, out bool deleted)
		{
			deleted = false;
			if ((Object)(object)leviathan.m_nview != (Object)null && leviathan.m_nview.IsOwner())
			{
				int lastSubmerged = leviathan.GetLastSubmerged();
				if (lastSubmerged != -1 && LocationReset.GetGameDay() - lastSubmerged >= LocationResetPlugin.GetLeviathanResetTime())
				{
					ZDO zDO = leviathan.m_nview.GetZDO();
					if (zDO != null)
					{
						ZDOMan.instance.DestroyZDO(zDO);
						deleted = true;
					}
				}
				return true;
			}
			return false;
		}
	}
	public static class LocationProxyExtension
	{
		public static bool SetLastResetNow(this LocationProxy loc)
		{
			if ((Object)(object)loc.m_nview == (Object)null || loc.m_nview.GetZDO() == null || !loc.m_nview.IsOwner())
			{
				return false;
			}
			loc.m_nview.GetZDO().Set("VV_LastReset", LocationReset.GetGameDay());
			return true;
		}

		public static int GetLastReset(this LocationProxy loc)
		{
			if ((Object)(object)loc.m_nview == (Object)null || loc.m_nview.GetZDO() == null)
			{
				return -1;
			}
			return loc.m_nview.GetZDO().GetInt("VV_LastReset", -1);
		}

		public static bool NeedsReset(this LocationProxy loc, int hash)
		{
			int lastReset = loc.GetLastReset();
			if (lastReset < 0)
			{
				loc.SetLastResetNow();
				LocationResetPlugin.LocationResetLogger.LogDebug((object)"Location does not need a reset. No timer found.");
				return false;
			}
			int num = LocationReset.GetGameDay() - lastReset;
			int resetTime = LocationResetPlugin.GetResetTime(hash);
			if (num >= resetTime)
			{
				return true;
			}
			LocationResetPlugin.LocationResetLogger.LogDebug((object)$"Location does not need a reset. {resetTime - num} days remaining.");
			return false;
		}
	}
	public class LocationProxyReset : MonoBehaviour
	{
		private const float RESET_RANGE = 100f;

		private IEnumerator resetCoroutine;

		public void Start()
		{
			resetCoroutine = WaitForReset();
			((MonoBehaviour)this).StartCoroutine(resetCoroutine);
		}

		public IEnumerator WaitForReset()
		{
			yield return (object)new WaitForSeconds(5f);
			yield return null;
			LocationProxy loc = ((Component)this).gameObject.GetComponent<LocationProxy>();
			if ((Object)(object)loc != (Object)null)
			{
				int hash = 0;
				if ((Object)(object)loc.m_nview != (Object)null && loc.m_nview.GetZDO() != null)
				{
					hash = loc.m_nview.GetZDO().GetInt(ZDOVars.s_location, 0);
				}
				if (hash != 0 && !LocationReset.IgnoreLocationHashes.Contains(hash))
				{
					int tries = 0;
					while (!LocationReset.LocalPlayerBeyondRange(((Component)loc).transform.position))
					{
						if (LocationReset.LocalPlayerInRange(((Component)loc).transform.position, 100f) && ZNetScene.instance.IsAreaReady(((Component)loc).transform.position))
						{
							if ((Object)(object)loc.m_nview != (Object)null && loc.m_nview.IsOwner())
							{
								LocationReset.Instance.TryReset(loc, hash);
								break;
							}
							tries++;
							if (tries > 100)
							{
								break;
							}
						}
						yield return (object)new WaitForSeconds(1f);
					}
				}
			}
			yield return null;
			Object.Destroy((Object)(object)this);
		}

		public void OnDestroy()
		{
			if (resetCoroutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(resetCoroutine);
			}
		}
	}
	public class LocationReset
	{
		public struct LocationPosition
		{
			public bool IsSkyLocation;

			public bool IsDungeon;

			public DungeonGenerator DungeonGenerator;

			public Vector3 SkyPosition;

			public float SkyDistance;

			public Vector3 GroundPosition;

			public float GroundDistance;

			public Vector3 GeneratorPosition;

			public LocationPosition(LocationProxy loc, ZoneLocation zone, Location location)
			{
				//IL_0049: Unknown result type (might be due to invalid IL or missing references)
				//IL_004e: Unknown result type (might be due to invalid IL or missing references)
				//IL_005a: 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_001f: Unknown result type (might be due to invalid IL or missing references)
				//IL_00af: 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_00b4: 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_00c1: 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)
				DungeonGenerator generator = location.m_generator;
				IsSkyLocation = location.m_hasInterior || ((Object)(object)generator != (Object)null && ((Component)generator).transform.position.y > 4000f);
				IsDungeon = false;
				GroundPosition = ((Component)loc).transform.position;
				SkyPosition = ((Component)loc).transform.position;
				GroundDistance = zone.m_exteriorRadius;
				SkyDistance = zone.m_interiorRadius;
				float distance = Mathf.Max(GroundDistance, SkyDistance);
				GeneratorPosition = (((Object)(object)location.m_generator != (Object)null) ? ((Component)location.m_generator).transform.localPosition : Vector3.zero);
				DungeonGenerator = GetDungeonGeneratorInBounds(GroundPosition + GeneratorPosition, distance);
				if ((Object)(object)DungeonGenerator != (Object)null)
				{
					IsDungeon = true;
					if (IsSkyLocation)
					{
						SkyDistance = Instance.GetDungeonRadius(DungeonGenerator);
					}
					else
					{
						GroundDistance += 5f;
					}
				}
			}
		}

		public struct PlayerActivity
		{
			public bool SkyActivity;

			public bool GroundActivity;

			public PlayerActivity(bool sky, bool ground)
			{
				SkyActivity = sky;
				GroundActivity = ground;
			}
		}

		[HarmonyPatch(typeof(LocationProxy), "SpawnLocation")]
		public static class Patch_LocationProxy_SpawnLocation
		{
			private static void Postfix(LocationProxy __instance)
			{
				if (!ZNet.instance.IsDedicated() && (Object)(object)((Component)__instance).gameObject.GetComponent<LocationProxyReset>() == (Object)null)
				{
					((Component)__instance).gameObject.AddComponent<LocationProxyReset>();
				}
			}
		}

		private static readonly LocationReset _instance;

		public const float LOCATION_MINIMUM = 4000f;

		public const string LAST_RESET = "VV_LastReset";

		public static readonly HashSet<int> IgnoreLocationHashes;

		public static LocationReset Instance => _instance;

		static LocationReset()
		{
			_instance = new LocationReset();
			IgnoreLocationHashes = new HashSet<int>
			{
				StringExtensionMethods.GetStableHashCode("Mystical_Well0"),
				StringExtensionMethods.GetStableHashCode("Wayshrine"),
				StringExtensionMethods.GetStableHashCode("Wayshrine_Ashlands"),
				StringExtensionMethods.GetStableHashCode("Wayshrine_Frost"),
				StringExtensionMethods.GetStableHashCode("Wayshrine_Plains"),
				StringExtensionMethods.GetStableHashCode("Wayshrine_Skull"),
				StringExtensionMethods.GetStableHashCode("Wayshrine_Skull_2")
			};
		}

		private LocationReset()
		{
		}

		public static int GetGameDay()
		{
			return EnvMan.instance.GetCurrentDay();
		}

		public static bool LocalPlayerInRange(Vector3 position, float resetRange)
		{
			//IL_0011: 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)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return false;
			}
			return InBounds(position, ((Component)localPlayer).gameObject.transform.position, resetRange);
		}

		public static bool LocalPlayerBeyondRange(Vector3 position)
		{
			//IL_0011: 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)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return true;
			}
			return !InBounds(position, ((Component)localPlayer).gameObject.transform.position, 200f);
		}

		private static PlayerActivity GetPlayerActivity(LocationPosition position)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: 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_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			PlayerActivity result = new PlayerActivity(sky: false, ground: false);
			Scene activeScene = SceneManager.GetActiveScene();
			GameObject[] rootGameObjects = ((Scene)(ref activeScene)).GetRootGameObjects();
			foreach (GameObject val in rootGameObjects)
			{
				if (val.transform.position.y >= 4000f)
				{
					if (position.IsSkyLocation && !result.SkyActivity && InBounds(val.transform.position, position.SkyPosition, position.SkyDistance))
					{
						result.SkyActivity = IsPlayerActiveObject(val);
					}
				}
				else if (!result.GroundActivity && InBounds(val.transform.position, position.GroundPosition, position.GroundDistance))
				{
					result.GroundActivity = IsPlayerActiveObject(val);
				}
			}
			return result;
		}

		private static bool IsPlayerActiveObject(GameObject obj)
		{
			Piece component = obj.GetComponent<Piece>();
			if ((Object)(object)component != (Object)null)
			{
				if (component.GetCreator() != 0L)
				{
					return true;
				}
			}
			else
			{
				if ((Object)(object)obj.GetComponent<TombStone>() != (Object)null)
				{
					return true;
				}
				if ((Object)(object)obj.GetComponent<Player>() != (Object)null)
				{
					return true;
				}
			}
			return false;
		}

		public static bool InBounds(Vector3 center, Vector3 position, float distance)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = center - position;
			return GetMaximumDistance(val.x, val.z) <= distance;
		}

		public static DungeonGenerator GetDungeonGeneratorInBounds(Vector3 center, float distance)
		{
			//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)
			//IL_0028: 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)
			Scene activeScene = SceneManager.GetActiveScene();
			GameObject[] rootGameObjects = ((Scene)(ref activeScene)).GetRootGameObjects();
			foreach (GameObject val in rootGameObjects)
			{
				DungeonGenerator component = val.GetComponent<DungeonGenerator>();
				if ((Object)(object)component != (Object)null && InBounds(center, val.transform.position, distance))
				{
					return component;
				}
			}
			return null;
		}

		public static float GetMaximumDistance(float x, float z)
		{
			return (float)Math.Sqrt(Math.Pow(x, 2.0) + Math.Pow(z, 2.0));
		}

		public float GetDungeonRadius(DungeonGenerator dg)
		{
			return GetMaximumDistance(dg.m_zoneSize.x / 2f, dg.m_zoneSize.z / 2f);
		}

		private static bool QualifyingObject(GameObject obj)
		{
			if (!Object.op_Implicit((Object)(object)obj.GetComponent<Destructible>()) && !Object.op_Implicit((Object)(object)obj.GetComponent<MineRock>()) && !Object.op_Implicit((Object)(object)obj.GetComponent<MineRock5>()) && !Object.op_Implicit((Object)(object)obj.GetComponent<ItemDrop>()) && !Object.op_Implicit((Object)(object)obj.GetComponent<Piece>()) && !Object.op_Implicit((Object)(object)obj.GetComponent<Pickable>()) && !Object.op_Implicit((Object)(object)obj.GetComponent<Character>()) && !Object.op_Implicit((Object)(object)obj.GetComponent<CreatureSpawner>()) && !Object.op_Implicit((Object)(object)obj.GetComponent<WearNTear>()) && !Object.op_Implicit((Object)(object)obj.GetComponent<SpawnArea>()))
			{
				return Object.op_Implicit((Object)(object)obj.GetComponent<RandomSpawn>());
			}
			return true;
		}

		private static bool QualifyingSkyObject(GameObject obj)
		{
			if (!Object.op_Implicit((Object)(object)obj.GetComponent<DungeonGenerator>()) && !Object.op_Implicit((Object)(object)obj.GetComponent<LocationProxy>()))
			{
				return !Object.op_Implicit((Object)(object)obj.GetComponent<Player>());
			}
			return false;
		}

		private static void DeleteObject(ref GameObject obj)
		{
			ZNetView component = obj.GetComponent<ZNetView>();
			if ((Object)(object)component != (Object)null && component.GetZDO() != null)
			{
				component.GetZDO().SetOwner(ZDOMan.GetSessionID());
			}
			ZNetScene.instance.Destroy(obj);
		}

		public static void TryResetDoor(GameObject obj)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			Door component = obj.GetComponent<Door>();
			if ((Object)(object)component != (Object)null && (Object)(object)component.m_keyItem != (Object)null)
			{
				LocationResetPlugin.LocationResetLogger.LogDebug((object)$"Attempting to reset a door at {obj.transform.position}.");
				if ((Object)(object)component.m_nview != (Object)null && component.m_nview.GetZDO() != null)
				{
					component.m_nview.GetZDO().Set(ZDOVars.s_state, 0, false);
					component.UpdateState();
				}
			}
		}

		public static void DeleteLocation(LocationPosition position, PlayerActivity activity)
		{
			//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)
			//IL_001f: 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_0047: 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_00a3: Unknown result type (might be due to invalid IL or missing references)
			Scene activeScene = SceneManager.GetActiveScene();
			GameObject[] rootGameObjects = ((Scene)(ref activeScene)).GetRootGameObjects();
			for (int i = 0; i < rootGameObjects.Length; i++)
			{
				GameObject obj = rootGameObjects[i];
				if (obj.transform.position.y < 4000f)
				{
					if (!activity.GroundActivity && InBounds(position.GroundPosition, obj.transform.position, position.GroundDistance))
					{
						if (!Object.op_Implicit((Object)(object)obj.GetComponent<Player>()) && QualifyingObject(obj))
						{
							DeleteObject(ref obj);
						}
						else
						{
							TryResetDoor(obj);
						}
					}
				}
				else if (position.IsSkyLocation && !activity.SkyActivity && QualifyingSkyObject(obj) && InBounds(position.SkyPosition, obj.transform.position, position.SkyDistance))
				{
					DeleteObject(ref obj);
				}
			}
		}

		public void TryReset(LocationProxy loc, int hash, bool force = false)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			LocationResetPlugin.LocationResetLogger.LogDebug((object)$"Trying to reset Location with hash {hash} at: {((Component)loc).transform.position}");
			int num = 0;
			if ((Object)(object)loc.m_nview != (Object)null && loc.m_nview.GetZDO() != null)
			{
				num = loc.m_nview.GetZDO().GetInt(ZDOVars.s_seed, 0);
			}
			if (num == 0 || hash == 0)
			{
				LocationResetPlugin.LocationResetLogger.LogDebug((object)"There was an issue getting the location hash or seed, abort.");
			}
			else if (force || loc.NeedsReset(hash))
			{
				ZoneLocation location = ZoneSystem.instance.GetLocation(hash);
				if (location == null)
				{
					LocationResetPlugin.LocationResetLogger.LogDebug((object)"There was an issue getting the zone location, abort.");
					return;
				}
				Location component = location.m_prefab.Asset.GetComponent<Location>();
				TryResetAfterLoadPrefab(loc, location, component, hash, num, force);
			}
		}

		private void TryResetAfterLoadPrefab(LocationProxy loc, ZoneLocation zone, Location location, int hash, int seed, bool force)
		{
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)location == (Object)null)
			{
				LocationResetPlugin.LocationResetLogger.LogDebug((object)"There was an issue getting the location, abort.");
				return;
			}
			LocationPosition position = new LocationPosition(loc, zone, location);
			if (LocationResetPlugin.DungeonSplitterInstalled && position.IsSkyLocation)
			{
				LocationResetPlugin.LocationResetLogger.LogDebug((object)"Cannot reset sky locations when using Dungeon Splitter.");
				return;
			}
			if ((Object)(object)position.DungeonGenerator != (Object)null)
			{
				if ((Object)(object)position.DungeonGenerator.m_nview == (Object)null || !position.DungeonGenerator.m_nview.IsOwner())
				{
					LocationResetPlugin.LocationResetLogger.LogDebug((object)"Needs a reset but does not own the DG object! Skipping.");
					return;
				}
			}
			else if (!LocationResetPlugin.GetResetGroundLocations() && !position.IsSkyLocation)
			{
				return;
			}
			PlayerActivity activity = ((!force) ? GetPlayerActivity(position) : new PlayerActivity(sky: false, ground: false));
			if (((!LocationResetPlugin.GetSkipPlayerGroundPieceCheck() || !position.IsSkyLocation) && activity.GroundActivity) || activity.SkyActivity)
			{
				LocationResetPlugin.LocationResetLogger.LogDebug((object)"There is player activity here! Skipping.");
				return;
			}
			if (!loc.SetLastResetNow())
			{
				LocationResetPlugin.LocationResetLogger.LogDebug((object)"There was an issue setting the reset time, abort.");
				return;
			}
			Reset(loc, zone, location, seed, position, activity);
			LocationResetPlugin.LocationResetLogger.LogInfo((object)$"Done regenerating location {zone.m_prefabName} at: {((Component)loc).transform.position}");
		}

		private void Reset(LocationProxy loc, ZoneLocation zone, Location location, int seed, LocationPosition position, PlayerActivity activity)
		{
			DeleteLocation(position, activity);
			Regenerate(loc, zone, location, seed, position, activity);
		}

		private void ResetTerrain(LocationPosition position)
		{
		}

		private void Regenerate(LocationProxy loc, ZoneLocation zone, Location location, int seed, LocationPosition position, PlayerActivity activity)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: 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)
			//IL_013f: 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_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
			ZNetView[] enabledComponentsInChildren = Utils.GetEnabledComponentsInChildren<ZNetView>(zone.m_prefab.Asset);
			RandomSpawn[] enabledComponentsInChildren2 = Utils.GetEnabledComponentsInChildren<RandomSpawn>(zone.m_prefab.Asset);
			for (int i = 0; i < enabledComponentsInChildren2.Length; i++)
			{
				enabledComponentsInChildren2[i].Prepare();
			}
			Vector3 position2 = zone.m_prefab.Asset.transform.position;
			Quaternion rotation = zone.m_prefab.Asset.transform.rotation;
			zone.m_prefab.Asset.transform.position = Vector3.zero;
			zone.m_prefab.Asset.transform.rotation = Quaternion.identity;
			WearNTear.m_randomInitialDamage = (((Object)(object)location != (Object)null && location.m_applyRandomDamage) ? true : false);
			if ((Object)(object)position.DungeonGenerator != (Object)null)
			{
				position.DungeonGenerator.m_originalPosition = position.GeneratorPosition;
				position.DungeonGenerator.Generate((SpawnMode)0);
			}
			Random.InitState(seed);
			RandomSpawn[] array = enabledComponentsInChildren2;
			for (int j = 0; j < array.Length; j++)
			{
				array[j].Randomize((Location)null, (DungeonGenerator)null);
			}
			int num = 0;
			int num2 = 0;
			ZNetView[] array2 = enabledComponentsInChildren;
			foreach (ZNetView val in array2)
			{
				if (((Component)val).gameObject.activeSelf)
				{
					if (((Component)val).transform.position.y < 4000f)
					{
						if (activity.GroundActivity || !QualifyingObject(((Component)val).gameObject))
						{
							num2++;
							continue;
						}
					}
					else if (activity.SkyActivity || Object.op_Implicit((Object)(object)((Component)val).GetComponent<DungeonGenerator>()))
					{
						num2++;
						continue;
					}
					Vector3 val2 = ((Component)loc).transform.position + ((Component)loc).transform.rotation * ((Component)val).gameObject.transform.position;
					Quaternion val3 = ((Component)loc).transform.rotation * ((Component)val).gameObject.transform.rotation;
					GameObject obj = Object.Instantiate<GameObject>(((Component)val).gameObject, val2, val3);
					obj.GetComponent<ZNetView>().HoldReferenceTo((IReferenceCounted)(object)zone.m_prefab);
					obj.SetActive(true);
					num++;
				}
				else
				{
					num2++;
				}
			}
			LocationResetPlugin.LocationResetLogger.LogDebug((object)$"Spawned {num} objects, ignored {num2}.");
			for (int k = 0; k < enabledComponentsInChildren2.Length; k++)
			{
				enabledComponentsInChildren2[k].Reset();
			}
			for (int l = 0; l < enabledComponentsInChildren.Length; l++)
			{
				((Component)enabledComponentsInChildren[l]).gameObject.SetActive(true);
			}
			zone.m_prefab.Asset.transform.position = position2;
			zone.m_prefab.Asset.transform.rotation = rotation;
			WearNTear.m_randomInitialDamage = false;
			SnapToGround.SnappAll();
		}
	}
	public static class ResetCommands
	{
		[HarmonyPatch(typeof(Terminal), "InitTerminal")]
		private static class Patch_Terminal_InitTerminal
		{
			[Serializable]
			[CompilerGenerated]
			private sealed class <>c
			{
				public static readonly <>c <>9 = new <>c();

				public static ConsoleEvent <>9__1_0;

				internal void <Postfix>b__1_0(ConsoleEventArgs args)
				{
					if (args.Length > 1)
					{
						int.TryParse(args[1], out var result);
						result = Math.Min(result, 100);
						ManualReset(result);
						args.Context.AddString($"Resetting all in range {result}...");
					}
					else
					{
						ManualReset(20);
						args.Context.AddString($"Resetting all in default range {20}...");
					}
				}
			}

			[HarmonyPriority(800)]
			private static void Prefix(out bool __state)
			{
				__state = Terminal.m_terminalInitialized;
			}

			private static void Postfix(bool __state)
			{
				//IL_0045: Unknown result type (might be due to invalid IL or missing references)
				//IL_0031: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Unknown result type (might be due to invalid IL or missing references)
				//IL_003c: Expected O, but got Unknown
				if (__state)
				{
					return;
				}
				LocationResetPlugin.LocationResetLogger.LogInfo((object)"Adding Terminal Commands for location management.");
				object obj = <>c.<>9__1_0;
				if (obj == null)
				{
					ConsoleEvent val = delegate(ConsoleEventArgs args)
					{
						if (args.Length > 1)
						{
							int.TryParse(args[1], out var result);
							result = Math.Min(result, 100);
							ManualReset(result);
							args.Context.AddString($"Resetting all in range {result}...");
						}
						else
						{
							ManualReset(20);
							args.Context.AddString($"Resetting all in default range {20}...");
						}
					};
					<>c.<>9__1_0 = val;
					obj = (object)val;
				}
				new ConsoleCommand("resetlocations", "[name]", (ConsoleEvent)obj, true, false, true, false, false, (ConsoleOptionsFetcher)null, false, false, false);
			}
		}

		public static void ManualReset(int range)
		{
			//IL_000a: 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_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_0036: 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)
			Vector3 position = ((Component)Player.m_localPlayer).transform.position;
			Scene activeScene = SceneManager.GetActiveScene();
			GameObject[] rootGameObjects = ((Scene)(ref activeScene)).GetRootGameObjects();
			for (int i = 0; i < rootGameObjects.Length; i++)
			{
				LocationProxy component = rootGameObjects[i].GetComponent<LocationProxy>();
				if ((Object)(object)component != (Object)null && LocationReset.InBounds(position, ((Component)component).transform.position, range))
				{
					int hash = 0;
					if ((Object)(object)component.m_nview != (Object)null && component.m_nview.GetZDO() != null)
					{
						hash = component.m_nview.GetZDO().GetInt(ZDOVars.s_location, 0);
					}
					LocationReset.Instance.TryReset(component, hash, force: true);
				}
			}
		}
	}
	public class ZoneSystemReset
	{
		public class ZoneSystemResetComponent : MonoBehaviour
		{
			private Dictionary<Vector2i, IEnumerator> resetCoroutines = new Dictionary<Vector2i, IEnumerator>();

			public IEnumerator WaitForReset(Vector2i zoneID, GameObject root)
			{
				//IL_000e: 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)
				yield return (object)new WaitForSeconds(3f);
				yield return null;
				int tries = 0;
				while ((Object)(object)root != (Object)null)
				{
					if (ZNetScene.instance.IsAreaReady(root.transform.position))
					{
						bool flag = false;
						List<ZDO> list = new List<ZDO>();
						ZDOMan.instance.FindObjects(zoneID, list);
						if (list != null)
						{
							int num = 0;
							bool flag2 = false;
							foreach (ZDO item in list)
							{
								if (item.m_prefab == LeviathanHash)
								{
									ZNetView val = ZNetScene.instance.FindInstance(item);
									if ((Object)(object)val == (Object)null)
									{
										continue;
									}
									Leviathan component = ((Component)((Component)val).transform.root).GetComponent<Leviathan>();
									if ((Object)(object)component != (Object)null && component.CheckDelete(out var deleted))
									{
										if (!deleted)
										{
											num++;
										}
										flag = true;
									}
									else
									{
										num++;
										flag = false;
									}
								}
								else if (item.m_prefab == SpawnSystemHash)
								{
									flag2 = item.IsOwner();
								}
							}
							if (num == 0 && flag2)
							{
								flag = true;
								ResetZone(zoneID, root);
							}
						}
						if (flag || tries > 100)
						{
							break;
						}
						tries++;
					}
					yield return (object)new WaitForSeconds(1f);
				}
				resetCoroutines.Remove(zoneID);
			}

			public void AddResetWatcher(Vector2i zoneID, GameObject root)
			{
				//IL_0006: 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_001e: Unknown result type (might be due to invalid IL or missing references)
				if (!resetCoroutines.ContainsKey(zoneID))
				{
					IEnumerator enumerator = WaitForReset(zoneID, root);
					resetCoroutines.Add(zoneID, enumerator);
					((MonoBehaviour)this).StartCoroutine(enumerator);
				}
			}

			private void ResetZone(Vector2i zoneID, GameObject root)
			{
				//IL_003c: 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_0042: Unknown result type (might be due to invalid IL or missing references)
				//IL_0056: Unknown result type (might be due to invalid IL or missing references)
				//IL_0057: Unknown result type (might be due to invalid IL or missing references)
				ZoneSystem component = ((Component)this).gameObject.GetComponent<ZoneSystem>();
				Heightmap componentInChildren = root.GetComponentInChildren<Heightmap>();
				if ((Object)(object)component != (Object)null && (Object)(object)componentInChildren != (Object)null)
				{
					component.m_tempClearAreas.Clear();
					component.m_tempSpawnedObjects.Clear();
					Vector3 zonePos = component.GetZonePos(zoneID);
					List<ZoneVegetation> vegetation = component.m_vegetation;
					component.m_vegetation = ResetVegetation;
					component.PlaceVegetation(zoneID, zonePos, root.transform, componentInChildren, component.m_tempClearAreas, (SpawnMode)0, component.m_tempSpawnedObjects);
					component.m_vegetation = vegetation;
				}
			}

			public void OnDestroy()
			{
				if (resetCoroutines == null)
				{
					return;
				}
				foreach (IEnumerator value in resetCoroutines.Values)
				{
					((MonoBehaviour)this).StopCoroutine(value);
				}
			}
		}

		[HarmonyPatch(typeof(ZoneSystem), "Start")]
		public static class Patch_ZoneSystem_Start
		{
			private static void Postfix(ZoneSystem __instance)
			{
				if (!LocationResetPlugin.GetEnableLeviathanReset())
				{
					return;
				}
				if (ResetVegetation == null)
				{
					foreach (ZoneVegetation item in __instance.m_vegetation)
					{
						if ((Object)(object)item.m_prefab != (Object)null && ((Object)item.m_prefab).name == "Leviathan")
						{
							ResetVegetation = new List<ZoneVegetation> { item };
							break;
						}
					}
				}
				ResetComponent = ((Component)__instance).gameObject.GetComponent<ZoneSystemResetComponent>();
				if ((Object)(object)ResetComponent == (Object)null)
				{
					ResetComponent = ((Component)__instance).gameObject.AddComponent<ZoneSystemResetComponent>();
				}
			}
		}

		[HarmonyPatch(typeof(ZoneSystem), "SpawnZone")]
		public static class Patch_ZoneSystem_SpawnZone
		{
			private static void Postfix(ZoneSystem __instance, Vector2i zoneID, ref GameObject root, bool __result)
			{
				//IL_0035: Unknown result type (might be due to invalid IL or missing references)
				if (LocationResetPlugin.GetEnableLeviathanReset() && __result && !((Object)(object)__instance == (Object)null) && !((Object)(object)root == (Object)null) && (Object)(object)Player.m_localPlayer != (Object)null)
				{
					ResetComponent?.AddResetWatcher(zoneID, root);
				}
			}
		}

		private static readonly int LeviathanHash = StringExtensionMethods.GetStableHashCode("Leviathan");

		private static readonly int SpawnSystemHash = StringExtensionMethods.GetStableHashCode("_ZoneCtrl");

		private static List<ZoneVegetation> ResetVegetation;

		private static ZoneSystemResetComponent ResetComponent;
	}
}