Decompiled source of Vaettir v1.0.0

plugins/Vaettir/Vaettir.dll

Decompiled 13 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using Ezomic.Core;
using Grove;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Stow;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: AssemblyCompany("Thijssen Software")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright (c) 2026 Robbin Thijssen")]
[assembly: AssemblyDescription("Plant an ancient seed, feed it greydwarf blood, and a forest spirit answers.")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+d8f84037b24170229ade3950fc81695a7ecb19df")]
[assembly: AssemblyProduct("Vaettir")]
[assembly: AssemblyTitle("Vaettir")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Stow
{
	internal static class CarriedItem
	{
		private const float CarrySize = 0.17f;

		private static readonly Dictionary<string, GameObject> Templates = new Dictionary<string, GameObject>();

		private static GameObject _holder;

		public static void Invalidate()
		{
			foreach (GameObject value in Templates.Values)
			{
				if ((Object)(object)value != (Object)null)
				{
					Object.Destroy((Object)(object)value);
				}
			}
			Templates.Clear();
		}

		public static GameObject For(ItemData item)
		{
			return For(ItemGroups.PrefabNameOf(item));
		}

		public static GameObject For(string prefabName)
		{
			GameObject val = Template(prefabName);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			GameObject obj = Object.Instantiate<GameObject>(val);
			obj.SetActive(true);
			return obj;
		}

		private static GameObject Template(string prefabName)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			if (string.IsNullOrEmpty(prefabName))
			{
				return null;
			}
			if (Templates.TryGetValue(prefabName, out var value))
			{
				return value;
			}
			Templates[prefabName] = null;
			if ((Object)(object)ObjectDB.instance == (Object)null)
			{
				return null;
			}
			GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(prefabName);
			if ((Object)(object)itemPrefab == (Object)null)
			{
				return null;
			}
			if ((Object)(object)_holder == (Object)null)
			{
				_holder = new GameObject("StowCarriedItems");
				_holder.SetActive(false);
				Object.DontDestroyOnLoad((Object)(object)_holder);
			}
			bool forceDisableInit = ZNetView.m_forceDisableInit;
			ZNetView.m_forceDisableInit = true;
			GameObject val;
			try
			{
				val = Object.Instantiate<GameObject>(itemPrefab, _holder.transform);
			}
			finally
			{
				ZNetView.m_forceDisableInit = forceDisableInit;
			}
			((Object)val).name = "carried_" + prefabName;
			Strip(val);
			GameObject val2 = Fit(val);
			if ((Object)(object)val2 == (Object)null)
			{
				Object.DestroyImmediate((Object)(object)val);
				return null;
			}
			Templates[prefabName] = val2;
			return val2;
		}

		private static void Strip(GameObject clone)
		{
			List<Component> list = new List<Component>();
			MonoBehaviour[] componentsInChildren = clone.GetComponentsInChildren<MonoBehaviour>(true);
			foreach (MonoBehaviour val in componentsInChildren)
			{
				if ((Object)(object)val != (Object)null)
				{
					list.Add((Component)(object)val);
				}
			}
			Collider[] componentsInChildren2 = clone.GetComponentsInChildren<Collider>(true);
			foreach (Collider val2 in componentsInChildren2)
			{
				if ((Object)(object)val2 != (Object)null)
				{
					list.Add((Component)(object)val2);
				}
			}
			Rigidbody[] componentsInChildren3 = clone.GetComponentsInChildren<Rigidbody>(true);
			foreach (Rigidbody val3 in componentsInChildren3)
			{
				if ((Object)(object)val3 != (Object)null)
				{
					list.Add((Component)(object)val3);
				}
			}
			ParticleSystem[] componentsInChildren4 = clone.GetComponentsInChildren<ParticleSystem>(true);
			foreach (ParticleSystem val4 in componentsInChildren4)
			{
				if ((Object)(object)val4 != (Object)null)
				{
					list.Add((Component)(object)val4);
				}
			}
			TrailRenderer[] componentsInChildren5 = clone.GetComponentsInChildren<TrailRenderer>(true);
			foreach (TrailRenderer val5 in componentsInChildren5)
			{
				if ((Object)(object)val5 != (Object)null)
				{
					list.Add((Component)(object)val5);
				}
			}
			Light[] componentsInChildren6 = clone.GetComponentsInChildren<Light>(true);
			foreach (Light val6 in componentsInChildren6)
			{
				if ((Object)(object)val6 != (Object)null)
				{
					list.Add((Component)(object)val6);
				}
			}
			AudioSource[] componentsInChildren7 = clone.GetComponentsInChildren<AudioSource>(true);
			foreach (AudioSource val7 in componentsInChildren7)
			{
				if ((Object)(object)val7 != (Object)null)
				{
					list.Add((Component)(object)val7);
				}
			}
			foreach (Component item in list)
			{
				if ((Object)(object)item != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)item);
				}
			}
			ParticleSystemRenderer[] componentsInChildren8 = clone.GetComponentsInChildren<ParticleSystemRenderer>(true);
			foreach (ParticleSystemRenderer val8 in componentsInChildren8)
			{
				if ((Object)(object)val8 != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)val8);
				}
			}
			Renderer[] componentsInChildren9 = clone.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val9 in componentsInChildren9)
			{
				if (!((Object)(object)val9 == (Object)null))
				{
					val9.shadowCastingMode = (ShadowCastingMode)0;
					val9.receiveShadows = false;
				}
			}
		}

		private static GameObject Fit(GameObject clone)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: 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_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: 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_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Expected O, but got Unknown
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			Bounds bounds = default(Bounds);
			bool found = false;
			Matrix4x4 worldToLocalMatrix = clone.transform.worldToLocalMatrix;
			MeshFilter[] componentsInChildren = clone.GetComponentsInChildren<MeshFilter>(true);
			foreach (MeshFilter val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val.sharedMesh == (Object)null))
				{
					Grow(ref bounds, ref found, worldToLocalMatrix * ((Component)val).transform.localToWorldMatrix, val.sharedMesh.bounds);
				}
			}
			SkinnedMeshRenderer[] componentsInChildren2 = clone.GetComponentsInChildren<SkinnedMeshRenderer>(true);
			foreach (SkinnedMeshRenderer val2 in componentsInChildren2)
			{
				if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val2.sharedMesh == (Object)null))
				{
					Grow(ref bounds, ref found, worldToLocalMatrix * ((Component)val2).transform.localToWorldMatrix, val2.sharedMesh.bounds);
				}
			}
			if (!found)
			{
				return null;
			}
			float num = Mathf.Max(((Bounds)(ref bounds)).size.x, Mathf.Max(((Bounds)(ref bounds)).size.y, ((Bounds)(ref bounds)).size.z));
			if (num <= 0.0001f)
			{
				return null;
			}
			float num2 = 0.17f / num;
			Quaternion val3 = Quaternion.Euler(-24f, 17f, 9f);
			GameObject val4 = new GameObject(((Object)clone).name + "_display");
			val4.transform.SetParent(_holder.transform, false);
			clone.transform.SetParent(val4.transform, false);
			clone.transform.localRotation = val3;
			clone.transform.localScale = new Vector3(num2, num2, num2);
			clone.transform.localPosition = -(val3 * (((Bounds)(ref bounds)).center * num2));
			return val4;
		}

		private static void Grow(ref Bounds bounds, ref bool found, Matrix4x4 local, Bounds mesh)
		{
			//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_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: 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_003e: 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_0029: 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)
			Vector3 val = ((Matrix4x4)(ref local)).MultiplyPoint3x4(((Bounds)(ref mesh)).min);
			Vector3 val2 = ((Matrix4x4)(ref local)).MultiplyPoint3x4(((Bounds)(ref mesh)).max);
			if (!found)
			{
				bounds = new Bounds(val, Vector3.zero);
				found = true;
			}
			((Bounds)(ref bounds)).Encapsulate(val);
			((Bounds)(ref bounds)).Encapsulate(val2);
		}
	}
	internal class Carrier : MonoBehaviour
	{
		private enum Phase
		{
			Flying,
			Fading
		}

		public const float Orbit = 0.34f;

		public static float Spin = 24f;

		public static float BobHeight = 0.045f;

		public static float BobPeriod = 3.1f;

		public static float DriftMin = 4f;

		public static float DriftMax = 13f;

		private const float Awake = 1.6f;

		private static readonly int EmissionColour = Shader.PropertyToID("_EmissionColor");

		private Renderer[] _renderers;

		private MaterialPropertyBlock _block;

		public static float FadeTime = 0.45f;

		public Transform Body;

		public Transform Hoop;

		public Transform Sling;

		public Transform Hook;

		private readonly List<Transform> _rings = new List<Transform>();

		private readonly List<Transform> _motes = new List<Transform>();

		private readonly List<float> _moteAngle = new List<float>();

		private readonly List<float> _moteRate = new List<float>();

		private Light _light;

		private Phase _phase;

		private SpiritTrips.Flight _flight;

		private bool _hasFlight;

		private float _fade;

		private Vector3 _spin;

		private Vector3 _rest;

		private float _bobPhase;

		private float _pulsePhase;

		private float _scale = 1f;

		private GameObject _cargo;

		public static Color LightColour => ForestSpirit.LightColour;

		public static float LightRange => ForestSpirit.LightRange;

		public static float PulseDepth => ForestSpirit.PulseDepth;

		public static float PulsePeriod => ForestSpirit.PulsePeriod;

		private void Start()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			Random random = new Random(((Object)this).GetInstanceID());
			_spin = new Vector3(Signed(random), Signed(random), Signed(random));
			_bobPhase = (float)random.NextDouble() * (float)Math.PI * 2f;
			_pulsePhase = (float)random.NextDouble() * (float)Math.PI * 2f;
			_scale = ((Component)this).transform.localScale.x;
			_rest = (((Object)(object)Body != (Object)null) ? Body.localPosition : Vector3.zero);
			CollectMotes(random);
			MakeLight();
		}

		private static float Signed(Random random)
		{
			float num = 1f + (float)random.NextDouble();
			if (random.Next(2) != 0)
			{
				return num;
			}
			return 0f - num;
		}

		private void CollectMotes(Random random)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Expected O, but got Unknown
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Hoop == (Object)null)
			{
				return;
			}
			foreach (Transform item in Hoop)
			{
				Transform val = item;
				if (!((Object)val).name.StartsWith("ring"))
				{
					continue;
				}
				_rings.Add(val);
				foreach (Transform item2 in val)
				{
					Transform val2 = item2;
					if (((Object)val2).name.StartsWith("mote"))
					{
						_motes.Add(val2);
						_moteAngle.Add(Mathf.Atan2(val2.localPosition.y, val2.localPosition.x) * 57.29578f);
						float num = DriftMin + (float)random.NextDouble() * (DriftMax - DriftMin);
						_moteRate.Add((random.Next(2) == 0) ? (0f - num) : num);
					}
				}
			}
		}

		private void MakeLight()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0061: 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_0093: Expected O, but got Unknown
			GameObject val = new GameObject("carrier_light");
			val.transform.SetParent(((Object)(object)Body != (Object)null) ? Body : ((Component)this).transform, false);
			_light = val.AddComponent<Light>();
			_light.type = (LightType)2;
			_light.range = LightRange;
			_light.color = LightColour;
			_light.intensity = 1.6f;
			_renderers = ((Component)this).GetComponentsInChildren<Renderer>(true);
			_block = new MaterialPropertyBlock();
			_light.shadows = (LightShadows)0;
		}

		public void Follow(SpiritTrips.Flight flight)
		{
			if (_phase != Phase.Fading)
			{
				_flight = flight;
				_hasFlight = true;
			}
		}

		public void Carry(GameObject model)
		{
			//IL_004f: 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)
			Release();
			if (!((Object)(object)model == (Object)null))
			{
				_cargo = model;
				_cargo.transform.SetParent(((Object)(object)Hook != (Object)null) ? Hook : ((Component)this).transform, false);
				_cargo.transform.localPosition = Vector3.zero;
				_cargo.transform.localRotation = Quaternion.identity;
			}
		}

		public void Release()
		{
			if (!((Object)(object)_cargo == (Object)null))
			{
				Object.Destroy((Object)(object)_cargo);
				_cargo = null;
			}
		}

		public void Dismiss()
		{
			if (_phase != Phase.Fading)
			{
				Release();
				_fade = FadeTime;
				_phase = Phase.Fading;
			}
		}

		private void Update()
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: 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)
			float deltaTime = Time.deltaTime;
			switch (_phase)
			{
			case Phase.Flying:
				if (_hasFlight)
				{
					((Component)this).transform.position = _flight.At(SpiritTrips.Now);
				}
				break;
			case Phase.Fading:
			{
				_fade -= deltaTime;
				if (_fade <= 0f)
				{
					Object.Destroy((Object)(object)((Component)this).gameObject);
					return;
				}
				float num = Mathf.Clamp01(_fade / Mathf.Max(0.01f, FadeTime));
				((Component)this).transform.localScale = Vector3.one * _scale * num;
				if ((Object)(object)_light != (Object)null)
				{
					_light.intensity = 1.6f * num;
				}
				break;
			}
			}
			Animate(Time.time, deltaTime);
		}

		private void Animate(float time, float delta)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Hoop != (Object)null)
			{
				Hoop.Rotate(_spin * Spin * delta, (Space)1);
			}
			float num = Spin * delta;
			for (int i = 0; i < _rings.Count; i++)
			{
				if (!((Object)(object)_rings[i] == (Object)null))
				{
					_rings[i].Rotate(0f, 0f, num, (Space)1);
				}
			}
			if ((Object)(object)Body != (Object)null)
			{
				float num2 = Mathf.Sin(time * ((float)Math.PI * 2f / BobPeriod) + _bobPhase);
				Body.localPosition = _rest + new Vector3(0f, num2 * BobHeight, 0f);
			}
			Drift(delta);
			Sway(time);
			Pulse(time);
		}

		private void Drift(float delta)
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < _motes.Count; i++)
			{
				if (!((Object)(object)_motes[i] == (Object)null))
				{
					_moteAngle[i] += _moteRate[i] * delta;
					float num = _moteAngle[i] * ((float)Math.PI / 180f);
					_motes[i].localPosition = new Vector3(Mathf.Cos(num) * 0.34f, Mathf.Sin(num) * 0.34f, 0f);
				}
			}
		}

		private void Sway(float time)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)Sling == (Object)null))
			{
				Sling.localRotation = Quaternion.Euler(Mathf.Sin(time * 1.7f) * 4.5f, 0f, Mathf.Cos(time * 1.3f) * 5.5f);
			}
		}

		private void Pulse(float time)
		{
			//IL_0063: 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_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_light == (Object)null || _phase == Phase.Fading)
			{
				return;
			}
			float num = Mathf.Sin(time * ((float)Math.PI * 2f / PulsePeriod) + _pulsePhase);
			float num2 = 1f + num * PulseDepth;
			_light.intensity = 1.6f * num2;
			if (_renderers == null || _block == null)
			{
				return;
			}
			Color val = LightColour * num2;
			Renderer[] renderers = _renderers;
			foreach (Renderer val2 in renderers)
			{
				if (!((Object)(object)val2 == (Object)null))
				{
					Material sharedMaterial = val2.sharedMaterial;
					if (!((Object)(object)sharedMaterial == (Object)null) && sharedMaterial.HasProperty(EmissionColour))
					{
						val2.GetPropertyBlock(_block);
						_block.SetColor(EmissionColour, val);
						val2.SetPropertyBlock(_block);
					}
				}
			}
		}
	}
	internal static class CarrierModel
	{
		private const string HeartMesh = "grove_spirit_heart.obj";

		private const string HoopMesh = "grove_spirit_hoop.obj";

		private const string MoteMesh = "grove_spirit_mote.obj";

		private const int Rings = 2;

		private const int Motes = 6;

		private static readonly bool ShowHoop;

		private const float SlingDrop = 0.155f;

		private const float TetherHigh = 0.035f;

		private const float TetherLow = 0.09f;

		private static ModelData _heart;

		private static ModelData _hoop;

		private static ModelData _mote;

		private static bool _missing;

		public static void Invalidate()
		{
			_heart = null;
			_hoop = null;
			_mote = null;
			_missing = false;
		}

		public static Carrier Build(Vector3 at)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			//IL_002f: 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_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected O, but got Unknown
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Expected O, but got Unknown
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Expected O, but got Unknown
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Expected O, but got Unknown
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			if (!LoadMeshes())
			{
				return null;
			}
			float num = Mathf.Max(0.05f, StowConfig.CarrierScale.Value);
			GameObject val = new GameObject("stow_carrier");
			val.transform.position = at;
			val.transform.localScale = new Vector3(num, num, num);
			GameObject val2 = new GameObject("body");
			val2.transform.SetParent(val.transform, false);
			Part(val2.transform, "heart", _heart);
			GameObject val3 = new GameObject("rings");
			val3.transform.SetParent(val2.transform, false);
			BuildRings(val3.transform);
			GameObject val4 = new GameObject("sling");
			val4.transform.SetParent(val2.transform, false);
			val4.transform.localPosition = new Vector3(0f, -0.34f, 0f);
			Bead(val4.transform, "tether_high", 0.035f, 1.2f);
			Bead(val4.transform, "tether_low", 0.09f, 0.92f);
			GameObject val5 = new GameObject("hook");
			val5.transform.SetParent(val4.transform, false);
			val5.transform.localPosition = new Vector3(0f, -0.155f, 0f);
			Flare.Attach(val2.transform, 0.884f);
			Carrier carrier = val.AddComponent<Carrier>();
			carrier.Body = val2.transform;
			carrier.Hoop = val3.transform;
			carrier.Sling = val4.transform;
			carrier.Hook = val5.transform;
			return carrier;
		}

		private static void BuildRings(Transform parent)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < 2; i++)
			{
				GameObject val = new GameObject("ring" + i);
				val.transform.SetParent(parent, false);
				val.transform.localRotation = Quaternion.Euler(90f + 90f * (float)i, 0f, 0f);
				if (ShowHoop)
				{
					Part(val.transform, "hoop", _hoop);
				}
				for (int j = 0; j < 6; j++)
				{
					float num = (60f * (float)j + 12f * (float)i) * ((float)Math.PI / 180f);
					Part(val.transform, "mote" + i + "_" + j, _mote).transform.localPosition = new Vector3(Mathf.Cos(num) * 0.34f, Mathf.Sin(num) * 0.34f, 0f);
				}
			}
		}

		private static GameObject Bead(Transform parent, string name, float drop, float size)
		{
			//IL_001e: 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)
			GameObject obj = Part(parent, name, _mote);
			obj.transform.localPosition = new Vector3(0f, 0f - drop, 0f);
			obj.transform.localScale = new Vector3(size, size, size);
			return obj;
		}

		private static GameObject Part(Transform parent, string name, ModelData model)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: 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_0049: Expected O, but got Unknown
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			val.AddComponent<MeshFilter>().sharedMesh = model.Mesh;
			MeshRenderer obj = val.AddComponent<MeshRenderer>();
			((Renderer)obj).sharedMaterials = Skins.Skin(model.Groups);
			((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0;
			((Renderer)obj).receiveShadows = false;
			return val;
		}

		private static bool LoadMeshes()
		{
			if (_heart != null && _hoop != null && _mote != null)
			{
				return true;
			}
			if (_missing)
			{
				return false;
			}
			string? directoryName = Path.GetDirectoryName(typeof(CarrierModel).Assembly.Location);
			_heart = ObjMesh.Load(Path.Combine(directoryName, "grove_spirit_heart.obj"));
			_hoop = ObjMesh.Load(Path.Combine(directoryName, "grove_spirit_hoop.obj"));
			_mote = ObjMesh.Load(Path.Combine(directoryName, "grove_spirit_mote.obj"));
			if (_heart != null && _hoop != null && _mote != null)
			{
				Dress(_heart);
				Dress(_hoop);
				Dress(_mote);
				return true;
			}
			_missing = true;
			StowRuntime.Log.LogError((object)"Carrier meshes are missing from beside the dll - the post will move things instantly instead. Expected grove_spirit_heart.obj, grove_spirit_hoop.obj and grove_spirit_mote.obj.");
			return false;
		}

		private static void Dress(ModelData model)
		{
			Skins.Skin(model.Groups);
			Skins.Remap(model.Mesh, model.Groups);
		}
	}
	internal class CarryRun
	{
		private enum Errand
		{
			Stow,
			Fetch,
			Tidy,
			Resting
		}

		private sealed class Courier
		{
			public Errand Errand;

			public ItemData Item;

			public Container Target;

			public Container Source;

			public bool Outbound;

			public SpiritTrips.Flight Flight;

			public double ReadyAt;

			public bool Idle(double now)
			{
				return now >= ReadyAt;
			}
		}

		private const float ScanInterval = 3f;

		private const float PostHover = 0.45f;

		private const float ChestHover = 0.35f;

		private readonly StowPost _post;

		private readonly List<Courier> _couriers = new List<Courier>();

		private readonly List<ItemData> _reserved = new List<ItemData>();

		private readonly List<Container> _touched = new List<Container>();

		private Transform _heartwood;

		private float _nextScan;

		private int _moved;

		public bool Working => _couriers.Count > 0;

		public CarryRun(StowPost post)
		{
			_post = post;
		}

		public void Wake()
		{
			_nextScan = 0f;
		}

		public void Abandon()
		{
			if (_couriers.Count != 0 || _reserved.Count != 0 || _moved != 0)
			{
				_couriers.Clear();
				_reserved.Clear();
				_touched.Clear();
				_moved = 0;
				Publish();
			}
		}

		public void Tick()
		{
			Container val = (((Object)(object)_post != (Object)null) ? _post.Container : null);
			Inventory val2 = (((Object)(object)val != (Object)null) ? val.GetInventory() : null);
			if (val2 == null)
			{
				Abandon();
				return;
			}
			ZNetView component = ((Component)_post).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || !component.IsValid() || !component.IsOwner())
			{
				Abandon();
				return;
			}
			double now = SpiritTrips.Now;
			for (int num = _couriers.Count - 1; num >= 0; num--)
			{
				Courier courier = _couriers[num];
				if (courier.Idle(now))
				{
					if (courier.Outbound)
					{
						Land(courier, val2, component);
					}
					else
					{
						Arrive(courier, component);
						if (!Dispatch(courier, val2, now))
						{
							Retire(courier, num);
						}
					}
				}
			}
			Recruit(val2, now);
			Publish();
			foreach (Courier courier2 in _couriers)
			{
				if (courier2.Errand != Errand.Resting)
				{
					return;
				}
			}
			_reserved.Clear();
			if (_moved > 0)
			{
				Announce();
			}
		}

		private void Land(Courier courier, Inventory inventory, ZNetView nview)
		{
			//IL_0022: 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_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			ItemData item = courier.Item;
			Errand errand = courier.Errand;
			Container source = courier.Source;
			Container target = courier.Target;
			Vector3 to = courier.Flight.To;
			courier.Outbound = false;
			bool flag = false;
			bool flag2 = false;
			string cargo = null;
			nview.ClaimOwnership();
			switch (errand)
			{
			case Errand.Stow:
				flag = !Move(inventory, target, item, ref cargo, celebrate: true);
				break;
			case Errand.Fetch:
				flag2 = Ready(source, item);
				if (flag2)
				{
					cargo = ItemGroups.PrefabNameOf(item);
				}
				break;
			case Errand.Tidy:
				flag = !Move(Held(source), target, item, ref cargo, celebrate: true);
				break;
			}
			if (!flag2)
			{
				courier.Item = null;
				courier.Source = null;
				if (!flag && item != null)
				{
					_reserved.Remove(item);
				}
			}
			courier.Target = null;
			Launch(courier, to, Home(), cargo, SpiritTrips.Now);
		}

		private bool Ready(Container source, ItemData item)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			Inventory val = Held(source);
			Inventory val2 = (((Object)(object)_post.Container != (Object)null) ? _post.Container.GetInventory() : null);
			if (val != null && val2 != null && item != null && val.ContainsItem(item) && val2.CanAddItem(item, -1))
			{
				return Depositor.Usable(source, ((Component)_post).transform.position, StowConfig.Range.Value);
			}
			return false;
		}

		private void Arrive(Courier courier, ZNetView nview)
		{
			if (courier.Errand == Errand.Fetch && courier.Item != null)
			{
				ItemData item = courier.Item;
				Container source = courier.Source;
				courier.Item = null;
				courier.Source = null;
				nview.ClaimOwnership();
				string cargo = null;
				Move(Held(source), _post.Container, item, ref cargo, celebrate: true);
				_reserved.Remove(item);
			}
		}

		private static Inventory Held(Container container)
		{
			if (!((Object)(object)container == (Object)null))
			{
				return container.GetInventory();
			}
			return null;
		}

		private bool Move(Inventory from, Container into, ItemData item, ref string cargo, bool celebrate)
		{
			//IL_0028: 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_00d8: Unknown result type (might be due to invalid IL or missing references)
			if (from == null || (Object)(object)into == (Object)null || item == null)
			{
				return true;
			}
			if (!from.ContainsItem(item))
			{
				return true;
			}
			if (!Depositor.Usable(into, ((Component)_post).transform.position, StowConfig.Range.Value))
			{
				return true;
			}
			cargo = ItemGroups.PrefabNameOf(item);
			bool emptied;
			int num = Depositor.Deposit(from, into, item, out emptied);
			if (num <= 0)
			{
				StowRuntime.Log.LogWarning((object)("A container offered room for " + item.m_shared.m_name + " and then accepted none - not trying it again this run."));
				return false;
			}
			_moved += num;
			if (!_touched.Contains(into))
			{
				_touched.Add(into);
			}
			if (celebrate && (Object)(object)InventoryGui.instance != (Object)null && InventoryGui.instance.m_moveItemEffects != null)
			{
				InventoryGui.instance.m_moveItemEffects.Create(((Component)into).transform.position, Quaternion.identity, (Transform)null, 1f, -1);
			}
			return true;
		}

		private bool Dispatch(Courier courier, Inventory inventory, double now)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: 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_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			Container container = _post.Container;
			Vector3 position = ((Component)_post).transform.position;
			if (Available(inventory) && Depositor.NextTrip(inventory, position, _reserved, out var item, out var target))
			{
				Begin(courier, Errand.Stow, item, null, target, AimAt(target), ItemGroups.PrefabNameOf(item), now, "carrying");
				return true;
			}
			if (Available(inventory) && Depositor.NextFetch(container, position, _reserved, out item, out var source))
			{
				Begin(courier, Errand.Fetch, item, source, null, AimAt(source), null, now, "fetching");
				return true;
			}
			if (PostRules.Tidy(container) && Depositor.NextTidy(position, _reserved, out item, out source, out target))
			{
				Begin(courier, Errand.Tidy, item, source, target, AimAt(source), null, now, "tidying");
				return true;
			}
			if (PostRules.Where(container) != PostRules.Presence.LivesHere)
			{
				return false;
			}
			if (courier.Errand != Errand.Resting)
			{
				courier.Errand = Errand.Resting;
				courier.Item = null;
				courier.Source = null;
				courier.Target = null;
				courier.Outbound = false;
				Launch(courier, courier.Flight.To, Home(), null, now);
			}
			courier.ReadyAt = now + 3.0;
			return true;
		}

		private void Begin(Courier courier, Errand errand, ItemData item, Container source, Container target, Vector3 aim, string cargo, double now, string verb)
		{
			//IL_0051: 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_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			courier.Errand = errand;
			courier.Item = item;
			courier.Source = source;
			courier.Target = target;
			courier.Outbound = true;
			_reserved.Add(item);
			Vector3 val = ((courier.Flight.Duration > 0f) ? courier.Flight.To : Home());
			Launch(courier, val, aim, cargo, now);
			if (StowConfig.Verbose.Value)
			{
				StowRuntime.Log.LogInfo((object)(verb + " " + item.m_stack + "x " + item.m_shared.m_name));
			}
		}

		private void Recruit(Inventory inventory, double now)
		{
			int num = Mathf.Clamp(StowConfig.Couriers.Value, 1, 8);
			if (_couriers.Count >= num)
			{
				return;
			}
			Container container = _post.Container;
			if ((inventory.NrOfItems() != 0 || PostRules.Fetch(container).Count != 0 || PostRules.Tidy(container) || PostRules.Where(container) == PostRules.Presence.LivesHere) && !(Time.time < _nextScan))
			{
				_nextScan = Time.time + 3f;
				Courier courier = new Courier
				{
					ReadyAt = now
				};
				_couriers.Add(courier);
				if (!Dispatch(courier, inventory, now))
				{
					_couriers.Remove(courier);
				}
			}
		}

		private void Retire(Courier courier, int index)
		{
			if (courier.Item != null)
			{
				_reserved.Remove(courier.Item);
			}
			_couriers.RemoveAt(index);
		}

		private bool Available(Inventory inventory)
		{
			if (inventory.NrOfItems() == 0)
			{
				return false;
			}
			Container container = _post.Container;
			if (!((Object)(object)container == (Object)null))
			{
				return !container.IsInUse();
			}
			return true;
		}

		public void Instant(Inventory inventory)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			int chestCount;
			int moved = Depositor.Distribute(inventory, ((Component)_post).transform.position, out chestCount);
			_moved = moved;
			_touched.Clear();
			Announce(chestCount);
		}

		private void Announce()
		{
			Announce(_touched.Count);
		}

		private void Announce(int chests)
		{
			int moved = _moved;
			_moved = 0;
			_touched.Clear();
			if (StowConfig.Messages.Value && !((Object)(object)Player.m_localPlayer == (Object)null))
			{
				Container container = _post.Container;
				Inventory val = (((Object)(object)container != (Object)null) ? container.GetInventory() : null);
				int num = ((val != null) ? val.NrOfItems() : 0);
				string text = ((moved != 0) ? ("Stowed " + moved + " item" + ((moved == 1) ? "" : "s") + " into " + chests + " chest" + ((chests == 1) ? "" : "s") + ".") : ((num > 0) ? "Nothing here has a home yet." : ""));
				if (num > 0 && moved > 0)
				{
					text = text + " " + num + " left waiting.";
				}
				if (text.Length != 0)
				{
					((Character)Player.m_localPlayer).Message((MessageType)2, Localization.instance.Localize(text), 0, (Sprite)null);
				}
			}
		}

		private void Launch(Courier courier, Vector3 from, Vector3 to, string cargo, double now)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: 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_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: 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_0095: 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_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Max(from.y, to.y) + Mathf.Max(0f, StowConfig.CarrierCruise.Value);
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor((from.x + to.x) * 0.5f, num, (from.z + to.z) * 0.5f);
			float num2 = Mathf.Max(0.4f, StowConfig.CarrierSpeed.Value);
			float num3 = Vector3.Distance(from, val) + Vector3.Distance(val, to);
			float num4 = Mathf.Max(0.35f, num3 / num2);
			courier.Flight = new SpiritTrips.Flight
			{
				From = from,
				Control = val,
				To = to,
				Cargo = cargo,
				Start = now,
				Duration = num4
			};
			courier.ReadyAt = now + (double)num4 + (double)Mathf.Max(0f, StowConfig.CarrierPause.Value);
		}

		private void Publish()
		{
			ZNetView val = (((Object)(object)_post != (Object)null) ? ((Component)_post).GetComponent<ZNetView>() : null);
			if ((Object)(object)val == (Object)null || !val.IsValid() || !val.IsOwner())
			{
				return;
			}
			List<SpiritTrips.Flight> list = new List<SpiritTrips.Flight>();
			foreach (Courier courier in _couriers)
			{
				list.Add(courier.Flight);
			}
			SpiritTrips.Publish(val, SpiritTrips.Encode(list));
		}

		private Vector3 Home()
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_heartwood == (Object)null)
			{
				_heartwood = ((Component)_post).transform.Find("post_visual/heartwood");
			}
			if (!((Object)(object)_heartwood != (Object)null))
			{
				return Above(((Component)_post).transform, 0.45f, 1f);
			}
			return _heartwood.position;
		}

		private static Vector3 AimAt(Container container)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			return Above(((Component)container).transform, 0.35f, 0.5f);
		}

		private static Vector3 Above(Transform thing, float clearance, float fallback)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: 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_002a: 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_0035: 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_0044: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = thing.position;
			Collider componentInChildren = ((Component)thing).GetComponentInChildren<Collider>();
			float num;
			if (!((Object)(object)componentInChildren != (Object)null))
			{
				num = position.y + fallback;
			}
			else
			{
				Bounds bounds = componentInChildren.bounds;
				num = ((Bounds)(ref bounds)).max.y;
			}
			float num2 = num;
			return new Vector3(position.x, num2 + clearance, position.z);
		}
	}
	internal static class ChestFilter
	{
		public sealed class Rule
		{
			public Container Container;

			public float Distance;

			public bool Configured;

			public bool CatchesAll;

			public readonly HashSet<string> Items = new HashSet<string>();

			public readonly List<ItemGroup> Groups = new List<ItemGroup>();

			public readonly HashSet<string> NotItems = new HashSet<string>();

			public readonly List<ItemGroup> NotGroups = new List<ItemGroup>();

			public int Match(ItemData item)
			{
				if (item == null || item.m_shared == null)
				{
					return -1;
				}
				string name = item.m_shared.m_name;
				if (Excludes(name))
				{
					return -1;
				}
				if (Configured)
				{
					if (Items.Contains(name))
					{
						return 3;
					}
					foreach (ItemGroup group in Groups)
					{
						if (group.Members.Contains(name))
						{
							return 2;
						}
					}
					if (!CatchesAll)
					{
						return -1;
					}
					return 1;
				}
				if (!StowConfig.MatchContents.Value)
				{
					return -1;
				}
				Inventory inventory = Container.GetInventory();
				if (inventory == null || !inventory.ContainsItemByName(name))
				{
					return -1;
				}
				return 0;
			}

			public bool Refuses(ItemData item)
			{
				if (item != null && item.m_shared != null)
				{
					return Excludes(item.m_shared.m_name);
				}
				return false;
			}

			private bool Excludes(string shared)
			{
				if (NotItems.Contains(shared))
				{
					return true;
				}
				foreach (ItemGroup notGroup in NotGroups)
				{
					if (notGroup.Members.Contains(shared))
					{
						return true;
					}
				}
				return false;
			}
		}

		private const string ZFilter = "stowFilter";

		public const string CatchAll = "*";

		public const int TierNone = -1;

		public const int TierContents = 0;

		public const int TierCatchAll = 1;

		public const int TierGroup = 2;

		public const int TierItem = 3;

		public static string Read(Container container)
		{
			ZDO val = Zdo(container);
			if (val != null)
			{
				return val.GetString("stowFilter", "");
			}
			return "";
		}

		public static void Write(Container container, IEnumerable<string> entries)
		{
			ZNetView val = (((Object)(object)container == (Object)null) ? null : ((Component)container).GetComponent<ZNetView>());
			if (!((Object)(object)val == (Object)null) && val.IsValid())
			{
				val.ClaimOwnership();
				val.GetZDO().Set("stowFilter", string.Join(",", Clean(entries).ToArray()));
			}
		}

		public static List<string> Entries(Container container)
		{
			return Clean(Read(container).Split(new char[1] { ',' }));
		}

		private static List<string> Clean(IEnumerable<string> entries)
		{
			List<string> list = new List<string>();
			if (entries == null)
			{
				return list;
			}
			foreach (string entry in entries)
			{
				if (entry != null)
				{
					string text = entry.Trim();
					if (text.Length != 0 && !list.Contains(text))
					{
						list.Add(text);
					}
				}
			}
			return list;
		}

		public static bool IsGroup(string entry)
		{
			if (entry != null && entry.Length > 1)
			{
				return entry[0] == '@';
			}
			return false;
		}

		public static string GroupId(string entry)
		{
			if (!IsGroup(entry))
			{
				return null;
			}
			return entry.Substring(1);
		}

		public static bool IsExclusion(string entry)
		{
			if (entry != null && entry.Length > 1)
			{
				return entry[0] == '-';
			}
			return false;
		}

		public static string Bare(string entry)
		{
			if (!IsExclusion(entry))
			{
				return entry;
			}
			return entry.Substring(1);
		}

		public static Rule RuleFor(Container container, float distance)
		{
			Rule rule = new Rule
			{
				Container = container,
				Distance = distance
			};
			foreach (string item in Entries(container))
			{
				bool flag = IsExclusion(item);
				string text = Bare(item);
				if (text == "*")
				{
					if (!flag)
					{
						rule.CatchesAll = true;
						rule.Configured = true;
					}
					continue;
				}
				if (IsGroup(text))
				{
					ItemGroup itemGroup = ItemGroups.Find(GroupId(text));
					if (itemGroup != null)
					{
						if (flag)
						{
							rule.NotGroups.Add(itemGroup);
							continue;
						}
						rule.Groups.Add(itemGroup);
						rule.Configured = true;
					}
					continue;
				}
				string text2 = ItemGroups.SharedNameOf(text);
				if (text2 != null)
				{
					if (flag)
					{
						rule.NotItems.Add(text2);
						continue;
					}
					rule.Items.Add(text2);
					rule.Configured = true;
				}
			}
			return rule;
		}

		public static bool Matches(List<string> entries, ItemData item)
		{
			if (entries == null || item == null || item.m_shared == null)
			{
				return false;
			}
			string name = item.m_shared.m_name;
			bool result = false;
			foreach (string entry in entries)
			{
				bool flag = IsExclusion(entry);
				string text = Bare(entry);
				if (text == "*" || ((!IsGroup(text)) ? (ItemGroups.SharedNameOf(text) == name) : (ItemGroups.Find(GroupId(text))?.Members.Contains(name) ?? false)))
				{
					if (flag)
					{
						return false;
					}
					result = true;
				}
			}
			return result;
		}

		public static string Summary(Container container)
		{
			List<string> list = Entries(container);
			if (list.Count == 0)
			{
				return null;
			}
			List<string> list2 = new List<string>();
			List<string> list3 = new List<string>();
			foreach (string item2 in list)
			{
				bool flag = IsExclusion(item2);
				string text = Bare(item2);
				string item;
				if (text == "*")
				{
					item = "anything else";
				}
				else if (IsGroup(text))
				{
					ItemGroup itemGroup = ItemGroups.Find(GroupId(text));
					item = ((itemGroup != null) ? itemGroup.Display.ToLowerInvariant() : GroupId(text));
				}
				else
				{
					item = ItemGroups.DisplayNameOf(text);
				}
				(flag ? list3 : list2).Add(item);
			}
			string text2 = string.Join(", ", list2.ToArray());
			if (list3.Count == 0)
			{
				return text2;
			}
			string text3 = "not " + string.Join(" or ", list3.ToArray());
			if (text2.Length != 0)
			{
				return text2 + " - " + text3;
			}
			return text3;
		}

		private static ZDO Zdo(Container container)
		{
			if ((Object)(object)container == (Object)null)
			{
				return null;
			}
			ZNetView component = ((Component)container).GetComponent<ZNetView>();
			if (!((Object)(object)component != (Object)null) || !component.IsValid())
			{
				return null;
			}
			return component.GetZDO();
		}
	}
	internal static class Depositor
	{
		private sealed class Plan
		{
			public ItemData Item;

			public int Tier;
		}

		private static readonly Collider[] Hits = (Collider[])(object)new Collider[256];

		private static HashSet<string> _neverStow;

		private static string _neverStowRaw;

		public static int Distribute(Inventory source, Vector3 origin, out int chestCount, Predicate<ItemData> allow = null)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			chestCount = 0;
			if (source == null || !ItemGroups.Ready)
			{
				return 0;
			}
			List<ChestFilter.Rule> list = new List<ChestFilter.Rule>();
			CollectChests(origin, list);
			if (list.Count == 0)
			{
				return 0;
			}
			List<Plan> list2 = new List<Plan>();
			foreach (ItemData item in new List<ItemData>(source.GetAllItems()))
			{
				if (allow == null || allow(item))
				{
					int num = BestTier(list, item);
					if (num != -1)
					{
						list2.Add(new Plan
						{
							Item = item,
							Tier = num
						});
					}
				}
			}
			if (list2.Count == 0)
			{
				return 0;
			}
			list2.Sort((Plan a, Plan b) => b.Tier.CompareTo(a.Tier));
			int num2 = 0;
			List<Container> list3 = new List<Container>();
			foreach (Plan item2 in list2)
			{
				num2 += Place(source, list, item2.Item, list3);
			}
			foreach (Container item3 in list3)
			{
				if ((Object)(object)InventoryGui.instance != (Object)null && InventoryGui.instance.m_moveItemEffects != null)
				{
					InventoryGui.instance.m_moveItemEffects.Create(((Component)item3).transform.position, Quaternion.identity, (Transform)null, 1f, -1);
				}
			}
			chestCount = list3.Count;
			return num2;
		}

		public static void Run(Player player)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null)
			{
				return;
			}
			if (!ItemGroups.Ready)
			{
				Announce("Item catalogue not loaded yet.");
				return;
			}
			int chestCount;
			int num = Distribute(((Humanoid)player).GetInventory(), ((Component)player).transform.position, out chestCount, (ItemData item) => Stowable(player, item));
			if (num == 0)
			{
				Announce("Nothing here belongs in those chests.");
				return;
			}
			Announce("Stowed " + num + " item" + ((num == 1) ? "" : "s") + " into " + chestCount + " chest" + ((chestCount == 1) ? "" : "s") + ".");
		}

		private static int Place(Inventory source, List<ChestFilter.Rule> rules, ItemData item, List<Container> touched)
		{
			int num = 0;
			while (item.m_stack > 0)
			{
				Container val = BestChestWithRoom(rules, item);
				if ((Object)(object)val == (Object)null)
				{
					break;
				}
				bool emptied;
				int num2 = Deposit(source, val, item, out emptied);
				if (num2 < 0)
				{
					break;
				}
				num += num2;
				if (num2 > 0 && !touched.Contains(val))
				{
					touched.Add(val);
				}
				if (emptied || num2 == 0)
				{
					break;
				}
			}
			return num;
		}

		public static int Deposit(Inventory source, Container target, ItemData item, out bool emptied)
		{
			emptied = false;
			if (source == null || (Object)(object)target == (Object)null || item == null)
			{
				return -1;
			}
			ZNetView component = ((Component)target).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || !component.IsValid())
			{
				return -1;
			}
			Inventory inventory = target.GetInventory();
			if (inventory == null)
			{
				return -1;
			}
			component.ClaimOwnership();
			int value = StowConfig.ItemsPerTrip.Value;
			int num = ((value > 0) ? Mathf.Min(value, item.m_stack) : item.m_stack);
			ItemData val = item.Clone();
			val.m_stack = num;
			int num2 = (inventory.AddItem(val) ? num : (num - val.m_stack));
			item.m_stack -= num2;
			if (item.m_stack <= 0)
			{
				source.RemoveItem(item);
				emptied = true;
			}
			if (num2 > 0 && StowConfig.Verbose.Value)
			{
				StowRuntime.Log.LogInfo((object)("stowed " + num2 + "x " + item.m_shared.m_name + " into " + target.m_name));
			}
			return num2;
		}

		public static bool NextFetch(Container post, Vector3 origin, List<ItemData> reserved, out ItemData item, out Container source)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			item = null;
			source = null;
			if ((Object)(object)post == (Object)null || !ItemGroups.Ready)
			{
				return false;
			}
			List<string> list = PostRules.Fetch(post);
			if (list.Count == 0)
			{
				return false;
			}
			Inventory inventory = post.GetInventory();
			if (inventory == null)
			{
				return false;
			}
			List<ChestFilter.Rule> list2 = new List<ChestFilter.Rule>();
			CollectChests(origin, list2);
			foreach (ChestFilter.Rule item2 in list2)
			{
				Inventory inventory2 = item2.Container.GetInventory();
				if (inventory2 == null)
				{
					continue;
				}
				foreach (ItemData allItem in inventory2.GetAllItems())
				{
					if ((reserved == null || !reserved.Contains(allItem)) && ChestFilter.Matches(list, allItem) && inventory.CanAddItem(allItem, -1))
					{
						item = allItem;
						source = item2.Container;
						return true;
					}
				}
			}
			return false;
		}

		public static bool NextTidy(Vector3 origin, List<ItemData> reserved, out ItemData item, out Container source, out Container target)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			item = null;
			source = null;
			target = null;
			if (!ItemGroups.Ready)
			{
				return false;
			}
			List<ChestFilter.Rule> list = new List<ChestFilter.Rule>();
			CollectChests(origin, list);
			if (list.Count < 2)
			{
				return false;
			}
			foreach (ChestFilter.Rule item2 in list)
			{
				Inventory inventory = item2.Container.GetInventory();
				if (inventory == null)
				{
					continue;
				}
				foreach (ItemData allItem in inventory.GetAllItems())
				{
					if ((reserved == null || !reserved.Contains(allItem)) && item2.Match(allItem) == -1 && item2.Refuses(allItem))
					{
						Container val = BestChestWithRoom(list, allItem);
						if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)item2.Container))
						{
							item = allItem;
							source = item2.Container;
							target = val;
							return true;
						}
					}
				}
			}
			return false;
		}

		public static bool NextTrip(Inventory source, Vector3 origin, List<ItemData> reserved, out ItemData item, out Container target)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			item = null;
			target = null;
			if (source == null || !ItemGroups.Ready)
			{
				return false;
			}
			List<ChestFilter.Rule> list = new List<ChestFilter.Rule>();
			CollectChests(origin, list);
			if (list.Count == 0)
			{
				return false;
			}
			List<Plan> list2 = new List<Plan>();
			foreach (ItemData allItem in source.GetAllItems())
			{
				if (reserved == null || !reserved.Contains(allItem))
				{
					int num = BestTier(list, allItem);
					if (num != -1)
					{
						list2.Add(new Plan
						{
							Item = allItem,
							Tier = num
						});
					}
				}
			}
			if (list2.Count == 0)
			{
				return false;
			}
			list2.Sort((Plan a, Plan b) => b.Tier.CompareTo(a.Tier));
			foreach (Plan item2 in list2)
			{
				Container val = BestChestWithRoom(list, item2.Item);
				if (!((Object)(object)val == (Object)null))
				{
					item = item2.Item;
					target = val;
					return true;
				}
			}
			return false;
		}

		private static int BestTier(List<ChestFilter.Rule> rules, ItemData item)
		{
			int num = -1;
			foreach (ChestFilter.Rule rule in rules)
			{
				int num2 = rule.Match(item);
				if (num2 > num)
				{
					num = num2;
				}
			}
			return num;
		}

		public static Container BestChestWithRoom(List<ChestFilter.Rule> rules, ItemData item)
		{
			ChestFilter.Rule rule = null;
			int num = -1;
			foreach (ChestFilter.Rule rule2 in rules)
			{
				int num2 = rule2.Match(item);
				if (num2 != -1 && num2 >= num && (num2 != num || rule == null || !(rule2.Distance >= rule.Distance)))
				{
					Inventory inventory = rule2.Container.GetInventory();
					if (inventory != null && inventory.CanAddItem(item, 1))
					{
						rule = rule2;
						num = num2;
					}
				}
			}
			return rule?.Container;
		}

		public static void CollectChests(Vector3 point, List<ChestFilter.Rule> into)
		{
			//IL_0011: 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_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			into.Clear();
			float value = StowConfig.Range.Value;
			int num = Physics.OverlapSphereNonAlloc(point, value, Hits);
			List<Container> list = new List<Container>();
			for (int i = 0; i < num; i++)
			{
				Container componentInParent = ((Component)Hits[i]).GetComponentInParent<Container>();
				if (!((Object)(object)componentInParent == (Object)null) && !list.Contains(componentInParent))
				{
					list.Add(componentInParent);
					if (Usable(componentInParent, point, value))
					{
						into.Add(ChestFilter.RuleFor(componentInParent, Vector3.Distance(((Component)componentInParent).transform.position, point)));
					}
				}
			}
		}

		public static bool Usable(Container container, Vector3 point, float range)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Invalid comparison between Unknown and I4
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			ZNetView component = ((Component)container).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || !component.IsValid())
			{
				return false;
			}
			if (StowPost.Is(container))
			{
				return false;
			}
			if (Vector3.Distance(((Component)container).transform.position, point) > range)
			{
				return false;
			}
			if ((Object)(object)((Component)container).GetComponentInParent<Vagon>() != (Object)null)
			{
				return false;
			}
			if ((Object)(object)((Component)container).GetComponentInParent<Ship>() != (Object)null)
			{
				return false;
			}
			if ((int)container.m_privacy != 2)
			{
				return false;
			}
			if (container.IsInUse())
			{
				return false;
			}
			if (container.m_checkGuardStone && !PrivateArea.CheckAccess(((Component)container).transform.position, 0f, true, false))
			{
				return false;
			}
			return true;
		}

		private static bool Stowable(Player player, ItemData item)
		{
			if (item == null || item.m_shared == null)
			{
				return false;
			}
			if (item.m_equipped || ((Humanoid)player).IsItemEquiped(item))
			{
				return false;
			}
			if (StowConfig.KeepHotbar.Value && item.m_gridPos.y == 0)
			{
				return false;
			}
			string text = ItemGroups.PrefabNameOf(item);
			if (text != null && NeverStow().Contains(text))
			{
				return false;
			}
			return true;
		}

		private static HashSet<string> NeverStow()
		{
			string text = StowConfig.NeverStow.Value ?? "";
			if (_neverStow != null && text == _neverStowRaw)
			{
				return _neverStow;
			}
			_neverStowRaw = text;
			_neverStow = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
			string[] array = text.Split(new char[1] { ',' });
			for (int i = 0; i < array.Length; i++)
			{
				string text2 = array[i].Trim();
				if (text2.Length > 0)
				{
					_neverStow.Add(text2);
				}
			}
			return _neverStow;
		}

		private static void Announce(string message)
		{
			if (StowConfig.Messages.Value && !((Object)(object)Player.m_localPlayer == (Object)null))
			{
				((Character)Player.m_localPlayer).Message((MessageType)2, Localization.instance.Localize(message), 0, (Sprite)null);
			}
		}
	}
	internal static class FilterPanel
	{
		public static class Styles
		{
			public static GUIStyle Window;

			public static GUIStyle Title;

			public static GUIStyle Dim;

			public static GUIStyle Caption;

			public static GUIStyle CellOn;

			public static GUIStyle CellOff;

			public static GUIStyle CellNot;

			public static GUIStyle Chip;

			public static GUIStyle Row;

			public static GUIStyle Field;

			public static GUIStyle List;

			public static Texture2D RuleLine;

			private static bool _built;

			public static void Build()
			{
				//IL_000e: 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_002c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0035: Unknown result type (might be due to invalid IL or missing references)
				//IL_003f: Expected O, but got Unknown
				//IL_003f: 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_004e: Expected O, but got Unknown
				//IL_0053: Expected O, but got Unknown
				//IL_0058: Unknown result type (might be due to invalid IL or missing references)
				//IL_005d: Unknown result type (might be due to invalid IL or missing references)
				//IL_006e: Unknown result type (might be due to invalid IL or missing references)
				//IL_007f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0090: 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_00b2: Expected O, but got Unknown
				//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
				//IL_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_00e0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f6: 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_0113: Unknown result type (might be due to invalid IL or missing references)
				//IL_011d: Expected O, but got Unknown
				//IL_011f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0124: Unknown result type (might be due to invalid IL or missing references)
				//IL_0148: Unknown result type (might be due to invalid IL or missing references)
				//IL_014d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0155: Unknown result type (might be due to invalid IL or missing references)
				//IL_015a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0164: Expected O, but got Unknown
				//IL_0169: Expected O, but got Unknown
				//IL_018f: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
				//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
				//IL_01cb: Expected O, but got Unknown
				//IL_01d0: Expected O, but got Unknown
				//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
				//IL_01da: Unknown result type (might be due to invalid IL or missing references)
				//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
				//IL_01fc: Expected O, but got Unknown
				if (!_built)
				{
					_built = true;
					RuleLine = Theme.Solid(Theme.Rule);
					Window = new GUIStyle(GUI.skin.window)
					{
						padding = new RectOffset(14, 14, 12, 12),
						border = new RectOffset(1, 1, 1, 1)
					};
					Paint(Window, Theme.Bordered(Theme.Bg, Theme.Rule));
					Title = Label(14, Theme.Gold);
					Dim = Label(12, Theme.Dim);
					Caption = Label(12, Theme.Dim);
					Caption.margin = new RectOffset(0, 0, 2, 4);
					CellOff = Button(13, Theme.Ink, Theme.Row);
					CellOn = Button(13, Theme.Bg, Theme.Gold);
					CellNot = Button(13, Theme.Gold, Theme.Bg);
					Chip = Button(12, Theme.Gold, Theme.Panel);
					Chip.padding = new RectOffset(8, 8, 2, 2);
					Row = Button(13, Theme.Ink, Color.clear);
					Row.alignment = (TextAnchor)3;
					Field = new GUIStyle(GUI.skin.textField)
					{
						fontSize = 13,
						padding = new RectOffset(6, 6, 3, 3)
					};
					if ((Object)(object)Theme.Mono != (Object)null)
					{
						Field.font = Theme.Mono;
					}
					Field.normal.textColor = Theme.Ink;
					Field.focused.textColor = Theme.Ink;
					List = new GUIStyle(GUI.skin.box)
					{
						padding = new RectOffset(2, 2, 2, 2)
					};
					Paint(List, Theme.Bordered(Theme.Panel, Theme.Rule));
					List.border = new RectOffset(1, 1, 1, 1);
				}
			}

			private static GUIStyle Label(int size, Color colour)
			{
				//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_0016: 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_0025: Expected O, but got Unknown
				//IL_0025: 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_0034: Expected O, but got Unknown
				//IL_0034: 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_0043: Expected O, but got Unknown
				//IL_0061: Unknown result type (might be due to invalid IL or missing references)
				GUIStyle val = new GUIStyle(GUI.skin.label)
				{
					fontSize = size,
					padding = new RectOffset(0, 0, 1, 1),
					margin = new RectOffset(0, 0, 0, 0),
					wordWrap = false,
					clipping = (TextClipping)1
				};
				if ((Object)(object)Theme.Mono != (Object)null)
				{
					val.font = Theme.Mono;
				}
				val.normal.textColor = colour;
				return val;
			}

			private static GUIStyle Button(int size, Color ink, Color fill)
			{
				//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_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_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: Expected O, but got Unknown
				//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_003b: Expected O, but got Unknown
				//IL_003b: 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_004a: Expected O, but got Unknown
				//IL_0063: 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_0070: 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_00a0: 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)
				GUIStyle val = new GUIStyle(GUI.skin.button)
				{
					fontSize = size,
					alignment = (TextAnchor)4,
					padding = new RectOffset(4, 4, 2, 2),
					margin = new RectOffset(0, 0, 0, 0),
					wordWrap = false,
					clipping = (TextClipping)1
				};
				if ((Object)(object)Theme.Mono != (Object)null)
				{
					val.font = Theme.Mono;
				}
				Paint(val, (fill == Color.clear) ? Theme.Clear() : Theme.Solid(fill));
				val.normal.textColor = ink;
				val.hover.textColor = ink;
				val.active.textColor = ink;
				val.focused.textColor = ink;
				return val;
			}

			private static void Paint(GUIStyle style, Texture2D texture)
			{
				style.normal.background = texture;
				style.hover.background = texture;
				style.active.background = texture;
				style.focused.background = texture;
				style.onNormal.background = texture;
				style.onHover.background = texture;
				style.onActive.background = texture;
				style.onFocused.background = texture;
			}
		}

		[CompilerGenerated]
		private static class <>O
		{
			public static WindowFunction <0>__DrawWindow;

			public static Action <1>__CommitChest;
		}

		private const float WindowWidth = 520f;

		private const float CellWidth = 118f;

		private const float CellGap = 4f;

		private const int Columns = 4;

		private static Rect _window = new Rect(90f, 90f, 520f, 0f);

		private static Container _container;

		private static List<string> _entries = new List<string>();

		private static List<string> _edit;

		private static Action _save;

		private static string _search = "";

		private static Vector2 _searchScroll;

		public static bool IsOpen { get; private set; }

		private static void Editing(List<string> entries, Action commit)
		{
			_edit = entries;
			_save = commit;
		}

		public static void Open(Container container)
		{
			//IL_0025: 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)
			if (!((Object)(object)container == (Object)null))
			{
				_container = container;
				_entries = ChestFilter.Entries(container);
				_search = "";
				_searchScroll = Vector2.zero;
				IsOpen = true;
			}
		}

		public static void Close()
		{
			IsOpen = false;
			_container = null;
			_search = "";
		}

		public static void Draw()
		{
			//IL_0032: 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_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected O, but got Unknown
			if (!IsOpen)
			{
				return;
			}
			if ((Object)(object)_container == (Object)null || (Object)(object)Player.m_localPlayer == (Object)null)
			{
				Close();
				return;
			}
			Styles.Build();
			Rect window = _window;
			object obj = <>O.<0>__DrawWindow;
			if (obj == null)
			{
				WindowFunction val = DrawWindow;
				<>O.<0>__DrawWindow = val;
				obj = (object)val;
			}
			_window = GUILayout.Window(356372, window, (WindowFunction)obj, GUIContent.none, Styles.Window, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(520f) });
		}

		private static void DrawWindow(int id)
		{
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			DrawHeader();
			Caption("GROUPS");
			DrawGroupGrid(_entries, CommitChest, 118f, 4f, 4);
			GUILayout.Space(6f);
			Caption("SINGLE ITEMS");
			DrawItemPicker(_entries, CommitChest, ref _search, ref _searchScroll);
			DrawItemChips(_entries, CommitChest, 520f);
			GUILayout.Space(6f);
			Rule();
			DrawFooter();
			GUI.DragWindow(new Rect(0f, 0f, 10000f, 22f));
		}

		private static void DrawHeader()
		{
			Inventory inventory = _container.GetInventory();
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			if (inventory != null)
			{
				HashSet<string> hashSet = new HashSet<string>();
				foreach (ItemData allItem in inventory.GetAllItems())
				{
					if (allItem != null && allItem.m_shared != null)
					{
						hashSet.Add(allItem.m_shared.m_name);
					}
				}
				num = hashSet.Count;
				num2 = inventory.NrOfItems();
				num3 = inventory.GetWidth() * inventory.GetHeight();
			}
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label(Localization.instance.Localize(_container.m_name), Styles.Title, Array.Empty<GUILayoutOption>());
			GUILayout.FlexibleSpace();
			GUILayout.Label("holds " + num + " kind" + ((num == 1) ? "" : "s") + "  ·  " + num2 + "/" + num3 + " slots", Styles.Dim, Array.Empty<GUILayoutOption>());
			GUILayout.EndHorizontal();
			Rule();
		}

		public static void DrawGroupGrid(List<string> entries, Action commit, float cellWidth, float cellGap, int columns)
		{
			Editing(entries, commit);
			DrawGroups(cellWidth, cellGap, columns);
		}

		private static void DrawGroups(float CellWidth, float CellGap, int Columns)
		{
			IList<ItemGroup> groups = ItemGroups.Groups;
			int num = groups.Count + 1;
			int num2 = (num + Columns - 1) / Columns;
			for (int i = 0; i < num2; i++)
			{
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				for (int j = 0; j < Columns; j++)
				{
					int num3 = i * Columns + j;
					if (num3 >= num)
					{
						GUILayout.Space(CellWidth + CellGap);
						continue;
					}
					if (num3 < groups.Count)
					{
						ItemGroup itemGroup = groups[num3];
						Cell(itemGroup.Display, "@" + itemGroup.Id, CellWidth);
					}
					else
					{
						Cell("Anything else", "*", CellWidth);
					}
					if (j < Columns - 1)
					{
						GUILayout.Space(CellGap);
					}
				}
				GUILayout.EndHorizontal();
				GUILayout.Space(CellGap);
			}
		}

		private static void Cell(string label, string entry, float CellWidth)
		{
			bool num = _edit.Contains("-" + entry);
			bool flag = _edit.Contains(entry);
			GUIStyle val = (num ? Styles.CellNot : (flag ? Styles.CellOn : Styles.CellOff));
			if (GUILayout.Button(num ? ("not " + label) : label, val, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(CellWidth),
				GUILayout.Height(24f)
			}))
			{
				Cycle(entry);
			}
		}

		public static void DrawItemPicker(List<string> entries, Action commit, ref string search, ref Vector2 scroll)
		{
			//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_0026: 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)
			Editing(entries, commit);
			_search = search;
			_searchScroll = scroll;
			DrawItemPicker();
			search = _search;
			scroll = _searchScroll;
		}

		private static void DrawItemPicker()
		{
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: 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_0153: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			_search = GUILayout.TextField(_search, Styles.Field, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(22f) });
			if (GUILayout.Button("add", Styles.CellOff, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(52f),
				GUILayout.Height(22f)
			}))
			{
				AddFirstMatch();
			}
			GUILayout.EndHorizontal();
			if (_search.Trim().Length == 0)
			{
				return;
			}
			List<string> list = Matches(_search.Trim());
			if (list.Count == 0)
			{
				GUILayout.Label("   nothing matches", Styles.Dim, Array.Empty<GUILayoutOption>());
				return;
			}
			_searchScroll = GUILayout.BeginScrollView(_searchScroll, false, true, GUIStyle.none, GUI.skin.verticalScrollbar, Styles.List, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(120f) });
			foreach (string item in list)
			{
				if (GUILayout.Button(" " + ItemGroups.DisplayNameOf(item), Styles.Row, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(20f) }))
				{
					if (Event.current != null && Event.current.shift)
					{
						Refuse(item);
					}
					else
					{
						Toggle(item);
					}
					_search = "";
					_searchScroll = Vector2.zero;
					break;
				}
			}
			GUILayout.EndScrollView();
			Caption("shift-click to refuse an item instead of holding it");
		}

		public static void DrawItemChips(List<string> entries, Action commit, float windowWidth)
		{
			Editing(entries, commit);
			DrawItemChips(windowWidth);
		}

		private static void DrawItemChips(float WindowWidth)
		{
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Expected O, but got Unknown
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			List<string> list = new List<string>();
			foreach (string item in _edit)
			{
				string text = ChestFilter.Bare(item);
				if (!ChestFilter.IsGroup(text) && !(text == "*"))
				{
					list.Add(item);
				}
			}
			if (list.Count == 0)
			{
				return;
			}
			GUILayout.Space(4f);
			float num = WindowWidth - 40f;
			float num2 = 0f;
			bool flag = false;
			string text2 = null;
			foreach (string item2 in list)
			{
				bool flag2 = ChestFilter.IsExclusion(item2);
				string text3 = ItemGroups.DisplayNameOf(ChestFilter.Bare(item2));
				string text4 = (flag2 ? ("not " + text3) : text3) + "  ×";
				float num3 = Styles.Chip.CalcSize(new GUIContent(text4)).x + 4f;
				if (!flag || num2 + num3 > num)
				{
					if (flag)
					{
						GUILayout.FlexibleSpace();
						GUILayout.EndHorizontal();
					}
					GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
					flag = true;
					num2 = 0f;
				}
				if (GUILayout.Button(text4, Styles.Chip, (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width(num3),
					GUILayout.Height(20f)
				}))
				{
					text2 = item2;
				}
				num2 += num3 + 4f;
			}
			if (flag)
			{
				GUILayout.FlexibleSpace();
				GUILayout.EndHorizontal();
			}
			if (text2 != null)
			{
				Toggle(text2);
			}
		}

		private static List<string> Matches(string text)
		{
			List<string> list = new List<string>();
			if ((Object)(object)ObjectDB.instance == (Object)null || ObjectDB.instance.m_items == null)
			{
				return list;
			}
			foreach (GameObject item in ObjectDB.instance.m_items)
			{
				if (!((Object)(object)item == (Object)null) && list.Count < 60 && (ItemGroups.DisplayNameOf(((Object)item).name).IndexOf(text, StringComparison.OrdinalIgnoreCase) >= 0 || ((Object)item).name.IndexOf(text, StringComparison.OrdinalIgnoreCase) >= 0) && !list.Contains(((Object)item).name))
				{
					list.Add(((Object)item).name);
				}
			}
			list.Sort(StringComparer.OrdinalIgnoreCase);
			return list;
		}

		private static void AddFirstMatch()
		{
			//IL_003a: 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)
			string text = _search.Trim();
			if (text.Length != 0)
			{
				List<string> list = Matches(text);
				if (list.Count != 0)
				{
					Toggle(list[0]);
					_search = "";
					_searchScroll = Vector2.zero;
				}
			}
		}

		private static void DrawFooter()
		{
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			if (GUILayout.Button("Learn from contents", Styles.CellOff, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(24f) }))
			{
				LearnFromContents();
			}
			GUILayout.Space(4f);
			if (GUILayout.Button("Clear", Styles.CellOff, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(24f) }))
			{
				_entries.Clear();
				CommitChest();
			}
			GUILayout.Space(4f);
			if (GUILayout.Button("Close", Styles.CellOff, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(24f) }))
			{
				Close();
			}
			GUILayout.EndHorizontal();
		}

		private static void LearnFromContents()
		{
			Editing(_entries, CommitChest);
			Inventory inventory = _container.GetInventory();
			if (inventory == null)
			{
				return;
			}
			foreach (ItemData allItem in inventory.GetAllItems())
			{
				string text = ItemGroups.PrefabNameOf(allItem);
				if (text != null && !_edit.Contains(text))
				{
					_edit.Add(text);
				}
			}
			Commit();
		}

		private static void Toggle(string entry)
		{
			if (_edit.Contains(entry))
			{
				_edit.Remove(entry);
			}
			else
			{
				_edit.Add(entry);
			}
			Commit();
		}

		private static void Refuse(string entry)
		{
			string item = "-" + entry;
			_edit.Remove(entry);
			if (!_edit.Contains(item))
			{
				_edit.Add(item);
			}
			Commit();
		}

		private static void Cycle(string entry)
		{
			string item = "-" + entry;
			if (_edit.Contains(entry))
			{
				_edit.Remove(entry);
				_edit.Add(item);
			}
			else if (_edit.Contains(item))
			{
				_edit.Remove(item);
			}
			else
			{
				_edit.Add(entry);
			}
			Commit();
		}

		private static void Commit()
		{
			if (_save != null)
			{
				_save();
			}
		}

		private static void CommitChest()
		{
			ChestFilter.Write(_container, _entries);
			RulesButton.Refresh();
		}

		public static void Caption(string text)
		{
			GUILayout.Label(text, Styles.Caption, Array.Empty<GUILayoutOption>());
		}

		public static void Rule()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			Rect rect = GUILayoutUtility.GetRect(1f, 1f, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
			GUI.DrawTexture(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y, ((Rect)(ref rect)).width, 1f), (Texture)(object)Styles.RuleLine);
			GUILayout.Space(5f);
		}
	}
	internal static class Flare
	{
		private const string FlareMaterial = "light_glow";

		private static GameObject _template;

		private static bool _searched;

		public static void Invalidate()
		{
			_template = null;
			_searched = false;
		}

		public static GameObject Attach(Transform parent, float scale)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Template();
			if ((Object)(object)val == (Object)null || (Object)(object)parent == (Object)null)
			{
				return null;
			}
			GameObject obj = Object.Instantiate<GameObject>(val, parent, false);
			((Object)obj).name = "flare";
			obj.transform.localPosition = Vector3.zero;
			obj.transform.localRotation = Quaternion.identity;
			obj.transform.localScale = new Vector3(scale, scale, scale);
			obj.SetActive(true);
			return obj;
		}

		private static GameObject Template()
		{
			if ((Object)(object)_template != (Object)null || _searched)
			{
				return _template;
			}
			_searched = true;
			string[] array = (StowConfig.FlareDonors.Value ?? "").Split(new char[1] { ',' });
			for (int i = 0; i < array.Length; i++)
			{
				string text = array[i].Trim();
				if (text.Length == 0)
				{
					continue;
				}
				GameObject val = PropIndex.Find(text);
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				GameObject val2 = FindFlare(val);
				if (!((Object)(object)val2 == (Object)null))
				{
					_template = Clone(val2);
					if (!((Object)(object)_template == (Object)null))
					{
						StowRuntime.Log.LogInfo((object)("Flare borrowed from " + text + "/" + ((Object)val2).name + "."));
						return _template;
					}
				}
			}
			StowRuntime.Log.LogWarning((object)"No flare donor resolved - spirits will be lit but will not halo. Set FlareDonors to a prefab that has one.");
			return null;
		}

		private static GameObject FindFlare(GameObject donor)
		{
			Renderer[] componentsInChildren = donor.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null))
				{
					Material sharedMaterial = val.sharedMaterial;
					if (!((Object)(object)sharedMaterial == (Object)null) && ((Object)sharedMaterial).name.StartsWith("light_glow"))
					{
						return ((Component)val).gameObject;
					}
				}
			}
			return null;
		}

		private static GameObject Clone(GameObject source)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			GameObject val = new GameObject("StowFlareTemplate");
			val.SetActive(false);
			Object.DontDestroyOnLoad((Object)(object)val);
			bool forceDisableInit = ZNetView.m_forceDisableInit;
			ZNetView.m_forceDisableInit = true;
			GameObject val2;
			try
			{
				val2 = Object.Instantiate<GameObject>(source, val.transform);
			}
			finally
			{
				ZNetView.m_forceDisableInit = forceDisableInit;
			}
			MonoBehaviour[] componentsInChildren = val2.GetComponentsInChildren<MonoBehaviour>(true);
			foreach (MonoBehaviour val3 in componentsInChildren)
			{
				if ((Object)(object)val3 != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)val3);
				}
			}
			return val2;
		}
	}
	internal sealed class ItemGroup
	{
		public string Id;

		public string Display;

		public readonly HashSet<string> Members = new HashSet<string>();
	}
	internal static class ItemGroups
	{
		private static readonly List<ItemGroup> All = new List<ItemGroup>();

		private static readonly Dictionary<string, ItemGroup> ById = new Dictionary<string, ItemGroup>(StringComparer.OrdinalIgnoreCase);

		private static readonly Dictionary<string, string> SharedByPrefab = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

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

		private static bool _built;

		public static IList<ItemGroup> Groups
		{
			get
			{
				Build();
				return All;
			}
		}

		public static bool Ready
		{
			get
			{
				Build();
				return _built;
			}
		}

		public static void Invalidate()
		{
			_built = false;
			All.Clear();
			ById.Clear();
			SharedByPrefab.Clear();
			PrefabBySharedName.Clear();
		}

		public static ItemGroup Find(string id)
		{
			Build();
			if (!ById.TryGetValue(id, out var value))
			{
				return null;
			}
			return value;
		}

		public static string SharedNameOf(string prefabName)
		{
			Build();
			if (!SharedByPrefab.TryGetValue(prefabName, out var value))
			{
				return null;
			}
			return value;
		}

		public static string PrefabNameOf(ItemData item)
		{
			if (item == null || item.m_shared == null)
			{
				return null;
			}
			if ((Object)(object)item.m_dropPrefab != (Object)null)
			{
				return ((Object)item.m_dropPrefab).name;
			}
			Build();
			if (!PrefabBySharedName.TryGetValue(item.m_shared.m_name, out var value))
			{
				return null;
			}
			return value;
		}

		public static string DisplayNameOf(string prefabName)
		{
			Build();
			if (!SharedByPrefab.TryGetValue(prefabName, out var value))
			{
				return prefabName;
			}
			if (Localization.instance == null)
			{
				return value;
			}
			return Localization.instance.Localize(value);
		}

		private static void Build()
		{
			//IL_01f7: 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_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Expected I4, but got Unknown
			//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0301: Invalid comparison between Unknown and I4
			if (_built || (Object)(object)ObjectDB.instance == (Object)null || ObjectDB.instance.m_items == null)
			{
				return;
			}
			All.Clear();
			ById.Clear();
			SharedByPrefab.Clear();
			PrefabBySharedName.Clear();
			ItemGroup ore = Group("ore", "Ore");
			ItemGroup bars = Group("bars", "Bars & ingots");
			ItemGroup fuel = Group("fuel", "Fuel");
			ItemGroup wood = Group("wood", "Wood");
			ItemGroup raw = Group("raw", "Raw food");
			ItemGroup itemGroup = Group("cooked", "Cooked food");
			ItemGroup itemGroup2 = Group("mead", "Mead & potions");
			ItemGroup itemGroup3 = Group("seeds", "Seeds & crops");
			ItemGroup itemGroup4 = Group("building", "Building materials");
			ItemGroup itemGroup5 = Group("material", "Crafting materials");
			ItemGroup itemGroup6 = Group("gear", "Weapons & armour");
			ItemGroup itemGroup7 = Group("ammo", "Ammo");
			ItemGroup itemGroup8 = Group("trophies", "Trophies");
			ItemGroup itemGroup9 = Group("fish", "Fish");
			ItemGroup itemGroup10 = Group("valuable", "Valuables");
			foreach (GameObject item in ObjectDB.instance.m_items)
			{
				if ((Object)(object)item == (Object)null)
				{
					continue;
				}
				ItemDrop component = item.GetComponent<ItemDrop>();
				if (!((Object)(object)component == (Object)null) && component.m_itemData != null && component.m_itemData.m_shared != null)
				{
					SharedData shared = component.m_itemData.m_shared;
					SharedByPrefab[((Object)item).name] = shared.m_name;
					if (!PrefabBySharedName.ContainsKey(shared.m_name))
					{
						PrefabBySharedName[shared.m_name] = ((Object)item).name;
					}
					ItemType itemType = shared.m_itemType;
					switch (itemType - 1)
					{
					case 12:
						itemGroup8.Members.Add(shared.m_name);
						break;
					case 8:
					case 22:
						itemGroup7.Members.Add(shared.m_name);
						break;
					case 20:
						itemGroup9.Members.Add(shared.m_name);
						break;
					case 0:
						itemGroup5.Members.Add(shared.m_name);
						break;
					case 2:
					case 3:
					case 4:
					case 5:
					case 6:
					case 10:
					case 11:
					case 13:
					case 14:
					case 16:
					case 17:
					case 18:
					case 21:
					case 23:
						itemGroup6.Members.Add(shared.m_name);
						break;
					}
					if (shared.m_food > 0f)
					{
						itemGroup.Members.Add(shared.m_name);
					}
					else if ((int)shared.m_itemType == 2)
					{
						itemGroup2.Members.Add(shared.m_name);
					}
					if (shared.m_value > 0)
					{
						itemGroup10.Members.Add(shared.m_name);
					}
				}
			}
			ReadStations(ore, bars, fuel, raw, itemGroup, itemGroup2);
			ReadPieceTable("Hammer", itemGroup4);
			ReadPieceTable("Cultivator", itemGroup3);
			SplitFirewood(ore, bars, fuel, wood);
			All.RemoveAll((ItemGroup g) => g.Members.Count == 0);
			ById.Clear();
			foreach (ItemGroup item2 in All)
			{
				ById[item2.Id] = item2;
			}
			_built = All.Count > 0;
			if (!_built || StowConfig.Verbose == null || !StowConfig.Verbose.Value)
			{
				return;
			}
			foreach (ItemGroup item3 in All)
			{
				StowRuntime.Log.LogInfo((object)("group " + item3.Id + ": " + item3.Members.Count + " items"));
			}
		}

		private static ItemGroup Group(string id, string display)
		{
			ItemGroup itemGroup = new ItemGroup
			{
				Id = id,
				Display = display
			};
			All.Add(itemGroup);
			ById[id] = itemGroup;
			return itemGroup;
		}

		private static void ReadStations(ItemGroup ore, ItemGroup bars, ItemGroup fuel, ItemGroup raw, ItemGroup cooked, ItemGroup mead)
		{
			ZNetScene instance = ZNetScene.instance;
			if ((Object)(object)instance == (Object)null || instance.m_prefabs == null)
			{
				return;
			}
			foreach (GameObject prefab in instance.m_prefabs)
			{
				if ((Object)(object)prefab == (Object)null)
				{
					continue;
				}
				Smelter component = prefab.GetComponent<Smelter>();
				if ((Object)(object)component != (Object)null)
				{
					Add(fuel, component.m_fuelItem);
					if (component.m_conversion != null)
					{
						foreach (ItemConversion item in component.m_conversion)
						{
							if (item != null)
							{
								Add(ore, item.m_from);
								Add(bars, item.m_to);
							}
						}
					}
				}
				CookingStation component2 = prefab.GetComponent<CookingStation>();
				if ((Object)(object)component2 != (Object)null)
				{
					Add(fuel, component2.m_fuelItem);
					if (component2.m_conversion != null)
					{
						foreach (ItemConversion item2 in component2.m_conversion)
						{
							if (item2 != null)
							{
								Add(raw, item2.m_from);
								Add(cooked, item2.m_to);
							}
						}
					}
				}
				Fireplace component3 = prefab.GetComponent<Fireplace>();
				if ((Object)(object)component3 != (Object)null)
				{
					Add(fuel, component3.m_fuelItem);
				}
				Fermenter component4 = prefab.GetComponent<Fermenter>();
				if (!((Object)(object)component4 != (Object)null) || component4.m_conversion == null)
				{
					continue;
				}
				foreach (ItemConversion item3 in component4.m_conversion)
				{
					if (item3 != null)
					{
						Add(mead, item3.m_from);
						Add(mead, item3.m_to);
					}
				}
			}
		}

		private static void ReadPieceTable(string toolPrefabName, ItemGroup into)
		{
			if ((Object)(object)ObjectDB.instance == (Object)null)
			{
				return;
			}
			GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(toolPrefabName);
			if ((Object)(object)itemPrefab == (Object)null)
			{
				return;
			}
			ItemDrop component = itemPrefab.GetComponent<ItemDrop>();
			if ((Object)(object)component == (Object)null || component.m_itemData == null || component.m_itemData.m_shared == null)
			{
				return;
			}
			PieceTable buildPieces = component.m_itemData.m_shared.m_buildPieces;
			if ((Object)(object)buildPieces == (Object)null || buildPieces.m_pieces == null)
			{
				return;
			}
			foreach (GameObject piece in buildPieces.m_pieces)
			{
				if ((Object)(object)piece == (Object)null)
				{
					continue;
				}
				Piece component2 = piece.GetComponent<Piece>();
				if ((Object)(object)component2 == (Object)null || component2.m_resources == null)
				{
					continue;
				}
				Requirement[] resources = component2.m_resources;
				foreach (Requirement val in resources)
				{
					if (val != null)
					{
						Add(into, val.m_resItem);
					}
				}
			}
		}

		private static void SplitFirewood(ItemGroup ore, ItemGroup bars, ItemGroup fuel, ItemGroup wood)
		{
			ZNetScene instance = ZNetScene.instance;
			if ((Object)(object)instance == (Object)null || instance.m_prefabs == null)
			{
				return;
			}
			foreach (GameObject prefab in instance.m_prefabs)
			{
				if ((Object)(object)prefab == (Object)null)
				{
					continue;
				}
				Smelter component = prefab.GetComponent<Smelter>();
				if ((Object)(object)component == (Object)null || component.m_conversion == null)
				{
					continue;
				}
				foreach (ItemConversion item in component.m_conversion)
				{
					if (item == null || (Object)(object)item.m_from == (Object)null || (Object)(object)item.m_to == (Object)null)
					{
						continue;
					}
					string text = SharedNameOfDrop(item.m_to);
					if (text != null && fuel.Members.Contains(text))
					{
						string text2 = SharedNameOfDrop(item.m_from);
						if (text2 != null)
						{
							ore.Members.Remove(text2);
							bars.Members.Remove(text);
							wood.Members.Add(text2);
						}
					}
				}
			}
		}

		private static void Add(ItemGroup group, ItemDrop drop)
		{
			string text = SharedNameOfDrop(drop);
			if (text != null)
			{
				group.Members.Add(text);
			}
		}

		private static string SharedNameOfDrop(ItemDrop drop)
		{
			if ((Object)(object)drop == (Object)null || drop.m_itemData == null || drop.m_itemData.m_shared == null)
			{
				return null;
			}
			return drop.m_itemData.m_shared.m_name;
		}
	}
	internal static class PostModel
	{
		public const string GlowGroup = "core";

		private static readonly Dictionary<string, string[]> Donors = new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase)
		{
			{
				"wood",
				new string[3] { "wood_wall", "wood_beam", "piece_chest_wood" }
			},
			{
				"iron",
				new string[5] { "piece_cauldron", "piece_chest_blackmetal", "forge", "blackforge", "piece_stonecutter" }
			},
			{
				"stone",
				new string[3] { "stone_wall_2x1", "piece_stonecutter", "smelter" }
			}
		};

		private static readonly Dictionary<string, Material> Cache = new Dictionary<string, Material>(StringComparer.OrdinalIgnoreCase);

		private static readonly Dictionary<string, Rect> Atlas = new Dictionary<string, Rect>(StringComparer.OrdinalIgnoreCase);

		public const string HeartwoodAnchor = "heartwood";

		private static string ModelFile => StowConfig.PostModelFile.Value;

		private static string ColliderFile => Path.ChangeExtension(ModelFile, ".col");

		public static bool Apply(GameObject prefab)
		{
			return Apply(prefab, ModelFile, "post_visual", heartwood: true);
		}

		public static bool Apply(GameObject prefab, string modelFile, string visualName, bool heartwood)
		{
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			string directoryName = Path.GetDirectoryName(typeof(PostModel).Assembly.Location);
			ModelData modelData = ObjMesh.Load(Path.Combine(directoryName, modelFile));
			if (modelData == null || (Object)(object)modelData.Mesh == (Object)null)
			{
				StowRuntime.Log.LogWarning((object)("No " + modelFile + " beside the dll - falling back to the donor's own look."));
				return false;
			}
			MeshRenderer[] componentsInChildren = prefab.GetComponentsInChildren<MeshRenderer>(true);
			foreach (MeshRenderer val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null))
				{
					Object.DestroyImmediate((Object)(object)((Component)val).gameObject);
				}
			}
			GameObject val2 = new GameObject(visualName);
			val2.transform.SetParent(prefab.transform, false);
			val2.transform.localPosition = Vector3.zero;
			val2.transform.localRotation = Quaternion.identity;
			val2.transform.localScale = Vector3.one;
			val2.AddComponent<MeshFilter>().sharedMesh = modelData.Mesh;
			((Renderer)val2.AddComponent<MeshRenderer>()).sharedMaterials = SkinsFor(modelData.Groups);
			Remap(modelData.Mesh, modelData.Groups);
			if (heartwood)
			{
				Heartwood(prefab, val2.transform, modelData);
			}
			ReplaceColliders(prefab, Path.Combine(directoryName, Path.ChangeExtension(modelFile, ".col")));
			StowRuntime.Log.LogInfo((object)string.Format("{0} loaded: {1} verts, {2} tris, groups [{3}].", modelFile, modelData.Mesh.vertexCount, modelData.Mesh.triangles.Length / 3, string.Join(", ", modelData.Groups)));
			return true;
		}

		private static void Heartwood(GameObject prefab, Transform visual, ModelData model)
		{
			//IL_0055: 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_005b: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown