Decompiled source of VanillaBarrelPlus v1.0.0

BepInEx/plugins/VanillaBarrelPlus/VanillaBarrelPlus.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Rendering;
using UnityEngine.UI;
using VanillaBarrelPlus.Barrel;
using VanillaBarrelPlus.Localization;
using VanillaBarrelPlus.UI;
using VanillaBarrelPlus.Visuals;

[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("VanillaBarrelPlus")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+627c93de35fe4ea8fc7db780adf6d890daf2a24a")]
[assembly: AssemblyProduct("VanillaBarrelPlus")]
[assembly: AssemblyTitle("VanillaBarrelPlus")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace VanillaBarrelPlus
{
	[BepInPlugin("dellarion.valheim.vanillabarrelplus", "VanillaBarrelPlus", "1.0.0")]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "dellarion.valheim.vanillabarrelplus";

		public const string PluginName = "VanillaBarrelPlus";

		public const string PluginVersion = "1.0.0";

		internal static ManualLogSource Log;

		private Harmony _harmony;

		internal static bool IsEnabled
		{
			get
			{
				if (Settings != null)
				{
					return Settings.Enabled;
				}
				return false;
			}
		}

		internal static bool UseFirstSlotItem
		{
			get
			{
				if (Settings != null)
				{
					return Settings.UseFirstSlotItem;
				}
				return false;
			}
		}

		internal static bool AlwaysDisplayContents
		{
			get
			{
				if (Settings != null)
				{
					return Settings.AlwaysDisplayContents;
				}
				return false;
			}
		}

		internal static ModConfig Settings { get; private set; }

		private void Awake()
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			Settings = new ModConfig(((BaseUnityPlugin)this).Config);
			Settings.Changed += OnSettingsChanged;
			LocalizationManager.Register();
			_harmony = new Harmony("dellarion.valheim.vanillabarrelplus");
			_harmony.PatchAll();
			if (IsEnabled)
			{
				BarrelContentsDisplay.AttachToExistingBarrels();
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)"VanillaBarrelPlus 1.0.0 loaded! Mesh-only full piles; barrel prefab=piece_chest_barrel");
		}

		private void OnDestroy()
		{
			if (Settings != null)
			{
				Settings.Changed -= OnSettingsChanged;
			}
			BarrelDisplayToggle.Clear();
			BarrelContentsDisplay.RemoveAllDisplays();
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			Settings = null;
		}

		private void OnSettingsChanged()
		{
			if (IsEnabled)
			{
				BarrelContentsDisplay.AttachToExistingBarrels();
				BarrelContentsDisplay.RequestAllRefreshes();
			}
			else
			{
				BarrelDisplayToggle.Clear();
				BarrelContentsDisplay.RemoveAllDisplays();
			}
		}
	}
	internal sealed class ModConfig
	{
		private readonly ConfigEntry<bool> _enabled;

		private readonly ConfigEntry<bool> _firstSlotItem;

		private readonly ConfigEntry<bool> _alwaysDisplayContents;

		internal bool Enabled => _enabled.Value;

		internal bool UseFirstSlotItem => _firstSlotItem.Value;

		internal bool AlwaysDisplayContents => _alwaysDisplayContents.Value;

		internal event Action Changed;

		internal ModConfig(ConfigFile config)
		{
			MigrateBooleanSettings(config);
			_enabled = config.Bind<bool>("General", "Enabled", true, "Enables or disables VanillaBarrelPlus.");
			_firstSlotItem = config.Bind<bool>("Display Selection", "First Slot Item", false, "Checked: display the first occupied barrel slot. Unchecked: display the item with the largest total stack count.");
			_alwaysDisplayContents = config.Bind<bool>("Display Contents", "Always Enabled", false, "Checked: force contents display on for every barrel. Unchecked: use each barrel's saved Display Contents checkbox.");
			_enabled.SettingChanged += ForwardChange;
			_firstSlotItem.SettingChanged += ForwardChange;
			_alwaysDisplayContents.SettingChanged += ForwardChange;
		}

		private static void MigrateBooleanSettings(ConfigFile config)
		{
			if (!File.Exists(config.ConfigFilePath))
			{
				return;
			}
			string[] array = File.ReadAllLines(config.ConfigFilePath);
			string text = string.Empty;
			bool flag = false;
			for (int i = 0; i < array.Length; i++)
			{
				string text2 = array[i].Trim();
				if (text2.StartsWith("[", StringComparison.Ordinal) && text2.EndsWith("]", StringComparison.Ordinal))
				{
					text = text2.Substring(1, text2.Length - 2).Trim();
					continue;
				}
				int num = array[i].IndexOf('=');
				if (num < 0)
				{
					continue;
				}
				string text3 = array[i].Substring(0, num).Trim();
				if ((!text.Equals("General", StringComparison.Ordinal) || !(text3 == "Enabled")) && (!text.Equals("Display Selection", StringComparison.Ordinal) || !(text3 == "First Slot Item")) && (!text.Equals("Display Contents", StringComparison.Ordinal) || !(text3 == "Always Enabled")))
				{
					continue;
				}
				string text4 = array[i].Substring(num + 1).Trim();
				string text5;
				if (text4 == "1" || text4.Equals("Enabled", StringComparison.OrdinalIgnoreCase))
				{
					text5 = "true";
				}
				else
				{
					if (!(text4 == "0") && !text4.Equals("Disabled", StringComparison.OrdinalIgnoreCase))
					{
						continue;
					}
					text5 = "false";
				}
				array[i] = array[i].Substring(0, num + 1) + " " + text5;
				flag = true;
			}
			if (flag)
			{
				File.WriteAllLines(config.ConfigFilePath, array);
				config.Reload();
			}
		}

		private void ForwardChange(object sender, EventArgs args)
		{
			this.Changed?.Invoke();
		}
	}
}
namespace VanillaBarrelPlus.Visuals
{
	internal sealed class BarrelLidVisual
	{
		private sealed class LidRenderer
		{
			internal Renderer Renderer;

			internal bool OriginalForceOff;
		}

		private const float PileInsetFraction = 0.08f;

		private static readonly string[] LidPaths = new string[4] { "New/Closed/blackmetalchesttop_closed", "New/Closed/blackmetalchesttop_closedLOD", "New/Open/blackmetalchesttop_open", "New/Open/blackmetalchesttop_openLOD" };

		private readonly List<LidRenderer> _lids = new List<LidRenderer>();

		private bool _hidden;

		internal Vector3 Anchor { get; private set; }

		internal float MouthDiameter { get; private set; }

		internal bool HasSurface { get; private set; }

		internal BarrelLidVisual(Container container)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: 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_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_0293: 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_00aa: 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_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: 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)
			Transform transform = ((Component)container).transform;
			Bounds val = default(Bounds);
			bool flag = false;
			for (int i = 0; i < LidPaths.Length; i++)
			{
				Transform val2 = transform.Find(LidPaths[i]);
				Renderer val3 = (Renderer)(object)(((Object)(object)val2 != (Object)null) ? ((Component)val2).GetComponent<MeshRenderer>() : null);
				if ((Object)(object)val3 == (Object)null || !MeshBounds.TryGet(val3, transform, out var bounds))
				{
					continue;
				}
				MeshFilter component = ((Component)val3).GetComponent<MeshFilter>();
				Vector3 val4;
				if (!((Object)(object)component != (Object)null) || !((Object)(object)component.sharedMesh != (Object)null))
				{
					val4 = Vector3.zero;
				}
				else
				{
					Bounds bounds2 = component.sharedMesh.bounds;
					val4 = ((Bounds)(ref bounds2)).size;
				}
				Vector3 val5 = val4;
				if (!(val5.y <= 0f) && !(val5.y > Mathf.Min(val5.x, val5.z) * 0.25f))
				{
					_lids.Add(new LidRenderer
					{
						Renderer = val3
					});
					if (i < 2 && !flag)
					{
						val = bounds;
						flag = true;
					}
				}
			}
			if (flag)
			{
				float num = (MouthDiameter = Mathf.Min(((Bounds)(ref val)).size.x, ((Bounds)(ref val)).size.z));
				Anchor = new Vector3(((Bounds)(ref val)).center.x, ((Bounds)(ref val)).max.y - num * 0.055f - MouthDiameter * 0.08f, ((Bounds)(ref val)).center.z);
				HasSurface = MouthDiameter > 0.1f;
				return;
			}
			_lids.Clear();
			Bounds val6 = default(Bounds);
			bool flag2 = false;
			string[] array = new string[2] { "New/blackmetalchest", "New/blackmetalchestLOD" };
			foreach (string text in array)
			{
				Transform val7 = transform.Find(text);
				Renderer val8 = (Renderer)(object)(((Object)(object)val7 != (Object)null) ? ((Component)val7).GetComponent<MeshRenderer>() : null);
				if (!((Object)(object)val8 == (Object)null) && MeshBounds.TryGet(val8, transform, out var bounds3))
				{
					if (!flag2)
					{
						val6 = bounds3;
						flag2 = true;
					}
					else
					{
						((Bounds)(ref val6)).Encapsulate(bounds3);
					}
				}
			}
			if (flag2)
			{
				MouthDiameter = Mathf.Min(((Bounds)(ref val6)).size.x, ((Bounds)(ref val6)).size.z) * 0.65f;
				Anchor = new Vector3(((Bounds)(ref val6)).center.x, ((Bounds)(ref val6)).max.y + 0.01f - MouthDiameter * 0.08f, ((Bounds)(ref val6)).center.z);
				HasSurface = MouthDiameter > 0.1f;
			}
			VisualDiagnostics.WarnOnce("barrel-lid", "Separate barrel lid renderer not found; keeping the original model and placing the pile on top.");
		}

		internal void Hide()
		{
			foreach (LidRenderer lid in _lids)
			{
				if (!((Object)(object)lid.Renderer == (Object)null))
				{
					if (!_hidden)
					{
						lid.OriginalForceOff = lid.Renderer.forceRenderingOff;
					}
					lid.Renderer.forceRenderingOff = true;
				}
			}
			_hidden = true;
		}

		internal void Restore()
		{
			if (!_hidden)
			{
				return;
			}
			foreach (LidRenderer lid in _lids)
			{
				if ((Object)(object)lid.Renderer != (Object)null)
				{
					lid.Renderer.forceRenderingOff = lid.OriginalForceOff;
				}
			}
			_hidden = false;
		}
	}
	internal sealed class ItemVisualTemplate : IDisposable
	{
		private readonly List<Mesh> _bakedMeshes = new List<Mesh>();

		private readonly Dictionary<Transform, Transform> _nodes = new Dictionary<Transform, Transform>();

		private bool _hasBounds;

		private bool _staticVegetation;

		private MaterialPropertyBlock _staticBlock;

		internal static readonly string[] MotionProperties = new string[6] { "_SwayDistance", "_SwaySpeed", "_RippleDistance", "_RippleSpeed", "_PushDistance", "_PushClothMode" };

		internal GameObject Root { get; private set; }

		internal Bounds Bounds { get; private set; }

		internal List<Vector3[]> MeshVertices { get; } = new List<Vector3[]>();

		internal List<Bounds> MeshPartBounds { get; } = new List<Bounds>();

		internal static bool TryCreate(GameObject prefab, out ItemVisualTemplate template)
		{
			template = new ItemVisualTemplate();
			try
			{
				template.Build(prefab);
				if (template._hasBounds)
				{
					return true;
				}
			}
			catch (Exception ex)
			{
				VisualDiagnostics.WarnOnce("mesh:" + ((Object)prefab).name, "Could not copy the visual mesh of " + ((Object)prefab).name + ": " + ex.Message);
			}
			template.Dispose();
			template = null;
			return false;
		}

		private void Build(GameObject prefab)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Expected O, but got Unknown
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Expected O, but got Unknown
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0264: Unknown result type (might be due to invalid IL or missing references)
			//IL_0288: Unknown result type (might be due to invalid IL or missing references)
			//IL_028d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0292: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0300: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
			_staticVegetation = ((Object)prefab).name.Equals("Barley", StringComparison.OrdinalIgnoreCase) || PileLayout.IsWoodResource(((Object)prefab).name);
			Root = new GameObject("VBP_VisualTemplate");
			Root.SetActive(false);
			HashSet<Renderer> hashSet = new HashSet<Renderer>();
			HashSet<Renderer> hashSet2 = new HashSet<Renderer>();
			LODGroup[] componentsInChildren = prefab.GetComponentsInChildren<LODGroup>(true);
			Renderer[] renderers;
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				LOD[] lODs = componentsInChildren[i].GetLODs();
				for (int j = 0; j < lODs.Length; j++)
				{
					renderers = lODs[j].renderers;
					foreach (Renderer val in renderers)
					{
						if (!((Object)(object)val == (Object)null))
						{
							if (j == 0)
							{
								hashSet2.Add(val);
							}
							else
							{
								hashSet.Add(val);
							}
						}
					}
				}
			}
			hashSet.ExceptWith(hashSet2);
			renderers = prefab.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val2 in renderers)
			{
				if (hashSet.Contains(val2) || !IsActiveVisual(((Component)val2).transform, prefab.transform) || (!val2.enabled && !hashSet2.Contains(val2)))
				{
					continue;
				}
				SkinnedMeshRenderer val3 = (SkinnedMeshRenderer)(object)((val2 is SkinnedMeshRenderer) ? val2 : null);
				Mesh val4;
				if (val3 != null && (Object)(object)val3.sharedMesh != (Object)null)
				{
					val4 = new Mesh
					{
						name = "VBP_Baked_" + ((Object)val3.sharedMesh).name
					};
					_bakedMeshes.Add(val4);
					val3.BakeMesh(val4);
				}
				else
				{
					if (!(val2 is MeshRenderer))
					{
						continue;
					}
					MeshFilter component = ((Component)val2).GetComponent<MeshFilter>();
					val4 = (((Object)(object)component != (Object)null) ? component.sharedMesh : null);
				}
				if (!((Object)(object)val4 == (Object)null) && val2.sharedMaterials.Length != 0)
				{
					Transform val5 = CopyTransform(((Component)val2).transform, prefab.transform);
					GameObject val6 = new GameObject("VBP_Mesh");
					val6.transform.SetParent(val5, false);
					val6.AddComponent<MeshFilter>().sharedMesh = val4;
					MeshRenderer obj = val6.AddComponent<MeshRenderer>();
					((Renderer)obj).sharedMaterials = val2.sharedMaterials;
					((Renderer)obj).shadowCastingMode = val2.shadowCastingMode;
					((Renderer)obj).receiveShadows = val2.receiveShadows;
					((Renderer)obj).lightProbeUsage = (LightProbeUsage)1;
					Matrix4x4 matrix = Root.transform.worldToLocalMatrix * val6.transform.localToWorldMatrix;
					Bounds val7 = MeshBounds.Transform(val4.bounds, matrix);
					Vector3[] array = (Vector3[])MeshVertexReader.Read(val4).Clone();
					for (int l = 0; l < array.Length; l++)
					{
						array[l] = ((Matrix4x4)(ref matrix)).MultiplyPoint3x4(array[l]);
					}
					MeshVertices.Add(array);
					MeshPartBounds.Add(val7);
					if (!_hasBounds)
					{
						Bounds = val7;
						Vector3 size = ((Bounds)(ref val7)).size;
						_hasBounds = ((Vector3)(ref size)).sqrMagnitude > 1E-06f;
					}
					else
					{
						Bounds bounds = Bounds;
						((Bounds)(ref bounds)).Encapsulate(val7);
						Bounds = bounds;
					}
				}
			}
		}

		private Transform CopyTransform(Transform source, Transform prefabRoot)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			if (_nodes.TryGetValue(source, out var value))
			{
				return value;
			}
			Transform val = (((Object)(object)source == (Object)(object)prefabRoot) ? Root.transform : CopyTransform(source.parent, prefabRoot));
			GameObject val2 = new GameObject(((Object)source).name);
			val2.transform.SetParent(val, false);
			val2.transform.localPosition = (((Object)(object)source == (Object)(object)prefabRoot) ? Vector3.zero : source.localPosition);
			val2.transform.localRotation = source.localRotation;
			val2.transform.localScale = source.localScale;
			_nodes.Add(source, val2.transform);
			return val2.transform;
		}

		private static bool IsActiveVisual(Transform node, Transform root)
		{
			while ((Object)(object)node != (Object)null && (Object)(object)node != (Object)(object)root)
			{
				if (!((Component)node).gameObject.activeSelf || !IncludeVisualNode(((Object)root).name, ((Object)node).name))
				{
					return false;
				}
				node = node.parent;
			}
			return (Object)(object)node == (Object)(object)root;
		}

		internal static bool IncludeVisualNode(string prefabName, string nodeName)
		{
			if (nodeName.Equals("equipoffset", StringComparison.OrdinalIgnoreCase))
			{
				return false;
			}
			if (prefabName.Equals("Carrot", StringComparison.OrdinalIgnoreCase) || prefabName.Equals("Turnip", StringComparison.OrdinalIgnoreCase))
			{
				return !nodeName.StartsWith("blast", StringComparison.OrdinalIgnoreCase);
			}
			return true;
		}

		internal void ApplyVisualOverrides(GameObject visual)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			if (!_staticVegetation)
			{
				return;
			}
			if (_staticBlock == null)
			{
				_staticBlock = new MaterialPropertyBlock();
				string[] motionProperties = MotionProperties;
				foreach (string text in motionProperties)
				{
					_staticBlock.SetFloat(text, 0f);
				}
			}
			Renderer[] componentsInChildren = visual.GetComponentsInChildren<Renderer>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				componentsInChildren[i].SetPropertyBlock(_staticBlock);
			}
		}

		public void Dispose()
		{
			if ((Object)(object)Root != (Object)null)
			{
				Root.SetActive(false);
				Object.Destroy((Object)(object)Root);
				Root = null;
			}
			foreach (Mesh bakedMesh in _bakedMeshes)
			{
				if ((Object)(object)bakedMesh != (Object)null)
				{
					Object.Destroy((Object)(object)bakedMesh);
				}
			}
			_bakedMeshes.Clear();
		}
	}
	internal static class MeshBounds
	{
		internal static Bounds Transform(Bounds source, Matrix4x4 matrix)
		{
			//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_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: 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_0028: 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_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: 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_005e: 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_0065: 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_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			Vector3 center = ((Bounds)(ref source)).center;
			Vector3 extents = ((Bounds)(ref source)).extents;
			Bounds result = default(Bounds);
			((Bounds)(ref result))..ctor(((Matrix4x4)(ref matrix)).MultiplyPoint3x4(center), Vector3.zero);
			for (int i = 0; i < 8; i++)
			{
				Vector3 val = center + new Vector3(((i & 1) == 0) ? (0f - extents.x) : extents.x, ((i & 2) == 0) ? (0f - extents.y) : extents.y, ((i & 4) == 0) ? (0f - extents.z) : extents.z);
				((Bounds)(ref result)).Encapsulate(((Matrix4x4)(ref matrix)).MultiplyPoint3x4(val));
			}
			return result;
		}

		internal static bool TryGet(Renderer renderer, Transform relativeTo, out Bounds bounds)
		{
			//IL_0040: 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_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			Mesh val = null;
			MeshFilter component = ((Component)renderer).GetComponent<MeshFilter>();
			if ((Object)(object)component != (Object)null)
			{
				val = component.sharedMesh;
			}
			else
			{
				SkinnedMeshRenderer val2 = (SkinnedMeshRenderer)(object)((renderer is SkinnedMeshRenderer) ? renderer : null);
				if (val2 != null)
				{
					val = val2.sharedMesh;
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				bounds = default(Bounds);
				return false;
			}
			bounds = Transform(val.bounds, relativeTo.worldToLocalMatrix * ((Component)renderer).transform.localToWorldMatrix);
			Vector3 size = ((Bounds)(ref bounds)).size;
			return ((Vector3)(ref size)).sqrMagnitude > 1E-06f;
		}
	}
	internal static class MeshVertexReader
	{
		private sealed class Cached
		{
			internal Vector3[] Points;
		}

		private static readonly ConditionalWeakTable<Mesh, Cached> Cache = new ConditionalWeakTable<Mesh, Cached>();

		internal static Vector3[] Read(Mesh mesh)
		{
			return Cache.GetValue(mesh, ReadUncached).Points;
		}

		private unsafe static Cached ReadUncached(Mesh mesh)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//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)
			//IL_003d: 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_0040: Invalid comparison between Unknown and I4
			//IL_004a: 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_0071: 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_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (mesh.isReadable)
				{
					return new Cached
					{
						Points = mesh.vertices
					};
				}
				VertexAttribute val = (VertexAttribute)0;
				if (!mesh.HasVertexAttribute(val))
				{
					throw new InvalidOperationException("No positions");
				}
				VertexAttributeFormat vertexAttributeFormat = mesh.GetVertexAttributeFormat(val);
				bool flag = (int)vertexAttributeFormat == 1;
				if ((!flag && (int)vertexAttributeFormat != 0) || mesh.GetVertexAttributeDimension(val) < 3)
				{
					throw new InvalidOperationException("Unsupported position format: " + ((object)(*(VertexAttributeFormat*)(&vertexAttributeFormat))/*cast due to .constrained prefix*/).ToString());
				}
				int vertexAttributeStream = mesh.GetVertexAttributeStream(val);
				int vertexBufferStride = mesh.GetVertexBufferStride(vertexAttributeStream);
				int vertexAttributeOffset = mesh.GetVertexAttributeOffset(val);
				int num = checked(mesh.vertexCount * vertexBufferStride);
				if (num <= 0 || num > 33554432)
				{
					throw new InvalidOperationException("Unexpected vertex buffer size");
				}
				byte[] array = new byte[num];
				GraphicsBuffer vertexBuffer = mesh.GetVertexBuffer(vertexAttributeStream);
				try
				{
					if (vertexBuffer == null)
					{
						throw new InvalidOperationException("No GPU vertex buffer");
					}
					vertexBuffer.GetData((Array)array);
				}
				finally
				{
					((IDisposable)vertexBuffer)?.Dispose();
				}
				Vector3[] array2 = Decode(array, mesh.vertexCount, vertexBufferStride, vertexAttributeOffset, flag);
				Bounds bounds = mesh.bounds;
				Vector3 size = ((Bounds)(ref bounds)).size;
				((Bounds)(ref bounds)).Expand(Mathf.Max(0.001f, ((Vector3)(ref size)).magnitude * 0.01f));
				Vector3[] array3 = array2;
				foreach (Vector3 val2 in array3)
				{
					if (!((Bounds)(ref bounds)).Contains(val2))
					{
						throw new InvalidOperationException("Vertex outside declared bounds");
					}
				}
				VisualDiagnostics.InfoOnce("gpu-mesh:" + ((Object)mesh).GetInstanceID(), "Read GPU vertices for " + ((Object)mesh).name + ": " + array2.Length);
				return new Cached
				{
					Points = array2
				};
			}
			catch (Exception ex)
			{
				VisualDiagnostics.WarnOnce("mesh-bounds:" + ((Object)mesh).GetInstanceID(), "Using conservative bounds for " + ((Object)mesh).name + ": " + ex.Message);
				return new Cached
				{
					Points = Array.Empty<Vector3>()
				};
			}
		}

		internal static Vector3[] Decode(byte[] bytes, int count, int stride, int offset, bool half)
		{
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			int num = (half ? 2 : 4);
			if (count < 0 || stride < num * 3 || offset < 0 || offset > stride - num * 3 || (long)count * (long)stride > bytes.Length)
			{
				throw new ArgumentException("Invalid vertex layout");
			}
			Vector3[] array = (Vector3[])(object)new Vector3[count];
			for (int i = 0; i < count; i++)
			{
				int num2 = i * stride + offset;
				float num3 = ReadFloat(bytes, num2, half);
				float num4 = ReadFloat(bytes, num2 + num, half);
				float num5 = ReadFloat(bytes, num2 + num * 2, half);
				if (float.IsNaN(num3) || float.IsInfinity(num3) || float.IsNaN(num4) || float.IsInfinity(num4) || float.IsNaN(num5) || float.IsInfinity(num5))
				{
					throw new ArgumentException("Non-finite vertex");
				}
				array[i] = new Vector3(num3, num4, num5);
			}
			return array;
		}

		private static float ReadFloat(byte[] bytes, int offset, bool half)
		{
			if (!half)
			{
				return BitConverter.ToSingle(bytes, offset);
			}
			ushort num = BitConverter.ToUInt16(bytes, offset);
			int num2 = (num >> 10) & 0x1F;
			int num3 = num & 0x3FF;
			float num4 = num2 switch
			{
				31 => (num3 == 0) ? float.PositiveInfinity : float.NaN, 
				0 => (float)num3 * 5.9604645E-08f, 
				_ => (float)Math.Pow(2.0, num2 - 15) * (1f + (float)num3 / 1024f), 
			};
			if ((num & 0x8000) == 0)
			{
				return num4;
			}
			return 0f - num4;
		}
	}
	internal struct PileFit
	{
		internal Vector3 Position;

		internal float ScaleFactor;
	}
	internal static class PileGeometry
	{
		internal static PileFit Fit(Vector3[] vertices, Vector3 desired, float radius, float top, float underlayDropLimit)
		{
			//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_0017: 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_0045: 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_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_0087: 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_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: 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)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: 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_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			Vector3[] array = (Vector3[])vertices.Clone();
			Bounds val = Measure(array);
			Vector3 val2 = default(Vector3);
			((Vector3)(ref val2))..ctor(((Bounds)(ref val)).center.x, 0f, ((Bounds)(ref val)).center.z);
			for (int i = 0; i < array.Length; i++)
			{
				ref Vector3 reference = ref array[i];
				reference -= val2;
			}
			float num = CenteredRadius(array);
			float num2 = ((num > radius) ? (radius / num) : 1f);
			for (int j = 0; j < array.Length; j++)
			{
				ref Vector3 reference2 = ref array[j];
				reference2 *= num2;
			}
			float num3 = Mathf.Sqrt(desired.x * desired.x + desired.z * desired.z);
			Vector3 val3 = ((num3 > 1E-05f) ? (desired / num3) : Vector3.right);
			val3.y = 0f;
			float num4 = EdgeDistance(array, val3, radius);
			float num5 = Mathf.Clamp01(num3 / radius);
			top -= Mathf.Min(((Bounds)(ref val)).size.y * num2 * 0.22f, underlayDropLimit);
			return new PileFit
			{
				Position = val3 * (num4 * num5) - val2 * num2 + new Vector3(0f, top - ((Bounds)(ref val)).max.y * num2, 0f),
				ScaleFactor = num2
			};
		}

		internal static Vector3[] TransformVertices(IList<Vector3[]> meshes, IList<Bounds> parts, Bounds fallback, Vector3 pivot, Matrix4x4 rotation, float scale)
		{
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: 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_0054: 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_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: 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_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			List<Vector3> list = new List<Vector3>();
			int num = Mathf.Max(1, parts?.Count ?? 0);
			for (int i = 0; i < num; i++)
			{
				Vector3[] array = ((meshes != null && i < meshes.Count) ? meshes[i] : null);
				if (array != null && array.Length != 0)
				{
					Vector3[] array2 = array;
					foreach (Vector3 val in array2)
					{
						list.Add(((Matrix4x4)(ref rotation)).MultiplyPoint3x4(val + pivot) * scale);
					}
				}
				else
				{
					Bounds val2 = ((parts != null && i < parts.Count) ? parts[i] : fallback);
					for (int k = 0; k < 8; k++)
					{
						Vector3 val3 = ((Bounds)(ref val2)).center + new Vector3(((k & 1) == 0) ? (0f - ((Bounds)(ref val2)).extents.x) : ((Bounds)(ref val2)).extents.x, ((k & 2) == 0) ? (0f - ((Bounds)(ref val2)).extents.y) : ((Bounds)(ref val2)).extents.y, ((k & 4) == 0) ? (0f - ((Bounds)(ref val2)).extents.z) : ((Bounds)(ref val2)).extents.z);
						list.Add(((Matrix4x4)(ref rotation)).MultiplyPoint3x4(val3 + pivot) * scale);
					}
				}
			}
			return list.ToArray();
		}

		internal static Bounds Measure(Vector3[] points)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: 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)
			Bounds result = default(Bounds);
			((Bounds)(ref result))..ctor(points[0], Vector3.zero);
			for (int i = 1; i < points.Length; i++)
			{
				((Bounds)(ref result)).Encapsulate(points[i]);
			}
			return result;
		}

		internal static float EdgeDistance(Vector3[] points, Vector3 direction, float radius)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			float num = radius;
			foreach (Vector3 val in points)
			{
				float num2 = val.x * direction.x + val.z * direction.z;
				float num3 = Mathf.Max(0f, val.x * val.x + val.z * val.z - num2 * num2);
				float num4 = Mathf.Sqrt(Mathf.Max(0f, radius * radius - num3)) - num2;
				num = Mathf.Min(num, num4);
			}
			return Mathf.Max(0f, num);
		}

		internal static float CenteredRadius(Vector3[] points)
		{
			//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_0015: 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_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			float num = 0f;
			foreach (Vector3 val in points)
			{
				num = Mathf.Max(num, val.x * val.x + val.z * val.z);
			}
			return Mathf.Sqrt(num);
		}
	}
	internal sealed class PileItemTuning
	{
		internal int? UpperCopies;

		internal int? OuterCopies;

		internal int? MiddleCopies;

		internal int? EdgeCopies;

		internal float ScaleMultiplier = 1f;

		internal float MaximumScale = 1f;

		internal float MaximumFootprint = 0.46f;

		internal float RadialSpread = 1f;

		internal float SurfaceHeight = 0.34f;

		internal bool AlternatingVertical;

		internal bool Calibrated;

		internal bool Upright;

		internal bool LayFlat;

		internal float PreferredScale = 1f;

		internal float RelativeScale;

		internal float MaximumHeight = 1.15f;

		internal float PackedTilt = 10f;

		internal float SurfaceLift;

		internal float HeightFactor = 1f;

		internal float MoundHeight;

		internal float HeightVariation = 0.012f;

		internal float CoverageLayers = 1f;

		internal float OverlapPenalty = 0.32f;

		internal float TiltBias = 1f;

		internal uint VariantSalt;

		internal bool PreservePreferredScale;

		internal float ScaleVariation;

		internal float PositionVariation;

		internal float MaximumProjectionOverlap = 1f;

		internal bool AnchorToBottom;

		internal float BottomHeight = 0.04f;

		internal int RimFirstCopies;

		internal Vector3 RotationOffset = Vector3.zero;

		internal Vector3 RotationJitterScale = Vector3.one;

		internal Dictionary<int, Vector3> UpperPositionOffsets = new Dictionary<int, Vector3>();

		internal Dictionary<int, Vector3> EdgePositionOffsets = new Dictionary<int, Vector3>();

		internal Dictionary<int, Vector3> PerCopyRotationOffsets = new Dictionary<int, Vector3>();

		private static readonly PileItemTuning Default = new PileItemTuning();

		private static readonly PileItemTuning Meat = MeatProfile(10, 5);

		private static readonly PileItemTuning Hide = HideProfile(dense: false);

		private static readonly PileItemTuning Ore = Packed(10, 5, 1f, 0.73f, 18f);

		private static readonly PileItemTuning Scrap = Packed(14, 8, 1f, 0.52f, 18f);

		private static readonly PileItemTuning Ballista = BallistaProfile();

		private static readonly PileItemTuning Wood = WoodProfile();

		private static readonly Dictionary<string, PileItemTuning> Overrides = new Dictionary<string, PileItemTuning>(StringComparer.OrdinalIgnoreCase)
		{
			["Lingonberry"] = new PileItemTuning
			{
				UpperCopies = 10,
				OuterCopies = 8,
				MiddleCopies = 1,
				EdgeCopies = 8,
				RotationJitterScale = new Vector3(0.6f, 1f, 0.2f)
			},
			["Raspberry"] = new PileItemTuning
			{
				UpperCopies = 12,
				OuterCopies = 8,
				MiddleCopies = 3,
				EdgeCopies = 8,
				RadialSpread = 1.12f,
				SurfaceHeight = 0.32f,
				RotationJitterScale = new Vector3(0.5f, 1f, 0.2f)
			},
			["Strawberry"] = new PileItemTuning
			{
				UpperCopies = 12,
				OuterCopies = 8,
				MiddleCopies = 3,
				EdgeCopies = 8,
				RadialSpread = 1.12f,
				SurfaceHeight = 0.32f,
				RotationJitterScale = new Vector3(0.5f, 1f, 0.2f)
			},
			["Vineberry"] = new PileItemTuning
			{
				UpperCopies = 12,
				OuterCopies = 8,
				MiddleCopies = 3,
				EdgeCopies = 8,
				Calibrated = true,
				PreferredScale = 1f,
				MaximumFootprint = 0.64f,
				PackedTilt = 10f,
				SurfaceHeight = 0.26f,
				RotationJitterScale = new Vector3(0.5f, 1f, 0.12f)
			},
			["Blueberries"] = new PileItemTuning
			{
				UpperCopies = 10,
				OuterCopies = 8,
				MiddleCopies = 1,
				EdgeCopies = 8,
				RotationJitterScale = new Vector3(0.6f, 1f, 0.2f)
			},
			["Cloudberry"] = RoundedProduce(),
			["Onion"] = ProduceProfile(),
			["Poteitr"] = ProduceProfile(),
			["Carrot"] = CarrotProfile(),
			["Mushroom"] = UprightMushroom(),
			["MushroomYellow"] = UprightMushroom(),
			["MushroomBlue"] = UprightMushroom(),
			["MushroomMagecap"] = UprightMushroom(),
			["MushroomJotunPuffs"] = new PileItemTuning(),
			["MushroomBzerker"] = UprightMushroom(),
			["MushroomSmokePuff"] = UprightMushroom(),
			["Dandelion"] = new PileItemTuning
			{
				UpperCopies = 24,
				OuterCopies = 16,
				MiddleCopies = 6,
				EdgeCopies = 16,
				RotationJitterScale = new Vector3(0.7f, 1f, 0.45f)
			},
			["Thistle"] = new PileItemTuning
			{
				UpperCopies = 32,
				OuterCopies = 22,
				MiddleCopies = 8,
				EdgeCopies = 22,
				RotationJitterScale = new Vector3(0.8f, 1f, 0.35f)
			},
			["Root"] = Packed(10, 5, 1f, 0.66f, 18f),
			["KaleSeeds"] = KaleSeedsProfile(),
			["WrithanRoots"] = Vertical(18, 10, 1f, 18f, alternate: true),
			["Needle"] = Vertical(36, 20, 1f, 15f),
			["CharredBone"] = RaisedBone(9f),
			["WitheredBone"] = RaisedBone(7f),
			["RottenMeat"] = Vertical(12, 6, 1f, 10f, alternate: true),
			["Fiddleheadfern"] = Packed(12, 6, 1f, 0.65f, 12f),
			["Charredskull"] = Packed(10, 5, 1f, 0.5f, 18f),
			["FrostCore"] = RimResource(18, 12, 0.64f, 16f, 10),
			["LeatherScraps"] = RimResource(28, 18, 0.46f, 20f, 12),
			["JuteBlue"] = Jute(),
			["JuteRed"] = Jute(),
			["Turnip"] = RaisedProduce(),
			["Barley"] = BarleyProfile(),
			["BoarJerky"] = LoweredMound(14, 7, 0.6f, 8f, 0.9f),
			["WolfJerky"] = LoweredMound(12, 6, 0.6f, 8f, 0.9f),
			["BjornMeat"] = MeatProfile(7, 4),
			["CookedBjornMeat"] = MeatProfile(7, 4),
			["ChickenMeat"] = ChickenProfile(),
			["CookedChickenMeat"] = ChickenProfile(),
			["DeerHide"] = DeerHideProfile(),
			["WolfPelt"] = HideProfile(dense: true),
			["TinOre"] = Packed(10, 5, 1f, 0.66f, 18f),
			["RawMeat"] = ReshuffledMeat(413609793u),
			["CookedMeat"] = ReshuffledMeat(852078701u),
			["LoxMeat"] = ReshuffledMeat(1222318451u),
			["CookedLoxMeat"] = ReshuffledMeat(1780384693u),
			["NeckTail"] = Vertical(16, 8, 1f, 12f, alternate: true),
			["NeckTailGrilled"] = Vertical(16, 8, 1f, 12f, alternate: true),
			["VoltureMeat"] = Vertical(14, 8, 1f, 12f, alternate: true),
			["CookedVoltureMeat"] = Vertical(14, 8, 1f, 12f, alternate: true),
			["WolfMeat"] = Vertical(14, 8, 1f, 12f, alternate: true),
			["CookedWolfMeat"] = Vertical(14, 8, 1f, 12f, alternate: true),
			["FishRaw"] = Vertical(16, 8, 1f, 12f, alternate: true),
			["FishAnglerRaw"] = Vertical(16, 8, 1f, 12f, alternate: true),
			["FishCooked"] = Vertical(16, 8, 1f, 12f, alternate: true),
			["AmberPearl"] = Controlled(18, 10, 0.5f, 25f),
			["Amber"] = AmberProfile(),
			["GreydwarfEye"] = Controlled(20, 10, 0.48f, 30f),
			["Coal"] = Controlled(18, 10, 0.52f, 20f),
			["Stone"] = Controlled(18, 10, 0.52f, 20f),
			["StoneRock"] = Controlled(18, 10, 0.52f, 20f),
			["Guck"] = Controlled(12, 6, 0.6f, 18f),
			["Bloodbag"] = Controlled(12, 6, 0.6f, 18f),
			["Ooze"] = Controlled(12, 6, 0.6f, 18f),
			["Chitin"] = Controlled(14, 8, 0.46f, 18f),
			["Crystal"] = DenseCrystal(),
			["FirCone"] = Controlled(18, 10, 0.42f, 18f),
			["FirConeFrost"] = Controlled(18, 10, 0.42f, 18f),
			["PineCone"] = Controlled(18, 10, 0.42f, 18f),
			["Feathers"] = FeatherProfile(),
			["CelestialFeather"] = FeatherProfile()
		};

		private static readonly PileItemTuning Bait = BaitProfile();

		private static readonly PileItemTuning Feathers = FeatherProfile();

		private static PileItemTuning UprightMushroom()
		{
			PileItemTuning pileItemTuning = Packed(16, 10, 1f, 0.5f, 30f);
			pileItemTuning.HeightVariation = 0.025f;
			return pileItemTuning;
		}

		private static PileItemTuning RoundedProduce()
		{
			//IL_0045: 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)
			return new PileItemTuning
			{
				UpperCopies = 6,
				OuterCopies = 5,
				MiddleCopies = 0,
				EdgeCopies = 5,
				RotationJitterScale = new Vector3(0.6f, 1f, 0.2f)
			};
		}

		internal static PileItemTuning For(string prefabName)
		{
			if (prefabName != null && Overrides.TryGetValue(prefabName, out var value))
			{
				return value;
			}
			if (prefabName == null)
			{
				return Default;
			}
			if (prefabName.StartsWith("TurretBolt", StringComparison.OrdinalIgnoreCase) || prefabName.StartsWith("Arrow", StringComparison.OrdinalIgnoreCase))
			{
				return Ballista;
			}
			if (PileLayout.IsWoodResource(prefabName))
			{
				return Wood;
			}
			if (prefabName.StartsWith("FishingBait", StringComparison.OrdinalIgnoreCase))
			{
				return Bait;
			}
			if (prefabName.EndsWith("Hide", StringComparison.OrdinalIgnoreCase) || prefabName.EndsWith("Pelt", StringComparison.OrdinalIgnoreCase))
			{
				return Hide;
			}
			if (prefabName.EndsWith("Ore", StringComparison.OrdinalIgnoreCase) || prefabName.StartsWith("FlametalOre", StringComparison.OrdinalIgnoreCase))
			{
				return Ore;
			}
			if (prefabName.EndsWith("Scrap", StringComparison.OrdinalIgnoreCase))
			{
				return Scrap;
			}
			if (prefabName.IndexOf("Feather", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return Feathers;
			}
			if (!PileLayout.IsPlainMeat(prefabName))
			{
				return Default;
			}
			return Meat;
		}

		private static PileItemTuning Packed(int upper, int edge, float scale, float footprint, float tilt)
		{
			return new PileItemTuning
			{
				Calibrated = true,
				UpperCopies = upper,
				EdgeCopies = edge,
				OuterCopies = Mathf.Max(1, upper * 2 / 3),
				MiddleCopies = upper / 5,
				PreferredScale = scale,
				MaximumFootprint = footprint,
				PackedTilt = tilt
			};
		}

		private static PileItemTuning Vertical(int upper, int edge, float scale, float tilt, bool alternate = false)
		{
			PileItemTuning pileItemTuning = Packed(upper, edge, scale, 0.48f, tilt);
			pileItemTuning.Upright = true;
			pileItemTuning.AlternatingVertical = alternate;
			return pileItemTuning;
		}

		private static PileItemTuning Jute()
		{
			PileItemTuning pileItemTuning = Packed(8, 4, 1f, 0.72f, 10f);
			pileItemTuning.RelativeScale = 1.5f;
			return pileItemTuning;
		}

		private static PileItemTuning MeatProfile(int upper, int edge)
		{
			PileItemTuning pileItemTuning = Packed(upper, edge, 1f, 0.93f, 9f);
			pileItemTuning.LayFlat = true;
			return pileItemTuning;
		}

		private static PileItemTuning RaisedProduce()
		{
			PileItemTuning pileItemTuning = ProduceProfile();
			pileItemTuning.SurfaceLift = 0.105f;
			return pileItemTuning;
		}

		private static PileItemTuning CarrotProfile()
		{
			PileItemTuning pileItemTuning = Vertical(28, 16, 0.95f, 10f, alternate: true);
			pileItemTuning.SurfaceHeight = 0.32f;
			pileItemTuning.CoverageLayers = 1.25f;
			return pileItemTuning;
		}

		private static PileItemTuning BarleyProfile()
		{
			PileItemTuning pileItemTuning = Packed(36, 24, 1f, 0.5f, 12f);
			pileItemTuning.SurfaceLift = 0.045f;
			pileItemTuning.HeightFactor = 1.5f;
			pileItemTuning.CoverageLayers = 2f;
			return pileItemTuning;
		}

		private static PileItemTuning RaisedBone(float tilt)
		{
			PileItemTuning pileItemTuning = Vertical(28, 16, 1f, tilt);
			pileItemTuning.HeightFactor = 1.15f;
			return pileItemTuning;
		}

		private static PileItemTuning HideProfile(bool dense)
		{
			PileItemTuning pileItemTuning = Vertical(dense ? 32 : 12, dense ? 20 : 6, dense ? 1f : 0.95f, 30f);
			pileItemTuning.TiltBias = 2f;
			pileItemTuning.HeightFactor = 1.15f;
			if (dense)
			{
				pileItemTuning.MaximumHeight = 1.3f;
				pileItemTuning.MaximumFootprint = 0.54f;
				pileItemTuning.CoverageLayers = 2.5f;
				pileItemTuning.OverlapPenalty = 0.16f;
			}
			return pileItemTuning;
		}

		private static PileItemTuning Mounded(int upper, int edge, float footprint, float tilt)
		{
			PileItemTuning pileItemTuning = Packed(upper, edge, 1f, footprint, tilt);
			pileItemTuning.MoundHeight = 0.055f;
			return pileItemTuning;
		}

		private static PileItemTuning LoweredMound(int upper, int edge, float footprint, float tilt, float factor)
		{
			PileItemTuning pileItemTuning = Mounded(upper, edge, footprint, tilt);
			pileItemTuning.HeightFactor = factor;
			return pileItemTuning;
		}

		private static PileItemTuning BaitProfile()
		{
			PileItemTuning pileItemTuning = LoweredMound(24, 14, 0.4f, 12f, 0.9f);
			pileItemTuning.AnchorToBottom = true;
			pileItemTuning.MoundHeight = 0.035f;
			pileItemTuning.HeightVariation = 0.006f;
			return pileItemTuning;
		}

		private static PileItemTuning KaleSeedsProfile()
		{
			return LoweredMound(38, 22, 0.46f, 8f, 0.95f);
		}

		private static PileItemTuning DeerHideProfile()
		{
			PileItemTuning pileItemTuning = HideProfile(dense: false);
			pileItemTuning.UpperCopies = 18;
			pileItemTuning.EdgeCopies = 10;
			pileItemTuning.OuterCopies = 12;
			pileItemTuning.MiddleCopies = 3;
			pileItemTuning.PreferredScale = 1.1f;
			pileItemTuning.MaximumHeight = 1.5f;
			pileItemTuning.MaximumFootprint = 0.62f;
			pileItemTuning.CoverageLayers = 1.25f;
			return pileItemTuning;
		}

		private static PileItemTuning ReshuffledMeat(uint salt)
		{
			PileItemTuning pileItemTuning = Vertical(14, 8, 1f, 32f, alternate: true);
			pileItemTuning.VariantSalt = salt;
			pileItemTuning.HeightVariation = 0.02f;
			return pileItemTuning;
		}

		private static PileItemTuning WoodProfile()
		{
			PileItemTuning pileItemTuning = Vertical(80, 0, 0.5f, 30f);
			pileItemTuning.PreservePreferredScale = true;
			pileItemTuning.TiltBias = 3f;
			pileItemTuning.HeightFactor = 1.15f;
			pileItemTuning.CoverageLayers = 1.8f;
			pileItemTuning.OverlapPenalty = 0.55f;
			pileItemTuning.MaximumProjectionOverlap = 0.18f;
			return pileItemTuning;
		}

		private static PileItemTuning ProduceProfile()
		{
			PileItemTuning pileItemTuning = Packed(36, 20, 0.65f, 0.46f, 30f);
			pileItemTuning.PreservePreferredScale = true;
			pileItemTuning.ScaleVariation = 0.23076925f;
			pileItemTuning.CoverageLayers = 1.6f;
			pileItemTuning.OverlapPenalty = 0.45f;
			pileItemTuning.HeightVariation = 0.018f;
			pileItemTuning.AnchorToBottom = true;
			pileItemTuning.BottomHeight = 0.06f;
			return pileItemTuning;
		}

		private static PileItemTuning ChickenProfile()
		{
			PileItemTuning pileItemTuning = Packed(18, 10, 0.65f, 0.6f, 12f);
			pileItemTuning.LayFlat = true;
			pileItemTuning.CoverageLayers = 1.25f;
			pileItemTuning.OverlapPenalty = 0.55f;
			pileItemTuning.AnchorToBottom = true;
			return pileItemTuning;
		}

		private static PileItemTuning RimResource(int upper, int edge, float footprint, float tilt, int rimCopies)
		{
			PileItemTuning pileItemTuning = Packed(upper, edge, 1f, footprint, tilt);
			pileItemTuning.RimFirstCopies = rimCopies;
			pileItemTuning.CoverageLayers = 1.6f;
			pileItemTuning.OverlapPenalty = 0.25f;
			return pileItemTuning;
		}

		private static PileItemTuning AmberProfile()
		{
			PileItemTuning pileItemTuning = Controlled(18, 10, 0.5f, 26f);
			pileItemTuning.OverlapPenalty = 0.85f;
			return pileItemTuning;
		}

		private static PileItemTuning FeatherProfile()
		{
			PileItemTuning pileItemTuning = BaitProfile();
			pileItemTuning.UpperCopies = 40;
			pileItemTuning.OuterCopies = 26;
			pileItemTuning.MiddleCopies = 8;
			pileItemTuning.EdgeCopies = 24;
			pileItemTuning.MaximumFootprint = 0.42f;
			pileItemTuning.PackedTilt = 20f;
			pileItemTuning.CoverageLayers = 2f;
			return pileItemTuning;
		}

		private static PileItemTuning Controlled(int upper, int edge, float footprint, float tilt)
		{
			PileItemTuning pileItemTuning = Packed(upper, edge, 1f, footprint, tilt);
			pileItemTuning.OverlapPenalty = 0.65f;
			pileItemTuning.HeightVariation = 0.022f;
			return pileItemTuning;
		}

		private static PileItemTuning DenseCrystal()
		{
			PileItemTuning pileItemTuning = Packed(30, 18, 1f, 0.46f, 55f);
			pileItemTuning.SurfaceHeight = 0.22f;
			pileItemTuning.CoverageLayers = 1.25f;
			pileItemTuning.HeightVariation = 0.035f;
			pileItemTuning.PositionVariation = 0.05f;
			return pileItemTuning;
		}

		private static PileItemTuning BallistaProfile()
		{
			PileItemTuning pileItemTuning = Vertical(64, 24, 0.95f, 30f);
			pileItemTuning.MaximumHeight = 1.7f;
			pileItemTuning.MaximumFootprint = 0.5f;
			pileItemTuning.SurfaceHeight = 0.36f;
			pileItemTuning.HeightFactor = 1.15f;
			pileItemTuning.CoverageLayers = 1.5f;
			pileItemTuning.OverlapPenalty = 0.55f;
			pileItemTuning.TiltBias = 2f;
			return pileItemTuning;
		}

		internal Vector3 UpperPositionOffset(int index, float diameter)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			return ScaledOffset(UpperPositionOffsets, index, diameter);
		}

		internal Vector3 EdgePositionOffset(int index, float diameter)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			return ScaledOffset(EdgePositionOffsets, index, diameter);
		}

		internal Vector3 CopyRotationOffset(int index)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			if (PerCopyRotationOffsets == null || !PerCopyRotationOffsets.TryGetValue(index, out var value))
			{
				return Vector3.zero;
			}
			return value;
		}

		private static Vector3 ScaledOffset(Dictionary<int, Vector3> offsets, int index, float diameter)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			if (offsets == null || !offsets.TryGetValue(index, out var value))
			{
				return Vector3.zero;
			}
			return value * diameter;
		}
	}
	internal struct PilePose
	{
		internal Vector3 Position;

		internal Quaternion Rotation;

		internal float ScaleFactor;
	}
	internal sealed class PileLayout
	{
		private const float MaxHeightFraction = 0.78f;

		private const float InnerEdgeRadiusFraction = 0.495f;

		private const float OuterEdgeBandInnerFraction = 0.992f;

		private const float OuterEdgeBandJitterFraction = 0.001f;

		private const float MoundPeakFraction = 0.035f;

		private readonly int _copies;

		private readonly int _outerRingCount;

		private readonly int _middleRingCount;

		private readonly int _edgeUnderlayCopies;

		private readonly PileItemTuning _tuning;

		private static readonly HashSet<string> ExcludedItems = LoadItems("item-exclusions.txt");

		private static readonly HashSet<string> WoodItems = LoadItems("wood-items.txt");

		internal PileItemTuning Tuning => _tuning;

		internal int Copies => _copies;

		internal int OuterRingCount => _outerRingCount;

		internal int MiddleRingCount => _middleRingCount;

		internal int EdgeUnderlayCopies => _edgeUnderlayCopies;

		private static HashSet<string> LoadItems(string fileName)
		{
			HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
			using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("VanillaBarrelPlus.Resources." + fileName);
			using StreamReader streamReader = new StreamReader(stream);
			string text;
			while ((text = streamReader.ReadLine()) != null)
			{
				if (!string.IsNullOrWhiteSpace(text))
				{
					hashSet.Add(text.Trim());
				}
			}
			return hashSet;
		}

		private PileLayout(string prefabName, bool compactPile)
		{
			_tuning = PileItemTuning.For(prefabName);
			_copies = _tuning.UpperCopies ?? (compactPile ? 16 : 20);
			_outerRingCount = _tuning.OuterCopies ?? (compactPile ? 12 : 14);
			_middleRingCount = _tuning.MiddleCopies ?? (compactPile ? 3 : 4);
			_edgeUnderlayCopies = _tuning.EdgeCopies ?? _outerRingCount;
		}

		internal static PileLayout For(string prefabName, ItemType itemType, bool preparedFood)
		{
			//IL_005e: 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_0062: Invalid comparison between Unknown and I4
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Invalid comparison between Unknown and I4
			if (string.IsNullOrEmpty(prefabName) || IsExcludedName(prefabName))
			{
				return null;
			}
			if (preparedFood && !IsPlainMeat(prefabName) && !IsFishPortion(prefabName))
			{
				return null;
			}
			if (prefabName.StartsWith("FishingBait", StringComparison.OrdinalIgnoreCase) || prefabName.StartsWith("TurretBolt", StringComparison.OrdinalIgnoreCase) || (prefabName.StartsWith("Arrow", StringComparison.OrdinalIgnoreCase) && (int)itemType == 9))
			{
				return new PileLayout(prefabName, compactPile: false);
			}
			if (itemType - 1 <= 1)
			{
				return new PileLayout(prefabName, IsBerryOrMushroom(prefabName));
			}
			return null;
		}

		internal static bool IsPreparedFood(string prefabName)
		{
			if (string.IsNullOrEmpty(prefabName) || (Object)(object)ObjectDB.instance == (Object)null || (Object)(object)ZNetScene.instance == (Object)null)
			{
				return false;
			}
			List<ItemDrop> allCreatableFood = ObjectDB.instance.GetAllCreatableFood();
			if (allCreatableFood == null)
			{
				return false;
			}
			foreach (ItemDrop item in allCreatableFood)
			{
				if ((Object)(object)item != (Object)null && (Object)(object)((Component)item).gameObject != (Object)null && string.Equals(((Object)((Component)item).gameObject).name, prefabName, StringComparison.OrdinalIgnoreCase))
				{
					return true;
				}
			}
			return false;
		}

		private static bool IsBerryOrMushroom(string prefabName)
		{
			string text = prefabName.ToLowerInvariant();
			if (text.EndsWith("berry") || text.EndsWith("berries"))
			{
				return true;
			}
			switch (text)
			{
			case "mushroombzerker":
			case "mushroommagecap":
			case "mushroom":
			case "mushroomyellow":
			case "mushroomblue":
			case "mushroomjotunpuffs":
			case "mushroomsmokepuff":
				return true;
			default:
				return false;
			}
		}

		private static bool IsExcludedName(string prefabName)
		{
			string text = prefabName.ToLowerInvariant();
			if (text.StartsWith("fishingbait") || text.StartsWith("turretbolt") || text.StartsWith("arrow") || IsWoodResource(prefabName) || IsFishPortion(prefabName))
			{
				return false;
			}
			if (!ExcludedItems.Contains(prefabName) && !text.StartsWith("staminaupgrade_") && !text.StartsWith("healthupgrade_") && !text.Contains("wood") && !text.Contains("log") && !text.Contains("bark") && !text.Contains("branch") && !text.Contains("trophy") && !text.Contains("flour") && !text.Contains("idol") && !text.Contains("totem") && !text.Contains("feast") && (!text.StartsWith("fish") || text.StartsWith("fishingbait")) && !text.StartsWith("mead") && !text.StartsWith("barleywine") && !(text == "sap") && !IsIngot(text))
			{
				return IsTechnicalPart(text);
			}
			return true;
		}

		private static bool IsTechnicalPart(string name)
		{
			if (!name.EndsWith("uncooked") && !name.StartsWith("mold") && !name.StartsWith("upgrader") && !name.StartsWith("axehead") && !name.Contains("bladefragment") && !name.Contains("hiltfragment") && !name.Contains("tipfragment") && !name.Contains("handle"))
			{
				switch (name)
				{
				default:
					if (!name.Contains("ribcage") && !name.StartsWith("fireworks") && !(name == "hook") && !(name == "ironpit"))
					{
						return name.StartsWith("pot_shard");
					}
					break;
				case "shieldcore":
				case "orbfrostfire":
				case "orbthunderblood":
				case "chain":
				case "eitr":
				case "faderdrop":
					break;
				}
			}
			return true;
		}

		internal static bool IsPlainMeat(string prefabName)
		{
			if (string.IsNullOrEmpty(prefabName))
			{
				return false;
			}
			switch (prefabName.ToLowerInvariant())
			{
			case "bugmeat":
			case "loxmeat":
			case "rawmeat":
			case "cookedmeat":
			case "rottenmeat":
			case "boarjerky":
			case "bjornmeat":
			case "moosemeat":
			case "wolfjerky":
			case "necktail":
			case "wolfmeat":
			case "deermeat":
			case "haremeat":
			case "cookeddeermeat":
			case "cookedharemeat":
			case "cookedwolfmeat":
			case "cookedbugmeat":
			case "cookedloxmeat":
			case "serpentmeat":
			case "volturemeat":
			case "asksvinmeat":
			case "chickenmeat":
			case "serpentmeatcooked":
			case "cookedvolturemeat":
			case "cookedasksvinmeat":
			case "cookedchickenmeat":
			case "cookedbjornmeat":
			case "necktailgrilled":
			case "cookedmoosemeat":
			case "bonemawserpentmeat":
			case "cookedbonemawserpentmeat":
				return true;
			default:
				return false;
			}
		}

		internal static bool IsFishPortion(string prefabName)
		{
			if (!string.Equals(prefabName, "FishRaw", StringComparison.OrdinalIgnoreCase) && !string.Equals(prefabName, "FishAnglerRaw", StringComparison.OrdinalIgnoreCase))
			{
				return string.Equals(prefabName, "FishCooked", StringComparison.OrdinalIgnoreCase);
			}
			return true;
		}

		internal static bool IsWoodResource(string prefabName)
		{
			if (prefabName != null)
			{
				return WoodItems.Contains(prefabName);
			}
			return false;
		}

		private static bool IsIngot(string name)
		{
			switch (name)
			{
			case "bronze":
			case "copper":
			case "silver":
			case "gold":
			case "iron":
			case "tin":
			case "blackmetal":
			case "flametal":
			case "flametalnew":
				return true;
			default:
				return false;
			}
		}

		internal float Scale(Bounds sourceBounds, float mouthDiameter)
		{
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: 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_002b: 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_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: 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_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			if (_tuning.PreservePreferredScale)
			{
				return _tuning.PreferredScale;
			}
			if (_tuning.Calibrated)
			{
				Bounds val = MeshBounds.Transform(sourceBounds, Matrix4x4.Rotate(BaseRotation(sourceBounds)));
				float num = Mathf.Max(((Bounds)(ref val)).size.x, ((Bounds)(ref val)).size.z);
				float num2 = _tuning.PreferredScale;
				if (_tuning.RelativeScale > 0f)
				{
					num2 = Mathf.Min(1f, Mathf.Min(mouthDiameter * 0.46f / Mathf.Max(((Bounds)(ref sourceBounds)).size.x, ((Bounds)(ref sourceBounds)).size.z), mouthDiameter * 0.78f / ((Bounds)(ref sourceBounds)).size.y)) * _tuning.RelativeScale;
				}
				return Mathf.Min(num2, Mathf.Min(mouthDiameter * _tuning.MaximumFootprint / Mathf.Max(0.001f, num), mouthDiameter * _tuning.MaximumHeight / Mathf.Max(0.001f, ((Bounds)(ref val)).size.y)));
			}
			Vector3 size = ((Bounds)(ref sourceBounds)).size;
			float num3 = Mathf.Max(0.001f, Mathf.Max(size.x, size.z));
			float num4 = Mathf.Max(0.001f, size.y);
			return Mathf.Min(Mathf.Min(mouthDiameter * _tuning.MaximumFootprint / num3, mouthDiameter * 0.78f / num4), Mathf.Min(_tuning.MaximumScale, _tuning.ScaleMultiplier));
		}

		internal Quaternion BaseRotation(Bounds bounds)
		{
			//IL_000f: 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_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: 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_0069: 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_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: 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_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_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			if (_tuning.LayFlat && ((Bounds)(ref bounds)).size.y > ((Bounds)(ref bounds)).size.x && ((Bounds)(ref bounds)).size.y > ((Bounds)(ref bounds)).size.z)
			{
				return Quaternion.FromToRotation(Vector3.up, Vector3.forward);
			}
			if (!_tuning.Upright)
			{
				if (!(_tuning.RotationOffset == Vector3.zero))
				{
					return Quaternion.Euler(_tuning.RotationOffset);
				}
				return Quaternion.identity;
			}
			Vector3 size = ((Bounds)(ref bounds)).size;
			return Quaternion.FromToRotation((size.x > size.z && size.x > size.y) ? Vector3.right : ((size.z > size.y) ? Vector3.forward : Vector3.up), Vector3.up);
		}

		internal Quaternion PackedRotation(int index, uint seed, Bounds bounds)
		{
			//IL_0003: 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_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: 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_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)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = PackedAngles(index, seed);
			float num = val.z * (MathF.PI / 180f);
			Quaternion val2 = Quaternion.AngleAxis(val.x, new Vector3(Mathf.Cos(num), 0f, Mathf.Sin(num))) * Quaternion.AngleAxis(val.y, Vector3.up);
			Quaternion val3 = ((_tuning.AlternatingVertical && (index & 1) != 0) ? Quaternion.Euler(180f, 0f, 0f) : Quaternion.identity);
			return val2 * val3 * BaseRotation(bounds);
		}

		internal Vector3 PackedAngles(int index, uint seed)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(Mathf.Pow(Sample(seed, index, 2769414579u), _tuning.TiltBias) * _tuning.PackedTilt, Sample(seed, index, 1675113877u) * 360f, Sample(seed, index, 3101290983u) * 360f);
		}

		internal float PackedSurface(float diameter, int index, uint seed, float radialFraction)
		{
			float num = Mathf.Clamp01(radialFraction);
			return diameter * (_tuning.SurfaceHeight + _tuning.SurfaceLift + _tuning.MoundHeight * (1f - num * num)) * _tuning.HeightFactor + HeightJitter(index, seed, diameter);
		}

		internal float MeshSurface(float diameter, int index, uint seed, float radialFraction, float meshHeight)
		{
			float num = PackedSurface(diameter, index, seed, radialFraction);
			if (!_tuning.AnchorToBottom)
			{
				return num;
			}
			float num2 = Mathf.Clamp01(radialFraction);
			float num3 = meshHeight + diameter * (_tuning.BottomHeight + _tuning.MoundHeight * (1f - num2 * num2) * _tuning.HeightFactor) + HeightJitter(index, seed, diameter);
			return Mathf.Min(num, num3);
		}

		internal float CopyScale(int index, uint seed)
		{
			return 1f + (Sample(seed, index, 2447445413u) * 2f - 1f) * _tuning.ScaleVariation;
		}

		internal Vector2 CandidateJitter(int index, int candidate, uint seed)
		{
			//IL_003a: 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)
			int index2 = index * 193 + candidate;
			return new Vector2(Sample(seed, index2, 1821285621u) * 2f - 1f, Sample(seed, index2, 3041260689u) * 2f - 1f) * _tuning.PositionVariation;
		}

		internal uint VariantSeed(uint seed)
		{
			if (_tuning.VariantSalt != 0)
			{
				return Mix(seed ^ _tuning.VariantSalt);
			}
			return seed;
		}

		internal static uint CreateSeed(long barrelUserId, uint barrelId, int prefabSeed)
		{
			return Mix(Mix(Mix(Mix((uint)((int)barrelUserId ^ -1640531527)) ^ (uint)(int)(barrelUserId >>> 32)) ^ barrelId) ^ (uint)prefabSeed);
		}

		internal Vector3 RotationJitter(int index, uint pileSeed)
		{
			//IL_0054: 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_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: 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)
			uint num = Mix(pileSeed ^ (uint)(index * -1640531527));
			return Vector3.Scale(new Vector3(SignedUnit(Mix(num ^ 0xA511E9B3u)) * 8f, SignedUnit(Mix(num ^ 0x63D83595)) * 12f, UnsignedUnit(Mix(num ^ 0xB8D9F1E7u)) * 60f), _tuning.RotationJitterScale) + _tuning.RotationOffset + _tuning.CopyRotationOffset(index);
		}

		internal float HeightJitter(int index, uint pileSeed, float diameter)
		{
			return SignedUnit(Mix(Mix(pileSeed ^ (uint)(index * -1640531527)) ^ 0xD17C36A5u)) * diameter * _tuning.HeightVariation;
		}

		private static float Sample(uint pileSeed, int index, uint salt)
		{
			return UnsignedUnit(Mix(Mix(pileSeed ^ (uint)(index * -1640531527)) ^ salt));
		}

		private static float UnsignedUnit(uint sample)
		{
			return (float)(sample & 0xFFFFFF) / 16777215f;
		}

		private static float SignedUnit(uint sample)
		{
			return UnsignedUnit(sample) * 2f - 1f;
		}

		private static uint Mix(uint value)
		{
			value ^= value >> 16;
			value *= 2146121005;
			value ^= value >> 15;
			value *= 2221713035u;
			return value ^ (value >> 16);
		}

		internal PilePose Pose(int index, float diameter, Bounds sourceBounds, IList<Vector3[]> meshVertices, IList<Bounds> meshPartBounds, float scale, int prefabSeed, uint pileSeed)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: 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_0029: Unknown result type (might be due to invalid IL or missing references)
			Vector3 target = Position(index, diameter, 0f, prefabSeed, pileSeed);
			return FitPose(index, diameter, sourceBounds, meshVertices, meshPartBounds, scale, prefabSeed, pileSeed, target, _tuning.UpperPositionOffset(index, diameter), underlay: false);
		}

		internal PilePose EdgeUnderlayPose(int index, float diameter, Bounds sourceBounds, IList<Vector3[]> meshVertices, IList<Bounds> meshPartBounds, float scale, int prefabSeed, uint pileSeed)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			Vector3 target = EdgeUnderlayPosition(index, diameter, 0f, prefabSeed, pileSeed);
			return FitPose(_copies + index, diameter, sourceBounds, meshVertices, meshPartBounds, scale, prefabSeed, pileSeed, target, _tuning.EdgePositionOffset(index, diameter), underlay: true);
		}

		private PilePose FitPose(int deterministicIndex, float diameter, Bounds sourceBounds, IList<Vector3[]> meshVertices, IList<Bounds> meshPartBounds, float scale, int prefabSeed, uint pileSeed, Vector3 target, Vector3 offset, bool underlay)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: 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_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: 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_008a: 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_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: 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)
			float yaw = (float)(prefabSeed & 0x3FF) * (45f / 128f) + (float)deterministicIndex * 137.50777f;
			Vector3 val = RotationAngles(deterministicIndex, pileSeed, yaw);
			Quaternion val2 = Quaternion.Euler(val.x, val.y, val.z);
			Vector3 pivot = default(Vector3);
			((Vector3)(ref pivot))..ctor(0f - ((Bounds)(ref sourceBounds)).center.x, 0f - ((Bounds)(ref sourceBounds)).min.y, 0f - ((Bounds)(ref sourceBounds)).center.z);
			Vector3[] array = PileGeometry.TransformVertices(meshVertices, meshPartBounds, sourceBounds, pivot, Matrix4x4.Rotate(val2), scale);
			float radius = diameter * 0.495f;
			Vector3 desired = default(Vector3);
			((Vector3)(ref desired))..ctor(target.x + offset.x, 0f, target.z + offset.z);
			float num = diameter * _tuning.SurfaceHeight;
			float num2 = diameter * 0.135f;
			Bounds val3 = PileGeometry.Measure(array);
			float top = Mathf.Min(num, num2 + ((Bounds)(ref val3)).size.y * 0.55f) + target.y + offset.y;
			PileFit pileFit = PileGeometry.Fit(array, desired, radius, top, underlay ? (diameter * 0.055f) : 0f);
			return new PilePose
			{
				Position = pileFit.Position,
				Rotation = val2,
				ScaleFactor = pileFit.ScaleFactor
			};
		}

		internal Vector3 RotationAngles(int deterministicIndex, uint pileSeed, float yaw)
		{
			//IL_0003: 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_003e: Unknown result type (might be due to invalid IL or missing references)
			Vector3 result = RotationJitter(deterministicIndex, pileSeed);
			if (_tuning.AlternatingVertical)
			{
				result.x += (((deterministicIndex & 1) == 0) ? 90f : (-90f));
			}
			result.y += yaw;
			return result;
		}

		internal Vector3 EdgeUnderlayPosition(int index, float diameter, float footprint, int prefabSeed, uint pileSeed)
		{
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Max(0f, diameter * 0.495f - footprint * 0.5f);
			float num2 = (float)(prefabSeed & 0x3FF) * (45f / 128f);
			float num3 = 360f / (float)_edgeUnderlayCopies;
			float num4 = SignedUnit(Mix((uint)(index * -1640531527) ^ pileSeed ^ 0x3C6EF372)) * num3 * 0.08f;
			float num5 = (num2 + ((float)index + 0.5f) * num3 + num4) * (MathF.PI / 180f);
			return new Vector3(Mathf.Cos(num5) * num, 0f, Mathf.Sin(num5) * num);
		}

		internal Vector3 Position(int index, float diameter, float footprint, int prefabSeed, uint pileSeed)
		{
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			float num = (float)(prefabSeed & 0x3FF) * (45f / 128f);
			float num2 = Mathf.Max(0f, diameter * 0.495f - footprint * 0.5f);
			int num3;
			int num4;
			int num5;
			if (index < _outerRingCount)
			{
				num3 = 0;
				num4 = index;
				num5 = _outerRingCount;
			}
			else if (index < _outerRingCount + _middleRingCount)
			{
				num3 = 1;
				num4 = index - _outerRingCount;
				num5 = _middleRingCount;
			}
			else
			{
				num3 = 2;
				num4 = index - _outerRingCount - _middleRingCount;
				num5 = _copies - _outerRingCount - _middleRingCount;
			}
			float num6 = num3 switch
			{
				1 => 0.42f, 
				0 => 0.55f, 
				_ => 0f, 
			};
			float num7 = num3 switch
			{
				1 => 0.58f, 
				0 => 0.66f, 
				_ => 0.16f, 
			};
			float num8 = Sample(pileSeed, index, 73244475u);
			float num9 = num2 * Mathf.Lerp(num6, num7, num8);
			float num10 = ((num3 == 0) ? (num2 * Mathf.Lerp(0.992f, 1f, num8)) : num9);
			float num11 = ((num3 == 0) ? ((0f - UnsignedUnit(Mix((uint)(index * -1640531527) ^ pileSeed ^ 0x7F4A7C15))) * num2 * 0.001f) : (SignedUnit(Mix((uint)(index * -1640531527) ^ pileSeed ^ 0x7F4A7C15)) * num2 * 0.018f));
			float num12 = Mathf.Clamp((num10 + num11) * _tuning.RadialSpread, 0f, num2);
			float num13 = (float)num3 * (180f / (float)num5);
			float num14 = (Sample(pileSeed, index, 3039394381u) - 0.5f) * (360f / (float)num5) * 0.22f;
			float num15 = (num + num13 + (float)num4 * (360f / (float)num5) + num14) * (MathF.PI / 180f);
			float num16 = ((num2 > 0.0001f) ? Mathf.Clamp01(num12 / num2) : 1f);
			float num17 = 1f - num16;
			float num18 = diameter * 0.035f;
			float num19 = num18 * Mathf.Pow(num17, 1.35f);
			num19 += HeightJitter(index, pileSeed, diameter);
			num19 = Mathf.Clamp(num19, 0f, num18 + diameter * 0.012f);
			return new Vector3(Mathf.Cos(num15) * num12, num19, Mathf.Sin(num15) * num12);
		}
	}
	internal static class PilePacking
	{
		private sealed class PlacedSilhouette
		{
			internal List<Vector2> Hull;

			internal Vector2 Offset;
		}

		internal static List<PilePose> Create(PileLayout layout, float diameter, ItemVisualTemplate template, float scale, uint seed)
		{
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: 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_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_0264: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: Unknown result type (might be due to invalid IL or missing references)
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_05dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0620: Unknown result type (might be due to invalid IL or missing references)
			//IL_0627: Unknown result type (might be due to invalid IL or missing references)
			//IL_062c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0631: Unknown result type (might be due to invalid IL or missing references)
			//IL_0634: Unknown result type (might be due to invalid IL or missing references)
			//IL_032b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0354: Unknown result type (might be due to invalid IL or missing references)
			//IL_035b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0360: Unknown result type (might be due to invalid IL or missing references)
			//IL_06bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_065e: Unknown result type (might be due to invalid IL or missing references)
			//IL_066a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0674: Unknown result type (might be due to invalid IL or missing references)
			//IL_0679: Unknown result type (might be due to invalid IL or missing references)
			//IL_0372: Unknown result type (might be due to invalid IL or missing references)
			//IL_0376: Unknown result type (might be due to invalid IL or missing references)
			//IL_036b: Unknown result type (might be due to invalid IL or missing references)
			//IL_037b: Unknown result type (might be due to invalid IL or missing references)
			//IL_037f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03db: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0447: Unknown result type (might be due to invalid IL or missing references)
			//IL_0453: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04de: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_047a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0485: Unknown result type (might be due to invalid IL or missing references)
			//IL_053b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0540: Unknown result type (might be due to invalid IL or missing references)
			List<PilePose> list = new List<PilePose>();
			List<Vector3> list2 = new List<Vector3>();
			List<PlacedSilhouette> list3 = new List<PlacedSilhouette>();
			float num = diameter * 0.495f;
			List<Vector3> list4 = new List<Vector3>();
			float num2 = num * 2f / 25f;
			Vector3 item = default(Vector3);
			for (int i = 0; i < 25; i++)
			{
				for (int j = 0; j < 25; j++)
				{
					((Vector3)(ref item))..ctor(((float)j + 0.5f) * num2 - num, 0f, ((float)i + 0.5f) * num2 - num);
					if (((Vector3)(ref item)).sqrMagnitude <= num * num)
					{
						list4.Add(item);
					}
				}
			}
			int[] array = new int[list4.Count];
			Bounds val = template.Bounds;
			float num3 = 0f - ((Bounds)(ref val)).center.x;
			val = template.Bounds;
			float num4 = 0f - ((Bounds)(ref val)).min.y;
			val = template.Bounds;
			Vector3 pivot = default(Vector3);
			((Vector3)(ref pivot))..ctor(num3, num4, 0f - ((Bounds)(ref val)).center.z);
			Vector2 firstOffset = default(Vector2);
			for (int k = 0; k < layout.Copies + layout.EdgeUnderlayCopies; k++)
			{
				bool flag = k >= layout.Copies;
				float num5 = layout.CopyScale(k, seed);
				Quaternion val2 = layout.PackedRotation(k, seed, template.Bounds);
				Vector3[] array2 = PileGeometry.TransformVertices(template.MeshVertices, template.MeshPartBounds, template.Bounds, pivot, Matrix4x4.Rotate(val2), scale * num5);
				val = PileGeometry.Measure(array2);
				float y = ((Bounds)(ref val)).size.y;
				float num6 = layout.PackedSurface(diameter, k, seed, 1f);
				float num7 = (flag ? Mathf.Min(y * 0.42f, diameter * 0.17f) : 0f);
				PileFit pileFit = PileGeometry.Fit(array2, Vector3.zero, num, num6, 0f);
				float meshHeight = y * pileFit.ScaleFactor;
				float num8 = layout.MeshSurface(diameter, k, seed, 1f, meshHeight);
				pileFit.Position.y += num8 - num6;
				num6 = num8;
				List<Vector2> list5 = new List<Vector2>();
				Vector3[] array3 = array2;
				foreach (Vector3 val3 in array3)
				{
					list5.Add(new Vector2(val3.x, val3.z) * pileFit.ScaleFactor);
				}
				List<Vector2> list6 = ConvexHull(list5);
				Vector3[] array4 = (Vector3[])(object)new Vector3[list6.Count];
				for (int m = 0; m < list6.Count; m++)
				{
					array4[m] = new Vector3(list6[m].x + pileFit.Position.x, 0f, list6[m].y + pileFit.Position.z);
				}
				PileFit pileFit2 = pileFit;
				float num9 = float.MinValue;
				int num10 = 0;
				for (int n = 0; n < 145; n++)
				{
					int num11 = ((n != 0) ? ((n - 1) / 24 + 1) : 0);
					if (k < layout.Tuning.RimFirstCopies && num11 < 6)
					{
						continue;
					}
					Vector2 val4 = layout.CandidateJitter(k, n, seed);
					float num12 = ((num11 == 0) ? Mathf.Abs(val4.x) : ((float)num11 / 6f + val4.x));
					float num13 = num * Mathf.Clamp01(num12);
					float num14 = ((float)((n - 1) % 24) * 15f + (float)k * 7f + val4.y * 360f) * (MathF.PI / 180f);
					Vector3 val5 = new Vector3(Mathf.Cos(num14), 0f, Mathf.Sin(num14)) * num13;
					Vector3 val6 = ((num13 > 0f) ? (val5 / num13) : Vector3.right);
					float num15 = PileGeometry.EdgeDistance(array4, val6, num);
					PileFit pileFit3 = new PileFit
					{
						ScaleFactor = pileFit.ScaleFactor,
						Position = pileFit.Position + val6 * num15 * (num13 / num)
					};
					Vector3 val7 = pileFit3.Position - pileFit.Position;
					bool flag2 = false;
					Vector3 val8;
					foreach (Vector3 item3 in list2)
					{
						val8 = item3 - val7;
						if (!(((Vector3)(ref val8)).sqrMagnitude >= diameter * diameter * 0.0025f))
						{
							flag2 = true;
							break;
						}
					}
					if (flag2)
					{
						continue;
					}
					if (layout.Tuning.MaximumProjectionOverlap < 1f)
					{
						((Vector2)(ref firstOffset))..ctor(pileFit3.Position.x, pileFit3.Position.z);
						bool flag3 = false;
						foreach (PlacedSilhouette item4 in list3)
						{
							if (!(OverlapFraction(list6, firstOffset, item4.Hull, item4.Offset) <= layout.Tuning.MaximumProjectionOverlap))
							{
								flag3 = true;
								break;
							}
						}
						if (flag3)
						{
							continue;
						}
					}
					float num16 = 0f;
					int num17 = 0;
					for (int num18 = 0; num18 < list4.Count; num18++)
					{
						Vector3 val9 = list4[num18] - pileFit3.Position;
						if (Contains(list6, new Vector2(val9.x, val9.z)))
						{
							float num19 = Mathf.Clamp01(layout.Tuning.CoverageLayers - (float)array[num18]);
							if (num19 > 0f)
							{
								num17++;
								float num20 = num16;
								val8 = list4[num18];
								num16 = num20 + num19 * (1f + ((Vector3)(ref val8)).magnitude / num * 0.5f);
							}
							num16 -= (flag ? 0.04f : layout.Tuning.OverlapPenalty) * (float)array[num18];
						}
					}
					if (!(num16 <= num9))
					{
						num9 = num16;
						num10 = num17;
						pileFit2 = pileFit3;
					}
				}
				if (num10 == 0 || (!flag && num9 <= 0f))
				{
					continue;
				}
				for (int num21 = 0; num21 < list4.Count; num21++)
				{
					Vector3 val10 = list4[num21] - pileFit2.Position;
					if (Contains(list6, new Vector2(val10.x, val10.z)))
					{
						array[num21]++;
					}
				}
				Vector3 item2 = pileFit2.Position - pileFit.Position;
				list2.Add(item2);
				if (layout.Tuning.MaximumProjectionOverlap < 1f)
				{
					list3.Add(new PlacedSilhouette
					{
						Hull = list6,
						Offset = new Vector2(pileFit2.Position.x, pileFit2.Position.z)
					});
				}
				pileFit2.Position.y += layout.MeshSurface(diameter, k, seed, ((Vector3)(ref item2)).magnitude / num, meshHeight) - num6 - num7;
				list.Add(new PilePose
				{
					Position = pileFit2.Position,
					Rotation = val2,
					ScaleFactor = pileFit2.ScaleFactor * num5
				});
			}
			return list;
		}

		internal static float OverlapFraction(List<Vector2> first, Vector2 firstOffset, List<Vector2> second, Vector2 secondOffset)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: 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_0044: 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_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			float num = 1f;
			Vector2 axis = default(Vector2);
			for (int i = 0; i < 2; i++)
			{
				List<Vector2> list = ((i == 0) ? first : second);
				for (int j = 0; j < list.Count; j++)
				{
					Vector2 val = list[(j + 1) % list.Count] - list[j];
					((Vector2)(ref axis))..ctor(0f - val.y, val.x);
					if (!(((Vector2)(ref axis)).sqrMagnitude < 1E-10f))
					{
						Project(first, firstOffset, axis, out var minimum, out var maximum);
						Project(second, secondOffset, axis, out var minimum2, out var maximum2);
						float num2 = Mathf.Min(maximum, maximum2) - Mathf.Max(minimum, minimum2);
						if (num2 <= 0f)
						{
							return 0f;
						}
						float num3 = Mathf.Min(maximum - minimum, maximum2 - minimum2);
						num = Mathf.Min(num, num2 / Mathf.Max(num3, 1E-08f));
					}
				}
			}
			return