Decompiled source of FreyjasFeeder v1.0.0

FreyjasFeeder.dll

Decompiled 3 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering;

[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("FreyjasFeeder")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+901b84ab23f2f10926b13865f9b40bb283490874")]
[assembly: AssemblyProduct("FreyjasFeeder")]
[assembly: AssemblyTitle("FreyjasFeeder")]
[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 FreyjasFeeder
{
	public static class FeederSettings
	{
		public static ConfigEntry<bool> Enabled { get; private set; }

		public static ConfigEntry<float> FeedRange { get; private set; }

		public static ConfigEntry<float> FeedInterval { get; private set; }

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

		public static ConfigEntry<bool> FeedTamed { get; private set; }

		public static ConfigEntry<bool> HealInjuredPets { get; private set; }

		public static ConfigEntry<float> HealAmount { get; private set; }

		public static ConfigEntry<float> HealCooldown { get; private set; }

		public static ConfigEntry<bool> PreventOvercrowding { get; private set; }

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

		public static ConfigEntry<bool> FeedUntamed { get; private set; }

		public static ConfigEntry<bool> FeedUntamedWhenAlerted { get; private set; }

		public static ConfigEntry<bool> PreventNightDespawn { get; private set; }

		public static ConfigEntry<float> TamingSpeedMultiplier { get; private set; }

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

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

		public static ConfigEntry<bool> PullFromNearbyChests { get; private set; }

		public static ConfigEntry<bool> EnableAnyChestFeeding { get; private set; }

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

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

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

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

		public static ConfigEntry<string> ModelFile { get; private set; }

		public static ConfigEntry<float> ModelScale { get; private set; }

		public static ConfigEntry<float> ModelRotationY { get; private set; }

		public static ConfigEntry<float> ModelOffsetX { get; private set; }

		public static ConfigEntry<float> ModelOffsetY { get; private set; }

		public static ConfigEntry<float> ModelOffsetZ { get; private set; }

		public static void Bind(ConfigFile config)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Expected O, but got Unknown
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Expected O, but got Unknown
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Expected O, but got Unknown
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Expected O, but got Unknown
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Expected O, but got Unknown
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Expected O, but got Unknown
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Expected O, but got Unknown
			//IL_0279: Unknown result type (might be due to invalid IL or missing references)
			//IL_0283: Expected O, but got Unknown
			//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e7: Expected O, but got Unknown
			//IL_030a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0314: Expected O, but got Unknown
			//IL_0337: Unknown result type (might be due to invalid IL or missing references)
			//IL_0341: Expected O, but got Unknown
			//IL_0364: Unknown result type (might be due to invalid IL or missing references)
			//IL_036e: Expected O, but got Unknown
			//IL_03bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c5: Expected O, but got Unknown
			//IL_03f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fd: Expected O, but got Unknown
			Enabled = config.Bind<bool>("1 - General", "Enabled", true, "Master toggle for Freyja's Feeder mod.");
			FeedRange = config.Bind<float>("1 - General", "FeedRange", 15f, new ConfigDescription("Radius in meters around the feeder to detect hungry animals.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(3f, 50f), Array.Empty<object>()));
			FeedInterval = config.Bind<float>("1 - General", "FeedInterval", 5f, new ConfigDescription("How often (in seconds) the feeder scans for hungry animals.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 60f), Array.Empty<object>()));
			MaxFeedsPerCycle = config.Bind<int>("1 - General", "MaxFeedsPerCycle", 4, new ConfigDescription("Maximum number of animals fed in a single scan cycle.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 20), Array.Empty<object>()));
			FeedTamed = config.Bind<bool>("2 - Tamed Pets", "FeedTamed", true, "Automatically feed nearby tamed pets when hungry, keeping them happy and ready for breeding.");
			HealInjuredPets = config.Bind<bool>("2 - Tamed Pets", "HealInjuredPets", true, "Feed injured tamed pets to restore their health, even if they are not yet fully hungry.");
			HealAmount = config.Bind<float>("2 - Tamed Pets", "HealAmount", 25f, new ConfigDescription("Health points restored to an injured pet upon eating.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 200f), Array.Empty<object>()));
			HealCooldown = config.Bind<float>("2 - Tamed Pets", "HealCooldown", 20f, new ConfigDescription("Minimum seconds between healing feeds for the same pet to prevent rapid food waste.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 300f), Array.Empty<object>()));
			PreventOvercrowding = config.Bind<bool>("2 - Tamed Pets", "PreventOvercrowding", false, "If true, stops feeding tamed animals when the nearby population of that species reaches MaxCreaturesLimit.");
			MaxCreaturesLimit = config.Bind<int>("2 - Tamed Pets", "MaxCreaturesLimit", 10, new ConfigDescription("Population limit for PreventOvercrowding check.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(2, 50), Array.Empty<object>()));
			FeedUntamed = config.Bind<bool>("3 - Taming Untamed", "FeedUntamed", true, "Automatically feed untamed wild beasts (boars, wolves, lox, asksvin) to tame them.");
			FeedUntamedWhenAlerted = config.Bind<bool>("3 - Taming Untamed", "FeedUntamedWhenAlerted", false, "If true, feeds untamed beasts even while alerted/frightened. If false, respects vanilla behavior where animals must calm down first.");
			PreventNightDespawn = config.Bind<bool>("3 - Taming Untamed", "PreventNightDespawn", true, "Prevent night-spawned creatures (e.g. 2-star wolves) from despawning during the day once they have eaten from the feeder.");
			TamingSpeedMultiplier = config.Bind<float>("3 - Taming Untamed", "TamingSpeedMultiplier", 1f, new ConfigDescription("Multiplier for taming progression speed while within range of Freyja's Feeder (1.0 = vanilla).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 5f), Array.Empty<object>()));
			ContainerWidth = config.Bind<int>("4 - Storage", "ContainerWidth", 6, new ConfigDescription("Number of inventory slot columns for Freyja's Feeder (default 6).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(2, 8), Array.Empty<object>()));
			ContainerHeight = config.Bind<int>("4 - Storage", "ContainerHeight", 4, new ConfigDescription("Number of inventory slot rows for Freyja's Feeder (default 4 = 24 slots).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(2, 4), Array.Empty<object>()));
			PullFromNearbyChests = config.Bind<bool>("4 - Storage", "PullFromNearbyChests", false, "If true, Freyja's Feeder will also search nearby standard chests (within FeedRange) for matching food if its own inventory runs out.");
			EnableAnyChestFeeding = config.Bind<bool>("4 - Storage", "EnableAnyChestFeeding", false, "If true, any standard chest in the world will also feed nearby hungry animals within FeedRange.");
			WoodCost = config.Bind<int>("5 - Crafting", "WoodCost", 10, new ConfigDescription("Wood cost to build Freyja's Feeder.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
			FineWoodCost = config.Bind<int>("5 - Crafting", "FineWoodCost", 5, new ConfigDescription("Fine Wood cost to build Freyja's Feeder.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
			BronzeCost = config.Bind<int>("5 - Crafting", "BronzeCost", 2, new ConfigDescription("Bronze cost to build Freyja's Feeder.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 50), Array.Empty<object>()));
			DandelionCost = config.Bind<int>("5 - Crafting", "DandelionCost", 2, new ConfigDescription("Dandelion offering cost to build Freyja's Feeder.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 50), Array.Empty<object>()));
			ModelFile = config.Bind<string>("6 - Visuals", "ModelFile", "FreyjasFeeder.obj", "Filename of custom 3D model for Freyja's Feeder. Set to 'none' to use vanilla chest visuals.");
			ModelScale = config.Bind<float>("6 - Visuals", "ModelScale", 1f, new ConfigDescription("Uniform scale of custom 3D model.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 5f), Array.Empty<object>()));
			ModelRotationY = config.Bind<float>("6 - Visuals", "ModelRotationY", 0f, new ConfigDescription("Y rotation offset in degrees.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-180f, 180f), Array.Empty<object>()));
			ModelOffsetX = config.Bind<float>("6 - Visuals", "ModelOffsetX", 0f, "X position offset in meters.");
			ModelOffsetY = config.Bind<float>("6 - Visuals", "ModelOffsetY", 0f, "Y position offset in meters.");
			ModelOffsetZ = config.Bind<float>("6 - Visuals", "ModelOffsetZ", 0f, "Z position offset in meters.");
		}
	}
	[HarmonyPatch(typeof(Container), "Awake")]
	internal static class ContainerAwakePatch
	{
		private static void Postfix(Container __instance)
		{
			if ((Object)(object)__instance != (Object)null)
			{
				ContainerTracker.Register(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(Container), "OnDestroyed")]
	internal static class ContainerOnDestroyedPatch
	{
		private static void Prefix(Container __instance)
		{
			if ((Object)(object)__instance != (Object)null)
			{
				ContainerTracker.Unregister(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(Container), "GetHoverText")]
	internal static class ContainerHoverTextPatch
	{
		private static void Postfix(Container __instance, ref string __result)
		{
			if ((Object)(object)__instance == (Object)null || !FeederSettings.Enabled.Value)
			{
				return;
			}
			FeederController component = ((Component)__instance).GetComponent<FeederController>();
			if (!((Object)(object)component == (Object)null))
			{
				string statusSummary = component.GetStatusSummary();
				if (!string.IsNullOrEmpty(statusSummary))
				{
					__result = __result + "\n" + statusSummary;
				}
			}
		}
	}
	internal static class ContainerTracker
	{
		private static readonly HashSet<Container> s_containers = new HashSet<Container>();

		public static IEnumerable<Container> Containers => s_containers;

		public static void Register(Container container)
		{
			if ((Object)(object)container != (Object)null && !s_containers.Contains(container))
			{
				s_containers.Add(container);
			}
		}

		public static void Unregister(Container container)
		{
			if ((Object)(object)container != (Object)null)
			{
				s_containers.Remove(container);
			}
		}

		public static void Clear()
		{
			s_containers.Clear();
		}
	}
	public sealed class FeederController : MonoBehaviour
	{
		public static readonly List<FeederController> AllFeeders = new List<FeederController>();

		private static readonly List<Character> s_charBuffer = new List<Character>();

		private static readonly Dictionary<int, float> s_healCooldowns = new Dictionary<int, float>();

		private static MethodInfo s_tameMethod;

		private static float s_globalChestScanTimer;

		private Container m_container;

		private ZNetView m_nview;

		private float m_timer;

		public Container Container
		{
			get
			{
				if ((Object)(object)m_container == (Object)null)
				{
					m_container = ((Component)this).GetComponent<Container>();
				}
				return m_container;
			}
		}

		private void Awake()
		{
			m_container = ((Component)this).GetComponent<Container>();
			m_nview = ((Component)this).GetComponent<ZNetView>();
			FeederModel.EnsureVisuals(((Component)this).gameObject);
			m_timer = Random.Range(0.5f, 2f);
		}

		private void OnEnable()
		{
			if (!AllFeeders.Contains(this))
			{
				AllFeeders.Add(this);
			}
		}

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

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

		private void Update()
		{
			if (!FeederSettings.Enabled.Value)
			{
				return;
			}
			m_timer -= Time.deltaTime;
			if (!(m_timer > 0f))
			{
				m_timer = FeederSettings.FeedInterval.Value;
				if ((Object)(object)m_nview != (Object)null && m_nview.IsValid() && m_nview.IsOwner())
				{
					PerformFeedScan();
				}
			}
		}

		internal static void UpdateGlobalChests()
		{
			if (!FeederSettings.Enabled.Value || !FeederSettings.EnableAnyChestFeeding.Value)
			{
				return;
			}
			s_globalChestScanTimer -= Time.deltaTime;
			if (s_globalChestScanTimer > 0f)
			{
				return;
			}
			s_globalChestScanTimer = FeederSettings.FeedInterval.Value;
			foreach (Container container in ContainerTracker.Containers)
			{
				if (!((Object)(object)container == (Object)null) && !((Object)(object)((Component)container).GetComponent<FeederController>() != (Object)null))
				{
					ZNetView component = ((Component)container).GetComponent<ZNetView>();
					if (!((Object)(object)component == (Object)null) && component.IsValid() && component.IsOwner())
					{
						ScanAndFeedFromContainer(container);
					}
				}
			}
		}

		private void PerformFeedScan()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)m_container == (Object)null)
			{
				return;
			}
			Inventory inventory = m_container.GetInventory();
			if (inventory == null)
			{
				return;
			}
			Vector3 position = ((Component)this).transform.position;
			float value = FeederSettings.FeedRange.Value;
			s_charBuffer.Clear();
			Character.GetCharactersInRange(position, value, s_charBuffer);
			if (s_charBuffer.Count == 0)
			{
				return;
			}
			int num = FeederSettings.MaxFeedsPerCycle.Value;
			for (int i = 0; i < s_charBuffer.Count; i++)
			{
				if (num <= 0)
				{
					break;
				}
				Character val = s_charBuffer[i];
				if ((Object)(object)val == (Object)null || val.IsDead())
				{
					continue;
				}
				Tameable component = ((Component)val).GetComponent<Tameable>();
				if ((Object)(object)component == (Object)null)
				{
					continue;
				}
				MonsterAI component2 = ((Component)val).GetComponent<MonsterAI>();
				if ((Object)(object)component2 == (Object)null || component2.m_consumeItems == null || component2.m_consumeItems.Count == 0)
				{
					continue;
				}
				if (component.IsTamed())
				{
					if (FeederSettings.FeedTamed.Value)
					{
						bool num2 = component.IsHungry();
						bool flag = val.GetHealth() < val.GetMaxHealth() && FeederSettings.HealInjuredPets.Value && CanHealCreature(val);
						if ((num2 || flag) && (!FeederSettings.PreventOvercrowding.Value || !IsOvercrowded(val, position, value)) && TryFeedCreature(val, component, component2, inventory, isTamed: true, flag))
						{
							num--;
						}
					}
				}
				else if (FeederSettings.FeedUntamed.Value && component.IsHungry() && (!((BaseAI)component2).IsAlerted() || FeederSettings.FeedUntamedWhenAlerted.Value) && TryFeedCreature(val, component, component2, inventory, isTamed: false, isHealing: false))
				{
					num--;
				}
			}
		}

		private static void ScanAndFeedFromContainer(Container container)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			Inventory inventory = container.GetInventory();
			if (inventory == null)
			{
				return;
			}
			Vector3 position = ((Component)container).transform.position;
			float value = FeederSettings.FeedRange.Value;
			s_charBuffer.Clear();
			Character.GetCharactersInRange(position, value, s_charBuffer);
			if (s_charBuffer.Count == 0)
			{
				return;
			}
			int num = FeederSettings.MaxFeedsPerCycle.Value;
			for (int i = 0; i < s_charBuffer.Count; i++)
			{
				if (num <= 0)
				{
					break;
				}
				Character val = s_charBuffer[i];
				if ((Object)(object)val == (Object)null || val.IsDead())
				{
					continue;
				}
				Tameable component = ((Component)val).GetComponent<Tameable>();
				if ((Object)(object)component == (Object)null)
				{
					continue;
				}
				MonsterAI component2 = ((Component)val).GetComponent<MonsterAI>();
				if ((Object)(object)component2 == (Object)null || component2.m_consumeItems == null || component2.m_consumeItems.Count == 0)
				{
					continue;
				}
				if (component.IsTamed())
				{
					if (FeederSettings.FeedTamed.Value)
					{
						bool num2 = component.IsHungry();
						bool flag = val.GetHealth() < val.GetMaxHealth() && FeederSettings.HealInjuredPets.Value && CanHealCreature(val);
						if ((num2 || flag) && (!FeederSettings.PreventOvercrowding.Value || !IsOvercrowded(val, position, value)) && ExecuteFeed(val, component, component2, inventory, isTamed: true, flag))
						{
							num--;
						}
					}
				}
				else if (FeederSettings.FeedUntamed.Value && component.IsHungry() && (!((BaseAI)component2).IsAlerted() || FeederSettings.FeedUntamedWhenAlerted.Value) && ExecuteFeed(val, component, component2, inventory, isTamed: false, isHealing: false))
				{
					num--;
				}
			}
		}

		private bool TryFeedCreature(Character ch, Tameable tameable, MonsterAI ai, Inventory feederInv, bool isTamed, bool isHealing)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			ItemData val = FindMatchingFood(ai, feederInv);
			Inventory foundInv = feederInv;
			if (val == null && FeederSettings.PullFromNearbyChests.Value)
			{
				val = FindMatchingFoodInNearbyChests(ai, ((Component)this).transform.position, FeederSettings.FeedRange.Value, out foundInv);
			}
			if (val == null || foundInv == null)
			{
				return false;
			}
			return ApplyFeed(ch, tameable, ai, foundInv, val, isTamed, isHealing);
		}

		private static bool ExecuteFeed(Character ch, Tameable tameable, MonsterAI ai, Inventory inv, bool isTamed, bool isHealing)
		{
			ItemData val = FindMatchingFood(ai, inv);
			if (val == null)
			{
				return false;
			}
			return ApplyFeed(ch, tameable, ai, inv, val, isTamed, isHealing);
		}

		private static bool ApplyFeed(Character ch, Tameable tameable, MonsterAI ai, Inventory sourceInv, ItemData foodItem, bool isTamed, bool isHealing)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: 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_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: 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)
			sourceInv.RemoveOneItem(foodItem);
			ZNetView component = ((Component)ch).GetComponent<ZNetView>();
			if ((Object)(object)component != (Object)null && component.IsValid())
			{
				if (!component.IsOwner())
				{
					component.ClaimOwnership();
				}
				component.GetZDO().Set(ZDOVars.s_tameLastFeeding, ZNet.instance.GetTime().Ticks);
			}
			if (tameable.m_sootheEffect != null)
			{
				tameable.m_sootheEffect.Create(ch.GetCenterPoint(), Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID));
			}
			Humanoid val = (Humanoid)(object)((ch is Humanoid) ? ch : null);
			if ((Object)(object)val != (Object)null && val.m_consumeItemEffects != null)
			{
				val.m_consumeItemEffects.Create(((Component)ch).transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID));
			}
			ZSyncAnimation zAnim = ch.GetZAnim();
			if ((Object)(object)zAnim != (Object)null)
			{
				zAnim.SetTrigger("consume");
			}
			if (isTamed)
			{
				if (isHealing)
				{
					float maxHealth = ch.GetMaxHealth();
					float health = ch.GetHealth();
					float num = Mathf.Min(FeederSettings.HealAmount.Value, maxHealth - health);
					if (num > 0f)
					{
						ch.Heal(num, true);
						s_healCooldowns[((Object)ch).GetInstanceID()] = Time.time;
					}
				}
			}
			else
			{
				if (FeederSettings.PreventNightDespawn.Value)
				{
					ai.SetDespawnInDay(false);
					ai.SetEventCreature(false);
				}
				float value = FeederSettings.TamingSpeedMultiplier.Value;
				if (value > 1f && (Object)(object)component != (Object)null && component.IsValid())
				{
					float num2 = 3f * (value - 1f);
					float num3 = component.GetZDO().GetFloat(ZDOVars.s_tameTimeLeft, tameable.m_tamingTime);
					num3 = Mathf.Max(0f, num3 - num2);
					component.GetZDO().Set(ZDOVars.s_tameTimeLeft, num3);
					if (num3 <= 0f)
					{
						if (s_tameMethod == null)
						{
							s_tameMethod = typeof(Tameable).GetMethod("Tame", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
						}
						s_tameMethod?.Invoke(tameable, null);
					}
				}
			}
			FreyjasFeederPlugin.Log.LogInfo((object)("Freyja's Feeder: fed " + ch.m_name + " (Tamed=" + isTamed + ", Heal=" + isHealing + ") with " + foodItem.m_shared.m_name));
			return true;
		}

		private static ItemData FindMatchingFood(MonsterAI ai, Inventory inv)
		{
			if ((Object)(object)ai == (Object)null || inv == null)
			{
				return null;
			}
			List<ItemData> allItems = inv.GetAllItems();
			for (int i = 0; i < allItems.Count; i++)
			{
				ItemData val = allItems[i];
				if (val != null && val.m_shared != null && IsFoodForAI(ai, val))
				{
					return val;
				}
			}
			return null;
		}

		private static ItemData FindMatchingFoodInNearbyChests(MonsterAI ai, Vector3 center, float range, out Inventory foundInv)
		{
			//IL_0038: 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_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			foundInv = null;
			float num = range * range;
			foreach (Container container in ContainerTracker.Containers)
			{
				if ((Object)(object)container == (Object)null || (Object)(object)((Component)container).GetComponent<FeederController>() != (Object)null)
				{
					continue;
				}
				Vector3 val = ((Component)container).transform.position - center;
				if (((Vector3)(ref val)).sqrMagnitude > num)
				{
					continue;
				}
				Inventory inventory = container.GetInventory();
				if (inventory != null)
				{
					ItemData val2 = FindMatchingFood(ai, inventory);
					if (val2 != null)
					{
						foundInv = inventory;
						return val2;
					}
				}
			}
			return null;
		}

		public static bool IsFoodForAI(MonsterAI ai, ItemData item)
		{
			if ((Object)(object)ai == (Object)null || item == null || item.m_shared == null)
			{
				return false;
			}
			if (ai.m_consumeItems != null)
			{
				for (int i = 0; i < ai.m_consumeItems.Count; i++)
				{
					ItemDrop val = ai.m_consumeItems[i];
					if ((Object)(object)val != (Object)null && val.m_itemData != null && val.m_itemData.m_shared != null && string.Equals(val.m_itemData.m_shared.m_name, item.m_shared.m_name, StringComparison.OrdinalIgnoreCase))
					{
						return true;
					}
				}
			}
			return false;
		}

		private static bool CanHealCreature(Character ch)
		{
			if ((Object)(object)ch == (Object)null)
			{
				return false;
			}
			int instanceID = ((Object)ch).GetInstanceID();
			if (s_healCooldowns.TryGetValue(instanceID, out var value) && Time.time - value < FeederSettings.HealCooldown.Value)
			{
				return false;
			}
			return true;
		}

		private static bool IsOvercrowded(Character ch, Vector3 center, float range)
		{
			string value = ((Object)((Component)ch).gameObject).name.Replace("(Clone)", "").Trim();
			int num = 0;
			for (int i = 0; i < s_charBuffer.Count; i++)
			{
				Character val = s_charBuffer[i];
				if (!((Object)(object)val == (Object)null) && !val.IsDead() && ((Object)((Component)val).gameObject).name.StartsWith(value, StringComparison.OrdinalIgnoreCase))
				{
					num++;
				}
			}
			return num >= FeederSettings.MaxCreaturesLimit.Value;
		}

		public string GetStatusSummary()
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			int num = 0;
			if ((Object)(object)m_container != (Object)null)
			{
				Inventory inventory = m_container.GetInventory();
				if (inventory != null)
				{
					List<ItemData> allItems = inventory.GetAllItems();
					for (int i = 0; i < allItems.Count; i++)
					{
						num += allItems[i].m_stack;
					}
				}
			}
			Vector3 position = ((Component)this).transform.position;
			float value = FeederSettings.FeedRange.Value;
			s_charBuffer.Clear();
			Character.GetCharactersInRange(position, value, s_charBuffer);
			int num2 = 0;
			int num3 = 0;
			int num4 = 0;
			for (int j = 0; j < s_charBuffer.Count; j++)
			{
				Character val = s_charBuffer[j];
				if ((Object)(object)val == (Object)null || val.IsDead())
				{
					continue;
				}
				Tameable component = ((Component)val).GetComponent<Tameable>();
				if ((Object)(object)component == (Object)null)
				{
					continue;
				}
				if (component.IsTamed())
				{
					num2++;
					if (component.IsHungry() || (FeederSettings.HealInjuredPets.Value && val.GetHealth() < val.GetMaxHealth()))
					{
						num4++;
					}
				}
				else
				{
					num3++;
					if (component.IsHungry())
					{
						num4++;
					}
				}
			}
			return $"<color=#fde047>Freyja's Grace:</color> <color=#a3e635>Feeding Active ({value:0}m radius)</color>\n" + $"<color=#e2e8f0>Food in trough: {num} items</color> | " + $"<color=#94a3b8>Nearby: {num2} pets, {num3} wild ({num4} hungry)</color>";
		}
	}
	internal static class FeederModel
	{
		internal static GameObject ModelRootTemplate;

		private static bool s_shaderRefreshed;

		internal static string FindModelPath()
		{
			string text = FeederSettings.ModelFile?.Value;
			if (string.Equals(text, "none", StringComparison.OrdinalIgnoreCase))
			{
				return null;
			}
			if (string.IsNullOrEmpty(text))
			{
				text = "FreyjasFeeder.obj";
			}
			string[] array = new string[5]
			{
				FreyjasFeederPlugin.PluginDirectory ?? "",
				Path.Combine(FreyjasFeederPlugin.PluginDirectory ?? "", "models"),
				Path.Combine(Paths.PluginPath ?? "", "FreyjasFeeder"),
				Path.Combine(Paths.PluginPath ?? "", "FreyjasFeeder", "models"),
				"C:\\Users\\dhugh\\Documents\\MyMods\\FreyjasFeeder"
			};
			string[] array2 = new string[4]
			{
				text,
				Path.GetFileNameWithoutExtension(text) + ".obj",
				"FreyjasFeeder.obj",
				"freyjasfeeder.obj"
			};
			foreach (string text2 in array)
			{
				if (string.IsNullOrEmpty(text2) || !Directory.Exists(text2))
				{
					continue;
				}
				for (int j = 0; j < array2.Length; j++)
				{
					string text3 = Path.Combine(text2, array2[j]);
					if (File.Exists(text3))
					{
						return text3;
					}
				}
			}
			return null;
		}

		internal static Shader FindModelShader(GameObject prefab)
		{
			Shader val = Shader.Find("Custom/Creature");
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			if ((Object)(object)ZNetScene.instance != (Object)null && ZNetScene.instance.m_prefabs != null)
			{
				string[] array = new string[5] { "Greydwarf", "Boar", "Deer", "Wolf", "Lox" };
				for (int i = 0; i < array.Length; i++)
				{
					GameObject prefab2 = ZNetScene.instance.GetPrefab(array[i]);
					if (!((Object)(object)prefab2 != (Object)null))
					{
						continue;
					}
					Renderer componentInChildren = prefab2.GetComponentInChildren<Renderer>(true);
					if ((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren.sharedMaterial != (Object)null && (Object)(object)componentInChildren.sharedMaterial.shader != (Object)null)
					{
						string name = ((Object)componentInChildren.sharedMaterial.shader).name;
						if (name.Contains("Creature") || !name.Contains("Piece"))
						{
							FreyjasFeederPlugin.Log.LogInfo((object)("Freyja's Feeder: borrowed shader '" + name + "' from " + array[i]));
							return componentInChildren.sharedMaterial.shader;
						}
					}
				}
			}
			val = Shader.Find("Standard");
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			val = Shader.Find("Unlit/Texture");
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			Renderer val2 = (((Object)(object)prefab != (Object)null) ? prefab.GetComponentInChildren<Renderer>(true) : null);
			if ((Object)(object)val2 != (Object)null && (Object)(object)val2.sharedMaterial != (Object)null && (Object)(object)val2.sharedMaterial.shader != (Object)null)
			{
				return val2.sharedMaterial.shader;
			}
			return Shader.Find("Hidden/InternalErrorShader");
		}

		internal static Sprite LoadPieceIcon()
		{
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Expected O, but got Unknown
			//IL_011f: 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)
			string[] array = new string[4]
			{
				FreyjasFeederPlugin.PluginDirectory ?? "",
				Path.Combine(FreyjasFeederPlugin.PluginDirectory ?? "", "models"),
				Path.Combine(Paths.PluginPath ?? "", "FreyjasFeeder"),
				"C:\\Users\\dhugh\\Documents\\MyMods\\FreyjasFeeder"
			};
			string[] array2 = new string[6] { "FreyjasFeeder_icon.jpg", "FreyjasFeeder_icon.png", "freyjasfeeder_icon.jpg", "freyjasfeeder_icon.png", "FreyjasFeeder.jpg", "FreyjasFeeder.png" };
			foreach (string text in array)
			{
				if (string.IsNullOrEmpty(text) || !Directory.Exists(text))
				{
					continue;
				}
				for (int j = 0; j < array2.Length; j++)
				{
					string text2 = Path.Combine(text, array2[j]);
					if (!File.Exists(text2))
					{
						continue;
					}
					try
					{
						byte[] array3 = File.ReadAllBytes(text2);
						Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
						if (ImageConversion.LoadImage(val, array3))
						{
							FreyjasFeederPlugin.Log.LogInfo((object)("Freyja's Feeder: loaded piece icon from " + text2));
							return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
						}
					}
					catch (Exception ex)
					{
						FreyjasFeederPlugin.Log.LogWarning((object)("Freyja's Feeder: failed to load icon from " + text2 + ": " + ex.Message));
					}
				}
			}
			return null;
		}

		internal static void ApplyToPrefab(GameObject prefab)
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)prefab == (Object)null)
			{
				return;
			}
			string text = FindModelPath();
			if (string.IsNullOrEmpty(text) || !File.Exists(text))
			{
				FreyjasFeederPlugin.Log.LogInfo((object)"Freyja's Feeder: no custom model file found. Retaining base chest visuals.");
				return;
			}
			Shader shader = FindModelShader(prefab);
			GameObject val = ObjLoader.Load(text, shader);
			if ((Object)(object)val == (Object)null)
			{
				FreyjasFeederPlugin.Log.LogWarning((object)("Freyja's Feeder: failed to load model from " + text + ". Retaining base chest visuals."));
				return;
			}
			StripOriginalVisualsAndColliders(prefab);
			prefab.transform.localScale = Vector3.one;
			((Object)val).name = "FeederModel";
			val.transform.SetParent(prefab.transform, false);
			ApplyTransform(val.transform);
			SetLayerRecursive(val, prefab.layer);
			BoxCollider componentInChildren = val.GetComponentInChildren<BoxCollider>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				((Collider)componentInChildren).enabled = true;
			}
			ClearWearNTearVisuals(prefab);
			ClearContainerVisuals(prefab);
			ModelRootTemplate = val;
			FreyjasFeederPlugin.Log.LogInfo((object)("Freyja's Feeder: applied custom model " + Path.GetFileName(text) + " to prefab."));
		}

		internal static void EnsureVisuals(GameObject instance)
		{
			if (!((Object)(object)instance == (Object)null) && !((Object)(object)ModelRootTemplate == (Object)null) && !((Object)(object)instance.transform.Find("FeederModel") != (Object)null))
			{
				StripOriginalVisualsAndColliders(instance);
				GameObject obj = Object.Instantiate<GameObject>(ModelRootTemplate);
				((Object)obj).name = "FeederModel";
				obj.transform.SetParent(instance.transform, false);
				ApplyTransform(obj.transform);
				SetLayerRecursive(obj, instance.layer);
				BoxCollider componentInChildren = obj.GetComponentInChildren<BoxCollider>(true);
				if ((Object)(object)componentInChildren != (Object)null)
				{
					((Collider)componentInChildren).enabled = true;
				}
				ClearWearNTearVisuals(instance);
				ClearContainerVisuals(instance);
			}
		}

		internal static void TryUpgradeShader(GameObject prefab)
		{
			if (s_shaderRefreshed || (Object)(object)ModelRootTemplate == (Object)null)
			{
				return;
			}
			MeshRenderer componentInChildren = ModelRootTemplate.GetComponentInChildren<MeshRenderer>(true);
			if ((Object)(object)componentInChildren == (Object)null || (Object)(object)((Renderer)componentInChildren).sharedMaterial == (Object)null)
			{
				return;
			}
			if ((((Object)(object)((Renderer)componentInChildren).sharedMaterial.shader != (Object)null) ? ((Object)((Renderer)componentInChildren).sharedMaterial.shader).name : "").Contains("Creature"))
			{
				s_shaderRefreshed = true;
				return;
			}
			Shader val = FindModelShader(prefab);
			if (!((Object)(object)val != (Object)null) || !((Object)val).name.Contains("Creature"))
			{
				return;
			}
			((Renderer)componentInChildren).sharedMaterial.shader = val;
			s_shaderRefreshed = true;
			FreyjasFeederPlugin.Log.LogInfo((object)("Freyja's Feeder: upgraded model shader to " + ((Object)val).name));
			FeederController[] array = Object.FindObjectsByType<FeederController>((FindObjectsSortMode)0);
			for (int i = 0; i < array.Length; i++)
			{
				Transform val2 = ((Component)array[i]).transform.Find("FeederModel");
				if ((Object)(object)val2 != (Object)null)
				{
					MeshRenderer componentInChildren2 = ((Component)val2).GetComponentInChildren<MeshRenderer>(true);
					if ((Object)(object)componentInChildren2 != (Object)null && (Object)(object)((Renderer)componentInChildren2).sharedMaterial != (Object)null)
					{
						((Renderer)componentInChildren2).sharedMaterial.shader = val;
					}
				}
			}
		}

		private static void ApplyTransform(Transform t)
		{
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Clamp(FeederSettings.ModelScale?.Value ?? 1f, 0.1f, 5f);
			float num2 = FeederSettings.ModelRotationY?.Value ?? 0f;
			float num3 = FeederSettings.ModelOffsetX?.Value ?? 0f;
			float num4 = FeederSettings.ModelOffsetY?.Value ?? 0f;
			float num5 = FeederSettings.ModelOffsetZ?.Value ?? 0f;
			t.localPosition = new Vector3(num3, num4, num5);
			t.localRotation = Quaternion.Euler(0f, num2, 0f);
			t.localScale = Vector3.one * num;
		}

		private static void StripOriginalVisualsAndColliders(GameObject go)
		{
			MeshFilter[] componentsInChildren = go.GetComponentsInChildren<MeshFilter>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				if (((Object)((Component)componentsInChildren[i]).gameObject).name != "Mesh" && ((Object)((Component)componentsInChildren[i]).gameObject).name != "FeederModel")
				{
					componentsInChildren[i].sharedMesh = null;
				}
			}
			Renderer[] componentsInChildren2 = go.GetComponentsInChildren<Renderer>(true);
			for (int j = 0; j < componentsInChildren2.Length; j++)
			{
				if (((Object)((Component)componentsInChildren2[j]).gameObject).name != "Mesh" && ((Object)((Component)componentsInChildren2[j]).gameObject).name != "FeederModel")
				{
					componentsInChildren2[j].enabled = false;
				}
			}
			Collider[] componentsInChildren3 = go.GetComponentsInChildren<Collider>(true);
			for (int k = 0; k < componentsInChildren3.Length; k++)
			{
				if (((Object)((Component)componentsInChildren3[k]).gameObject).name != "Mesh" && ((Object)((Component)componentsInChildren3[k]).gameObject).name != "FeederModel")
				{
					componentsInChildren3[k].enabled = false;
				}
			}
		}

		private static void ClearWearNTearVisuals(GameObject go)
		{
			WearNTear component = go.GetComponent<WearNTear>();
			if ((Object)(object)component != (Object)null)
			{
				component.m_new = null;
				component.m_worn = null;
				component.m_broken = null;
				component.m_wet = null;
				component.m_snow = null;
				component.m_snowWorn = null;
				component.m_snowBroken = null;
				component.m_noRoofWear = true;
				component.m_noSupportWear = true;
			}
		}

		private static void ClearContainerVisuals(GameObject go)
		{
			Container component = go.GetComponent<Container>();
			if ((Object)(object)component != (Object)null)
			{
				component.m_open = null;
				component.m_closed = null;
			}
		}

		private static void SetLayerRecursive(GameObject go, int layer)
		{
			if (!((Object)(object)go == (Object)null))
			{
				go.layer = layer;
				for (int i = 0; i < go.transform.childCount; i++)
				{
					SetLayerRecursive(((Component)go.transform.GetChild(i)).gameObject, layer);
				}
			}
		}
	}
	internal static class FeederPiece
	{
		internal const string PrefabName = "DFG_FreyjasFeeder";

		private const string BaseChestPrefabName = "piece_chest_wood";

		private const string DisplayName = "Freyja's Feeder";

		private const string Description = "Sacred trough blessed by Freyja. Automatically feeds nearby tamed pets and untamed beasts from its stores.";

		private static bool s_prefabRegistered;

		private static bool s_pieceManagerAdded;

		private static bool s_pieceTableRegistered;

		private static bool s_pieceRegistered;

		private static bool s_registrationWarningLogged;

		private static float s_registrationTimer;

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

		private static MethodInfo s_addKnownPieceMethod;

		private static MethodInfo s_updateAvailablePiecesListMethod;

		internal static void Initialize()
		{
			PrefabManager.OnVanillaPrefabsAvailable += OnVanillaPrefabsAvailable;
		}

		internal static void Shutdown()
		{
			PrefabManager.OnVanillaPrefabsAvailable -= OnVanillaPrefabsAvailable;
			s_cachedRequirementItems.Clear();
			s_prefabRegistered = false;
			s_pieceManagerAdded = false;
			s_pieceTableRegistered = false;
			s_pieceRegistered = false;
			s_registrationWarningLogged = false;
			s_registrationTimer = 0f;
			FeederController.AllFeeders.Clear();
			ContainerTracker.Clear();
		}

		internal static void Update()
		{
			if (FeederSettings.Enabled.Value)
			{
				TryRegisterContent();
				EnsureLocalPlayerKnownPiece();
				FeederController.UpdateGlobalChests();
			}
		}

		private static void OnVanillaPrefabsAvailable()
		{
			s_registrationTimer = 0f;
			TryRegisterPrefab();
		}

		private static void ConfigureContainer(GameObject prefab)
		{
			Container val = prefab.GetComponent<Container>();
			if ((Object)(object)val == (Object)null)
			{
				val = prefab.AddComponent<Container>();
			}
			val.m_name = "Freyja's Feeder";
			val.m_width = FeederSettings.ContainerWidth.Value;
			val.m_height = FeederSettings.ContainerHeight.Value;
			val.m_checkGuardStone = true;
			val.m_autoDestroyEmpty = false;
			val.m_defaultItems = null;
		}

		private static void TryRegisterPrefab()
		{
			if (!FeederSettings.Enabled.Value || s_prefabRegistered)
			{
				return;
			}
			try
			{
				GameObject prefab = PrefabManager.Instance.GetPrefab("piece_chest_wood");
				if ((Object)(object)prefab == (Object)null && (Object)(object)ZNetScene.instance != (Object)null)
				{
					prefab = ZNetScene.instance.GetPrefab("piece_chest_wood");
				}
				if ((Object)(object)prefab == (Object)null)
				{
					if (!s_registrationWarningLogged)
					{
						FreyjasFeederPlugin.Log.LogWarning((object)"Freyja's Feeder: could not find piece_chest_wood.");
						s_registrationWarningLogged = true;
					}
					return;
				}
				GameObject val = PrefabManager.Instance.CreateClonedPrefab("DFG_FreyjasFeeder", prefab);
				if ((Object)(object)val == (Object)null)
				{
					FreyjasFeederPlugin.Log.LogError((object)"Freyja's Feeder: failed to clone piece_chest_wood.");
					return;
				}
				ConfigureContainer(val);
				val.AddComponent<FeederController>();
				FeederModel.ApplyToPrefab(val);
				PrefabManager.Instance.AddPrefab(val);
				s_prefabRegistered = true;
				s_registrationWarningLogged = false;
				FreyjasFeederPlugin.Log.LogInfo((object)"Freyja's Feeder: registered prefab DFG_FreyjasFeeder.");
			}
			catch (Exception ex)
			{
				FreyjasFeederPlugin.Log.LogError((object)("Freyja's Feeder: prefab registration failed: " + ex));
			}
		}

		private static void TryRegisterContent()
		{
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: 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_00c6: 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_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Expected O, but got Unknown
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Expected O, but got Unknown
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Expected I4, but got Unknown
			if (!FeederSettings.Enabled.Value || s_pieceRegistered)
			{
				return;
			}
			s_registrationTimer -= Time.deltaTime;
			if (s_registrationTimer > 0f)
			{
				return;
			}
			s_registrationTimer = 1f;
			TryRegisterPrefab();
			ZNetScene instance = ZNetScene.instance;
			if (!s_prefabRegistered || (Object)(object)instance == (Object)null || instance.m_prefabs == null || instance.m_prefabs.Count == 0 || (Object)(object)ObjectDB.instance == (Object)null)
			{
				return;
			}
			GameObject prefab = PrefabManager.Instance.GetPrefab("DFG_FreyjasFeeder");
			if ((Object)(object)prefab == (Object)null)
			{
				return;
			}
			try
			{
				PieceCategory val = PieceManager.Instance.AddPieceCategory("DFG");
				if (!s_pieceManagerAdded)
				{
					PieceConfig val2 = new PieceConfig
					{
						Name = "Freyja's Feeder",
						Description = "Sacred trough blessed by Freyja. Automatically feeds nearby tamed pets and untamed beasts from its stores.",
						PieceTable = "Hammer",
						Category = "DFG",
						Enabled = true
					};
					PieceManager.Instance.AddPiece(new CustomPiece(prefab, false, val2));
					s_pieceManagerAdded = true;
				}
				if (!s_pieceTableRegistered)
				{
					PieceManager.Instance.RegisterPieceInPieceTable(prefab, "Hammer", "DFG");
					s_pieceTableRegistered = true;
				}
				FinalizePiece(prefab, val);
				FeederModel.TryUpgradeShader(prefab);
				s_pieceRegistered = true;
				FreyjasFeederPlugin.Log.LogInfo((object)("Freyja's Feeder: added to live Hammer PieceTable in category 'DFG' (id=" + (int)val + ")."));
				RefreshPieceCategories();
				EnsureLocalPlayerKnownPiece();
			}
			catch (Exception ex)
			{
				FreyjasFeederPlugin.Log.LogError((object)("Freyja's Feeder: piece registration failed: " + ex));
			}
		}

		private static void FinalizePiece(GameObject prefab, PieceCategory categoryId)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			Piece component = prefab.GetComponent<Piece>();
			if (!((Object)(object)component == (Object)null))
			{
				component.m_name = "Freyja's Feeder";
				component.m_description = "Sacred trough blessed by Freyja. Automatically feeds nearby tamed pets and untamed beasts from its stores.";
				component.m_category = categoryId;
				component.m_craftingStation = null;
				component.m_usage = (UsageTagFlags)0;
				component.m_groundPiece = true;
				component.m_clipGround = true;
				component.m_canBeRemoved = true;
				component.m_resources = BuildRequirements();
				Sprite val = FeederModel.LoadPieceIcon();
				if ((Object)(object)val != (Object)null)
				{
					component.m_icon = val;
				}
			}
		}

		private static Requirement[] BuildRequirements()
		{
			List<Requirement> list = new List<Requirement>();
			AddRequirement(list, "Wood", FeederSettings.WoodCost.Value);
			AddRequirement(list, "FineWood", FeederSettings.FineWoodCost.Value);
			AddRequirement(list, "Bronze", FeederSettings.BronzeCost.Value);
			AddRequirement(list, "Dandelion", FeederSettings.DandelionCost.Value);
			return list.ToArray();
		}

		private static void AddRequirement(List<Requirement> requirements, string itemName, int amount)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Expected O, but got Unknown
			if (amount > 0)
			{
				ItemDrop val = ResolveRequirementItem(itemName);
				if ((Object)(object)val == (Object)null || val.m_itemData == null || val.m_itemData.m_shared == null)
				{
					FreyjasFeederPlugin.Log.LogWarning((object)("Freyja's Feeder: build requirement " + itemName + " could not be resolved."));
					return;
				}
				requirements.Add(new Requirement
				{
					m_resItem = val,
					m_amount = amount,
					m_recover = true
				});
			}
		}

		private static ItemDrop ResolveRequirementItem(string prefabName)
		{
			if (s_cachedRequirementItems.TryGetValue(prefabName, out var value) && (Object)(object)value != (Object)null && value.m_itemData != null && value.m_itemData.m_shared != null)
			{
				return value;
			}
			Piece[] array = Resources.FindObjectsOfTypeAll<Piece>();
			foreach (Piece val in array)
			{
				if ((Object)(object)val == (Object)null || val.m_resources == null)
				{
					continue;
				}
				for (int j = 0; j < val.m_resources.Length; j++)
				{
					Requirement val2 = val.m_resources[j];
					if (val2 != null && !((Object)(object)val2.m_resItem == (Object)null) && !(((Object)val2.m_resItem).name != prefabName) && val2.m_resItem.m_itemData != null && val2.m_resItem.m_itemData.m_shared != null)
					{
						s_cachedRequirementItems[prefabName] = val2.m_resItem;
						return val2.m_resItem;
					}
				}
			}
			if ((Object)(object)ObjectDB.instance != (Object)null)
			{
				GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(prefabName);
				ItemDrop val3 = (((Object)(object)itemPrefab != (Object)null) ? itemPrefab.GetComponent<ItemDrop>() : null);
				if ((Object)(object)val3 != (Object)null && val3.m_itemData != null && val3.m_itemData.m_shared != null)
				{
					s_cachedRequirementItems[prefabName] = val3;
					return val3;
				}
			}
			return null;
		}

		private static void EnsureLocalPlayerKnownPiece()
		{
			if (!s_pieceRegistered || (Object)(object)Player.m_localPlayer == (Object)null || Player.m_localPlayer.IsRecipeKnown("Freyja's Feeder"))
			{
				return;
			}
			GameObject prefab = PrefabManager.Instance.GetPrefab("DFG_FreyjasFeeder");
			Piece val = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<Piece>() : null);
			if (!((Object)(object)val != (Object)null))
			{
				return;
			}
			if (s_addKnownPieceMethod == null)
			{
				s_addKnownPieceMethod = typeof(Player).GetMethod("AddKnownPiece", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			}
			if (s_updateAvailablePiecesListMethod == null)
			{
				s_updateAvailablePiecesListMethod = typeof(Player).GetMethod("UpdateAvailablePiecesList", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			}
			try
			{
				s_addKnownPieceMethod?.Invoke(Player.m_localPlayer, new object[1] { val });
				s_updateAvailablePiecesListMethod?.Invoke(Player.m_localPlayer, null);
				RefreshPieceCategories();
				FreyjasFeederPlugin.Log.LogInfo((object)"Freyja's Feeder: unlocked in Hammer menu for local player.");
			}
			catch (Exception ex)
			{
				FreyjasFeederPlugin.Log.LogWarning((object)("Freyja's Feeder: error adding known piece to player: " + ex.Message));
			}
		}

		private static void RefreshPieceCategories()
		{
			try
			{
				MethodInfo method = typeof(PieceManager).GetMethod("RefreshCategories", BindingFlags.Instance | BindingFlags.NonPublic);
				if (method != null)
				{
					method.Invoke(PieceManager.Instance, null);
				}
			}
			catch (Exception ex)
			{
				FreyjasFeederPlugin.Log.LogWarning((object)("Freyja's Feeder: could not refresh categories: " + ex.Message));
			}
		}
	}
	internal static class ObjLoader
	{
		public static GameObject Load(string objPath, Shader shader)
		{
			//IL_04e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ee: Expected O, but got Unknown
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0573: Unknown result type (might be due to invalid IL or missing references)
			//IL_0578: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_05bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_060c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0613: Expected O, but got Unknown
			//IL_061a: Unknown result type (might be due to invalid IL or missing references)
			//IL_061f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0632: Unknown result type (might be due to invalid IL or missing references)
			//IL_063f: Unknown result type (might be due to invalid IL or missing references)
			//IL_031c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0321: Unknown result type (might be due to invalid IL or missing references)
			//IL_0323: Unknown result type (might be due to invalid IL or missing references)
			//IL_0328: Unknown result type (might be due to invalid IL or missing references)
			//IL_06b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_06bc: Expected O, but got Unknown
			//IL_06ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_0365: Unknown result type (might be due to invalid IL or missing references)
			//IL_036a: Unknown result type (might be due to invalid IL or missing references)
			//IL_06e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_035e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0363: Unknown result type (might be due to invalid IL or missing references)
			//IL_0446: Unknown result type (might be due to invalid IL or missing references)
			//IL_044b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0451: Unknown result type (might be due to invalid IL or missing references)
			//IL_045a: Unknown result type (might be due to invalid IL or missing references)
			//IL_045f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0461: Unknown result type (might be due to invalid IL or missing references)
			//IL_0463: Unknown result type (might be due to invalid IL or missing references)
			//IL_0468: Unknown result type (might be due to invalid IL or missing references)
			//IL_046a: Unknown result type (might be due to invalid IL or missing references)
			//IL_046c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0471: Unknown result type (might be due to invalid IL or missing references)
			//IL_0476: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03be: Unknown result type (might be due to invalid IL or missing references)
			//IL_0795: Unknown result type (might be due to invalid IL or missing references)
			//IL_07a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_080f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0814: Unknown result type (might be due to invalid IL or missing references)
			//IL_0818: Unknown result type (might be due to invalid IL or missing references)
			//IL_0824: Unknown result type (might be due to invalid IL or missing references)
			//IL_0829: Unknown result type (might be due to invalid IL or missing references)
			//IL_082d: Unknown result type (might be due to invalid IL or missing references)
			if (string.IsNullOrEmpty(objPath) || !File.Exists(objPath))
			{
				FreyjasFeederPlugin.Log.LogWarning((object)("Freyja's Feeder: OBJ file not found: " + objPath));
				return null;
			}
			FreyjasFeederPlugin.Log.LogInfo((object)("Freyja's Feeder: loading OBJ model: " + objPath));
			string directoryName = Path.GetDirectoryName(objPath);
			string[] array;
			try
			{
				array = File.ReadAllLines(objPath);
			}
			catch (Exception ex)
			{
				FreyjasFeederPlugin.Log.LogError((object)("Freyja's Feeder: could not read OBJ file: " + ex.Message));
				return null;
			}
			List<Vector3> list = new List<Vector3>();
			List<Vector2> list2 = new List<Vector2>();
			List<Vector3> list3 = new List<Vector3>();
			List<Vector3> list4 = new List<Vector3>();
			List<Vector2> list5 = new List<Vector2>();
			List<Vector3> list6 = new List<Vector3>();
			List<int> list7 = new List<int>();
			Dictionary<string, int> dictionary = new Dictionary<string, int>();
			string mtlLib = null;
			for (int i = 0; i < array.Length; i++)
			{
				string text = array[i].Trim();
				if (text.Length < 2 || text[0] == '#')
				{
					continue;
				}
				if (text.StartsWith("v ") || text.StartsWith("v\t"))
				{
					string[] array2 = text.Split(new char[2] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
					if (array2.Length >= 4)
					{
						float num = float.Parse(array2[1], CultureInfo.InvariantCulture);
						float num2 = float.Parse(array2[2], CultureInfo.InvariantCulture);
						float num3 = float.Parse(array2[3], CultureInfo.InvariantCulture);
						list.Add(new Vector3(0f - num, num2, num3));
					}
				}
				else if (text.StartsWith("vt ") || text.StartsWith("vt\t"))
				{
					string[] array3 = text.Split(new char[2] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
					if (array3.Length >= 3)
					{
						float num4 = float.Parse(array3[1], CultureInfo.InvariantCulture);
						float num5 = float.Parse(array3[2], CultureInfo.InvariantCulture);
						list2.Add(new Vector2(num4, num5));
					}
				}
				else if (text.StartsWith("vn ") || text.StartsWith("vn\t"))
				{
					string[] array4 = text.Split(new char[2] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
					if (array4.Length >= 4)
					{
						float num6 = float.Parse(array4[1], CultureInfo.InvariantCulture);
						float num7 = float.Parse(array4[2], CultureInfo.InvariantCulture);
						float num8 = float.Parse(array4[3], CultureInfo.InvariantCulture);
						list3.Add(new Vector3(0f - num6, num7, num8));
					}
				}
				else if (text.StartsWith("mtllib ", StringComparison.OrdinalIgnoreCase))
				{
					mtlLib = text.Substring(7).Trim();
				}
				else
				{
					if (!text.StartsWith("f ") && !text.StartsWith("f\t"))
					{
						continue;
					}
					string[] array5 = text.Split(new char[2] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
					if (array5.Length < 4)
					{
						continue;
					}
					int[] array6 = new int[array5.Length - 1];
					for (int j = 1; j < array5.Length; j++)
					{
						string text2 = array5[j];
						if (!dictionary.TryGetValue(text2, out var value))
						{
							string[] array7 = text2.Split('/');
							int num9 = int.Parse(array7[0]);
							if (num9 < 0)
							{
								num9 = list.Count + num9 + 1;
							}
							Vector3 item = list[num9 - 1];
							Vector2 item2 = Vector2.zero;
							if (array7.Length > 1 && !string.IsNullOrEmpty(array7[1]))
							{
								int num10 = int.Parse(array7[1]);
								if (num10 < 0)
								{
									num10 = list2.Count + num10 + 1;
								}
								item2 = list2[num10 - 1];
							}
							Vector3 item3 = Vector3.up;
							if (array7.Length > 2 && !string.IsNullOrEmpty(array7[2]))
							{
								int num11 = int.Parse(array7[2]);
								if (num11 < 0)
								{
									num11 = list3.Count + num11 + 1;
								}
								item3 = list3[num11 - 1];
								item3 = ((!(((Vector3)(ref item3)).sqrMagnitude > 0.0001f)) ? Vector3.up : ((Vector3)(ref item3)).normalized);
							}
							value = list4.Count;
							list4.Add(item);
							list5.Add(item2);
							list6.Add(item3);
							dictionary[text2] = value;
						}
						array6[j - 1] = value;
					}
					for (int k = 1; k < array6.Length - 1; k++)
					{
						int num12 = array6[0];
						int num13 = array6[k];
						int num14 = array6[k + 1];
						if (num12 != num13 && num12 != num14 && num13 != num14)
						{
							Vector3 val = list4[num12];
							Vector3 val2 = list4[num13];
							Vector3 val3 = list4[num14];
							Vector3 val4 = Vector3.Cross(val2 - val, val3 - val);
							if (!(((Vector3)(ref val4)).sqrMagnitude < 1E-10f))
							{
								list7.Add(num12);
								list7.Add(num13);
								list7.Add(num14);
							}
						}
					}
				}
			}
			if (list4.Count == 0 || list7.Count == 0)
			{
				FreyjasFeederPlugin.Log.LogWarning((object)"Freyja's Feeder: OBJ file contained no valid geometry.");
				return null;
			}
			Mesh val5 = new Mesh();
			((Object)val5).name = Path.GetFileNameWithoutExtension(objPath);
			val5.indexFormat = (IndexFormat)1;
			val5.SetVertices(list4);
			val5.SetTriangles(list7, 0);
			if (list5.Count == list4.Count)
			{
				val5.SetUVs(0, list5);
			}
			if (list3.Count > 0 && list6.Count == list4.Count)
			{
				val5.SetNormals(list6);
			}
			else
			{
				val5.RecalculateNormals();
			}
			Color[] array8 = (Color[])(object)new Color[list4.Count];
			for (int l = 0; l < array8.Length; l++)
			{
				array8[l] = Color.white;
			}
			val5.colors = array8;
			Vector4[] array9 = (Vector4[])(object)new Vector4[list4.Count];
			for (int m = 0; m < array9.Length; m++)
			{
				array9[m] = new Vector4(1f, 0f, 0f, 1f);
			}
			val5.tangents = array9;
			val5.RecalculateBounds();
			string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(objPath);
			Texture2D val6 = ResolveDiffuseTexture(directoryName, mtlLib, fileNameWithoutExtension);
			Texture2D val7 = ResolveNormalTexture(directoryName, mtlLib, fileNameWithoutExtension);
			GameObject val8 = new GameObject("FeederModel");
			GameObject val9 = new GameObject(((Object)val5).name);
			val9.transform.SetParent(val8.transform, false);
			val9.AddComponent<MeshFilter>().sharedMesh = val5;
			MeshRenderer obj = val9.AddComponent<MeshRenderer>();
			Shader val10 = shader;
			if ((Object)(object)val10 == (Object)null || ((Object)val10).name == "Hidden/InternalErrorShader")
			{
				val10 = Shader.Find("Custom/Creature");
			}
			if ((Object)(object)val10 == (Object)null)
			{
				val10 = Shader.Find("Standard");
			}
			if ((Object)(object)val10 == (Object)null)
			{
				val10 = Shader.Find("Unlit/Texture");
			}
			Material val11 = new Material(((Object)(object)val10 != (Object)null) ? val10 : Shader.Find("Hidden/InternalErrorShader"));
			((Object)val11).name = "FreyjasFeederMaterial";
			val11.color = Color.white;
			if (val11.HasProperty("_Color"))
			{
				val11.SetColor("_Color", Color.white);
			}
			if (val11.HasProperty("_Glossiness"))
			{
				val11.SetFloat("_Glossiness", 0.35f);
			}
			if (val11.HasProperty("_Metallic"))
			{
				val11.SetFloat("_Metallic", 0.15f);
			}
			if (val11.HasProperty("_Mode"))
			{
				val11.SetFloat("_Mode", 0f);
			}
			val11.DisableKeyword("_ALPHATEST_ON");
			val11.DisableKeyword("_ALPHABLEND_ON");
			val11.DisableKeyword("_ALPHAPREMULTIPLY_ON");
			val11.renderQueue = 2000;
			if ((Object)(object)val6 != (Object)null)
			{
				val11.mainTexture = (Texture)(object)val6;
				val11.mainTextureScale = Vector2.one;
				val11.mainTextureOffset = Vector2.zero;
			}
			if ((Object)(object)val7 != (Object)null && val11.HasProperty("_BumpMap"))
			{
				val11.SetTexture("_BumpMap", (Texture)(object)val7);
				val11.EnableKeyword("_NORMALMAP");
			}
			if (val11.HasProperty("_Cull"))
			{
				val11.SetInt("_Cull", 0);
			}
			val11.doubleSidedGI = true;
			((Renderer)obj).sharedMaterial = val11;
			BoxCollider obj2 = val9.AddComponent<BoxCollider>();
			Bounds bounds = val5.bounds;
			obj2.size = ((Bounds)(ref bounds)).size;
			bounds = val5.bounds;
			obj2.center = ((Bounds)(ref bounds)).center;
			FreyjasFeederPlugin.Log.LogInfo((object)("Freyja's Feeder: OBJ loaded successfully - " + list4.Count + " vertices, " + list7.Count / 3 + " triangles."));
			return val8;
		}

		private static Texture2D ResolveDiffuseTexture(string dir, string mtlLib, string baseName)
		{
			string[] array;
			if (!string.IsNullOrEmpty(mtlLib))
			{
				string path = Path.Combine(dir, mtlLib);
				if (File.Exists(path))
				{
					try
					{
						array = File.ReadAllLines(path);
						for (int i = 0; i < array.Length; i++)
						{
							string text = array[i].Trim();
							if (text.StartsWith("map_Kd ", StringComparison.OrdinalIgnoreCase))
							{
								string path2 = text.Substring(7).Trim();
								string path3 = Path.Combine(dir, path2);
								if (File.Exists(path3))
								{
									return LoadTextureFromFile(path3);
								}
							}
						}
					}
					catch
					{
					}
				}
			}
			array = new string[8]
			{
				baseName + "_basecolor.jpg",
				baseName + "_basecolor.png",
				baseName + ".jpg",
				baseName + ".png",
				baseName + "_diffuse.jpg",
				baseName + "_diffuse.png",
				"basecolor.jpg",
				"basecolor.png"
			};
			foreach (string path4 in array)
			{
				string path5 = Path.Combine(dir, path4);
				if (File.Exists(path5))
				{
					return LoadTextureFromFile(path5);
				}
			}
			return null;
		}

		private static Texture2D ResolveNormalTexture(string dir, string mtlLib, string baseName)
		{
			string[] array;
			if (!string.IsNullOrEmpty(mtlLib))
			{
				string path = Path.Combine(dir, mtlLib);
				if (File.Exists(path))
				{
					try
					{
						array = File.ReadAllLines(path);
						for (int i = 0; i < array.Length; i++)
						{
							string text = array[i].Trim();
							if (!text.StartsWith("norm ", StringComparison.OrdinalIgnoreCase) && !text.StartsWith("bump ", StringComparison.OrdinalIgnoreCase) && !text.StartsWith("map_Bump ", StringComparison.OrdinalIgnoreCase))
							{
								continue;
							}
							int num = text.IndexOf(' ');
							if (num > 0)
							{
								string path2 = text.Substring(num + 1).Trim();
								string path3 = Path.Combine(dir, path2);
								if (File.Exists(path3))
								{
									return LoadTextureFromFile(path3, isNormal: true);
								}
							}
						}
					}
					catch
					{
					}
				}
			}
			array = new string[4]
			{
				baseName + "_normal.png",
				baseName + "_normal.jpg",
				"normal.png",
				"normal.jpg"
			};
			foreach (string path4 in array)
			{
				string path5 = Path.Combine(dir, path4);
				if (File.Exists(path5))
				{
					return LoadTextureFromFile(path5, isNormal: true);
				}
			}
			return null;
		}

		public static Texture2D LoadTextureFromFile(string path, bool isNormal = false)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			try
			{
				byte[] array = File.ReadAllBytes(path);
				Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false, isNormal);
				if (ImageConversion.LoadImage(val, array))
				{
					((Object)val).name = Path.GetFileNameWithoutExtension(path);
					((Texture)val).wrapMode = (TextureWrapMode)0;
					((Texture)val).filterMode = (FilterMode)1;
					FreyjasFeederPlugin.Log.LogInfo((object)("Freyja's Feeder: loaded texture: " + Path.GetFileName(path) + " (" + ((Texture)val).width + "x" + ((Texture)val).height + ")"));
					return val;
				}
				Object.Destroy((Object)(object)val);
			}
			catch (Exception ex)
			{
				FreyjasFeederPlugin.Log.LogWarning((object)("Freyja's Feeder: failed to load texture " + path + ": " + ex.Message));
			}
			return null;
		}
	}
	[BepInPlugin("com.dfg.freyjasfeeder", "Freyja's Feeder", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class FreyjasFeederPlugin : BaseUnityPlugin
	{
		public const string PluginGUID = "com.dfg.freyjasfeeder";

		public const string PluginName = "Freyja's Feeder";

		public const string PluginVersion = "1.0.0";

		internal static ManualLogSource Log;

		internal static string PluginDirectory;

		private Harmony m_harmony;

		internal static FreyjasFeederPlugin Instance { get; private set; }

		private void Awake()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			PluginDirectory = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
			FeederSettings.Bind(((BaseUnityPlugin)this).Config);
			try
			{
				m_harmony = new Harmony("com.dfg.freyjasfeeder");
				m_harmony.PatchAll();
				Log.LogInfo((object)"Freyja's Feeder: Harmony patches applied.");
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Freyja's Feeder: failed to apply Harmony patches: " + ex));
			}
			FeederPiece.Initialize();
			Log.LogInfo((object)"Freyja's Feeder v1.0.0 initialized.");
		}

		private void Update()
		{
			FeederPiece.Update();
		}

		private void OnDestroy()
		{
			FeederPiece.Shutdown();
			try
			{
				Harmony harmony = m_harmony;
				if (harmony != null)
				{
					harmony.UnpatchSelf();
				}
			}
			catch
			{
			}
		}
	}
}