Decompiled source of RavenIsle v1.0.8

RavenIsle.dll

Decompiled 3 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Text.RegularExpressions;
using System.Threading;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Splatform;
using UnityEngine;

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

public static class IsleBuilder
{
	public const string IdKey = "anwo_ri_id";

	public const string ProtKey = "anwo_ri_prot";

	public const string LootKey = "anwo_ri_loot";

	public const string HoardKey = "anwo_ri_hoard";

	public const string LayoutVersion = "1";

	public const string PartKey = "anwo_ri_part";

	public const string PortalHome = "anwo_ri_portal_home";

	public const string PortalIsle = "anwo_ri_portal_isle";

	public const string Beacon = "anwo_ri_beacon";

	public const string Gate = "anwo_ri_gate";

	public const string Altar = "anwo_ri_altar";

	public const string LoreStone = "anwo_ri_lore";

	public const float KeeperPerchHeight = 0f;

	private static Piece s_homePiece;

	private static readonly Type s_clearAreaType = AccessTools.Inner(typeof(ZoneSystem), "ClearArea");

	private static bool s_layoutChecked;

	private static bool s_buildChecked;

	private static string BuildKey => "2" + (RavenIslePlugin.WardFires.Value ? "w" : "");

	private static Vector3 Ground(double lx, double lz, float add = 0f)
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		return Realm.ToWorld(lx, lz, IsleTerrain.Sample(lx, lz).Height + add);
	}

	public static Vector3 ArrivalPoint()
	{
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		IsleSite isleSite = IsleLayout.Get("plaza");
		return Ground(isleSite.X, isleSite.Z + 6.0, 0.6f);
	}

	public static Vector3 KeeperPoint()
	{
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		IsleSite isleSite = IsleLayout.Get("camp");
		return Ground(isleSite.X - 3.0, isleSite.Z + 2.0);
	}

	public static Vector3 AltarPoint()
	{
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		IsleSite isleSite = IsleLayout.Get("altar");
		return Ground(isleSite.X, isleSite.Z + 14.0);
	}

	public static Vector3 WardenSpawnPoint()
	{
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		IsleSite isleSite = IsleLayout.Get("altar");
		return Ground(isleSite.X, isleSite.Z - 18.0, 0.5f);
	}

	public static string BeaconLabel(string id)
	{
		if (!(id == "east"))
		{
			if (!(id == "west"))
			{
				return "Mistwood beacon";
			}
			return "west beacon";
		}
		return "east beacon";
	}

	private static string Pick(params string[] names)
	{
		foreach (string text in names)
		{
			if ((Object)(object)PrefabManager.Instance.GetPrefab(text) != (Object)null)
			{
				return text;
			}
		}
		return null;
	}

	public static void RegisterPrefabs()
	{
		IslePlan.Has = (string n) => (Object)(object)PrefabManager.Instance.GetPrefab(n) != (Object)null;
		try
		{
			MakePortals();
		}
		catch (Exception ex)
		{
			RavenIslePlugin.Log.LogError((object)("Portals: " + ex));
		}
		try
		{
			MakeBeacon();
		}
		catch (Exception ex2)
		{
			RavenIslePlugin.Log.LogError((object)("Beacon: " + ex2));
		}
		try
		{
			MakeGate();
		}
		catch (Exception ex3)
		{
			RavenIslePlugin.Log.LogError((object)("Gate: " + ex3));
		}
		try
		{
			MakeAltar();
		}
		catch (Exception ex4)
		{
			RavenIslePlugin.Log.LogError((object)("Altar: " + ex4));
		}
		try
		{
			MakeLore();
		}
		catch (Exception ex5)
		{
			RavenIslePlugin.Log.LogError((object)("Lore stone: " + ex5));
		}
	}

	public unsafe static void CheckShapes()
	{
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_010f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0126: Unknown result type (might be due to invalid IL or missing references)
		//IL_013d: Unknown result type (might be due to invalid IL or missing references)
		//IL_019f: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a1: 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_01bd: Unknown result type (might be due to invalid IL or missing references)
		List<string> list = new List<string> { IslePlan.Bases["anwo_ri_gate"] };
		list.Add(IslePlan.Pick(IslePlan.WallPieces));
		list.Add(IslePlan.Pick(IslePlan.LintelPieces));
		list.Add(IslePlan.Pick(IslePlan.WardPieces));
		list.Add(IslePlan.Pick("piece_brazierfloor01"));
		int num = 0;
		foreach (string item in list)
		{
			if (item == null)
			{
				continue;
			}
			PieceShapes.Shape shape = PieceShapes.Get(item);
			GameObject prefab = PrefabManager.Instance.GetPrefab(item);
			if (shape != null && !((Object)(object)prefab == (Object)null) && SolidBounds(prefab, out var lo, out var hi))
			{
				PieceShapes.Box solid = shape.Solid;
				float num2 = Mathf.Max(new float[6]
				{
					Mathf.Abs(lo.x - solid.MinX),
					Mathf.Abs(lo.y - solid.MinY),
					Mathf.Abs(lo.z - solid.MinZ),
					Mathf.Abs(hi.x - solid.MaxX),
					Mathf.Abs(hi.y - solid.MaxY),
					Mathf.Abs(hi.z - solid.MaxZ)
				});
				if (num2 > 0.06f)
				{
					num++;
					ManualLogSource log = RavenIslePlugin.Log;
					string[] obj = new string[9]
					{
						"Raven Isle: ",
						item,
						" is shaped differently than expected (off by ",
						num2.ToString("0.00"),
						" m: ",
						null,
						null,
						null,
						null
					};
					Vector3 val = lo;
					obj[5] = ((object)(*(Vector3*)(&val))/*cast due to .constrained prefix*/).ToString();
					obj[6] = " to ";
					val = hi;
					obj[7] = ((object)(*(Vector3*)(&val))/*cast due to .constrained prefix*/).ToString();
					obj[8] = "). The isle's gates and fires may not line up; please report this.";
					log.LogWarning((object)string.Concat(obj));
				}
			}
		}
		if (num == 0)
		{
			RavenIslePlugin.Log.LogInfo((object)"Raven Isle: the game's pieces have the sizes the isle is built for");
		}
	}

	private static bool SolidBounds(GameObject go, out Vector3 lo, out Vector3 hi)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_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)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00da: Unknown result type (might be due to invalid IL or missing references)
		//IL_012e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0136: Unknown result type (might be due to invalid IL or missing references)
		//IL_013b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0140: Unknown result type (might be due to invalid IL or missing references)
		//IL_0107: 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_011e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0123: Unknown result type (might be due to invalid IL or missing references)
		//IL_0127: Unknown result type (might be due to invalid IL or missing references)
		//IL_012c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0149: Unknown result type (might be due to invalid IL or missing references)
		//IL_014b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0152: Unknown result type (might be due to invalid IL or missing references)
		//IL_0178: Unknown result type (might be due to invalid IL or missing references)
		//IL_017d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0182: Unknown result type (might be due to invalid IL or missing references)
		//IL_0187: Unknown result type (might be due to invalid IL or missing references)
		//IL_018c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0190: Unknown result type (might be due to invalid IL or missing references)
		//IL_0195: Unknown result type (might be due to invalid IL or missing references)
		//IL_0197: Unknown result type (might be due to invalid IL or missing references)
		//IL_019c: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_01af: Unknown result type (might be due to invalid IL or missing references)
		lo = Vector3.one * 1E+09f;
		hi = -lo;
		bool result = false;
		Matrix4x4 val = Matrix4x4.Scale(go.transform.localScale) * go.transform.worldToLocalMatrix;
		Collider[] componentsInChildren = go.GetComponentsInChildren<Collider>(true);
		foreach (Collider val2 in componentsInChildren)
		{
			if (val2.isTrigger || !val2.enabled)
			{
				continue;
			}
			bool flag = true;
			Transform val3 = ((Component)val2).transform;
			while ((Object)(object)val3 != (Object)null && (Object)(object)val3 != (Object)(object)go.transform)
			{
				if (!((Component)val3).gameObject.activeSelf)
				{
					flag = false;
				}
				val3 = val3.parent;
			}
			if (!flag)
			{
				continue;
			}
			BoxCollider val4 = (BoxCollider)(object)((val2 is BoxCollider) ? val2 : null);
			Vector3 center;
			Vector3 size;
			if (val4 != null)
			{
				center = val4.center;
				size = val4.size;
			}
			else
			{
				MeshCollider val5 = (MeshCollider)(object)((val2 is MeshCollider) ? val2 : null);
				if (val5 == null || !((Object)(object)val5.sharedMesh != (Object)null))
				{
					continue;
				}
				Bounds bounds = val5.sharedMesh.bounds;
				center = ((Bounds)(ref bounds)).center;
				bounds = val5.sharedMesh.bounds;
				size = ((Bounds)(ref bounds)).size;
			}
			Matrix4x4 val6 = val * ((Component)val2).transform.localToWorldMatrix;
			for (int j = 0; j < 8; j++)
			{
				Vector3 val7 = ((Matrix4x4)(ref val6)).MultiplyPoint3x4(center + Vector3.Scale(size * 0.5f, new Vector3((float)(((j & 1) != 0) ? 1 : (-1)), (float)(((j & 2) != 0) ? 1 : (-1)), (float)(((j & 4) != 0) ? 1 : (-1)))));
				lo = Vector3.Min(lo, val7);
				hi = Vector3.Max(hi, val7);
				result = true;
			}
		}
		return result;
	}

	private static void Strip<T>(GameObject go) where T : Component
	{
		T[] componentsInChildren = go.GetComponentsInChildren<T>(true);
		for (int i = 0; i < componentsInChildren.Length; i++)
		{
			Object.DestroyImmediate((Object)(object)componentsInChildren[i]);
		}
	}

	private static void EnsureNetView(GameObject go)
	{
		if ((Object)(object)go.GetComponent<ZNetView>() == (Object)null)
		{
			go.AddComponent<ZNetView>().m_persistent = true;
		}
	}

	private static IslePortal ConvertPortal(GameObject go, bool toIsland)
	{
		TeleportWorld component = go.GetComponent<TeleportWorld>();
		IslePortal islePortal = go.AddComponent<IslePortal>();
		islePortal.m_toIsland = toIsland;
		if ((Object)(object)component != (Object)null)
		{
			islePortal.m_model = component.m_model;
			islePortal.m_targetFound = component.m_target_found;
			islePortal.m_connected = component.m_connected;
			islePortal.m_proximityRoot = component.m_proximityRoot;
		}
		Strip<TeleportWorldTrigger>(go);
		Strip<TeleportWorld>(go);
		return islePortal;
	}

	public static void UpdatePieceEnabled()
	{
		if ((Object)(object)s_homePiece != (Object)null)
		{
			s_homePiece.m_enabled = RavenIslePlugin.IslandOn.Value;
		}
	}

	private static void MakePortals()
	{
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: 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_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Expected O, but got Unknown
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Expected O, but got Unknown
		//IL_012d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0137: Expected O, but got Unknown
		string text = Pick("portal_wood", "portal");
		if (text != null)
		{
			IslePlan.Bases["anwo_ri_portal_home"] = text;
			GameObject val = PrefabManager.Instance.CreateClonedPrefab("anwo_ri_portal_home", text);
			ConvertPortal(val, toIsland: true);
			PieceConfig val2 = new PieceConfig
			{
				Name = "Raven portal",
				Description = "A portal carved with ravens. It leads to Raven Isle, beyond the edge of the world.\n<color=orange>A late-game challenge: bring your best gear.</color>",
				PieceTable = PieceTables.Hammer,
				Category = PieceCategories.Misc,
				CraftingStation = CraftingStations.Workbench,
				Requirements = RavenIslePlugin.ParseRecipe(RavenIslePlugin.PortalRecipe.Value)
			};
			PieceManager.Instance.AddPiece(new CustomPiece(val, false, val2));
			s_homePiece = val.GetComponent<Piece>();
			UpdatePieceEnabled();
		}
		string text2 = Pick("portal_stone", "portal_wood");
		if (text2 != null)
		{
			IslePlan.Bases["anwo_ri_portal_isle"] = text2;
			GameObject val3 = PrefabManager.Instance.CreateClonedPrefab("anwo_ri_portal_isle", text2);
			ConvertPortal(val3, toIsland: false);
			Piece component = val3.GetComponent<Piece>();
			if ((Object)(object)component != (Object)null)
			{
				component.m_canBeRemoved = false;
			}
			PrefabManager.Instance.AddPrefab(new CustomPrefab(val3, false));
		}
	}

	private static void MakeBeacon()
	{
		//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e6: Expected O, but got Unknown
		string text = Pick("bonfire", "fire_pit");
		if (text == null)
		{
			return;
		}
		IslePlan.Bases["anwo_ri_beacon"] = text;
		GameObject val = PrefabManager.Instance.CreateClonedPrefab("anwo_ri_beacon", text);
		Fireplace component = val.GetComponent<Fireplace>();
		if ((Object)(object)component != (Object)null)
		{
			component.m_startFuel = 0f;
			component.m_maxFuel = 10f;
			component.m_secPerFuel = 1000000f;
			component.m_canTurnOff = false;
			component.m_name = "Beacon";
			GameObject prefab = PrefabManager.Instance.GetPrefab("Wood");
			if ((Object)(object)prefab != (Object)null)
			{
				component.m_fuelItem = prefab.GetComponent<ItemDrop>();
			}
		}
		Piece component2 = val.GetComponent<Piece>();
		if ((Object)(object)component2 != (Object)null)
		{
			component2.m_canBeRemoved = false;
			component2.m_name = "Beacon";
		}
		val.AddComponent<IsleBeacon>();
		PrefabManager.Instance.AddPrefab(new CustomPrefab(val, false));
	}

	private static void MakeGate()
	{
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Expected O, but got Unknown
		string text = Pick(RavenIslePlugin.GateBases);
		if (text == null)
		{
			RavenIslePlugin.Log.LogWarning((object)"No gate prefab found; gates are missing");
			return;
		}
		IslePlan.Bases["anwo_ri_gate"] = text;
		GameObject val = PrefabManager.Instance.CreateClonedPrefab("anwo_ri_gate", text);
		Piece component = val.GetComponent<Piece>();
		if ((Object)(object)component != (Object)null)
		{
			component.m_canBeRemoved = false;
		}
		val.AddComponent<IsleGate>();
		PrefabManager.Instance.AddPrefab(new CustomPrefab(val, false));
		RavenIslePlugin.Log.LogInfo((object)("Gates are built from " + text));
	}

	private static void MakeAltar()
	{
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0077: Expected O, but got Unknown
		string text = Pick(RavenIslePlugin.AltarBases);
		if (text != null)
		{
			IslePlan.Bases["anwo_ri_altar"] = text;
			GameObject val = PrefabManager.Instance.CreateClonedPrefab("anwo_ri_altar", text);
			Strip<OfferingBowl>(val);
			Strip<RuneStone>(val);
			Strip<ItemStand>(val);
			EnsureNetView(val);
			Piece component = val.GetComponent<Piece>();
			if ((Object)(object)component != (Object)null)
			{
				component.m_canBeRemoved = false;
			}
			val.AddComponent<IsleAltar>();
			PrefabManager.Instance.AddPrefab(new CustomPrefab(val, false));
			RavenIslePlugin.Log.LogInfo((object)("The altar is built from " + text));
		}
	}

	private static void MakeLore()
	{
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Expected O, but got Unknown
		string text = Pick(RavenIslePlugin.LoreBases);
		if (text != null)
		{
			IslePlan.Bases["anwo_ri_lore"] = text;
			GameObject val = PrefabManager.Instance.CreateClonedPrefab("anwo_ri_lore", text);
			Strip<RuneStone>(val);
			EnsureNetView(val);
			Piece component = val.GetComponent<Piece>();
			if ((Object)(object)component != (Object)null)
			{
				component.m_canBeRemoved = false;
			}
			val.AddComponent<IsleLore>();
			PrefabManager.Instance.AddPrefab(new CustomPrefab(val, false));
			RavenIslePlugin.Log.LogInfo((object)("Lore stones are built from " + text));
		}
	}

	private static void Fields(ZDO z, string comp, string field, object value)
	{
		z.Set("HasFields", true);
		z.Set("HasFields" + comp, true);
		string text = comp + "." + field;
		if (!(value is bool flag))
		{
			if (!(value is float num))
			{
				if (!(value is int num2))
				{
					if (value is string text2)
					{
						z.Set(text, text2);
					}
				}
				else
				{
					z.Set(text, num2);
				}
			}
			else
			{
				z.Set(text, num);
			}
		}
		else
		{
			z.Set(text, flag);
		}
	}

	public static List<PlanItem> Plan()
	{
		IslePlan.PlaceWards = RavenIslePlugin.WardFires.Value;
		return IslePlan.Items();
	}

	public static Vector3 WorldPos(PlanItem it)
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		return Realm.ToWorld(it.X, it.Z, (float)it.Y);
	}

	public static Quaternion WorldRot(PlanItem it)
	{
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		return Quaternion.Euler(it.Pitch, it.Yaw, it.Roll);
	}

	private static ZDO SpawnZdo(PlanItem it)
	{
		//IL_0074: 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_007f: 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_00ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
		GameObject prefab = ZNetScene.instance.GetPrefab(it.Prefab);
		if ((Object)(object)prefab == (Object)null)
		{
			RavenIslePlugin.Log.LogWarning((object)("Missing prefab " + it.Prefab));
			return null;
		}
		ZNetView component = prefab.GetComponent<ZNetView>();
		if ((Object)(object)component == (Object)null)
		{
			RavenIslePlugin.Log.LogWarning((object)("Prefab " + it.Prefab + " is not a world object"));
			return null;
		}
		int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)prefab).name);
		Vector3 val = WorldPos(it);
		ZDO val2 = ZDOMan.instance.CreateNewZDO(val, stableHashCode);
		val2.Persistent = component.m_persistent;
		val2.Type = component.m_type;
		val2.Distant = component.m_distant;
		val2.SetPrefab(stableHashCode);
		val2.SetRotation(WorldRot(it));
		if (it.Protect)
		{
			val2.Set("anwo_ri_prot", true);
		}
		if (it.Part.Length > 0)
		{
			val2.Set("anwo_ri_part", it.Part);
		}
		if (it.Id.Length > 0)
		{
			val2.Set("anwo_ri_id", it.Id);
		}
		if (it.Hoard.Length > 0)
		{
			val2.Set("anwo_ri_hoard", it.Hoard);
		}
		if (it.Loot.Length > 0)
		{
			val2.Set("anwo_ri_loot", it.Loot);
		}
		if (it.AlwaysLit)
		{
			Fields(val2, "Fireplace", "m_infiniteFuel", true);
			val2.Set(ZDOVars.s_fuel, 10f);
		}
		if (it.Loot.Length > 0 && (Object)(object)prefab.GetComponent<Container>() != (Object)null)
		{
			Loot.FillZdo(val2, it.Loot, val);
		}
		return val2;
	}

	private static bool AlreadyThere(PlanItem it)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c5: 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_00cb: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val = WorldPos(it);
		Vector2s zone = ZoneSystem.GetZone(val);
		int stableHashCode = StringExtensionMethods.GetStableHashCode(it.Prefab);
		List<ZDO> list = new List<ZDO>();
		for (int i = -1; i <= 1; i++)
		{
			for (int j = -1; j <= 1; j++)
			{
				list.Clear();
				ZDOMan.instance.FindSectorObjects(new Vector2s(zone.x + j, zone.y + i), new SimulationDistance(0, 0, true), list, (List<ZDO>)null);
				foreach (ZDO item in list)
				{
					if (it.Hoard.Length > 0 && item.GetString("anwo_ri_hoard", "") == it.Hoard)
					{
						return true;
					}
					if (item.GetPrefab() == stableHashCode && item.GetBool("anwo_ri_prot", false))
					{
						Vector3 val2 = item.GetPosition() - val;
						if (((Vector3)(ref val2)).sqrMagnitude < 0.25f)
						{
							return true;
						}
					}
				}
			}
		}
		return false;
	}

	private static float ClearRadius(PlanItem it)
	{
		PieceShapes.Shape shape = IslePlan.ShapeOf(it.Prefab);
		if (shape == null)
		{
			return 2f;
		}
		return Mathf.Max(1.5f, Mathf.Sqrt(Mathf.Max(shape.Solid.MinX * shape.Solid.MinX, shape.Solid.MaxX * shape.Solid.MaxX) + Mathf.Max(shape.Solid.MinZ * shape.Solid.MinZ, shape.Solid.MaxZ * shape.Solid.MaxZ)) + 0.8f);
	}

	[HarmonyPatch(typeof(ZoneSystem), "PlaceVegetation")]
	[HarmonyPrefix]
	private unsafe static void BeforeVegetation(Vector2s zoneID, Vector3 zoneCenterPos, object clearAreas, SpawnMode mode)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Invalid comparison between Unknown and I4
		//IL_0291: Unknown result type (might be due to invalid IL or missing references)
		//IL_0296: Unknown result type (might be due to invalid IL or missing references)
		//IL_029b: 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_0094: 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_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0204: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_02eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_0217: Unknown result type (might be due to invalid IL or missing references)
		//IL_021e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_023f: Unknown result type (might be due to invalid IL or missing references)
		//IL_014b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0150: Unknown result type (might be due to invalid IL or missing references)
		//IL_0152: Unknown result type (might be due to invalid IL or missing references)
		//IL_0159: Unknown result type (might be due to invalid IL or missing references)
		//IL_016c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0173: Unknown result type (might be due to invalid IL or missing references)
		//IL_0194: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if (!Realm.In(zoneCenterPos) || !ZNet.instance.IsServer() || ((int)mode != 0 && (int)mode != 2))
			{
				return;
			}
			IList list = clearAreas as IList;
			if (list != null && s_clearAreaType != null)
			{
				foreach (IsleSite site in IsleLayout.Sites)
				{
					double num = Math.Max(site.Flat, 6.0) + 4.0;
					Vector3 val = Realm.ToWorld(site.X, site.Z, 0f);
					if (!((double)Mathf.Abs(val.x - zoneCenterPos.x) > 32.0 + num) && !((double)Mathf.Abs(val.z - zoneCenterPos.z) > 32.0 + num))
					{
						list.Add(Activator.CreateInstance(s_clearAreaType, val, (float)num));
					}
				}
				IsleLayout.HoardSpot[] hoards = IsleLayout.Hoards;
				foreach (IsleLayout.HoardSpot hoardSpot in hoards)
				{
					Vector3 val2 = Realm.ToWorld(hoardSpot.X, hoardSpot.Z, 0f);
					if (!(Mathf.Abs(val2.x - zoneCenterPos.x) > 36f) && !(Mathf.Abs(val2.z - zoneCenterPos.z) > 36f))
					{
						list.Add(Activator.CreateInstance(s_clearAreaType, val2, 4f));
					}
				}
			}
			List<PlanItem> list2 = Plan();
			if (list != null && s_clearAreaType != null)
			{
				foreach (PlanItem item in list2)
				{
					Vector3 val3 = WorldPos(item);
					if (!(Mathf.Abs(val3.x - zoneCenterPos.x) > 36f) && !(Mathf.Abs(val3.z - zoneCenterPos.z) > 36f))
					{
						list.Add(Activator.CreateInstance(s_clearAreaType, val3, ClearRadius(item)));
					}
				}
			}
			int num2 = 0;
			foreach (PlanItem item2 in list2)
			{
				if (!(ZoneSystem.GetZone(WorldPos(item2)) != zoneID) && !AlreadyThere(item2))
				{
					SpawnZdo(item2);
					num2++;
				}
			}
			if (num2 > 0)
			{
				ManualLogSource log = RavenIslePlugin.Log;
				string text = num2.ToString();
				Vector2s val4 = zoneID;
				log.LogInfo((object)("Raven Isle: placed " + text + " objects in zone " + ((object)(*(Vector2s*)(&val4))/*cast due to .constrained prefix*/).ToString()));
			}
		}
		catch (Exception ex)
		{
			RavenIslePlugin.Log.LogError((object)("Raven Isle zone setup failed: " + ex));
		}
	}

	public static void ResetSession()
	{
		s_layoutChecked = false;
		s_buildChecked = false;
		IslePlan.Reset();
	}

	public static void EnsureLayout()
	{
		//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
		if (s_layoutChecked)
		{
			return;
		}
		ZoneSystem instance = ZoneSystem.instance;
		if ((Object)(object)instance == (Object)null || (Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer() || !instance.LocationsGenerated || !Realm.Enabled)
		{
			return;
		}
		s_layoutChecked = true;
		if (IsleState.Value("layout") == "1")
		{
			return;
		}
		try
		{
			HashSet<Vector2s> hashSet = AccessTools.Field(typeof(ZoneSystem), "m_generatedZones").GetValue(instance) as HashSet<Vector2s>;
			int num = 0;
			if (hashSet != null)
			{
				List<ZDO> objs = new List<ZDO>();
				num = hashSet.RemoveWhere(delegate(Vector2s z)
				{
					//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_001f: Unknown result type (might be due to invalid IL or missing references)
					//IL_0023: Unknown result type (might be due to invalid IL or missing references)
					if (!Realm.In(ZoneSystem.GetZonePos(z)))
					{
						return false;
					}
					objs.Clear();
					ZDOMan.instance.FindSectorObjects(z, new SimulationDistance(0, 0, true), objs, (List<ZDO>)null);
					return objs.Count == 0;
				});
			}
			MethodInfo methodInfo = AccessTools.Method(typeof(ZoneSystem), "RegisterLocation", (Type[])null, (Type[])null);
			int num2 = 0;
			foreach (IsleSite site in IsleLayout.Sites)
			{
				if (site.Kind == SiteKind.Location && !string.IsNullOrEmpty(site.Prefab))
				{
					ZoneLocation val = FindLocation(site.Prefab);
					if (val == null)
					{
						RavenIslePlugin.Log.LogWarning((object)("Location " + site.Prefab + " not found; " + site.Label + " stays empty"));
					}
					else if (val.m_unique)
					{
						RavenIslePlugin.Log.LogWarning((object)("Location " + site.Prefab + " is unique in the world; " + site.Label + " stays empty"));
					}
					else
					{
						Vector3 val2 = Ground(site.X, site.Z);
						methodInfo.Invoke(instance, new object[3] { val, val2, false });
						num2++;
					}
				}
			}
			IsleState.SetValue("layout", "1");
			RavenIslePlugin.Log.LogInfo((object)("Raven Isle laid out: " + num2 + " places registered, " + num + " old zones cleared"));
		}
		catch (Exception ex)
		{
			RavenIslePlugin.Log.LogError((object)("Raven Isle layout failed: " + ex));
		}
	}

	public static void EnsureBuild()
	{
		//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)
		//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0102: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01df: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_034c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0351: Unknown result type (might be due to invalid IL or missing references)
		//IL_0356: Unknown result type (might be due to invalid IL or missing references)
		//IL_023b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0240: Unknown result type (might be due to invalid IL or missing references)
		//IL_0263: Unknown result type (might be due to invalid IL or missing references)
		//IL_0277: Unknown result type (might be due to invalid IL or missing references)
		//IL_0285: Unknown result type (might be due to invalid IL or missing references)
		//IL_029b: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_04e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_04ec: Expected O, but got Unknown
		//IL_04f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_04f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0501: Unknown result type (might be due to invalid IL or missing references)
		//IL_0506: Unknown result type (might be due to invalid IL or missing references)
		//IL_036a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0374: Unknown result type (might be due to invalid IL or missing references)
		//IL_0384: Unknown result type (might be due to invalid IL or missing references)
		//IL_0548: Unknown result type (might be due to invalid IL or missing references)
		//IL_054d: Unknown result type (might be due to invalid IL or missing references)
		//IL_054f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0554: Unknown result type (might be due to invalid IL or missing references)
		//IL_039c: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0584: Unknown result type (might be due to invalid IL or missing references)
		//IL_058d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0566: Unknown result type (might be due to invalid IL or missing references)
		//IL_056b: Unknown result type (might be due to invalid IL or missing references)
		//IL_05df: Unknown result type (might be due to invalid IL or missing references)
		//IL_05e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0405: Unknown result type (might be due to invalid IL or missing references)
		//IL_0419: Unknown result type (might be due to invalid IL or missing references)
		//IL_0427: Unknown result type (might be due to invalid IL or missing references)
		//IL_067a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0681: Expected O, but got Unknown
		if (s_buildChecked)
		{
			return;
		}
		ZoneSystem instance = ZoneSystem.instance;
		if ((Object)(object)instance == (Object)null || (Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer() || !instance.LocationsGenerated || !Realm.Enabled || (Object)(object)ZNetScene.instance == (Object)null)
		{
			return;
		}
		s_buildChecked = true;
		if (IsleState.Value("build") == BuildKey)
		{
			return;
		}
		try
		{
			HashSet<Vector2s> gen = AccessTools.Field(typeof(ZoneSystem), "m_generatedZones").GetValue(instance) as HashSet<Vector2s>;
			if (gen == null)
			{
				return;
			}
			List<PlanItem> list = Plan();
			HashSet<Vector2s> hashSet = new HashSet<Vector2s>();
			Vector2s item = default(Vector2s);
			foreach (PlanItem item2 in list)
			{
				Vector2s zone = ZoneSystem.GetZone(WorldPos(item2));
				for (int i = -1; i <= 1; i++)
				{
					for (int j = -1; j <= 1; j++)
					{
						((Vector2s)(ref item))..ctor(zone.x + j, zone.y + i);
						if (gen.Contains(item))
						{
							hashSet.Add(item);
						}
					}
				}
			}
			HashSet<string> hashSet2 = new HashSet<string>(list.Select((PlanItem planItem) => planItem.Prefab).Concat(IslePlan.OldGatePieces));
			Dictionary<int, string> dictionary = new Dictionary<int, string>();
			foreach (string item3 in hashSet2)
			{
				dictionary[StringExtensionMethods.GetStableHashCode(item3)] = item3;
			}
			List<IslePlan.Existing> list2 = new List<IslePlan.Existing>();
			List<ZDO> list3 = new List<ZDO>();
			foreach (Vector2s item4 in hashSet)
			{
				list3.Clear();
				ZDOMan.instance.FindSectorObjects(item4, new SimulationDistance(0, 0, true), list3, (List<ZDO>)null);
				foreach (ZDO item5 in list3)
				{
					string text = item5.GetString("anwo_ri_hoard", "");
					if (dictionary.TryGetValue(item5.GetPrefab(), out var value) || text.Length != 0)
					{
						Vector3 position = item5.GetPosition();
						IslePlan.Existing obj = new IslePlan.Existing
						{
							Ref = item5,
							Prefab = (value ?? ""),
							X = position.x - 0f,
							Y = position.y,
							Z = position.z - -14000f
						};
						Quaternion rotation = item5.GetRotation();
						obj.Yaw = ((Quaternion)(ref rotation)).eulerAngles.y;
						obj.Hoard = text;
						obj.PlayerBuilt = item5.GetLong(ZDOVars.s_creator, 0L) != 0;
						obj.Ours = item5.GetBool("anwo_ri_prot", false);
						list2.Add(obj);
					}
				}
			}
			IsleLayout.HoardSpot[] hoards = IsleLayout.Hoards;
			Vector2s val = default(Vector2s);
			foreach (IsleLayout.HoardSpot hoardSpot in hoards)
			{
				Vector2s zone2 = ZoneSystem.GetZone(Realm.ToWorld(hoardSpot.X, hoardSpot.Z, 0f));
				for (int num2 = -1; num2 <= 1; num2++)
				{
					for (int num3 = -1; num3 <= 1; num3++)
					{
						((Vector2s)(ref val))..ctor(zone2.x + num3, zone2.y + num2);
						if (hashSet.Contains(val))
						{
							continue;
						}
						list3.Clear();
						ZDOMan.instance.FindSectorObjects(val, new SimulationDistance(0, 0, true), list3, (List<ZDO>)null);
						foreach (ZDO item6 in list3)
						{
							string text2 = item6.GetString("anwo_ri_hoard", "");
							if (text2.Length != 0)
							{
								Vector3 position2 = item6.GetPosition();
								list2.Add(new IslePlan.Existing
								{
									Ref = item6,
									Prefab = "",
									X = position2.x - 0f,
									Y = position2.y,
									Z = position2.z - -14000f,
									Hoard = text2,
									Ours = true
								});
							}
						}
					}
				}
			}
			IslePlan.Update update = IslePlan.Migrate(list, list2, (double x, double z) => gen.Contains(ZoneSystem.GetZone(Realm.ToWorld(x, z, 0f))));
			long sessionID = ZDOMan.GetSessionID();
			int num4 = 0;
			int num5 = 0;
			int num6 = 0;
			foreach (KeyValuePair<PlanItem, IslePlan.Existing> item7 in update.Keep)
			{
				ZDO val2 = (ZDO)item7.Value.Ref;
				Vector3 val3 = WorldPos(item7.Key);
				Quaternion val4 = WorldRot(item7.Key);
				if (item7.Key.Prefab == "anwo_ri_gate" && val2.GetInt(ZDOVars.s_state, 0) != 0)
				{
					val2.SetOwner(sessionID);
					val2.Set(ZDOVars.s_state, 0, false);
				}
				Vector3 val5 = val2.GetPosition() - val3;
				if (!(((Vector3)(ref val5)).sqrMagnitude <= 0.0004f) || !(Quaternion.Angle(val2.GetRotation(), val4) <= 0.5f))
				{
					val2.SetOwner(sessionID);
					val2.SetPosition(val3);
					val2.SetRotation(val4);
					if (item7.Key.Part.Length > 0)
					{
						val2.Set("anwo_ri_part", item7.Key.Part);
					}
					ZNetView val6 = ZNetScene.instance.FindInstance(val2);
					if ((Object)(object)val6 != (Object)null)
					{
						((Component)val6).transform.SetPositionAndRotation(val3, val4);
					}
					num4++;
				}
			}
			int num7 = 0;
			foreach (PlanItem item8 in update.Add)
			{
				num7 += ClearAround(item8, list3, sessionID);
				if (SpawnZdo(item8) != null)
				{
					num5++;
				}
			}
			foreach (IslePlan.Existing item9 in update.Remove)
			{
				ZDO val7 = (ZDO)item9.Ref;
				val7.SetOwner(sessionID);
				ZDOMan.instance.DestroyZDO(val7);
				num6++;
			}
			IsleState.SetValue("build", BuildKey);
			RavenIslePlugin.Log.LogInfo((object)("Raven Isle brought up to date: " + num4 + " pieces moved, " + num5 + " added, " + num6 + " old gate pieces taken down, " + num7 + " trees and rocks cleared from their spots"));
		}
		catch (Exception ex)
		{
			RavenIslePlugin.Log.LogError((object)("Raven Isle update failed: " + ex));
		}
	}

	private static int ClearAround(PlanItem it, List<ZDO> buf, long me)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: 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_00b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00da: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val = WorldPos(it);
		float num = ClearRadius(it);
		if (it.Part.StartsWith("ward"))
		{
			num = Mathf.Max(num, 3.8f);
		}
		if (it.Hoard.Length > 0)
		{
			num = Mathf.Max(num, 4.6f);
		}
		Vector2s zone = ZoneSystem.GetZone(val);
		int num2 = 0;
		for (int i = -1; i <= 1; i++)
		{
			for (int j = -1; j <= 1; j++)
			{
				buf.Clear();
				ZDOMan.instance.FindSectorObjects(new Vector2s(zone.x + j, zone.y + i), new SimulationDistance(0, 0, true), buf, (List<ZDO>)null);
				foreach (ZDO item in buf)
				{
					Vector3 position = item.GetPosition();
					if (Mathf.Abs(position.y - val.y) > 12f)
					{
						continue;
					}
					Vector2 val2 = new Vector2(position.x - val.x, position.z - val.z);
					if (!(((Vector2)(ref val2)).magnitude > num) && item.GetLong(ZDOVars.s_creator, 0L) == 0L && !item.GetBool("anwo_ri_prot", false))
					{
						GameObject prefab = ZNetScene.instance.GetPrefab(item.GetPrefab());
						if (!((Object)(object)prefab == (Object)null) && !((Object)(object)prefab.GetComponent<Piece>() != (Object)null) && ((Object)(object)prefab.GetComponent<TreeBase>() != (Object)null || (Object)(object)prefab.GetComponent<TreeLog>() != (Object)null || (Object)(object)prefab.GetComponent<MineRock>() != (Object)null || (Object)(object)prefab.GetComponent<MineRock5>() != (Object)null || (Object)(object)prefab.GetComponent<Pickable>() != (Object)null || ((Object)(object)prefab.GetComponent<Destructible>() != (Object)null && (Object)(object)prefab.GetComponent<Container>() == (Object)null)))
						{
							item.SetOwner(me);
							ZDOMan.instance.DestroyZDO(item);
							num2++;
						}
					}
				}
			}
		}
		return num2;
	}

	public static ZoneLocation FindLocation(string name)
	{
		ZoneLocation val = null;
		foreach (ZoneLocation location in ZoneSystem.instance.m_locations)
		{
			if (location != null && location.m_prefab.IsValid && !(location.m_prefab.Name != name) && (val == null || (location.m_enable && !val.m_enable)))
			{
				val = location;
			}
		}
		return val;
	}
}
public enum IsleBuildRule
{
	LandingUntilWarden,
	LandingOnly,
	Everywhere,
	NowhereUntilWarden
}
public static class IsleHooks
{
	private static bool s_nightmare;

	private static float s_nightmareAt = -1f;

	private static IsleRegion s_lastRegion = IsleRegion.Sea;

	private static float s_curseMsg;

	private static bool s_cursed;

	private static bool s_ridgeArmed = true;

	private static float s_ridgeLast = -999f;

	private const string StarsDone = "anwo_ri_stars";

	private static bool s_ownStars;

	internal const string LootDone = "anwo_ri_lootdone";

	public static bool BuildAllowed(Vector3 p)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		if (!Realm.In(p))
		{
			return true;
		}
		bool wardenSlain = IsleState.WardenSlain;
		switch (RavenIslePlugin.BuildRule.Value)
		{
		case IsleBuildRule.Everywhere:
			return true;
		case IsleBuildRule.NowhereUntilWarden:
			return wardenSlain;
		case IsleBuildRule.LandingOnly:
			return InLandingCamp(p);
		default:
			if (!wardenSlain)
			{
				return InLandingCamp(p);
			}
			return true;
		}
	}

	public static bool InLandingCamp(Vector3 p)
	{
		//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)
		return Realm.Distance2D(p, IsleBuilder.KeeperPoint()) < RavenIslePlugin.LandingBuildRadius.Value;
	}

	[HarmonyPatch(typeof(Location), "IsInsideNoBuildLocation")]
	[HarmonyPostfix]
	private static void NoBuild(Vector3 point, ref bool __result)
	{
		//IL_0004: Unknown result type (might be due to invalid IL or missing references)
		if (!__result && !BuildAllowed(point))
		{
			__result = true;
		}
	}

	[HarmonyPatch(typeof(Player), "UpdatePlacementGhost")]
	[HarmonyPostfix]
	private static void NoPortals(Player __instance, GameObject ___m_placementGhost, ref PlacementStatus ___m_placementStatus)
	{
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)___m_placementGhost == (Object)null) && RavenIslePlugin.NoPortalsBeforeWarden.Value && !IsleState.WardenSlain && Realm.In(___m_placementGhost.transform.position) && ((Object)(object)___m_placementGhost.GetComponent<TeleportWorld>() != (Object)null || (Object)(object)___m_placementGhost.GetComponent<IslePortal>() != (Object)null))
		{
			___m_placementStatus = (PlacementStatus)6;
		}
	}

	[HarmonyPatch(typeof(Player), "OnDeath")]
	[HarmonyPostfix]
	private static void Died(Player __instance)
	{
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && Realm.In(((Component)__instance).transform.position) && !IsleState.WardenSlain)
		{
			s_nightmare = true;
		}
	}

	[HarmonyPatch(typeof(Player), "OnSpawned")]
	[HarmonyPostfix]
	private static void Spawned(Player __instance)
	{
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
		{
			if (s_nightmare && !Realm.In(((Component)__instance).transform.position) && RavenIslePlugin.Nightmare.Value)
			{
				s_nightmareAt = Time.time + 2.5f;
			}
			s_nightmare = false;
			Quests.ResetSeen();
		}
	}

	public static void Tick(Player p)
	{
		//IL_0054: 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_0088: Unknown result type (might be due to invalid IL or missing references)
		if (s_nightmareAt > 0f && Time.time > s_nightmareAt)
		{
			s_nightmareAt = -1f;
			MessageHud instance = MessageHud.instance;
			if (instance != null)
			{
				instance.ShowMessage((MessageType)2, "It must have been a nightmare...", 0, (Sprite)null, false, true);
			}
		}
		if ((Object)(object)p == (Object)null || ((Character)p).IsDead())
		{
			return;
		}
		int num;
		int num2;
		if (Realm.In(((Component)p).transform.position))
		{
			num = ((!((Character)p).InInterior()) ? 1 : 0);
			if (num != 0)
			{
				num2 = (int)Realm.Sample(((Component)p).transform.position.x, ((Component)p).transform.position.z).Region;
				goto IL_009c;
			}
		}
		else
		{
			num = 0;
		}
		num2 = 0;
		goto IL_009c;
		IL_009c:
		IsleRegion isleRegion = (IsleRegion)num2;
		if (num != 0 && isleRegion != s_lastRegion && isleRegion != IsleRegion.Sea && RavenIslePlugin.RegionNames.Value)
		{
			MessageHud instance2 = MessageHud.instance;
			if (instance2 != null)
			{
				instance2.ShowMessage((MessageType)2, "<size=40>" + RegionTitle(isleRegion) + "</size>", 0, (Sprite)null, false, true);
			}
		}
		if (num != 0 && IsleState.Get(p, "arrived") == null)
		{
			IsleState.Put(p, "arrived", "1");
			if (RavenIslePlugin.ArrivalIntro.Value && (Object)(object)TextViewer.instance != (Object)null)
			{
				TextViewer.instance.ShowText((Style)1, "Raven Isle", "Beyond the edge of the world, where the sea falls into nothing, the ravens keep an island.\n\nFind Munin by the fire.", false);
			}
		}
		s_lastRegion = isleRegion;
		if (num != 0)
		{
			Curse(p, isleRegion);
		}
		if (num != 0)
		{
			RidgeWarning(p, isleRegion);
		}
	}

	private static bool Sealed(IsleRegion r)
	{
		if (r != IsleRegion.Ashfields || IsleState.EmberOpen)
		{
			if (r == IsleRegion.Frostpeak || r == IsleRegion.Summit)
			{
				return !IsleState.FrostOpen;
			}
			return false;
		}
		return true;
	}

	private static void RidgeWarning(Player p, IsleRegion reg)
	{
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
		if (!RavenIslePlugin.RidgeWarning.Value || !RavenIslePlugin.Curse.Value || Sealed(reg))
		{
			return;
		}
		Vector3 position = ((Component)p).transform.position;
		double num = position.x - 0f;
		double num2 = position.z - -14000f;
		string[] array = new string[2] { "ember_gate", "frost_gate" };
		for (int i = 0; i < array.Length; i++)
		{
			IsleSite isleSite = IsleLayout.Get(array[i]);
			if (isleSite != null && (isleSite.X - num) * (isleSite.X - num) + (isleSite.Z - num2) * (isleSite.Z - num2) < 900.0)
			{
				s_ridgeArmed = false;
				return;
			}
		}
		IsleRegion isleRegion = IsleRegion.Sea;
		IsleRegion isleRegion2 = IsleRegion.Sea;
		for (int j = 0; j < 12; j++)
		{
			double num3 = (double)j * Math.PI / 6.0;
			double[] array2 = new double[5] { 12.0, 24.0, 36.0, 48.0, 60.0 };
			foreach (double num4 in array2)
			{
				IsleRegion region = IsleTerrain.Sample(num + Math.Sin(num3) * num4, num2 + Math.Cos(num3) * num4, withSites: false).Region;
				if (Sealed(region))
				{
					if (num4 <= 36.0 && isleRegion == IsleRegion.Sea)
					{
						isleRegion = region;
					}
					isleRegion2 = region;
				}
			}
		}
		if (isleRegion2 == IsleRegion.Sea)
		{
			s_ridgeArmed = true;
		}
		else if (isleRegion != IsleRegion.Sea)
		{
			double num5 = double.MaxValue;
			for (int k = 0; k < 8; k++)
			{
				double num6 = (double)k * Math.PI / 4.0;
				num5 = Math.Min(num5, IsleTerrain.Sample(num + Math.Sin(num6) * 14.0, num2 + Math.Cos(num6) * 14.0).Height);
			}
			if (!((double)position.y - num5 < 6.0) && s_ridgeArmed && !(Time.time - s_ridgeLast < 60f))
			{
				s_ridgeArmed = false;
				s_ridgeLast = Time.time;
				((Character)p).Message((MessageType)2, (isleRegion == IsleRegion.Ashfields) ? "The ravens' ward holds this ridge.\nThe Ashfields burn whoever crosses it: the Ember gate is the way in." : "The ravens' ward holds this ridge.\nThe north freezes whoever crosses it: the Frost gate is the way in.", 0, (Sprite)null, false);
			}
		}
	}

	private static string RegionTitle(IsleRegion r)
	{
		return r switch
		{
			IsleRegion.Landing => "The Landing", 
			IsleRegion.Mistwood => "Mistwood", 
			IsleRegion.Ashfields => "The Ashfields", 
			IsleRegion.Frostpeak => "Frostpeak", 
			IsleRegion.Summit => "The Warden's Barrow", 
			_ => "Raven Isle", 
		};
	}

	private static void Curse(Player p, IsleRegion reg)
	{
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_005c: Expected O, but got Unknown
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		if (!RavenIslePlugin.Curse.Value)
		{
			return;
		}
		bool flag = reg == IsleRegion.Ashfields && !IsleState.EmberOpen;
		bool flag2 = reg == IsleRegion.Frostpeak && !IsleState.FrostOpen;
		bool flag3 = reg == IsleRegion.Summit && !IsleState.FrostOpen;
		if (!flag && !flag2 && !flag3)
		{
			s_cursed = false;
		}
		else if (!((Character)p).IsDebugFlying())
		{
			HitData val = new HitData();
			val.m_damage.m_damage = RavenIslePlugin.CurseDamage.Value;
			val.m_point = ((Character)p).GetCenterPoint();
			val.m_hitType = (HitType)(flag ? 5 : 6);
			if (flag)
			{
				((Character)p).GetSEMan().AddStatusEffect(SEMan.s_statusEffectBurning, true, 0, 0f, (short)(-1));
			}
			((Character)p).Damage(val);
			string text = (flag ? "The ash burns you! The Ember gate is still sealed: turn back." : "The frost bites! The Frost gate is still sealed: turn back.");
			if (!s_cursed)
			{
				s_cursed = true;
				s_curseMsg = Time.time + 15f;
				((Character)p).Message((MessageType)2, text, 0, (Sprite)null, false);
			}
			else if (Time.time > s_curseMsg)
			{
				s_curseMsg = Time.time + 15f;
				((Character)p).Message((MessageType)1, text, 0, (Sprite)null, false);
			}
		}
	}

	internal static bool Tough(Character c, out IsleRegion reg)
	{
		//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_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		reg = IsleRegion.Sea;
		if ((Object)(object)c == (Object)null || !RavenIslePlugin.ToughCreatures.Value || c.IsPlayer())
		{
			return false;
		}
		Vector3 position = ((Component)c).transform.position;
		if (!Realm.In(position) || c.IsTamed())
		{
			return false;
		}
		reg = Realm.RegionAt(position);
		if (reg != IsleRegion.Mistwood && reg != IsleRegion.Ashfields && reg != IsleRegion.Frostpeak)
		{
			return reg == IsleRegion.Summit;
		}
		return true;
	}

	[HarmonyPatch(typeof(Character), "SetLevel")]
	[HarmonyPrefix]
	private static void ExtraStars(Character __instance, ref int level)
	{
		if (!Warden.s_spawning && !s_ownStars && level >= 1 && level < 3 && !Warden.Is(__instance) && Tough(__instance, out var reg))
		{
			int num = RavenIslePlugin.StarsFor(reg);
			if (num > 0)
			{
				level = Mathf.Min(level + num, 3);
			}
		}
	}

	[HarmonyPatch(typeof(Character), "Awake")]
	[HarmonyPostfix]
	private static void StarsOnSpawn(Character __instance, ZNetView ___m_nview)
	{
		try
		{
			if (Warden.s_spawning || (Object)(object)___m_nview == (Object)null || !___m_nview.IsValid() || !___m_nview.IsOwner() || __instance.IsPlayer() || Warden.Is(__instance))
			{
				return;
			}
			ZDO zDO = ___m_nview.GetZDO();
			if (zDO.GetBool("anwo_ri_stars", false) || !Tough(__instance, out var reg))
			{
				return;
			}
			zDO.Set("anwo_ri_stars", true);
			int level = __instance.GetLevel();
			int num = RavenIslePlugin.StarsFor(reg);
			if (num <= 0 || level >= 3)
			{
				return;
			}
			s_ownStars = true;
			try
			{
				__instance.SetLevel(Mathf.Min(level + num, 3));
			}
			finally
			{
				s_ownStars = false;
			}
		}
		catch (Exception ex)
		{
			RavenIslePlugin.Log.LogDebug((object)("Raven Isle stars: " + ex.Message));
		}
	}

	[HarmonyPatch(typeof(Character), "GetMaxHealthBase")]
	[HarmonyPostfix]
	private static void MoreHealth(Character __instance, ref float __result)
	{
		if (!Warden.Is(__instance) && Tough(__instance, out var reg))
		{
			__result *= RavenIslePlugin.HealthFor(reg);
		}
	}

	[HarmonyPatch(typeof(Attack), "GetLevelDamageFactor")]
	[HarmonyPostfix]
	private static void HarderHits(Humanoid ___m_character, ref float __result)
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)___m_character == (Object)null) && !((Character)___m_character).IsPlayer() && Realm.In(((Component)___m_character).transform.position))
		{
			IsleRegion reg;
			if (Warden.Is((Character)(object)___m_character))
			{
				__result *= RavenIslePlugin.WardenDamage.Value;
			}
			else if (Tough((Character)(object)___m_character, out reg))
			{
				__result *= RavenIslePlugin.DamageFor(reg);
			}
		}
	}

	[HarmonyPatch(typeof(Door), "HaveKey")]
	[HarmonyPostfix]
	private static void IsleDoorKey(Door __instance, ref bool __result)
	{
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		if (__result || (Object)(object)__instance.m_keyItem == (Object)null || (Object)(object)((Component)__instance).GetComponent<IsleGate>() != (Object)null)
		{
			return;
		}
		Vector3 position = ((Component)__instance).transform.position;
		if (Realm.In(position))
		{
			switch (Realm.RegionAt(position))
			{
			case IsleRegion.Ashfields:
				__result = IsleState.EmberOpen;
				break;
			case IsleRegion.Frostpeak:
			case IsleRegion.Summit:
				__result = IsleState.FrostOpen;
				break;
			default:
				__result = true;
				break;
			}
		}
	}

	[HarmonyPatch(typeof(Container), "Awake")]
	[HarmonyPrefix]
	private static void ChestAwakePre(Container __instance, out bool __state)
	{
		ZNetView component = ((Component)__instance).GetComponent<ZNetView>();
		__state = (Object)(object)component != (Object)null && component.GetZDO() != null && !component.GetZDO().GetBool(ZDOVars.s_addedDefaultItems, false);
	}

	[HarmonyPatch(typeof(Container), "Awake")]
	[HarmonyPostfix]
	private static void ChestAwake(Container __instance, bool __state, ZNetView ___m_nview, Inventory ___m_inventory)
	{
		if (__state)
		{
			TryFill(__instance, ___m_nview, ___m_inventory);
		}
	}

	[HarmonyPatch(typeof(Container), "Load")]
	[HarmonyPostfix]
	private static void ChestLoad(Container __instance, bool __result, ZNetView ___m_nview, Inventory ___m_inventory)
	{
		if (__result)
		{
			TryFill(__instance, ___m_nview, ___m_inventory);
		}
	}

	[HarmonyPatch(typeof(Container), "CheckForChanges")]
	[HarmonyPostfix]
	private static void ChestCheck(Container __instance, ZNetView ___m_nview, Inventory ___m_inventory, bool ___m_inUse, uint ___m_lastRevision)
	{
		if (!___m_inUse && !((Object)(object)___m_nview == (Object)null) && ___m_nview.IsValid() && ___m_nview.IsOwner())
		{
			ZDO zDO = ___m_nview.GetZDO();
			if (___m_lastRevision == zDO.DataRevision && zDO.GetString("anwo_ri_loot", "").Length != 0)
			{
				TryFill(__instance, ___m_nview, ___m_inventory);
			}
		}
	}

	private static void TryFill(Container c, ZNetView nview, Inventory inv)
	{
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if (!((Object)(object)nview == (Object)null) && nview.IsValid() && nview.IsOwner() && inv != null)
			{
				ZDO zDO = nview.GetZDO();
				string text = zDO.GetString("anwo_ri_loot", "");
				if (text.Length != 0 && !zDO.GetBool("anwo_ri_lootdone", false) && zDO.GetBool(ZDOVars.s_addedDefaultItems, false))
				{
					zDO.Set("anwo_ri_lootdone", true);
					Loot.Fill(inv, text, ((Component)c).transform.position);
				}
			}
		}
		catch (Exception ex)
		{
			RavenIslePlugin.Log.LogWarning((object)("Raven Isle chest loot failed: " + ex.Message));
		}
	}

	[HarmonyPatch(typeof(Container), "Interact")]
	[HarmonyPostfix]
	private static void HoardOpened(Container __instance, Humanoid character, bool __result)
	{
		if (__result && !((Object)(object)character != (Object)(object)Player.m_localPlayer))
		{
			ZNetView component = ((Component)__instance).GetComponent<ZNetView>();
			string text = (((Object)(object)component != (Object)null && component.GetZDO() != null) ? component.GetZDO().GetString("anwo_ri_hoard", "") : "");
			if (text.Length != 0 && !IsleState.Has("hoard_" + text))
			{
				IsleState.Set("hoard_" + text);
				Quests.Announce("A ravens' hoard! (" + (IsleState.HoardsFound() + 1) + "/" + IsleState.HoardIds.Length + ")");
			}
		}
	}
}
public static class Loot
{
	private class Check
	{
		public ZDO Zdo;

		public string Spec;

		public float Until;

		public float Next;
	}

	private static readonly List<Check> s_checks = new List<Check>();

	private static readonly Dictionary<string, string> FoundKey = new Dictionary<string, string>
	{
		{ "RI_EmberKey", "emberkey" },
		{ "RI_FrostKey", "frostkey" },
		{ "RI_HeirloomMist", "heir1" },
		{ "RI_HeirloomEmber", "heir2" },
		{ "RI_HeirloomFrost", "heir3" }
	};

	public static readonly Dictionary<string, string> SiteItems = new Dictionary<string, string>
	{
		{ "mine", "item:RI_EmberKey;item:RI_HeirloomMist" },
		{ "fortress", "item:RI_FrostKey;item:RI_HeirloomEmber" },
		{ "frosthall", "item:RI_HeirloomFrost" }
	};

	private static readonly List<ZDO> s_tmp = new List<ZDO>();

	private static readonly Dictionary<string, float> s_seenAt = new Dictionary<string, float>();

	private static float s_nextCheck;

	private static FieldInfo s_generatedField;

	public static void Fill(Inventory inv, string spec, Vector3 pos)
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		string[] array = spec.Split(';');
		foreach (string text in array)
		{
			if (text == "hoard")
			{
				Hoard(inv, pos);
			}
			else if (text.StartsWith("item:"))
			{
				Add(inv, text.Substring(5), 1);
			}
		}
	}

	private static void Add(Inventory inv, string name, int amount)
	{
		GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab(name) : null);
		if ((Object)(object)val == (Object)null || amount <= 0 || inv.AddItem(val, amount))
		{
			return;
		}
		List<ItemData> allItems = inv.GetAllItems();
		for (int num = allItems.Count - 1; num >= 0; num--)
		{
			GameObject dropPrefab = allItems[num].m_dropPrefab;
			if (!((Object)(object)dropPrefab != (Object)null) || !((Object)dropPrefab).name.StartsWith("RI_"))
			{
				inv.RemoveItem(allItems[num]);
				break;
			}
		}
		inv.AddItem(val, amount);
	}

	public static bool FillZdo(ZDO zdo, string spec, Vector3 pos, bool markDone = true)
	{
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Expected O, but got Unknown
		//IL_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: Expected O, but got Unknown
		//IL_010a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0110: Unknown result type (might be due to invalid IL or missing references)
		//IL_0117: Expected O, but got Unknown
		try
		{
			GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab(zdo.GetPrefab()) : null);
			Container val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<Container>() : null);
			if ((Object)(object)val2 == (Object)null || (Object)(object)ObjectDB.instance == (Object)null)
			{
				return false;
			}
			if (zdo.HasOwner() && !zdo.IsOwner())
			{
				zdo.SetOwner(ZDOMan.GetSessionID());
			}
			Inventory val3 = new Inventory(val2.m_name, val2.m_bkg, val2.m_width, val2.m_height);
			byte[] byteArray = zdo.GetByteArray(ZDOVars.s_items, (byte[])null);
			if (byteArray != null)
			{
				val3.Load(new ZPackage(byteArray));
			}
			if (!zdo.GetBool(ZDOVars.s_addedDefaultItems, false))
			{
				if (val2.m_defaultItems != null)
				{
					foreach (ItemData dropListItem in val2.m_defaultItems.GetDropListItems())
					{
						val3.AddItem(dropListItem);
					}
				}
				zdo.Set(ZDOVars.s_addedDefaultItems, true);
			}
			Fill(val3, spec, pos);
			ZPackage val4 = new ZPackage();
			val3.Save(val4);
			zdo.Set(ZDOVars.s_items, val4.GetArray());
			if (markDone)
			{
				zdo.Set("anwo_ri_lootdone", true);
			}
			return true;
		}
		catch (Exception ex)
		{
			RavenIslePlugin.Log.LogWarning((object)("Raven Isle: filling a chest failed: " + ex.Message));
			return false;
		}
	}

	private static void VerifyHidden()
	{
		//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d2: Expected O, but got Unknown
		//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f7: Expected O, but got Unknown
		//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
		for (int num = s_checks.Count - 1; num >= 0; num--)
		{
			Check check = s_checks[num];
			if (!(Time.time < check.Next))
			{
				check.Next = Time.time + 10f;
				if (Time.time > check.Until || check.Zdo == null || !check.Zdo.IsValid())
				{
					s_checks.RemoveAt(num);
				}
				else
				{
					GameObject prefab = ZNetScene.instance.GetPrefab(check.Zdo.GetPrefab());
					Container val = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<Container>() : null);
					if ((Object)(object)val == (Object)null)
					{
						s_checks.RemoveAt(num);
					}
					else
					{
						Inventory val2 = new Inventory(val.m_name, val.m_bkg, val.m_width, val.m_height);
						byte[] byteArray = check.Zdo.GetByteArray(ZDOVars.s_items, (byte[])null);
						if (byteArray != null)
						{
							val2.Load(new ZPackage(byteArray));
						}
						string text = "";
						string[] array = check.Spec.Split(';');
						foreach (string text2 in array)
						{
							if (!text2.StartsWith("item:"))
							{
								continue;
							}
							string text3 = text2.Substring(5);
							if (!FoundKey.TryGetValue(text3, out var value) || !IsleState.Has(value))
							{
								GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(text3);
								if (!((Object)(object)itemPrefab == (Object)null) && !val2.HaveItem(itemPrefab.GetComponent<ItemDrop>().m_itemData.m_shared.m_name, false))
								{
									text = text + ((text.Length > 0) ? ";" : "") + text2;
								}
							}
						}
						if (text.Length != 0)
						{
							RavenIslePlugin.Log.LogWarning((object)("Raven Isle: quest items went missing from their chest, putting them back: " + text));
							FillZdo(check.Zdo, text, check.Zdo.GetPosition());
						}
					}
				}
			}
		}
	}

	private static void Hoard(Inventory inv, Vector3 pos)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		IsleRegion isleRegion = Realm.RegionAt(pos);
		Add(inv, "Coins", Random.Range(120, 260));
		string[] array = isleRegion switch
		{
			IsleRegion.Mistwood => new string[6] { "BlackCore", "Softtissue", "Sap", "JuteBlue", "MeadHealthMajor", "MeadEitrMinor" }, 
			IsleRegion.Ashfields => new string[6] { "FlametalNew", "CharcoalResin", "ProustitePowder", "MeadHealthMajor", "GemstoneRed", "MoltenCore" }, 
			IsleRegion.Frostpeak => new string[6] { "AncientCoin", "AncientGemstoneBlack", "MeadHealthMajor", "MeadStaminaLingering", "Silver", "FreezeGland" }, 
			IsleRegion.Summit => new string[5] { "GemstoneBlue", "GemstoneGreen", "GemstoneRed", "MeadHealthMajor", "MeadEitrLingering" }, 
			_ => new string[5] { "AmberPearl", "Ruby", "SilverNecklace", "MeadHealthMedium", "MeadStaminaMedium" }, 
		};
		for (int i = 0; i < 3; i++)
		{
			string name = array[Random.Range(0, array.Length)];
			Add(inv, name, Random.Range(2, 6));
		}
	}

	public static void ResetSession()
	{
		s_seenAt.Clear();
		s_nextCheck = 0f;
		s_checks.Clear();
	}

	public static void Process()
	{
		//IL_00da: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_012d: Unknown result type (might be due to invalid IL or missing references)
		if (!Realm.Enabled || Time.time < s_nextCheck || (Object)(object)ZoneSystem.instance == (Object)null || ZDOMan.instance == null)
		{
			return;
		}
		s_nextCheck = Time.time + 2f;
		VerifyHidden();
		if (s_generatedField == null)
		{
			s_generatedField = AccessTools.Field(typeof(ZoneSystem), "m_generatedZones");
		}
		if (!(s_generatedField?.GetValue(ZoneSystem.instance) is HashSet<Vector2s> hashSet))
		{
			return;
		}
		foreach (KeyValuePair<string, string> siteItem in SiteItems)
		{
			if (IsleState.Has("hid_" + siteItem.Key))
			{
				continue;
			}
			IsleSite isleSite = IsleLayout.Get(siteItem.Key);
			if (isleSite == null)
			{
				continue;
			}
			Vector2s zone = ZoneSystem.GetZone(Realm.ToWorld(isleSite.X, isleSite.Z, 0f));
			if (!hashSet.Contains(zone))
			{
				continue;
			}
			if (!s_seenAt.TryGetValue(siteItem.Key, out var value))
			{
				s_seenAt[siteItem.Key] = Time.time;
			}
			else if (!(Time.time - value < 4f))
			{
				try
				{
					HideQuestItems(zone);
				}
				catch (Exception ex)
				{
					RavenIslePlugin.Log.LogError((object)("Hiding quest items failed: " + ex));
				}
			}
		}
	}

	private static int ChestScore(GameObject prefab)
	{
		string name = ((Object)prefab).name;
		if (name.StartsWith("TreasureChest") || name.IndexOf("Chest", StringComparison.OrdinalIgnoreCase) >= 0)
		{
			return 1;
		}
		return 0;
	}

	public static void HideQuestItems(Vector2s zone)
	{
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: 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_02e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0112: Unknown result type (might be due to invalid IL or missing references)
		//IL_0117: Unknown result type (might be due to invalid IL or missing references)
		//IL_0119: Unknown result type (might be due to invalid IL or missing references)
		//IL_011b: Unknown result type (might be due to invalid IL or missing references)
		//IL_012c: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_023e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0243: Unknown result type (might be due to invalid IL or missing references)
		//IL_024a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0274: Unknown result type (might be due to invalid IL or missing references)
		foreach (KeyValuePair<string, string> siteItem in SiteItems)
		{
			IsleSite isleSite = IsleLayout.Get(siteItem.Key);
			if (isleSite == null)
			{
				continue;
			}
			Vector3 val = Realm.ToWorld(isleSite.X, isleSite.Z, 0f);
			if (ZoneSystem.GetZone(val) != zone || IsleState.Has("hid_" + siteItem.Key))
			{
				continue;
			}
			s_tmp.Clear();
			ZDOMan.instance.FindSectorObjects(zone, new SimulationDistance(1, 0, true), s_tmp, (List<ZDO>)null);
			ZDO val2 = null;
			float num = float.MinValue;
			foreach (ZDO item in s_tmp)
			{
				GameObject prefab = ZNetScene.instance.GetPrefab(item.GetPrefab());
				if ((Object)(object)prefab == (Object)null || (Object)(object)prefab.GetComponent<Container>() == (Object)null || item.GetLong(ZDOVars.s_creator, 0L) != 0L || item.GetString("anwo_ri_hoard", "").Length > 0)
				{
					continue;
				}
				Vector3 position = item.GetPosition();
				float num2 = Realm.Distance2D(position, val);
				if (!(num2 > 90f))
				{
					float num3 = ((position.y > 3000f) ? 10000f : 0f) + (float)ChestScore(prefab) * 1000f + num2;
					if (num3 > num)
					{
						val2 = item;
						num = num3;
					}
				}
			}
			if (val2 == null)
			{
				string text = ((siteItem.Key == "fortress") ? "TreasureChest_charredfortress" : ((siteItem.Key == "mine") ? "TreasureChest_dvergrtown" : "TreasureChest_deepnorth_village"));
				GameObject val3 = ZNetScene.instance.GetPrefab(text) ?? ZNetScene.instance.GetPrefab("piece_chest_wood");
				if ((Object)(object)val3 == (Object)null)
				{
					continue;
				}
				Vector3 val4 = Realm.ToWorld(isleSite.X + isleSite.Flat * 0.5, isleSite.Z, IsleTerrain.Sample(isleSite.X + isleSite.Flat * 0.5, isleSite.Z).Height + 0.1f);
				val2 = ZDOMan.instance.CreateNewZDO(val4, StringExtensionMethods.GetStableHashCode(((Object)val3).name));
				ZNetView component = val3.GetComponent<ZNetView>();
				val2.Persistent = true;
				val2.Type = component.m_type;
				val2.Distant = component.m_distant;
				val2.SetPrefab(StringExtensionMethods.GetStableHashCode(((Object)val3).name));
				val2.Set("anwo_ri_prot", true);
				RavenIslePlugin.Log.LogWarning((object)("No chest found at " + isleSite.Label + "; placed one for the quest items"));
			}
			val2.Set("anwo_ri_prot", true);
			if (FillZdo(val2, siteItem.Value, val2.GetPosition(), markDone: false))
			{
				s_checks.Add(new Check
				{
					Zdo = val2,
					Spec = siteItem.Value,
					Until = Time.time + 60f,
					Next = Time.time + 5f
				});
			}
			else
			{
				string text2 = val2.GetString("anwo_ri_loot", "");
				val2.Set("anwo_ri_loot", (text2.Length > 0) ? (text2 + ";" + siteItem.Value) : siteItem.Value);
			}
			IsleState.Set("hid_" + siteItem.Key);
			ManualLogSource log = RavenIslePlugin.Log;
			string[] obj = new string[7] { "Raven Isle: ", siteItem.Value, " hidden in ", null, null, null, null };
			GameObject prefab2 = ZNetScene.instance.GetPrefab(val2.GetPrefab());
			obj[3] = ((prefab2 != null) ? ((Object)prefab2).name : null);
			obj[4] = " at ";
			obj[5] = isleSite.Label;
			obj[6] = ((val2.GetPosition().y > 3000f) ? " (inside)" : "");
			log.LogInfo((object)string.Concat(obj));
		}
	}
}
public static class IsleItems
{
	public const string RavenStone = "RI_RavenStone";

	public const string EmberKey = "RI_EmberKey";

	public const string FrostKey = "RI_FrostKey";

	public const string HeirMist = "RI_HeirloomMist";

	public const string HeirEmber = "RI_HeirloomEmber";

	public const string HeirFrost = "RI_HeirloomFrost";

	public const string WardenSkull = "RI_TrophyWarden";

	public const string Cloak = "RI_RavenCloak";

	public static readonly string[] Heirlooms = new string[3] { "RI_HeirloomMist", "RI_HeirloomEmber", "RI_HeirloomFrost" };

	private const string StoneRolled = "anwo_ri_stoneroll";

	public static void Register()
	{
		Add("RI_RavenStone", new string[3] { "AncientGemstoneBlack", "Obsidian", "Flint" }, "Raven stone", "A cold black stone with a raven cut into it, humming when you hold it near the sea. Build a Raven portal with it (Hammer, Misc).\n\n<color=orange>Warning: the portal leads to Raven Isle, beyond the edge of the world: a hard, late-game place, and the trip may be one way until the isle's Warden falls. Go with your best gear.</color>", 0.3f, 5);
		Add("RI_EmberKey", new string[3] { "HildirKey_plainsfortress", "HildirKey_forestcrypt", "CryptKey" }, "Ember key", "Warm to the touch. Opens the Ember gate on Raven Isle, between the Landing and the Ashfields.", 0.2f, 1);
		Add("RI_FrostKey", new string[3] { "HildirKey_mountaincave", "HildirKey_forestcrypt", "CryptKey" }, "Frost key", "Rimed with frost that never melts. Opens the Frost gate on Raven Isle, between the Ashfields and Frostpeak.", 0.2f, 1);
		Add("RI_HeirloomMist", new string[3] { "AncientGemstoneGreen", "GemstoneGreen", "Ruby" }, "Hrafn's Eye", "The first of Jarl Hrafn's three heirlooms, taken by the dvergr into the dark under Mistwood. Lay it on the summit altar.", 0.5f, 1);
		Add("RI_HeirloomEmber", new string[3] { "AncientGemstoneOrange", "GemstoneRed", "Ruby" }, "Hrafn's Heart", "The second of Jarl Hrafn's three heirlooms, still warm from the Ashfields. Lay it on the summit altar.", 0.5f, 1);
		Add("RI_HeirloomFrost", new string[3] { "DragonTear", "GemstoneBlue", "Ruby" }, "Hrafn's Tear", "The last of Jarl Hrafn's three heirlooms, frozen in Frostpeak. Lay it on the summit altar.", 0.5f, 1);
		Add("RI_TrophyWarden", new string[2] { "TrophyDraugrElite", "TrophyDraugr" }, "Warden's skull", "The skull of the Barrow Warden of Raven Isle. Proof that the isle is free.", 2f, 20);
		AddCloak();
	}

	private static void Add(string name, string[] bases, string display, string description, float weight, int stack)
	{
		//IL_0051: 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_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: Expected O, but got Unknown
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Expected O, but got Unknown
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		string text = null;
		foreach (string text2 in bases)
		{
			if ((Object)(object)PrefabManager.Instance.GetPrefab(text2) != (Object)null)
			{
				text = text2;
				break;
			}
		}
		if (text == null)
		{
			RavenIslePlugin.Log.LogError((object)("No base item found for " + name));
			return;
		}
		ItemConfig val = new ItemConfig
		{
			Name = display,
			Description = description,
			Weight = weight,
			StackSize = stack
		};
		CustomItem val2 = new CustomItem(name, text, val);
		SharedData shared = val2.ItemDrop.m_itemData.m_shared;
		shared.m_value = 0;
		shared.m_teleportable = true;
		if (name == "RI_TrophyWarden")
		{
			shared.m_itemType = (ItemType)13;
		}
		ItemManager.Instance.AddItem(val2);
	}

	private static void AddCloak()
	{
		//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_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Expected O, but got Unknown
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Expected O, but got Unknown
		//IL_00a2: 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_00b4: 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_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0121: Unknown result type (might be due to invalid IL or missing references)
		//IL_0128: Expected O, but got Unknown
		//IL_0149: Unknown result type (might be due to invalid IL or missing references)
		//IL_0153: Unknown result type (might be due to invalid IL or missing references)
		string text = (((Object)(object)PrefabManager.Instance.GetPrefab("CapeFeather") != (Object)null) ? "CapeFeather" : "CapeLinen");
		ItemConfig val = new ItemConfig
		{
			Name = "Raven cloak",
			Description = "Woven by Munin from his brothers' feathers and given to those who freed Raven Isle. Fall like a feather, move a little faster, and heat and cold bite less. It never wears out."
		};
		CustomItem val2 = new CustomItem("RI_RavenCloak", text, val);
		SharedData shared = val2.ItemDrop.m_itemData.m_shared;
		shared.m_armor = 12f;
		shared.m_armorPerLevel = 0f;
		shared.m_maxQuality = 1;
		shared.m_useDurability = false;
		shared.m_movementModifier = 0.05f;
		shared.m_value = 0;
		shared.m_teleportable = true;
		shared.m_damageModifiers = new List<DamageModPair>
		{
			new DamageModPair
			{
				m_type = (DamageType)32,
				m_modifier = (DamageModifier)1
			},
			new DamageModPair
			{
				m_type = (DamageType)64,
				m_modifier = (DamageModifier)1
			}
		};
		Renderer[] componentsInChildren = val2.ItemPrefab.GetComponentsInChildren<Renderer>(true);
		foreach (Renderer val3 in componentsInChildren)
		{
			Material[] sharedMaterials = val3.sharedMaterials;
			for (int j = 0; j < sharedMaterials.Length; j++)
			{
				if (!((Object)(object)sharedMaterials[j] == (Object)null))
				{
					Material val4 = new Material(sharedMaterials[j]);
					if (val4.HasProperty("_Color"))
					{
						val4.color = new Color(0.16f, 0.16f, 0.2f, val4.color.a);
					}
					sharedMaterials[j] = val4;
				}
			}
			val3.sharedMaterials = sharedMaterials;
		}
		ItemManager.Instance.AddItem(val2);
	}

	public static GameObject Prefab(string name)
	{
		if (!((Object)(object)ObjectDB.instance != (Object)null))
		{
			return null;
		}
		return ObjectDB.instance.GetItemPrefab(name);
	}

	public static bool Has(Player p, string name)
	{
		GameObject val = Prefab(name);
		if ((Object)(object)p == (Object)null || (Object)(object)val == (Object)null)
		{
			return false;
		}
		return ((Humanoid)p).GetInventory().HaveItem(val.GetComponent<ItemDrop>().m_itemData.m_shared.m_name, false);
	}

	public static void Remove(Player p, string name, int amount = 1)
	{
		GameObject val = Prefab(name);
		if (!((Object)(object)p == (Object)null) && !((Object)(object)val == (Object)null))
		{
			((Humanoid)p).GetInventory().RemoveItem(val.GetComponent<ItemDrop>().m_itemData.m_shared.m_name, amount, -1, false);
		}
	}

	public static bool Give(Player p, string name, int amount)
	{
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = Prefab(name);
		if ((Object)(object)p == (Object)null || (Object)(object)val == (Object)null || amount <= 0)
		{
			return false;
		}
		Inventory inventory = ((Humanoid)p).GetInventory();
		SharedData shared = val.GetComponent<ItemDrop>().m_itemData.m_shared;
		if (!inventory.AddItem(val, amount))
		{
			ItemDrop component = Object.Instantiate<GameObject>(val, ((Component)p).transform.position + ((Component)p).transform.forward + Vector3.up, Quaternion.identity).GetComponent<ItemDrop>();
			if ((Object)(object)component != (Object)null)
			{
				component.SetStack(amount);
			}
			((Character)p).Message((MessageType)1, "Your inventory is full: " + shared.m_name + " dropped at your feet", 0, (Sprite)null, false);
		}
		else
		{
			((Character)p).Message((MessageType)1, "$msg_added " + shared.m_name, amount, (shared.m_icons != null && shared.m_icons.Length != 0) ? shared.m_icons[0] : null, false);
		}
		return true;
	}

	[HarmonyPatch(typeof(Container), "CheckForChanges")]
	[HarmonyPostfix]
	private static void EarlyChests(Container __instance, ZNetView ___m_nview, Inventory ___m_inventory, bool ___m_inUse, uint ___m_lastRevision)
	{
		try
		{
			if (!RavenIslePlugin.StoneInChests.Value || !RavenIslePlugin.IslandOn.Value || (Object)(object)___m_nview == (Object)null || ___m_inventory == null || !___m_nview.IsValid() || !___m_nview.IsOwner() || ___m_inUse)
			{
				return;
			}
			ZDO zDO = ___m_nview.GetZDO();
			if (!RavenIslePlugin.EarlyChestHashes.Contains(zDO.GetPrefab()) || zDO.GetBool("anwo_ri_stoneroll", false) || ___m_lastRevision != zDO.DataRevision || !zDO.GetBool(ZDOVars.s_addedDefaultItems, false))
			{
				return;
			}
			zDO.Set("anwo_ri_stoneroll", true);
			if (!(Random.value >= RavenIslePlugin.StoneChance.Value))
			{
				GameObject val = Prefab("RI_RavenStone");
				if ((Object)(object)val != (Object)null && ___m_inventory.AddItem(val, 1))
				{
					RavenIslePlugin.Log.LogInfo((object)("A Raven stone turned up in " + Utils.GetPrefabName(((Component)__instance).gameObject)));
				}
			}
		}
		catch (Exception ex)
		{
			RavenIslePlugin.Log.LogDebug((object)("Raven stone roll failed: " + ex.Message));
		}
	}
}
public enum SiteKind
{
	Plaza,
	Camp,
	Beacon,
	Location,
	Gate,
	Altar,
	Hoard,
	Lore
}
public class IsleSite
{
	public string Id;

	public SiteKind Kind;

	public IsleRegion Region;

	public double X;

	public double Z;

	public double Flat;

	public double Fall = 12.0;

	public double Rot;

	public string Prefab = "";

	public string Label = "";

	public double TargetY = double.NaN;

	public IsleSite(string id, SiteKind kind, IsleRegion region, double x, double z, double flat, string prefab, string label, double rot = 0.0)
	{
		Id = id;
		Kind = kind;
		Region = region;
		X = x;
		Z = z;
		Flat = flat;
		Prefab = prefab;
		Label = label;
		Rot = rot;
	}
}
public static class IsleLayout
{
	public class WardSpot
	{
		public int Ridge;

		public double X;

		public double Z;

		public double TargetY;

		public const double Flat = 2.0;

		public const double Fall = 1.8;
	}

	public class HoardSpot
	{
		public string Id;

		public double X;

		public double Z;

		public float Yaw;

		public string[] Chests;

		public double Flat = 2.4;

		public double Fall = 2.2;

		public double TargetY = double.NaN;
	}

	public static readonly List<IsleSite> Sites = new List<IsleSite>
	{
		new IsleSite("plaza", SiteKind.Plaza, IsleRegion.Landing, 0.0, -440.0, 15.0, "", "Raven Stones"),
		new IsleSite("camp", SiteKind.Camp, IsleRegion.Landing, 30.0, -414.0, 11.0, "", "Keeper's Camp", 200.0),
		new IsleSite("beacon_east", SiteKind.Beacon, IsleRegion.Landing, 168.0, -360.0, 6.0, "", "East Beacon"),
		new IsleSite("beacon_west", SiteKind.Beacon, IsleRegion.Landing, -175.0, -350.0, 6.0, "", "West Beacon"),
		new IsleSite("beacon_mist", SiteKind.Beacon, IsleRegion.Mistwood, -468.0, 10.0, 6.0, "", "Mist Beacon"),
		new IsleSite("lore_landing", SiteKind.Lore, IsleRegion.Landing, -22.0, -410.0, 0.0, "", "Weathered stone"),
		new IsleSite("mine", SiteKind.Location, IsleRegion.Mistwood, -330.0, 80.0, 26.0, "Mistlands_DvergrTownEntrance1", "Infested Mine"),
		new IsleSite("mist_tower", SiteKind.Location, IsleRegion.Mistwood, -262.0, -160.0, 22.0, "Mistlands_GuardTower1_ruined_new", "Fallen Watchtower"),
		new IsleSite("mist_statues", SiteKind.Location, IsleRegion.Mistwood, -405.0, -105.0, 17.0, "Mistlands_StatueGroup1", "Silent Statues"),
		new IsleSite("mist_dig", SiteKind.Location, IsleRegion.Mistwood, -300.0, 205.0, 22.0, "Mistlands_Excavation1", "Old Dig"),
		new IsleSite("fortress", SiteKind.Location, IsleRegion.Ashfields, 335.0, -20.0, 34.0, "CharredFortress", "Charred Fortress"),
		new IsleSite("ash_ruins", SiteKind.Location, IsleRegion.Ashfields, 300.0, -155.0, 33.0, "CharredRuins1", "Burnt Hall"),
		new IsleSite("ash_tower", SiteKind.Location, IsleRegion.Ashfields, 425.0, 125.0, 23.0, "CharredTowerRuins1", "Ember Tower"),
		new IsleSite("ash_morgen", SiteKind.Location, IsleRegion.Ashfields, 232.0, 150.0, 25.0, "MorgenHole1", "Sleeper's Pit"),
		new IsleSite("ash_arch", SiteKind.Location, IsleRegion.Ashfields, 205.0, 45.0, 18.0, "SulfurArch", "Sulfur Arch"),
		new IsleSite("frosthall", SiteKind.Location, IsleRegion.Frostpeak, 0.0, 385.0, 30.0, "MorkBorg", "Frozen Hall"),
		new IsleSite("frost_hut", SiteKind.Location, IsleRegion.Frostpeak, 135.0, 300.0, 13.0, "DN_hut01", "Trapper's Hut"),
		new IsleSite("frost_camp", SiteKind.Location, IsleRegion.Frostpeak, -150.0, 330.0, 33.0, "LumberCamp", "Frozen Lumber Camp"),
		new IsleSite("frost_memorial", SiteKind.Location, IsleRegion.Frostpeak, -78.0, 245.0, 23.0, "NorthMemorialPlace", "Memorial Stones"),
		new IsleSite("altar", SiteKind.Altar, IsleRegion.Summit, 0.0, 0.0, 0.0, "", "Warden's Barrow")
	};

	public static readonly List<WardSpot> WardSpots = new List<WardSpot>();

	public static readonly HoardSpot[] Hoards = new HoardSpot[6]
	{
		new HoardSpot
		{
			Id = "landing",
			X = 172.0,
			Z = -455.0,
			Yaw = 30f,
			Chests = new string[2] { "TreasureChest_meadows_buried", "TreasureChest_meadows" }
		},
		new HoardSpot
		{
			Id = "mistspire",
			X = -221.5,
			Z = 125.5,
			Yaw = 200f,
			Chests = new string[3] { "TreasureChest_dvergrtown", "TreasureChest_dvergrtower", "TreasureChest_mountaincave" }
		},
		new HoardSpot
		{
			Id = "mistbay",
			X = -475.5,
			Z = -77.0,
			Yaw = 90f,
			Chests = new string[2] { "TreasureChest_dvergr_loose_stone", "TreasureChest_dvergrtown" }
		},
		new HoardSpot
		{
			Id = "ashcrater",
			X = 431.0,
			Z = -48.0,
			Yaw = 180f,
			Chests = new string[2] { "TreasureChest_ashland_stone", "TreasureChest_charredfortress" }
		},
		new HoardSpot
		{
			Id = "frostcliff",
			X = 30.0,
			Z = 545.0,
			Yaw = 0f,
			Chests = new string[3] { "TreasureChest_morkhalla", "TreasureChest_deepnorth_village", "TreasureChest_mountains" }
		},
		new HoardSpot
		{
			Id = "summit",
			X = -45.0,
			Z = -9.0,
			Yaw = 79f,
			Chests = new string[2] { "TreasureChest_mountains", "TreasureChest_mountaincave" }
		}
	};

	private static bool s_ready;

	private static readonly object s_lock = new object();

	public static IsleSite Get(string id)
	{
		foreach (IsleSite site in Sites)
		{
			if (site.Id == id)
			{
				return site;
			}
		}
		return null;
	}

	public static void EnsureTargets()
	{
		if (s_ready)
		{
			return;
		}
		lock (s_lock)
		{
			if (s_ready)
			{
				return;
			}
			if (Get("ember_gate") == null)
			{
				IsleTerrain.GatePos(ember: true, out var x, out var z, out var facing);
				IsleTerrain.GatePos(ember: false, out var x2, out var z2, out var facing2);
				Sites.Add(new IsleSite("ember_gate", SiteKind.Gate, IsleRegion.Landing, x, z, 8.0, "", "Ember Gate", facing)
				{
					Fall = 6.0
				});
				Sites.Add(new IsleSite("frost_gate", SiteKind.Gate, IsleRegion.Ashfields, x2, z2, 8.0, "", "Frost Gate", facing2)
				{
					Fall = 6.0
				});
			}
			foreach (IsleSite site in Sites)
			{
				if (!(site.Flat <= 0.0))
				{
					double num = 0.0;
					int num2 = 0;
					for (int i = 0; i < 9; i++)
					{
						double num3 = (double)i * Math.PI * 2.0 / 8.0;
						double num4 = ((i == 0) ? 0.0 : (site.Flat * 0.6));
						num += (double)IsleTerrain.Sample(site.X + Math.Sin(num3) * num4, site.Z + Math.Cos(num3) * num4, withSites: false).Height;
						num2++;
					}
					site.TargetY = Math.Max(32.5, num / (double)num2);
				}
			}
			double[] data = IsleWardSpots.Data;
			for (int j = 0; j + 2 < data.Length; j += 3)
			{
				WardSpot wardSpot = new WardSpot
				{
					Ridge = (int)data[j],
					X = data[j + 1],
					Z = data[j + 2]
				};
				double num5 = 0.0;
				int num6 = 0;
				for (int k = 0; k < 9; k++)
				{
					double num7 = (double)k * Math.PI * 2.0 / 8.0;
					double num8 = ((k == 0) ? 0.0 : 1.2);
					num5 += (double)IsleTerrain.Sample(wardSpot.X + Math.Sin(num7) * num8, wardSpot.Z + Math.Cos(num7) * num8, withSites: false).Height;
					num6++;
				}
				wardSpot.TargetY = num5 / (double)num6;
				WardSpots.Add(wardSpot);
			}
			HoardSpot[] hoards = Hoards;
			foreach (HoardSpot hoardSpot in hoards)
			{
				double num9 = 0.0;
				int num10 = 0;
				for (int m = 0; m < 9; m++)
				{
					double num11 = (double)m * Math.PI * 2.0 / 8.0;
					double num12 = ((m == 0) ? 0.0 : (hoardSpot.Flat * 0.6));
					num9 += (double)IsleTerrain.Sample(hoardSpot.X + Math.Sin(num11) * num12, hoardSpot.Z + Math.Cos(num11) * num12, withSites: false).Height;
					num10++;
				}
				hoardSpot.TargetY = Math.Max(31.5, num9 / (double)num10);
			}
			s_ready = true;
		}
	}

	public static double ApplyFlatten(double x, double z, double h)
	{
		EnsureTargets();
		foreach (IsleSite site in Sites)
		{
			if (site.Flat <= 0.0)
			{
				continue;
			}
			double num = x - site.X;
			double num2 = z - site.Z;
			double num3 = site.Flat + site.Fall;
			if (!(Math.Abs(num) > num3) && !(Math.Abs(num2) > num3))
			{
				double num4 = Math.Sqrt(num * num + num2 * num2);
				if (!(num4 > num3))
				{
					double t = IsleNoise.SmoothRange(num3, site.Flat, num4);
					h = IsleNoise.Lerp(h, site.TargetY, t);
				}
			}
		}
		foreach (WardSpot wardSpot in WardSpots)
		{
			double num5 = x - wardSpot.X;
			double num6 = z - wardSpot.Z;
			double num7 = 3.8;
			if (!(Math.Abs(num5) > num7) && !(Math.Abs(num6) > num7))
			{
				double num8 = Math.Sqrt(num5 * num5 + num6 * num6);
				if (!(num8 > num7))
				{
					h = IsleNoise.Lerp(h, wardSpot.TargetY, IsleNoise.SmoothRange(num7, 2.0, num8));
				}
			}
		}
		HoardSpot[] hoards = Hoards;
		foreach (HoardSpot hoardSpot in hoards)
		{
			double num9 = x - hoardSpot.X;
			double num10 = z - hoardSpot.Z;
			double num11 = hoardSpot.Flat + hoardSpot.Fall;
			if (!(Math.Abs(num9) > num11) && !(Math.Abs(num10) > num11))
			{
				double num12 = Math.Sqrt(num9 * num9 + num10 * num10);
				if (!(num12 > num11))
				{
					h = IsleNoise.Lerp(h, hoardSpot.TargetY, IsleNoise.SmoothRange(num11, hoardSpot.Flat, num12));
				}
			}
		}
		return h;
	}

	public static double LavaAllowed(double x, double z)
	{
		double val = 1.0;
		foreach (IsleSite site in Sites)
		{
			if (site.Region == IsleRegion.Ashfields)
			{
				double num = x - site.X;
				double num2 = z - site.Z;
				double v = Math.Sqrt(num * num + num2 * num2);
				val = Math.Min(val, IsleNoise.SmoothRange(site.Flat + 10.0, site.Flat + 25.0, v));
			}
		}
		foreach (WardSpot wardSpot in WardSpots)
		{
			double num3 = x - wardSpot.X;
			double num4 = z - wardSpot.Z;
			if (!(Math.Abs(num3) > 9.0) && !(Math.Abs(num4) > 9.0))
			{
				val = Math.Min(val, IsleNoise.SmoothRange(4.8, 8.8, Math.Sqrt(num3 * num3 + num4 * num4)));
			}
		}
		HoardSpot[] hoards = Hoards;
		foreach (HoardSpot hoardSpot in hoards)
		{
			double num5 = x - hoardSpot.X;
			double num6 = z - hoardSpot.Z;
			if (!(Math.Abs(num5) > 10.0) && !(Math.Abs(num6) > 10.0))
			{
				val = Math.Min(val, IsleNoise.SmoothRange(hoardSpot.Flat + hoardSpot.Fall + 1.0, hoardSpot.Flat + hoardSpot.Fall + 5.0, Math.Sqrt(num5 * num5 + num6 * num6)));
			}
		}
		IsleTerrain.GatePos(ember: true, out var x2, out var z2, out var facing);
		IsleTerrain.GatePos(ember: false, out var x3, out var z3, out facing);
		IsleSite isleSite = Get("fortress");
		val = Math.Min(val, IsleNoise.SmoothRange(8.0, 18.0, DistToSegment(x, z, x2, z2, isleSite.X, isleSite.Z)));
		return Math.Min(val, IsleNoise.SmoothRange(8.0, 18.0, DistToSegment(x, z, isleSite.X, isleSite.Z, x3, z3)));
	}

	public static double DistToSegment(double px, double pz, double ax, double az, double bx, double bz)
	{
		double num = bx - ax;
		double num2 = bz - az;
		double num3 = IsleNoise.Clamp01(((px - ax) * num + (pz - az) * num2) / (num * num + num2 * num2 + 1E-09));
		double num4 = ax + num * num3 - px;
		double num5 = az + num2 * num3 - pz;
		return Math.Sqrt(num4 * num4 + num5 * num5);
	}
}
public static class IsleMap
{
	public static class Pins
	{
		private static readonly Dictionary<string, PinData> s_pins = new Dictionary<string, PinData>();

		private static Minimap s_for;

		private static float s_timer;

		public static void Tick(Player p)
		{
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: 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_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			s_timer -= Time.deltaTime;
			if (s_timer > 0f)
			{
				return;
			}
			s_timer = 1f;
			Minimap instance = Minimap.instance;
			if ((Object)(object)s_for != (Object)(object)instance)
			{
				s_pins.Clear();
				s_for = instance;
			}
			bool flag = IsleState.BeaconsLit() >= 3;
			Quest quest = Quests.Current();
			HashSet<string> set = IsleState.GetSet(p, "found");
			bool flag2 = false;
			foreach (IsleSite site in IsleLayout.Sites)
			{
				if (string.IsNullOrEmpty(site.Label) || site.Kind == SiteKind.Lore)
				{
					continue;
				}
				if (!set.Contains(site.Id))
				{
					Vector3 b = Realm.ToWorld(site.X, site.Z, 0f);
					bool num = Realm.In(((Component)p).transform.position) && Realm.Distance2D(((Component)p).transform.position, b) < 70f;
					bool flag3 = (flag && site.Kind != SiteKind.Hoard) || (quest != null && quest.Pin == site.Id) || site.Kind == SiteKind.Plaza || site.Kind == SiteKind.Camp;
					if (!num && !flag3)
					{
						continue;
					}
					set.Add(site.Id);
					flag2 = true;
				}
				if (!s_pins.ContainsKey(site.Id))
				{
					s_pins[site.Id] = instance.AddPin(Realm.ToWorld(site.X, site.Z, 0f), PinFor(site), site.Label, false, false, 0L, default(PlatformUserID));
				}
			}
			if (flag2)
			{
				IsleState.Put(p, "found", string.Join(",", set));
			}
		}

		private static PinType PinFor(IsleSite s)
		{
			switch (s.Kind)
			{
			case SiteKind.Altar:
				return (PinType)9;
			case SiteKind.Plaza:
				return (PinType)6;
			case SiteKind.Camp:
			case SiteKind.Beacon:
				return (PinType)0;
			case SiteKind.Gate:
				return (PinType)2;
			default:
				return (PinType)3;
			}
		}
	}

	public const int Size = 1024;

	public const float Pixel = 2f;

	private static bool s_islandMode;

	private static bool s_ready;

	private static bool s_building;

	private static Color32[] s_biomePixels;

	private static Color32[] s_maskPixels;

	private static Color[] s_heightPixels;

	private static Texture2D s_map;

	private static Texture2D s_mask;

	private static Texture2D s_height;

	private static Texture2D s_fog;

	private static BitArray s_explored;

	private static BitArray s_exploredOthers;

	private static Color32[] s_colors = (Color32[])(object)new Color32[6];

	private static Texture2D w_map;

	private static Texture2D w_mask;

	private static Texture2D w_height;

	private static Texture2D w_fog;

	private static BitArray w_explored;

	private static BitArray w_exploredOthers;

	private static int w_size;

	private static float w_pixel;

	private static float s_saveTimer;

	private static Minimap s_owner;

	private static readonly FieldInfo F_mask = AccessTools.Field(typeof(Minimap), "m_forestMaskTexture");

	private static readonly FieldInfo F_height = AccessTools.Field(typeof(Minimap), "m_heightTexture");

	private static readonly FieldInfo F_fog = AccessTools.Field(typeof(Minimap), "m_fogTexture");

	private static readonly FieldInfo F_explored = AccessTools.Field(typeof(Minimap), "m_explored");

	private static readonly FieldInfo F_exploredOthers = AccessTools.Field(typeof(Minimap), "m_exploredOthers");

	private static readonly FieldInfo F_small = AccessTools.Field(typeof(Minimap), "m_mapSmallShader");

	private static readonly FieldInfo F_large = AccessTools.Field(typeof(Minimap), "m_mapLargeShader");

	private static readonly FieldInfo F_smallZoom = AccessTools.Field(typeof(Minimap), "m_smallZoom");

	private static readonly FieldInfo F_largeZoom = AccessTools.Field(typeof(Minimap), "m_largeZoom");

	private static readonly FieldInfo F_mistColor = AccessTools.Field(typeof(Minimap), "m_mistlandsColor");

	private static bool w_fogDirty;

	public static bool IslandMode => s_islandMode;

	public static void Tick(Player p, float dt)
	{
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		Minimap instance = Minimap.instance;
		if ((Object)(object)instance == (Object)null || (Object)(object)p == (Object)null)
		{
			return;
		}
		if ((Object)(object)s_owner != (Object)(object)instance)
		{
			ResetSession();
			s_owner = instance;
		}
		bool flag = RavenIslePlugin.IslandMap.Value && Realm.In(((Component)p).transform.position) && !((Character)p).InInterior();
		if (flag && !s_ready)
		{
			Build(instance);
			return;
		}
		if (flag != s_islandMode)
		{
			Switch(instance, flag, p);
		}
		if (s_islandMode)
		{
			s_saveTimer += dt;
			if (s_saveTimer > 30f)
			{
				s_saveTimer = 0f;
				SaveFog(p);
			}
		}
		if (Realm.Enabled)
		{
			Pins.Tick(p);
		}
	}

	public static void ResetSession()
	{
		s_islandMode = false;
		s_owne