Decompiled source of BuriedTreasures v1.1.6

BepInEx/plugins/BuriedTreasures/BuriedTreasures.dll

Decompiled 14 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Cryptography;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using BuriedTreasures.Api;
using BuriedTreasures.Bottle;
using BuriedTreasures.Burying;
using BuriedTreasures.Chest;
using BuriedTreasures.Digging;
using BuriedTreasures.Islands;
using BuriedTreasures.Items;
using BuriedTreasures.Memo;
using BuriedTreasures.Memo.Messages;
using BuriedTreasures.Memo.TreasureMap;
using BuriedTreasures.Models;
using BuriedTreasures.Save;
using FishNet;
using FishNet.Broadcast;
using FishNet.Connection;
using FishNet.Managing;
using FishNet.Managing.Client;
using FishNet.Managing.Object;
using FishNet.Managing.Server;
using FishNet.Object;
using FishNet.Serializing;
using FishNet.Transporting;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.Networking;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("BuriedTreasures")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.6.0")]
[assembly: AssemblyInformationalVersion("1.1.6+6706bcb4fcac56d60a25a3253a22a288dcc41096")]
[assembly: AssemblyProduct("BuriedTreasures")]
[assembly: AssemblyTitle("BuriedTreasures")]
[assembly: AssemblyVersion("1.1.6.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BuriedTreasures
{
	internal static class ConfigParse
	{
		public static Vector3 ReadVector3(string value, string label)
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			string[] array = (value ?? string.Empty).Split(',');
			if (array.Length == 3 && TryFloat(array[0], out var value2) && TryFloat(array[1], out var value3) && TryFloat(array[2], out var value4))
			{
				return new Vector3(value2, value3, value4);
			}
			Warn(label, value, "x, y, z", "0, 0, 0");
			return Vector3.zero;
		}

		public static Vector2 ReadCell(string value, string label, Vector2 fallback)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			if (string.IsNullOrWhiteSpace(value))
			{
				return fallback;
			}
			string[] array = value.Split(',');
			if (array.Length == 2 && TryInt(array[0], out var value2) && TryInt(array[1], out var value3))
			{
				return Palette.Uv(value2, value3);
			}
			Warn(label, value, "column, row", "the default colour");
			return fallback;
		}

		private static bool TryFloat(string s, out float value)
		{
			return float.TryParse(s.Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out value);
		}

		private static bool TryInt(string s, out int value)
		{
			return int.TryParse(s.Trim(), NumberStyles.Integer, CultureInfo.InvariantCulture, out value);
		}

		private static void Warn(string label, string value, string expected, string fallbackDescription)
		{
			Plugin.Log.LogWarning((object)(label + " = \"" + value + "\" isn't \"" + expected + "\"; using " + fallbackDescription + "."));
		}
	}
	internal readonly struct DevSetting<T>
	{
		private readonly T _fixedValue;

		public T Value => _fixedValue;

		public DevSetting(T fixedValue)
		{
			_fixedValue = fixedValue;
		}
	}
	internal static class EmbeddedResources
	{
		public static Stream Open(string name)
		{
			return Assembly.GetExecutingAssembly().GetManifestResourceStream(name);
		}

		public static byte[] ReadBytes(string name)
		{
			using Stream stream = Open(name);
			if (stream == null)
			{
				return null;
			}
			using MemoryStream memoryStream = new MemoryStream();
			stream.CopyTo(memoryStream);
			return memoryStream.ToArray();
		}
	}
	internal static class NetHandlerUtil
	{
		public static void Guarded(string tag, string what, Action handler)
		{
			try
			{
				handler();
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"{tag} Handling a {what} failed: {arg}");
			}
		}

		public static bool TrySwapOwner<T>(ref T owner, T current, out T previous) where T : class
		{
			previous = owner;
			if (current == owner)
			{
				return false;
			}
			owner = current;
			return true;
		}
	}
	internal sealed class NetworkInstaller : MonoBehaviour
	{
		private void Awake()
		{
			SettingsSync.EnsureSerializers();
			MemoNetwork.EnsureSerializers();
			BuryNetwork.EnsureSerializers();
		}

		private void Update()
		{
			MemoNetwork.PumpServerHandlers();
			BuryNetwork.PumpServerHandlers();
			SettingsSync.PumpClientHandlers();
			MemoNetwork.PumpClientHandlers();
			BuryNetwork.PumpClientHandlers();
		}
	}
	internal static class PlayerBody
	{
		public static Transform Of(Player player)
		{
			if ((Object)(object)player == (Object)null)
			{
				return null;
			}
			if (!((Object)(object)player.Transform != (Object)null))
			{
				return ((Component)player).transform;
			}
			return player.Transform;
		}

		public static Vector3 PositionOf(Player player)
		{
			//IL_0017: 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)
			Transform val = Of(player);
			if (!((Object)(object)val != (Object)null))
			{
				return Vector3.zero;
			}
			return val.position;
		}

		public static Vector3 FlatForward(Player player)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: 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)
			Transform val = Of(player);
			Transform val2 = (((Object)(object)player != (Object)null && (Object)(object)player.CamObject != (Object)null) ? player.CamObject : val);
			if ((Object)(object)val2 == (Object)null)
			{
				return Vector3.forward;
			}
			Vector3 forward = val2.forward;
			forward.y = 0f;
			if (((Vector3)(ref forward)).sqrMagnitude < 0.0001f)
			{
				forward = val.forward;
				forward.y = 0f;
			}
			if (!(((Vector3)(ref forward)).sqrMagnitude > 0.0001f))
			{
				return Vector3.forward;
			}
			return ((Vector3)(ref forward)).normalized;
		}
	}
	[BepInPlugin("0cahlo.howtofish.buriedtreasures", "BuriedTreasures", "1.1.6")]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "0cahlo.howtofish.buriedtreasures";

		public const string PluginName = "BuriedTreasures";

		public const string PluginVersion = "1.1.6";

		internal static ManualLogSource Log;

		private Harmony _harmony;

		internal static Plugin Instance { get; private set; }

		private void Awake()
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			Settings.Bind(((BaseUnityPlugin)this).Config);
			SettingsSync.Watch(((BaseUnityPlugin)this).Config);
			_harmony = new Harmony("0cahlo.howtofish.buriedtreasures");
			_harmony.PatchAll();
			((Component)this).gameObject.AddComponent<CustomItemRegistry>();
			((Component)this).gameObject.AddComponent<NetworkInstaller>();
			((Component)this).gameObject.AddComponent<IslandRebaser>();
			((Component)this).gameObject.AddComponent<IslandOutlineBaker>();
			((Component)this).gameObject.AddComponent<BottleSpawnScheduler>();
			((Component)this).gameObject.AddComponent<IslandSpotProber>();
			DigSound.Preload((MonoBehaviour)(object)this);
			MemoMessageFeed.Begin((MonoBehaviour)(object)this);
			PlayerMessageFeed.Begin((MonoBehaviour)(object)this);
			PlayerMessageReads.Begin((MonoBehaviour)(object)this);
			Log.LogInfo((object)"BuriedTreasures 1.1.6 loaded.");
		}
	}
	internal static class Settings
	{
		internal static class Digging
		{
			public static class Defaults
			{
				public const float AcceptedRange = 1.5f;

				public const bool UnearthWithStrikes = true;

				public const float StrikeAcceptedRange = 1f;

				public const float MaxStrikeDistance = 200f;

				public const bool DigUnderFootOnMiss = true;

				public const bool UnearthWithExplosions = true;

				public const float ExplosionRadiusScale = 0.6f;

				public const float MaxFloorGap = 0.5f;

				public const float FootprintScale = 0.6f;

				public const float UndersideCheckDepth = 3f;

				public const string StructureStepSounds = "Footstep_Wood_V, Footstep_Metal_V, Footstep_Inside_V";

				public const float CooldownSeconds = 0.3f;

				public const float UnearthSpawnHeight = 1f;

				public const bool ShowFeedback = true;

				public const bool LogAttempts = false;

				public const bool PlaySound = false;

				public const float SoundVolume = 1f;
			}

			public static HostSetting<float> AcceptedRange;

			public static HostSetting<bool> UnearthWithStrikes;

			public static HostSetting<float> StrikeAcceptedRange;

			public static HostSetting<float> MaxStrikeDistance;

			public static HostSetting<bool> DigUnderFootOnMiss;

			public static HostSetting<bool> UnearthWithExplosions;

			public static HostSetting<float> ExplosionRadiusScale;

			public static HostSetting<float> MaxFloorGap;

			public static HostSetting<float> FootprintScale;

			public static HostSetting<float> UndersideCheckDepth;

			public static HostSetting<string> StructureStepSounds;

			public static HostSetting<float> CooldownSeconds;

			public static HostSetting<float> UnearthSpawnHeight;

			public static DevSetting<bool> ShowFeedback;

			public static DevSetting<bool> LogAttempts;

			public static DevSetting<bool> PlaySound;

			public static DevSetting<float> SoundVolume;

			private static string _cachedStructureStepSoundsRaw;

			private static HashSet<string> _cachedStructureStepSounds;

			public static bool IsStructureStepSound(string stepSound)
			{
				string text = StructureStepSounds.Value ?? string.Empty;
				if (_cachedStructureStepSounds == null || _cachedStructureStepSoundsRaw != text)
				{
					_cachedStructureStepSounds = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
					string[] array = text.Split(',');
					foreach (string text2 in array)
					{
						_cachedStructureStepSounds.Add(text2.Trim());
					}
					_cachedStructureStepSoundsRaw = text;
				}
				return _cachedStructureStepSounds.Contains(stepSound);
			}
		}

		internal static class Bury
		{
			public static class Defaults
			{
				public const bool Enabled = true;

				public const string PromptLabel = "Bury";

				public const bool LogAttempts = false;
			}

			public static HostSetting<bool> Enabled;

			public static DevSetting<string> PromptLabel;

			public static DevSetting<bool> LogAttempts;
		}

		internal static class Memos
		{
			public static class Defaults
			{
				public const float TextHeight = 0.011f;

				public const string Messages = "";

				public const string MessagesUrl = "https://raw.githubusercontent.com/ccarus77/htf-contentfeed/main/buriedtreasures-messages.json";

				public const bool PlayerMessagesEnabled = false;

				public const string PlayerMessagesUrl = "https://hgki4m235kjjpnpa5fkzilo4rq0mutqn.lambda-url.us-east-1.on.aws";
			}

			public static HostSetting<float> TextHeight;

			public static DevSetting<string> Messages;

			public static DevSetting<string> MessagesUrl;

			public static DevSetting<bool> PlayerMessagesEnabled;

			public static DevSetting<string> PlayerMessagesUrl;
		}

		internal static class TreasureMaps
		{
			public static class Defaults
			{
				public const float GridCellSize = 21f;

				public const string WorldBounds = "";

				public const int MapZoom = 10;

				public const bool DrawIslands = true;

				public const float IslandOutlineCellSize = 3f;

				public const float IslandOutlineWaterLevel = -1f;

				public const string Treasure = "TreasureChest:4";

				public const float TreasureRadius = 140f;

				public const int TreasureAttempts = 40;
			}

			public static HostSetting<float> GridCellSize;

			public static HostSetting<string> WorldBounds;

			public static HostSetting<int> MapZoom;

			public static HostSetting<bool> DrawIslands;

			public static HostSetting<float> IslandOutlineCellSize;

			public static HostSetting<float> IslandOutlineWaterLevel;

			public static ConfigEntry<string> Treasure;

			public static DevSetting<float> TreasureRadius;

			public static DevSetting<int> TreasureAttempts;

			private static string _warnedWorldBounds;

			public static bool TryGetWorldBoundsOverride(out Rect bounds)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0082: Unknown result type (might be due to invalid IL or missing references)
				//IL_0087: Unknown result type (might be due to invalid IL or missing references)
				bounds = default(Rect);
				string text = WorldBounds.Value?.Trim() ?? string.Empty;
				if (text.Length == 0)
				{
					return false;
				}
				string[] array = text.Split(',');
				if (array.Length == 4 && TryParse(array[0], out var value) && TryParse(array[1], out var value2) && TryParse(array[2], out var value3) && TryParse(array[3], out var value4) && value3 > value && value4 > value2)
				{
					bounds = Rect.MinMaxRect(value, value2, value3, value4);
					return true;
				}
				if (_warnedWorldBounds != text)
				{
					_warnedWorldBounds = text;
					Plugin.Log.LogWarning((object)("[TreasureMaps] WorldBounds = \"" + text + "\" isn't \"minX, minZ, maxX, maxZ\"; fitting the islands instead."));
				}
				return false;
			}

			private static bool TryParse(string text, out float value)
			{
				return float.TryParse(text.Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out value);
			}
		}

		internal static class TreasureChests
		{
			public static class Defaults
			{
				public const bool ScaleWithProgress = true;

				public const float SecondsToBreak = 20f;

				public const string IslandDps = "48, 85, 267, 267, 320";

				public const string IslandRewards = "40, 100, 375, 1250, 3750";

				public const int Hitpoints = 2000;

				public const int Reward = 2500;

				public const string BreakSound = "Sell_01";

				public const string BreakVfx = "GoldCoins";

				public const int BreakCoins = 20;

				public const bool FloatOnWater = true;
			}

			public static HostSetting<bool> ScaleWithProgress;

			public static HostSetting<float> SecondsToBreak;

			public static HostSetting<string> IslandDps;

			public static HostSetting<string> IslandRewards;

			public static HostSetting<int> Hitpoints;

			public static HostSetting<int> Reward;

			public static DevSetting<string> BreakSound;

			public static DevSetting<string> BreakVfx;

			public static DevSetting<int> BreakCoins;

			public static DevSetting<bool> FloatOnWater;
		}

		internal static class Bottle
		{
			public static class Defaults
			{
				public const bool FloatOnWater = true;

				public const string ShatterSound = "Poof";

				public const string ShatterVfx = "WaterSplash";

				public const float ContentsSpawnHeight = 0.15f;

				public const bool SpawnEnabled = true;

				public const float SpawnIntervalSeconds = 300f;

				public const float SpawnMinDistance = 15f;

				public const float SpawnMaxDistance = 75f;

				public const int SpawnMaxAlive = 3;

				public const int SpawnPlacementAttempts = 24;

				public const float DespawnDistance = 240f;

				public const string LootTable = "TreasureMap:2, MemoNote:4";

				public const string DefaultContents = "Beer";
			}

			public static DevSetting<bool> FloatOnWater;

			public static DevSetting<string> ShatterSound;

			public static DevSetting<string> ShatterVfx;

			public static DevSetting<float> ContentsSpawnHeight;

			public static ConfigEntry<bool> SpawnEnabled;

			public static ConfigEntry<float> SpawnIntervalSeconds;

			public static ConfigEntry<float> SpawnMinDistance;

			public static ConfigEntry<float> SpawnMaxDistance;

			public static ConfigEntry<int> SpawnMaxAlive;

			public static DevSetting<int> SpawnPlacementAttempts;

			public static ConfigEntry<float> DespawnDistance;

			public static ConfigEntry<string> LootTable;

			public static DevSetting<string> DefaultContents;
		}

		internal static class Api
		{
			public static class Defaults
			{
				public const float SpawnHeight = 0.5f;
			}

			public static DevSetting<float> SpawnHeight;
		}

		private const string HostNote = " [Host setting: in multiplayer everyone uses the host's value.]";

		private const string HostOnlyNote = " [Host only: only the host's value matters.]";

		private static readonly List<IHostSetting> HostSettingList = new List<IHostSetting>();

		public static IReadOnlyList<IHostSetting> HostSettings => HostSettingList;

		public static void Bind(ConfigFile config)
		{
			BindDigging(config);
			BindBury(config);
			BindMemos(config);
			BindTreasureMaps(config);
			BindTreasureChests(config);
			BindBottle(config);
			BindApi(config);
			ApplyForcedDefaults(config);
		}

		private static void ApplyForcedDefaults(ConfigFile config)
		{
			if (ResetToDefault(TreasureChests.IslandRewards.Entry) | ResetToDefault(TreasureChests.Reward.Entry) | ResetToDefault((ConfigEntryBase)(object)Bottle.LootTable))
			{
				config.Save();
			}
		}

		private static bool ResetToDefault(ConfigEntryBase entry)
		{
			if (entry == null || object.Equals(entry.BoxedValue, entry.DefaultValue))
			{
				return false;
			}
			Plugin.Log.LogInfo((object)($"[Settings] Resetting {entry.Definition} to its default ({entry.DefaultValue}); " + $"it was {entry.BoxedValue}."));
			entry.BoxedValue = entry.DefaultValue;
			return true;
		}

		private static void BindApi(ConfigFile config)
		{
			Api.SpawnHeight = new DevSetting<float>(0.5f);
		}

		private static void BindDigging(ConfigFile config)
		{
			Digging.AcceptedRange = new HostSetting<float>(1.5f);
			Digging.UnearthWithStrikes = new HostSetting<bool>(fixedValue: true);
			Digging.StrikeAcceptedRange = new HostSetting<float>(1f);
			Digging.MaxStrikeDistance = new HostSetting<float>(200f);
			Digging.DigUnderFootOnMiss = new HostSetting<bool>(fixedValue: true);
			Digging.UnearthWithExplosions = new HostSetting<bool>(fixedValue: true);
			Digging.ExplosionRadiusScale = new HostSetting<float>(0.6f);
			Digging.MaxFloorGap = new HostSetting<float>(0.5f);
			Digging.FootprintScale = new HostSetting<float>(0.6f);
			Digging.UndersideCheckDepth = new HostSetting<float>(3f);
			Digging.StructureStepSounds = new HostSetting<string>("Footstep_Wood_V, Footstep_Metal_V, Footstep_Inside_V");
			Digging.CooldownSeconds = new HostSetting<float>(0.3f);
			Digging.UnearthSpawnHeight = new HostSetting<float>(1f);
			Digging.ShowFeedback = new DevSetting<bool>(fixedValue: true);
			Digging.LogAttempts = new DevSetting<bool>(fixedValue: false);
			Digging.PlaySound = new DevSetting<bool>(fixedValue: false);
			Digging.SoundVolume = new DevSetting<float>(1f);
		}

		private static void BindBury(ConfigFile config)
		{
			Bury.Enabled = new HostSetting<bool>(fixedValue: true);
			Bury.PromptLabel = new DevSetting<string>("Bury");
			Bury.LogAttempts = new DevSetting<bool>(fixedValue: false);
		}

		private static void BindMemos(ConfigFile config)
		{
			Memos.MessagesUrl = new DevSetting<string>("https://raw.githubusercontent.com/ccarus77/htf-contentfeed/main/buriedtreasures-messages.json");
			Memos.TextHeight = new HostSetting<float>(0.011f);
			Memos.Messages = new DevSetting<string>("");
			Memos.PlayerMessagesEnabled = new DevSetting<bool>(fixedValue: false);
			Memos.PlayerMessagesUrl = new DevSetting<string>("https://hgki4m235kjjpnpa5fkzilo4rq0mutqn.lambda-url.us-east-1.on.aws");
		}

		private static void BindTreasureMaps(ConfigFile config)
		{
			TreasureMaps.GridCellSize = new HostSetting<float>(21f);
			TreasureMaps.WorldBounds = new HostSetting<string>("");
			TreasureMaps.MapZoom = new HostSetting<int>(10);
			TreasureMaps.DrawIslands = new HostSetting<bool>(fixedValue: true);
			TreasureMaps.IslandOutlineCellSize = new HostSetting<float>(3f);
			TreasureMaps.IslandOutlineWaterLevel = new HostSetting<float>(-1f);
			TreasureMaps.Treasure = config.Bind<string>("TreasureMaps", "Treasure", "TreasureChest:4", "Weighted table of what a treasure map actually buries (the reward you dig up). Comma-separated \"item:weight\", plain items only -- no Memo tokens. \"TreasureChest\" is this mod's own chest: dig it up, shoot it open, and it pays out [TreasureChests] Reward. [Host only: only the host's value matters.]");
			TreasureMaps.TreasureRadius = new DevSetting<float>(140f);
			TreasureMaps.TreasureAttempts = new DevSetting<int>(40);
		}

		private static void BindTreasureChests(ConfigFile config)
		{
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Expected O, but got Unknown
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Expected O, but got Unknown
			TreasureChests.ScaleWithProgress = Host<bool>(config.Bind<bool>("TreasureChests", "ScaleWithProgress", true, "Size a chest's HP and reward to the lobby: HP = the best weapon DPS on sale up to the highest unlocked island (IslandDps) x the number of players x SecondsToBreak, and reward = that island's IslandRewards entry x the number of players. Updates live as islands unlock and players join or leave; a damaged chest keeps its fraction of health. Off = the flat Hitpoints and Reward below. [Host setting: in multiplayer everyone uses the host's value.]"));
			TreasureChests.IslandDps = Host<string>(config.Bind<string>("TreasureChests", "IslandDps", "48, 85, 267, 267, 320", "With ScaleWithProgress: sustained damage per second of one player with the best weapon each island (Island1, Island2, ...) adds to the shop, counting magazine and reload time. The strongest value up to the highest unlocked island is used, and the last entry covers any island past the list. Defaults, from the game's weapon prefabs (base ammo, no upgrades): Island1 Knife 16 dmg x 3 swings/s = 48; Island2 Pistol 25 dmg, 10 rounds, 0.15 s, 1.6 s reload = 85 (Shotgun 25 pellets x 3 dmg, 2 shells, 1.9 s reload = 70); Island3 SMG 24 dmg, 30 rounds, 0.05 s, 1.25 s reload = 267; Island4 Sniper Rifle 200 dmg, 5 rounds, 1.17 s, 1.2 s reload = 169, so the SMG's 267 still leads; Island5 Assault Rifle 40 dmg, 30 rounds, 0.07 s, 1.7 s reload = 320. A fresh save already has two islands unlocked. [Host setting: in multiplayer everyone uses the host's value.]"));
			TreasureChests.IslandRewards = Host<string>(config.Bind<string>("TreasureChests", "IslandRewards", "40, 100, 375, 1250, 3750", "With ScaleWithProgress: base payout per player, by highest unlocked island (Island1, Island2, ...), multiplied by the number of players. The last entry covers any island past the list. Defaults sit at a quarter of that stage's weapon prices (Shotgun $150, SMG $650, Sniper Rifle $3800, Assault Rifle $20000). [Host setting: in multiplayer everyone uses the host's value.]"));
			TreasureChests.Hitpoints = Host<int>(config.Bind<int>("TreasureChests", "Hitpoints", 2000, new ConfigDescription("With ScaleWithProgress off: how much damage a chest takes before it breaks open. The game's own health multiplier still applies on top. [Host setting: in multiplayer everyone uses the host's value.]", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100000), Array.Empty<object>())));
			TreasureChests.Reward = Host<int>(config.Bind<int>("TreasureChests", "Reward", 2500, new ConfigDescription("With ScaleWithProgress off: base amount cracking a chest open pays into the shared money pot. Either way the payout works exactly as selling a fish would: multiplied by the cracker's kill-score bonuses (headshot, longshot, explosion, ...) and any betting multiplier. 0 pays nothing (the chest still breaks). It also sets the worth a chest is announced with in the kill feed. [Host setting: in multiplayer everyone uses the host's value.]", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 250000), Array.Empty<object>())));
			TreasureChests.SecondsToBreak = new HostSetting<float>(20f);
			TreasureChests.BreakSound = new DevSetting<string>("Sell_01");
			TreasureChests.BreakVfx = new DevSetting<string>("GoldCoins");
			TreasureChests.BreakCoins = new DevSetting<int>(20);
			TreasureChests.FloatOnWater = new DevSetting<bool>(fixedValue: true);
		}

		private static void BindBottle(ConfigFile config)
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Expected O, but got Unknown
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Expected O, but got Unknown
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Expected O, but got Unknown
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Expected O, but got Unknown
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Expected O, but got Unknown
			Bottle.FloatOnWater = new DevSetting<bool>(fixedValue: true);
			Bottle.ShatterSound = new DevSetting<string>("Poof");
			Bottle.ShatterVfx = new DevSetting<string>("WaterSplash");
			Bottle.ContentsSpawnHeight = new DevSetting<float>(0.15f);
			Bottle.SpawnEnabled = config.Bind<bool>("Bottle Spawn", "Enabled", true, "Periodically drop a bottle on open water away from the host, so bottles keep appearing. What each one holds is rolled from [Bottle Contents] Table when it breaks. [Host only: only the host's value matters.]");
			Bottle.SpawnIntervalSeconds = config.Bind<float>("Bottle Spawn", "IntervalSeconds", 300f, new ConfigDescription("Seconds between drops. [Host only: only the host's value matters.]", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 3600f), Array.Empty<object>()));
			Bottle.SpawnMinDistance = config.Bind<float>("Bottle Spawn", "MinDistance", 15f, new ConfigDescription("Nearest a dropped bottle may be to the host, in metres -- far enough to feel like it drifted in. [Host only: only the host's value matters.]", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 1000f), Array.Empty<object>()));
			Bottle.SpawnMaxDistance = config.Bind<float>("Bottle Spawn", "MaxDistance", 75f, new ConfigDescription("Farthest a dropped bottle may be from the host, in metres. Keep it inside the island's waters so the bottle stays reachable; too small and every candidate lands on the island itself. [Host only: only the host's value matters.]", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 2000f), Array.Empty<object>()));
			Bottle.SpawnMaxAlive = config.Bind<int>("Bottle Spawn", "MaxAlive", 3, new ConfigDescription("Most drip-fed bottles allowed out at once (broken ones free a slot). 0 = no limit. [Host only: only the host's value matters.]", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
			Bottle.SpawnPlacementAttempts = new DevSetting<int>(24);
			Bottle.DespawnDistance = config.Bind<float>("Bottle Spawn", "DespawnDistance", 240f, new ConfigDescription("A drip-fed bottle that is farther than this from every player, in metres, is quietly removed (freeing its MaxAlive slot). Never goes below 2x MaxDistance, so a bottle dropped at the edge of the spawn range can't be despawned straight away. [Host only: only the host's value matters.]", (AcceptableValueBase)(object)new AcceptableValueRange<float>(50f, 10000f), Array.Empty<object>()));
			Bottle.LootTable = config.Bind<string>("Bottle Contents", "Table", "TreasureMap:2, MemoNote:4", "Weighted contents rolled when a bottle has no explicit contents. Comma-separated \"entry:weight\". An entry is a spawnable name (e.g. Beer), a numeric item id, or one of the reserved tokens \"TreasureMap\" (a treasure map to a freshly buried reward) and \"MemoNote\" (a written message). Unresolved names are skipped. [Host only: only the host's value matters.]");
			Bottle.DefaultContents = new DevSetting<string>("Beer");
		}

		private static HostSetting<T> Host<T>(ConfigEntry<T> entry)
		{
			HostSetting<T> hostSetting = new HostSetting<T>(entry);
			HostSettingList.Add(hostSetting);
			return hostSetting;
		}
	}
	internal interface IHostSetting
	{
		string Key { get; }

		ConfigEntryBase Entry { get; }

		string SerializeLocal();

		bool ApplyHostValue(string serialized);

		void ClearHostValue();
	}
	internal sealed class HostSetting<T> : IHostSetting
	{
		private readonly ConfigEntry<T> _entry;

		private readonly T _fixedValue;

		private T _hostValue;

		private bool _hasHostValue;

		public T Value
		{
			get
			{
				if (!_hasHostValue)
				{
					if (_entry == null)
					{
						return _fixedValue;
					}
					return _entry.Value;
				}
				return _hostValue;
			}
		}

		public string Key => ((ConfigEntryBase)_entry).Definition.Section + "." + ((ConfigEntryBase)_entry).Definition.Key;

		public ConfigEntryBase Entry => (ConfigEntryBase)(object)_entry;

		public HostSetting(ConfigEntry<T> entry)
		{
			_entry = entry;
		}

		public HostSetting(T fixedValue)
		{
			_fixedValue = fixedValue;
		}

		public string SerializeLocal()
		{
			return ((ConfigEntryBase)_entry).GetSerializedValue();
		}

		public bool ApplyHostValue(string serialized)
		{
			try
			{
				object obj = TomlTypeConverter.ConvertToValue(serialized, typeof(T));
				ConfigDescription description = ((ConfigEntryBase)_entry).Description;
				AcceptableValueBase val = ((description != null) ? description.AcceptableValues : null);
				if (val != null)
				{
					obj = val.Clamp(obj);
				}
				_hostValue = (T)obj;
				_hasHostValue = true;
				return true;
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[Settings] Couldn't read the host's value \"" + serialized + "\" for " + Key + "; using this machine's own. " + ex.Message));
				return false;
			}
		}

		public void ClearHostValue()
		{
			_hasHostValue = false;
			_hostValue = default(T);
		}
	}
	internal struct HostSettingsBroadcast : IBroadcast
	{
		public string[] Keys;

		public string[] Values;
	}
	internal static class SettingsSync
	{
		private const int MaxWireEntries = 256;

		private static bool _serializerReady;

		private static ClientManager _clientHandlerOwner;

		private static bool _usingHostValues;

		private static bool IsHost => InstanceFinder.IsServerStarted;

		public static void Watch(ConfigFile config)
		{
			config.SettingChanged += delegate(object sender, SettingChangedEventArgs args)
			{
				if (IsHost && IsHostSetting(args.ChangedSetting))
				{
					SendToAll();
				}
			};
			config.ConfigReloaded += delegate
			{
				if (IsHost)
				{
					SendToAll();
				}
			};
		}

		public static void SendTo(NetworkConnection connection)
		{
			ServerManager serverManager = InstanceFinder.ServerManager;
			if (IsHost && (Object)(object)serverManager != (Object)null && connection != (NetworkConnection)null)
			{
				serverManager.Broadcast<HostSettingsBroadcast>(connection, Snapshot(), true, (Channel)0);
			}
		}

		private static void SendToAll()
		{
			ServerManager serverManager = InstanceFinder.ServerManager;
			if (!((Object)(object)serverManager == (Object)null))
			{
				serverManager.Broadcast<HostSettingsBroadcast>(Snapshot(), true, (Channel)0);
				Plugin.Log.LogDebug((object)"[Settings] A host setting changed; sent the host settings to every player.");
			}
		}

		private static HostSettingsBroadcast Snapshot()
		{
			IReadOnlyList<IHostSetting> hostSettings = Settings.HostSettings;
			HostSettingsBroadcast result = new HostSettingsBroadcast
			{
				Keys = new string[hostSettings.Count],
				Values = new string[hostSettings.Count]
			};
			for (int i = 0; i < hostSettings.Count; i++)
			{
				result.Keys[i] = hostSettings[i].Key;
				result.Values[i] = hostSettings[i].SerializeLocal();
			}
			return result;
		}

		private static bool IsHostSetting(ConfigEntryBase entry)
		{
			foreach (IHostSetting hostSetting in Settings.HostSettings)
			{
				if (hostSetting.Entry == entry)
				{
					return true;
				}
			}
			return false;
		}

		private static void OnHostSettings(HostSettingsBroadcast msg, Channel channel)
		{
			NetHandlerUtil.Guarded("[Settings]", "host settings", delegate
			{
				if (!IsHost && msg.Keys != null && msg.Values != null)
				{
					Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.Ordinal);
					for (int i = 0; i < msg.Keys.Length && i < msg.Values.Length; i++)
					{
						dictionary[msg.Keys[i]] = msg.Values[i];
					}
					int num = 0;
					foreach (IHostSetting hostSetting in Settings.HostSettings)
					{
						if (dictionary.TryGetValue(hostSetting.Key, out var value) && hostSetting.ApplyHostValue(value))
						{
							num++;
						}
						else
						{
							hostSetting.ClearHostValue();
						}
					}
					_usingHostValues = true;
					Plugin.Log.LogInfo((object)$"[Settings] Using the host's values for {num} host setting(s).");
				}
			});
		}

		private static void RevertToLocal()
		{
			if (!_usingHostValues)
			{
				return;
			}
			foreach (IHostSetting hostSetting in Settings.HostSettings)
			{
				hostSetting.ClearHostValue();
			}
			_usingHostValues = false;
			Plugin.Log.LogInfo((object)"[Settings] Left the host's game; back to this machine's own settings.");
		}

		public static void PumpClientHandlers()
		{
			ClientManager val = (InstanceFinder.IsClientStarted ? InstanceFinder.ClientManager : null);
			if (NetHandlerUtil.TrySwapOwner(ref _clientHandlerOwner, val, out var previous))
			{
				if (previous != null)
				{
					previous.UnregisterBroadcast<HostSettingsBroadcast>((Action<HostSettingsBroadcast, Channel>)OnHostSettings);
				}
				if (val != null)
				{
					val.RegisterBroadcast<HostSettingsBroadcast>((Action<HostSettingsBroadcast, Channel>)OnHostSettings);
				}
				if ((Object)(object)val == (Object)null)
				{
					RevertToLocal();
				}
			}
		}

		public static void EnsureSerializers()
		{
			if (_serializerReady)
			{
				return;
			}
			GenericWriter<HostSettingsBroadcast>.SetWrite((Action<Writer, HostSettingsBroadcast>)delegate(Writer w, HostSettingsBroadcast v)
			{
				string[] keys = v.Keys;
				int val = ((keys != null) ? keys.Length : 0);
				string[] values = v.Values;
				int num = Math.Min(Math.Min(val, (values != null) ? values.Length : 0), 256);
				w.WriteInt32(num);
				for (int i = 0; i < num; i++)
				{
					w.WriteString(v.Keys[i] ?? string.Empty);
					w.WriteString(v.Values[i] ?? string.Empty);
				}
			});
			GenericReader<HostSettingsBroadcast>.SetRead((Func<Reader, HostSettingsBroadcast>)delegate(Reader r)
			{
				int num = r.ReadInt32();
				if (num < 0 || num > 256)
				{
					throw new InvalidOperationException($"Malformed host settings: {num} entries.");
				}
				HostSettingsBroadcast result = new HostSettingsBroadcast
				{
					Keys = new string[num],
					Values = new string[num]
				};
				for (int i = 0; i < num; i++)
				{
					result.Keys[i] = r.ReadStringAllocated() ?? string.Empty;
					result.Values[i] = r.ReadStringAllocated() ?? string.Empty;
				}
				return result;
			});
			_serializerReady = true;
		}
	}
}
namespace BuriedTreasures.Save
{
	[Serializable]
	internal sealed class PersistenceData
	{
		public List<BuriedItemRecord> BuriedItems = new List<BuriedItemRecord>();

		public List<MemoRecord> Memos = new List<MemoRecord>();
	}
	[Serializable]
	internal sealed class BuriedItemRecord
	{
		public string Id;

		public float X;

		public float Y;

		public float Z;

		public int ItemId;

		public bool Dug;

		public string IslandScene = string.Empty;

		public float LocalX;

		public float LocalY;

		public float LocalZ;

		public bool HasMap;

		public bool HasState;

		public bool IsMemo;

		public int MemoMode;

		public string MemoText = string.Empty;

		public string TreasureMapId = string.Empty;

		public bool TreasureMapUnearthed;

		public float TreasureMapDugX;

		public float TreasureMapDugY;

		public float TreasureMapDugZ;

		public float Cookness;

		public float BettingMultiplier = 1f;

		public float Weight = 1f;

		public float KillScoreMultiplier = 1f;

		public bool IsDrip;

		public byte SkinIndex;

		public byte Sight;

		public byte BarrelAttachment;

		public byte AmmoType;

		public bool ExtendedMag;

		public bool LaserSight;

		public byte Sharpness;
	}
	[Serializable]
	internal sealed class MemoRecord
	{
		public const int HeldSlot = -1;

		public const int WorldSlot = -2;

		public const int MapMode = 1;

		public const int TextMode = 2;

		public string SteamId;

		public int Slot;

		public float X;

		public float Y;

		public float Z;

		public int Mode;

		public string Text = string.Empty;

		public string MapId = string.Empty;

		public bool Unearthed;

		public float DugX;

		public float DugY;

		public float DugZ;
	}
	internal static class PersistencePatches
	{
		[HarmonyPatch(typeof(SaveManager), "SavePlayer")]
		private static class SavePlayerPatch
		{
			private static void Prefix(Player player, ref Item heldItem, Dictionary<byte, Item> slotToItem)
			{
				if ((Object)(object)player == (Object)null || !IsHost)
				{
					return;
				}
				EnsureLoaded();
				string steamId = player.SteamID.ToString();
				PlayerMaps.RemoveAll((MemoRecord r) => r.SteamId == steamId);
				if (CustomItemRegistry.Memo.Is(heldItem) && !TryRecordMap(heldItem, steamId, -1))
				{
					heldItem = null;
				}
				if (slotToItem == null)
				{
					return;
				}
				foreach (byte item in new List<byte>(slotToItem.Keys))
				{
					Item val = slotToItem[item];
					if (CustomItemRegistry.Memo.Is(val) && !TryRecordMap(val, steamId, item))
					{
						slotToItem.Remove(item);
					}
				}
			}
		}

		[HarmonyPatch(typeof(SaveManager), "SaveWorldItems")]
		private static class SaveWorldItemsPatch
		{
			private static void Postfix(List<SavedWorldItem> __result)
			{
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				//IL_0061: Unknown result type (might be due to invalid IL or missing references)
				//IL_0066: Unknown result type (might be due to invalid IL or missing references)
				//IL_0067: 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_006e: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
				if (__result == null || !IsHost)
				{
					return;
				}
				Vector3 closestIslandPos = Island.GetClosestIslandPos(Vector3.zero);
				List<MemoRecord> list = new List<MemoRecord>();
				HashSet<Item> hashSet = new HashSet<Item>();
				for (int num = __result.Count - 1; num >= 0; num--)
				{
					SavedWorldItem val = __result[num];
					if (val?.Item != null && val.Item.ItemID == 201)
					{
						Vector3 val2 = val.Position + closestIslandPos;
						Item val3 = FindLooseMemoAt(val2, hashSet);
						if (!(ContentOf(val3) is MemoTreasureMap map))
						{
							__result.RemoveAt(num);
						}
						else
						{
							hashSet.Add(val3);
							MemoRecord memoRecord = MapRecord(map, string.Empty, -2);
							memoRecord.X = val2.x;
							memoRecord.Y = val2.y;
							memoRecord.Z = val2.z;
							list.Add(memoRecord);
						}
					}
				}
				_worldMaps = list;
			}
		}

		[HarmonyPatch(typeof(SaveManager), "SaveServer")]
		private static class SaveServerPatch
		{
			private static void Postfix()
			{
				ServerSaveObject curServerSave = SaveManager.CurServerSave;
				if (curServerSave != null && IsHost)
				{
					EnsureLoaded();
					int num = PruneOrphanedTreasure(live: true);
					if (num > 0)
					{
						Plugin.Log.LogInfo((object)$"[Save] Removed {num} buried treasure(s) whose map no longer exists.");
					}
					PersistenceData persistenceData = new PersistenceData();
					CaptureBuried(persistenceData);
					persistenceData.Memos.AddRange(PlayerMaps);
					persistenceData.Memos.AddRange(_worldMaps);
					PersistenceStore.Save(curServerSave.Name, persistenceData);
				}
			}
		}

		[HarmonyPatch(typeof(PlayerInventory), "LoadFromSave")]
		private static class LoadInventoryPatch
		{
			private static void Prefix(PlayerInventory __instance)
			{
				EnsureLoaded();
				_loadingPlayer = InventoryPlayer.Invoke(__instance);
				_loadingSave = InventoryToLoadFrom.Invoke(__instance);
			}

			private static void Postfix()
			{
				_loadingPlayer = null;
				_loadingSave = null;
				GivePendingMaps();
			}
		}

		[HarmonyPatch(typeof(ItemManager), "SpawnSavedItem")]
		private static class LoadWorldItemPatch
		{
			private static void Prefix()
			{
				EnsureLoaded();
				_loadingWorldItem = true;
			}

			private static void Postfix()
			{
				_loadingWorldItem = false;
				GivePendingMaps();
			}
		}

		[HarmonyPatch(typeof(Item), "LoadFromSave")]
		private static class LoadItemPatch
		{
			private static void Postfix(Item __instance, SavedItem savedItem)
			{
				//IL_0087: Unknown result type (might be due to invalid IL or missing references)
				if (!CustomItemRegistry.Memo.Is(__instance) || savedItem == null)
				{
					return;
				}
				MemoRecord memoRecord = null;
				if ((Object)(object)_loadingPlayer != (Object)null && _loadingSave != null)
				{
					int slot = ((savedItem == _loadingSave.HeldItem) ? (-1) : savedItem.InventorySlot);
					string steamId = _loadingPlayer.SteamID.ToString();
					memoRecord = PlayerMaps.Find((MemoRecord r) => r.SteamId == steamId && r.Slot == slot);
				}
				else if (_loadingWorldItem)
				{
					memoRecord = TakeWorldMapAt(((Component)__instance).transform.position);
				}
				MemoContent memoContent = ((memoRecord != null) ? ContentFrom(memoRecord) : null);
				if (memoContent != null)
				{
					PendingMaps.Add(new KeyValuePair<Item, MemoContent>(__instance, memoContent));
				}
			}
		}

		[HarmonyPatch(typeof(PlayerInventory), "OnStopServer")]
		private static class OnStopServerPatch
		{
			private static void Postfix(PlayerInventory __instance)
			{
				if (!(((NetworkBehaviour)__instance).Owner != (NetworkConnection)null) || ((NetworkBehaviour)__instance).Owner.IsLocalClient || !Object.op_Implicit((Object)(object)Server.Instance) || ((NetworkBehaviour)Server.Instance).IsDeinitializing)
				{
					BuriedItemStore.Clear();
					MemoContentStore.Clear();
					IslandSpotCache.Clear();
					IslandRegistry.Clear();
					BottleLoot.ClearAll();
					BottleOnDeathPatch.ClearAll();
					ChestCredit.ClearAll();
					ChestOnDeathPatch.ClearAll();
					_loadedSaveName = null;
					PlayerMaps.Clear();
					_worldMaps = new List<MemoRecord>();
					UnmatchedWorldMaps.Clear();
					PendingMaps.Clear();
				}
			}
		}

		private static readonly FieldRef<PlayerInventory, Player> InventoryPlayer = AccessTools.FieldRefAccess<PlayerInventory, Player>("_player");

		private static readonly FieldRef<PlayerInventory, SavedPlayer> InventoryToLoadFrom = AccessTools.FieldRefAccess<PlayerInventory, SavedPlayer>("_toLoadFrom");

		private const float WorldMatchDistance = 0.05f;

		private static string _loadedSaveName;

		private static readonly List<MemoRecord> PlayerMaps = new List<MemoRecord>();

		private static List<MemoRecord> _worldMaps = new List<MemoRecord>();

		private static readonly List<MemoRecord> UnmatchedWorldMaps = new List<MemoRecord>();

		private static Player _loadingPlayer;

		private static SavedPlayer _loadingSave;

		private static bool _loadingWorldItem;

		private static readonly List<KeyValuePair<Item, MemoContent>> PendingMaps = new List<KeyValuePair<Item, MemoContent>>();

		private static bool IsHost => InstanceFinder.IsServerStarted;

		private static bool TryRecordMap(Item memo, string steamId, int slot)
		{
			if (!(ContentOf(memo) is MemoTreasureMap map))
			{
				return false;
			}
			PlayerMaps.Add(MapRecord(map, steamId, slot));
			return true;
		}

		private static MemoRecord MapRecord(MemoTreasureMap map, string steamId, int slot)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			return new MemoRecord
			{
				SteamId = steamId,
				Slot = slot,
				Mode = 1,
				MapId = map.BuriedItemId.ToString(),
				Unearthed = map.IsUnearthed,
				DugX = map.UnearthedAt.x,
				DugY = map.UnearthedAt.y,
				DugZ = map.UnearthedAt.z
			};
		}

		private static Item FindLooseMemoAt(Vector3 position, HashSet<Item> claimed)
		{
			//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_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			Item result = null;
			float num = 0.0025000002f;
			foreach (Item value in ItemManager.Items.Values)
			{
				if (!((Object)(object)value == (Object)null) && !claimed.Contains(value) && CustomItemRegistry.Memo.Is(value))
				{
					Vector3 val = ((Component)value).transform.position - position;
					float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
					if (sqrMagnitude <= num)
					{
						result = value;
						num = sqrMagnitude;
					}
				}
			}
			return result;
		}

		private static void CaptureBuried(PersistenceData data)
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			BuriedItem[] array = BuriedItemStore.Snapshot();
			foreach (BuriedItem buriedItem in array)
			{
				if (buriedItem.GameItemId == 201)
				{
					BuriedItemState state = buriedItem.State;
					if (state == null || state.ToMemoContent()?.IsTreasureMap != true)
					{
						continue;
					}
				}
				BuriedItemRecord buriedItemRecord = new BuriedItemRecord
				{
					Id = buriedItem.Id.ToString(),
					X = buriedItem.WorldPosition.x,
					Y = buriedItem.WorldPosition.y,
					Z = buriedItem.WorldPosition.z,
					ItemId = buriedItem.GameItemId,
					IslandScene = (buriedItem.IslandScene ?? string.Empty),
					LocalX = buriedItem.LocalPosition.x,
					LocalY = buriedItem.LocalPosition.y,
					LocalZ = buriedItem.LocalPosition.z,
					HasMap = buriedItem.HasMap
				};
				WriteState(buriedItemRecord, buriedItem.State);
				data.BuriedItems.Add(buriedItemRecord);
			}
		}

		private static void WriteState(BuriedItemRecord record, BuriedItemState state)
		{
			if (state != null)
			{
				record.HasState = true;
				record.IsMemo = state.IsMemo;
				record.MemoMode = state.MemoMode;
				record.MemoText = state.MemoText;
				record.TreasureMapId = state.TreasureMapId.ToString();
				record.TreasureMapUnearthed = state.TreasureMapUnearthed;
				record.TreasureMapDugX = state.TreasureMapUnearthedAt.x;
				record.TreasureMapDugY = state.TreasureMapUnearthedAt.y;
				record.TreasureMapDugZ = state.TreasureMapUnearthedAt.z;
				SavedItem saved = state.Saved;
				record.Cookness = saved.Cookness;
				record.BettingMultiplier = saved.BettingMultiplier;
				record.Weight = saved.Weight;
				record.KillScoreMultiplier = saved.KillScoreMultiplier;
				record.IsDrip = saved.IsDripCreature;
				record.SkinIndex = saved.SkinIndex;
				record.Sight = saved.Sight;
				record.BarrelAttachment = saved.BarrelAttachment;
				record.AmmoType = saved.AmmoType;
				record.ExtendedMag = saved.ExtendedMag;
				record.LaserSight = saved.LaserSight;
				record.Sharpness = saved.Sharpness;
			}
		}

		private static void GivePendingMaps()
		{
			foreach (KeyValuePair<Item, MemoContent> pendingMap in PendingMaps)
			{
				Item key = pendingMap.Key;
				if ((Object)(object)key != (Object)null && ((NetworkBehaviour)key).IsSpawned)
				{
					MemoNetwork.HostSet(((NetworkBehaviour)key).ObjectId, pendingMap.Value);
				}
			}
			PendingMaps.Clear();
		}

		private static MemoRecord TakeWorldMapAt(Vector3 position)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			MemoRecord memoRecord = null;
			float num = 0.0025000002f;
			foreach (MemoRecord unmatchedWorldMap in UnmatchedWorldMaps)
			{
				Vector3 val = new Vector3(unmatchedWorldMap.X, unmatchedWorldMap.Y, unmatchedWorldMap.Z) - position;
				float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
				if (sqrMagnitude <= num)
				{
					memoRecord = unmatchedWorldMap;
					num = sqrMagnitude;
				}
			}
			if (memoRecord != null)
			{
				UnmatchedWorldMaps.Remove(memoRecord);
			}
			return memoRecord;
		}

		private static MemoContent ContentFrom(MemoRecord record)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			if (record.Mode != 1)
			{
				return null;
			}
			Guid.TryParse(record.MapId, out var result);
			if (!record.Unearthed)
			{
				return MemoTreasureMap.To(result);
			}
			return MemoTreasureMap.Dug(result, new Vector3(record.DugX, record.DugY, record.DugZ));
		}

		private static MemoContent ContentOf(Item memo)
		{
			if (!((Object)(object)memo != (Object)null) || !((NetworkBehaviour)memo).IsSpawned)
			{
				return null;
			}
			return MemoContentStore.Get(((NetworkBehaviour)memo).ObjectId);
		}

		internal static void HostMarkSavedMapsUnearthed(Guid buriedItemId, Vector3 at)
		{
			//IL_0029: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			if (IsHost && !(buriedItemId == Guid.Empty))
			{
				string buriedItemId2 = buriedItemId.ToString();
				MarkUnearthed(PlayerMaps, buriedItemId2, at);
				MarkUnearthed(_worldMaps, buriedItemId2, at);
				MarkUnearthed(UnmatchedWorldMaps, buriedItemId2, at);
			}
		}

		private static int PruneOrphanedTreasure(bool live)
		{
			HashSet<Guid> hashSet = new HashSet<Guid>();
			if (live)
			{
				KeyValuePair<int, MemoContent>[] array = MemoContentStore.Snapshot();
				foreach (KeyValuePair<int, MemoContent> keyValuePair in array)
				{
					if (keyValuePair.Value is MemoTreasureMap { IsUnearthed: false } memoTreasureMap)
					{
						hashSet.Add(memoTreasureMap.BuriedItemId);
					}
				}
			}
			foreach (BuriedItem item in BuriedItemStore.Live)
			{
				BuriedItemState state = item.State;
				if (state != null && state.MemoMode == 1 && !state.TreasureMapUnearthed)
				{
					hashSet.Add(state.TreasureMapId);
				}
			}
			AddMarked(hashSet, PlayerMaps);
			AddMarked(hashSet, _worldMaps);
			AddMarked(hashSet, UnmatchedWorldMaps);
			List<Guid> list = new List<Guid>();
			foreach (BuriedItem item2 in BuriedItemStore.Live)
			{
				if (item2.HasMap && !hashSet.Contains(item2.Id))
				{
					list.Add(item2.Id);
				}
			}
			foreach (Guid item3 in list)
			{
				if (live)
				{
					BuriedTreasuresApi.RemoveBuriedItem(item3);
				}
				else
				{
					BuriedItemStore.Remove(item3);
				}
			}
			return list.Count;
		}

		private static void AddMarked(HashSet<Guid> marked, List<MemoRecord> records)
		{
			foreach (MemoRecord record in records)
			{
				if (record.Mode == 1 && !record.Unearthed && Guid.TryParse(record.MapId, out var result))
				{
					marked.Add(result);
				}
			}
		}

		private static void MarkUnearthed(List<MemoRecord> records, string buriedItemId, Vector3 at)
		{
			//IL_0038: 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_0050: Unknown result type (might be due to invalid IL or missing references)
			foreach (MemoRecord record in records)
			{
				if (!record.Unearthed && record.Mode == 1 && !(record.MapId != buriedItemId))
				{
					record.Unearthed = true;
					record.DugX = at.x;
					record.DugY = at.y;
					record.DugZ = at.z;
				}
			}
		}

		private static void EnsureLoaded()
		{
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			ServerSaveObject curServerSave = SaveManager.CurServerSave;
			if (!IsHost || curServerSave == null || curServerSave.Name == _loadedSaveName)
			{
				return;
			}
			PersistenceData persistenceData = PersistenceStore.Load(curServerSave.Name);
			_loadedSaveName = curServerSave.Name;
			List<BuriedItem> list = new List<BuriedItem>(persistenceData.BuriedItems.Count);
			foreach (BuriedItemRecord buriedItem in persistenceData.BuriedItems)
			{
				if (!buriedItem.Dug && Guid.TryParse(buriedItem.Id, out var result) && buriedItem.ItemId >= 0 && buriedItem.ItemId < 255)
				{
					BuriedItemState buriedItemState = ReadState(buriedItem);
					if (buriedItem.ItemId != 201 || (buriedItemState != null && buriedItemState.ToMemoContent()?.IsTreasureMap == true))
					{
						list.Add(new BuriedItem(result, new Vector3(buriedItem.X, buriedItem.Y, buriedItem.Z), (byte)buriedItem.ItemId, buriedItemState, buriedItem.IslandScene, (Vector3?)new Vector3(buriedItem.LocalX, buriedItem.LocalY, buriedItem.LocalZ))
						{
							HasMap = buriedItem.HasMap
						});
					}
				}
			}
			PlayerMaps.Clear();
			UnmatchedWorldMaps.Clear();
			_worldMaps = new List<MemoRecord>();
			foreach (MemoRecord memo in persistenceData.Memos)
			{
				if (memo.Mode == 1)
				{
					if (memo.Slot == -2)
					{
						_worldMaps.Add(memo);
						UnmatchedWorldMaps.Add(memo);
					}
					else
					{
						PlayerMaps.Add(memo);
					}
				}
			}
			BuriedItemStore.Replace(list);
			int num = PruneOrphanedTreasure(live: false);
			BuryNetwork.SendFullListToAll();
			if (num > 0)
			{
				Plugin.Log.LogInfo((object)$"[Save] Dropped {num} buried treasure(s) whose map no longer exists.");
			}
			Plugin.Log.LogInfo((object)($"[Save] Restored {BuriedItemStore.Count} buried item(s) and {PlayerMaps.Count + _worldMaps.Count} " + "treasure map(s) from '" + curServerSave.Name + "'."));
		}

		private static BuriedItemState ReadState(BuriedItemRecord record)
		{
			//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)
			if (!record.HasState)
			{
				return null;
			}
			BuriedItemState buriedItemState = new BuriedItemState
			{
				IsMemo = record.IsMemo,
				MemoMode = record.MemoMode,
				MemoText = (record.MemoText ?? string.Empty),
				TreasureMapUnearthed = record.TreasureMapUnearthed,
				TreasureMapUnearthedAt = new Vector3(record.TreasureMapDugX, record.TreasureMapDugY, record.TreasureMapDugZ)
			};
			SavedItem saved = buriedItemState.Saved;
			saved.Cookness = record.Cookness;
			saved.BettingMultiplier = record.BettingMultiplier;
			saved.Weight = record.Weight;
			saved.KillScoreMultiplier = record.KillScoreMultiplier;
			saved.IsDripCreature = record.IsDrip;
			saved.SkinIndex = record.SkinIndex;
			saved.Sight = record.Sight;
			saved.BarrelAttachment = record.BarrelAttachment;
			saved.AmmoType = record.AmmoType;
			saved.ExtendedMag = record.ExtendedMag;
			saved.LaserSight = record.LaserSight;
			saved.Sharpness = record.Sharpness;
			if (Guid.TryParse(record.TreasureMapId, out var result))
			{
				buriedItemState.TreasureMapId = result;
			}
			return buriedItemState;
		}
	}
	internal static class PersistenceStore
	{
		[Serializable]
		private sealed class Envelope
		{
			public List<string> BuriedItems = new List<string>();

			public List<string> Memos = new List<string>();
		}

		private const string FolderName = "BuriedTreasures";

		private static string Folder => Path.Combine(Paths.ConfigPath, "BuriedTreasures");

		public static PersistenceData Load(string saveName)
		{
			string text = PathFor(saveName);
			if (text == null || !File.Exists(text))
			{
				return new PersistenceData();
			}
			try
			{
				Envelope envelope = JsonUtility.FromJson<Envelope>(File.ReadAllText(text));
				PersistenceData persistenceData = new PersistenceData();
				if (envelope != null)
				{
					foreach (string item in envelope.BuriedItems ?? new List<string>())
					{
						BuriedItemRecord buriedItemRecord = FromFragment<BuriedItemRecord>(item);
						if (buriedItemRecord != null)
						{
							BuriedItemRecord buriedItemRecord2 = buriedItemRecord;
							if (buriedItemRecord2.TreasureMapId == null)
							{
								buriedItemRecord2.TreasureMapId = string.Empty;
							}
							buriedItemRecord2 = buriedItemRecord;
							if (buriedItemRecord2.IslandScene == null)
							{
								buriedItemRecord2.IslandScene = string.Empty;
							}
							persistenceData.BuriedItems.Add(buriedItemRecord);
						}
					}
					foreach (string item2 in envelope.Memos ?? new List<string>())
					{
						MemoRecord memoRecord = FromFragment<MemoRecord>(item2);
						if (memoRecord != null)
						{
							MemoRecord memoRecord2 = memoRecord;
							if (memoRecord2.MapId == null)
							{
								memoRecord2.MapId = string.Empty;
							}
							persistenceData.Memos.Add(memoRecord);
						}
					}
				}
				Plugin.Log.LogInfo((object)$"[Save] Loaded {persistenceData.BuriedItems.Count} buried item(s) and {persistenceData.Memos.Count} Memo(s) from {Path.GetFileName(text)}.");
				return persistenceData;
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"[Save] Couldn't read {text}; starting empty. {arg}");
				return new PersistenceData();
			}
		}

		public static void Save(string saveName, PersistenceData data)
		{
			string text = PathFor(saveName);
			if (text == null)
			{
				Plugin.Log.LogWarning((object)"[Save] No current save name; skipping the BuriedTreasures side-file.");
				return;
			}
			try
			{
				Envelope envelope = new Envelope();
				foreach (BuriedItemRecord buriedItem in data.BuriedItems)
				{
					envelope.BuriedItems.Add(JsonUtility.ToJson((object)buriedItem));
				}
				foreach (MemoRecord memo in data.Memos)
				{
					envelope.Memos.Add(JsonUtility.ToJson((object)memo));
				}
				Directory.CreateDirectory(Folder);
				File.WriteAllText(text, JsonUtility.ToJson((object)envelope, true));
				Plugin.Log.LogInfo((object)$"[Save] Wrote {data.BuriedItems.Count} buried item(s) and {data.Memos.Count} Memo(s) to {Path.GetFileName(text)}.");
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"[Save] Couldn't write {text}. {arg}");
			}
		}

		private static T FromFragment<T>(string fragment) where T : class
		{
			if (string.IsNullOrEmpty(fragment))
			{
				return null;
			}
			try
			{
				return JsonUtility.FromJson<T>(fragment);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[Save] Skipped an unreadable " + typeof(T).Name + " record. " + ex.Message));
				return null;
			}
		}

		private static string PathFor(string saveName)
		{
			string text = Sanitize(saveName);
			if (!string.IsNullOrEmpty(text))
			{
				return Path.Combine(Folder, text + ".json");
			}
			return null;
		}

		private static string Sanitize(string saveName)
		{
			if (string.IsNullOrWhiteSpace(saveName))
			{
				return null;
			}
			StringBuilder stringBuilder = new StringBuilder(saveName.Length);
			foreach (char c in saveName)
			{
				stringBuilder.Append((Array.IndexOf(Path.GetInvalidFileNameChars(), c) >= 0) ? '_' : c);
			}
			return stringBuilder.ToString();
		}
	}
}
namespace BuriedTreasures.Models
{
	internal static class MaterialTweaks
	{
		private static readonly int NormalStrengthId = Shader.PropertyToID("_Normal_Strength");

		private static readonly int NormalScaleId = Shader.PropertyToID("_Normal_Scale");

		private static readonly int EmissionId = Shader.PropertyToID("_Emission");

		private static readonly int SmoothnessId = Shader.PropertyToID("_Smoothness");

		private static readonly int MetallicId = Shader.PropertyToID("_Metallic");

		private static readonly int ShininessId = Shader.PropertyToID("_Shininess");

		private static readonly int SpecularHighlightsId = Shader.PropertyToID("_SpecularHighlights");

		private static readonly int EnvReflectionsId = Shader.PropertyToID("_EnvironmentReflections");

		private static readonly int GlossyReflectionsId = Shader.PropertyToID("_GlossyReflections");

		private static readonly int SpecColorId = Shader.PropertyToID("_SpecColor");

		private static readonly int SpecularColorId = Shader.PropertyToID("_SpecularColor");

		private static readonly int ReflectColorId = Shader.PropertyToID("_ReflectColor");

		private static readonly int ColorsId = Shader.PropertyToID("_Colors");

		private static readonly int BaseMapId = Shader.PropertyToID("_BaseMap");

		private static Shader _unlit;

		public static void DisableNormalMap(Renderer renderer)
		{
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			Material material = renderer.material;
			material.SetFloat(NormalStrengthId, 0f);
			material.SetFloat(NormalScaleId, 0f);
			material.SetFloat(SmoothnessId, 0f);
			material.SetFloat(MetallicId, 0f);
			material.SetFloat(ShininessId, 0f);
			material.SetFloat(SpecularHighlightsId, 0f);
			material.SetFloat(EnvReflectionsId, 0f);
			material.SetFloat(GlossyReflectionsId, 0f);
			material.SetColor(SpecColorId, Color.black);
			material.SetColor(SpecularColorId, Color.black);
			material.SetColor(ReflectColorId, Color.black);
		}

		public static void DisableEmission(Renderer renderer)
		{
			renderer.material.SetFloat(EmissionId, 0f);
		}

		public static void MakeMatte(Renderer renderer)
		{
			Material material = renderer.material;
			Texture val = (material.HasProperty(ColorsId) ? material.GetTexture(ColorsId) : null);
			_unlit = (((Object)(object)_unlit != (Object)null) ? _unlit : Shader.Find("Universal Render Pipeline/Unlit"));
			if (!((Object)(object)_unlit == (Object)null) && !((Object)(object)val == (Object)null))
			{
				material.shader = _unlit;
				material.SetTexture(BaseMapId, val);
			}
		}
	}
	internal static class MeshTangents
	{
		public static Vector4 ForNormal(Vector3 normal)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: 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_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: 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_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			normal = ((((Vector3)(ref normal)).sqrMagnitude > 1E-12f) ? ((Vector3)(ref normal)).normalized : Vector3.forward);
			Vector3 val = Vector3.Cross((Mathf.Abs(Vector3.Dot(normal, Vector3.up)) < 0.99f) ? Vector3.up : Vector3.right, normal);
			Vector3 normalized = ((Vector3)(ref val)).normalized;
			return new Vector4(normalized.x, normalized.y, normalized.z, -1f);
		}
	}
	internal sealed class ObjModel
	{
		private readonly struct Corner
		{
			public readonly int Position;

			public readonly int Normal;

			public Corner(int position, int normal)
			{
				Position = position;
				Normal = normal;
			}
		}

		private static readonly char[] Whitespace = new char[2] { ' ', '\t' };

		private readonly List<Vector3> _positions = new List<Vector3>();

		private readonly List<Vector3> _normals = new List<Vector3>();

		private readonly List<Corner[]> _faces = new List<Corner[]>();

		private readonly List<int> _faceMaterial = new List<int>();

		private readonly List<string> _materialNames = new List<string>();

		private int _currentMaterial = -1;

		private int[] _facePart;

		public Bounds Bounds { get; private set; }

		private ObjModel()
		{
		}

		public string MaterialNameAt(int index)
		{
			if (index < 0 || index >= _materialNames.Count)
			{
				return null;
			}
			return _materialNames[index];
		}

		public static ObjModel LoadEmbedded(string resourceName)
		{
			Stream stream = EmbeddedResources.Open(resourceName) ?? throw new InvalidOperationException("The embedded model '" + resourceName + "' is missing from the DLL.");
			ObjModel objModel = new ObjModel();
			using (StreamReader streamReader = new StreamReader(stream))
			{
				string line;
				while ((line = streamReader.ReadLine()) != null)
				{
					objModel.ParseLine(line);
				}
			}
			if (objModel._faces.Count == 0)
			{
				throw new InvalidOperationException("The embedded model '" + resourceName + "' has no faces.");
			}
			objModel.FindPartsAndBounds();
			return objModel;
		}

		public Mesh ToMesh(string name, Matrix4x4 fileToMesh, Func<int, Vector2> partUv)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			return Build(name, fileToMesh, (int f) => partUv(_facePart[f]));
		}

		public Mesh ToMeshByMaterial(string name, Matrix4x4 fileToMesh, Func<int, Vector2> materialUv)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			return Build(name, fileToMesh, (int f) => materialUv(_faceMaterial[f]));
		}

		public Mesh ToMeshByMaterial(string name, Matrix4x4 fileToMesh, Func<int, Vector2> materialUv, int submeshCount, Func<int, int> materialSubmesh)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			return Build(name, fileToMesh, (int f) => materialUv(_faceMaterial[f]), submeshCount, (int f) => materialSubmesh(_faceMaterial[f]));
		}

		private Mesh Build(string name, Matrix4x4 fileToMesh, Func<int, Vector2> faceUv, int submeshCount = 1, Func<int, int> faceSubmesh = null)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: 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)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0241: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: 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_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: 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)
			//IL_027d: Expected O, but got Unknown
			bool flag = ((Matrix4x4)(ref fileToMesh)).determinant < 0f;
			List<Vector3> vertices = new List<Vector3>();
			List<Vector3> normals = new List<Vector3>();
			List<Vector2> uvs = new List<Vector2>();
			List<int>[] array = new List<int>[Mathf.Max(1, submeshCount)];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = new List<int>();
			}
			Dictionary<long, int> vertexOfCorner = new Dictionary<long, int>();
			List<Vector3> list = new List<Vector3>();
			List<int> list2 = new List<int>();
			int f;
			for (f = 0; f < _faces.Count; f++)
			{
				Corner[] array2 = _faces[f];
				list.Clear();
				Corner[] array3 = array2;
				for (int j = 0; j < array3.Length; j++)
				{
					Corner corner = array3[j];
					list.Add(_positions[corner.Position]);
				}
				Vector3 val = NewellNormal(list);
				Triangulate(list, val, list2);
				Vector3 val2 = ((Matrix4x4)(ref fileToMesh)).MultiplyVector(val);
				Vector3 meshFaceNormal = ((Vector3)(ref val2)).normalized;
				Vector2 uv = faceUv(f);
				List<int> list3 = array[(faceSubmesh != null) ? Mathf.Clamp(faceSubmesh(f), 0, array.Length - 1) : 0];
				for (int k = 0; k < list2.Count; k += 3)
				{
					int num = list2[k];
					int num2 = list2[k + 1];
					int num3 = list2[k + 2];
					if (flag)
					{
						int num4 = num3;
						num3 = num2;
						num2 = num4;
					}
					list3.Add(VertexOf(array2[num]));
					list3.Add(VertexOf(array2[num2]));
					list3.Add(VertexOf(array2[num3]));
				}
				int VertexOf(Corner corner2)
				{
					//IL_008c: Unknown result type (might be due to invalid IL or missing references)
					//IL_0091: Unknown result type (might be due to invalid IL or missing references)
					//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
					//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
					//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
					//IL_00d2: 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_00e4: Unknown result type (might be due to invalid IL or missing references)
					long num5 = ((corner2.Normal >= 0) ? (((long)corner2.Position * (long)(_normals.Count + 1) + corner2.Normal) * (_materialNames.Count + 1) + _faceMaterial[f] + 1) : (-1));
					if (num5 >= 0 && vertexOfCorner.TryGetValue(num5, out var value))
					{
						return value;
					}
					int count = vertices.Count;
					vertices.Add(((Matrix4x4)(ref fileToMesh)).MultiplyPoint3x4(_positions[corner2.Position]));
					List<Vector3> list5 = normals;
					Vector3 item;
					if (corner2.Normal < 0)
					{
						item = meshFaceNormal;
					}
					else
					{
						Vector3 val4 = ((Matrix4x4)(ref fileToMesh)).MultiplyVector(_normals[corner2.Normal]);
						item = ((Vector3)(ref val4)).normalized;
					}
					list5.Add(item);
					uvs.Add(uv);
					if (num5 >= 0)
					{
						vertexOfCorner[num5] = count;
					}
					return count;
				}
			}
			List<Vector4> list4 = new List<Vector4>(normals.Count);
			foreach (Vector3 item2 in normals)
			{
				list4.Add(MeshTangents.ForNormal(item2));
			}
			Mesh val3 = new Mesh
			{
				name = name
			};
			if (vertices.Count > 65535)
			{
				val3.indexFormat = (IndexFormat)1;
			}
			val3.SetVertices(vertices);
			val3.SetNormals(normals);
			val3.SetTangents(list4);
			val3.SetUVs(0, uvs);
			val3.subMeshCount = array.Length;
			for (int l = 0; l < array.Length; l++)
			{
				val3.SetTriangles(array[l], l);
			}
			val3.RecalculateBounds();
			return val3;
		}

		private void ParseLine(string line)
		{
			//IL_0052: 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)
			string[] array = line.Split(Whitespace, StringSplitOptions.RemoveEmptyEntries);
			if (array.Length != 0)
			{
				switch (array[0])
				{
				case "v":
					_positions.Add(ParseVector(array));
					break;
				case "vn":
					_normals.Add(ParseVector(array));
					break;
				case "f":
					ParseFace(array);
					break;
				case "usemtl":
					SetMaterial((array.Length > 1) ? array[1] : "");
					break;
				}
			}
		}

		private void SetMaterial(string materialName)
		{
			int num = _materialNames.IndexOf(materialName);
			if (num < 0)
			{
				num = _materialNames.Count;
				_materialNames.Add(materialName);
			}
			_currentMaterial = num;
		}

		private void ParseFace(string[] tokens)
		{
			if (tokens.Length >= 4)
			{
				if (_currentMaterial < 0)
				{
					SetMaterial("");
				}
				Corner[] array = new Corner[tokens.Length - 1];
				for (int i = 1; i < tokens.Length; i++)
				{
					string[] array2 = tokens[i].Split('/');
					int position = ResolveIndex(array2[0], _positions.Count);
					int normal = ((array2.Length > 2 && array2[2].Length > 0) ? ResolveIndex(array2[2], _normals.Count) : (-1));
					array[i - 1] = new Corner(position, normal);
				}
				_faces.Add(array);
				_faceMaterial.Add(_currentMaterial);
			}
		}

		private static Vector3 ParseVector(string[] tokens)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(ParseFloat(tokens[1]), ParseFloat(tokens[2]), ParseFloat(tokens[3]));
		}

		private static float ParseFloat(string token)
		{
			return float.Parse(token, NumberStyles.Float, CultureInfo.InvariantCulture);
		}

		private static int ResolveIndex(string token, int count)
		{
			int num = int.Parse(token, NumberStyles.Integer, CultureInfo.InvariantCulture);
			if (num >= 0)
			{
				return num - 1;
			}
			return count + num;
		}

		private void FindPartsAndBounds()
		{
			//IL_005f: 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_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			int[] array = new int[_positions.Count];
			bool[] array2 = new bool[_positions.Count];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = i;
			}
			Bounds bounds = default(Bounds);
			((Bounds)(ref bounds))..ctor(_positions[_faces[0][0].Position], Vector3.zero);
			foreach (Corner[] face in _faces)
			{
				for (int j = 0; j < face.Length; j++)
				{
					array2[face[j].Position] = true;
					((Bounds)(ref bounds)).Encapsulate(_positions[face[j].Position]);
					if (j > 0)
					{
						Union(array, face[0].Position, face[j].Position);
					}
				}
			}
			Bounds = bounds;
			Dictionary<int, int> sizes = new Dictionary<int, int>();
			for (int k = 0; k < array.Length; k++)
			{
				if (array2[k])
				{
					int key = Find(array, k);
					sizes.TryGetValue(key, out var value);
					sizes[key] = value + 1;
				}
			}
			List<int> list = new List<int>(sizes.Keys);
			list.Sort((int x, int y) => (sizes[x] == sizes[y]) ? x.CompareTo(y) : sizes[y].CompareTo(sizes[x]));
			Dictionary<int, int> dictionary = new Dictionary<int, int>();
			for (int num = 0; num < list.Count; num++)
			{
				dictionary[list[num]] = num;
			}
			_facePart = new int[_faces.Count];
			for (int num2 = 0; num2 < _faces.Count; num2++)
			{
				_facePart[num2] = dictionary[Find(array, _faces[num2][0].Position)];
			}
		}

		private static int Find(int[] parent, int i)
		{
			while (parent[i] != i)
			{
				parent[i] = parent[parent[i]];
				i = parent[i];
			}
			return i;
		}

		private static void Union(int[] parent, int a, int b)
		{
			a = Find(parent, a);
			b = Find(parent, b);
			if (a != b)
			{
				parent[b] = a;
			}
		}

		private static Vector3 NewellNormal(List<Vector3> polygon)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = Vector3.zero;
			Vector3 val2 = polygon[0];
			for (int i = 1; i < polygon.Count - 1; i++)
			{
				val += Vector3.Cross(polygon[i] - val2, polygon[i + 1] - val2);
			}
			if (!(((Vector3)(ref val)).sqrMagnitude > 1E-20f))
			{
				return Vector3.forward;
			}
			return ((Vector3)(ref val)).normalized;
		}

		private static void Triangulate(List<Vector3> polygon, Vector3 normal, List<int> result)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			result.Clear();
			int count = polygon.Count;
			if (count == 3)
			{
				result.Add(0);
				result.Add(1);
				result.Add(2);
				return;
			}
			Vector3 val = Vector3.Cross(normal, (Mathf.Abs(normal.x) < 0.9f) ? Vector3.right : Vector3.up);
			Vector3 normalized = ((Vector3)(ref val)).normalized;
			Vector3 val2 = Vector3.Cross(normal, normalized);
			Vector2[] array = (Vector2[])(object)new Vector2[count];
			List<int> list = new List<int>(count);
			for (int i = 0; i < count; i++)
			{
				array[i] = new Vector2(Vector3.Dot(polygon[i], normalized), Vector3.Dot(polygon[i], val2));
				list.Add(i);
			}
			while (list.Count > 3)
			{
				bool flag = false;
				for (int j = 0; j < list.Count; j++)
				{
					if (flag)
					{
						break;
					}
					int num = list[(j + list.Count - 1) % list.Count];
					int num2 = list[j];
					int num3 = list[(j + 1) % list.Count];
					if (!(Area2(array[num], array[num2], array[num3]) <= 0f) && !AnyInside(array, list, num, num2, num3))
					{
						result.Add(num);
						result.Add(num2);
						result.Add(num3);
						list.RemoveAt(j);
						flag = true;
					}
				}
				if (!flag)
				{
					break;
				}
			}
			for (int k = 1; k < list.Count - 1; k++)
			{
				result.Add(list[0]);
				result.Add(list[k]);
				result.Add(list[k + 1]);
			}
		}

		private static float Area2(Vector2 a, Vector2 b, Vector2 c)
		{
			//IL_0000: 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_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
		}

		private static bool AnyInside(Vector2[] points, List<int> remaining, int a, int b, int c)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: 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_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_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			foreach (int item in remaining)
			{
				if (item != a && item != b && item != c)
				{
					Vector2 c2 = points[item];
					if (Area2(points[a], points[b], c2) >= 0f && Area2(points[b], points[c], c2) >= 0f && Area2(points[c], points[a], c2) >= 0f)
					{
						return true;
					}
				}
			}
			return false;
		}
	}
	internal static class Palette
	{
		public static readonly Vector2 Wood = Uv(31, 21);

		public static readonly Vector2 Steel = Uv(31, 6);

		public static readonly Vector2 DarkSteel = Uv(31, 9);

		public static readonly Vector2 Parchment = Uv(31, 17);

		public static readonly Vector2 Ink = Uv(31, 24);

		public static readonly Vector2 DarkInk = Uv(31, 22);

		public static readonly Vector2 MarkRed = Uv(0, 1);

		public static readonly Vector2 MarkGreen = Uv(11, 1);

		public static readonly Vector2 PlayerBlue = Uv(19, 1);

		public static readonly Vector2 Brass = Uv(7, 9);

		public static readonly Vector2 Gold = Uv(7, 8);

		public static readonly Vector2 Glass = Uv(14, 9);

		public static readonly Vector2 Cork = Uv(31, 21);

		public static readonly Vector2 Paper = Uv(31, 17);

		public static readonly Vector2 Twine = Uv(31, 24);

		public static Vector2 Uv(int column, int row)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			return new Vector2(((float)column + 0.5f) / 32f, 1f - ((float)row + 0.5f) / 32f);
		}
	}
	internal static class TransformBounds
	{
		public static Bounds LocalTo(Transform target, Transform source, Bounds local)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: 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_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			Bounds result = default(Bounds);
			((Bounds)(ref result))..ctor(target.InverseTransformPoint(source.TransformPoint(((Bounds)(ref local)).min)), Vector3.zero);
			Vector3 val = default(Vector3);
			for (int i = 0; i < 8; i++)
			{
				((Vector3)(ref val))..ctor(((i & 1) == 0) ? ((Bounds)(ref local)).min.x : ((Bounds)(ref local)).max.x, ((i & 2) == 0) ? ((Bounds)(ref local)).min.y : ((Bounds)(ref local)).max.y, ((i & 4) == 0) ? ((Bounds)(ref local)).min.z : ((Bounds)(ref local)).max.z);
				((Bounds)(ref result)).Encapsulate(target.InverseTransformPoint(source.TransformPoint(val)));
			}
			return result;
		}
	}
}
namespace BuriedTreasures.Memo
{
	internal sealed class InkMeshBuilder
	{
		private const float MaxStep = 0.005f;

		private readonly MemoSheet _sheet;

		private readonly List<Vector3> _vertices = new List<Vector3>();

		private readonly List<Vector3> _normals = new List<Vector3>();

		private readonly List<Vector2> _uvs = new List<Vector2>();

		private readonly List<int> _triangles = new List<int>();

		public bool IsEmpty => _triangles.Count == 0;

		public InkMeshBuilder(MemoSheet sheet)
		{
			_sheet = sheet;
		}

		public void Clear()
		{
			_vertices.Clear();
			_normals.Clear();
			_uvs.Clear();
			_triangles.Clear();
		}

		public void Line(Vector2 a, Vector2 b, float width, float lift, Vector2 uv)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: 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_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: 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_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = b - a;
			float magnitude = ((Vector2)(ref val)).magnitude;
			if (!(magnitude < 1E-06f))
			{
				Vector2 val2 = new Vector2(0f - val.y, val.x) * (width * 0.5f / magnitude);
				int num = Mathf.Max(1, Mathf.CeilToInt(magnitude / 0.005f));
				int count = _vertices.Count;
				for (int i = 0; i <= num; i++)
				{
					Vector2 val3 = a + val * ((float)i / (float)num);
					AddDraped(val3 + val2, lift, uv);
					AddDraped(val3 - val2, lift, uv);
				}
				for (int j = 0; j < num; j++)
				{
					int num2 = count + 2 * j;
					AddTriangle(num2, num2 + 1, num2 + 3);
					AddTriangle(num2, num2 + 3, num2 + 2);
				}
			}
		}

		public void Polyline(IReadOnlyList<Vector2> points, float width, float lift, Vector2 uv)
		{
			//IL_0007: 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)
			for (int i = 0; i < points.Count - 1; i++)
			{
				Line(points[i], points[i + 1], width, lift, uv);
			}
		}

		public void Cross(Vector2 center, float size, float width, float lift, Vector2 uv)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: 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_0039: 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_0042: 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_004f: Unknown result type (might be due to invalid IL or missing references)
			float num = size * 0.5f;
			Line(center + new Vector2(0f - num, 0f - num), center + new Vector2(num, num), width, lift, uv);
			Line(center + new Vector2(0f - num, num), center + new Vector2(num, 0f - num), width, lift, uv);
		}

		public void Check(Vector2 center, float size, float width, float lift, Vector2 uv, float upSign)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			float num = size * 0.5f;
			Vector2[] points = (Vector2[])(object)new Vector2[3]
			{
				center + new Vector2(0f - num, 0f),
				center + new Vector2((0f - num) * 0.25f, (0f - num) * upSign),
				center + new Vector2(num, num * upSign)
			};
			Polyline(points, width, lift, uv);
		}

		public void Disc(float radius, Vector2 uv, int segments = 16)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			int count = _vertices.Count;
			AddVertex(Vector3.zero, uv);
			for (int i = 0; i < segments; i++)
			{
				float num = (float)i * MathF.PI * 2f / (float)segments;
				AddVertex(new Vector3(Mathf.Cos(num) * radius, Mathf.Sin(num) * radius, 0f), uv);
			}
			for (int j = 0; j < segments; j++)
			{
				AddTriangle(count, count + 1 + j, count + 1 + (j + 1) % segments);
			}
		}

		public void WriteTo(Mesh mesh)
		{
			//IL_0030: 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_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			mesh.Clear();
			if (IsEmpty)
			{
				return;
			}
			List<Vector4> list = new List<Vector4>(_normals.Count);
			foreach (Vector3 normal in _normals)
			{
				list.Add(MeshTangents.ForNormal(normal));
			}
			mesh.indexFormat = (IndexFormat)(_vertices.Count > 65535);
			mesh.SetVertices(_vertices);
			mesh.SetNormals(_normals);
			mesh.SetTangents(list);
			mesh.SetUVs(0, _uvs);
			mesh.SetTriangles(_triangles, 0);
			mesh.RecalculateBounds();
		}

		private void AddDraped(Vector2 point, float lift, Vector2 uv)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			AddVertex(new Vector3(point.x, point.y, _sheet.SurfaceZ(point) + lift), uv);
		}

		private void AddVertex(Vector3 position, Vector2 uv)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			_vertices.Add(position);
			_normals.Add(Vector3.forward);
			_uvs.Add(uv);
		}

		private void AddTriangle(int a, int b, int c)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: 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_003a: Unknown result type (might be due to invalid IL or missing references)
			if (Vector3.Cross(_vertices[b] - _vertices[a], _vertices[c] - _vertices[a]).z < 0f)
			{
				int num = c;
				c = b;
				b = num;
			}
			_triangles.Add(a);
			_triangles.Add(b);
			_triangles.Add(c);
		}
	}
	internal enum MemoMode
	{
		Blank,
		Map,
		Text,
		Coordinates
	}
	internal interface IWrittenMemo
	{
		string Text { get; }
	}
	internal abstract class MemoContent
	{
		public abstract MemoMode Mode { get; }

		public bool IsTreasureMap => Mode == MemoMode.Map;
	}
	internal static class MemoContentStore
	{
		private static readonly Dictionary<int, MemoContent> ByObject = new Dictionary<int, MemoContent>();

		public static int Revision { get; private set; }

		public static MemoContent Get(int objectId)
		{
			if (!ByObject.TryGetValue(objectId, out var value))
			{
				return null;
			}
			return value;
		}

		public static void Set(int objectId, MemoContent content)
		{
			ByObject.TryGetValue(objectId, out var value);
			if (value != content)
			{
				if (content == null)
				{
					ByObject.Remove(objectId);
				}
				else
				{
					ByObject[objectId] = content;
				}
				Revision++;
			}
		}

		public static KeyValuePair<int, MemoContent>[] Snapshot()
		{
			KeyValuePair<int, MemoContent>[] array = new KeyValuePair<int, MemoContent>[ByObject.Count];
			int num = 0;
			foreach (KeyValuePair<int, MemoContent> item in ByObject)
			{
				array[num++] = item;
			}
			return array;
		}

		public static void Clear()
		{
			if (ByObject.Count != 0)
			{
				ByObject.Clear();
				Revision++;
			}
		}
	}
	internal static class MemoDefinition
	{
		public const byte ItemId = 201;

		public const ushort SpawnableCollectionId = 201;

		public const ulong AssetPathHash = 5567941517325063237uL;

		public const string BaseItemKey = "map";

		public const string PrefabName = "Memo";

		public const string DisplayName = "Memo";
	}
	internal sealed class MemoDisplay : MonoBehaviour
	{
		private Item _item;

		private MeshFilter _grid;

		private MeshFilter _marks;

		private Transform _playerDot;

		private MeshFilter _memo;

		private Renderer _gridRenderer;

		private Renderer _marksRenderer;

		private Renderer _playerDotRenderer;

		private Renderer _memoRenderer;

		private InkMeshBuilder _gridBuilder;

		private InkMeshBuilder _marksBuilder;

		private InkMeshBuilder _memoBuilder;

		private Mesh _gridMesh;

		private Mesh _marksMesh;

		private Mesh _memoMesh;

		private string _text = string.Empty;

		private MemoContent _content;

		private int _appliedStoreRevision = -1;

		private int _spawnedObjectId = -1;

		private float _drawnTextHeight = -1f;

		private Rect _drawnWorld = Rect.zero;

		private float _drawnCellSize = -1f;

		private bool _drawnDrawIslands;

		private bool _gridDrawn;

		private int _drawnBuriedRevision = -1;

		private bool _marksDirty = true;

		private bool _memoDirty = true;

		private bool _ready;

		public MemoMode Mode { get; private set; }

		public MemoTreasureMap Map { get; private set; }

		private void SyncContent()
		{
			if (!((NetworkBehaviour)_item).IsSpawned)
			{
				return;
			}
			int objectId = ((NetworkBehaviour)_item).ObjectId;
			if (objectId == _spawnedObjectId && _appliedStoreRevision == MemoContentStore.Revision)
			{
				return;
			}
			_spawnedObjectId = objectId;
			_appliedStoreRevision = MemoContentStore.Revision;
			MemoContent memoContent = MemoContentStore.Get(objectId);
			if (memoContent != _content)
			{
				_content = memoContent;
				if (memoContent is MemoTreasureMap map)
				{
					Map = map;
					_text = string.Empty;
					Mode = MemoMode.Map;
					_marksDirty = true;
				}
				else if (memoContent is IWrittenMemo writtenMemo)
				{
					Map = null;
					_text = writtenMemo.Text;
					Mode = MemoMode.Text;
					_memoDirty = true;
				}
				else
				{
					Mode = MemoMode.Blank;
					Map = null;
					_text = string.Empty;
				}
			}
		}

		private void Awake()
		{
			//IL_00e8: Unknown result