Decompiled source of DynamicStorage Mead Hall v1.0.1

plugins/DynamicStorageMeadHall/DynamicStorageMeadHall.dll

Decompiled 7 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Extensions;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering;

[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("DynamicStorageMeadHall")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1")]
[assembly: AssemblyProduct("DynamicStorageMeadHall")]
[assembly: AssemblyTitle("DynamicStorageMeadHall")]
[assembly: AssemblyVersion("1.0.1.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 DynamicStorageMeadHall
{
	internal sealed class ConfigurationManagerAttributes
	{
		public int? Order;

		public bool? IsAdminOnly;

		public bool? ReadOnly;

		public bool? Browsable;

		public bool? IsAdvanced;
	}
	[BepInPlugin("com.muji.DynamicStorageMeadHall", "DynamicStorage Mead Hall", "1.0.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	internal sealed class DynamicStorageMeadHallPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.muji.DynamicStorageMeadHall";

		public const string PluginName = "DynamicStorage Mead Hall";

		public const string PluginVersion = "1.0.1";

		public const string KegPrefabName = "DSMK_MeadKeg";

		private ConfigEntry<int> kegSlots;

		private ConfigEntry<int> quickGrabAmount;

		private ConfigEntry<KeyboardShortcut> quickGrabShortcut;

		private ConfigEntry<float> kegScale;

		private ConfigEntry<float> kegHeightOffset;

		private ConfigEntry<bool> enableIdleEffect;

		private ConfigEntry<string> barrelLabel;

		private ConfigEntry<bool> loopTapEffectPreview;

		private ConfigEntry<float> tapX;

		private ConfigEntry<float> tapY;

		private ConfigEntry<float> tapZ;

		private ConfigEntry<float> tapScale;

		private ConfigEntry<float> labelX;

		private ConfigEntry<float> labelY;

		private ConfigEntry<float> labelZ;

		private ConfigEntry<float> labelRotX;

		private ConfigEntry<float> labelRotY;

		private ConfigEntry<float> labelRotZ;

		private ConfigEntry<float> labelScale;

		private ConfigEntry<bool> labelFlipX;

		private ConfigEntry<bool> labelFlipY;

		private ConfigEntry<float> idleX;

		private ConfigEntry<float> idleY;

		private ConfigEntry<float> idleZ;

		private ConfigEntry<float> idleScale;

		private Harmony harmony;

		private GameObject registeredKegPrefab;

		private Vector3 kegBaseScale = Vector3.one;

		internal static DynamicStorageMeadHallPlugin Current { get; private set; }

		internal int KegStorageCapacity => NormalizeStorageCapacity((kegSlots != null) ? kegSlots.Value : 20);

		internal int QuickGrabAmount => Mathf.Clamp((quickGrabAmount != null) ? quickGrabAmount.Value : 5, 1, 50);

		internal KeyboardShortcut QuickGrabShortcut
		{
			get
			{
				//IL_0024: 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)
				if (quickGrabShortcut == null)
				{
					return new KeyboardShortcut((KeyCode)101, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 });
				}
				return quickGrabShortcut.Value;
			}
		}

		internal float KegScale => Mathf.Clamp((kegScale != null) ? kegScale.Value : 1f, 0.5f, 3f);

		internal float KegHeightOffset => Mathf.Clamp((kegHeightOffset != null) ? kegHeightOffset.Value : 0f, -2f, 2f);

		internal string LabelAtlasPath => Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location) ?? string.Empty, "Assets", "labels_atlas.png");

		internal bool EnableIdleEffect
		{
			get
			{
				if (enableIdleEffect != null)
				{
					return enableIdleEffect.Value;
				}
				return false;
			}
		}

		internal string BarrelLabelTemplateMode => MeadCatalog.LabelModeFromConfig((barrelLabel != null) ? barrelLabel.Value : "Dynamic");

		internal bool LoopTapEffectPreview
		{
			get
			{
				if (loopTapEffectPreview != null)
				{
					return loopTapEffectPreview.Value;
				}
				return false;
			}
		}

		internal float TapEffectLocalX
		{
			get
			{
				if (tapX == null)
				{
					return 0f;
				}
				return tapX.Value;
			}
		}

		internal float TapEffectLocalY
		{
			get
			{
				if (tapY == null)
				{
					return 0f;
				}
				return tapY.Value;
			}
		}

		internal float TapEffectLocalZ
		{
			get
			{
				if (tapZ == null)
				{
					return 0f;
				}
				return tapZ.Value;
			}
		}

		internal float TapEffectScaleMultiplier
		{
			get
			{
				if (tapScale == null)
				{
					return 1f;
				}
				return Mathf.Clamp(tapScale.Value, 0.1f, 2f);
			}
		}

		internal float LabelLocalX
		{
			get
			{
				if (labelX == null)
				{
					return 0f;
				}
				return labelX.Value;
			}
		}

		internal float LabelLocalY
		{
			get
			{
				if (labelY == null)
				{
					return 0.01f;
				}
				return labelY.Value;
			}
		}

		internal float LabelLocalZ
		{
			get
			{
				if (labelZ == null)
				{
					return -0.3f;
				}
				return labelZ.Value;
			}
		}

		internal float LabelRotationX
		{
			get
			{
				if (labelRotX == null)
				{
					return 0f;
				}
				return labelRotX.Value;
			}
		}

		internal float LabelRotationY
		{
			get
			{
				if (labelRotY == null)
				{
					return 0f;
				}
				return labelRotY.Value;
			}
		}

		internal float LabelRotationZ
		{
			get
			{
				if (labelRotZ == null)
				{
					return 0f;
				}
				return labelRotZ.Value;
			}
		}

		internal float LabelScale
		{
			get
			{
				if (labelScale == null)
				{
					return 0.95f;
				}
				return Mathf.Clamp(labelScale.Value, 0.1f, 2f);
			}
		}

		internal bool LabelFlipX
		{
			get
			{
				if (labelFlipX != null)
				{
					return labelFlipX.Value;
				}
				return false;
			}
		}

		internal bool LabelFlipY
		{
			get
			{
				if (labelFlipY != null)
				{
					return labelFlipY.Value;
				}
				return false;
			}
		}

		internal float IdleEffectLocalX
		{
			get
			{
				if (idleX == null)
				{
					return 0f;
				}
				return idleX.Value;
			}
		}

		internal float IdleEffectLocalY
		{
			get
			{
				if (idleY == null)
				{
					return 0f;
				}
				return idleY.Value;
			}
		}

		internal float IdleEffectLocalZ
		{
			get
			{
				if (idleZ == null)
				{
					return 0f;
				}
				return idleZ.Value;
			}
		}

		internal float IdleEffectScale
		{
			get
			{
				if (idleScale == null)
				{
					return 0.2f;
				}
				return Mathf.Clamp(idleScale.Value, 0.02f, 1f);
			}
		}

		private void Awake()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			Current = this;
			BindConfig();
			harmony = new Harmony("com.muji.DynamicStorageMeadHall");
			MeadKegInventoryPatches.Install(harmony);
			MeadKegCapacityPatches.Install(harmony);
			MeadKegInteractionPatches.Install(harmony);
			MeadKegPlacementGhostPatches.Install(harmony);
			MeadKegAppearancePlacementPatches.Install(harmony);
			PrefabManager.OnPrefabsRegistered += OnPrefabsRegistered;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"DynamicStorage Mead Hall 1.0.1 loaded.");
		}

		private void OnDestroy()
		{
			MeadKegEffects.StopTapPreview();
			PrefabManager.OnPrefabsRegistered -= OnPrefabsRegistered;
			if (harmony != null)
			{
				try
				{
					harmony.UnpatchSelf();
				}
				catch
				{
				}
			}
			if ((Object)(object)Current == (Object)(object)this)
			{
				Current = null;
			}
		}

		private void Update()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: 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_0024: Invalid comparison between Unknown and I4
			MeadKegEffects.UpdateTapPreview(LoopTapEffectPreview);
			KeyboardShortcut val = QuickGrabShortcut;
			if ((int)((KeyboardShortcut)(ref val)).MainKey == 0 || (int)((KeyboardShortcut)(ref val)).MainKey == 101 || !((KeyboardShortcut)(ref val)).IsDown())
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			if (Object.op_Implicit((Object)(object)localPlayer) && !InventoryGui.IsVisible() && !Menu.IsVisible() && !TextInput.IsVisible() && !Console.IsVisible())
			{
				GameObject hoverObject = ((Humanoid)localPlayer).GetHoverObject();
				MeadKegStorage meadKegStorage = (Object.op_Implicit((Object)(object)hoverObject) ? hoverObject.GetComponentInParent<MeadKegStorage>() : null);
				if (Object.op_Implicit((Object)(object)meadKegStorage))
				{
					meadKegStorage.TryQuickGrab(localPlayer, QuickGrabAmount);
				}
			}
		}

		private void BindConfig()
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Expected O, but got Unknown
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Expected O, but got Unknown
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Expected O, but got Unknown
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Expected O, but got Unknown
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Expected O, but got Unknown
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Expected O, but got Unknown
			//IL_0349: Unknown result type (might be due to invalid IL or missing references)
			//IL_0353: Expected O, but got Unknown
			//IL_0397: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a1: Expected O, but got Unknown
			//IL_03e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ef: Expected O, but got Unknown
			//IL_048d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0497: Expected O, but got Unknown
			AcceptableValueList<int> val = new AcceptableValueList<int>(new int[4] { 10, 20, 40, 60 });
			kegSlots = ConfigFileExtensions.BindConfig<int>(((BaseUnityPlugin)this).Config, "Server Settings", "Mead Keg Slots", 20, "Server-controlled inventory slot count for Mead Kegs. Options: 10, 20, 40, or 60.", true, (int?)100, (AcceptableValueBase)(object)val, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			quickGrabAmount = ((BaseUnityPlugin)this).Config.Bind<int>("Quick Grab", "Quick Grab Amount", 5, new ConfigDescription("Number of bottles requested by the Quick Grab action.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 50), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 100
				}
			}));
			quickGrabShortcut = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Quick Grab", "Quick Grab Key", new KeyboardShortcut((KeyCode)101, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), new ConfigDescription("Shortcut used while looking at an assigned Mead Keg.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 90
				}
			}));
			kegScale = ((BaseUnityPlugin)this).Config.Bind<float>("Appearance", "Keg Scale", 1f, new ConfigDescription("Template scale for newly placed kegs. Each placed keg saves its own scale.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 3f), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 100
				}
			}));
			kegHeightOffset = ((BaseUnityPlugin)this).Config.Bind<float>("Appearance", "Keg Height Offset", 0f, new ConfigDescription("Vertical offset saved to newly placed kegs. Negative values sink large kegs into the ground.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-2f, 2f), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 95
				}
			}));
			barrelLabel = ((BaseUnityPlugin)this).Config.Bind<string>("Appearance", "Barrel Label", "Dynamic", new ConfigDescription("Placement template for the keg label. Dynamic follows the actual stored mead; Empty or any named label stays fixed on that placed keg. The choice is saved into the keg ZDO and replicated to other clients.", (AcceptableValueBase)(object)new AcceptableValueList<string>(MeadCatalog.LabelConfigOptions), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 92
				}
			}));
			enableIdleEffect = ((BaseUnityPlugin)this).Config.Bind<bool>("Appearance", "Subtle Idle Effect", false, new ConfigDescription("Optional client-side visual: shows a scaled-down copy of the vanilla fermenting effect while a keg is assigned.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 90
				}
			}));
			labelX = BindTuning("Label Local X", 0f, 80);
			labelY = BindTuning("Label Local Y", 0.01f, 79);
			labelZ = BindTuning("Label Local Z", -0.3f, 78);
			labelRotX = BindTuning("Label Rotation X", 0f, 77, -180f, 180f);
			labelRotY = BindTuning("Label Rotation Y", 0f, 76, -180f, 180f);
			labelRotZ = BindTuning("Label Rotation Z", 0f, 75, -180f, 180f);
			labelScale = BindTuning("Label Scale", 0.95f, 74, 0.1f);
			labelFlipX = ((BaseUnityPlugin)this).Config.Bind<bool>("Appearance - Debug Tuning", "Label Flip Horizontal", true, new ConfigDescription("Advanced face-local debug toggle. Flips the label artwork left/right via UVs without turning the disc around.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 73,
					IsAdvanced = true
				}
			}));
			labelFlipY = ((BaseUnityPlugin)this).Config.Bind<bool>("Appearance - Debug Tuning", "Label Flip Vertical", false, new ConfigDescription("Advanced face-local debug toggle. Flips the label artwork up/down via UVs without turning the disc around.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 72,
					IsAdvanced = true
				}
			}));
			loopTapEffectPreview = ((BaseUnityPlugin)this).Config.Bind<bool>("Appearance - Debug Tuning", "Loop Tap Effect Preview", false, new ConfigDescription("Advanced tuning aid for the QUICK GRAB POUR VFX only. Repeats one safe preview instance on a nearby keg, never overlaps preview instances, and does not repeat the sound.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 69,
					IsAdvanced = true
				}
			}));
			tapX = BindTapTuning("Tap Effect Local X", 0f, 68);
			tapY = BindTapTuning("Tap Effect Local Y", 0f, 67);
			tapZ = BindTapTuning("Tap Effect Local Z", 0f, 66);
			tapScale = ((BaseUnityPlugin)this).Config.Bind<float>("Appearance - Debug Tuning", "Tap Effect Scale", 1f, new ConfigDescription("Multiplier for the Quick Grab pour VFX size. 1.0 uses the native vanilla effect size.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 2f), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 65,
					IsAdvanced = true
				}
			}));
			idleX = BindTuning("Idle Effect Local X", 0f, 60);
			idleY = BindTuning("Idle Effect Local Y", 0f, 59);
			idleZ = BindTuning("Idle Effect Local Z", 0f, 58);
			idleScale = BindTuning("Idle Effect Scale", 0.2f, 57, 0.02f, 1f);
			MigrateQuickGrabDefault();
			MigratePocLabelDefaults();
			MigratePocEffectDefaults();
			MigrateTapCalibrationDefaults();
			kegSlots.SettingChanged += delegate
			{
				MeadKegCapacity.RefreshAll();
			};
			kegScale.SettingChanged += delegate
			{
				RefreshPlacementTemplateScale();
			};
			EventHandler eventHandler = delegate
			{
				MeadKegVisual.RefreshAllTransforms();
			};
			labelX.SettingChanged += eventHandler;
			labelY.SettingChanged += eventHandler;
			labelZ.SettingChanged += eventHandler;
			labelRotX.SettingChanged += eventHandler;
			labelRotY.SettingChanged += eventHandler;
			labelRotZ.SettingChanged += eventHandler;
			labelScale.SettingChanged += eventHandler;
			labelFlipX.SettingChanged += eventHandler;
			labelFlipY.SettingChanged += eventHandler;
			tapX.SettingChanged += eventHandler;
			tapY.SettingChanged += eventHandler;
			tapZ.SettingChanged += eventHandler;
			tapScale.SettingChanged += eventHandler;
			idleX.SettingChanged += eventHandler;
			idleY.SettingChanged += eventHandler;
			idleZ.SettingChanged += eventHandler;
			idleScale.SettingChanged += eventHandler;
			enableIdleEffect.SettingChanged += eventHandler;
			barrelLabel.SettingChanged += eventHandler;
			loopTapEffectPreview.SettingChanged += delegate
			{
				if (!LoopTapEffectPreview)
				{
					MeadKegEffects.StopTapPreview();
				}
			};
		}

		private void MigrateQuickGrabDefault()
		{
			//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_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			if (quickGrabShortcut != null)
			{
				string a = ((object)quickGrabShortcut.Value/*cast due to .constrained prefix*/).ToString();
				string b = ((object)new KeyboardShortcut((KeyCode)101, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 })/*cast due to .constrained prefix*/).ToString();
				if (string.Equals(a, b, StringComparison.Ordinal))
				{
					quickGrabShortcut.Value = new KeyboardShortcut((KeyCode)101, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 });
					((BaseUnityPlugin)this).Config.Save();
					((BaseUnityPlugin)this).Logger.LogInfo((object)"Migrated untouched Quick Grab shortcut default from Left Alt + E to Left Shift + E.");
				}
			}
		}

		private void MigratePocLabelDefaults()
		{
			if (labelX == null || labelY == null || labelZ == null || labelRotX == null || labelRotY == null || labelRotZ == null)
			{
				return;
			}
			bool flag = Mathf.Approximately(labelX.Value, 0f) && Mathf.Approximately(labelY.Value, 0.08f) && Mathf.Approximately(labelZ.Value, 0.015f) && Mathf.Approximately(labelRotX.Value, 0f) && Mathf.Approximately(labelRotY.Value, 0f) && Mathf.Approximately(labelRotZ.Value, 0f) && labelScale != null && Mathf.Approximately(labelScale.Value, 0.55f);
			if (((Mathf.Approximately(labelX.Value, 0.72f) || Mathf.Approximately(labelX.Value, 0.92f)) && Mathf.Approximately(labelY.Value, 0.03f) && Mathf.Approximately(labelZ.Value, 0f) && Mathf.Approximately(labelRotY.Value, -90f)) || (Mathf.Approximately(labelX.Value, 0.94f) && Mathf.Approximately(labelY.Value, 0.58f) && Mathf.Approximately(labelZ.Value, 0f) && Mathf.Approximately(labelRotY.Value, 90f)) || (Mathf.Approximately(labelX.Value, -0.94f) && Mathf.Approximately(labelY.Value, 0.58f) && Mathf.Approximately(labelZ.Value, 0f) && Mathf.Approximately(labelRotY.Value, -90f)) || flag)
			{
				labelX.Value = 0f;
				labelY.Value = 0.01f;
				labelZ.Value = -0.3f;
				labelRotX.Value = 0f;
				labelRotY.Value = 0f;
				labelRotZ.Value = 0f;
				if (labelScale != null)
				{
					labelScale.Value = 0.95f;
				}
				if (labelFlipX != null)
				{
					labelFlipX.Value = true;
				}
				if (labelFlipY != null)
				{
					labelFlipY.Value = false;
				}
				((BaseUnityPlugin)this).Config.Save();
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Migrated untouched prototype label settings to the release face-local defaults.");
			}
		}

		private void MigratePocEffectDefaults()
		{
			if (idleX != null && idleY != null && idleZ != null && ((Mathf.Approximately(idleX.Value, 0.08f) && Mathf.Approximately(idleY.Value, -0.25f) && Mathf.Approximately(idleZ.Value, -0.18f)) || (Mathf.Approximately(idleX.Value, 1.05f) && Mathf.Approximately(idleY.Value, 0.28f) && Mathf.Approximately(idleZ.Value, 0f)) || (Mathf.Approximately(idleX.Value, -1.05f) && Mathf.Approximately(idleY.Value, 0.28f) && Mathf.Approximately(idleZ.Value, 0f))))
			{
				idleX.Value = 0f;
				idleY.Value = 0f;
				idleZ.Value = 0f;
				((BaseUnityPlugin)this).Config.Save();
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Migrated untouched prototype effect settings to the auto-detected tap anchor.");
			}
		}

		private void MigrateTapCalibrationDefaults()
		{
			if (tapX != null && tapY != null && tapZ != null)
			{
				bool num = Mathf.Approximately(tapX.Value, 0f) && Mathf.Approximately(tapY.Value, -0.6f) && Mathf.Approximately(tapZ.Value, -1.2f);
				bool flag = Mathf.Approximately(tapX.Value, 0f) && Mathf.Approximately(tapY.Value, -0.4f) && Mathf.Approximately(tapZ.Value, -0.6f);
				if (num || flag)
				{
					tapX.Value = 0f;
					tapY.Value = 0f;
					tapZ.Value = 0f;
					((BaseUnityPlugin)this).Config.Save();
					((BaseUnityPlugin)this).Logger.LogInfo((object)"Migrated measured tap calibration values to the 1.0 scale-aware tap defaults.");
				}
			}
		}

		private ConfigEntry<float> BindTapTuning(string key, float value, int order)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			return ((BaseUnityPlugin)this).Config.Bind<float>("Appearance - Debug Tuning", key, value, new ConfigDescription("Advanced fine adjustment added after the automatic scale-aware Quick Grab tap position. X = left/right across the keg face, Y = up/down, Z = outward/inward.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-2f, 2f), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = order,
					IsAdvanced = true
				}
			}));
		}

		private ConfigEntry<float> BindTuning(string key, float value, int order, float min = -2f, float max = 2f)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			return ((BaseUnityPlugin)this).Config.Bind<float>("Appearance - Debug Tuning", key, value, new ConfigDescription("Advanced face-local debug tuning control for label and effect alignment. X = left/right across the keg face, Y = up/down on the face, Z = outward/inward from the face.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(min, max), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = order,
					IsAdvanced = true
				}
			}));
		}

		private void OnPrefabsRegistered()
		{
			PrefabManager.OnPrefabsRegistered -= OnPrefabsRegistered;
			MeadCatalog.Initialize();
			MeadKegEffects.Initialize();
			RegisterKeg();
		}

		private void RegisterKeg()
		{
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: 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_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Expected O, but got Unknown
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Expected O, but got Unknown
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Expected O, but got Unknown
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Expected O, but got Unknown
			GameObject prefab = PrefabManager.Instance.GetPrefab("dvergrprops_barrel");
			GameObject prefab2 = PrefabManager.Instance.GetPrefab("piece_chest_wood");
			if (!Object.op_Implicit((Object)(object)prefab) || !Object.op_Implicit((Object)(object)prefab2))
			{
				((BaseUnityPlugin)this).Logger.LogError((object)"Could not create Mead Keg: dvergrprops_barrel or piece_chest_wood was not found.");
				return;
			}
			GameObject val = PrefabManager.Instance.CreateClonedPrefab("DSMK_MeadKeg", prefab);
			if (!Object.op_Implicit((Object)(object)val))
			{
				((BaseUnityPlugin)this).Logger.LogError((object)"Could not create Mead Keg clone.");
				return;
			}
			RemoveComponentIfPresent<Destructible>(val);
			RemoveComponentIfPresent<DropOnDestroyed>(val);
			RemoveComponentIfPresent<Container>(val);
			SetLayerRecursively(val, prefab2.layer);
			ZNetView component = val.GetComponent<ZNetView>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				ZNetView component2 = prefab2.GetComponent<ZNetView>();
				if (Object.op_Implicit((Object)(object)component2))
				{
					ExposedGameObjectExtension.AddComponentCopy<ZNetView>(val, component2);
				}
				component = val.GetComponent<ZNetView>();
			}
			if (!Object.op_Implicit((Object)(object)component))
			{
				((BaseUnityPlugin)this).Logger.LogError((object)"Mead Keg could not obtain a ZNetView.");
				return;
			}
			component.m_persistent = true;
			Piece component3 = prefab2.GetComponent<Piece>();
			if (!Object.op_Implicit((Object)(object)val.GetComponent<Piece>()) && Object.op_Implicit((Object)(object)component3))
			{
				ExposedGameObjectExtension.AddComponentCopy<Piece>(val, component3);
			}
			WearNTear component4 = prefab2.GetComponent<WearNTear>();
			if (!Object.op_Implicit((Object)(object)val.GetComponent<WearNTear>()) && Object.op_Implicit((Object)(object)component4))
			{
				ExposedGameObjectExtension.AddComponentCopy<WearNTear>(val, component4);
			}
			Piece component5 = val.GetComponent<Piece>();
			if (!Object.op_Implicit((Object)(object)component5))
			{
				((BaseUnityPlugin)this).Logger.LogError((object)"Mead Keg could not obtain a Piece component.");
				return;
			}
			component5.m_name = "Mead Keg";
			component5.m_description = "Stores one type of finished mead at a time.";
			WearNTear component6 = val.GetComponent<WearNTear>();
			if (Object.op_Implicit((Object)(object)component6))
			{
				component6.m_autoCreateFragments = false;
			}
			val.AddComponent<MeadKegCapacity>();
			Container obj = val.AddComponent<Container>();
			obj.m_name = "Mead Keg";
			GetStorageGrid(KegStorageCapacity, out var width, out var height);
			obj.m_width = width;
			obj.m_height = height;
			val.AddComponent<MeadKegStorage>();
			val.AddComponent<MeadKegVisual>();
			kegBaseScale = val.transform.localScale;
			val.AddComponent<MeadKegScale>().Setup(kegBaseScale);
			val.transform.localScale = Multiply(kegBaseScale, KegScale);
			registeredKegPrefab = val;
			PieceConfig val2 = new PieceConfig
			{
				PieceTable = PieceTables.Hammer,
				Category = PieceCategories.Misc
			};
			val2.AddRequirement(new RequirementConfig("FineWood", 10, 0, true));
			val2.AddRequirement(new RequirementConfig("Bronze", 2, 0, true));
			TryAssignRenderedPieceIcon(prefab, component5);
			CustomPiece val3 = new CustomPiece(val, true, val2);
			if (!PieceManager.Instance.AddPiece(val3))
			{
				((BaseUnityPlugin)this).Logger.LogError((object)"Jotunn PieceManager rejected the Mead Keg piece.");
			}
			else
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Registered DynamicStorage Mead Hall Mead Keg.");
			}
		}

		private void TryAssignRenderedPieceIcon(GameObject iconSource, Piece piece)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)iconSource) || !Object.op_Implicit((Object)(object)piece))
			{
				return;
			}
			try
			{
				RenderRequest val = new RenderRequest(iconSource);
				val.Rotation = RenderManager.IsometricRotation;
				val.UseCache = true;
				val.TargetPlugin = ((BaseUnityPlugin)this).Info.Metadata;
				Sprite val2 = RenderManager.Instance.Render(val);
				if (Object.op_Implicit((Object)(object)val2))
				{
					piece.m_icon = val2;
					((BaseUnityPlugin)this).Logger.LogInfo((object)"Rendered Mead Keg hammer icon from clean dvergrprops_barrel source.");
				}
				else
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)"Mead Keg icon renderer returned no sprite; inherited donor icon will remain as a fallback.");
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not render Mead Keg hammer icon; inherited donor icon will remain as a fallback: " + ex.Message));
			}
		}

		private void RefreshPlacementTemplateScale()
		{
			//IL_0019: 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)
			if (Object.op_Implicit((Object)(object)registeredKegPrefab))
			{
				registeredKegPrefab.transform.localScale = Multiply(kegBaseScale, KegScale);
			}
		}

		private static Vector3 Multiply(Vector3 value, float multiplier)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(value.x * multiplier, value.y * multiplier, value.z * multiplier);
		}

		internal static int NormalizeStorageCapacity(int value)
		{
			return value switch
			{
				10 => 10, 
				40 => 40, 
				60 => 60, 
				_ => 20, 
			};
		}

		internal static void GetStorageGrid(int capacity, out int width, out int height)
		{
			switch (NormalizeStorageCapacity(capacity))
			{
			case 10:
				width = 5;
				height = 2;
				break;
			case 40:
				width = 8;
				height = 5;
				break;
			case 60:
				width = 10;
				height = 6;
				break;
			default:
				width = 5;
				height = 4;
				break;
			}
		}

		private static void SetLayerRecursively(GameObject root, int layer)
		{
			if (!Object.op_Implicit((Object)(object)root))
			{
				return;
			}
			Transform[] componentsInChildren = root.GetComponentsInChildren<Transform>(true);
			foreach (Transform val in componentsInChildren)
			{
				if (Object.op_Implicit((Object)(object)val))
				{
					((Component)val).gameObject.layer = layer;
				}
			}
		}

		private static void RemoveComponentIfPresent<T>(GameObject gameObject) where T : Component
		{
			T val = (Object.op_Implicit((Object)(object)gameObject) ? gameObject.GetComponent<T>() : default(T));
			if (Object.op_Implicit((Object)(object)val))
			{
				Object.DestroyImmediate((Object)(object)val);
			}
		}
	}
	internal static class MeadKegPlacementGhostPatches
	{
		private static readonly FieldInfo PlacementGhostField = AccessTools.Field(typeof(Player), "m_placementGhost");

		internal static bool Install(Harmony harmony)
		{
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Expected O, but got Unknown
			if (harmony == null)
			{
				return false;
			}
			MethodInfo methodInfo = AccessTools.Method(typeof(Player), "UpdatePlacementGhost", new Type[1] { typeof(bool) }, (Type[])null) ?? AccessTools.Method(typeof(Player), "UpdatePlacementGhost", Type.EmptyTypes, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.Method(typeof(MeadKegPlacementGhostPatches), "UpdatePlacementGhostPostfix", (Type[])null, (Type[])null);
			if (methodInfo == null || methodInfo2 == null)
			{
				Logger.LogWarning((object)"Mead Keg placement-ghost scaling hook was not found in this Valheim build.");
				return false;
			}
			try
			{
				harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				return true;
			}
			catch (Exception ex)
			{
				Logger.LogWarning((object)("Mead Keg placement-ghost scaling hook failed: " + ex.Message));
				return false;
			}
		}

		private static void UpdatePlacementGhostPostfix(Player __instance)
		{
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)__instance) || (Object)(object)__instance != (Object)(object)Player.m_localPlayer || PlacementGhostField == null)
			{
				return;
			}
			GameObject val = null;
			try
			{
				object? value = PlacementGhostField.GetValue(__instance);
				val = (GameObject)((value is GameObject) ? value : null);
			}
			catch
			{
				return;
			}
			if (!Object.op_Implicit((Object)(object)val))
			{
				return;
			}
			MeadKegScale component = val.GetComponent<MeadKegScale>();
			if (Object.op_Implicit((Object)(object)component))
			{
				DynamicStorageMeadHallPlugin current = DynamicStorageMeadHallPlugin.Current;
				if (!((Object)(object)current == (Object)null))
				{
					component.ApplyPlacementPreview(current.KegScale, 0f, current.BarrelLabelTemplateMode);
					Transform transform = val.transform;
					transform.position += Vector3.up * current.KegHeightOffset;
				}
			}
		}
	}
	internal static class MeadKegAppearancePlacementPatches
	{
		internal static bool Install(Harmony harmony)
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			if (harmony == null)
			{
				return false;
			}
			MethodInfo methodInfo = AccessTools.Method(typeof(MeadKegAppearancePlacementPatches), "SetCreatorPostfix", (Type[])null, (Type[])null);
			MethodInfo[] methods = typeof(Piece).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			bool flag = false;
			MethodInfo[] array = methods;
			foreach (MethodInfo methodInfo2 in array)
			{
				ParameterInfo[] parameters = methodInfo2.GetParameters();
				if (!(methodInfo2.Name != "SetCreator") && parameters.Length != 0 && !(parameters[0].ParameterType != typeof(long)))
				{
					try
					{
						harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(methodInfo), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
						flag = true;
					}
					catch (Exception ex)
					{
						Logger.LogWarning((object)("Mead Keg placement appearance hook failed: " + ex.Message));
					}
				}
			}
			if (!flag)
			{
				Logger.LogWarning((object)"No compatible Piece.SetCreator overload was found for Mead Keg placement snapshots.");
			}
			return flag;
		}

		private static void SetCreatorPostfix(Piece __instance)
		{
			try
			{
				if (Object.op_Implicit((Object)(object)__instance) && Object.op_Implicit((Object)(object)Player.m_localPlayer))
				{
					MeadKegScale component = ((Component)__instance).GetComponent<MeadKegScale>();
					if (Object.op_Implicit((Object)(object)component))
					{
						component.SavePlacementDefaults();
					}
				}
			}
			catch (Exception ex)
			{
				Logger.LogWarning((object)("Mead Keg placement appearance snapshot failed: " + ex.Message));
			}
		}
	}
	internal static class MeadKegInteractionPatches
	{
		internal static bool Install(Harmony harmony)
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Expected O, but got Unknown
			bool result = true;
			MethodInfo methodInfo = AccessTools.Method(typeof(Container), "GetHoverText", Type.EmptyTypes, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.Method(typeof(MeadKegInteractionPatches), "GetHoverTextPostfix", (Type[])null, (Type[])null);
			if (methodInfo != null && methodInfo2 != null)
			{
				harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			else
			{
				result = false;
			}
			MethodInfo methodInfo3 = AccessTools.Method(typeof(Container), "Interact", new Type[3]
			{
				typeof(Humanoid),
				typeof(bool),
				typeof(bool)
			}, (Type[])null);
			MethodInfo methodInfo4 = AccessTools.Method(typeof(MeadKegInteractionPatches), "InteractPrefix", (Type[])null, (Type[])null);
			if (methodInfo3 != null && methodInfo4 != null)
			{
				harmony.Patch((MethodBase)methodInfo3, new HarmonyMethod(methodInfo4), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			else
			{
				result = false;
			}
			return result;
		}

		private static void GetHoverTextPostfix(Container __instance, ref string __result)
		{
			MeadKegStorage meadKegStorage = (Object.op_Implicit((Object)(object)__instance) ? ((Component)__instance).GetComponent<MeadKegStorage>() : null);
			if (Object.op_Implicit((Object)(object)meadKegStorage))
			{
				__result = meadKegStorage.BuildHoverText(__result);
			}
		}

		private static bool InteractPrefix(Container __instance, Humanoid character, bool hold, bool alt, ref bool __result)
		{
			//IL_0048: 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_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Invalid comparison between Unknown and I4
			MeadKegStorage meadKegStorage = (Object.op_Implicit((Object)(object)__instance) ? ((Component)__instance).GetComponent<MeadKegStorage>() : null);
			Player val = (Player)(object)((character is Player) ? character : null);
			DynamicStorageMeadHallPlugin current = DynamicStorageMeadHallPlugin.Current;
			if (!Object.op_Implicit((Object)(object)meadKegStorage) || !Object.op_Implicit((Object)(object)val) || (Object)(object)val != (Object)(object)Player.m_localPlayer || (Object)(object)current == (Object)null)
			{
				return true;
			}
			KeyboardShortcut quickGrabShortcut = current.QuickGrabShortcut;
			if ((int)((KeyboardShortcut)(ref quickGrabShortcut)).MainKey != 101 || !((KeyboardShortcut)(ref quickGrabShortcut)).IsDown())
			{
				return true;
			}
			if (!hold)
			{
				meadKegStorage.TryQuickGrab(val, current.QuickGrabAmount);
			}
			__result = true;
			return false;
		}
	}
	internal sealed class MeadDefinition
	{
		internal string PrefabName { get; }

		internal string LabelKey { get; }

		internal int AtlasIndex { get; }

		internal string LabelName { get; }

		internal MeadDefinition(string prefabName, string labelKey, int atlasIndex, string labelName)
		{
			PrefabName = prefabName;
			LabelKey = labelKey;
			AtlasIndex = atlasIndex;
			LabelName = labelName;
		}
	}
	internal static class MeadCatalog
	{
		internal static readonly MeadDefinition[] Definitions = new MeadDefinition[20]
		{
			new MeadDefinition("BarleyWine", "fire_resistance_barley_wine", 1, "Fire Resistance Barley Wine"),
			new MeadDefinition("MeadBugRepellent", "anti_sting_concoction", 2, "Anti-Sting Concoction"),
			new MeadDefinition("MeadBzerker", "berserkir_mead", 3, "Berserkir Mead"),
			new MeadDefinition("MeadEitrLingering", "lingering_eitr_mead", 4, "Lingering Eitr Mead"),
			new MeadDefinition("MeadEitrMinor", "minor_eitr_mead", 5, "Minor Eitr Mead"),
			new MeadDefinition("MeadFrostResist", "frost_resistance_mead", 6, "Frost Resistance Mead"),
			new MeadDefinition("MeadHasty", "tonic_of_ratatosk", 7, "Tonic of Ratatosk"),
			new MeadDefinition("MeadHealthLingering", "lingering_healing_mead", 8, "Lingering Healing Mead"),
			new MeadDefinition("MeadHealthMajor", "major_healing_mead", 9, "Major Healing Mead"),
			new MeadDefinition("MeadHealthMedium", "medium_healing_mead", 10, "Medium Healing Mead"),
			new MeadDefinition("MeadHealthMinor", "minor_healing_mead", 11, "Minor Healing Mead"),
			new MeadDefinition("MeadLightfoot", "lightfoot_mead", 12, "Lightfoot Mead"),
			new MeadDefinition("MeadPoisonResist", "poison_resistance_mead", 13, "Poison Resistance Mead"),
			new MeadDefinition("MeadStaminaLingering", "lingering_stamina_mead", 14, "Lingering Stamina Mead"),
			new MeadDefinition("MeadStaminaMedium", "medium_stamina_mead", 15, "Medium Stamina Mead"),
			new MeadDefinition("MeadStaminaMinor", "minor_stamina_mead", 16, "Minor Stamina Mead"),
			new MeadDefinition("MeadStrength", "mead_of_troll_endurance", 17, "Mead of Troll Endurance"),
			new MeadDefinition("MeadSwimmer", "draught_of_vananidir", 18, "Draught of Vananidir"),
			new MeadDefinition("MeadTamer", "brew_of_animal_whispers", 19, "Brew of Animal Whispers"),
			new MeadDefinition("MeadTasty", "tasty_mead", 20, "Tasty Mead")
		};

		private static readonly Dictionary<string, MeadDefinition> ByPrefab = new Dictionary<string, MeadDefinition>(StringComparer.Ordinal);

		internal const string DynamicLabelOption = "Dynamic";

		internal const string EmptyLabelOption = "Empty";

		internal static readonly string[] LabelConfigOptions = BuildLabelConfigOptions();

		private static string[] BuildLabelConfigOptions()
		{
			List<string> list = new List<string> { "Dynamic", "Empty" };
			MeadDefinition[] definitions = Definitions;
			foreach (MeadDefinition meadDefinition in definitions)
			{
				list.Add(meadDefinition.LabelName);
			}
			return list.ToArray();
		}

		internal static string LabelModeFromConfig(string option)
		{
			if (string.IsNullOrEmpty(option) || string.Equals(option, "Dynamic", StringComparison.OrdinalIgnoreCase))
			{
				return "Dynamic";
			}
			if (string.Equals(option, "Empty", StringComparison.OrdinalIgnoreCase))
			{
				return "Empty";
			}
			MeadDefinition[] definitions = Definitions;
			foreach (MeadDefinition meadDefinition in definitions)
			{
				if (string.Equals(option, meadDefinition.LabelName, StringComparison.OrdinalIgnoreCase) || string.Equals(option, meadDefinition.PrefabName, StringComparison.Ordinal))
				{
					return meadDefinition.PrefabName;
				}
			}
			return "Dynamic";
		}

		internal static string NormalizeLabelMode(string mode)
		{
			if (string.Equals(mode, "Empty", StringComparison.OrdinalIgnoreCase))
			{
				return "Empty";
			}
			if (string.Equals(mode, "Dynamic", StringComparison.OrdinalIgnoreCase) || string.IsNullOrEmpty(mode))
			{
				return "Dynamic";
			}
			MeadDefinition[] definitions = Definitions;
			foreach (MeadDefinition meadDefinition in definitions)
			{
				if (string.Equals(mode, meadDefinition.PrefabName, StringComparison.Ordinal))
				{
					return meadDefinition.PrefabName;
				}
			}
			return "Dynamic";
		}

		internal static int AtlasIndexForLabelMode(string mode, string assignedPrefab)
		{
			mode = NormalizeLabelMode(mode);
			if (string.Equals(mode, "Dynamic", StringComparison.Ordinal))
			{
				return AtlasIndexFor(assignedPrefab);
			}
			if (string.Equals(mode, "Empty", StringComparison.Ordinal))
			{
				return 0;
			}
			MeadDefinition[] definitions = Definitions;
			foreach (MeadDefinition meadDefinition in definitions)
			{
				if (string.Equals(mode, meadDefinition.PrefabName, StringComparison.Ordinal))
				{
					return meadDefinition.AtlasIndex;
				}
			}
			return 0;
		}

		internal static void Initialize()
		{
			ByPrefab.Clear();
			MeadDefinition[] definitions = Definitions;
			foreach (MeadDefinition meadDefinition in definitions)
			{
				if (Object.op_Implicit((Object)(object)PrefabManager.Instance.GetPrefab(meadDefinition.PrefabName)))
				{
					ByPrefab[meadDefinition.PrefabName] = meadDefinition;
				}
				else
				{
					Logger.LogWarning((object)("Mead keg support item '" + meadDefinition.PrefabName + "' was not found in this game build."));
				}
			}
		}

		internal static bool IsSupported(string prefabName)
		{
			if (!string.IsNullOrEmpty(prefabName))
			{
				return ByPrefab.ContainsKey(prefabName);
			}
			return false;
		}

		internal static string LabelKeyFor(string prefabName)
		{
			if (prefabName == null || !ByPrefab.TryGetValue(prefabName, out var value))
			{
				return "empty";
			}
			return value.LabelKey;
		}

		internal static int AtlasIndexFor(string prefabName)
		{
			if (prefabName == null || !ByPrefab.TryGetValue(prefabName, out var value))
			{
				return 0;
			}
			return value.AtlasIndex;
		}

		internal static string PrefabName(ItemData item)
		{
			if (item == null || !Object.op_Implicit((Object)(object)item.m_dropPrefab))
			{
				return null;
			}
			return ((Object)item.m_dropPrefab).name;
		}

		internal static string DisplayName(string prefabName)
		{
			if (string.IsNullOrEmpty(prefabName))
			{
				return "";
			}
			GameObject prefab = PrefabManager.Instance.GetPrefab(prefabName);
			ItemDrop val = (Object.op_Implicit((Object)(object)prefab) ? prefab.GetComponent<ItemDrop>() : null);
			string text = (((Object)(object)val != (Object)null && val.m_itemData != null && val.m_itemData.m_shared != null) ? val.m_itemData.m_shared.m_name : null);
			if (!string.IsNullOrEmpty(text) && Localization.instance != null)
			{
				return Localization.instance.Localize(text);
			}
			return prefabName;
		}
	}
	public sealed class MeadKegCapacity : MonoBehaviour
	{
		private static readonly HashSet<MeadKegCapacity> Active = new HashSet<MeadKegCapacity>();

		private static readonly FieldInfo InventoryWidth = AccessTools.Field(typeof(Inventory), "m_width");

		private static readonly FieldInfo InventoryHeight = AccessTools.Field(typeof(Inventory), "m_height");

		private Container container;

		private Inventory inventory;

		private float nextRefresh;

		private int lastAppliedCapacity = -1;

		private int lastBlockedCapacity = -1;

		private void OnEnable()
		{
			Active.Add(this);
			nextRefresh = 0f;
		}

		private void OnDisable()
		{
			Active.Remove(this);
		}

		private void OnDestroy()
		{
			Active.Remove(this);
		}

		private void Start()
		{
			ApplyConfiguredCapacity(force: true);
		}

		private void Update()
		{
			if (!(Time.unscaledTime < nextRefresh))
			{
				nextRefresh = Time.unscaledTime + 0.5f;
				ApplyConfiguredCapacity(force: false);
			}
		}

		internal static void RefreshAll()
		{
			MeadKegCapacity[] array = new MeadKegCapacity[Active.Count];
			Active.CopyTo(array);
			MeadKegCapacity[] array2 = array;
			foreach (MeadKegCapacity meadKegCapacity in array2)
			{
				if (Object.op_Implicit((Object)(object)meadKegCapacity))
				{
					meadKegCapacity.ApplyConfiguredCapacity(force: true);
				}
			}
		}

		internal void ApplyConfiguredCapacity(bool force)
		{
			DynamicStorageMeadHallPlugin current = DynamicStorageMeadHallPlugin.Current;
			if ((Object)(object)current == (Object)null)
			{
				return;
			}
			int kegStorageCapacity = current.KegStorageCapacity;
			if (!force && kegStorageCapacity == lastAppliedCapacity)
			{
				return;
			}
			if (!Object.op_Implicit((Object)(object)container))
			{
				container = ((Component)this).GetComponent<Container>();
			}
			if (!Object.op_Implicit((Object)(object)container))
			{
				return;
			}
			Inventory val = container.GetInventory();
			if (val != null)
			{
				inventory = val;
			}
			DynamicStorageMeadHallPlugin.GetStorageGrid(kegStorageCapacity, out var width, out var height);
			if (inventory == null)
			{
				container.m_width = width;
				container.m_height = height;
				return;
			}
			int num = ReadDimension(InventoryWidth, inventory, container.m_width);
			int num2 = ReadDimension(InventoryHeight, inventory, container.m_height);
			if (width * height < num * num2 && !ItemsFit(width, height))
			{
				container.m_width = num;
				container.m_height = num2;
				if (lastBlockedCapacity != kegStorageCapacity)
				{
					lastBlockedCapacity = kegStorageCapacity;
					Logger.LogWarning((object)$"{((Object)((Component)this).gameObject).name}: keg capacity reduction to {kegStorageCapacity} slots deferred because existing items do not fit.");
				}
				return;
			}
			lastBlockedCapacity = -1;
			bool num3 = num != width || num2 != height || container.m_width != width || container.m_height != height;
			container.m_width = width;
			container.m_height = height;
			WriteDimension(InventoryWidth, inventory, width);
			WriteDimension(InventoryHeight, inventory, height);
			lastAppliedCapacity = kegStorageCapacity;
			if (num3)
			{
				int num4 = inventory.GetAllItems()?.Count ?? 0;
				Logger.LogInfo((object)($"{((Object)((Component)this).gameObject).name}: keg grid resized {num}x{num2} -> {width}x{height} " + $"without Inventory.Changed notification; stacks={num4}."));
			}
		}

		private bool ItemsFit(int width, int height)
		{
			if (inventory == null)
			{
				return true;
			}
			List<ItemData> allItems = inventory.GetAllItems();
			if (allItems == null)
			{
				return true;
			}
			foreach (ItemData item in allItems)
			{
				if (item != null && (item.m_gridPos.x < 0 || item.m_gridPos.y < 0 || item.m_gridPos.x >= width || item.m_gridPos.y >= height))
				{
					return false;
				}
			}
			return true;
		}

		private static int ReadDimension(FieldInfo field, Inventory target, int fallback)
		{
			if (field == null || target == null)
			{
				return fallback;
			}
			try
			{
				return (int)field.GetValue(target);
			}
			catch
			{
				return fallback;
			}
		}

		private static void WriteDimension(FieldInfo field, Inventory target, int value)
		{
			if (field == null || target == null)
			{
				return;
			}
			try
			{
				field.SetValue(target, value);
			}
			catch (Exception ex)
			{
				Logger.LogWarning((object)("Mead keg inventory dimension update failed: " + ex.Message));
			}
		}
	}
	internal static class MeadKegCapacityPatches
	{
		private static bool installed;

		internal static bool Install(Harmony harmony)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			if (installed)
			{
				return true;
			}
			MethodInfo methodInfo = AccessTools.Method(typeof(Container), "Awake", (Type[])null, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.Method(typeof(MeadKegCapacityPatches), "ContainerAwakePrefix", (Type[])null, (Type[])null);
			if (methodInfo == null || methodInfo2 == null)
			{
				return false;
			}
			harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			installed = true;
			return true;
		}

		private static void ContainerAwakePrefix(Container __instance)
		{
			if (Object.op_Implicit((Object)(object)__instance) && Object.op_Implicit((Object)(object)((Component)__instance).GetComponent<MeadKegCapacity>()))
			{
				DynamicStorageMeadHallPlugin.GetStorageGrid(60, out var width, out var height);
				__instance.m_width = width;
				__instance.m_height = height;
			}
		}
	}
	public sealed class MeadKegScale : MonoBehaviour
	{
		private const string ZdoScaleKey = "DSMK.Scale";

		private const string ZdoHeightOffsetKey = "DSMK.HeightOffset";

		private const string ZdoLabelModeKey = "DSMK.LabelMode";

		[SerializeField]
		private Vector3 baseScale = Vector3.one;

		private ZNetView nview;

		private bool applied;

		private float nextCheck;

		private float currentHeightOffset;

		private float currentScaleMultiplier = 1f;

		private string currentLabelMode = "Dynamic";

		private bool pendingPlacementSnapshot;

		private float pendingScale;

		private float pendingHeightOffset;

		private string pendingLabelMode;

		private float pendingDeadline;

		private float startedAt;

		internal float CurrentHeightOffset => currentHeightOffset;

		internal float CurrentScaleMultiplier => currentScaleMultiplier;

		internal string CurrentLabelMode => MeadCatalog.NormalizeLabelMode(currentLabelMode);

		internal void Setup(Vector3 originalBaseScale)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			baseScale = originalBaseScale;
		}

		private void Start()
		{
			startedAt = Time.time;
			nview = ((Component)this).GetComponent<ZNetView>();
			ApplyOrSave();
		}

		private void Update()
		{
			if (!applied && !(Time.unscaledTime < nextCheck))
			{
				nextCheck = Time.unscaledTime + 0.25f;
				ApplyOrSave();
			}
		}

		private void ApplyOrSave()
		{
			if (!Object.op_Implicit((Object)(object)nview))
			{
				nview = ((Component)this).GetComponent<ZNetView>();
			}
			if (!Object.op_Implicit((Object)(object)nview) || !nview.IsValid() || nview.GetZDO() == null)
			{
				return;
			}
			if (pendingPlacementSnapshot)
			{
				TryCommitPendingPlacementSnapshot();
			}
			ZDO zDO = nview.GetZDO();
			float num = zDO.GetFloat("DSMK.Scale", -1f);
			bool flag = num > 0f;
			float num2 = zDO.GetFloat("DSMK.HeightOffset", float.NaN);
			bool flag2 = !float.IsNaN(num2);
			string text = zDO.GetString("DSMK.LabelMode", "");
			bool flag3 = !string.IsNullOrEmpty(text);
			if ((!flag || !flag2 || !flag3) && nview.IsOwner())
			{
				DynamicStorageMeadHallPlugin current = DynamicStorageMeadHallPlugin.Current;
				if (!flag)
				{
					num = (((Object)(object)current != (Object)null) ? current.KegScale : 1f);
					zDO.Set("DSMK.Scale", num);
				}
				if (!flag2)
				{
					num2 = (((Object)(object)current != (Object)null) ? current.KegHeightOffset : 0f);
					zDO.Set("DSMK.HeightOffset", num2);
				}
				if (!flag3)
				{
					if (Time.time - startedAt < 1f && !pendingPlacementSnapshot)
					{
						return;
					}
					text = "Dynamic";
					zDO.Set("DSMK.LabelMode", text);
				}
			}
			if (!flag && num <= 0f)
			{
				num = 1f;
			}
			if (!flag2 && float.IsNaN(num2))
			{
				num2 = 0f;
			}
			if (string.IsNullOrEmpty(text))
			{
				text = "Dynamic";
			}
			ApplyScaleAndOffset(num, num2, text);
			applied = true;
		}

		internal void SavePlacementDefaults()
		{
			DynamicStorageMeadHallPlugin current = DynamicStorageMeadHallPlugin.Current;
			if (!((Object)(object)current == (Object)null))
			{
				pendingScale = current.KegScale;
				pendingHeightOffset = current.KegHeightOffset;
				pendingLabelMode = current.BarrelLabelTemplateMode;
				pendingPlacementSnapshot = true;
				pendingDeadline = Time.time + 15f;
				applied = false;
				TryCommitPendingPlacementSnapshot();
			}
		}

		private bool TryCommitPendingPlacementSnapshot()
		{
			if (!pendingPlacementSnapshot)
			{
				return false;
			}
			if (Time.time > pendingDeadline)
			{
				Logger.LogWarning((object)(((Object)((Component)this).gameObject).name + ": Mead Keg placement appearance snapshot timed out before ZDO ownership became ready."));
				pendingPlacementSnapshot = false;
				return false;
			}
			if (!Object.op_Implicit((Object)(object)nview))
			{
				nview = ((Component)this).GetComponent<ZNetView>();
			}
			if (!Object.op_Implicit((Object)(object)nview) || !nview.IsValid() || nview.GetZDO() == null || !nview.IsOwner())
			{
				return false;
			}
			ZDO zDO = nview.GetZDO();
			zDO.Set("DSMK.Scale", Mathf.Clamp(pendingScale, 0.5f, 3f));
			zDO.Set("DSMK.HeightOffset", Mathf.Clamp(pendingHeightOffset, -2f, 2f));
			zDO.Set("DSMK.LabelMode", MeadCatalog.NormalizeLabelMode(pendingLabelMode));
			pendingPlacementSnapshot = false;
			Logger.LogInfo((object)(((Object)((Component)this).gameObject).name + ": saved per-keg scale/height/label placement snapshot."));
			return true;
		}

		internal void ApplyPlacementPreview(float multiplier, float heightOffset, string labelMode)
		{
			ApplyScaleAndOffset(multiplier, heightOffset, labelMode);
		}

		private void ApplyScaleAndOffset(float multiplier, float heightOffset, string labelMode)
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			multiplier = Mathf.Clamp(multiplier, 0.5f, 3f);
			currentScaleMultiplier = multiplier;
			currentHeightOffset = Mathf.Clamp(heightOffset, -2f, 2f);
			currentLabelMode = MeadCatalog.NormalizeLabelMode(labelMode);
			((Component)this).transform.localScale = new Vector3(baseScale.x * multiplier, baseScale.y * multiplier, baseScale.z * multiplier);
			MeadKegVisual component = ((Component)this).GetComponent<MeadKegVisual>();
			if (Object.op_Implicit((Object)(object)component))
			{
				MeadKegStorage component2 = ((Component)this).GetComponent<MeadKegStorage>();
				component.Refresh(Object.op_Implicit((Object)(object)component2) ? component2.AssignedPrefabName : null);
			}
		}
	}
	public sealed class MeadKegStorage : MonoBehaviour
	{
		private const string ZdoAssignedKey = "DSMK.AssignedMead";

		private static readonly Dictionary<Inventory, MeadKegStorage> Registry = new Dictionary<Inventory, MeadKegStorage>();

		private Container container;

		private Inventory inventory;

		private ZNetView nview;

		private string assignedPrefab;

		private float nextRefresh;

		private bool mixedWarningShown;

		private float lastRejectMessageTime = -10f;

		internal string AssignedPrefabName => assignedPrefab;

		internal Container Container
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)container))
				{
					return container = ((Component)this).GetComponent<Container>();
				}
				return container;
			}
		}

		private void OnEnable()
		{
			nextRefresh = 0f;
		}

		private void Start()
		{
			container = ((Component)this).GetComponent<Container>();
			nview = ((Component)this).GetComponent<ZNetView>();
			RefreshState(forceVisual: true);
		}

		private void Update()
		{
			if (!(Time.unscaledTime < nextRefresh))
			{
				nextRefresh = Time.unscaledTime + 0.25f;
				RefreshState(forceVisual: false);
			}
		}

		private void OnDisable()
		{
			UnregisterInventory();
		}

		private void OnDestroy()
		{
			UnregisterInventory();
		}

		private void RefreshState(bool forceVisual)
		{
			if (!Object.op_Implicit((Object)(object)container))
			{
				container = ((Component)this).GetComponent<Container>();
			}
			if (!Object.op_Implicit((Object)(object)nview))
			{
				nview = ((Component)this).GetComponent<ZNetView>();
			}
			if (!Object.op_Implicit((Object)(object)container))
			{
				return;
			}
			Inventory val = container.GetInventory();
			if (inventory != val)
			{
				UnregisterInventory();
				inventory = val;
				if (inventory != null)
				{
					Registry[inventory] = this;
				}
			}
			bool mixed;
			string text = ResolveAssignmentFromInventory(out mixed);
			string text2 = ReadAssignedFromZdo();
			string b = ((!string.IsNullOrEmpty(text)) ? text : text2);
			if (inventory != null && inventory.GetAllItems().Count == 0)
			{
				b = null;
			}
			if (mixed && !mixedWarningShown)
			{
				mixedWarningShown = true;
				Logger.LogWarning((object)(((Object)((Component)this).gameObject).name + ": multiple mead types were already present. New inserts will be restricted to the first detected type until the keg is emptied."));
			}
			if (!mixed)
			{
				mixedWarningShown = false;
			}
			bool num = !string.Equals(assignedPrefab, b, StringComparison.Ordinal);
			assignedPrefab = b;
			if (Object.op_Implicit((Object)(object)nview) && nview.IsValid() && nview.IsOwner() && nview.GetZDO() != null)
			{
				string a = nview.GetZDO().GetString("DSMK.AssignedMead", "");
				string text3 = assignedPrefab ?? "";
				if (!string.Equals(a, text3, StringComparison.Ordinal))
				{
					nview.GetZDO().Set("DSMK.AssignedMead", text3);
				}
			}
			if (num || forceVisual)
			{
				MeadKegVisual component = ((Component)this).GetComponent<MeadKegVisual>();
				if (Object.op_Implicit((Object)(object)component))
				{
					component.Refresh(assignedPrefab);
				}
			}
		}

		private string ReadAssignedFromZdo()
		{
			if (!Object.op_Implicit((Object)(object)nview) || !nview.IsValid() || nview.GetZDO() == null)
			{
				return null;
			}
			string text = nview.GetZDO().GetString("DSMK.AssignedMead", "");
			if (!MeadCatalog.IsSupported(text))
			{
				return null;
			}
			return text;
		}

		private string ResolveAssignmentFromInventory(out bool mixed)
		{
			mixed = false;
			if (inventory == null)
			{
				return null;
			}
			string text = null;
			foreach (ItemData allItem in inventory.GetAllItems())
			{
				string text2 = MeadCatalog.PrefabName(allItem);
				if (!string.IsNullOrEmpty(text2))
				{
					if (text == null)
					{
						text = text2;
					}
					else if (!string.Equals(text, text2, StringComparison.Ordinal))
					{
						mixed = true;
					}
				}
			}
			return text;
		}

		internal bool Allows(ItemData item)
		{
			if (item == null)
			{
				return true;
			}
			return AllowsPrefab(MeadCatalog.PrefabName(item));
		}

		internal bool AllowsPrefab(GameObject prefab)
		{
			if (Object.op_Implicit((Object)(object)prefab))
			{
				return AllowsPrefab(((Object)prefab).name);
			}
			return false;
		}

		internal bool AllowsPrefab(string prefabName)
		{
			if (!MeadCatalog.IsSupported(prefabName))
			{
				return false;
			}
			bool mixed;
			string text = ResolveAssignmentFromInventory(out mixed);
			if (string.IsNullOrEmpty(text))
			{
				text = assignedPrefab;
			}
			if (!string.IsNullOrEmpty(text))
			{
				return string.Equals(text, prefabName, StringComparison.Ordinal);
			}
			return true;
		}

		internal void NotifyRejected(string attemptedPrefab)
		{
			if (Time.unscaledTime - lastRejectMessageTime < 0.6f)
			{
				return;
			}
			lastRejectMessageTime = Time.unscaledTime;
			string text;
			if (!MeadCatalog.IsSupported(attemptedPrefab))
			{
				text = "Only finished mead can be stored in this keg.";
			}
			else
			{
				bool mixed;
				string text2 = ResolveAssignmentFromInventory(out mixed);
				if (string.IsNullOrEmpty(text2))
				{
					text2 = assignedPrefab;
				}
				string text3 = MeadCatalog.DisplayName(text2);
				text = (string.IsNullOrEmpty(text3) ? "This keg already contains a different mead." : ("This keg can only hold " + text3 + "."));
			}
			Player localPlayer = Player.m_localPlayer;
			if (Object.op_Implicit((Object)(object)localPlayer))
			{
				((Character)localPlayer).Message((MessageType)2, text, 0, (Sprite)null, false);
			}
		}

		internal int TryQuickGrab(Player player, int requested)
		{
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)player) || requested <= 0 || !Object.op_Implicit((Object)(object)container))
			{
				return 0;
			}
			Inventory val = container.GetInventory();
			Inventory val2 = ((Humanoid)player).GetInventory();
			if (val == null || val2 == null)
			{
				return 0;
			}
			bool mixed;
			string text = ResolveAssignmentFromInventory(out mixed);
			if (string.IsNullOrEmpty(text))
			{
				return 0;
			}
			int num = requested;
			int num2 = 0;
			foreach (ItemData item in new List<ItemData>(val.GetAllItems()))
			{
				if (num <= 0)
				{
					break;
				}
				if (item == null || item.m_stack <= 0 || !string.Equals(MeadCatalog.PrefabName(item), text, StringComparison.Ordinal))
				{
					continue;
				}
				int num3 = Math.Min(num, item.m_stack);
				int num4 = 0;
				for (int num5 = num3; num5 >= 1; num5--)
				{
					ItemData val3 = item.Clone();
					val3.m_stack = num5;
					val3.m_gridPos = new Vector2i(-1, -1);
					if (val2.CanAddItem(val3, num5))
					{
						num4 = num5;
						break;
					}
				}
				if (num4 <= 0)
				{
					continue;
				}
				ItemData val4 = item.Clone();
				val4.m_stack = num4;
				val4.m_gridPos = new Vector2i(-1, -1);
				if (val2.AddItem(val4))
				{
					if (!val.RemoveItem(item, num4))
					{
						Logger.LogWarning((object)$"{((Object)((Component)this).gameObject).name}: quick grab added {num4} item(s) to the player but keg removal unexpectedly failed.");
						break;
					}
					num2 += num4;
					num -= num4;
				}
			}
			if (num2 > 0)
			{
				RefreshState(forceVisual: true);
				MeadKegEffects.PlayTapEffect(((Component)this).GetComponent<MeadKegVisual>());
			}
			return num2;
		}

		internal string BuildHoverText(string vanillaText)
		{
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			string text = (string.IsNullOrEmpty(assignedPrefab) ? null : MeadCatalog.DisplayName(assignedPrefab));
			string text2 = (string.IsNullOrEmpty(text) ? "Mead Keg" : ("Mead Keg - " + text));
			string text3 = vanillaText ?? "";
			int num = text3.IndexOf('\n');
			if (num >= 0)
			{
				text3 = text3.Substring(num + 1);
			}
			else if (!string.IsNullOrWhiteSpace(text3))
			{
				text3 = "[<color=yellow><b>$KEY_Use</b></color>] Open";
			}
			if (string.IsNullOrEmpty(text3))
			{
				text3 = "[<color=yellow><b>$KEY_Use</b></color>] Open";
			}
			if (!string.IsNullOrEmpty(text))
			{
				DynamicStorageMeadHallPlugin current = DynamicStorageMeadHallPlugin.Current;
				int num2 = (((Object)(object)current != (Object)null) ? current.QuickGrabAmount : 5);
				string text4 = (((Object)(object)current != (Object)null) ? ((object)current.QuickGrabShortcut/*cast due to .constrained prefix*/).ToString() : "LeftShift + E");
				text3 = text3 + "\n[<color=yellow><b>" + text4 + "</b></color>] Grab " + num2 + " " + text;
			}
			return text2 + "\n" + text3;
		}

		private void UnregisterInventory()
		{
			if (inventory != null)
			{
				if (Registry.TryGetValue(inventory, out var value) && (Object)(object)value == (Object)(object)this)
				{
					Registry.Remove(inventory);
				}
				inventory = null;
			}
		}

		internal static MeadKegStorage ForInventory(Inventory target)
		{
			if (target == null)
			{
				return null;
			}
			if (!Registry.TryGetValue(target, out var value))
			{
				return null;
			}
			return value;
		}
	}
	internal static class MeadKegInventoryPatches
	{
		internal static bool Install(Harmony harmony)
		{
			if (harmony == null)
			{
				return false;
			}
			return (byte)(1u & (PatchPrefix(harmony, AccessTools.Method(typeof(Inventory), "CanAddItem", new Type[2]
			{
				typeof(ItemData),
				typeof(int)
			}, (Type[])null), "CanAddItemData") ? 1u : 0u) & (PatchPrefix(harmony, AccessTools.Method(typeof(Inventory), "CanAddItem", new Type[2]
			{
				typeof(GameObject),
				typeof(int)
			}, (Type[])null), "CanAddPrefab") ? 1u : 0u) & (PatchPrefix(harmony, AccessTools.Method(typeof(Inventory), "AddItem", new Type[1] { typeof(ItemData) }, (Type[])null), "AddItemData") ? 1u : 0u) & (PatchPrefix(harmony, AccessTools.Method(typeof(Inventory), "AddItem", new Type[5]
			{
				typeof(ItemData),
				typeof(int),
				typeof(int),
				typeof(int),
				typeof(bool)
			}, (Type[])null), "AddItemAt") ? 1u : 0u) & (PatchPrefix(harmony, AccessTools.Method(typeof(Inventory), "MoveItemToThis", new Type[2]
			{
				typeof(Inventory),
				typeof(ItemData)
			}, (Type[])null), "MoveItemToThisSimple") ? 1u : 0u) & (PatchPrefix(harmony, AccessTools.Method(typeof(Inventory), "MoveItemToThis", new Type[5]
			{
				typeof(Inventory),
				typeof(ItemData),
				typeof(int),
				typeof(int),
				typeof(int)
			}, (Type[])null), "MoveItemToThisAt") ? 1u : 0u)) != 0;
		}

		private static bool PatchPrefix(Harmony harmony, MethodBase target, string prefixName)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			if (target == null)
			{
				Logger.LogWarning((object)"A mead-keg inventory restriction hook was not found in this Valheim build.");
				return false;
			}
			MethodInfo methodInfo = AccessTools.Method(typeof(MeadKegInventoryPatches), prefixName, (Type[])null, (Type[])null);
			try
			{
				harmony.Patch(target, new HarmonyMethod(methodInfo), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				return true;
			}
			catch (Exception ex)
			{
				Logger.LogWarning((object)("Mead-keg restriction hook failed: " + ex.Message));
				return false;
			}
		}

		private static bool CanAddItemData(Inventory __instance, ItemData item, ref bool __result)
		{
			MeadKegStorage meadKegStorage = MeadKegStorage.ForInventory(__instance);
			if (!Object.op_Implicit((Object)(object)meadKegStorage) || meadKegStorage.Allows(item))
			{
				return true;
			}
			__result = false;
			return false;
		}

		private static bool CanAddPrefab(Inventory __instance, GameObject prefab, ref bool __result)
		{
			MeadKegStorage meadKegStorage = MeadKegStorage.ForInventory(__instance);
			if (!Object.op_Implicit((Object)(object)meadKegStorage) || meadKegStorage.AllowsPrefab(prefab))
			{
				return true;
			}
			__result = false;
			return false;
		}

		private static bool AddItemData(Inventory __instance, ItemData item, ref bool __result)
		{
			MeadKegStorage meadKegStorage = MeadKegStorage.ForInventory(__instance);
			if (!Object.op_Implicit((Object)(object)meadKegStorage) || meadKegStorage.Allows(item))
			{
				return true;
			}
			meadKegStorage.NotifyRejected(MeadCatalog.PrefabName(item));
			__result = false;
			return false;
		}

		private static bool AddItemAt(Inventory __instance, ItemData item, ref bool __result)
		{
			MeadKegStorage meadKegStorage = MeadKegStorage.ForInventory(__instance);
			if (!Object.op_Implicit((Object)(object)meadKegStorage) || meadKegStorage.Allows(item))
			{
				return true;
			}
			meadKegStorage.NotifyRejected(MeadCatalog.PrefabName(item));
			__result = false;
			return false;
		}

		private static bool MoveItemToThisSimple(Inventory __instance, Inventory fromInventory, ItemData item)
		{
			MeadKegStorage meadKegStorage = MeadKegStorage.ForInventory(__instance);
			if ((Object)(object)meadKegStorage == (Object)null || fromInventory == __instance || meadKegStorage.Allows(item))
			{
				return true;
			}
			RejectMoveAndRestore(meadKegStorage, fromInventory, item);
			return false;
		}

		private static bool MoveItemToThisAt(Inventory __instance, Inventory fromInventory, ItemData item)
		{
			MeadKegStorage meadKegStorage = MeadKegStorage.ForInventory(__instance);
			if ((Object)(object)meadKegStorage == (Object)null || fromInventory == __instance || meadKegStorage.Allows(item))
			{
				return true;
			}
			RejectMoveAndRestore(meadKegStorage, fromInventory, item);
			return false;
		}

		private static void RejectMoveAndRestore(MeadKegStorage storage, Inventory fromInventory, ItemData item)
		{
			//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_004b: 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)
			if (Object.op_Implicit((Object)(object)storage))
			{
				storage.NotifyRejected(MeadCatalog.PrefabName(item));
			}
			if (fromInventory == null || item == null || ContainsReference(fromInventory, item))
			{
				return;
			}
			try
			{
				Vector2i gridPos = item.m_gridPos;
				if (fromInventory.AddItem(item))
				{
					Logger.LogInfo((object)("Rejected incompatible Mead Keg swap and restored '" + MeadCatalog.PrefabName(item) + "' " + $"to the source inventory (previous grid {gridPos.x},{gridPos.y})."));
				}
				else
				{
					Logger.LogError((object)("Rejected incompatible Mead Keg swap but could not restore '" + MeadCatalog.PrefabName(item) + "' to the source inventory. Leave the inventories open and report this log before moving more items."));
				}
			}
			catch (Exception ex)
			{
				Logger.LogError((object)("Rejected incompatible Mead Keg swap restoration failed: " + ex));
			}
		}

		private static bool ContainsReference(Inventory inventory, ItemData item)
		{
			if (inventory == null || item == null)
			{
				return false;
			}
			List<ItemData> allItems = inventory.GetAllItems();
			if (allItems == null)
			{
				return false;
			}
			foreach (ItemData item2 in allItems)
			{
				if (item2 == item)
				{
					return true;
				}
			}
			return false;
		}
	}
	public sealed class MeadKegVisual : MonoBehaviour
	{
		private const int DiscSegments = 32;

		private static readonly HashSet<MeadKegVisual> Active = new HashSet<MeadKegVisual>();

		private Transform labelAnchor;

		private Transform tapEffectAnchor;

		private Transform idleEffectAnchor;

		private MeshRenderer labelRenderer;

		private MeshFilter labelFilter;

		private Mesh labelMesh;

		private Material labelMaterial;

		private GameObject idleEffect;

		private int currentAtlasIndex = -1;

		private bool faceFrameResolved;

		private Vector3 faceCenterLocal;

		private Vector3 faceOutwardLocal = Vector3.forward;

		private Vector3 faceRightLocal = Vector3.right;

		private Vector3 faceUpLocal = Vector3.up;

		private Vector3 tapPointLocal;

		private Quaternion faceRotationLocal = Quaternion.identity;

		internal Transform TapEffectAnchor
		{
			get
			{
				EnsureLabel();
				if (!Object.op_Implicit((Object)(object)tapEffectAnchor))
				{
					return ((Component)this).transform;
				}
				return tapEffectAnchor;
			}
		}

		internal Transform IdleEffectAnchor
		{
			get
			{
				EnsureLabel();
				if (!Object.op_Implicit((Object)(object)idleEffectAnchor))
				{
					return ((Component)this).transform;
				}
				return idleEffectAnchor;
			}
		}

		internal float TapEffectPlaybackScale
		{
			get
			{
				DynamicStorageMeadHallPlugin current = DynamicStorageMeadHallPlugin.Current;
				if (!((Object)(object)current != (Object)null))
				{
					return 1f;
				}
				return current.TapEffectScaleMultiplier;
			}
		}

		private void OnEnable()
		{
			Active.Add(this);
		}

		private void OnDisable()
		{
			Active.Remove(this);
		}

		private void Start()
		{
			if (!string.Equals(((Object)((Component)this).gameObject).name, "DSMK_MeadKeg", StringComparison.Ordinal))
			{
				EnsureLabel();
				MeadKegStorage component = ((Component)this).GetComponent<MeadKegStorage>();
				Refresh(Object.op_Implicit((Object)(object)component) ? component.AssignedPrefabName : null);
			}
		}

		private void OnDestroy()
		{
			Active.Remove(this);
			if (Object.op_Implicit((Object)(object)labelMaterial))
			{
				Object.Destroy((Object)(object)labelMaterial);
			}
			if (Object.op_Implicit((Object)(object)labelMesh))
			{
				Object.Destroy((Object)(object)labelMesh);
			}
		}

		internal static void RefreshAllTransforms()
		{
			MeadKegVisual[] array = Active.ToArray();
			foreach (MeadKegVisual meadKegVisual in array)
			{
				if (Object.op_Implicit((Object)(object)meadKegVisual))
				{
					MeadKegStorage component = ((Component)meadKegVisual).GetComponent<MeadKegStorage>();
					meadKegVisual.Refresh(Object.op_Implicit((Object)(object)component) ? component.AssignedPrefabName : null);
				}
			}
		}

		internal static MeadKegVisual FindNearestPlaced(Vector3 worldPosition, float maxDistance)
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: 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)
			MeadKegVisual result = null;
			float num = maxDistance * maxDistance;
			MeadKegVisual[] array = Active.ToArray();
			foreach (MeadKegVisual meadKegVisual in array)
			{
				if (!Object.op_Implicit((Object)(object)meadKegVisual) || string.Equals(((Object)((Component)meadKegVisual).gameObject).name, "DSMK_MeadKeg", StringComparison.Ordinal))
				{
					continue;
				}
				ZNetView component = ((Component)meadKegVisual).GetComponent<ZNetView>();
				if (Object.op_Implicit((Object)(object)component) && component.IsValid() && component.GetZDO() != null)
				{
					Vector3 val = ((Component)meadKegVisual).transform.position - worldPosition;
					float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
					if (sqrMagnitude <= num)
					{
						num = sqrMagnitude;
						result = meadKegVisual;
					}
				}
			}
			return result;
		}

		internal void Refresh(string assignedPrefab)
		{
			EnsureLabel();
			MeadKegScale component = ((Component)this).GetComponent<MeadKegScale>();
			int num = MeadCatalog.AtlasIndexForLabelMode(Object.op_Implicit((Object)(object)component) ? component.CurrentLabelMode : "Dynamic", assignedPrefab);
			if (currentAtlasIndex != num)
			{
				currentAtlasIndex = num;
				ApplyAtlasIndex(num);
			}
			RefreshTransform();
			RefreshIdleEffect(!string.IsNullOrEmpty(assignedPrefab));
		}

		internal void RefreshTransform()
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: 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_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: 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_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: 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_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//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_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: 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_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0268: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			DynamicStorageMeadHallPlugin current = DynamicStorageMeadHallPlugin.Current;
			if (!((Object)(object)current == (Object)null))
			{
				ResolveFrontFaceFrame();
				if (Object.op_Implicit((Object)(object)labelAnchor))
				{
					labelAnchor.localPosition = faceCenterLocal + faceRightLocal * current.LabelLocalX + faceUpLocal * current.LabelLocalY + faceOutwardLocal * current.LabelLocalZ;
					labelAnchor.localRotation = faceRotationLocal * Quaternion.Euler(current.LabelRotationX, current.LabelRotationY, current.LabelRotationZ);
					labelAnchor.localScale = Vector3.one * current.LabelScale;
				}
				if (Object.op_Implicit((Object)(object)tapEffectAnchor))
				{
					MeadKegScale component = ((Component)this).GetComponent<MeadKegScale>();
					float num = (Object.op_Implicit((Object)(object)component) ? component.CurrentScaleMultiplier : 1f);
					float num2 = 0f;
					float num3 = -0.6f + 0.2f * (num - 1f);
					float num4 = -1.2f + 0.6f * (num - 1f);
					tapEffectAnchor.localPosition = tapPointLocal + faceRightLocal * (num2 + current.TapEffectLocalX) + faceUpLocal * (num3 + current.TapEffectLocalY) + faceOutwardLocal * (num4 + current.TapEffectLocalZ);
					tapEffectAnchor.localRotation = faceRotationLocal;
					tapEffectAnchor.localScale = Vector3.one;
				}
				if (Object.op_Implicit((Object)(object)idleEffectAnchor))
				{
					idleEffectAnchor.localPosition = tapPointLocal + faceRightLocal * current.IdleEffectLocalX + faceUpLocal * current.IdleEffectLocalY + faceOutwardLocal * current.IdleEffectLocalZ;
					idleEffectAnchor.localRotation = faceRotationLocal;
					idleEffectAnchor.localScale = Vector3.one;
				}
				if (Object.op_Implicit((Object)(object)idleEffect))
				{
					idleEffect.transform.localPosition = Vector3.zero;
					idleEffect.transform.localRotation = Quaternion.identity;
					idleEffect.transform.localScale = Vector3.one * current.IdleEffectScale;
				}
			}
		}

		private unsafe void ResolveFrontFaceFrame()
		{
			//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_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_026b: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: 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_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_029c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0301: Unknown result type (might be due to invalid IL or missing references)
			//IL_0306: Unknown result type (might be due to invalid IL or missing references)
			//IL_030a: Unknown result type (might be due to invalid IL or missing references)
			//IL_030f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0315: Unknown result type (might be due to invalid IL or missing references)
			//IL_031a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0321: Unknown result type (might be due to invalid IL or missing references)
			//IL_0327: Unknown result type (might be due to invalid IL or missing references)
			//IL_032c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0331: Unknown result type (might be due to invalid IL or missing references)
			//IL_0335: Unknown result type (might be due to invalid IL or missing references)
			//IL_033a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: 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_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_035e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0364: Unknown result type (might be due to invalid IL or missing references)
			//IL_0369: Unknown result type (might be due to invalid IL or missing references)
			//IL_036e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0372: Unknown result type (might be due to invalid IL or missing references)
			//IL_0377: Unknown result type (might be due to invalid IL or missing references)
			//IL_037d: Unknown result type (might be due to invalid IL or missing references)
			//IL_037f: Unknown result type (might be due to invalid IL or missing references)
			//IL_038b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0390: Unknown result type (might be due to invalid IL or missing references)
			//IL_0395: Unknown result type (might be due to invalid IL or missing references)
			//IL_039c: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_0352: Unknown result type (might be due to invalid IL or missing references)
			//IL_0357: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0401: Unknown result type (might be due to invalid IL or missing references)
			//IL_040d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0412: Unknown result type (might be due to invalid IL or missing references)
			//IL_0417: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03da: Unknown result type (might be due to invalid IL or missing references)
			//IL_03df: Unknown result type (might be due to invalid IL or missing references)
			//IL_042d: Unknown result type (might be due to invalid IL or missing references)
			//IL_042e: Unknown result type (might be due to invalid IL or missing references)
			//IL_045b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0460: Unknown result type (might be due to invalid IL or missing references)
			//IL_047b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0480: Unknown result type (might be due to invalid IL or missing references)
			if (faceFrameResolved)
			{
				return;
			}
			faceFrameResolved = true;
			Vector3 val = Vector3.zero;
			Vector3 val2 = Vector3.forward;
			float num = 0.82f;
			float num2 = 0.72f;
			CapsuleCollider val3 = null;
			float num3 = -1f;
			CapsuleCollider[] componentsInChildren = ((Component)this).GetComponentsInChildren<CapsuleCollider>(true);
			foreach (CapsuleCollider val4 in componentsInChildren)
			{
				if (Object.op_Implicit((Object)(object)val4) && !IsDsmkRuntimeChild(((Component)val4).transform))
				{
					float num4 = Mathf.Max(val4.height, val4.radius * 2f) * val4.radius * val4.radius;
					if (num4 > num3)
					{
						num3 = num4;
						val3 = val4;
					}
				}
			}
			Vector3 val8;
			Bounds result;
			if (Object.op_Implicit((Object)(object)val3))
			{
				Vector3 val5 = ((val3.direction == 0) ? Vector3.right : ((val3.direction == 1) ? Vector3.up : Vector3.forward));
				Vector3 val6 = ((Component)val3).transform.TransformPoint(val3.center);
				val = ((Component)this).transform.InverseTransformPoint(val6);
				Vector3 val7 = ((Component)val3).transform.TransformDirection(val5);
				val8 = ((Component)this).transform.InverseTransformDirection(val7);
				val2 = ((Vector3)(ref val8)).normalized;
				Vector3 val9 = val3.center + val5 * (val3.height * 0.5f);
				num = Mathf.Abs(Vector3.Dot(((Component)this).transform.InverseTransformPoint(((Component)val3).transform.TransformPoint(val9)) - val, val2));
				Vector3 val10 = ((val3.direction == 0) ? Vector3.up : Vector3.right);
				Vector3 val11 = val3.center + val10 * val3.radius;
				val8 = ((Component)this).transform.InverseTransformPoint(((Component)val3).transform.TransformPoint(val11)) - val;
				num2 = ((Vector3)(ref val8)).magnitude;
			}
			else if (TryGetMeshBoundsLocal(out result))
			{
				val = ((Bounds)(ref result)).center;
				Vector3 size = ((Bounds)(ref result)).size;
				if (size.x >= size.z)
				{
					val2 = Vector3.right;
					num = ((Bounds)(ref result)).extents.x;
					num2 = Mathf.Min(((Bounds)(ref result)).extents.y, ((Bounds)(ref result)).extents.z);
				}
				else
				{
					val2 = Vector3.forward;
					num = ((Bounds)(ref result)).extents.z;
					num2 = Mathf.Min(((Bounds)(ref result)).extents.y, ((Bounds)(ref result)).extents.x);
				}
			}
			float maximum = num;
			float minimum = 0f - num;
			TryGetMeshProjectionRange(val, val2, out minimum, out maximum);
			float num5 = maximum - num;
			float num6 = 0f - num - minimum;
			float num7 = ((num5 >= num6) ? 1f : (-1f));
			Transform val12 = FindNamedTapTransform();
			Vector3 val13 = Vector3.zero;
			bool flag = false;
			if (Object.op_Implicit((Object)(object)val12))
			{
				val13 = ((Component)this).transform.InverseTransformPoint(val12.position);
				float num8 = Vector3.Dot(val13 - val, val2);
				if (Mathf.Abs(num8) > num * 0.35f)
				{
					num7 = ((num8 >= 0f) ? 1f : (-1f));
					flag = true;
				}
			}
			val8 = val2 * num7;
			faceOutwardLocal = ((Vector3)(ref val8)).normalized;
			faceUpLocal = Vector3.up;
			val8 = Vector3.Cross(faceUpLocal, faceOutwardLocal);
			faceRightLocal = ((Vector3)(ref val8)).normalized;
			if (((Vector3)(ref faceRightLocal)).sqrMagnitude < 0.5f)
			{
				faceRightLocal = Vector3.right;
			}
			val8 = Vector3.Cross(faceOutwardLocal, faceRightLocal);
			faceUpLocal = ((Vector3)(ref val8)).normalized;
			faceCenterLocal = val + faceOutwardLocal * (num + 0.018f);
			faceRotationLocal = Quaternion.LookRotation(faceOutwardLocal, faceUpLocal);
			float num9 = ((num7 > 0f) ? maximum : (0f - minimum));
			if (flag)
			{
				tapPointLocal = val13 + faceOutwardLocal * 0.06f;
			}
			else
			{
				tapPointLocal = val + faceOutwardLocal * (num9 + 0.025f) - faceUpLocal * (num2 * 0.3f);
			}
			string[] obj = new string[9] { "Mead Keg front-face frame resolved: axis=", null, null, null, null, null, null, null, null };
			val8 = val2;
			obj[1] = ((object)(*(Vector3*)(&val8))/*cast due to .constrained prefix*/).ToString();
			obj[2] = ", tappedSign=";
			obj[3] = num7.ToString();
			obj[4] = ", face=";
			val8 = faceCenterLocal;
			obj[5] = ((object)(*(Vector3*)(&val8))/*cast due to .constrained prefix*/).ToString();
			obj[6] = ", tap=";
			val8 = tapPointLocal;
			obj[7] = ((object)(*(Vector3*)(&val8))/*cast due to .constrained prefix*/).ToString();
			obj[8] = ".";
			Logger.LogInfo((object)string.Concat(obj));
		}

		private Transform FindNamedTapTransform()
		{
			Transform[] componentsInChildren = ((Component)this).GetComponentsInChildren<Transform>(true);
			foreach (Transform val in componentsInChildren)
			{
				if (Object.op_Implicit((Object)(object)val) && !((Object)(object)val == (Object)(object)((Component)this).transform) && !IsDsmkRuntimeChild(val))
				{
					string text = (((Object)val).name ?? string.Empty).ToLowerInvariant();
					if (text.Contains("tap") || text.Contains("spigot") || text.Contains("spout") || text.Contains("faucet") || text.Contains("kran"))
					{
						return val;
					}
				}
			}
			return null;
		}

		private bool TryGetMeshProjectionRange(Vector3 origin, Vector3 axis, out float minimum, out float maximum)
		{
			//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_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: 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)
			//IL_0097: 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_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			minimum = float.PositiveInfinity;
			maximum = float.NegativeInfinity;
			bool flag = false;
			MeshFilter[] componentsInChildren = ((Component)this).GetComponentsInChildren<MeshFilter>(true);
			foreach (MeshFilter val in componentsInChildren)
			{
				if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.sharedMesh) || IsDsmkRuntimeChild(((Component)val).transform))
				{
					continue;
				}
				Bounds bounds = val.sharedMesh.bounds;
				Vector3 center = ((Bounds)(ref bounds)).center;
				Vector3 extents = ((Bounds)(ref bounds)).extents;
				for (int j = -1; j <= 1; j += 2)
				{
					for (int k = -1; k <= 1; k += 2)
					{
						for (int l = -1; l <= 1; l += 2)
						{
							Vector3 val2 = center + Vector3.Scale(extents, new Vector3((float)j, (float)k, (float)l));
							float num = Vector3.Dot(((Component)this).transform.InverseTransformPoint(((Component)val).transform.TransformPoint(val2)) - origin, axis);
							minimum = Mathf.Min(minimum, num);
							maximum = Mathf.Max(maximum, num);
							flag = true;
						}
					}
				}
			}
			if (!flag)
			{
				minimum = 0f;
				maximum = 0f;
			}
			return flag;
		}

		private bool TryGetMeshBoundsLocal(out Bounds result)
		{
			//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_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown