using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; 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_FoodContainer")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("HZ_FoodContainer")] [assembly: AssemblyTitle("HZ_FoodContainer")] [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 HZ_FoodContainer { [BepInPlugin("hz.valheim.foodcontainer", "HZ_FoodContainer", "1.0.0")] public class HZFoodContainerPlugin : BaseUnityPlugin { public const string PluginGUID = "hz.valheim.foodcontainer"; public const string PluginName = "HZ_FoodContainer"; public const string PluginVersion = "1.0.0"; internal const string BarrelPrefabName = "piece_chest_barrel"; internal static ConfigEntry OnlyTamedAnimals; internal static ConfigEntry SearchRadius; internal static ConfigEntry SearchInterval; private void Awake() { //IL_006d: Unknown result type (might be due to invalid IL or missing references) OnlyTamedAnimals = ((BaseUnityPlugin)this).Config.Bind("General", "OnlyTamedAnimals", true, "Se true, só animais já domesticados usam o barril como alimentador (uso para procriação). Se false, animais selvagens também podem comer dele."); SearchRadius = ((BaseUnityPlugin)this).Config.Bind("General", "SearchRadius", 10f, "Raio (em metros) em que o animal consegue 'enxergar' o barril como fonte de comida."); SearchInterval = ((BaseUnityPlugin)this).Config.Bind("General", "SearchInterval", 10f, "Intervalo (em segundos) entre buscas por um barril próximo."); new Harmony("hz.valheim.foodcontainer").PatchAll(); } } internal class FeederState { public Container TargetContainer; public string TargetItemName; public float SearchTimer; } [HarmonyPatch(typeof(MonsterAI), "UpdateConsumeItem")] public static class MonsterAI_UpdateConsumeItem_FeederPatch { private static readonly ConditionalWeakTable States = new ConditionalWeakTable(); private static void Postfix(MonsterAI __instance, Humanoid humanoid, float dt, ref bool __result) { if (!__result && __instance.m_consumeItems != null && __instance.m_consumeItems.Count != 0) { Tameable component = ((Component)__instance).GetComponent(); if (!HZFoodContainerPlugin.OnlyTamedAnimals.Value || (!((Object)(object)component == (Object)null) && component.IsTamed())) { FeederState orCreateValue = States.GetOrCreateValue(__instance); __result = UpdateFeederConsume(__instance, humanoid, component, orCreateValue, dt); } } } private static bool UpdateFeederConsume(MonsterAI ai, Humanoid humanoid, Tameable tameable, FeederState state, float dt) { //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)tameable != (Object)null && tameable.IsTamed() && !tameable.IsHungry()) { state.TargetContainer = null; return false; } if ((Object)(object)state.TargetContainer != (Object)null) { ZNetView component = ((Component)state.TargetContainer).GetComponent(); if ((Object)(object)component == (Object)null || !component.IsValid()) { state.TargetContainer = null; } } state.SearchTimer += dt; if ((Object)(object)state.TargetContainer == (Object)null && state.SearchTimer > HZFoodContainerPlugin.SearchInterval.Value) { state.SearchTimer = 0f; FindFeederTarget(ai, state); } if ((Object)(object)state.TargetContainer == (Object)null) { return false; } Vector3 position = ((Component)state.TargetContainer).transform.position; if (MoveToViaTraverse(ai, dt, position, ai.m_consumeRange)) { LookAtViaTraverse(ai, position); if (IsLookingAtViaTraverse(ai, position, 20f)) { TryConsumeFromContainer(ai, humanoid, state); } } return true; } private static void FindFeederTarget(MonsterAI ai, FeederState state) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) int mask = LayerMask.GetMask(new string[2] { "piece", "piece_nonsolid" }); Collider[] array = Physics.OverlapSphere(((Component)ai).transform.position, HZFoodContainerPlugin.SearchRadius.Value, mask); Container targetContainer = null; string targetItemName = null; float num = float.MaxValue; Collider[] array2 = array; for (int i = 0; i < array2.Length; i++) { Container componentInParent = ((Component)array2[i]).GetComponentInParent(); if ((Object)(object)componentInParent == (Object)null || Utils.GetPrefabName(((Component)componentInParent).gameObject) != "piece_chest_barrel") { continue; } string text = FindFirstMatchingItem(ai, componentInParent); if (text != null) { float num2 = Vector3.Distance(((Component)ai).transform.position, ((Component)componentInParent).transform.position); if (num2 < num) { num = num2; targetContainer = componentInParent; targetItemName = text; } } } state.TargetContainer = targetContainer; state.TargetItemName = targetItemName; } private static string FindFirstMatchingItem(MonsterAI ai, Container container) { Inventory inventory = container.GetInventory(); if (inventory == null) { return null; } foreach (ItemData allItem in inventory.GetAllItems()) { foreach (ItemDrop consumeItem in ai.m_consumeItems) { if ((Object)(object)consumeItem != (Object)null && consumeItem.m_itemData.m_shared.m_name == allItem.m_shared.m_name) { return allItem.m_shared.m_name; } } } return null; } private static void TryConsumeFromContainer(MonsterAI ai, Humanoid humanoid, FeederState state) { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) Container targetContainer = state.TargetContainer; if ((Object)(object)targetContainer == (Object)null) { return; } Inventory inventory = targetContainer.GetInventory(); if (inventory == null) { state.TargetContainer = null; return; } ItemData val = ((IEnumerable)inventory.GetAllItems()).FirstOrDefault((Func)((ItemData i) => ai.m_consumeItems.Any((ItemDrop c) => (Object)(object)c != (Object)null && c.m_itemData.m_shared.m_name == i.m_shared.m_name))); if (val == null) { state.TargetContainer = null; return; } ZNetView component = ((Component)targetContainer).GetComponent(); if (component != null) { component.ClaimOwnership(); } inventory.RemoveItem(val, 1); humanoid.m_consumeItemEffects.Create(((Component)ai).transform.position, Quaternion.identity, (Transform)null, 1f, -1); Character component2 = ((Component)ai).GetComponent(); if (component2 != null) { ZSyncAnimation zAnim = component2.GetZAnim(); if (zAnim != null) { zAnim.SetTrigger("consume"); } } ai.m_onConsumedItem?.Invoke(null); state.TargetContainer = null; } private static bool MoveToViaTraverse(MonsterAI ai, float dt, Vector3 point, float dist) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) return Traverse.Create((object)ai).Method("MoveTo", new object[4] { dt, point, dist, false }).GetValue(); } private static void LookAtViaTraverse(MonsterAI ai, Vector3 point) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) Traverse.Create((object)ai).Method("LookAt", new object[1] { point }).GetValue(); } private static bool IsLookingAtViaTraverse(MonsterAI ai, Vector3 point, float minAngle) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) return Traverse.Create((object)ai).Method("IsLookingAt", new object[3] { point, minAngle, false }).GetValue(); } } }