Decompiled source of AllTheBones v1.0.0

AllTheBones.dll

Decompiled 4 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Permissions;
using AllTheBones.Configuration;
using AllTheBones.Items;
using AllTheBones.Patches;
using AllTheBones.Systems;
using AllTheBones.Utils;
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 UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("JotunnModStub")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("JotunnModStub")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")]
[assembly: AssemblyFileVersion("0.1.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = "")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.0.0")]
namespace AllTheBones
{
	[BepInPlugin("com.ggr.AllTheBones", "AllTheBones", "0.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[SynchronizationMode(/*Could not decode attribute arguments.*/)]
	internal class AllTheBones : BaseUnityPlugin
	{
		public const string PluginGUID = "com.ggr.AllTheBones";

		public const string PluginName = "AllTheBones";

		public const string PluginVersion = "0.1.0";

		public static CustomLocalization Localization = LocalizationManager.Instance.GetLocalization();

		private void Awake()
		{
			Logger.LogInfo((object)"All The Bones has landed");
			ModConfig.Init(((BaseUnityPlugin)this).Config);
			Diagnostics.Enabled = ModConfig.Diagnostics.Value;
			AddLocalizations();
			ApplyPatches();
			PrefabManager.OnVanillaPrefabsAvailable += AddItems;
		}

		private void ApplyPatches()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			Harmony harmony = new Harmony("com.ggr.AllTheBones");
			ApplyPatch(harmony, ModConfig.UseItemPatch, typeof(UseItemPatches));
			ApplyPatch(harmony, ModConfig.PlantGrowthPatch, typeof(PlantGrowthPatches));
			ApplyPatch(harmony, ModConfig.PlantGrowthPatch, typeof(PlantAwakePatches));
			ApplyPatch(harmony, ModConfig.StabilityBoostPatch, typeof(StabilityBoostPatch));
			ApplyPatch(harmony, ModConfig.WeatherImmunityPatch, typeof(WeatherImmunityPatch));
			if (Diagnostics.Enabled)
			{
				ApplyPatch(harmony, null, typeof(UpdateSupportProbe));
				ApplyPatch(harmony, null, typeof(ClearCacheProbe));
			}
			Logger.LogInfo((object)$"[AllTheBones] configuration: UseItem={ToggleText(ModConfig.UseItemPatch)} PlantGrowth={ToggleText(ModConfig.PlantGrowthPatch)} StabilityBoost={ToggleText(ModConfig.StabilityBoostPatch)} WeatherImmunity={ToggleText(ModConfig.WeatherImmunityPatch)} diagnostics={Diagnostics.Enabled}");
		}

		private static void ApplyPatch(Harmony harmony, ConfigEntry<bool> toggle, Type patchClass)
		{
			if (toggle != null && !toggle.Value)
			{
				Logger.LogInfo((object)("[AllTheBones] patch " + patchClass.Name + ": disabled by config"));
				return;
			}
			try
			{
				List<MethodInfo> list = harmony.CreateClassProcessor(patchClass).Patch();
				Logger.LogInfo((object)$"[AllTheBones] patch {patchClass.Name}: {list.Count} method(s)");
			}
			catch (Exception ex)
			{
				Logger.LogError((object)("[AllTheBones] patch " + patchClass.Name + " failed: " + ex.Message));
			}
		}

		private static string ToggleText(ConfigEntry<bool> toggle)
		{
			return (toggle != null && toggle.Value) ? "on" : "off";
		}

		private void Update()
		{
			Diagnostics.Tick();
			MealBagRadiusIndicator.EnsureExists();
			BoostedPlantTint.Tick();
		}

		private void AddLocalizations()
		{
			CustomLocalization localization = Localization;
			string text = "English";
			localization.AddTranslation(ref text, new Dictionary<string, string>
			{
				{ "item_bonemeal", "Bone Meal" },
				{ "item_bonemeal_description", "Ground bone, rich in nutrients. Spread on a planted crop to speed up its growth. Put it on your hotbar and use it on a crop." },
				{ "item_ivorypowder", "Ivory Powder" },
				{ "item_ivorypowder_description", "Bone, ground to a fine white powder. Binds bone glue into bone cement." },
				{ "atb_plant_mature", "This plant is already fully grown." },
				{ "atb_growth_maxed", "This plant is already growing as fast as it can." },
				{ "atb_no_plants_nearby", "There are no plants close enough." },
				{ "atb_treat_done", "This piece is already treated." },
				{ "atb_wrong_material", "That material cannot be treated with this." },
				{ "atb_growth_applied", "Bone Meal applied. Growth time reduced by $1% ($2/$3)." },
				{ "item_mealbag", "Meal Bag" },
				{ "item_mealbag_description", "A bag of ground bone. Boosts every plant around you at once. Put it on your hotbar and use it among your crops." },
				{ "atb_bag_applied", "Meal Bag applied to $1 plant(s). Growth time reduced by $2%." },
				{ "item_boneglue", "Bone Glue" },
				{ "item_boneglue_description", "Sticky bone glue. Treats wood and corewood so the rain no longer rots them. Each treated piece lets the structure above it carry one extra metre. Use it on a building piece from your hotbar." },
				{ "item_bonecement", "Bone Cement" },
				{ "item_bonecement_description", "Bone glue bound with ivory powder. Turns stone and iron pieces into stronger structures. Each treated piece lets the structure above it carry one extra metre. Use it on a building piece from your hotbar." },
				{ "atb_glue_applied", "Bone Glue applied. This piece now carries more weight above it." },
				{ "atb_cement_applied", "Bone Cement applied. This piece now carries more weight above it." }
			});
		}

		private void AddItems()
		{
			BoneMeal.Add();
			MealBag.Add();
			BoneGlue.Add();
			BoneCement.Add();
			IvoryPowder.Add();
			PrefabManager.OnVanillaPrefabsAvailable -= AddItems;
		}
	}
}
namespace AllTheBones.Utils
{
	internal static class ItemRecolor
	{
		private class IconPixels
		{
			public Color32[] Pixels;

			public string Origin;
		}

		private const float ShadowFactor = 0.45f;

		private const float Contrast = 1.15f;

		private const int MinimumCoveragePercent = 2;

		private const float MinimumLuminance = 0.05f;

		private static readonly List<Object> KeepAlive = new List<Object>();

		private static Texture2D whiteTexture;

		public static void Recolor(CustomItem item, Color tint)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			if (item == null || (Object)(object)item.ItemPrefab == (Object)null || (Object)(object)item.ItemDrop == (Object)null)
			{
				return;
			}
			DisableParticles(item.ItemPrefab);
			TintMaterials(item.ItemPrefab, tint);
			Sprite[] array = item.ItemDrop.m_itemData?.m_shared?.m_icons;
			if (array == null || array.Length == 0)
			{
				Logger.LogWarning((object)$"Custom item {item} has no icon to recolour");
				return;
			}
			Sprite val = RecolorIcon(item.ItemPrefab, array[0], tint);
			if ((Object)(object)val == (Object)null)
			{
				Logger.LogWarning((object)("Keeping the vanilla icon of " + ((Object)item.ItemPrefab).name));
				return;
			}
			item.ItemDrop.m_itemData.m_shared.m_icons = (Sprite[])(object)new Sprite[1] { val };
		}

		public static Sprite RecolorIcon(GameObject prefab, Sprite sourceIcon, Color tint)
		{
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)prefab == (Object)null || (Object)(object)sourceIcon == (Object)null)
			{
				return null;
			}
			if ((Object)(object)sourceIcon.texture != (Object)null)
			{
				Texture2D texture = sourceIcon.texture;
				Logger.LogInfo((object)$"Icon source of {((Object)prefab).name}: '{((Object)texture).name}' {((Texture)texture).width}x{((Texture)texture).height}, readable {((Texture)texture).isReadable}, rect {sourceIcon.rect}, textureRect {sourceIcon.textureRect}");
			}
			Sprite val = LoadShippedIcon(prefab, sourceIcon);
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			IconPixels iconPixels = ReadPixels(sourceIcon);
			if (iconPixels != null)
			{
				Measure(iconPixels.Pixels, out var opaque, out var maxLuminance);
				Logger.LogInfo((object)$"Icon of {((Object)prefab).name}: {iconPixels.Origin} readback, {opaque}/{iconPixels.Pixels.Length} opaque, max luminance {maxLuminance:0.00}");
				if (IsPlausible(iconPixels.Pixels, opaque, maxLuminance))
				{
					Sprite val2 = CreateSprite(sourceIcon, TintPixels(iconPixels.Pixels, tint));
					if ((Object)(object)val2 != (Object)null)
					{
						return val2;
					}
				}
				else
				{
					Logger.LogWarning((object)("Icon readback of " + ((Object)prefab).name + " via " + iconPixels.Origin + " looks empty, discarding it"));
				}
			}
			Sprite val3 = RenderIcon(prefab);
			if ((Object)(object)val3 != (Object)null)
			{
				Logger.LogWarning((object)("Rendered the icon of " + ((Object)prefab).name + " from its model"));
				return val3;
			}
			Logger.LogWarning((object)("Could not create an icon for " + ((Object)prefab).name));
			return null;
		}

		private static IconPixels ReadPixels(Sprite source)
		{
			return ReadPixelsDirect(source) ?? ReadPixelsViaGpu(source);
		}

		private static IconPixels ReadPixelsDirect(Sprite source)
		{
			Texture2D texture = source.texture;
			if ((Object)(object)texture == (Object)null || !((Texture)texture).isReadable)
			{
				return null;
			}
			try
			{
				Color32[] array = CopyRegion(texture.GetPixels32(), ((Texture)texture).width, ((Texture)texture).height, source);
				return (array == null) ? null : new IconPixels
				{
					Pixels = array,
					Origin = "cpu"
				};
			}
			catch (UnityException)
			{
				return null;
			}
		}

		private static IconPixels ReadPixelsViaGpu(Sprite source)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Expected O, but got Unknown
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			Texture2D texture = source.texture;
			if ((Object)(object)texture == (Object)null)
			{
				return null;
			}
			Rect val = SourceRegion(source);
			int num = Mathf.RoundToInt(((Rect)(ref val)).width);
			int num2 = Mathf.RoundToInt(((Rect)(ref val)).height);
			if (num <= 0 || num2 <= 0)
			{
				return null;
			}
			RenderTexture active = RenderTexture.active;
			RenderTexture val2 = null;
			try
			{
				val2 = RenderTexture.GetTemporary(num, num2, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)2);
				Vector2 val3 = default(Vector2);
				((Vector2)(ref val3))..ctor(((Rect)(ref val)).width / (float)((Texture)texture).width, ((Rect)(ref val)).height / (float)((Texture)texture).height);
				Vector2 val4 = default(Vector2);
				((Vector2)(ref val4))..ctor(((Rect)(ref val)).x / (float)((Texture)texture).width, ((Rect)(ref val)).y / (float)((Texture)texture).height);
				Graphics.Blit((Texture)(object)texture, val2, val3, val4);
				RenderTexture.active = val2;
				Texture2D val5 = new Texture2D(num, num2, (TextureFormat)4, false);
				val5.ReadPixels(new Rect(0f, 0f, (float)num, (float)num2), 0, 0);
				val5.Apply();
				Color32[] pixels = val5.GetPixels32();
				Object.Destroy((Object)(object)val5);
				return new IconPixels
				{
					Pixels = pixels,
					Origin = "gpu"
				};
			}
			catch (Exception ex)
			{
				Logger.LogWarning((object)("Reading the icon texture of " + ((Object)source).name + " failed: " + ex.Message));
				return null;
			}
			finally
			{
				RenderTexture.active = active;
				if ((Object)(object)val2 != (Object)null)
				{
					RenderTexture.ReleaseTemporary(val2);
				}
			}
		}

		private static Color32[] CopyRegion(Color32[] sourcePixels, int sourceWidth, int sourceHeight, Sprite source)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			if (sourcePixels == null)
			{
				return null;
			}
			Rect val = SourceRegion(source);
			int num = Mathf.RoundToInt(((Rect)(ref val)).width);
			int num2 = Mathf.RoundToInt(((Rect)(ref val)).height);
			int num3 = Mathf.RoundToInt(((Rect)(ref val)).x);
			int num4 = Mathf.RoundToInt(((Rect)(ref val)).y);
			if (num <= 0 || num2 <= 0 || num3 < 0 || num4 < 0 || num3 + num > sourceWidth || num4 + num2 > sourceHeight)
			{
				return null;
			}
			Color32[] array = (Color32[])(object)new Color32[num * num2];
			for (int i = 0; i < num2; i++)
			{
				int num5 = (num4 + i) * sourceWidth + num3;
				int num6 = i * num;
				for (int j = 0; j < num; j++)
				{
					array[num6 + j] = sourcePixels[num5 + j];
				}
			}
			return array;
		}

		private static void Measure(Color32[] pixels, out int opaque, out float maxLuminance)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			opaque = 0;
			maxLuminance = 0f;
			if (pixels == null)
			{
				return;
			}
			foreach (Color32 val in pixels)
			{
				if (val.a > 8)
				{
					opaque++;
				}
				float num = (0.299f * (float)(int)val.r + 0.587f * (float)(int)val.g + 0.114f * (float)(int)val.b) / 255f;
				if (num > maxLuminance)
				{
					maxLuminance = num;
				}
			}
		}

		private static bool IsPlausible(Color32[] pixels, int opaque, float maxLuminance)
		{
			if (pixels == null || pixels.Length == 0)
			{
				return false;
			}
			return opaque * 100 >= pixels.Length * 2 && maxLuminance >= 0.05f;
		}

		private static Color32[] TintPixels(Color32[] pixels, Color tint)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: 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_003a: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			Color32[] array = (Color32[])(object)new Color32[pixels.Length];
			for (int i = 0; i < pixels.Length; i++)
			{
				Color32 val = pixels[i];
				float num = (0.299f * (float)(int)val.r + 0.587f * (float)(int)val.g + 0.114f * (float)(int)val.b) / 255f;
				float num2 = Mathf.Clamp01(Mathf.Lerp(0.45f, 1f, num) * 1.15f);
				array[i] = new Color32((byte)(tint.r * num2 * 255f), (byte)(tint.g * num2 * 255f), (byte)(tint.b * num2 * 255f), val.a);
			}
			return array;
		}

		private static Sprite CreateSprite(Sprite source, Color32[] pixels)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Expected O, but got Unknown
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			Texture2D texture = source.texture;
			Rect val = SourceRegion(source);
			int num = Mathf.RoundToInt(((Rect)(ref val)).width);
			int num2 = Mathf.RoundToInt(((Rect)(ref val)).height);
			if ((Object)(object)texture == (Object)null || pixels == null || pixels.Length != num * num2)
			{
				return null;
			}
			Texture2D val2 = new Texture2D(num, num2, (TextureFormat)4, false)
			{
				name = ((Object)texture).name + "_AllTheBones",
				filterMode = ((Texture)texture).filterMode,
				wrapMode = (TextureWrapMode)1
			};
			val2.SetPixels32(pixels);
			val2.Apply();
			KeepAlive.Add((Object)(object)val2);
			Sprite val3 = Sprite.Create(val2, new Rect(0f, 0f, (float)num, (float)num2), GetPivot(source), source.pixelsPerUnit, 0u, (SpriteMeshType)0);
			KeepAlive.Add((Object)(object)val3);
			return val3;
		}

		private static Vector2 GetPivot(Sprite sprite)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: 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_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0060: Unknown result type (might be due to invalid IL or missing references)
			Vector2 pivot = sprite.pivot;
			if (pivot.x > 1f || pivot.y > 1f)
			{
				float x = pivot.x;
				Rect rect = sprite.rect;
				float num = x / ((Rect)(ref rect)).width;
				float y = pivot.y;
				rect = sprite.rect;
				return new Vector2(num, y / ((Rect)(ref rect)).height);
			}
			return pivot;
		}

		private static Sprite RenderIcon(GameObject prefab)
		{
			try
			{
				return RenderManager.Instance.Render(prefab);
			}
			catch (Exception ex)
			{
				Logger.LogWarning((object)("Rendering an icon for " + ((Object)prefab).name + " failed: " + ex.Message));
				return null;
			}
		}

		private static void TintMaterials(GameObject prefab, Color tint)
		{
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			Renderer[] componentsInChildren = prefab.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				Material[] materials = val.materials;
				foreach (Material val2 in materials)
				{
					if ((Object)(object)val2 == (Object)null)
					{
						continue;
					}
					if (val2.HasProperty("_Saturation"))
					{
						if (val2.HasProperty("_Hue"))
						{
							val2.SetFloat("_Hue", 0f);
						}
						val2.SetFloat("_Saturation", -1f);
					}
					else if (val2.HasProperty("_MainTex"))
					{
						val2.SetTexture("_MainTex", (Texture)(object)WhiteTexture());
					}
					if (val2.HasProperty("_Color"))
					{
						val2.SetColor("_Color", tint);
					}
					else if (val2.HasProperty("_BaseColor"))
					{
						val2.SetColor("_BaseColor", tint);
					}
				}
			}
		}

		public static void DisableParticles(GameObject prefab)
		{
			//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)
			ParticleSystem[] componentsInChildren = prefab.GetComponentsInChildren<ParticleSystem>(true);
			foreach (ParticleSystem val in componentsInChildren)
			{
				if ((Object)(object)((Component)val).gameObject == (Object)(object)prefab)
				{
					Logger.LogInfo((object)("Switching off the root particle system of " + ((Object)prefab).name));
					EmissionModule emission = val.emission;
					((EmissionModule)(ref emission)).enabled = false;
					val.Stop(true, (ParticleSystemStopBehavior)0);
					ParticleSystemRenderer component = ((Component)val).GetComponent<ParticleSystemRenderer>();
					if ((Object)(object)component != (Object)null)
					{
						((Renderer)component).enabled = false;
					}
				}
				else
				{
					Logger.LogInfo((object)("Disabling the particle system '" + ((Object)((Component)val).gameObject).name + "' of " + ((Object)prefab).name));
					((Component)val).gameObject.SetActive(false);
				}
			}
		}

		private static Rect SourceRegion(Sprite sprite)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			Rect textureRect = sprite.textureRect;
			if (((Rect)(ref textureRect)).width > 0f && ((Rect)(ref textureRect)).height > 0f)
			{
				return textureRect;
			}
			return sprite.rect;
		}

		private static Sprite LoadShippedIcon(GameObject prefab, Sprite sourceIcon)
		{
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Expected O, but got Unknown
			//IL_010a: 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_01fb: 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_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			string text = FindIconFile(((Object)prefab).name);
			if (text == null)
			{
				return null;
			}
			try
			{
				byte[] array = File.ReadAllBytes(text);
				if (array.Length != 16384)
				{
					Logger.LogWarning((object)$"Shipped icon {text} has {array.Length} bytes, expected {16384}");
					return null;
				}
				Color32[] array2 = (Color32[])(object)new Color32[4096];
				for (int i = 0; i < array2.Length; i++)
				{
					array2[i] = new Color32(array[i * 4], array[i * 4 + 1], array[i * 4 + 2], array[i * 4 + 3]);
				}
				Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false)
				{
					name = ((Object)prefab).name + "_AllTheBones",
					wrapMode = (TextureWrapMode)1
				};
				if ((Object)(object)sourceIcon != (Object)null && (Object)(object)sourceIcon.texture != (Object)null)
				{
					((Texture)val).filterMode = ((Texture)sourceIcon.texture).filterMode;
				}
				val.SetPixels32(array2);
				val.Apply();
				Measure(array2, out var opaque, out var maxLuminance);
				Logger.LogInfo((object)$"Shipped icon of {((Object)prefab).name}: {((Texture)val).width}x{((Texture)val).height}, {opaque}/{array2.Length} opaque, max luminance {maxLuminance:0.00}");
				if (!IsPlausible(array2, opaque, maxLuminance))
				{
					Logger.LogWarning((object)("Shipped icon " + text + " looks empty, ignoring it"));
					return null;
				}
				KeepAlive.Add((Object)(object)val);
				float num = (((Object)(object)sourceIcon != (Object)null) ? sourceIcon.pixelsPerUnit : 100f);
				Vector2 val2 = (Vector2)(((Object)(object)sourceIcon != (Object)null) ? GetPivot(sourceIcon) : new Vector2(0.5f, 0.5f));
				Sprite val3 = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), val2, num, 0u, (SpriteMeshType)0);
				KeepAlive.Add((Object)(object)val3);
				return val3;
			}
			catch (Exception ex)
			{
				Logger.LogWarning((object)("Loading the shipped icon " + text + " failed: " + ex.Message));
				return null;
			}
		}

		private static string FindIconFile(string prefabId)
		{
			foreach (string item in IconDirectories())
			{
				string text = Path.Combine(item, prefabId + ".bin");
				if (File.Exists(text))
				{
					return text;
				}
			}
			return null;
		}

		private static IEnumerable<string> IconDirectories()
		{
			string assemblyDirectory;
			try
			{
				assemblyDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
			}
			catch (Exception)
			{
				assemblyDirectory = null;
			}
			if (!string.IsNullOrEmpty(assemblyDirectory))
			{
				yield return Path.Combine(assemblyDirectory, "AllTheBones", "icons");
			}
			if (!string.IsNullOrEmpty(Paths.PluginPath))
			{
				yield return Path.Combine(Paths.PluginPath, "AllTheBones", "icons");
			}
		}

		private static Texture2D WhiteTexture()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			//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)
			if ((Object)(object)whiteTexture != (Object)null)
			{
				return whiteTexture;
			}
			whiteTexture = new Texture2D(1, 1, (TextureFormat)4, false)
			{
				name = "AllTheBones_White",
				filterMode = (FilterMode)0,
				wrapMode = (TextureWrapMode)1
			};
			whiteTexture.SetPixels32((Color32[])(object)new Color32[1]
			{
				new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue)
			});
			whiteTexture.Apply();
			KeepAlive.Add((Object)(object)whiteTexture);
			return whiteTexture;
		}
	}
}
namespace AllTheBones.Systems
{
	internal static class BoostedPlantTint
	{
		private const float UpdateInterval = 1f;

		private static readonly List<Plant> loaded = new List<Plant>();

		private static readonly Dictionary<Material, Material> tintCache = new Dictionary<Material, Material>();

		private static readonly HashSet<Material> tintedMaterials = new HashSet<Material>();

		private static float nextUpdate;

		public static void Register(Plant plant)
		{
			if ((Object)(object)plant != (Object)null)
			{
				loaded.Add(plant);
			}
		}

		public static void Mark(ZNetView nview)
		{
			Apply(((Object)(object)nview != (Object)null) ? ((Component)nview).GetComponent<Plant>() : null);
		}

		public static void Tick()
		{
			if (Time.realtimeSinceStartup < nextUpdate)
			{
				return;
			}
			nextUpdate = Time.realtimeSinceStartup + 1f;
			for (int num = loaded.Count - 1; num >= 0; num--)
			{
				Plant val = loaded[num];
				if ((Object)(object)val == (Object)null)
				{
					loaded.RemoveAt(num);
				}
				else if (GrowthBoostStore.GetStacks(val.m_nview) > 0)
				{
					Apply(val);
				}
			}
		}

		private static void Apply(Plant plant)
		{
			if ((Object)(object)plant == (Object)null)
			{
				return;
			}
			Renderer[] componentsInChildren = ((Component)plant).GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val.sharedMaterial == (Object)null) && !tintedMaterials.Contains(val.sharedMaterial))
				{
					Material val2 = Tinted(val.sharedMaterial);
					if ((Object)(object)val2 != (Object)null)
					{
						val.sharedMaterial = val2;
					}
				}
			}
		}

		private static Material Tinted(Material source)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: 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_0068: Unknown result type (might be due to invalid IL or missing references)
			if (tintCache.TryGetValue(source, out var value))
			{
				return value;
			}
			Material val = null;
			if (source.HasProperty("_Color"))
			{
				val = new Material(source)
				{
					name = ((Object)source).name + " (boosted)"
				};
				Color color = source.GetColor("_Color");
				val.SetColor("_Color", Color.Lerp(color, Constants.PlantTint, 0.45f));
				tintedMaterials.Add(val);
			}
			tintCache[source] = val;
			return val;
		}
	}
	internal sealed class Counter
	{
		public readonly string Name;

		public long Calls;

		public long Ticks;

		public long WorstTicks;

		public long Flagged;

		public Counter(string name)
		{
			Name = name;
		}

		public void Reset()
		{
			Calls = 0L;
			Ticks = 0L;
			WorstTicks = 0L;
			Flagged = 0L;
		}
	}
	internal static class Diagnostics
	{
		public static bool Enabled;

		public static readonly Counter GetSupport = new Counter("GetSupportPostfix");

		public static readonly Counter UpdateWear = new Counter("UpdateWearPrefix");

		public static readonly Counter ZdoRead = new Counter("TreatmentStoreRead");

		public static readonly Counter GrowTime = new Counter("GetGrowTimePostfix");

		public static readonly Counter UseItem = new Counter("UseItemPrefix");

		public static readonly Counter VanillaUpdateWear = new Counter("vanillaUpdateWear");

		public static readonly Counter VanillaUpdateSupport = new Counter("vanillaUpdateSupport");

		public static readonly Counter VanillaClearCacheRpc = new Counter("vanillaClearCacheRpc");

		private static readonly Counter[] All = new Counter[8] { GetSupport, UpdateWear, ZdoRead, GrowTime, UseItem, VanillaUpdateWear, VanillaUpdateSupport, VanillaClearCacheRpc };

		private static float nextReport;

		private static float nextScaleReport;

		private static int framesOver50;

		private static int framesOver100;

		private static int framesOver200;

		private static float worstFrame;

		private static int lastGc0;

		private static int lastGc1;

		private static int lastGc2;

		public static long Begin()
		{
			return Enabled ? Stopwatch.GetTimestamp() : 0;
		}

		public static void End(Counter counter, long startedAt, bool flagged = false)
		{
			if (startedAt != 0L && counter != null)
			{
				long num = Stopwatch.GetTimestamp() - startedAt;
				counter.Calls++;
				counter.Ticks += num;
				if (num > counter.WorstTicks)
				{
					counter.WorstTicks = num;
				}
				if (flagged)
				{
					counter.Flagged++;
				}
			}
		}

		public static void Count(Counter counter)
		{
			if (Enabled && counter != null)
			{
				counter.Calls++;
			}
		}

		public static void Tick()
		{
			if (Enabled)
			{
				float realtimeSinceStartup = Time.realtimeSinceStartup;
				float unscaledDeltaTime = Time.unscaledDeltaTime;
				if (unscaledDeltaTime > worstFrame)
				{
					worstFrame = unscaledDeltaTime;
				}
				if (unscaledDeltaTime > 0.05f)
				{
					framesOver50++;
				}
				if (unscaledDeltaTime > 0.1f)
				{
					framesOver100++;
				}
				if (unscaledDeltaTime > 0.2f)
				{
					framesOver200++;
				}
				if (realtimeSinceStartup >= nextReport)
				{
					nextReport = realtimeSinceStartup + 1f;
					ReportInterval();
				}
				if (realtimeSinceStartup >= nextScaleReport)
				{
					nextScaleReport = realtimeSinceStartup + 10f;
					ReportScale();
				}
			}
		}

		private static void ReportInterval()
		{
			Counter[] all = All;
			foreach (Counter counter in all)
			{
				if (counter.Calls > 0)
				{
					Logger.LogInfo((object)$"[ATB-DIAG] {counter.Name} calls={counter.Calls} time={Ms(counter.Ticks):0.00}ms worst={Ms(counter.WorstTicks):0.00}ms flagged={counter.Flagged}");
					counter.Reset();
				}
			}
			int num = GC.CollectionCount(0);
			int num2 = GC.CollectionCount(1);
			int num3 = GC.CollectionCount(2);
			Logger.LogInfo((object)$"[ATB-DIAG] frames>50ms={framesOver50} >100ms={framesOver100} >200ms={framesOver200} worstFrame={worstFrame * 1000f:0}ms gc0=+{num - lastGc0} gc1=+{num2 - lastGc1} gc2=+{num3 - lastGc2} managed={GC.GetTotalMemory(forceFullCollection: false) / 1024 / 1024}MB");
			framesOver50 = 0;
			framesOver100 = 0;
			framesOver200 = 0;
			worstFrame = 0f;
			lastGc0 = num;
			lastGc1 = num2;
			lastGc2 = num3;
		}

		private static void ReportScale()
		{
			List<WearNTear> allInstances = WearNTear.GetAllInstances();
			if (allInstances == null)
			{
				return;
			}
			int num = 0;
			foreach (WearNTear item in allInstances)
			{
				if ((Object)(object)item != (Object)null && TreatmentStore.IsTreated(item.m_nview))
				{
					num++;
				}
			}
			Logger.LogInfo((object)$"[ATB-DIAG] scale pieces={allInstances.Count} treated={num}");
		}

		private static double Ms(long ticks)
		{
			return (double)ticks * 1000.0 / (double)Stopwatch.Frequency;
		}
	}
	internal enum GrowthApplyResult
	{
		Applied,
		OtherSource,
		AtMaximum
	}
	internal static class GrowthBoostStore
	{
		public static int GetStacks(ZNetView nview)
		{
			return Read(nview, Constants.GrowthCountHash);
		}

		public static int GetSource(ZNetView nview)
		{
			return Read(nview, Constants.GrowthSourceHash);
		}

		public static bool IsMature(Plant plant)
		{
			return (Object)(object)plant != (Object)null && plant.TimeSincePlanted() >= (double)plant.GetGrowTime();
		}

		public static GrowthApplyResult TryApply(ZNetView nview, int source)
		{
			int stacks = GetStacks(nview);
			int source2 = GetSource(nview);
			if (stacks > 0)
			{
				if (source2 != source)
				{
					return GrowthApplyResult.OtherSource;
				}
				if (source == 2 || stacks >= 5)
				{
					return GrowthApplyResult.AtMaximum;
				}
			}
			nview.ClaimOwnership();
			ZDO zDO = nview.GetZDO();
			zDO.Set(Constants.GrowthSourceHash, source, false);
			zDO.Set(Constants.GrowthCountHash, stacks + 1, false);
			BoostedPlantTint.Mark(nview);
			return GrowthApplyResult.Applied;
		}

		public static float GetGrowTimeMultiplier(ZNetView nview)
		{
			int stacks = GetStacks(nview);
			if (stacks <= 0)
			{
				return 1f;
			}
			float num = ((GetSource(nview) == 2) ? 0.8f : 0.8f);
			return Mathf.Pow(num, (float)stacks);
		}

		private static int Read(ZNetView nview, int hash)
		{
			if ((Object)(object)nview == (Object)null || !nview.IsValid())
			{
				return 0;
			}
			return nview.GetZDO().GetInt(hash, 0);
		}
	}
	internal class MealBagRadiusIndicator : MonoBehaviour
	{
		private const float UpdateInterval = 0.25f;

		private const int Segments = 64;

		private const float HeightAboveGround = 0.06f;

		private static MealBagRadiusIndicator instance;

		private LineRenderer line;

		private float nextUpdate;

		public static void EnsureExists()
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			if (!((Object)(object)instance != (Object)null) && !((Object)(object)Player.m_localPlayer == (Object)null))
			{
				GameObject val = new GameObject("AllTheBones_MealBagRadius");
				Object.DontDestroyOnLoad((Object)(object)val);
				instance = val.AddComponent<MealBagRadiusIndicator>();
				instance.Build();
			}
		}

		private void Build()
		{
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			Material val = CreateMaterial();
			if ((Object)(object)val == (Object)null)
			{
				Logger.LogWarning((object)"No usable shader for the Meal Bag radius ring, skipping it");
				Object.Destroy((Object)(object)((Component)this).gameObject);
				instance = null;
				return;
			}
			line = ((Component)this).gameObject.AddComponent<LineRenderer>();
			line.useWorldSpace = false;
			line.loop = true;
			line.positionCount = 64;
			line.widthMultiplier = 0.05f;
			line.numCapVertices = 0;
			line.numCornerVertices = 0;
			line.alignment = (LineAlignment)0;
			((Renderer)line).shadowCastingMode = (ShadowCastingMode)0;
			((Renderer)line).receiveShadows = false;
			((Renderer)line).material = val;
			line.startColor = val.color;
			line.endColor = val.color;
			for (int i = 0; i < 64; i++)
			{
				float num = (float)i / 64f * (float)Math.PI * 2f;
				line.SetPosition(i, new Vector3(Mathf.Cos(num), Mathf.Sin(num), 0f) * 3f);
			}
			((Component)this).transform.rotation = Quaternion.Euler(90f, 0f, 0f);
			((Component)this).gameObject.SetActive(false);
			Logger.LogInfo((object)"Meal Bag radius ring created");
		}

		private void Update()
		{
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			if (Time.realtimeSinceStartup < nextUpdate)
			{
				return;
			}
			nextUpdate = Time.realtimeSinceStartup + 0.25f;
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead() || !HasMealBagInHotbar(localPlayer))
			{
				if (((Component)this).gameObject.activeSelf)
				{
					((Component)this).gameObject.SetActive(false);
				}
				return;
			}
			Vector3 position = ((Component)localPlayer).transform.position;
			float num = (((Object)(object)ZoneSystem.instance != (Object)null) ? ZoneSystem.instance.GetGroundHeight(position) : position.y);
			((Component)this).transform.position = new Vector3(position.x, num + 0.06f, position.z);
			if (!((Component)this).gameObject.activeSelf)
			{
				((Component)this).gameObject.SetActive(true);
			}
		}

		private static bool HasMealBagInHotbar(Player player)
		{
			Inventory inventory = ((Humanoid)player).GetInventory();
			if (inventory == null)
			{
				return false;
			}
			for (int i = 0; i < 8; i++)
			{
				ItemData itemAt = inventory.GetItemAt(i, 0);
				if (itemAt != null && itemAt.m_shared != null && itemAt.m_shared.m_name == "$item_mealbag")
				{
					return true;
				}
			}
			return false;
		}

		private static Material CreateMaterial()
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Expected O, but got Unknown
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			Color color = default(Color);
			((Color)(ref color))..ctor(1f, 0.97f, 0.9f, 0.4f);
			string[] array = new string[3] { "Sprites/Default", "UI/Default", "Particles/Standard Unlit" };
			string[] array2 = array;
			foreach (string text in array2)
			{
				Shader val = Shader.Find(text);
				if ((Object)(object)val != (Object)null)
				{
					Material val2 = new Material(val);
					val2.color = color;
					return val2;
				}
			}
			Material val3 = FindWardMarkerMaterial();
			if ((Object)(object)val3 != (Object)null)
			{
				Material val4 = new Material(val3);
				val4.color = color;
				return val4;
			}
			return null;
		}

		private static Material FindWardMarkerMaterial()
		{
			GameObject prefab = PrefabManager.Instance.GetPrefab("guard_stone");
			if ((Object)(object)prefab == (Object)null)
			{
				return null;
			}
			Transform val = prefab.transform.Find("marker");
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			ParticleSystemRenderer component = ((Component)val).GetComponent<ParticleSystemRenderer>();
			return ((Object)(object)component != (Object)null) ? ((Renderer)component).sharedMaterial : null;
		}
	}
	internal static class PlantedCrops
	{
		private static HashSet<string> grownPrefabs;

		private static bool scanned;

		public static bool IsGrownCrop(GameObject aimed)
		{
			if ((Object)(object)aimed == (Object)null)
			{
				return false;
			}
			Pickable componentInParent = aimed.GetComponentInParent<Pickable>();
			if ((Object)(object)componentInParent == (Object)null)
			{
				return false;
			}
			return GetGrownPrefabs()?.Contains(((Object)((Component)componentInParent).gameObject).name) ?? false;
		}

		private static HashSet<string> GetGrownPrefabs()
		{
			if (scanned)
			{
				return grownPrefabs;
			}
			ZNetScene instance = ZNetScene.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return null;
			}
			grownPrefabs = new HashSet<string>();
			foreach (GameObject prefab in instance.m_prefabs)
			{
				if ((Object)(object)prefab == (Object)null)
				{
					continue;
				}
				Plant component = prefab.GetComponent<Plant>();
				if ((Object)(object)component == (Object)null || component.m_grownPrefabs == null)
				{
					continue;
				}
				GameObject[] array = component.m_grownPrefabs;
				foreach (GameObject val in array)
				{
					if ((Object)(object)val != (Object)null)
					{
						grownPrefabs.Add(((Object)val).name);
					}
				}
			}
			scanned = true;
			Logger.LogInfo((object)$"Tracked {grownPrefabs.Count} grown plant prefabs");
			return grownPrefabs;
		}
	}
	internal static class TargetResolver
	{
		private const float RayLength = 50f;

		private static readonly RaycastHit[] Hits = (RaycastHit[])(object)new RaycastHit[16];

		private static readonly Collider[] Colliders = (Collider[])(object)new Collider[64];

		public static Plant FindAimedPlant(Player player)
		{
			GameObject hoverObject = ((Humanoid)player).GetHoverObject();
			if ((Object)(object)hoverObject != (Object)null)
			{
				Plant componentInParent = hoverObject.GetComponentInParent<Plant>();
				if ((Object)(object)componentInParent != (Object)null)
				{
					return componentInParent;
				}
			}
			return FindAimed<Plant>(player, player.m_interactMask);
		}

		public static WearNTear FindAimedWearNTear(Player player)
		{
			WearNTear val = FindAimed<WearNTear>(player, player.m_removeRayMask);
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			GameObject hoverObject = ((Humanoid)player).GetHoverObject();
			if ((Object)(object)hoverObject != (Object)null)
			{
				WearNTear componentInParent = hoverObject.GetComponentInParent<WearNTear>();
				if ((Object)(object)componentInParent != (Object)null)
				{
					return componentInParent;
				}
			}
			return FindAimed<WearNTear>(player, player.m_interactMask);
		}

		public static List<Plant> FindPlantsAround(Player player, float radius)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			List<Plant> list = new List<Plant>();
			if ((Object)(object)player == (Object)null)
			{
				return list;
			}
			Vector3 position = ((Component)player).transform.position;
			int num = Physics.OverlapSphereNonAlloc(position, radius, Colliders, -1, (QueryTriggerInteraction)1);
			for (int i = 0; i < num; i++)
			{
				Collider val = Colliders[i];
				if (!((Object)(object)val == (Object)null))
				{
					Plant componentInParent = ((Component)val).GetComponentInParent<Plant>();
					if (!((Object)(object)componentInParent == (Object)null) && !list.Contains(componentInParent) && !(Vector3.Distance(((Component)componentInParent).transform.position, position) > radius))
					{
						list.Add(componentInParent);
					}
				}
			}
			return list;
		}

		public static GameObject FindAimedObject(Player player)
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			GameObject hoverObject = ((Humanoid)player).GetHoverObject();
			if ((Object)(object)hoverObject != (Object)null)
			{
				return hoverObject;
			}
			GameCamera instance = GameCamera.instance;
			if ((Object)(object)player == (Object)null || (Object)(object)instance == (Object)null || (Object)(object)((Character)player).m_eye == (Object)null)
			{
				return null;
			}
			Transform transform = ((Component)instance).transform;
			int num = Physics.RaycastNonAlloc(transform.position, transform.forward, Hits, 50f, -1, (QueryTriggerInteraction)1);
			float num2 = Mathf.Max(player.m_maxInteractDistance, player.m_maxPlaceDistance);
			float num3 = float.MaxValue;
			GameObject result = null;
			for (int i = 0; i < num; i++)
			{
				RaycastHit val = Hits[i];
				if (!((Object)(object)((RaycastHit)(ref val)).collider == (Object)null) && !((Object)(object)((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<Player>() != (Object)null) && !((Object)(object)((Component)((RaycastHit)(ref val)).collider).GetComponent<Heightmap>() != (Object)null) && !(Vector3.Distance(((RaycastHit)(ref val)).point, ((Character)player).m_eye.position) > num2) && !(((RaycastHit)(ref val)).distance >= num3))
				{
					num3 = ((RaycastHit)(ref val)).distance;
					result = ((Component)((RaycastHit)(ref val)).collider).gameObject;
				}
			}
			return result;
		}

		private static T FindAimed<T>(Player player, int mask) where T : Component
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			GameCamera instance = GameCamera.instance;
			if ((Object)(object)player == (Object)null || (Object)(object)instance == (Object)null || (Object)(object)((Character)player).m_eye == (Object)null)
			{
				return default(T);
			}
			Transform transform = ((Component)instance).transform;
			int num = Physics.RaycastNonAlloc(transform.position, transform.forward, Hits, 50f, mask);
			float num2 = Mathf.Max(player.m_maxInteractDistance, player.m_maxPlaceDistance);
			T result = default(T);
			float num3 = float.MaxValue;
			for (int i = 0; i < num; i++)
			{
				RaycastHit val = Hits[i];
				if (!((Object)(object)((RaycastHit)(ref val)).collider == (Object)null) && !(Vector3.Distance(((RaycastHit)(ref val)).point, ((Character)player).m_eye.position) > num2))
				{
					T componentInParent = ((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<T>();
					if (!((Object)(object)componentInParent == (Object)null) && !(((RaycastHit)(ref val)).distance >= num3))
					{
						result = componentInParent;
						num3 = ((RaycastHit)(ref val)).distance;
					}
				}
			}
			return result;
		}
	}
	internal enum TreatmentApplyResult
	{
		Applied,
		AlreadyTreated
	}
	internal static class TreatmentStore
	{
		public static int GetTreatments(ZNetView nview)
		{
			long startedAt = Diagnostics.Begin();
			try
			{
				if ((Object)(object)nview == (Object)null || !nview.IsValid())
				{
					return 0;
				}
				return nview.GetZDO().GetInt(Constants.TreatmentCountHash, 0);
			}
			finally
			{
				Diagnostics.End(Diagnostics.ZdoRead, startedAt);
			}
		}

		public static bool IsTreated(ZNetView nview)
		{
			return GetTreatments(nview) > 0;
		}

		public static bool MatchesGlueMaterial(WearNTear wearNTear)
		{
			return HasMaterial(wearNTear, (MaterialType)0, (MaterialType)3);
		}

		public static bool MatchesCementMaterial(WearNTear wearNTear)
		{
			return HasMaterial(wearNTear, (MaterialType)1, (MaterialType)2);
		}

		public static bool IsTreatableStructure(WearNTear wearNTear)
		{
			if ((Object)(object)wearNTear == (Object)null)
			{
				return false;
			}
			return IsStructure(wearNTear) && !IsStorageOrStation(wearNTear);
		}

		public static TreatmentApplyResult TryApply(ZNetView nview)
		{
			if (IsTreated(nview))
			{
				return TreatmentApplyResult.AlreadyTreated;
			}
			nview.ClaimOwnership();
			nview.GetZDO().Set(Constants.TreatmentCountHash, 1, false);
			return TreatmentApplyResult.Applied;
		}

		public static float GetSupportMultiplier(ZNetView nview, float verticalLoss)
		{
			if (!IsTreated(nview) || verticalLoss >= 1f || verticalLoss < 0f)
			{
				return 1f;
			}
			return 1f / (1f - verticalLoss);
		}

		public static float GetHeightAboveGround(WearNTear wearNTear)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)wearNTear == (Object)null || (Object)(object)ZoneSystem.instance == (Object)null)
			{
				return 0f;
			}
			Vector3 position = ((Component)wearNTear).transform.position;
			return position.y - ZoneSystem.instance.GetGroundHeight(position);
		}

		private static bool HasMaterial(WearNTear wearNTear, MaterialType first, MaterialType second)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)wearNTear == (Object)null)
			{
				return false;
			}
			MaterialType materialType = wearNTear.m_materialType;
			return materialType == first || materialType == second;
		}

		private static bool IsStructure(WearNTear wearNTear)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected I4, but got Unknown
			Piece piece = wearNTear.m_piece;
			if ((Object)(object)piece == (Object)null)
			{
				return true;
			}
			PieceCategory category = piece.m_category;
			PieceCategory val = category;
			switch ((int)val)
			{
			case 0:
			case 1:
			case 4:
			case 6:
			case 7:
			case 8:
				return false;
			default:
				return true;
			}
		}

		private static bool IsStorageOrStation(WearNTear wearNTear)
		{
			return HasComponent<Container>(wearNTear) || HasComponent<CraftingStation>(wearNTear) || HasComponent<StationExtension>(wearNTear) || HasComponent<Smelter>(wearNTear) || HasComponent<Fermenter>(wearNTear) || HasComponent<CookingStation>(wearNTear) || HasComponent<Beehive>(wearNTear) || HasComponent<ItemStand>(wearNTear) || HasComponent<Incinerator>(wearNTear) || HasComponent<Feast>(wearNTear) || HasComponent<TeleportWorld>(wearNTear);
		}

		private static bool HasComponent<T>(WearNTear wearNTear) where T : Component
		{
			return (Object)(object)((Component)wearNTear).GetComponentInParent<T>() != (Object)null || (Object)(object)((Component)wearNTear).GetComponentInChildren<T>(true) != (Object)null;
		}
	}
}
namespace AllTheBones.Patches
{
	[HarmonyPatch(typeof(Plant), "GetGrowTime")]
	internal static class PlantGrowthPatches
	{
		private static void Postfix(Plant __instance, ref float __result)
		{
			long startedAt = Diagnostics.Begin();
			bool flagged = false;
			try
			{
				if (!((Object)(object)__instance == (Object)null))
				{
					float growTimeMultiplier = GrowthBoostStore.GetGrowTimeMultiplier(__instance.m_nview);
					if (growTimeMultiplier < 1f)
					{
						flagged = true;
						__result *= growTimeMultiplier;
					}
				}
			}
			finally
			{
				Diagnostics.End(Diagnostics.GrowTime, startedAt, flagged);
			}
		}
	}
	[HarmonyPatch(typeof(Plant), "Awake")]
	internal static class PlantAwakePatches
	{
		private static void Postfix(Plant __instance)
		{
			BoostedPlantTint.Register(__instance);
		}
	}
	[HarmonyPatch(typeof(WearNTear), "GetSupport")]
	internal static class StabilityBoostPatch
	{
		private static void Postfix(WearNTear __instance, ref float __result)
		{
			long startedAt = Diagnostics.Begin();
			bool flagged = false;
			try
			{
				if (!((Object)(object)__instance == (Object)null) && !((Object)(object)__instance.m_nview == (Object)null) && __instance.m_nview.IsValid() && TreatmentStore.GetTreatments(__instance.m_nview) > 0)
				{
					flagged = true;
					float num = default(float);
					float num2 = default(float);
					float num3 = default(float);
					float verticalLoss = default(float);
					__instance.GetMaterialProperties(ref num, ref num2, ref num3, ref verticalLoss);
					float supportMultiplier = TreatmentStore.GetSupportMultiplier(__instance.m_nview, verticalLoss);
					if (supportMultiplier > 1f)
					{
						__result *= supportMultiplier;
					}
				}
			}
			finally
			{
				Diagnostics.End(Diagnostics.GetSupport, startedAt, flagged);
			}
		}
	}
	[HarmonyPatch(typeof(WearNTear), "UpdateWear")]
	internal static class WeatherImmunityPatch
	{
		private static void Prefix(WearNTear __instance)
		{
			long startedAt = Diagnostics.Begin();
			bool flagged = false;
			try
			{
				if (!((Object)(object)__instance == (Object)null) && __instance.m_noRoofWear && !((Object)(object)__instance.m_nview == (Object)null) && __instance.m_nview.IsValid() && TreatmentStore.GetTreatments(__instance.m_nview) > 0)
				{
					flagged = true;
					__instance.m_noRoofWear = false;
				}
			}
			finally
			{
				Diagnostics.End(Diagnostics.UpdateWear, startedAt, flagged);
			}
		}
	}
	[HarmonyPatch(typeof(Humanoid), "UseItem")]
	internal static class UseItemPatches
	{
		private enum ItemKind
		{
			None,
			BoneMeal,
			MealBag,
			BoneGlue,
			BoneCement
		}

		private static readonly HashSet<ItemKind> HintShown = new HashSet<ItemKind>();

		private static bool Prefix(Humanoid __instance, Inventory inventory, ItemData item, bool fromInventoryGui)
		{
			ItemKind itemKind = GetItemKind(item);
			if (itemKind != ItemKind.None)
			{
				Player val = (Player)(object)((__instance is Player) ? __instance : null);
				if (val != null)
				{
					if (inventory == null)
					{
						inventory = ((Humanoid)val).GetInventory();
					}
					if (inventory == null)
					{
						return false;
					}
					ShowFirstUseHint(val, itemKind);
					long startedAt = Diagnostics.Begin();
					try
					{
						return itemKind switch
						{
							ItemKind.BoneMeal => UseOnPlant(val, inventory, item), 
							ItemKind.MealBag => UseMealBag(val, inventory, item), 
							ItemKind.BoneGlue => UseOnPiece(val, inventory, item, glue: true), 
							ItemKind.BoneCement => UseOnPiece(val, inventory, item, glue: false), 
							_ => true, 
						};
					}
					finally
					{
						Diagnostics.End(Diagnostics.UseItem, startedAt, flagged: true);
					}
				}
			}
			return true;
		}

		private static ItemKind GetItemKind(ItemData item)
		{
			string text = item?.m_shared?.m_name;
			if (text == null)
			{
				return ItemKind.None;
			}
			return text switch
			{
				"$item_bonemeal" => ItemKind.BoneMeal, 
				"$item_mealbag" => ItemKind.MealBag, 
				"$item_boneglue" => ItemKind.BoneGlue, 
				"$item_bonecement" => ItemKind.BoneCement, 
				_ => ItemKind.None, 
			};
		}

		private static bool UseOnPlant(Player player, Inventory inventory, ItemData item)
		{
			Plant val = TargetResolver.FindAimedPlant(player);
			if ((Object)(object)val == (Object)null)
			{
				return RejectWithoutTarget(player, item);
			}
			if (!IsUsable((Component)(object)val, val.m_nview))
			{
				return RejectTarget(player, item, (Component)(object)val);
			}
			if (GrowthBoostStore.IsMature(val))
			{
				ShowMessage(player, "$atb_plant_mature");
				return false;
			}
			switch (GrowthBoostStore.TryApply(val.m_nview, 1))
			{
			case GrowthApplyResult.Applied:
				ShowGrowthApplied(player, val);
				inventory.RemoveOneItem(item);
				return false;
			case GrowthApplyResult.OtherSource:
			case GrowthApplyResult.AtMaximum:
				ShowMessage(player, "$atb_growth_maxed");
				return false;
			default:
				return RejectTarget(player, item, (Component)(object)val);
			}
		}

		private static bool UseMealBag(Player player, Inventory inventory, ItemData item)
		{
			List<Plant> list = TargetResolver.FindPlantsAround(player, 3f);
			if (list.Count == 0)
			{
				ShowMessage(player, "$atb_no_plants_nearby");
				return false;
			}
			int num = 0;
			int num2 = 0;
			foreach (Plant item2 in list)
			{
				if (IsUsable((Component)(object)item2, item2.m_nview))
				{
					if (GrowthBoostStore.IsMature(item2))
					{
						num2++;
					}
					else if (GrowthBoostStore.TryApply(item2.m_nview, 2) == GrowthApplyResult.Applied)
					{
						num++;
					}
				}
			}
			if (num == 0)
			{
				ShowMessage(player, (num2 > 0) ? "$atb_plant_mature" : "$atb_growth_maxed");
				return false;
			}
			ShowBagApplied(player, num);
			inventory.RemoveOneItem(item);
			return false;
		}

		private static bool UseOnPiece(Player player, Inventory inventory, ItemData item, bool glue)
		{
			WearNTear val = TargetResolver.FindAimedWearNTear(player);
			if ((Object)(object)val == (Object)null)
			{
				return RejectWithoutTarget(player, item);
			}
			if (!IsUsable((Component)(object)val, val.m_nview))
			{
				return RejectTarget(player, item, (Component)(object)val);
			}
			if (!(glue ? TreatmentStore.MatchesGlueMaterial(val) : TreatmentStore.MatchesCementMaterial(val)))
			{
				ShowMessage(player, "$atb_wrong_material");
				return false;
			}
			if (!glue)
			{
			}
			if (!TreatmentStore.IsTreatableStructure(val))
			{
				return RejectTarget(player, item, (Component)(object)val);
			}
			if (TreatmentStore.TryApply(val.m_nview) == TreatmentApplyResult.AlreadyTreated)
			{
				ShowMessage(player, "$atb_treat_done");
				return false;
			}
			val.ClearCachedSupport();
			ShowTreatmentApplied(player, val, glue);
			inventory.RemoveOneItem(item);
			return false;
		}

		private static void ShowGrowthApplied(Player player, Plant plant)
		{
			int stacks = GrowthBoostStore.GetStacks(plant.m_nview);
			int num = Mathf.RoundToInt(19.999998f);
			ShowMessage(player, "$atb_growth_applied", num.ToString(), stacks.ToString(), 5.ToString());
		}

		private static void ShowBagApplied(Player player, int plants)
		{
			int num = Mathf.RoundToInt(19.999998f);
			ShowMessage(player, "$atb_bag_applied", plants.ToString(), num.ToString());
		}

		private static void ShowFirstUseHint(Player player, ItemKind kind)
		{
			if (HintShown.Add(kind))
			{
				switch (kind)
				{
				case ItemKind.BoneMeal:
					ShowMessage(player, "$atb_hint_bonemeal");
					break;
				case ItemKind.MealBag:
					ShowMessage(player, "$atb_hint_mealbag");
					break;
				case ItemKind.BoneGlue:
					ShowMessage(player, "$atb_hint_boneglue");
					break;
				case ItemKind.BoneCement:
					ShowMessage(player, "$atb_hint_bonecement");
					break;
				}
			}
		}

		private static void ShowTreatmentApplied(Player player, WearNTear wearNTear, bool glue)
		{
			Logger.LogInfo((object)string.Format("Treated {0} with {1} at {2:0.0} m above ground", ((Object)((Component)wearNTear).gameObject).name, glue ? "Bone Glue" : "Bone Cement", TreatmentStore.GetHeightAboveGround(wearNTear)));
			ShowMessage(player, glue ? "$atb_glue_applied" : "$atb_cement_applied");
		}

		private static bool IsUsable(Component target, ZNetView nview)
		{
			return (Object)(object)target != (Object)null && (Object)(object)nview != (Object)null && nview.IsValid();
		}

		private static bool RejectWithoutTarget(Player player, ItemData item)
		{
			GameObject val = TargetResolver.FindAimedObject(player);
			string text = Localization.instance.Localize(item.m_shared.m_name);
			if ((Object)(object)val == (Object)null)
			{
				ShowMessage(player, "$msg_useonwhat", text);
				return false;
			}
			if (PlantedCrops.IsGrownCrop(val))
			{
				ShowMessage(player, "$atb_plant_mature");
				return false;
			}
			ShowMessage(player, "$msg_cantuseon", text, GetTargetName(val));
			return false;
		}

		private static bool RejectTarget(Player player, ItemData item, Component target)
		{
			ShowMessage(player, "$msg_cantuseon", Localization.instance.Localize(item.m_shared.m_name), GetTargetName(target.gameObject));
			return false;
		}

		private static string GetTargetName(GameObject target)
		{
			if ((Object)(object)target == (Object)null)
			{
				return string.Empty;
			}
			Plant componentInParent = target.GetComponentInParent<Plant>();
			if ((Object)(object)componentInParent != (Object)null && !string.IsNullOrEmpty(componentInParent.m_name))
			{
				return Localization.instance.Localize(componentInParent.m_name);
			}
			WearNTear componentInParent2 = target.GetComponentInParent<WearNTear>();
			if ((Object)(object)componentInParent2 != (Object)null && (Object)(object)componentInParent2.m_piece != (Object)null && !string.IsNullOrEmpty(componentInParent2.m_piece.m_name))
			{
				return Localization.instance.Localize(componentInParent2.m_piece.m_name);
			}
			return ((Object)target).name;
		}

		private static void ShowMessage(Player player, string token, params string[] arguments)
		{
			string text = ((arguments == null || arguments.Length == 0) ? Localization.instance.Localize(token) : Localization.instance.Localize(token, arguments));
			((Character)player).Message((MessageType)1, text, 0, (Sprite)null, false);
		}
	}
	[HarmonyPatch(typeof(WearNTear), "UpdateWear")]
	internal static class UpdateWearProbe
	{
		private static void Prefix(out long __state)
		{
			__state = Diagnostics.Begin();
		}

		private static void Postfix(long __state)
		{
			Diagnostics.End(Diagnostics.VanillaUpdateWear, __state);
		}
	}
	[HarmonyPatch(typeof(WearNTear), "UpdateSupport")]
	internal static class UpdateSupportProbe
	{
		private static void Prefix(out long __state)
		{
			__state = Diagnostics.Begin();
		}

		private static void Postfix(long __state)
		{
			Diagnostics.End(Diagnostics.VanillaUpdateSupport, __state);
		}
	}
	[HarmonyPatch(typeof(WearNTear), "RPC_ClearCachedSupport")]
	internal static class ClearCacheProbe
	{
		private static void Postfix()
		{
			Diagnostics.Count(Diagnostics.VanillaClearCacheRpc);
		}
	}
}
namespace AllTheBones.Items
{
	internal static class BoneCement
	{
		public static void Add()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			//IL_0068: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Expected O, but got Unknown
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Expected O, but got Unknown
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			ItemConfig val = new ItemConfig();
			val.Name = "$item_bonecement";
			val.Description = "$item_bonecement_description";
			val.CraftingStation = CraftingStations.Cauldron;
			val.MinStationLevel = 1;
			val.Amount = 1;
			val.Requirements = (RequirementConfig[])(object)new RequirementConfig[2]
			{
				new RequirementConfig
				{
					Item = "BoneGlue",
					Amount = 1,
					Recover = false
				},
				new RequirementConfig
				{
					Item = "IvoryPowder",
					Amount = 1,
					Recover = false
				}
			};
			ItemConfig val2 = val;
			CustomItem val3 = new CustomItem("BoneCement", "Guck", val2);
			ItemRecolor.Recolor(val3, Constants.CementGray);
			ItemManager.Instance.AddItem(val3);
			Logger.LogInfo((object)"Bone Cement has been added to the game");
		}
	}
	internal static class BoneGlue
	{
		public static void Add()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			//IL_0068: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Expected O, but got Unknown
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Expected O, but got Unknown
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			ItemConfig val = new ItemConfig();
			val.Name = "$item_boneglue";
			val.Description = "$item_boneglue_description";
			val.CraftingStation = CraftingStations.Workbench;
			val.MinStationLevel = 1;
			val.Amount = 1;
			val.Requirements = (RequirementConfig[])(object)new RequirementConfig[2]
			{
				new RequirementConfig
				{
					Item = "Resin",
					Amount = 1,
					Recover = false
				},
				new RequirementConfig
				{
					Item = "BoneMeal",
					Amount = 1,
					Recover = false
				}
			};
			ItemConfig val2 = val;
			CustomItem val3 = new CustomItem("BoneGlue", "Guck", val2);
			ItemRecolor.Recolor(val3, Constants.ChalkWhite);
			ItemManager.Instance.AddItem(val3);
			Logger.LogInfo((object)"Bone Glue has been added to the game");
		}
	}
	internal static class BoneMeal
	{
		public static void Add()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected O, but got Unknown
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			ItemConfig val = new ItemConfig();
			val.Name = "$item_bonemeal";
			val.Description = "$item_bonemeal_description";
			val.CraftingStation = CraftingStations.Cauldron;
			val.MinStationLevel = 1;
			val.Amount = 1;
			val.Requirements = (RequirementConfig[])(object)new RequirementConfig[1]
			{
				new RequirementConfig
				{
					Item = "BoneFragments",
					Amount = 1,
					Recover = false
				}
			};
			ItemConfig val2 = val;
			CustomItem val3 = new CustomItem("BoneMeal", "Blueberries", val2);
			ItemRecolor.Recolor(val3, Constants.BoneWhite);
			SharedData shared = val3.ItemDrop.m_itemData.m_shared;
			shared.m_food = 0f;
			shared.m_foodStamina = 0f;
			shared.m_foodEitr = 0f;
			shared.m_foodBurnTime = 0f;
			shared.m_foodRegen = 0f;
			shared.m_foodEatAnimTime = 0f;
			ItemManager.Instance.AddItem(val3);
			Logger.LogInfo((object)"Bone Meal has been added to the game");
		}
	}
	internal static class IvoryPowder
	{
		public static void Add()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: 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_0067: Expected O, but got Unknown
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Expected O, but got Unknown
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			ItemConfig val = new ItemConfig();
			val.Name = "$item_ivorypowder";
			val.Description = "$item_ivorypowder_description";
			val.CraftingStation = CraftingStations.Cauldron;
			val.MinStationLevel = 2;
			val.Amount = 1;
			val.Requirements = (RequirementConfig[])(object)new RequirementConfig[1]
			{
				new RequirementConfig
				{
					Item = "BoneFragments",
					Amount = 20,
					Recover = false
				}
			};
			ItemConfig val2 = val;
			CustomItem val3 = new CustomItem("IvoryPowder", "SpiceMountains", val2);
			ItemRecolor.Recolor(val3, Constants.BoneWhite);
			ItemManager.Instance.AddItem(val3);
			Logger.LogInfo((object)"Ivory Powder has been added to the game");
		}
	}
	internal static class MealBag
	{
		public static void Add()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: 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_0067: Expected O, but got Unknown
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Expected O, but got Unknown
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			ItemConfig val = new ItemConfig();
			val.Name = "$item_mealbag";
			val.Description = "$item_mealbag_description";
			val.CraftingStation = CraftingStations.Cauldron;
			val.MinStationLevel = 3;
			val.Amount = 1;
			val.Requirements = (RequirementConfig[])(object)new RequirementConfig[1]
			{
				new RequirementConfig
				{
					Item = "BoneFragments",
					Amount = 10,
					Recover = false
				}
			};
			ItemConfig val2 = val;
			CustomItem val3 = new CustomItem("MealBag", "BarleyFlour", val2);
			ItemRecolor.Recolor(val3, Constants.MealBagWarmWhite);
			ItemManager.Instance.AddItem(val3);
			Logger.LogInfo((object)"Meal Bag has been added to the game");
		}
	}
}
namespace AllTheBones.Configuration
{
	internal static class Constants
	{
		public const string BoneMeal = "BoneMeal";

		public const string MealBag = "MealBag";

		public const string BoneGlue = "BoneGlue";

		public const string BoneCement = "BoneCement";

		public const string IvoryPowder = "IvoryPowder";

		public const string BlueberriesPrefab = "Blueberries";

		public const string BarleyFlourPrefab = "BarleyFlour";

		public const string GuckPrefab = "Guck";

		public const string SpiceMountainsPrefab = "SpiceMountains";

		public const string BoneFragments = "BoneFragments";

		public const string Resin = "Resin";

		public const string BoneMealToken = "$item_bonemeal";

		public const string BoneMealDescriptionToken = "$item_bonemeal_description";

		public const string MealBagToken = "$item_mealbag";

		public const string MealBagDescriptionToken = "$item_mealbag_description";

		public const string BoneGlueToken = "$item_boneglue";

		public const string BoneGlueDescriptionToken = "$item_boneglue_description";

		public const string BoneCementToken = "$item_bonecement";

		public const string BoneCementDescriptionToken = "$item_bonecement_description";

		public const string IvoryPowderToken = "$item_ivorypowder";

		public const string IvoryPowderDescriptionToken = "$item_ivorypowder_description";

		public const string UseOnWhatToken = "$msg_useonwhat";

		public const string CantUseOnToken = "$msg_cantuseon";

		public const string PlantMatureToken = "$atb_plant_mature";

		public const string GrowthMaxedToken = "$atb_growth_maxed";

		public const string NoPlantsNearbyToken = "$atb_no_plants_nearby";

		public const string TreatmentDoneToken = "$atb_treat_done";

		public const string BoneMealHintToken = "$atb_hint_bonemeal";

		public const string MealBagHintToken = "$atb_hint_mealbag";

		public const string BoneGlueHintToken = "$atb_hint_boneglue";

		public const string BoneCementHintToken = "$atb_hint_bonecement";

		public const string WrongMaterialToken = "$atb_wrong_material";

		public const string GrowthAppliedToken = "$atb_growth_applied";

		public const string MealBagAppliedToken = "$atb_bag_applied";

		public const string GlueAppliedToken = "$atb_glue_applied";

		public const string CementAppliedToken = "$atb_cement_applied";

		public const string English = "English";

		public const string GrowthCountKey = "AllTheBones_growthCount";

		public const string GrowthSourceKey = "AllTheBones_growthSource";

		public const string TreatmentCountKey = "AllTheBones_treatmentCount";

		public static readonly int GrowthCountHash = StringExtensionMethods.GetStableHashCode("AllTheBones_growthCount");

		public static readonly int GrowthSourceHash = StringExtensionMethods.GetStableHashCode("AllTheBones_growthSource");

		public static readonly int TreatmentCountHash = StringExtensionMethods.GetStableHashCode("AllTheBones_treatmentCount");

		public const int GrowthSourceNone = 0;

		public const int GrowthSourceBoneMeal = 1;

		public const int GrowthSourceMealBag = 2;

		public const float BoneMealGrowthFactor = 0.8f;

		public const int MaxBoneMealStacks = 5;

		public const float MealBagGrowthFactor = 0.8f;

		public const float MealBagRadius = 3f;

		public const float StabilityBoostPerTreatment = 1f;

		public const bool ExcludeStationsForCement = true;

		public const string PlantTintProperty = "_Color";

		public const float PlantTintStrength = 0.45f;

		public static readonly Color PlantTint = new Color(1f, 0.94f, 0.7f);

		public static readonly Color BoneWhite = new Color(0.96f, 0.95f, 0.9f);

		public static readonly Color ChalkWhite = new Color(0.93f, 0.94f, 0.93f);

		public static readonly Color MealBagWarmWhite = new Color(0.9f, 0.87f, 0.78f);

		public static readonly Color CementGray = new Color(0.63f, 0.64f, 0.62f);
	}
	internal static class ModConfig
	{
		public static ConfigEntry<bool> Diagnostics;

		public static ConfigEntry<bool> UseItemPatch;

		public static ConfigEntry<bool> PlantGrowthPatch;

		public static ConfigEntry<bool> StabilityBoostPatch;

		public static ConfigEntry<bool> WeatherImmunityPatch;

		public static void Init(ConfigFile config)
		{
			Diagnostics = ConfigFileExtensions.BindConfig<bool>(config, "Diagnostics", "Enabled", false, "Log per second counters for the mod's patches, frame spikes and GC activity.", false, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			UseItemPatch = ConfigFileExtensions.BindConfig<bool>(config, "Patches", "UseItem", true, "Route using the mod's items (hotbar key or inventory) to plants and building pieces.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			PlantGrowthPatch = ConfigFileExtensions.BindConfig<bool>(config, "Patches", "PlantGrowth", true, "Apply Bone Meal and Meal Bag growth boosts to plants.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			StabilityBoostPatch = ConfigFileExtensions.BindConfig<bool>(config, "Patches", "StabilityBoost", true, "Let treated pieces hand extra support to the structure above them.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
			WeatherImmunityPatch = ConfigFileExtensions.BindConfig<bool>(config, "Patches", "WeatherImmunity", true, "Stop treated pieces from taking rain damage.", true, (int?)null, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
		}
	}
}