Decompiled source of HZ FarmAll v1.0.0

HZ_FarmAll.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Better_Farming.Bushs;
using Better_Farming.Bushs.Fiddlehead;
using Better_Farming.Mushrooms;
using Better_Farming.Utils;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("HZ_FarmAll")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("HZ_FarmAll")]
[assembly: AssemblyTitle("HZ_FarmAll")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Better_Farming
{
	internal static class ModConfig
	{
		private const string BlueberrySection = "BlueberryBush";

		private const string RaspberrySection = "RaspberryBush";

		private const string CloudberrySection = "CloudberryBush";

		private const string FiddleHeadSection = "FiddleheadBush";

		private const string ThistleSection = "ThistleBush";

		public static ConfigEntry<int> BlueberryGrowDaysMin { get; private set; }

		public static ConfigEntry<int> BlueberryGrowDaysMax { get; private set; }

		public static ConfigEntry<int> BlueberryPukeberriesCost { get; private set; }

		public static ConfigEntry<int> RaspberryGrowDaysMin { get; private set; }

		public static ConfigEntry<int> RaspberryGrowDaysMax { get; private set; }

		public static ConfigEntry<int> RaspberryCost { get; private set; }

		public static ConfigEntry<int> CloudberryGrowDaysMin { get; private set; }

		public static ConfigEntry<int> CloudberryGrowDaysMax { get; private set; }

		public static ConfigEntry<int> CloudberryCost { get; private set; }

		public static ConfigEntry<int> FiddleHeadCost { get; private set; }

		public static ConfigEntry<int> FiddleHeadGrowDaysMin { get; private set; }

		public static ConfigEntry<int> FiddleHeadGrowDaysMax { get; private set; }

		public static ConfigEntry<int> ThistleGrowDaysMin { get; private set; }

		public static ConfigEntry<int> ThistleGrowDaysMax { get; private set; }

		public static ConfigEntry<int> ThistleCost { get; private set; }

		public static void Init(ConfigFile config)
		{
			BlueberryGrowDaysMin = config.Bind<int>("BlueberryBush", "GrowDaysMin", 3, "Tempo mínimo (em dias de jogo) para o arbusto de mirtilo crescer.");
			BlueberryGrowDaysMax = config.Bind<int>("BlueberryBush", "GrowDaysMax", 4, "Tempo máximo (em dias de jogo) para o arbusto de mirtilo crescer. Se igual ao mínimo, o tempo é fixo; se maior, varia por planta (como as árvores vanilla).");
			BlueberryPukeberriesCost = config.Bind<int>("BlueberryBush", "PukeberriesCost", 5, "Quantidade de Pukeberries necessária para plantar um arbusto de mirtilo.");
			RaspberryGrowDaysMin = config.Bind<int>("RaspberryBush", "GrowDaysMin", 3, "Tempo mínimo (em dias de jogo) para o arbusto de framboesa crescer.");
			RaspberryGrowDaysMax = config.Bind<int>("RaspberryBush", "GrowDaysMax", 4, "Tempo máximo (em dias de jogo) para o arbusto de framboesa crescer. Se igual ao mínimo, o tempo é fixo; se maior, varia por planta.");
			RaspberryCost = config.Bind<int>("RaspberryBush", "RaspberriesCost", 5, "Quantidade de Framboesas necessária para plantar um arbusto de framboesa.");
			CloudberryGrowDaysMin = config.Bind<int>("CloudberryBush", "GrowDaysMin", 3, "Tempo mínimo (em dias de jogo) para o arbusto de framboesa crescer.");
			CloudberryGrowDaysMax = config.Bind<int>("CloudberryBush", "GrowDaysMax", 4, "Tempo máximo (em dias de jogo) para o arbusto de Cloudberry crescer. Se igual ao mínimo, o tempo é fixo; se maior, varia por planta.");
			CloudberryCost = config.Bind<int>("CloudberryBush", "CloudberryCost", 5, "Quantidade de Cloudberry necessária para plantar um arbusto de Cloudberry.");
			FiddleHeadGrowDaysMin = config.Bind<int>("FiddleheadBush", "GrowDaysMin", 3, "Tempo mínimo (em dias de jogo) para o arbusto de framboesa crescer.");
			FiddleHeadGrowDaysMax = config.Bind<int>("FiddleheadBush", "GrowDaysMax", 4, "Tempo máximo (em dias de jogo) para o arbusto de framboesa crescer. Se igual ao mínimo, o tempo é fixo; se maior, varia por planta.");
			FiddleHeadCost = config.Bind<int>("FiddleheadBush", "FiddleHeadCost", 5, "Quantidade de FiddleHead necessária para plantar um arbusto de FiddleHead.");
			ThistleGrowDaysMin = config.Bind<int>("ThistleBush", "GrowDaysMin", 2, "Tempo mínimo (em dias de jogo) para o arbusto de framboesa crescer.");
			ThistleGrowDaysMax = config.Bind<int>("ThistleBush", "GrowDaysMax", 3, "Tempo máximo (em dias de jogo) para o arbusto de framboesa crescer. Se igual ao mínimo, o tempo é fixo; se maior, varia por planta.");
			ThistleCost = config.Bind<int>("ThistleBush", "ThistleCost", 1, "Quantidade de Thistle necessária para plantar um arbusto de Thistle.");
		}

		public static float DaysToSeconds(int days)
		{
			return (float)days * 1800f;
		}
	}
	[BepInPlugin("hz.farmall", "HZ_FarmAll", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string ModGuid = "hz.farmall";

		public const string ModName = "HZ_FarmAll";

		public const string ModVersion = "1.0.0";

		private Harmony _harmony;

		internal static Plugin Instance { get; private set; }

		internal static ManualLogSource Log => ((BaseUnityPlugin)Instance).Logger;

		private void Awake()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			_harmony = new Harmony("hz.farmall");
			_harmony.PatchAll();
			Instance = this;
			ModConfig.Init(((BaseUnityPlugin)this).Config);
			MethodInfo[] methods = typeof(Plant).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (MethodInfo methodInfo in methods)
			{
				if (methodInfo.Name.ToLower().Contains("grow") || methodInfo.Name.ToLower().Contains("time") || methodInfo.Name.ToLower().Contains("planted"))
				{
					Log.LogInfo((object)$"Plant method: {methodInfo.Name} -> {methodInfo.ReturnType}");
				}
			}
			PrefabManager.OnVanillaPrefabsAvailable += BlueberryBushPiece.Setup;
			PrefabManager.OnVanillaPrefabsAvailable += RaspberryBushPiece.Setup;
			PrefabManager.OnVanillaPrefabsAvailable += CloudberryPiece.Setup;
			PrefabManager.OnVanillaPrefabsAvailable += FiddleHeadPiece.Setup;
			PrefabManager.OnVanillaPrefabsAvailable += ThistlePiece.Setup;
			PrefabManager.OnVanillaPrefabsAvailable += MushroomPiece.Setup;
			PrefabManager.OnVanillaPrefabsAvailable += MushroomYellowPiece.Setup;
			PrefabManager.OnVanillaPrefabsAvailable += MushroomSmokePuffPiece.Setup;
			PrefabManager.OnVanillaPrefabsAvailable += MushroomBluePiece.Setup;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"HZ_FarmAll 1.0.0 loaded.");
		}
	}
}
namespace Better_Farming.Utils
{
	internal static class GameClock
	{
		private const double DayOffsetSec = 0.0;

		public static double GetCurrentGameHour()
		{
			if ((Object)(object)EnvMan.instance == (Object)null || (Object)(object)ZNet.instance == (Object)null)
			{
				return -1.0;
			}
			double num = EnvMan.instance.m_dayLengthSec;
			if (num <= 0.0)
			{
				return -1.0;
			}
			double num2 = (ZNet.instance.GetTimeSeconds() + 0.0) % num / num;
			if (num2 < 0.0)
			{
				num2 += 1.0;
			}
			return num2 * 24.0;
		}

		public static bool IsWithinHourWindow(double startHour, double endHour)
		{
			double currentGameHour = GetCurrentGameHour();
			if (currentGameHour < 0.0)
			{
				return false;
			}
			if (currentGameHour >= startHour)
			{
				return currentGameHour < endHour;
			}
			return false;
		}

		public static double SecondsUntilHour(double targetHour)
		{
			double currentGameHour = GetCurrentGameHour();
			if (currentGameHour < 0.0 || (Object)(object)EnvMan.instance == (Object)null)
			{
				return -1.0;
			}
			double num = EnvMan.instance.m_dayLengthSec;
			double num2 = targetHour - currentGameHour;
			if (num2 < 0.0)
			{
				num2 += 24.0;
			}
			return num2 / 24.0 * num;
		}
	}
}
namespace Better_Farming.Pollination
{
	public class PollinatablePlant : MonoBehaviour
	{
	}
	public static class PollinationMod
	{
		public static void ApplyPatches(Harmony harmony)
		{
			harmony.PatchAll(typeof(Plant_GrowTime_Patch));
			harmony.PatchAll(typeof(Beehive_GetTime_Patch));
			Plugin.Log.LogInfo((object)"[Pollination] Patches de polinização aplicados com sucesso!");
		}
	}
	[HarmonyPatch(typeof(Plant), "GetGrowTime")]
	public static class Plant_GrowTime_Patch
	{
		private const float RANGE = 25f;

		private static void Postfix(Plant __instance, ref float __result)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)((Component)__instance).GetComponent<PollinatablePlant>() == (Object)null)
			{
				return;
			}
			Collider[] array = Physics.OverlapSphere(((Component)__instance).transform.position, 25f);
			for (int i = 0; i < array.Length; i++)
			{
				if ((Object)(object)((Component)array[i]).GetComponent<Beehive>() != (Object)null)
				{
					__result *= 0.75f;
					Plugin.Log.LogInfo((object)$"[Pollination] Colmeia encontrada! Tempo de {((Object)((Component)__instance).gameObject).name} reduzido para {__result}s");
					break;
				}
			}
		}
	}
	[HarmonyPatch(typeof(Beehive), "GetTimeSinceLastUpdate")]
	public static class Beehive_GetTime_Patch
	{
		private const float RANGE = 25f;

		private const float BONUS_PER_PLANT = 0.02f;

		private const int MAX_PLANTS = 25;

		private static void Postfix(Beehive __instance, ref float __result)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			Collider[] array = Physics.OverlapSphere(((Component)__instance).transform.position, 25f);
			int num = 0;
			Collider[] array2 = array;
			for (int i = 0; i < array2.Length; i++)
			{
				if ((Object)(object)((Component)array2[i]).GetComponent<PollinatablePlant>() != (Object)null)
				{
					num++;
				}
			}
			if (num > 0)
			{
				int num2 = Mathf.Min(num, 25);
				float num3 = 1f + (float)num2 * 0.02f;
				__result *= num3;
				Plugin.Log.LogInfo((object)$"[Pollination] Colmeia com {num} plantas próximas. Fator de velocidade: {num3}x");
			}
		}
	}
}
namespace Better_Farming.Mushrooms
{
	internal static class MushroomBluePiece
	{
		public static void Setup()
		{
			MushroomPlantFactory.Create(new MushroomPlantDefinition("MushroomBlue_Seedling", "Pickable_Mushroom_blue", "MushroomBlue", 1, ModConfig.DaysToSeconds(1), 1f, MushroomGrowthCondition.NeedsCold, 0f, 0f, requiresRoof: false, "Blue Mushroom", "Pickable_Mushroom_blue", "Plante um cogumelo azul.", "Blue Mushroom", "MushroomBlue"));
		}
	}
	internal static class MushroomDefinitionRegistry
	{
		private static readonly Dictionary<string, MushroomPlantDefinition> Definitions = new Dictionary<string, MushroomPlantDefinition>();

		internal static void Register(MushroomPlantDefinition def)
		{
			Definitions[def.SeedlingPrefabName] = def;
		}

		internal static bool TryGet(string seedlingPrefabName, out MushroomPlantDefinition def)
		{
			return Definitions.TryGetValue(seedlingPrefabName, out def);
		}
	}
	internal static class MushroomPiece
	{
		public static void Setup()
		{
			MushroomPlantFactory.Create(new MushroomPlantDefinition("Mushroom_Seedling", "Pickable_Mushroom", "Mushroom", 1, ModConfig.DaysToSeconds(1), 1f, MushroomGrowthCondition.OpenCover, 0f, 0.3f, requiresRoof: false, "Mushroom", "Pickable_Mushroom", "Plante um cogumelo protegido. Ele se espalha sozinho com o tempo.", "Mushroom", "Mushroom"));
		}
	}
	internal enum MushroomGrowthCondition
	{
		OpenCover,
		NeedsFire,
		NeedsCold
	}
	internal readonly struct MushroomPlantDefinition
	{
		public readonly string SeedlingPrefabName;

		public readonly string CloneSourceName;

		public readonly string RequirementItem;

		public readonly int RequirementAmount;

		public readonly float SpreadDelaySeconds;

		public readonly float SpreadRadius;

		public readonly MushroomGrowthCondition Condition;

		public readonly float ConditionCheckRadius;

		public readonly float RequiredCoverPercentage;

		public readonly bool RequiresRoof;

		public readonly string PieceName;

		public readonly string PieceDescription;

		public readonly string PlantHoverName;

		public readonly string IconItemName;

		public readonly string SeedlingVisualSourceName;

		public MushroomPlantDefinition(string seedlingPrefabName, string cloneSourceName, string requirementItem, int requirementAmount, float spreadDelaySeconds, float spreadRadius, MushroomGrowthCondition condition, float conditionCheckRadius, float requiredCoverPercentage, bool requiresRoof, string pieceName, string seedlingVisualSourceName, string pieceDescription, string plantHoverName, string iconItemName)
		{
			SeedlingPrefabName = seedlingPrefabName;
			CloneSourceName = cloneSourceName;
			RequirementItem = requirementItem;
			RequirementAmount = requirementAmount;
			SpreadDelaySeconds = spreadDelaySeconds;
			SpreadRadius = spreadRadius;
			Condition = condition;
			ConditionCheckRadius = conditionCheckRadius;
			RequiredCoverPercentage = requiredCoverPercentage;
			SeedlingVisualSourceName = seedlingVisualSourceName;
			RequiresRoof = requiresRoof;
			PieceName = pieceName;
			PieceDescription = pieceDescription;
			PlantHoverName = plantHoverName;
			IconItemName = iconItemName;
		}
	}
	internal static class MushroomPlantFactory
	{
		private static Sprite GetItemIcon(string prefabName)
		{
			GameObject prefab = PrefabManager.Instance.GetPrefab(prefabName);
			if ((Object)(object)prefab == (Object)null)
			{
				Plugin.Log.LogWarning((object)("Prefab '" + prefabName + "' não encontrado ao buscar ícone."));
				return null;
			}
			ItemDrop component = prefab.GetComponent<ItemDrop>();
			if ((Object)(object)component == (Object)null || component.m_itemData?.m_shared?.m_icons == null || component.m_itemData.m_shared.m_icons.Length == 0)
			{
				Plugin.Log.LogWarning((object)("Prefab '" + prefabName + "' não tem ícone disponível."));
				return null;
			}
			return component.m_itemData.m_shared.m_icons[0];
		}

		internal static void Create(MushroomPlantDefinition def)
		{
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Expected O, but got Unknown
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Expected O, but got Unknown
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Expected O, but got Unknown
			if ((Object)(object)PrefabManager.Instance.GetPrefab(def.RequirementItem) == (Object)null)
			{
				Plugin.Log.LogError((object)("Item de requisito '" + def.RequirementItem + "' não encontrado — abortando registro de '" + def.SeedlingPrefabName + "'."));
				return;
			}
			if ((Object)(object)PrefabManager.Instance.GetPrefab(def.CloneSourceName) == (Object)null)
			{
				Plugin.Log.LogError((object)("Prefab vanilla '" + def.CloneSourceName + "' não encontrado."));
				return;
			}
			GameObject val = PrefabManager.Instance.CreateClonedPrefab(def.SeedlingPrefabName, def.CloneSourceName);
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Log.LogError((object)("Não foi possível clonar '" + def.CloneSourceName + "' para '" + def.SeedlingPrefabName + "'."));
				return;
			}
			Pickable component = val.GetComponent<Pickable>();
			if ((Object)(object)component == (Object)null)
			{
				Plugin.Log.LogError((object)("Prefab clonado '" + def.CloneSourceName + "' não tem componente Pickable — algo mudou na estrutura vanilla."));
				return;
			}
			component.m_respawnTimeMinutes = 0f;
			component.m_hideWhenPicked = null;
			component.m_overrideName = def.PlantHoverName;
			Sprite itemIcon = GetItemIcon(def.IconItemName);
			Piece obj = val.AddComponent<Piece>();
			obj.m_name = def.PieceName;
			obj.m_description = def.PieceDescription;
			obj.m_icon = itemIcon;
			obj.m_canBeRemoved = true;
			obj.m_groundPiece = true;
			obj.m_cultivatedGroundOnly = true;
			obj.m_repairPiece = false;
			obj.m_allowedInDungeons = false;
			MushroomDefinitionRegistry.Register(def);
			val.AddComponent<MushroomSpreadMarker>().SeedlingPrefabName = def.SeedlingPrefabName;
			PieceConfig val2 = new PieceConfig();
			val2.Name = def.PieceName;
			val2.Description = def.PieceDescription;
			val2.PieceTable = "_CultivatorPieceTable";
			val2.Icon = itemIcon;
			val2.Requirements = (RequirementConfig[])(object)new RequirementConfig[1]
			{
				new RequirementConfig
				{
					Item = def.RequirementItem,
					Amount = def.RequirementAmount,
					Recover = false
				}
			};
			PieceConfig val3 = val2;
			CustomPiece val4 = new CustomPiece(val, true, val3);
			if (PieceManager.Instance.AddPiece(val4))
			{
				Plugin.Log.LogInfo((object)("'" + def.SeedlingPrefabName + "' registrado no cultivador com sucesso."));
			}
			else
			{
				Plugin.Log.LogError((object)("Falha ao registrar '" + def.SeedlingPrefabName + "' no cultivador — veja os avisos do Jotunn acima."));
			}
		}
	}
	internal static class MushroomSmokePuffPiece
	{
		public static void Setup()
		{
			MushroomPlantFactory.Create(new MushroomPlantDefinition("MushroomSmokePuff_Seedling", "Pickable_SmokePuff", "MushroomSmokePuff", 1, ModConfig.DaysToSeconds(1), 1f, MushroomGrowthCondition.NeedsFire, 5f, 0f, requiresRoof: false, "Smoke Puff", "Pickable_SmokePuff", "Onde você vai plantar isso? Precisa de Calor por perto para brotar!", "Smoke Puff Mushroom", "MushroomSmokePuff"));
		}
	}
	internal static class MushroomSpreadFactory
	{
		private static readonly Collider[] s_hits = (Collider[])(object)new Collider[30];

		private const int MaxPerSquareMeter = 6;

		private const float StackPreventionDistance = 0.3f;

		internal static bool TrySpawnNearby(MushroomPlantDefinition def, Vector3 origin)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			if (!ConditionMet(def, origin))
			{
				return false;
			}
			if (!TryFindSpot(def, origin, out var spot))
			{
				return false;
			}
			GameObject prefab = PrefabManager.Instance.GetPrefab(def.SeedlingPrefabName);
			if ((Object)(object)prefab == (Object)null)
			{
				return false;
			}
			Object.Instantiate<GameObject>(prefab, spot, Quaternion.Euler(0f, (float)Random.Range(0, 360), 0f));
			return true;
		}

		private static bool ConditionMet(MushroomPlantDefinition def, Vector3 pos)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			return def.Condition switch
			{
				MushroomGrowthCondition.OpenCover => HasEnoughCover(pos, def.RequiredCoverPercentage, def.RequiresRoof), 
				MushroomGrowthCondition.NeedsFire => HasNearbyBurningFire(pos, def.ConditionCheckRadius), 
				_ => true, 
			};
		}

		private static bool HasEnoughCover(Vector3 pos, float requiredCoverPercentage, bool requiresRoof)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			float num = default(float);
			bool flag = default(bool);
			Cover.GetCoverForPoint(pos, ref num, ref flag, 0.5f);
			if (requiresRoof && !flag)
			{
				return false;
			}
			return num >= requiredCoverPercentage;
		}

		private static bool HasNearbyBurningFire(Vector3 pos, float radius)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			int num = Physics.OverlapSphereNonAlloc(pos, radius, s_hits);
			for (int i = 0; i < num; i++)
			{
				Fireplace componentInParent = ((Component)s_hits[i]).GetComponentInParent<Fireplace>();
				if ((Object)(object)componentInParent != (Object)null && componentInParent.IsBurning())
				{
					return true;
				}
			}
			return false;
		}

		private static bool TryFindSpot(MushroomPlantDefinition def, Vector3 origin, out Vector3 spot)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: 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_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: 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_0074: Unknown result type (might be due to invalid IL or missing references)
			spot = Vector3.zero;
			float y = default(float);
			for (int i = 0; i < 8; i++)
			{
				Vector2 val = Random.insideUnitCircle * def.SpreadRadius;
				Vector3 val2 = origin + new Vector3(val.x, 0f, val.y);
				if (Heightmap.GetHeight(val2, ref y))
				{
					val2.y = y;
					Heightmap val3 = Heightmap.FindHeightmap(val2);
					if (Object.op_Implicit((Object)(object)val3) && val3.IsCultivated(val2) && HasRoomAt(val2))
					{
						spot = val2;
						return true;
					}
				}
			}
			return false;
		}

		private static bool HasRoomAt(Vector3 pos)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			int num = Physics.OverlapSphereNonAlloc(pos, 0.56f, s_hits);
			int num2 = 0;
			for (int i = 0; i < num; i++)
			{
				MushroomSpreadMarker componentInParent = ((Component)s_hits[i]).GetComponentInParent<MushroomSpreadMarker>();
				if (!((Object)(object)componentInParent == (Object)null))
				{
					if (Vector3.Distance(((Component)componentInParent).transform.position, pos) < 0.3f)
					{
						return false;
					}
					num2++;
				}
			}
			return num2 < 6;
		}
	}
	internal class MushroomSpreadMarker : MonoBehaviour
	{
		public string SeedlingPrefabName;

		private const string LastSpreadKey = "HZ_spread_last";

		private const string SpreadDelayKey = "HZ_spread_delay";

		private const float CheckIntervalSeconds = 60f;

		private ZNetView _nview;

		private void Awake()
		{
			((MonoBehaviour)this).InvokeRepeating("TrySpreadTick", Random.Range(1f, 10f), 60f);
		}

		private void TrySpreadTick()
		{
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_nview == (Object)null)
			{
				_nview = ((Component)this).GetComponent<ZNetView>();
			}
			if ((Object)(object)_nview == (Object)null || !_nview.IsValid() || _nview.GetZDO() == null || !_nview.IsOwner())
			{
				return;
			}
			if (!MushroomDefinitionRegistry.TryGet(SeedlingPrefabName, out var def))
			{
				Plugin.Log.LogWarning((object)("MushroomSpreadMarker sem definição registrada para '" + SeedlingPrefabName + "'."));
				return;
			}
			ZDO zDO = _nview.GetZDO();
			zDO.Set("HZ_spread_delay", def.SpreadDelaySeconds);
			long num = zDO.GetLong("HZ_spread_last", 0L);
			if (num == 0L)
			{
				zDO.Set("HZ_spread_last", ZNet.instance.GetTime().Ticks);
				return;
			}
			DateTime dateTime = new DateTime(num);
			if (!((ZNet.instance.GetTime() - dateTime).TotalSeconds < (double)def.SpreadDelaySeconds) && MushroomSpreadFactory.TrySpawnNearby(def, ((Component)this).transform.position))
			{
				zDO.Set("HZ_spread_last", ZNet.instance.GetTime().Ticks);
			}
		}
	}
	internal static class MushroomYellowPiece
	{
		public static void Setup()
		{
			MushroomPlantFactory.Create(new MushroomPlantDefinition("MushroomYellow_Seedling", "Pickable_Mushroom_yellow", "MushroomYellow", 1, ModConfig.DaysToSeconds(1), 1f, MushroomGrowthCondition.OpenCover, 0f, 0.9f, requiresRoof: true, "Yellow Mushroom", "Pickable_Mushroom_yellow", "Monte uma estufa! Ele não gosta de céu aberto.", "Yellow Mushroom", "MushroomYellow"));
		}
	}
}
namespace Better_Farming.Bushs
{
	internal static class BlueberryBushPiece
	{
		public static void Setup()
		{
			BushPlantFactory.Create(new BushPlantDefinition("BlueberryBush_Seedling", "sapling_turnip", "BlueberryBush", "Pukeberries", ModConfig.BlueberryPukeberriesCost.Value, ModConfig.DaysToSeconds(ModConfig.BlueberryGrowDaysMin.Value), ModConfig.DaysToSeconds(ModConfig.BlueberryGrowDaysMax.Value), (Biome)9, "Blueberry Bush", "Requires Pukeberries to plant. Takes about 9 days to grow.", "Blueberry Bush", "Blueberries", "Bush01", 0.3f, hideSourceMesh: true));
		}
	}
	[HarmonyPatch(typeof(Plant), "Grow")]
	internal static class Plant_Grow_ExtraVisual_Patch
	{
		internal static readonly Dictionary<string, string> ExtraVisualByPrefabName = new Dictionary<string, string>();

		private static void Prefix(Plant __instance, out Vector3 __state)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			__state = ((Component)__instance).transform.position;
		}

		private static void Postfix(Plant __instance, Vector3 __state)
		{
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance == (Object)null)
			{
				return;
			}
			string text = ((Object)((Component)__instance).gameObject).name.Replace("(Clone)", string.Empty).Trim();
			if (ExtraVisualByPrefabName.TryGetValue(text, out var value))
			{
				GameObject prefab = PrefabManager.Instance.GetPrefab(value);
				if ((Object)(object)prefab == (Object)null)
				{
					Plugin.Log.LogWarning((object)("Prefab visual extra '" + value + "' não encontrado ao crescer '" + text + "'."));
				}
				else
				{
					Object.Instantiate<GameObject>(prefab, __state, ((Component)__instance).transform.rotation);
				}
			}
		}
	}
	internal class BushGrowthVisual : MonoBehaviour
	{
		public float SeedlingScale;

		public float SeedlingScaleMax;

		public void SetProgress(float progress)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			progress = Mathf.Clamp01(progress);
			progress = Mathf.Floor(progress * 10f) / 10f;
			((Component)this).transform.localScale = Vector3.one * Mathf.Lerp(SeedlingScale, SeedlingScaleMax, progress);
		}
	}
	internal class BushGrowthMarker : MonoBehaviour
	{
		private Plant _plant;

		private float _timer;

		private void Awake()
		{
			_plant = ((Component)this).GetComponent<Plant>();
		}

		private void Update()
		{
			if ((Object)(object)_plant == (Object)null)
			{
				return;
			}
			ZNetView component = ((Component)_plant).GetComponent<ZNetView>();
			if (!((Object)(object)component == (Object)null) && component.IsValid() && component.GetZDO() != null)
			{
				_timer += Time.deltaTime;
				if (!(_timer < 0.5f))
				{
					_timer = 0f;
					BushPlantFactory.UpdateGrowthVisual(_plant);
				}
			}
		}
	}
	internal readonly struct BushPlantDefinition
	{
		public readonly string SeedlingPrefabName;

		public readonly string CloneSourceName;

		public readonly string GrownPrefabName;

		public readonly string RequirementItem;

		public readonly int RequirementAmount;

		public readonly float GrowTimeSeconds;

		public readonly float GrowTimeMaxSeconds;

		public readonly Biome Biome;

		public readonly string PieceName;

		public readonly string PieceDescription;

		public readonly string PlantHoverName;

		public readonly string IconItemName;

		public readonly string SeedlingVisualSourceName;

		public readonly float SeedlingScale;

		public readonly float SeedlingScaleMax;

		public readonly bool HideSourceMesh;

		public readonly string ExtraVisualPrefabName;

		public BushPlantDefinition(string seedlingPrefabName, string cloneSourceName, string grownPrefabName, string requirementItem, int requirementAmount, float growTimeSeconds, float growTimeMaxSeconds, Biome biome, string pieceName, string pieceDescription, string plantHoverName, string iconItemName, string seedlingVisualSourceName, float seedlingScale, bool hideSourceMesh, float seedlingScaleMax = 0.8f, string extraVisualPrefabName = null)
		{
			//IL_0036: 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)
			SeedlingPrefabName = seedlingPrefabName;
			CloneSourceName = cloneSourceName;
			GrownPrefabName = grownPrefabName;
			RequirementItem = requirementItem;
			RequirementAmount = requirementAmount;
			GrowTimeSeconds = growTimeSeconds;
			GrowTimeMaxSeconds = growTimeMaxSeconds;
			Biome = biome;
			PieceName = pieceName;
			PieceDescription = pieceDescription;
			PlantHoverName = plantHoverName;
			IconItemName = iconItemName;
			SeedlingVisualSourceName = seedlingVisualSourceName;
			SeedlingScale = seedlingScale;
			SeedlingScaleMax = seedlingScaleMax;
			HideSourceMesh = hideSourceMesh;
			ExtraVisualPrefabName = extraVisualPrefabName;
		}
	}
	internal static class BushPlantFactory
	{
		private static readonly BindingFlags PrivateInstance = BindingFlags.Instance | BindingFlags.NonPublic;

		private static readonly MethodInfo TimeSincePlantedMethod = typeof(Plant).GetMethod("TimeSincePlanted", PrivateInstance);

		private static readonly MethodInfo GetGrowTimeMethod = typeof(Plant).GetMethod("GetGrowTime", PrivateInstance);

		internal static void UpdateGrowthVisual(Plant plant)
		{
			if ((Object)(object)plant == (Object)null)
			{
				return;
			}
			double num = (double)TimeSincePlantedMethod.Invoke(plant, null);
			float num2 = (float)GetGrowTimeMethod.Invoke(plant, null);
			float progress = Mathf.Clamp01((float)(num / (double)num2));
			string[] array = new string[4] { "m_healthy", "m_unhealthy", "m_healthyGrown", "m_unhealthyGrown" };
			foreach (string fieldName in array)
			{
				GameObject plantField = GetPlantField(plant, fieldName);
				if (Object.op_Implicit((Object)(object)plantField))
				{
					BushGrowthVisual component = plantField.GetComponent<BushGrowthVisual>();
					if ((Object)(object)component != (Object)null)
					{
						component.SetProgress(progress);
					}
				}
			}
		}

		private static Sprite GetItemIcon(string prefabName)
		{
			GameObject prefab = PrefabManager.Instance.GetPrefab(prefabName);
			if ((Object)(object)prefab == (Object)null)
			{
				Plugin.Log.LogWarning((object)("Prefab '" + prefabName + "' não encontrado ao buscar ícone."));
				return null;
			}
			ItemDrop component = prefab.GetComponent<ItemDrop>();
			if ((Object)(object)component == (Object)null || component.m_itemData?.m_shared?.m_icons == null || component.m_itemData.m_shared.m_icons.Length == 0)
			{
				Plugin.Log.LogWarning((object)("Prefab '" + prefabName + "' não tem ícone disponível em m_shared.m_icons."));
				return null;
			}
			return component.m_itemData.m_shared.m_icons[0];
		}

		private static GameObject GetPlantField(Plant plant, string fieldName)
		{
			FieldInfo field = typeof(Plant).GetField(fieldName, PrivateInstance);
			if (field == null)
			{
				Plugin.Log.LogWarning((object)("Campo '" + fieldName + "' não encontrado em Plant (API pode ter mudado)."));
				return null;
			}
			object? value = field.GetValue(plant);
			return (GameObject)((value is GameObject) ? value : null);
		}

		private static Transform ResolveVisualSource(GameObject prefab)
		{
			Transform val = prefab.transform.Find("model");
			if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).GetComponent<MeshFilter>() != (Object)null)
			{
				return val;
			}
			if ((Object)(object)prefab.GetComponent<MeshFilter>() != (Object)null)
			{
				return prefab.transform;
			}
			LODGroup componentInChildren = prefab.GetComponentInChildren<LODGroup>();
			if ((Object)(object)componentInChildren != (Object)null)
			{
				LOD[] lODs = componentInChildren.GetLODs();
				if (lODs.Length != 0 && lODs[0].renderers.Length != 0)
				{
					Renderer val2 = lODs[0].renderers[0];
					if ((Object)(object)val2 != (Object)null && (Object)(object)((Component)val2).GetComponent<MeshFilter>() != (Object)null)
					{
						return ((Component)val2).transform;
					}
				}
			}
			MeshFilter componentInChildren2 = prefab.GetComponentInChildren<MeshFilter>();
			if ((Object)(object)componentInChildren2 != (Object)null)
			{
				return ((Component)componentInChildren2).transform;
			}
			Plugin.Log.LogError((object)("Não achei nenhum MeshFilter em '" + ((Object)prefab).name + "' — visual não vai aplicar."));
			return prefab.transform;
		}

		private static void ApplyVisual(Transform source, GameObject targetGO, float seedlingScale, float seedlingScaleMax)
		{
			MeshFilter component = ((Component)source).GetComponent<MeshFilter>();
			MeshRenderer component2 = ((Component)source).GetComponent<MeshRenderer>();
			if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null)
			{
				Plugin.Log.LogError((object)("'" + ((Object)source).name + "' não tem MeshFilter/MeshRenderer — visual não aplicado."));
				return;
			}
			MeshFilter component3 = targetGO.GetComponent<MeshFilter>();
			MeshRenderer component4 = targetGO.GetComponent<MeshRenderer>();
			component3.sharedMesh = component.sharedMesh;
			((Renderer)component4).sharedMaterials = ((Renderer)component2).sharedMaterials;
			BushGrowthVisual obj = targetGO.GetComponent<BushGrowthVisual>() ?? targetGO.AddComponent<BushGrowthVisual>();
			obj.SeedlingScale = seedlingScale;
			obj.SeedlingScaleMax = seedlingScaleMax;
			obj.SetProgress(0f);
		}

		private static void StripSourceMesh(GameObject clonedPrefab, params GameObject[] keepTargets)
		{
			MeshRenderer[] componentsInChildren = clonedPrefab.GetComponentsInChildren<MeshRenderer>(true);
			foreach (MeshRenderer val in componentsInChildren)
			{
				bool flag = false;
				foreach (GameObject val2 in keepTargets)
				{
					if ((Object)(object)val2 != (Object)null && (Object)(object)((Component)val).gameObject == (Object)(object)val2)
					{
						flag = true;
						break;
					}
				}
				if (!flag)
				{
					MeshFilter component = ((Component)val).GetComponent<MeshFilter>();
					if ((Object)(object)component != (Object)null)
					{
						component.sharedMesh = null;
					}
					((Renderer)val).enabled = false;
				}
			}
		}

		internal static void Create(BushPlantDefinition def)
		{
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ad: Expected O, but got Unknown
			//IL_02e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0303: Unknown result type (might be due to invalid IL or missing references)
			//IL_030b: Expected O, but got Unknown
			//IL_0318: Unknown result type (might be due to invalid IL or missing references)
			//IL_031f: Expected O, but got Unknown
			if ((Object)(object)PrefabManager.Instance.GetPrefab(def.RequirementItem) == (Object)null)
			{
				Plugin.Log.LogError((object)("Item de requisito '" + def.RequirementItem + "' não encontrado — abortando registro de '" + def.SeedlingPrefabName + "' pra evitar quebrar o HUD."));
				return;
			}
			GameObject prefab = PrefabManager.Instance.GetPrefab(def.SeedlingVisualSourceName);
			if ((Object)(object)prefab == (Object)null)
			{
				Plugin.Log.LogError((object)("Prefab '" + def.SeedlingVisualSourceName + "' (visual da muda) não encontrado — abortando registro de '" + def.SeedlingPrefabName + "'."));
				return;
			}
			GameObject prefab2 = PrefabManager.Instance.GetPrefab(def.GrownPrefabName);
			if ((Object)(object)prefab2 == (Object)null)
			{
				Plugin.Log.LogError((object)("Prefab vanilla '" + def.GrownPrefabName + "' não encontrado."));
				return;
			}
			GameObject val = PrefabManager.Instance.CreateClonedPrefab(def.SeedlingPrefabName, def.CloneSourceName);
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Log.LogError((object)("Não foi possível clonar o prefab base '" + def.CloneSourceName + "' para '" + def.SeedlingPrefabName + "'."));
				return;
			}
			Plant component = val.GetComponent<Plant>();
			if ((Object)(object)component == (Object)null)
			{
				Plugin.Log.LogError((object)("Prefab clonado '" + def.CloneSourceName + "' não tem componente Plant — algo mudou na estrutura vanilla."));
				return;
			}
			BushGrowthMarker bushGrowthMarker = default(BushGrowthMarker);
			if (!val.TryGetComponent<BushGrowthMarker>(ref bushGrowthMarker))
			{
				val.AddComponent<BushGrowthMarker>();
			}
			component.m_name = def.PlantHoverName;
			component.m_growTime = def.GrowTimeSeconds;
			component.m_growTimeMax = def.GrowTimeMaxSeconds;
			component.m_biome = def.Biome;
			component.m_needCultivatedGround = true;
			component.m_grownPrefabs = (GameObject[])(object)new GameObject[1] { prefab2 };
			Transform source = ResolveVisualSource(prefab);
			ApplyVisual(source, GetPlantField(component, "m_healthy"), def.SeedlingScale, def.SeedlingScaleMax);
			ApplyVisual(source, GetPlantField(component, "m_unhealthy"), def.SeedlingScale, def.SeedlingScaleMax);
			ApplyVisual(source, GetPlantField(component, "m_healthyGrown"), def.SeedlingScale, def.SeedlingScaleMax);
			ApplyVisual(source, GetPlantField(component, "m_unhealthyGrown"), def.SeedlingScale, def.SeedlingScaleMax);
			if (def.HideSourceMesh)
			{
				StripSourceMesh(val, GetPlantField(component, "m_healthy"), GetPlantField(component, "m_unhealthy"), GetPlantField(component, "m_healthyGrown"), GetPlantField(component, "m_unhealthyGrown"));
			}
			Sprite itemIcon = GetItemIcon(def.IconItemName);
			PieceConfig val2 = new PieceConfig();
			val2.Name = def.PieceName;
			val2.Description = def.PieceDescription;
			val2.PieceTable = "_CultivatorPieceTable";
			val2.Icon = itemIcon;
			val2.Requirements = (RequirementConfig[])(object)new RequirementConfig[1]
			{
				new RequirementConfig
				{
					Item = def.RequirementItem,
					Amount = def.RequirementAmount,
					Recover = false
				}
			};
			PieceConfig val3 = val2;
			CustomPiece val4 = new CustomPiece(val, true, val3);
			if (PieceManager.Instance.AddPiece(val4))
			{
				Plugin.Log.LogInfo((object)("'" + def.SeedlingPrefabName + "' registrado no cultivador com sucesso."));
			}
			else
			{
				Plugin.Log.LogError((object)("Falha ao registrar '" + def.SeedlingPrefabName + "' no cultivador — veja os avisos do Jotunn acima."));
			}
		}
	}
	internal static class CloudberryPiece
	{
		public static void Setup()
		{
			BushPlantFactory.Create(new BushPlantDefinition("CloudberryBush_Seedling", "sapling_turnip", "CloudberryBush", "Cloudberry", ModConfig.CloudberryCost.Value, ModConfig.DaysToSeconds(ModConfig.CloudberryGrowDaysMin.Value), ModConfig.DaysToSeconds(ModConfig.CloudberryGrowDaysMax.Value), (Biome)25, "Cloudberry Bush", "Requires Cloudberries to plant.", "Cloudberry Bush", "Cloudberry", "CloudberryBush", 1.25f, hideSourceMesh: true, 2f));
		}
	}
	internal static class RaspberryBushPiece
	{
		public static void Setup()
		{
			BushPlantFactory.Create(new BushPlantDefinition("RaspberryBush_Seedling", "sapling_turnip", "RaspberryBush", "Raspberry", ModConfig.RaspberryCost.Value, ModConfig.DaysToSeconds(ModConfig.RaspberryGrowDaysMin.Value), ModConfig.DaysToSeconds(ModConfig.RaspberryGrowDaysMax.Value), (Biome)1, "Raspberry Bush", "Requires Raspberries to plant. Takes about 7 days to grow.", "Raspberry Bush", "Raspberry", "Bush01", 0.3f, hideSourceMesh: true));
		}
	}
	internal static class ThistlePiece
	{
		public static void Setup()
		{
			if ((Object)(object)ThistlePrefabBuilder.Build() == (Object)null)
			{
				Plugin.Log.LogError((object)"Abortando registro de Thistle_Seedling — prefab de Thistle plantável não foi construído.");
				return;
			}
			BushPlantFactory.Create(new BushPlantDefinition("Thistle_Seedling", "sapling_turnip", "BetterFarming_Thistle_Plantable", "Thistle", 1, ModConfig.DaysToSeconds(ModConfig.ThistleGrowDaysMin.Value), ModConfig.DaysToSeconds(ModConfig.ThistleGrowDaysMax.Value), (Biome)25, "Thistle Plant", "Requires a Thistle to plant. Does not regrow after harvest. Only sprouts in the dead of night.", "Thistle Plant", "Thistle", "Pickable_Thistle", 0.2f, hideSourceMesh: true, 0.35f));
			GameObject prefab = PrefabManager.Instance.GetPrefab("Thistle_Seedling");
			if ((Object)(object)prefab != (Object)null && !Object.op_Implicit((Object)(object)prefab.GetComponent<WitchingHourGate>()))
			{
				prefab.AddComponent<WitchingHourGate>();
			}
			else if ((Object)(object)prefab == (Object)null)
			{
				Plugin.Log.LogError((object)"Thistle_Seedling não encontrado após o registro — WitchingHourGate não foi anexado.");
			}
		}
	}
	internal static class ThistlePrefabBuilder
	{
		internal const string PrefabName = "BetterFarming_Thistle_Plantable";

		internal static GameObject Build()
		{
			GameObject prefab = PrefabManager.Instance.GetPrefab("BetterFarming_Thistle_Plantable");
			if ((Object)(object)prefab != (Object)null)
			{
				return prefab;
			}
			GameObject prefab2 = PrefabManager.Instance.GetPrefab("Pickable_Thistle");
			if ((Object)(object)prefab2 == (Object)null)
			{
				Plugin.Log.LogError((object)"Prefab vanilla 'Pickable_Thistle' não encontrado.");
				return null;
			}
			GameObject val = PrefabManager.Instance.CreateClonedPrefab("BetterFarming_Thistle_Plantable", prefab2);
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Log.LogError((object)"Falha ao clonar 'Pickable_Thistle' para o Thistle plantável.");
				return null;
			}
			Pickable component = val.GetComponent<Pickable>();
			if ((Object)(object)component == (Object)null)
			{
				Plugin.Log.LogError((object)"'Pickable_Thistle' clonado não tem componente Pickable — algo mudou na estrutura vanilla.");
				return null;
			}
			component.m_amount = 2;
			component.m_respawnTimeMinutes = 0f;
			component.m_hideWhenPicked = null;
			return val;
		}
	}
	internal class WitchingHourGate : MonoBehaviour
	{
		public const double StartHour = 0.0;

		public const double EndHour = 3.0;

		private const string GateFlagZdoKey = "HZ_witch_gate";

		private void Awake()
		{
			ZNetView component = ((Component)this).GetComponent<ZNetView>();
			if ((Object)(object)component != (Object)null && component.IsValid())
			{
				component.GetZDO().Set("HZ_witch_gate", true);
			}
		}
	}
	[HarmonyPatch(typeof(Plant), "Grow")]
	internal static class WitchingHourGrowPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(Plant __instance)
		{
			if ((Object)(object)((Component)__instance).GetComponent<WitchingHourGate>() == (Object)null)
			{
				return true;
			}
			return GameClock.IsWithinHourWindow(0.0, 3.0);
		}
	}
}
namespace Better_Farming.Bushs.Fiddlehead
{
	internal class FernPickableHoverProxy : MonoBehaviour, Hoverable
	{
		private Pickable m_pickable;

		public void SetPickable(Pickable pickable)
		{
			m_pickable = pickable;
		}

		public string GetHoverName()
		{
			if (!((Object)(object)m_pickable != (Object)null))
			{
				return "";
			}
			return m_pickable.GetHoverName();
		}

		public string GetHoverText()
		{
			if (!((Object)(object)m_pickable != (Object)null))
			{
				return "";
			}
			return m_pickable.GetHoverText();
		}
	}
	internal static class FiddleHeadPiece
	{
		public static void Setup()
		{
			if ((Object)(object)FiddleheadPrefabBuilder.Build() == (Object)null)
			{
				Plugin.Log.LogError((object)"Abortando registro de FiddleheadBush_Seedling — FiddleheadPlant não foi construído.");
			}
			else
			{
				BushPlantFactory.Create(new BushPlantDefinition("FiddleheadBush_Seedling", "sapling_carrot", "FiddleheadPlant", "Fiddleheadfern", ModConfig.FiddleHeadCost.Value, ModConfig.DaysToSeconds(ModConfig.FiddleHeadGrowDaysMin.Value), ModConfig.DaysToSeconds(ModConfig.FiddleHeadGrowDaysMax.Value), (Biome)25, "Fiddlehead Bush", "Requires Fiddleheads to plant.", "Fiddlehead Bush", "Fiddleheadfern", "FernAshlands", 0.7f, hideSourceMesh: true));
			}
		}
	}
	internal class FiddleheadPlantController : MonoBehaviour
	{
		[SerializeField]
		private GameObject m_fern;

		[SerializeField]
		private Pickable m_pickable;

		private GameObject m_pickableGO;

		private ZNetView m_pickableView;

		private void Awake()
		{
			if (!Object.op_Implicit((Object)(object)m_fern))
			{
				m_fern = ((Component)this).gameObject;
			}
			if (!Object.op_Implicit((Object)(object)m_pickable))
			{
				m_pickable = ((Component)this).GetComponentInChildren<Pickable>(true);
			}
			if ((Object)(object)m_pickable != (Object)null)
			{
				m_pickableGO = ((Component)m_pickable).gameObject;
				m_pickableView = m_pickableGO.GetComponent<ZNetView>();
				(((Component)this).gameObject.GetComponent<FernPickableHoverProxy>() ?? ((Component)this).gameObject.AddComponent<FernPickableHoverProxy>()).SetPickable(m_pickable);
			}
		}

		private void OnDestroy()
		{
			if (!((Object)(object)m_pickableGO == (Object)null))
			{
				if ((Object)(object)m_pickableView != (Object)null && m_pickableView.IsValid() && (Object)(object)ZNetScene.instance != (Object)null)
				{
					ZNetScene.instance.Destroy(m_pickableGO);
				}
				else if ((Object)(object)m_pickableGO != (Object)null)
				{
					Object.Destroy((Object)(object)m_pickableGO);
				}
			}
		}
	}
	internal static class FiddleheadPrefabBuilder
	{
		internal const string PrefabName = "FiddleheadPlant";

		internal static GameObject Build()
		{
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: 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)
			GameObject prefab = PrefabManager.Instance.GetPrefab("FiddleheadPlant");
			if ((Object)(object)prefab != (Object)null)
			{
				return prefab;
			}
			GameObject prefab2 = PrefabManager.Instance.GetPrefab("FernAshlands");
			if ((Object)(object)prefab2 == (Object)null)
			{
				Plugin.Log.LogError((object)"FernAshlands não encontrado — abortando build do FiddleheadPlant.");
				return null;
			}
			GameObject prefab3 = PrefabManager.Instance.GetPrefab("Pickable_Fiddlehead");
			if ((Object)(object)prefab3 == (Object)null)
			{
				Plugin.Log.LogError((object)"Pickable_Fiddlehead não encontrado — abortando build do FiddleheadPlant.");
				return null;
			}
			GameObject val = PrefabManager.Instance.CreateClonedPrefab("FiddleheadPlant", prefab2);
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Log.LogError((object)"Falha ao clonar FernAshlands para FiddleheadPlant.");
				return null;
			}
			GameObject obj = Object.Instantiate<GameObject>(prefab3, val.transform);
			((Object)obj).name = "Pickable_Fiddlehead";
			obj.transform.localPosition = Vector3.zero;
			obj.transform.localRotation = Quaternion.identity;
			obj.transform.localScale = Vector3.one;
			val.AddComponent<FiddleheadPlantController>();
			val.AddComponent<FiddleheadRegrowthModifier>();
			Plugin.Log.LogInfo((object)"FiddleheadPlant construído com sucesso (Fern + Pickable + modificadores de regrowth).");
			return val;
		}
	}
	internal class FiddleheadRegrowthModifier : MonoBehaviour
	{
		private const float CheckIntervalSec = 5f;

		private const float Radius = 5f;

		private const float FireReductionPct = 0.25f;

		private const float StoneReductionPct = 0.25f;

		private const string FireFlagZdoKey = "HZ_fh_fire";

		private const string StoneFlagZdoKey = "HZ_fh_stone";

		private Pickable m_pickable;

		private ZNetView m_pickableView;

		private float m_baseRespawnMinutes = -1f;

		private void Awake()
		{
			m_pickable = ((Component)this).GetComponentInChildren<Pickable>(true);
			if ((Object)(object)m_pickable == (Object)null)
			{
				Plugin.Log.LogWarning((object)"FiddleheadRegrowthModifier sem Pickable filho — desativando.");
				((Behaviour)this).enabled = false;
			}
			else
			{
				m_pickableView = ((Component)m_pickable).GetComponent<ZNetView>();
				m_baseRespawnMinutes = m_pickable.m_respawnTimeMinutes;
				((MonoBehaviour)this).StartCoroutine(CheckLoop());
			}
		}

		private IEnumerator CheckLoop()
		{
			WaitForSeconds wait = new WaitForSeconds(5f);
			while (true)
			{
				Recalculate();
				yield return wait;
			}
		}

		private void Recalculate()
		{
			if (!((Object)(object)m_pickable == (Object)null) && !(m_baseRespawnMinutes < 0f))
			{
				bool flag = HasNearbyFire();
				bool flag2 = HasNearbyGreyStone();
				float num = 0f;
				if (flag)
				{
					num += 0.25f;
				}
				if (flag2)
				{
					num += 0.25f;
				}
				num = Mathf.Clamp01(num);
				m_pickable.m_respawnTimeMinutes = m_baseRespawnMinutes * (1f - num);
				if ((Object)(object)m_pickableView != (Object)null && m_pickableView.IsValid())
				{
					ZDO zDO = m_pickableView.GetZDO();
					zDO.Set("HZ_fh_fire", flag);
					zDO.Set("HZ_fh_stone", flag2);
				}
			}
		}

		private bool HasNearbyFire()
		{
			//IL_0006: 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)
			Collider[] array = Physics.OverlapSphere(((Component)this).transform.position, 5f);
			for (int i = 0; i < array.Length; i++)
			{
				EffectArea componentInParent = ((Component)array[i]).GetComponentInParent<EffectArea>();
				if ((Object)(object)componentInParent != (Object)null && ((Enum)componentInParent.m_type).HasFlag((Enum)(object)(Type)2))
				{
					return true;
				}
			}
			return false;
		}

		private bool HasNearbyGreyStone()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Invalid comparison between Unknown and I4
			Collider[] array = Physics.OverlapSphere(((Component)this).transform.position, 5f);
			for (int i = 0; i < array.Length; i++)
			{
				WearNTear componentInParent = ((Component)array[i]).GetComponentInParent<WearNTear>();
				if (!((Object)(object)componentInParent == (Object)null))
				{
					if (((Object)((Component)componentInParent).gameObject).name.IndexOf("grausten", StringComparison.OrdinalIgnoreCase) >= 0)
					{
						return true;
					}
					if ((int)componentInParent.m_materialType == 1)
					{
						return true;
					}
				}
			}
			return false;
		}
	}
}
namespace Better_Farming.AreaHarvest
{
	[HarmonyPatch(typeof(Pickable), "Interact")]
	internal static class AreaHarvestPatch
	{
		private const float Radius = 1f;

		private static bool s_inAreaHarvest;

		[HarmonyPostfix]
		private static void Postfix(Pickable __instance, Humanoid character, bool repeat, bool alt, bool __result)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if (!__result || repeat || s_inAreaHarvest || !Input.GetKey((KeyCode)304))
			{
				return;
			}
			s_inAreaHarvest = true;
			try
			{
				Collider[] array = Physics.OverlapSphere(((Component)__instance).transform.position, 1f);
				HashSet<Pickable> hashSet = new HashSet<Pickable>();
				Collider[] array2 = array;
				for (int i = 0; i < array2.Length; i++)
				{
					Pickable componentInParent = ((Component)array2[i]).GetComponentInParent<Pickable>();
					if (!((Object)(object)componentInParent == (Object)null) && !((Object)(object)componentInParent == (Object)(object)__instance) && hashSet.Add(componentInParent) && !componentInParent.GetPicked())
					{
						componentInParent.Interact(character, false, alt);
					}
				}
			}
			finally
			{
				s_inAreaHarvest = false;
			}
		}
	}
}