Decompiled source of Valharvest v3.4.0

plugins/Valharvest.dll

Decompiled 21 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using SimpleJson;
using Splatform;
using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.Rendering;
using UnityEngine.Serialization;
using Valharvest.Configurations;
using Valharvest.Scripts;
using Valharvest.WorldGen;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Valharvest")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Valharvest")]
[assembly: AssemblyCopyright("Copyright Frenvius 2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")]
[assembly: AssemblyFileVersion("3.4.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("3.4.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
public class CustomBeehive : MonoBehaviour, Hoverable, Interactable
{
	public string m_name = "";

	public GameObject m_hideWhenPicked;

	public Transform m_spawnPoint;

	public float m_secPerUnit = 800f;

	public int m_maxHoney = 3;

	public ItemDrop m_honeyItem;

	public EffectList m_spawnEffect = new EffectList();

	private ZNetView m_nview;

	private void Awake()
	{
		m_nview = ((Component)this).GetComponent<ZNetView>();
		if (m_nview.GetZDO() != null)
		{
			HidePrefab();
			if (m_nview.IsOwner() && m_nview.GetZDO().GetLong("lastTime", 0L) == 0L)
			{
				m_nview.GetZDO().Set("lastTime", ZNet.instance.GetTime().Ticks);
			}
			m_nview.Register("Extract", (Action<long>)RPC_Extract);
			((MonoBehaviour)this).InvokeRepeating("UpdateBees", 0f, 10f);
			((MonoBehaviour)this).InvokeRepeating("HidePrefab", 0f, 5f);
		}
	}

	private void HidePrefab()
	{
		if (Object.op_Implicit((Object)(object)m_hideWhenPicked))
		{
			int honeyLevel = GetHoneyLevel();
			m_hideWhenPicked.SetActive(honeyLevel > 0);
		}
	}

	public string GetHoverText()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		if (!PrivateArea.CheckAccess(((Component)this).transform.position, 0f, false, false))
		{
			return Localization.instance.Localize(m_name + "\n$piece_noaccess");
		}
		int honeyLevel = GetHoneyLevel();
		if (honeyLevel > 0)
		{
			return Localization.instance.Localize(m_name + " ( " + m_honeyItem.m_itemData.m_shared.m_name + " x " + honeyLevel + " )\n[<color=yellow><b>$KEY_Use</b></color>] $water_well_extract");
		}
		return Localization.instance.Localize(m_name + " ( $piece_container_empty )\n[<color=yellow><b>$KEY_Use</b></color>] $water_well_check");
	}

	public string GetHoverName()
	{
		return m_name;
	}

	public float GetHoverOffset()
	{
		return 0f;
	}

	public bool Interact(Humanoid character, bool repeat, bool alt)
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		if (repeat)
		{
			return false;
		}
		if (!PrivateArea.CheckAccess(((Component)this).transform.position, 0f, true, false))
		{
			return true;
		}
		if (GetHoneyLevel() > 0)
		{
			Extract();
		}
		else
		{
			((Character)character).Message((MessageType)2, "$water_well_use", 0, (Sprite)null, false);
		}
		return true;
	}

	public bool UseItem(Humanoid user, ItemData item)
	{
		return false;
	}

	private void Extract()
	{
		m_nview.InvokeRPC("Extract", Array.Empty<object>());
	}

	private void RPC_Extract(long caller)
	{
		//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_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_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)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: 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)
		int honeyLevel = GetHoneyLevel();
		if (honeyLevel > 0)
		{
			if (Object.op_Implicit((Object)(object)m_hideWhenPicked))
			{
				m_hideWhenPicked.SetActive(false);
			}
			m_spawnEffect.Create(m_spawnPoint.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID));
			for (int i = 0; i < honeyLevel; i++)
			{
				Vector2 val = Random.insideUnitCircle * 0.5f;
				Vector3 val2 = m_spawnPoint.position + new Vector3(val.x, 0.25f * (float)i, val.y);
				Object.Instantiate<ItemDrop>(m_honeyItem, val2, Quaternion.identity);
			}
			ResetLevel();
		}
	}

	private float GetTimeSinceLastUpdate()
	{
		DateTime dateTime = new DateTime(m_nview.GetZDO().GetLong("lastTime", ZNet.instance.GetTime().Ticks));
		DateTime time = ZNet.instance.GetTime();
		TimeSpan timeSpan = time - dateTime;
		m_nview.GetZDO().Set("lastTime", time.Ticks);
		double num = timeSpan.TotalSeconds;
		if (num < 0.0)
		{
			num = 0.0;
		}
		return (float)num;
	}

	private void ResetLevel()
	{
		m_nview.GetZDO().Set("level", 0);
	}

	private void IncreseLevel(int i)
	{
		int honeyLevel = GetHoneyLevel();
		honeyLevel += i;
		honeyLevel = Mathf.Clamp(honeyLevel, 0, m_maxHoney);
		m_nview.GetZDO().Set("level", honeyLevel);
	}

	private int GetHoneyLevel()
	{
		return m_nview.GetZDO().GetInt("level", 0);
	}

	private void UpdateBees()
	{
		if (GetHoneyLevel() > 0 && Object.op_Implicit((Object)(object)m_hideWhenPicked))
		{
			m_hideWhenPicked.SetActive(true);
		}
		if (m_nview.IsOwner())
		{
			float timeSinceLastUpdate = GetTimeSinceLastUpdate();
			float num = m_nview.GetZDO().GetFloat("product", 0f);
			num += timeSinceLastUpdate;
			if (num > m_secPerUnit)
			{
				int i = (int)(num / m_secPerUnit);
				IncreseLevel(i);
				num = 0f;
			}
			m_nview.GetZDO().Set("product", num);
		}
	}
}
namespace Valharvest
{
	public static class BoneAppetitCompat
	{
		private static bool? _isInstalled;

		public static bool IsInstalled
		{
			get
			{
				if (!_isInstalled.HasValue)
				{
					_isInstalled = Chainloader.PluginInfos.ContainsKey("com.rockerkitten.boneappetit");
					Logger.LogInfo((object)("BoneAppetit detection: " + (_isInstalled.Value ? "INSTALLED" : "NOT FOUND")));
				}
				return _isInstalled.Value;
			}
		}

		public static string GetEggItem()
		{
			if (!IsInstalled)
			{
				return "vh_egg";
			}
			return "rk_egg";
		}

		public static string GetPorkItem()
		{
			if (!IsInstalled)
			{
				return "RawMeat";
			}
			return "rk_pork";
		}

		public static string GetCookingStation(string stationName, bool useBAStations = true)
		{
			if (IsInstalled && useBAStations)
			{
				return stationName;
			}
			switch (stationName)
			{
			case "rk_prep":
				if (Valharvest.Configurations.Valharvest.UseVanillaPrepTable.Value)
				{
					return "piece_preptable";
				}
				return "piece_prep_table";
			case "rk_griddle":
			case "rk_grill":
				return "piece_cooking_pot";
			default:
				return stationName;
			}
		}

		public static void RemapIngredients(RequirementConfig[] requirements)
		{
			if (IsInstalled || requirements == null)
			{
				return;
			}
			for (int i = 0; i < requirements.Length; i++)
			{
				if (requirements[i].Item == "rk_egg")
				{
					requirements[i].Item = "vh_egg";
				}
				else if (requirements[i].Item == "rk_pork")
				{
					requirements[i].Item = "RawMeat";
				}
			}
		}
	}
	public static class Utils
	{
		private const string Name = "name";

		private const string Food = "food";

		private const string Weight = "weight";

		private const string Variants = "variants";

		private const string FoodRegen = "foodRegen";

		private const string FoodStamina = "foodStamina";

		private const string Description = "description";

		private const string MaxStackSize = "maxStackSize";

		private const string FoodBurnTime = "foodBurnTime";

		private const string ConsumeStatusEffect = "consumeStatusEffect";

		public static readonly int MainTex = Shader.PropertyToID("_MainTex");

		public static readonly int Color = Shader.PropertyToID("_Color");

		private static readonly int Cull = Shader.PropertyToID("_Cull");

		private static readonly int Cutoff = Shader.PropertyToID("_Cutoff");

		private static readonly int Height = Shader.PropertyToID("_Height");

		private static readonly int AddSnow = Shader.PropertyToID("_AddSnow");

		private static readonly int AddRain = Shader.PropertyToID("_AddRain");

		private static readonly int CamCull = Shader.PropertyToID("_CamCull");

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

		private static readonly int SwaySpeed = Shader.PropertyToID("_SwaySpeed");

		private static readonly int MossNormal = Shader.PropertyToID("_MossNormal");

		private static readonly int Glossiness = Shader.PropertyToID("_Glossiness");

		private static readonly int RippleSpeed = Shader.PropertyToID("_RippleSpeed");

		private static readonly int SwayDistance = Shader.PropertyToID("_SwayDistance");

		private static readonly int PushDistance = Shader.PropertyToID("_PushDistance");

		private static readonly int MossTransition = Shader.PropertyToID("_MossTransition");

		private static readonly int RippleDistance = Shader.PropertyToID("_RippleDistance");

		private static readonly int FadeDistanceMin = Shader.PropertyToID("_FadeDistanceMin");

		private static readonly int FadeDistanceMax = Shader.PropertyToID("_FadeDistanceMax");

		private static readonly int RippleDeadzoneMin = Shader.PropertyToID("_RippleDeadzoneMin");

		private static readonly int RippleDeadzoneMax = Shader.PropertyToID("_RippleDeadzoneMax");

		public static void ConfigureMaterial(Material material, Shader shader, JsonObject content, Dictionary<Type, int> typeDict, Dictionary<string, int> getMatItem)
		{
			material.shader = shader;
			foreach (KeyValuePair<string, object> item in content)
			{
				if (!(item.Key == "shader"))
				{
					SetMaterialConfigItems(typeDict, item, material, getMatItem);
				}
			}
		}

		private static void SetMaterialConfigItems(Dictionary<Type, int> typeDict, KeyValuePair<string, object> materialItem, Material material, Dictionary<string, int> getMatItem)
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			switch (typeDict[materialItem.Value.GetType()])
			{
			case 0:
				material.SetFloat(getMatItem[materialItem.Key], float.Parse(materialItem.Value.ToString()));
				break;
			case 1:
			{
				Color val = default(Color);
				ColorUtility.TryParseHtmlString(materialItem.Value.ToString(), ref val);
				material.SetColor(Color, val);
				break;
			}
			case 2:
				material.SetFloat(getMatItem[materialItem.Key], float.Parse(materialItem.Value.ToString()));
				break;
			}
		}

		public static Dictionary<Type, int> GetTypeDict()
		{
			return new Dictionary<Type, int>
			{
				{
					typeof(long),
					0
				},
				{
					typeof(string),
					1
				},
				{
					typeof(double),
					2
				}
			};
		}

		public static Dictionary<string, int> GetMatItem()
		{
			return new Dictionary<string, int>
			{
				{ "glossiness", Glossiness },
				{ "cutoff", Cutoff },
				{ "mossNormal", MossNormal },
				{ "mossTransition", MossTransition },
				{ "addSnow", AddSnow },
				{ "addRain", AddRain },
				{ "height", Height },
				{ "swaySpeed", SwaySpeed },
				{ "metallic", Metallic },
				{ "swayDistance", SwayDistance },
				{ "rippleSpeed", RippleSpeed },
				{ "rippleDistance", RippleDistance },
				{ "rippleDeadzoneMin", RippleDeadzoneMin },
				{ "rippleDeadzoneMax", RippleDeadzoneMax },
				{ "pushDistance", PushDistance },
				{ "camCull", CamCull },
				{ "cull", Cull },
				{ "color", Color },
				{ "fadeDistanceMin", FadeDistanceMin },
				{ "fadeDistanceMax", FadeDistanceMax }
			};
		}

		public static void ChangeItemDrop(CustomItem item, string configObject)
		{
			using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("BoneAppetitBalance.resources");
			if (stream != null)
			{
				JsonObject content = SimpleJson.DeserializeObject<JsonObject>(SimpleJson.DeserializeObject<JsonObject>(new StreamReader(stream).ReadToEnd())[configObject].ToString());
				SharedData shared = item.ItemDrop.m_itemData.m_shared;
				SetItemDropFromContent(content, shared);
			}
		}

		public static void LoadNewFood()
		{
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: 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_00ae: 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)
			//IL_00dc: Expected O, but got Unknown
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Expected O, but got Unknown
			using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("newFoodsConfig.resources");
			if (stream == null)
			{
				return;
			}
			foreach (KeyValuePair<string, object> item in SimpleJson.DeserializeObject<JsonObject>(new StreamReader(stream).ReadToEnd()))
			{
				string key = item.Key;
				JsonObject val = SimpleJson.DeserializeObject<JsonObject>(item.Value.ToString());
				RequirementConfig[] requirements = SimpleJson.DeserializeObject<RequirementConfig[]>(val["requirements"].ToString());
				BoneAppetitCompat.RemapIngredients(requirements);
				CustomItem val2 = null;
				try
				{
					val2 = new CustomItem(Main.modAssets.LoadAsset<GameObject>(key), true, new ItemConfig
					{
						Name = val["name"].ToString(),
						Enabled = true,
						Requirements = requirements,
						CraftingStation = GetCookingStation(val),
						Amount = Convert.ToInt32(val["amount"].ToString())
					});
					ChangeFoodDrop(val2, key);
				}
				catch (Exception ex)
				{
					Logger.LogError((object)("Error while loading " + key + ": " + ex.Message));
				}
				finally
				{
					ItemManager.Instance.AddItem(val2);
				}
			}
			PrefabManager.OnVanillaPrefabsAvailable -= LoadNewFood;
		}

		private static string GetCookingStation(JsonObject foodObject)
		{
			return BoneAppetitCompat.GetCookingStation(foodObject["craftingStation"].ToString(), Valharvest.Configurations.Valharvest.UseBoneAppetitCookingStations.Value);
		}

		public static void LoadBalancedFood()
		{
			if (!BoneAppetitCompat.IsInstalled)
			{
				ItemManager.OnItemsRegisteredFejd -= LoadBalancedFood;
				return;
			}
			using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("BoneAppetitBalance.resources");
			if (stream == null)
			{
				return;
			}
			foreach (KeyValuePair<string, object> item in SimpleJson.DeserializeObject<JsonObject>(new StreamReader(stream).ReadToEnd()))
			{
				string key = item.Key;
				JsonObject val = SimpleJson.DeserializeObject<JsonObject>(item.Value.ToString());
				RequirementConfig[] requirements = SimpleJson.DeserializeObject<RequirementConfig[]>(val["requirements"].ToString());
				BoneAppetitCompat.RemapIngredients(requirements);
				RegisterFood(key, key, Convert.ToInt32(val["amount"].ToString()), GetCookingStation(val), requirements);
			}
			ItemManager.OnItemsRegisteredFejd -= LoadBalancedFood;
		}

		private static void ChangeFoodDrop(CustomItem item, string configObject)
		{
			using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("newFoodsConfig.resources");
			if (stream != null)
			{
				JsonObject content = SimpleJson.DeserializeObject<JsonObject>(SimpleJson.DeserializeObject<JsonObject>(new StreamReader(stream).ReadToEnd())[configObject].ToString());
				SharedData shared = item.ItemDrop.m_itemData.m_shared;
				SetItemDropFromContent(content, shared);
			}
		}

		private static void SetItemDropFromContent(JsonObject content, SharedData itemDrop)
		{
			if (content["name"] != null)
			{
				itemDrop.m_name = content["name"].ToString();
			}
			if (content["description"] != null)
			{
				itemDrop.m_description = content["description"].ToString();
			}
			if (content["weight"] != null)
			{
				itemDrop.m_weight = float.Parse(content["weight"].ToString());
			}
			if (content["maxStackSize"] != null)
			{
				itemDrop.m_maxStackSize = int.Parse(content["maxStackSize"].ToString());
			}
			if (content["variants"] != null)
			{
				itemDrop.m_variants = int.Parse(content["variants"].ToString());
			}
			if (content["food"] != null)
			{
				itemDrop.m_food = float.Parse(content["food"].ToString());
			}
			if (content["foodStamina"] != null)
			{
				itemDrop.m_foodStamina = float.Parse(content["foodStamina"].ToString());
			}
			if (content["foodBurnTime"] != null)
			{
				itemDrop.m_foodBurnTime = float.Parse(content["foodBurnTime"].ToString()) * 60f;
			}
			if (content["foodRegen"] != null)
			{
				itemDrop.m_foodRegen = float.Parse(content["foodRegen"].ToString());
			}
			if (content["consumeStatusEffect"] != null)
			{
				StatusEffect consumeStatusEffect = Main.modAssets.LoadAsset<StatusEffect>(content["consumeStatusEffect"].ToString());
				itemDrop.m_consumeStatusEffect = consumeStatusEffect;
			}
		}

		private static void RegisterFood(string name, string prefab, int amount, string craftingStation, RequirementConfig[] requirements)
		{
			//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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			CustomItem item = ItemManager.Instance.GetItem(prefab);
			ItemManager.Instance.RemoveRecipe("Recipe_" + prefab);
			try
			{
				CustomRecipe val = new CustomRecipe(new RecipeConfig
				{
					Item = prefab,
					Amount = amount,
					CraftingStation = craftingStation,
					Requirements = requirements
				});
				ChangeItemDrop(item, prefab);
				ItemManager.Instance.AddRecipe(val);
			}
			catch (Exception ex)
			{
				Logger.LogError((object)("Error while loading " + name + ": " + ex.Message));
			}
		}

		public static string ReadEmbeddedFile(string embeddedName)
		{
			using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(embeddedName);
			if (stream == null)
			{
				return null;
			}
			return new StreamReader(stream).ReadToEnd();
		}
	}
	[BepInPlugin("com.frenvius.Valharvest", "Valharvest", "3.4.0")]
	[BepInDependency("com.jotunn.jotunn", "2.7.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public class Main : BaseUnityPlugin
	{
		public const string ModGuid = "com.frenvius.Valharvest";

		public const string ModName = "Valharvest";

		public const string Version = "3.4.0";

		public static AssetBundle modAssets;

		public static EffectList loxMilkSfx;

		public static EffectList boneMealVfx;

		public static EffectList troughFillSfx;

		public static Texture2D newEggTexture;

		public static Texture2D pizzaPlateTexture;

		public static Sprite newEggSprite;

		public static Sprite pizzaSprite;

		public static bool IsFarmingModInstalled;

		public static KeyboardShortcut MassPlantShortcut;

		public GameObject greydwarfFab;

		public GameObject trollFab;

		public GameObject goblinFab;

		public GameObject draugrFab;

		public GameObject greydwarfBruteFab;

		public GameObject draugrEliteFab;

		public GameObject seagullFab;

		private Harmony _h;

		public void Awake()
		{
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Expected O, but got Unknown
			CreateConfigValues();
			AssetLoad();
			Loaders.LoadItems();
			Loaders.LoadPieces();
			PrefabManager.OnVanillaPrefabsAvailable += Utils.LoadNewFood;
			PrefabManager.OnVanillaPrefabsAvailable += LoadSounds;
			PrefabManager.OnVanillaPrefabsAvailable += PlantUtils.AddCustomPlantsPrefab;
			if (BoneAppetitCompat.IsInstalled)
			{
				ItemManager.OnItemsRegisteredFejd += Utils.LoadBalancedFood;
				ItemManager.OnItemsRegisteredFejd += LoadBalance;
			}
			ItemManager.OnItemsRegisteredFejd += Loaders.LoadCookingStations;
			PrefabManager.OnVanillaPrefabsAvailable += Plants.AddCustomPlants;
			PrefabManager.OnVanillaPrefabsAvailable += CustomDrops;
			PrefabManager.OnVanillaPrefabsAvailable += CheckIfFarmingModInstalled;
			PrefabManager.OnVanillaPrefabsAvailable += HandlePrefabComponent.ZNetViewAwakePatch;
			PrefabManager.OnPrefabsRegistered += HandlePrefabComponent.PrepTableSmokePatch;
			PrefabManager.OnPrefabsRegistered += HandlePrefabComponent.WoodPieceEffectsPatch;
			PrefabManager.OnPrefabsRegistered += CustomFeed;
			PrefabManager.OnPrefabsRegistered += FeedingTrough.CollectFeedItems;
			PrefabManager.OnPrefabsRegistered += PrepTableRecipeCopier.CopyVanillaPrepTableRecipes;
			CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new ExportItemsCommand());
			if (Valharvest.Configurations.Valharvest.DropEnabled.Value)
			{
				PrefabManager.OnVanillaPrefabsAvailable += NewDrops;
			}
			_h = new Harmony("mod.valharvest");
			_h.PatchAll();
		}

		private void OnDestroy()
		{
			Logger.LogInfo((object)"Valharvest: OnDestroy");
			_h.UnpatchSelf();
		}

		private static void CheckIfFarmingModInstalled()
		{
			//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_00cf: 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_00db: Unknown result type (might be due to invalid IL or missing references)
			Chainloader.Start();
			using (IEnumerator<KeyValuePair<string, PluginInfo>> enumerator = Chainloader.PluginInfos.Where((KeyValuePair<string, PluginInfo> plugin) => plugin.Value.Metadata.GUID == "org.bepinex.plugins.farming").GetEnumerator())
			{
				if (enumerator.MoveNext())
				{
					_ = enumerator.Current;
					IsFarmingModInstalled = true;
				}
			}
			if (IsFarmingModInstalled)
			{
				ConfigFile config = Chainloader.PluginInfos["org.bepinex.plugins.farming"].Instance.Config;
				foreach (ConfigDefinition key in config.Keys)
				{
					if (((object)key).ToString().Contains("Toggle Mass Plant"))
					{
						ConfigEntryBase val = config[key];
						KeyCode val2 = (KeyCode)Enum.Parse(typeof(KeyCode), val.BoxedValue.ToString());
						MassPlantShortcut = new KeyboardShortcut(val2, Array.Empty<KeyCode>());
					}
				}
			}
			PrefabManager.OnVanillaPrefabsAvailable -= CheckIfFarmingModInstalled;
		}

		public void CreateConfigValues()
		{
			((BaseUnityPlugin)this).Config.SaveOnConfigSet = true;
			new Valharvest.Configurations.Valharvest(((BaseUnityPlugin)this).Config);
		}

		public void LoadBalance()
		{
			if (!BoneAppetitCompat.IsInstalled)
			{
				ItemManager.OnItemsRegistered -= LoadBalance;
				return;
			}
			try
			{
				BoneAppetitBalance.SeagullEgg();
				BoneAppetitBalance.Kabob();
				BoneAppetitBalance.Pizza();
			}
			catch (Exception ex)
			{
				Logger.LogError((object)("Error while running OnItemsRegistered: " + ex.Message));
			}
			finally
			{
				Logger.LogInfo((object)"Load Complete.");
				ItemManager.OnItemsRegistered -= LoadBalance;
			}
		}

		public void AssetLoad()
		{
			modAssets = AssetUtils.LoadAssetBundleFromResources("valharvest", Assembly.GetExecutingAssembly());
			newEggTexture = modAssets.LoadAsset<Texture2D>("egg");
			newEggSprite = modAssets.LoadAsset<Sprite>("eggsprite");
			pizzaPlateTexture = modAssets.LoadAsset<Texture2D>("pizza_plate");
			pizzaSprite = modAssets.LoadAsset<Sprite>("pizzaSprite");
			Logger.LogInfo((object)"Preparing the plants...");
		}

		public void LoadSounds()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected O, but got Unknown
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Expected O, but got Unknown
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Expected O, but got Unknown
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Expected O, but got Unknown
			//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_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Expected O, but got Unknown
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Expected O, but got Unknown
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Expected O, but got Unknown
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Expected O, but got Unknown
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Expected O, but got Unknown
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Expected O, but got Unknown
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Expected O, but got Unknown
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Expected O, but got Unknown
			RouteCustomAudioToSfxMixer();
			GameObject val = modAssets.LoadAsset<GameObject>("sfx_pours_milk");
			PrefabManager.Instance.AddPrefab(new CustomPrefab(val, true));
			GameObject val2 = modAssets.LoadAsset<GameObject>("sfx_lox_pet_milk");
			PrefabManager.Instance.AddPrefab(new CustomPrefab(val2, true));
			GameObject val3 = modAssets.LoadAsset<GameObject>("sfx_lox_pet");
			PrefabManager.Instance.AddPrefab(new CustomPrefab(val3, true));
			GameObject val4 = modAssets.LoadAsset<GameObject>("vfx_bone_meal");
			PrefabManager.Instance.AddPrefab(new CustomPrefab(val4, true));
			GameObject val5 = modAssets.LoadAsset<GameObject>("sfx_vh_trough_fill");
			PrefabManager.Instance.AddPrefab(new CustomPrefab(val5, true));
			EffectList val6 = new EffectList();
			val6.m_effectPrefabs = (EffectData[])(object)new EffectData[2]
			{
				new EffectData
				{
					m_prefab = val2,
					m_enabled = true
				},
				new EffectData
				{
					m_prefab = val,
					m_enabled = true
				}
			};
			loxMilkSfx = val6;
			val6 = new EffectList();
			val6.m_effectPrefabs = (EffectData[])(object)new EffectData[1]
			{
				new EffectData
				{
					m_prefab = val5,
					m_enabled = true
				}
			};
			troughFillSfx = val6;
			val6 = new EffectList();
			val6.m_effectPrefabs = (EffectData[])(object)new EffectData[1]
			{
				new EffectData
				{
					m_prefab = val4,
					m_enabled = true
				}
			};
			boneMealVfx = val6;
			PrefabManager.OnVanillaPrefabsAvailable -= LoadSounds;
			CookingConversionConfig val7 = new CookingConversionConfig
			{
				FromItem = "apple",
				ToItem = "baked_apple",
				CookTime = 5f,
				Station = "piece_cookingstation"
			};
			ItemManager.Instance.AddItemConversion(new CustomItemConversion((ConversionConfig)(object)val7));
		}

		private static void RouteCustomAudioToSfxMixer()
		{
			GameObject prefab = PrefabManager.Instance.GetPrefab("sfx_cooking_station_take");
			object obj;
			if (prefab == null)
			{
				obj = null;
			}
			else
			{
				AudioSource componentInChildren = prefab.GetComponentInChildren<AudioSource>(true);
				obj = ((componentInChildren != null) ? componentInChildren.outputAudioMixerGroup : null);
			}
			AudioMixerGroup val = (AudioMixerGroup)obj;
			if ((Object)(object)val == (Object)null)
			{
				Logger.LogWarning((object)"Could not find the game's SFX audio mixer group");
				return;
			}
			GameObject[] array = modAssets.LoadAllAssets<GameObject>();
			for (int i = 0; i < array.Length; i++)
			{
				AudioSource[] componentsInChildren = array[i].GetComponentsInChildren<AudioSource>(true);
				for (int j = 0; j < componentsInChildren.Length; j++)
				{
					componentsInChildren[j].outputAudioMixerGroup = val;
				}
			}
		}

		public void NewDrops()
		{
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: 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_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Expected O, but got Unknown
			//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_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: 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)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Expected O, but got Unknown
			//IL_0180: 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_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Expected O, but got Unknown
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: 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_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Expected O, but got Unknown
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: 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)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Expected O, but got Unknown
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_027f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0286: Unknown result type (might be due to invalid IL or missing references)
			//IL_0292: Expected O, but got Unknown
			greydwarfFab = PrefabManager.Instance.GetPrefab("Greydwarf");
			trollFab = PrefabManager.Instance.GetPrefab("Troll");
			goblinFab = PrefabManager.Instance.GetPrefab("Goblin");
			draugrFab = PrefabManager.Instance.GetPrefab("Draugr");
			greydwarfBruteFab = PrefabManager.Instance.GetPrefab("Greydwarf_Elite");
			draugrEliteFab = PrefabManager.Instance.GetPrefab("Draugr_Elite");
			GameObject prefab = PrefabManager.Instance.GetPrefab("pepper");
			GameObject prefab2 = PrefabManager.Instance.GetPrefab("tomato");
			GameObject prefab3 = PrefabManager.Instance.GetPrefab("garlic");
			GameObject prefab4 = PrefabManager.Instance.GetPrefab("rice");
			GameObject prefab5 = PrefabManager.Instance.GetPrefab("potato");
			GameObject prefab6 = PrefabManager.Instance.GetPrefab("pumpkin");
			greydwarfFab.GetComponent<CharacterDrop>().m_drops.Add(new Drop
			{
				m_prefab = prefab,
				m_amountMin = 1,
				m_amountMax = 2,
				m_chance = 0.4f,
				m_levelMultiplier = true,
				m_onePerPlayer = false
			});
			trollFab.GetComponent<CharacterDrop>().m_drops.Add(new Drop
			{
				m_prefab = prefab3,
				m_amountMin = 1,
				m_amountMax = 3,
				m_chance = 0.4f,
				m_levelMultiplier = true,
				m_onePerPlayer = false
			});
			goblinFab.GetComponent<CharacterDrop>().m_drops.Add(new Drop
			{
				m_prefab = prefab4,
				m_amountMin = 1,
				m_amountMax = 1,
				m_chance = 0.4f,
				m_levelMultiplier = true,
				m_onePerPlayer = false
			});
			draugrFab.GetComponent<CharacterDrop>().m_drops.Add(new Drop
			{
				m_prefab = prefab2,
				m_amountMin = 1,
				m_amountMax = 1,
				m_chance = 0.4f,
				m_levelMultiplier = true,
				m_onePerPlayer = false
			});
			greydwarfBruteFab.GetComponent<CharacterDrop>().m_drops.Add(new Drop
			{
				m_prefab = prefab5,
				m_amountMin = 1,
				m_amountMax = 1,
				m_chance = 0.4f,
				m_levelMultiplier = true,
				m_onePerPlayer = false
			});
			draugrEliteFab.GetComponent<CharacterDrop>().m_drops.Add(new Drop
			{
				m_prefab = prefab6,
				m_amountMin = 1,
				m_amountMax = 1,
				m_chance = 0.4f,
				m_levelMultiplier = true,
				m_onePerPlayer = false
			});
			PrefabManager.OnVanillaPrefabsAvailable -= NewDrops;
		}

		public void CustomDrops()
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			if (!BoneAppetitCompat.IsInstalled)
			{
				try
				{
					GameObject prefab = PrefabManager.Instance.GetPrefab("Seagal");
					if ((Object)(object)prefab != (Object)null)
					{
						GameObject prefab2 = PrefabManager.Instance.GetPrefab(BoneAppetitCompat.GetEggItem());
						if ((Object)(object)prefab2 != (Object)null)
						{
							DropOnDestroyed component = prefab.GetComponent<DropOnDestroyed>();
							if ((Object)(object)component != (Object)null)
							{
								component.m_dropWhenDestroyed.m_drops.Add(new DropData
								{
									m_item = prefab2,
									m_stackMin = 1,
									m_stackMax = 2,
									m_weight = 0.75f
								});
								Logger.LogInfo((object)"Added vh_egg drop to seagulls (BoneAppetit not installed)");
							}
						}
					}
				}
				catch (Exception ex)
				{
					Logger.LogWarning((object)("Failed to add egg drops to seagulls: " + ex.Message));
				}
			}
			PrefabManager.OnVanillaPrefabsAvailable -= CustomDrops;
		}

		public static void AddConsumableItemsToCreature(string creature, params string[] items)
		{
			GameObject prefab = PrefabManager.Instance.GetPrefab(creature);
			MonsterAI val = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<MonsterAI>() : null);
			if (val?.m_consumeItems == null)
			{
				Logger.LogWarning((object)("Feed: creature " + creature + " not found, skipping"));
				return;
			}
			foreach (string text in items)
			{
				GameObject prefab2 = PrefabManager.Instance.GetPrefab(text);
				ItemDrop val2 = (((Object)(object)prefab2 != (Object)null) ? prefab2.GetComponent<ItemDrop>() : null);
				if ((Object)(object)val2 == (Object)null)
				{
					Logger.LogWarning((object)("Feed: item " + text + " not found, skipping"));
					continue;
				}
				string name = val2.m_itemData.m_shared.m_name;
				if (!val.m_consumeItems.Exists((ItemDrop fed) => (Object)(object)fed != (Object)null && fed.m_itemData.m_shared.m_name == name))
				{
					val.m_consumeItems.Add(val2);
				}
			}
		}

		public void CustomFeed()
		{
			AddConsumableItemsToCreature("Boar", "apple", "tomato", "potato", "pumpkin", "corn", "garlic");
			AddConsumableItemsToCreature("Hen", "rice", "corn", "CornSeeds", "PepperSeeds", "PumpkinSeeds", "AppleSeeds");
			AddConsumableItemsToCreature("Lox", "pumpkin", "corn", "rice");
			AddConsumableItemsToCreature("Wolf", "raw_seagull", BoneAppetitCompat.GetPorkItem());
			PrefabManager.OnPrefabsRegistered -= CustomFeed;
		}
	}
}
namespace Valharvest.WorldGen
{
	public static class Plants
	{
		private const string Min = "min";

		private const string Max = "max";

		private const string Biome = "biome";

		private const string InForest = "inForest";

		private const string BiomeArea = "biomeArea";

		private const string GroupRadius = "groupRadius";

		private const string GroupSizeMin = "groupSizeMin";

		private const string GroupSizeMax = "groupSizeMax";

		private const string MinAltitude = "minAltitude";

		private const string MaxAltitude = "maxAltitude";

		private const string ForestThresholdMin = "forestThresholdMin";

		private const string ForestThresholdMax = "forestThresholdMax";

		private const Biome Swamp = (Biome)2;

		private const Biome Plains = (Biome)16;

		private const Biome Meadows = (Biome)1;

		private const Biome Mountain = (Biome)4;

		private const Biome Mistlands = (Biome)512;

		private const Biome BlackForest = (Biome)8;

		private const BiomeArea Edge = (BiomeArea)1;

		private const BiomeArea Median = (BiomeArea)2;

		private const BiomeArea Everything = (BiomeArea)3;

		public static void AddCustomPlants()
		{
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Expected O, but got Unknown
			string text = Utils.ReadEmbeddedFile("plantsLocations.resources");
			if (text == null)
			{
				return;
			}
			JsonObject val = SimpleJson.DeserializeObject<JsonObject>(text);
			try
			{
				foreach (KeyValuePair<string, object> item in val)
				{
					JsonObject content = SimpleJson.DeserializeObject<JsonObject>(item.Value.ToString());
					try
					{
						GameObject val2 = PrefabManager.Instance.CreateClonedPrefab(item.Key + "_wild", item.Key);
						if ((Object)(object)val2 == (Object)null)
						{
							Logger.LogError((object)("Plant prefab not found: " + item.Key));
						}
						else
						{
							ZoneManager.Instance.AddCustomVegetation(new CustomVegetation(val2, true, GetVegetationConfig(content)));
						}
					}
					catch (Exception ex)
					{
						Logger.LogError((object)("Error while loading " + item.Key + ": " + ex.Message));
					}
				}
			}
			finally
			{
				PrefabManager.OnVanillaPrefabsAvailable -= AddCustomPlants;
			}
		}

		private static VegetationConfig GetVegetationConfig(JsonObject content)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			VegetationConfig val = new VegetationConfig();
			Dictionary<string, Biome> biome = GetBiome();
			Dictionary<string, BiomeArea> biomeArea = GetBiomeArea();
			if (content["min"] != null)
			{
				val.Min = float.Parse(content["min"].ToString());
			}
			if (content["max"] != null)
			{
				val.Max = float.Parse(content["max"].ToString());
			}
			if (content["groupSizeMin"] != null)
			{
				val.GroupSizeMin = int.Parse(content["groupSizeMin"].ToString());
			}
			if (content["groupSizeMax"] != null)
			{
				val.GroupSizeMax = int.Parse(content["groupSizeMax"].ToString());
			}
			if (content["groupRadius"] != null)
			{
				val.GroupRadius = float.Parse(content["groupRadius"].ToString());
			}
			if (content["minAltitude"] != null)
			{
				val.MinAltitude = float.Parse(content["minAltitude"].ToString());
			}
			if (content["maxAltitude"] != null)
			{
				val.MaxAltitude = float.Parse(content["maxAltitude"].ToString());
			}
			if (content["biome"] != null)
			{
				val.Biome = biome[content["biome"].ToString()];
			}
			if (content["biomeArea"] != null)
			{
				val.BiomeArea = biomeArea[content["biomeArea"].ToString()];
			}
			if (content["inForest"] != null)
			{
				val.InForest = Convert.ToBoolean(content["inForest"].ToString());
			}
			if (content["forestThresholdMin"] != null)
			{
				val.ForestThresholdMin = float.Parse(content["forestThresholdMin"].ToString());
			}
			if (content["forestThresholdMax"] != null)
			{
				val.ForestThresholdMax = float.Parse(content["forestThresholdMax"].ToString());
			}
			return val;
		}

		private static Dictionary<string, Biome> GetBiome()
		{
			return new Dictionary<string, Biome>
			{
				{
					"swamp",
					(Biome)2
				},
				{
					"plains",
					(Biome)16
				},
				{
					"meadows",
					(Biome)1
				},
				{
					"mountain",
					(Biome)4
				},
				{
					"mistlands",
					(Biome)512
				},
				{
					"black_forest",
					(Biome)8
				}
			};
		}

		private static Dictionary<string, BiomeArea> GetBiomeArea()
		{
			return new Dictionary<string, BiomeArea>
			{
				{
					"edge",
					(BiomeArea)1
				},
				{
					"median",
					(BiomeArea)2
				},
				{
					"everything",
					(BiomeArea)3
				}
			};
		}
	}
	public static class PlantUtils
	{
		public static void AddCustomPlantsPrefab()
		{
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Expected O, but got Unknown
			string text = Utils.ReadEmbeddedFile("plants.resources");
			if (text == null)
			{
				return;
			}
			JsonObject val = SimpleJson.DeserializeObject<JsonObject>(text);
			try
			{
				foreach (KeyValuePair<string, object> item in val)
				{
					Dictionary<string, AssetBundle> assetBundle = Loaders.GetAssetBundle();
					JsonObject val2 = SimpleJson.DeserializeObject<JsonObject>(item.Value.ToString());
					string text2 = val2["assetBundle"].ToString();
					object obj = val2["dropConfig"];
					object obj2 = val2["respawnConfig"];
					Dictionary<string, ConfigEntry<int>> dropConfigs = Valharvest.Configurations.Valharvest.GetDropConfigs();
					Dictionary<string, ConfigEntry<int>> respawnTimeConfigs = Valharvest.Configurations.Valharvest.GetRespawnTimeConfigs();
					GameObject val3 = assetBundle[text2].LoadAsset<GameObject>(item.Key);
					if ((Object)(object)val3 == (Object)null)
					{
						Logger.LogError((object)("Plant prefab not found in " + text2 + ": " + item.Key));
						continue;
					}
					try
					{
						LoadPlantMaterials(val3, val2);
						if (obj != null)
						{
							ConfigEntry<int> val4 = dropConfigs[obj.ToString()];
							val3.GetComponent<Pickable>().m_amount = val4.Value;
						}
						if (obj2 != null)
						{
							ConfigEntry<int> val5 = respawnTimeConfigs[obj2.ToString()];
							val3.GetComponent<Pickable>().m_respawnTimeMinutes = val5.Value * 60;
						}
						if (val2["crafting"] != null)
						{
							CustomPiece val6 = Loaders.CreatePieceRecipe(val3, val2);
							PieceManager.Instance.AddPiece(val6);
						}
						else
						{
							PrefabManager.Instance.AddPrefab(new CustomPrefab(val3, true));
						}
					}
					catch (Exception ex)
					{
						Logger.LogError((object)("Error while loading " + item.Key + ": " + ex.Message));
					}
				}
			}
			finally
			{
				PrefabManager.OnVanillaPrefabsAvailable -= AddCustomPlantsPrefab;
			}
		}

		private static void LoadPlantMaterials(GameObject plantPrefab, JsonObject plantObject)
		{
			JsonObject val = SimpleJson.DeserializeObject<JsonObject>(plantObject["materials"].ToString());
			foreach (Renderer renderer in ShaderHelper.GetRenderers(plantPrefab))
			{
				Material[] sharedMaterials = renderer.sharedMaterials;
				foreach (Material val2 in sharedMaterials)
				{
					if (!((Object)(object)val2 == (Object)null))
					{
						string name = ((Object)val2).name;
						if (val.ContainsKey(name) && !string.IsNullOrEmpty(val[name].ToString()))
						{
							Dictionary<Type, int> typeDict = Utils.GetTypeDict();
							Dictionary<string, int> matItem = Utils.GetMatItem();
							JsonObject val3 = SimpleJson.DeserializeObject<JsonObject>(val[name].ToString());
							Shader prefab = Cache.GetPrefab<Shader>(val3["shader"].ToString());
							Texture mainTexture = val2.mainTexture;
							Utils.ConfigureMaterial(val2, prefab, val3, typeDict, matItem);
							val2.SetTexture(Utils.MainTex, mainTexture);
						}
					}
				}
			}
		}
	}
}
namespace Valharvest.Scripts
{
	public static class BoneAppetitBalance
	{
		public static void SeagullEgg()
		{
			try
			{
				foreach (Material item in from rend in ShaderHelper.GetRenderers(PrefabManager.Instance.GetPrefab("rk_egg"))
					from mat in rend.materials
					where mat.HasProperty("_MainTex")
					select mat)
				{
					item.SetTexture(Utils.MainTex, (Texture)(object)Main.newEggTexture);
				}
				ItemDrop itemDrop = ItemManager.Instance.GetItem("rk_egg").ItemDrop;
				itemDrop.m_itemData.m_shared.m_description = "A small egg.";
				itemDrop.m_itemData.m_shared.m_icons[0] = Main.newEggSprite;
			}
			catch (Exception ex)
			{
				Logger.LogError((object)("Error while loading SeagullEgg: " + ex.Message));
			}
			finally
			{
				Logger.LogInfo((object)"SeagullEgg Loaded.");
			}
		}

		public static void Kabob()
		{
			CustomItem item = ItemManager.Instance.GetItem("rk_kabob");
			if (Valharvest.Configurations.Valharvest.KabobName.Value)
			{
				item.ItemDrop.m_itemData.m_shared.m_name = "Kebab";
			}
		}

		public static void Pizza()
		{
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			CustomItem item = ItemManager.Instance.GetItem("rk_pizza");
			Color val = default(Color);
			Color val2 = default(Color);
			foreach (Renderer renderer in ShaderHelper.GetRenderers(PrefabManager.Instance.GetPrefab("rk_pizza")))
			{
				string name = ((Object)renderer).name;
				if (!(name == "pizza"))
				{
					if (name == "Tarelka001")
					{
						Material[] materials = renderer.materials;
						foreach (Material obj in materials)
						{
							ColorUtility.TryParseHtmlString("#855B41", ref val);
							obj.SetTexture(Utils.MainTex, (Texture)(object)Main.pizzaPlateTexture);
							obj.SetColor(Utils.Color, val);
						}
					}
				}
				else
				{
					Material[] materials = renderer.materials;
					foreach (Material obj2 in materials)
					{
						ColorUtility.TryParseHtmlString("#FFFFFF", ref val2);
						obj2.SetColor(Utils.Color, val2);
					}
				}
			}
			item.ItemDrop.m_itemData.m_shared.m_icons[0] = Main.pizzaSprite;
		}
	}
	[HarmonyPatch]
	public static class BoneAppetitNotice
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static PopupButtonCallback <0>__OnOk;
		}

		private const float MaxWaitSeconds = 10f;

		private const float PollInterval = 0.2f;

		private static bool _shownThisSession;

		[HarmonyPostfix]
		[HarmonyPatch(typeof(FejdStartup), "Awake")]
		public static void FejdStartupAwakePostfix(FejdStartup __instance)
		{
			if (!_shownThisSession && BoneAppetitCompat.IsInstalled && !Valharvest.Configurations.Valharvest.UseBoneAppetitCookingStations.Value && !Valharvest.Configurations.Valharvest.BoneAppetitNoticeShown.Value)
			{
				_shownThisSession = true;
				((MonoBehaviour)__instance).StartCoroutine(ShowWhenAvailable());
			}
		}

		private static IEnumerator ShowWhenAvailable()
		{
			float elapsed = 0f;
			while (!UnifiedPopup.IsAvailable() && elapsed < 10f)
			{
				yield return (object)new WaitForSeconds(0.2f);
				elapsed += 0.2f;
			}
			if (UnifiedPopup.IsAvailable())
			{
				while (UnifiedPopup.IsVisible())
				{
					yield return null;
				}
				object obj = <>O.<0>__OnOk;
				if (obj == null)
				{
					PopupButtonCallback val = OnOk;
					<>O.<0>__OnOk = val;
					obj = (object)val;
				}
				UnifiedPopup.Push((PopupBase)new WarningPopup("$valharvest_ba_notice_title", "$valharvest_ba_notice_body", (PopupButtonCallback)obj, true));
			}
		}

		private static void OnOk()
		{
			Valharvest.Configurations.Valharvest.BoneAppetitNoticeShown.Value = true;
			UnifiedPopup.Pop();
		}
	}
	public static class ConsumableItemExtractor
	{
		private static HashSet<string> GetValharvestPrefabNames()
		{
			//IL_0015: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
			HashSet<string> hashSet = new HashSet<string>();
			try
			{
				foreach (string key in ((JsonObject)SimpleJson.DeserializeObject(Utils.ReadEmbeddedFile("items.resources"))).Keys)
				{
					hashSet.Add(key);
				}
			}
			catch
			{
			}
			try
			{
				foreach (string key2 in ((JsonObject)SimpleJson.DeserializeObject(Utils.ReadEmbeddedFile("newFoodsConfig.resources"))).Keys)
				{
					hashSet.Add(key2);
				}
			}
			catch
			{
			}
			try
			{
				foreach (string key3 in ((JsonObject)SimpleJson.DeserializeObject(Utils.ReadEmbeddedFile("plants.resources"))).Keys)
				{
					hashSet.Add(key3);
				}
			}
			catch
			{
			}
			return hashSet;
		}

		public static void GenerateConsumableItemList()
		{
			Logger.LogInfo((object)"Starting item extraction...");
			if (!Object.op_Implicit((Object)(object)ObjectDB.instance))
			{
				Logger.LogError((object)"ObjectDB not available. Make sure you're in-game.");
				return;
			}
			JsonArray val = ExtractAllItems();
			File.WriteAllText("itemdrops.json", ((object)val).ToString());
			Logger.LogInfo((object)$"Wrote itemdrops.json with {((List<object>)(object)val).Count} items");
			JsonArray val2 = ExtractAllRecipes();
			File.WriteAllText("recipes.json", ((object)val2).ToString());
			Logger.LogInfo((object)$"Wrote recipes.json with {((List<object>)(object)val2).Count} recipes");
			Logger.LogInfo((object)"Item extraction complete!");
		}

		private static JsonArray ExtractAllItems()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: 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_00db: Expected O, but got Unknown
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Expected O, but got Unknown
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Expected I4, but got Unknown
			//IL_0661: Unknown result type (might be due to invalid IL or missing references)
			//IL_0679: Unknown result type (might be due to invalid IL or missing references)
			JsonArray val = new JsonArray();
			HashSet<string> hashSet = new HashSet<string>();
			HashSet<string> valharvestPrefabNames = GetValharvestPrefabNames();
			string text = "icons";
			if (!Directory.Exists(text))
			{
				Directory.CreateDirectory(text);
			}
			int num = 0;
			foreach (ItemType value in Enum.GetValues(typeof(ItemType)))
			{
				foreach (ItemDrop allItem in ObjectDB.instance.GetAllItems(value, ""))
				{
					if ((Object)(object)allItem == (Object)null || allItem.m_itemData == null || allItem.m_itemData.m_shared == null)
					{
						continue;
					}
					string name = ((Object)((Component)allItem).gameObject).name;
					if (hashSet.Contains(name) || valharvestPrefabNames.Contains(name))
					{
						continue;
					}
					hashSet.Add(name);
					JsonObject val3 = new JsonObject();
					SharedData shared = allItem.m_itemData.m_shared;
					val3.Add("var_name", (object)(shared.m_name ?? ""));
					val3.Add("raw_name", (object)Localization.instance.Localize(shared.m_name ?? ""));
					val3.Add("true_name", (object)name);
					JsonObject val4 = new JsonObject();
					val4.Add("raw_name", (object)Localization.instance.Localize(shared.m_name ?? ""));
					val4.Add("var_name", (object)(shared.m_name ?? ""));
					val4.Add("item_type_name", (object)((object)Unsafe.As<ItemType, ItemType>(ref shared.m_itemType)/*cast due to .constrained prefix*/).ToString());
					val4.Add("item_type", (object)(int)shared.m_itemType);
					val4.Add("description", (object)Localization.instance.Localize(shared.m_description ?? ""));
					val4.Add("prefab_name", (object)name);
					val4.Add("food", (object)shared.m_food);
					val4.Add("food_burn_time", (object)shared.m_foodBurnTime);
					val4.Add("food_regen", (object)shared.m_foodRegen);
					val4.Add("food_stamina", (object)shared.m_foodStamina);
					val4.Add("armor", (object)shared.m_armor);
					val4.Add("armor_per_level", (object)shared.m_armorPerLevel);
					val4.Add("attack_force", (object)shared.m_attackForce);
					val4.Add("backstab_bonus", (object)shared.m_backstabBonus);
					val4.Add("block_power", (object)shared.m_blockPower);
					val4.Add("block_power_per_level", (object)shared.m_blockPowerPerLevel);
					val4.Add("deflection_force", (object)shared.m_deflectionForce);
					val4.Add("deflection_force_per_level", (object)shared.m_deflectionForcePerLevel);
					val4.Add("ai_attack_interval", (object)shared.m_aiAttackInterval);
					val4.Add("ai_attack_max_angle", (object)shared.m_aiAttackMaxAngle);
					val4.Add("ai_attack_range", (object)shared.m_aiAttackRange);
					val4.Add("ai_attack_range_min", (object)shared.m_aiAttackRangeMin);
					val4.Add("ai_prioritized", (object)shared.m_aiPrioritized);
					val4.Add("ai_target_type", (object)((object)Unsafe.As<AiTarget, AiTarget>(ref shared.m_aiTargetType)/*cast due to .constrained prefix*/).ToString());
					val4.Add("ai_when_flying", (object)shared.m_aiWhenFlying);
					val4.Add("ai_when_swiming", (object)shared.m_aiWhenSwiming);
					val4.Add("ai_when_walking", (object)shared.m_aiWhenWalking);
					val4.Add("animation_state", (object)((object)Unsafe.As<AnimationState, AnimationState>(ref shared.m_animationState)/*cast due to .constrained prefix*/).ToString());
					val4.Add("blockable", (object)shared.m_blockable);
					val4.Add("can_be_reparied", (object)shared.m_canBeReparied);
					val4.Add("destroy_broken", (object)shared.m_destroyBroken);
					val4.Add("dodgeable", (object)shared.m_dodgeable);
					val4.Add("durability_drain", (object)shared.m_durabilityDrain);
					val4.Add("durability_per_level", (object)shared.m_durabilityPerLevel);
					val4.Add("equip_duration", (object)shared.m_equipDuration);
					val4.Add("helmet_hide_hair", (object)((object)Unsafe.As<HelmetHairType, HelmetHairType>(ref shared.m_helmetHideHair)/*cast due to .constrained prefix*/).ToString());
					val4.Add("max_durability", (object)shared.m_maxDurability);
					val4.Add("max_quality", (object)shared.m_maxQuality);
					val4.Add("max_stack_size", (object)shared.m_maxStackSize);
					val4.Add("movement_modifier", (object)shared.m_movementModifier);
					val4.Add("quest_item", (object)shared.m_questItem);
					val4.Add("set_size", (object)shared.m_setSize);
					val4.Add("teleportable", (object)shared.m_teleportable);
					val4.Add("timed_block_bonus", (object)shared.m_timedBlockBonus);
					val4.Add("tool_tier", (object)shared.m_toolTier);
					val4.Add("use_durability", (object)shared.m_useDurability);
					val4.Add("use_durability_drain", (object)shared.m_useDurabilityDrain);
					val4.Add("value", (object)shared.m_value);
					val4.Add("variants", (object)shared.m_variants);
					val4.Add("weight", (object)shared.m_weight);
					val4.Add("ammo_type", (object)(shared.m_ammoType ?? ""));
					val4.Add("skill_type", (object)((object)Unsafe.As<SkillType, SkillType>(ref shared.m_skillType)/*cast due to .constrained prefix*/).ToString());
					val4.Add("damages", (object)ExtractDamageData(shared.m_damages));
					val4.Add("damages_per_level", (object)ExtractDamageDataWithPrefix(shared.m_damagesPerLevel));
					val4.Add("status_effects", (object)ExtractStatusEffects(shared));
					val4.Add("set_name", (object)(shared.m_setName ?? ""));
					val4.Add("set_status_effect", (object)(((Object)(object)shared.m_setStatusEffect != (Object)null) ? ((Object)shared.m_setStatusEffect).name : ""));
					val4.Add("food_eitr", (object)shared.m_foodEitr);
					if (shared.m_icons != null && shared.m_icons.Length != 0 && (Object)(object)shared.m_icons[0] != (Object)null)
					{
						val4.Add("icon", (object)(name + ".png"));
						if (ExportItemIcon(shared, name, text))
						{
							num++;
						}
					}
					val3.Add("shared_data", (object)val4);
					((List<object>)(object)val).Add((object)val3);
				}
			}
			Logger.LogInfo((object)$"Exported {num} icons to {text}/");
			return val;
		}

		private static JsonArray ExtractAllRecipes()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Expected O, but got Unknown
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Expected O, but got Unknown
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Expected O, but got Unknown
			JsonArray val = new JsonArray();
			HashSet<string> valharvestPrefabNames = GetValharvestPrefabNames();
			if (ObjectDB.instance.m_recipes == null)
			{
				return val;
			}
			foreach (Recipe recipe in ObjectDB.instance.m_recipes)
			{
				if ((Object)(object)recipe == (Object)null || (Object)(object)recipe.m_item == (Object)null)
				{
					continue;
				}
				string name = ((Object)((Component)recipe.m_item).gameObject).name;
				if (valharvestPrefabNames.Contains(name))
				{
					continue;
				}
				JsonObject val2 = new JsonObject();
				SharedData shared = recipe.m_item.m_itemData.m_shared;
				val2.Add("raw_name", (object)Localization.instance.Localize(shared.m_name ?? ""));
				val2.Add("var_name", (object)(shared.m_name ?? ""));
				val2.Add("true_name", (object)(((Object)recipe).name ?? ""));
				val2.Add("enabled", (object)recipe.m_enabled);
				val2.Add("min_station_level", (object)recipe.m_minStationLevel);
				val2.Add("amount", (object)recipe.m_amount);
				if ((Object)(object)recipe.m_craftingStation != (Object)null)
				{
					val2.Add("raw_crafting_station_name", (object)Localization.instance.Localize(recipe.m_craftingStation.m_name ?? ""));
					val2.Add("true_crafting_station_name", (object)(((Object)recipe.m_craftingStation).name ?? ""));
				}
				else
				{
					val2.Add("raw_crafting_station_name", (object)"");
					val2.Add("true_crafting_station_name", (object)"");
				}
				JsonArray val3 = new JsonArray();
				if (recipe.m_resources != null)
				{
					Requirement[] resources = recipe.m_resources;
					foreach (Requirement val4 in resources)
					{
						if (val4 != null && !((Object)(object)val4.m_resItem == (Object)null))
						{
							JsonObject val5 = new JsonObject();
							SharedData shared2 = val4.m_resItem.m_itemData.m_shared;
							val5.Add("amount", (object)val4.m_amount);
							val5.Add("amount_per_level", (object)val4.m_amountPerLevel);
							val5.Add("raw_name", (object)Localization.instance.Localize(shared2.m_name ?? ""));
							val5.Add("var_name", (object)(shared2.m_name ?? ""));
							val5.Add("true_name", (object)(((Object)((Component)val4.m_resItem).gameObject).name ?? ""));
							val5.Add("recover", (object)val4.m_recover);
							((List<object>)(object)val3).Add((object)val5);
						}
					}
				}
				val2.Add("requirements", (object)val3);
				((List<object>)(object)val).Add((object)val2);
			}
			return val;
		}

		private static JsonObject ExtractDamageData(DamageTypes damages)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: 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_005d: 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_0073: 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_008f: 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_00a5: 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)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: 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_00f8: Expected O, but got Unknown
			JsonObject val = new JsonObject();
			val.Add("damage", (object)damages.m_damage);
			val.Add("blunt", (object)damages.m_blunt);
			val.Add("slash", (object)damages.m_slash);
			val.Add("pierce", (object)damages.m_pierce);
			val.Add("chop", (object)damages.m_chop);
			val.Add("pickaxe", (object)damages.m_pickaxe);
			val.Add("fire", (object)damages.m_fire);
			val.Add("frost", (object)damages.m_frost);
			val.Add("lightning", (object)damages.m_lightning);
			val.Add("poison", (object)damages.m_poison);
			val.Add("spirit", (object)damages.m_spirit);
			return val;
		}

		private static JsonObject ExtractDamageDataWithPrefix(DamageTypes damages)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: 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_005d: 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_0073: 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_008f: 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_00a5: 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)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: 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_00f8: Expected O, but got Unknown
			JsonObject val = new JsonObject();
			val.Add("m_damage", (object)damages.m_damage);
			val.Add("m_blunt", (object)damages.m_blunt);
			val.Add("m_slash", (object)damages.m_slash);
			val.Add("m_pierce", (object)damages.m_pierce);
			val.Add("m_chop", (object)damages.m_chop);
			val.Add("m_pickaxe", (object)damages.m_pickaxe);
			val.Add("m_fire", (object)damages.m_fire);
			val.Add("m_frost", (object)damages.m_frost);
			val.Add("m_lightning", (object)damages.m_lightning);
			val.Add("m_poison", (object)damages.m_poison);
			val.Add("m_spirit", (object)damages.m_spirit);
			return val;
		}

		private static JsonArray ExtractStatusEffects(SharedData shared)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			JsonArray val = new JsonArray();
			if ((Object)(object)shared.m_attackStatusEffect != (Object)null)
			{
				((List<object>)(object)val).Add((object)((Object)shared.m_attackStatusEffect).name);
			}
			if ((Object)(object)shared.m_consumeStatusEffect != (Object)null)
			{
				((List<object>)(object)val).Add((object)((Object)shared.m_consumeStatusEffect).name);
			}
			if ((Object)(object)shared.m_equipStatusEffect != (Object)null)
			{
				((List<object>)(object)val).Add((object)((Object)shared.m_equipStatusEffect).name);
			}
			if ((Object)(object)shared.m_setStatusEffect != (Object)null)
			{
				((List<object>)(object)val).Add((object)((Object)shared.m_setStatusEffect).name);
			}
			return val;
		}

		private static bool ExportItemIcon(SharedData shared, string prefabName, string outputDir)
		{
			if (shared.m_icons == null || shared.m_icons.Length == 0)
			{
				return false;
			}
			Sprite val = shared.m_icons[0];
			if ((Object)(object)val == (Object)null || (Object)(object)val.texture == (Object)null)
			{
				return false;
			}
			try
			{
				Texture2D val2 = MakeTextureReadable(val);
				if ((Object)(object)val2 == (Object)null)
				{
					return false;
				}
				byte[] bytes = ImageConversion.EncodeToPNG(val2);
				File.WriteAllBytes(Path.Combine(outputDir, prefabName + ".png"), bytes);
				Object.Destroy((Object)(object)val2);
				return true;
			}
			catch (Exception ex)
			{
				Logger.LogWarning((object)("Failed to export icon for " + prefabName + ": " + ex.Message));
				return false;
			}
		}

		private static Texture2D MakeTextureReadable(Sprite sprite)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Expected O, but got Unknown
			Texture2D texture = sprite.texture;
			Rect textureRect = sprite.textureRect;
			RenderTexture temporary = RenderTexture.GetTemporary(((Texture)texture).width, ((Texture)texture).height, 0, (RenderTextureFormat)0);
			Graphics.Blit((Texture)(object)texture, temporary);
			RenderTexture active = RenderTexture.active;
			RenderTexture.active = temporary;
			int num = Mathf.FloorToInt(((Rect)(ref textureRect)).x);
			int num2 = Mathf.FloorToInt(((Rect)(ref textureRect)).y);
			int num3 = Mathf.FloorToInt(((Rect)(ref textureRect)).width);
			int num4 = Mathf.FloorToInt(((Rect)(ref textureRect)).height);
			Texture2D val = new Texture2D(num3, num4, (TextureFormat)5, false);
			val.ReadPixels(new Rect((float)num, (float)num2, (float)num3, (float)num4), 0, 0);
			val.Apply();
			RenderTexture.active = active;
			RenderTexture.ReleaseTemporary(temporary);
			return val;
		}
	}
	public class ExportItemsCommand : ConsoleCommand
	{
		public override string Name => "exportitems";

		public override string Help => "Exports all game items to itemdrops.json and recipes to recipes.json in the Valheim directory";

		public override void Run(string[] args)
		{
			Logger.LogInfo((object)"Running exportitems command...");
			ConsumableItemExtractor.GenerateConsumableItemList();
		}
	}
	public class CultivatedGround : Heightmap
	{
		private void Awake()
		{
		}

		private void Update()
		{
		}

		private void OnEnable()
		{
			Regenerate();
		}

		private void Regenerate()
		{
			Generate();
		}

		private void Generate()
		{
			Initialize();
		}

		public void Initialize()
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			int num = base.m_width + 1;
			int num2 = num * num;
			if (base.m_heights.Count != num2)
			{
				base.m_heights.Clear();
				for (int i = 0; i < num2; i++)
				{
					base.m_heights.Add(0f);
				}
				base.m_paintMask = new Texture2D(base.m_width, base.m_width)
				{
					wrapMode = (TextureWrapMode)1
				};
			}
		}
	}
	[HarmonyPatch]
	public static class DeepFireCheckPatch
	{
		[HarmonyPatch(typeof(CraftingStation), "CheckFire")]
		private static class CheckFirePatch
		{
			private static bool Prefix(CraftingStation __instance, ref bool ___m_haveFire)
			{
				//IL_0052: Unknown result type (might be due to invalid IL or missing references)
				//IL_0045: Unknown result type (might be due to invalid IL or missing references)
				if (!IsTarget((Object)(object)__instance))
				{
					return true;
				}
				GameObject haveFireObject = __instance.m_haveFireObject;
				Collider val = (((Object)(object)haveFireObject != (Object)null) ? haveFireObject.GetComponent<Collider>() : null);
				bool flag;
				if ((Object)(object)val != (Object)null)
				{
					flag = HasBurningInVolume(val);
				}
				else
				{
					Vector3 val2 = (((Object)(object)haveFireObject != (Object)null) ? haveFireObject.transform.position : ((Component)__instance).transform.position);
					float num = ((Valharvest.Configurations.Valharvest.CookingPotFireCheckRadius != null) ? Valharvest.Configurations.Valharvest.CookingPotFireCheckRadius.Value : 0.5f);
					flag = (Object)(object)EffectArea.IsPointInsideArea(val2, (Type)8, num) != (Object)null;
				}
				___m_haveFire = flag;
				if ((Object)(object)haveFireObject != (Object)null)
				{
					haveFireObject.SetActive(flag);
				}
				return false;
			}
		}

		private static int _characterTriggerMask;

		private static readonly Collider[] _hits = (Collider[])(object)new Collider[32];

		private static int CharacterTriggerMask
		{
			get
			{
				if (_characterTriggerMask == 0)
				{
					_characterTriggerMask = LayerMask.GetMask(new string[1] { "character_trigger" });
				}
				return _characterTriggerMask;
			}
		}

		private static bool IsTarget(Object instance)
		{
			if (instance != (Object)null && instance.name != null)
			{
				return instance.name.StartsWith("piece_cooking_pot");
			}
			return false;
		}

		private static bool HasBurningInVolume(Collider volume)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_002c: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: 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_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: 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)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = ((Component)volume).transform;
			Vector3 lossyScale = transform.lossyScale;
			int num = 0;
			BoxCollider val = (BoxCollider)(object)((volume is BoxCollider) ? volume : null);
			if (val != null)
			{
				Vector3 val2 = transform.TransformPoint(val.center);
				Vector3 val3 = default(Vector3);
				((Vector3)(ref val3))..ctor(Mathf.Abs(val.size.x * lossyScale.x) * 0.5f, Mathf.Abs(val.size.y * lossyScale.y) * 0.5f, Mathf.Abs(val.size.z * lossyScale.z) * 0.5f);
				num = Physics.OverlapBoxNonAlloc(val2, val3, _hits, transform.rotation, CharacterTriggerMask, (QueryTriggerInteraction)2);
			}
			else
			{
				SphereCollider val4 = (SphereCollider)(object)((volume is SphereCollider) ? volume : null);
				if (val4 != null)
				{
					Vector3 val5 = transform.TransformPoint(val4.center);
					float num2 = val4.radius * Mathf.Max(new float[3]
					{
						Mathf.Abs(lossyScale.x),
						Mathf.Abs(lossyScale.y),
						Mathf.Abs(lossyScale.z)
					});
					num = Physics.OverlapSphereNonAlloc(val5, num2, _hits, CharacterTriggerMask, (QueryTriggerInteraction)2);
				}
				else
				{
					CapsuleCollider val6 = (CapsuleCollider)(object)((volume is CapsuleCollider) ? volume : null);
					if (val6 != null)
					{
						Bounds bounds = ((Collider)val6).bounds;
						num = Physics.OverlapBoxNonAlloc(((Bounds)(ref bounds)).center, ((Bounds)(ref bounds)).extents, _hits, Quaternion.identity, CharacterTriggerMask, (QueryTriggerInteraction)2);
					}
					else
					{
						Bounds bounds2 = volume.bounds;
						num = Physics.OverlapBoxNonAlloc(((Bounds)(ref bounds2)).center, ((Bounds)(ref bounds2)).extents, _hits, Quaternion.identity, CharacterTriggerMask, (QueryTriggerInteraction)2);
					}
				}
			}
			for (int i = 0; i < num; i++)
			{
				EffectArea component = ((Component)_hits[i]).GetComponent<EffectArea>();
				if ((Object)(object)component != (Object)null && (component.m_type & 8) != 0)
				{
					return true;
				}
			}
			return false;
		}
	}
	[HarmonyPatch]
	public class EggAndFeatherDrop
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(TreeBase), "SpawnLog")]
		public static void TreeBaseSpawnLog_Patch(TreeBase __instance)
		{
			//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_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			string name = ((Object)__instance.m_logPrefab).name;
			if (((IList)new string[6] { "PineTree_log", "PineTree_logOLD", "FirTree_log", "beech_log", "Birch_log", "Oak_log" }).Contains((object?)name) && Random.value < 0.15f)
			{
				GameObject prefab = ZNetScene.instance.GetPrefab("Feathers");
				GameObject prefab2 = ZNetScene.instance.GetPrefab(BoneAppetitCompat.GetEggItem());
				int num = Random.Range(1, 8);
				int num2 = Random.Range(1, 3);
				for (int i = 0; i < num; i++)
				{
					Object.Instantiate<GameObject>(prefab, ((Component)__instance).transform.position, Quaternion.identity);
				}
				for (int j = 0; j < num2; j++)
				{
					Object.Instantiate<GameObject>(prefab2, ((Component)__instance).transform.position, Quaternion.identity);
				}
			}
		}
	}
	public class FeedingTrough : MonoBehaviour, Hoverable, Interactable
	{
		public const int Capacity = 20;

		internal static readonly List<FeedingTrough> Active = new List<FeedingTrough>();

		private const string FILL_ITEM_KEY = "vh_fill_item";

		private const string FILL_AMOUNT_KEY = "vh_fill_amount";

		private const string RPC_REFRESH = "VH_RefreshTrough";

		private static readonly Vector2 InteriorX = new Vector2(-0.75f, 0.75f);

		private static readonly Vector2 InteriorZ = new Vector2(-0.2f, 0.2f);

		private const float FloorY = 0.205f;

		private const float RimY = 0.44f;

		private const int GridX = 24;

		private const int GridZ = 6;

		private static readonly HashSet<string> FeedItems = new HashSet<string>();

		private ZNetView _nview;

		private Piece _piece;

		private Transform _model;

		private Renderer _woodRenderer;

		private GameObject _fill;

		private MeshFilter _fillFilter;

		private MeshRenderer _fillRenderer;

		private string _visualKey;

		public static void CollectFeedItems()
		{
			FeedItems.Clear();
			if ((Object)(object)ZNetScene.instance == (Object)null)
			{
				return;
			}
			foreach (GameObject prefab in ZNetScene.instance.m_prefabs)
			{
				if ((Object)(object)prefab == (Object)null || (Object)(object)prefab.GetComponent<Tameable>() == (Object)null)
				{
					continue;
				}
				MonsterAI component = prefab.GetComponent<MonsterAI>();
				if (component?.m_consumeItems == null)
				{
					continue;
				}
				foreach (ItemDrop consumeItem in component.m_consumeItems)
				{
					if ((Object)(object)consumeItem != (Object)null)
					{
						FeedItems.Add(Utils.GetPrefabName(((Component)consumeItem).gameObject));
					}
				}
			}
			Logger.LogInfo((object)string.Format("Feeding trough accepts {0} items: {1}", FeedItems.Count, string.Join(", ", FeedItems)));
		}

		private void Awake()
		{
			_nview = ((Component)this).GetComponent<ZNetView>();
			_piece = ((Component)this).GetComponent<Piece>();
			_model = ((Component)this).transform.Find("model");
			Transform model = _model;
			object woodRenderer;
			if (model == null)
			{
				woodRenderer = null;
			}
			else
			{
				Transform obj = model.Find("plank_floor");
				woodRenderer = ((obj != null) ? ((Component)obj).GetComponent<Renderer>() : null);
			}
			_woodRenderer = (Renderer)woodRenderer;
			ZNetView nview = _nview;
			if (nview != null)
			{
				nview.Register("VH_RefreshTrough", (Action<long>)delegate
				{
					RefreshVisual();
				});
			}
		}

		private void Start()
		{
			RefreshVisual();
		}

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

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

		public string GetHoverName()
		{
			return Localization.instance.Localize(((Object)(object)_piece != (Object)null) ? _piece.m_name : "$vh_feeding_through_name");
		}

		public string GetHoverText()
		{
			if ((Object)(object)_nview == (Object)null || !_nview.IsValid())
			{
				return "";
			}
			string feedItem = GetFeedItem();
			int feedAmount = GetFeedAmount();
			int num;
			object obj;
			if (feedAmount > 0)
			{
				num = (string.IsNullOrEmpty(feedItem) ? 1 : 0);
				if (num == 0)
				{
					obj = $"{GetItemName(feedItem)} {Mathf.RoundToInt(100f * (float)feedAmount / 20f)}%";
					goto IL_006e;
				}
			}
			else
			{
				num = 1;
			}
			obj = "$vh_trough_empty";
			goto IL_006e;
			IL_006e:
			string text = (string)obj;
			string text2 = ((num != 0) ? "$vh_trough_use_item" : "[<color=yellow><b>$KEY_Use</b></color>] $vh_trough_add");
			return Localization.instance.Localize(GetHoverName() + "\n" + text + "\n" + text2);
		}

		public float GetHoverOffset()
		{
			return 0f;
		}

		public bool Interact(Humanoid user, bool hold, bool alt)
		{
			if (hold || (Object)(object)_nview == (Object)null || !_nview.IsValid())
			{
				return false;
			}
			string feedItem = GetFeedItem();
			if (string.IsNullOrEmpty(feedItem))
			{
				((Character)user).Message((MessageType)2, "$vh_trough_use_item", 0, (Sprite)null, false);
				return false;
			}
			ItemData item = user.GetInventory().GetItem(feedItem, -1, true);
			if (item == null)
			{
				((Character)user).Message((MessageType)2, "$vh_trough_no_feed", 0, (Sprite)null, false);
				return false;
			}
			return AddFeed(user, item);
		}

		public bool UseItem(Humanoid user, ItemData item)
		{
			if ((Object)(object)_nview == (Object)null || !_nview.IsValid() || (Object)(object)item?.m_dropPrefab == (Object)null)
			{
				return false;
			}
			if (FeedItems.Count == 0)
			{
				CollectFeedItems();
			}
			if (!FeedItems.Contains(Utils.GetPrefabName(item.m_dropPrefab)))
			{
				return false;
			}
			return AddFeed(user, item);
		}

		private bool AddFeed(Humanoid user, ItemData item)
		{
			//IL_00c6: 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_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			string prefabName = Utils.GetPrefabName(item.m_dropPrefab);
			string feedItem = GetFeedItem();
			int feedAmount = GetFeedAmount();
			if (feedAmount > 0 && feedItem != prefabName)
			{
				((Character)user).Message((MessageType)2, "$vh_trough_other_feed", 0, (Sprite)null, false);
				return true;
			}
			if (feedAmount >= 20)
			{
				((Character)user).Message((MessageType)2, "$vh_trough_full", 0, (Sprite)null, false);
				return true;
			}
			int num = Mathf.Min(item.m_stack, 20 - feedAmount);
			user.GetInventory().RemoveItem(item, num);
			_nview.ClaimOwnership();
			ZDO zDO = _nview.GetZDO();
			zDO.Set("vh_fill_item", prefabName);
			zDO.Set("vh_fill_amount", feedAmount + num);
			_nview.InvokeRPC(ZNetView.Everybody, "VH_RefreshTrough", Array.Empty<object>());
			EffectList troughFillSfx = Main.troughFillSfx;
			if (troughFillSfx != null)
			{
				troughFillSfx.Create(((Component)this).transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID));
			}
			((Character)user).Message((MessageType)2, $"$vh_trough_added {item.m_shared.m_name} x{num}", 0, (Sprite)null, false);
			return true;
		}

		public bool TryConsume(int amount = 1)
		{
			if ((Object)(object)_nview == (Object)null || !_nview.IsValid())
			{
				return false;
			}
			int feedAmount = GetFeedAmount();
			if (feedAmount < amount)
			{
				return false;
			}
			_nview.ClaimOwnership();
			ZDO zDO = _nview.GetZDO();
			int num = feedAmount - amount;
			zDO.Set("vh_fill_amount", num);
			if (num <= 0)
			{
				zDO.Set("vh_fill_item", "");
			}
			_nview.InvokeRPC(ZNetView.Everybody, "VH_RefreshTrough", Array.Empty<object>());
			return true;
		}

		public bool HasFeedFor(MonsterAI ai)
		{
			if (GetFeedAmount() <= 0)
			{
				return false;
			}
			GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab(GetFeedItem()) : null);
			ItemDrop val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<ItemDrop>() : null);
			if ((Object)(object)val2 != (Object)null)
			{
				return ai.CanConsume(val2.m_itemData);
			}
			return false;
		}

		public string GetFeedItem()
		{
			if (!((Object)(object)_nview != (Object)null) || !_nview.IsValid())
			{
				return "";
			}
			return _nview.GetZDO().GetString("vh_fill_item", "");
		}

		public int GetFeedAmount()
		{
			if (!((Object)(object)_nview != (Object)null) || !_nview.IsValid())
			{
				return 0;
			}
			return _nview.GetZDO().GetInt("vh_fill_amount", 0);
		}

		private static string GetItemName(string prefabName)
		{
			GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab(prefabName) : null);
			ItemDrop val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<ItemDrop>() : null);
			if (!((Object)(object)val2 != (Object)null))
			{
				return prefabName;
			}
			return val2.m_itemData.m_shared.m_name;
		}

		private void RefreshVisual()
		{
			if ((Object)(object)_model == (Object)null)
			{
				return;
			}
			string feedItem = GetFeedItem();
			int feedAmount = GetFeedAmount();
			if (string.IsNullOrEmpty(feedItem) || feedAmount <= 0)
			{
				if ((Object)(object)_fill != (Object)null)
				{
					_fill.SetActive(false);
				}
				_visualKey = null;
				return;
			}
			int num = Mathf.Clamp(Mathf.CeilToInt(4f * (float)feedAmount / 20f), 1, 4);
			string text = feedItem + "/" + num;
			if (_visualKey == text && (Object)(object)_fill != (Object)null && _fill.activeSelf)
			{
				return;
			}
			Material pileMaterial = FoodCrate.GetPileMaterial(feedItem, ((Object)(object)_woodRenderer != (Object)null) ? _woodRenderer.sharedMaterial : null);
			if ((Object)(object)pileMaterial == (Object)null)
			{
				if ((Object)(object)_fill != (Object)null)
				{
					_fill.SetActive(false);
				}
				_visualKey = null;
			}
			else
			{
				EnsureFillObject();
				_fillFilter.sharedMesh = BuildMound((float)num / 4f, feedItem.GetHashCode());
				((Renderer)_fillRenderer).sharedMaterial = pileMaterial;
				_fill.SetActive(true);
				_visualKey = text;
			}
		}

		private void EnsureFillObject()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			if (!((Object)(object)_fill != (Object)null))
			{
				_fill = new GameObject("fill");
				_fill.layer = ((Component)this).gameObject.layer;
				_fill.transform.SetParent(((Component)this).transform, false);
				_fillFilter = _fill.AddComponent<MeshFilter>();
				_fillRenderer = _fill.AddComponent<MeshRenderer>();
				((Renderer)_fillRenderer).shadowCastingMode = (ShadowCastingMode)0;
			}
		}

		private static Mesh BuildMound(float fill, int seed)
		{
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: 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_020f: Expected O, but got Unknown
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Lerp(0.235f, 0.44f, fill);
			Random random = new Random(seed);
			List<Vector3> list = new List<Vector3>();
			List<Vector2> list2 = new List<Vector2>();
			List<int> list3 = new List<int>();
			for (int i = 0; i <= 6; i++)
			{
				for (int j = 0; j <= 24; j++)
				{
					float num2 = (float)j / 24f;
					float num3 = (float)i / 6f;
					float num4 = Mathf.Lerp(InteriorX.x, InteriorX.y, num2);
					float num5 = Mathf.Lerp(InteriorZ.x, InteriorZ.y, num3);
					bool num6 = j == 0 || j == 24 || i == 0 || i == 6;
					float num7 = Mathf.Min(Mathf.Sin(num2 * (float)Math.PI) * 3f, 1f) * Mathf.Min(Mathf.Sin(num3 * (float)Math.PI) * 1.5f, 1f);
					float num8 = (num6 ? (0.205f + (num - 0.205f) * 0.85f) : (0.205f + (num - 0.205f) * (0.75f + 0.25f * num7) + ((float)random.NextDouble() - 0.5f) * 0.015f));
					list.Add(new Vector3(num4, num8, num5));
					list2.Add(new Vector2(num4, num5));
				}
			}
			for (int k = 0; k < 6; k++)
			{
				for (int l = 0; l < 24; l++)
				{
					int num9 = k * 25 + l;
					int item = num9 + 1;
					int num10 = num9 + 24 + 1;
					int item2 = num10 + 1;
					list3.Add(num9);
					list3.Add(num10);
					list3.Add(item);
					list3.Add(item);
					list3.Add(num10);
					list3.Add(item2);
				}
			}
			Mesh val = new Mesh
			{
				name = "vh_trough_fill"
			};
			val.SetVertices(list);
			val.SetUVs(0, list2);
			val.SetTriangles(list3, 0);
			val.RecalculateNormals();
			val.RecalculateTangents();
			return val;
		}
	}
	[HarmonyPatch(typeof(MonsterAI), "UpdateConsumeItem")]
	internal static class TroughFeedPatch
	{
		private const float SearchRange = 12f;

		private static readonly Dictionary<int, FeedingTrough> Targets = new Dictionary<int, FeedingTrough>();

		[HarmonyPostfix]
		private static void Postfix(MonsterAI __instance, Humanoid humanoid, float dt, ref bool __result)
		{
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			if (__result || FeedingTrough.Active.Count == 0 || (Object)(object)((BaseAI)__instance).m_tamable == (Object)null || (Object)(object)((BaseAI)__instance).m_nview == (Object)null || !((BaseAI)__instance).m_nview.IsOwner() || !((BaseAI)__instance).m_tamable.IsHungry() || __instance.m_consumeItems == null || __instance.m_consumeItems.Count == 0)
			{
				return;
			}
			int instanceID = ((Object)__instance).GetInstanceID();
			if (__instance.m_consumeSearchTimer == 0f || !Targets.TryGetValue(instanceID, out var value) || (Object)(object)value == (Object)null || !value.HasFeedFor(__instance))
			{
				value = FindTrough(__instance);
				if ((Object)(object)value == (Object)null)
				{
					Targets.Remove(instanceID);
					return;
				}
				Targets[instanceID] = value;
			}
			Vector3 position = ((Component)value).transform.position;
			__result = true;
			if (!((BaseAI)__instance).MoveTo(dt, position, __instance.m_consumeRange, false))
			{
				return;
			}
			((BaseAI)__instance).LookAt(position);
			if (((BaseAI)__instance).IsLookingAt(position, 20f, false))
			{
				if (!value.TryConsume())
				{
					Targets.Remove(instanceID);
					__result = false;
				}
				else
				{
					__instance.m_onConsumedItem?.Invoke(null);
					humanoid.m_consumeItemEffects.Create(((Component)__instance).transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID));
					((BaseAI)__instance).m_animator.SetTrigger("consume");
				}
			}
		}

		private static FeedingTrough FindTrough(MonsterAI ai)
		{
			//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_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_005f: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ((Component)ai).transform.position;
			FeedingTrough result = null;
			float num = 12f;
			foreach (FeedingTrough item in FeedingTrough.Active)
			{
				float num2 = Vector3.Distance(((Component)item).transform.position, position);
				if (!(num2 >= num) && item.HasFeedFor(ai) && (!(num2 > ai.m_consumeRange) || ((BaseAI)ai).HavePath(((Component)item).transform.position)))
				{
					result = item;
					num = num2;
				}
			}
			return result;
		}
	}
	public class FixPlantHealth : SlowUpdate
	{
		private const float GrowRadiusOverride = 0.4f;

		private const Biome BiomeOverride = (Biome)895;

		public override void Awake()
		{
			((SlowUpdate)this).Awake();
		}

		public override void SUpdate(float currentTime, Vector2s referenceZone)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			Plant component = ((Component)this).GetComponent<Plant>();
			Vector3 position = ((Component)this).transform.position;
			if (IsPlantValid(component, currentTime) && RaisedBed.CheckIfItemBellowIsCultivatedGround(position))
			{
				ApplyPlantOverrides(component);
			}
		}

		private bool IsPlantValid(Plant plant, float currentTime)
		{
			if (plant.m_nview.IsValid())
			{
				return currentTime <= plant.m_updateTime;
			}
			return false;
		}

		private void ApplyPlantOverrides(Plant plant)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			plant.m_tolerateHeat = true;
			plant.m_tolerateCold = true;
			plant.m_biome = (Biome)895;
			plant.m_growRadius = 0.4f;
		}
	}
	public class FoodCrate : MonoBehaviour
	{
		private sealed class PileBody
		{
			public GameObject Root;

			public Rigidbody Rigidbody;

			public Collider Collider;

			public Renderer[] Renderers;
		}

		private sealed class PileSource
		{
			public string Name;

			public Transform Visual;
		}

		[HarmonyPatch]
		private static class FoodOnlyInventoryPatch
		{
			private static IEnumerable<MethodBase> TargetMethods()
			{
				yield return AccessTools.Method(typeof(Inventory), "CanAddItem", new Type[2]
				{
					typeof(ItemData),
					typeof(int)
				}, (Type[])null);
				yield return AccessTools.Method(typeof(Inventory), "AddItem", new Type[1] { typeof(ItemData) }, (Type[])null);
				yield return AccessTools.Method(typeof(Inventory), "AddItem", new Type[2]
				{
					typeof(ItemData),
					typeof(Vector2i)
				}, (Type[])null);
				yield return AccessTools.Method(typeof(Inventory), "AddItem", new Type[5]
				{
					typeof(ItemData),
					typeof(int),
					typeof(int),
					typeof(int),
					typeof(bool)
				}, (Type[])null);
			}

			private static bool Prefix(Inventory __instance, ItemData __0, ref bool __result)
			{
				if (!FoodInventories.TryGetValue(__instance, out var value) || (Object)(object)value._container == (Object)null || value._container.m_loading || IsFoodOrIngredient(__0))
				{
					return true;
				}
				__result = false;
				ShowFoodOnlyMessage();
				return false;
			}
		}

		public const string VH_PILE_ITEM_KEY = "vh_pile_item";

		public const string VH_MIGRATED_KEY = "vh_migrated";

		private const string VH_GROUNDED_KEY = "vh_grounded";

		private const string RPC_REFRESH = "VH_RefreshPile";

		private const string MAT_PREFIX = "Pile";

		private const float GroundSnapEpsilon = 0.05f;

		private const int GroundSettlePasses = 24;

		private const int VisualItemsPerLevel = 12;

		private const int MaxVisualItems = 48;

		private const int SettleFrames = 30;

		private const int StableFrames = 2;

		private const float OverflowTolerance = 0.01f;

		private const float SimulationOffsetY = -5000f;

		private const string FoodOnlyMessage = "$food_crate_food_only";

		private static readonly Dictionary<Inventory, FoodCrate> FoodInventories = new Dictionary<Inventory, FoodCrate>();

		private static Dictionary<string, Material> _materialCache;

		private static HashSet<string> _foodStorageItems;

		private static int _cachedItemCount = -1;

		private static int _cachedRecipeCount = -1;

		private static float _lastRejectMessageAt = -1f;

		private Container _container;

		private ZNetView _nview;

		private Transform _model;

		private BoxCollider _pileVolume;

		private GameObject[] _piles;

		private Renderer _crateRenderer;

		private GameObject _runtimePile;

		private Coroutine _runtimePileRoutine;

		private string _visualKey;

		private string _lastVisualWarning;

		private void Awake()
		{
			_container = ((Component)this).GetComponent<Container>();
			_nview = ((Component)this).GetComponent<ZNetView>();
			_model = ((Component)this).transform.Find("model");
			if ((Object)(object)_model != (Object)null)
			{
				GameObject[] array = new GameObject[4];
				Transform obj = _model.Find("pile_1_25");
				array[0] = ((obj != null) ? ((Component)obj).gameObject : null);
				Transform obj2 = _model.Find("pile_2_50");
				array[1] = ((obj2 != null) ? ((Component)obj2).gameObject : null);
				Transform obj3 = _model.Find("pile_3_75");
				array[2] = ((obj3 != null) ? ((Component)obj3).gameObject : null);
				Transform obj4 = _model.Find("pile_4_100");
				array[3] = ((obj4 != null) ? ((Component)obj4).gameObject : null);
				_piles = (GameObject[])(object)array;
				Transform obj5 = _model.Find("crate_box");
				_crateRenderer = ((obj5 != null) ? ((Component)obj5).GetComponent<Renderer>() : null);
				Transform obj6 = _model.Find("pile_volume");
				_pileVolume = ((obj6 != null) ? ((Component)obj6).GetComponent<BoxCollider>() : null);
			}
			ZNetView nview = _nview;
			if (nview != null)
			{
				nview.Register("VH_RefreshPile", (Action<long>)delegate
				{
					RefreshVisual();
				});
			}
		}

		private void Start()
		{
			if (_container?.m_inventory != null)
			{
				Inventory inventory = _container.m_inventory;
				inventor