Decompiled source of FeedingTrough v0.3.4

plugins/RippCast-FeedingTrough/RippCast.FeedingTrough.dll

Decompiled 8 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
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(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("0.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 RippCast.FeedingTrough
{
	public sealed class RippCastContents : MonoBehaviour
	{
		public Material FoodMaterial;

		private Container container;

		private Transform display;

		private string previous;

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

		private readonly List<Mesh> bakedMeshes = new List<Mesh>();

		private readonly HashSet<string> reported = new HashSet<string>();

		private void Start()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			container = ((Component)this).GetComponent<Container>();
			ZNetView component = ((Component)this).GetComponent<ZNetView>();
			if (Object.op_Implicit((Object)(object)component) && component.IsValid())
			{
				display = new GameObject("RC_InventoryDisplay").transform;
				display.SetParent(((Component)this).transform, false);
				((MonoBehaviour)this).InvokeRepeating("Refresh", 0.2f, 0.5f);
			}
		}

		private void Refresh()
		{
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			Inventory val = (Object.op_Implicit((Object)(object)container) ? container.GetInventory() : null);
			if (val == null || !Object.op_Implicit((Object)(object)display))
			{
				return;
			}
			ItemData[] array = (from i in val.GetAllItems()
				orderby i.m_gridPos.x
				select i).ToArray();
			string text = string.Join(";", array.Select((ItemData i) => (Object.op_Implicit((Object)(object)i.m_dropPrefab) ? ((Object)i.m_dropPrefab).name : i.m_shared.m_name) + ":" + i.m_stack + ":" + i.m_gridPos.x));
			if (text == previous)
			{
				return;
			}
			foreach (Transform item in display)
			{
				((Component)item).gameObject.SetActive(false);
				Object.Destroy((Object)(object)((Component)item).gameObject);
			}
			foreach (Mesh bakedMesh in bakedMeshes)
			{
				Object.Destroy((Object)(object)bakedMesh);
			}
			bakedMeshes.Clear();
			Random random = new Random(73219);
			int[] array2 = Enumerable.Range(0, 60).ToArray();
			for (int num = array2.Length - 1; num > 0; num--)
			{
				int num2 = random.Next(num + 1);
				int num3 = array2[num];
				array2[num] = array2[num2];
				array2[num2] = num3;
			}
			int num4 = 0;
			for (int num5 = 0; num5 < 12; num5++)
			{
				ItemData[] array3 = array;
				foreach (ItemData val3 in array3)
				{
					if (Object.op_Implicit((Object)(object)val3.m_dropPrefab) && num5 < val3.m_stack)
					{
						int num7 = array2[num4 % array2.Length];
						float num8 = -0.88f + (float)(num7 % 10) * 0.196f + ((float)random.NextDouble() - 0.5f) * 0.07f;
						float num9 = -0.32f + (float)(num7 / 10) * 0.128f + ((float)random.NextDouble() - 0.5f) * 0.05f;
						CreateVisual(val3.m_dropPrefab, new Vector3(num8, 0.34f - 0.2f * num9 + 0.012f * (float)(num4 % 3), num9), (float)random.NextDouble() * 360f);
						num4++;
					}
				}
			}
			previous = text;
		}

		private void CreateVisual(GameObject source, Vector3 position, float angle)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0352: Unknown result type (might be due to invalid IL or missing references)
			//IL_0357: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_037e: Unknown result type (might be due to invalid IL or missing references)
			//IL_038a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0396: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Expected O, but got Unknown
			//IL_03c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_0241: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: 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_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_027f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_0452: Unknown result type (might be due to invalid IL or missing references)
			//IL_0457: Unknown result type (might be due to invalid IL or missing references)
			//IL_0425: Unknown result type (might be due to invalid IL or missing references)
			//IL_042a: Unknown result type (might be due to invalid IL or missing references)
			//IL_042c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0431: 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_0471: Expected O, but got Unknown
			//IL_0473: Unknown result type (might be due to invalid IL or missing references)
			//IL_0477: Unknown result type (might be due to invalid IL or missing references)
			//IL_047c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0488: Unknown result type (might be due to invalid IL or missing references)
			//IL_048c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0491: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_04df: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0582: Unknown result type (might be due to invalid IL or missing references)
			//IL_058e: Unknown result type (might be due to invalid IL or missing references)
			//IL_059a: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_063e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0643: Unknown result type (might be due to invalid IL or missing references)
			//IL_0644: Unknown result type (might be due to invalid IL or missing references)
			//IL_064b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0657: Unknown result type (might be due to invalid IL or missing references)
			//IL_0663: Unknown result type (might be due to invalid IL or missing references)
			//IL_066d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0672: Unknown result type (might be due to invalid IL or missing references)
			//IL_069d: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_051a: Unknown result type (might be due to invalid IL or missing references)
			//IL_051f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0524: Unknown result type (might be due to invalid IL or missing references)
			//IL_0529: Unknown result type (might be due to invalid IL or missing references)
			//IL_0533: Unknown result type (might be due to invalid IL or missing references)
			//IL_0535: Unknown result type (might be due to invalid IL or missing references)
			//IL_053a: Unknown result type (might be due to invalid IL or missing references)
			//IL_053f: Unknown result type (might be due to invalid IL or missing references)
			//IL_055a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0547: Unknown result type (might be due to invalid IL or missing references)
			//IL_0549: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = new GameObject("Food_" + ((Object)source).name).transform;
			transform.SetParent(display, false);
			Transform val = source.transform.Find("attach") ?? source.transform;
			HashSet<Renderer> hashSet = new HashSet<Renderer>();
			LODGroup[] componentsInChildren = ((Component)val).GetComponentsInChildren<LODGroup>(true);
			Renderer[] renderers;
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				LOD[] lODs = componentsInChildren[i].GetLODs();
				Renderer[] source2 = (Renderer[])((lODs.Length != 0) ? ((Array)lODs[0].renderers) : ((Array)new Renderer[0]));
				foreach (LOD item in lODs.Skip(1))
				{
					renderers = item.renderers;
					foreach (Renderer val2 in renderers)
					{
						if (Object.op_Implicit((Object)(object)val2) && !source2.Contains(val2))
						{
							hashSet.Add(val2);
						}
					}
				}
			}
			renderers = ((Component)val).GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val3 in renderers)
			{
				if (hashSet.Contains(val3))
				{
					continue;
				}
				bool flag = false;
				Transform val4 = ((Component)val3).transform;
				while (Object.op_Implicit((Object)(object)val4) && (Object)(object)val4 != (Object)(object)source.transform)
				{
					if (!((Component)val4).gameObject.activeSelf || ((Object)val4).name == "equipoffset")
					{
						flag = true;
						break;
					}
					val4 = val4.parent;
				}
				if (flag)
				{
					continue;
				}
				Mesh val5 = null;
				SkinnedMeshRenderer val6 = (SkinnedMeshRenderer)(object)((val3 is SkinnedMeshRenderer) ? val3 : null);
				if (Object.op_Implicit((Object)(object)val6) && Object.op_Implicit((Object)(object)val6.sharedMesh))
				{
					val5 = new Mesh
					{
						name = "RC_Harvested_" + ((Object)val6).name
					};
					val6.BakeMesh(val5);
					bakedMeshes.Add(val5);
				}
				else if (val3 is MeshRenderer)
				{
					MeshFilter component = ((Component)val3).GetComponent<MeshFilter>();
					if (Object.op_Implicit((Object)(object)component))
					{
						val5 = component.sharedMesh;
					}
				}
				if (Object.op_Implicit((Object)(object)val5) && val5.vertexCount != 0)
				{
					GameObject val7 = new GameObject(((Object)val3).name);
					val7.transform.SetParent(transform, false);
					Matrix4x4 val8 = source.transform.worldToLocalMatrix * ((Component)val3).transform.localToWorldMatrix;
					val7.transform.localPosition = Vector4.op_Implicit(((Matrix4x4)(ref val8)).GetColumn(3));
					val7.transform.localRotation = ((Matrix4x4)(ref val8)).rotation;
					val7.transform.localScale = ((Matrix4x4)(ref val8)).lossyScale;
					val7.AddComponent<MeshFilter>().sharedMesh = val5;
					((Renderer)val7.AddComponent<MeshRenderer>()).sharedMaterials = val3.sharedMaterials.Select(StaticMaterial).ToArray();
					val7.layer = LayerMask.NameToLayer("piece");
				}
			}
			MeshFilter[] componentsInChildren2 = ((Component)transform).GetComponentsInChildren<MeshFilter>();
			if (reported.Add(((Object)source).name))
			{
				Debug.Log((object)("RippCast harvested visual: " + ((Object)source).name + " meshes=" + componentsInChildren2.Length));
			}
			if (componentsInChildren2.Length == 0)
			{
				Debug.LogWarning((object)("RippCast: missing food geometry " + ((Object)source).name));
				Object.Destroy((Object)(object)((Component)transform).gameObject);
				return;
			}
			string text = ((Object)source).name.ToLowerInvariant();
			Bounds val9 = Measure(transform, componentsInChildren2);
			bool flag2 = text.Contains("carrot") || text.Contains("turnip");
			Quaternion val10 = ((flag2 && ((Bounds)(ref val9)).size.y > Mathf.Max(((Bounds)(ref val9)).size.x, ((Bounds)(ref val9)).size.z)) ? Quaternion.Euler(0f, 0f, 90f) : Quaternion.identity);
			val10 = (text.Contains("mushroom") ? Quaternion.Euler(80f + 12f * Mathf.Sin(angle), 0f, 10f * Mathf.Cos(angle)) : ((!flag2) ? Quaternion.Euler(15f * Mathf.Sin(angle), 0f, 18f * Mathf.Cos(angle)) : (Quaternion.Euler(8f * Mathf.Sin(angle), 0f, 12f * Mathf.Cos(angle * 1.7f)) * val10)));
			foreach (Transform item2 in transform)
			{
				Transform val11 = item2;
				val11.localPosition = val10 * val11.localPosition;
				val11.localRotation = val10 * val11.localRotation;
			}
			Bounds val12 = default(Bounds);
			bool flag3 = true;
			MeshFilter[] array = componentsInChildren2;
			foreach (MeshFilter val13 in array)
			{
				Bounds bounds = val13.sharedMesh.bounds;
				for (int k = 0; k < 8; k++)
				{
					Vector3 val14 = ((Bounds)(ref bounds)).center + Vector3.Scale(((Bounds)(ref bounds)).extents, new Vector3((float)(((k & 1) != 0) ? 1 : (-1)), (float)(((k & 2) != 0) ? 1 : (-1)), (float)(((k & 4) != 0) ? 1 : (-1))));
					val14 = transform.InverseTransformPoint(((Component)val13).transform.TransformPoint(val14));
					if (flag3)
					{
						((Bounds)(ref val12))..ctor(val14, Vector3.zero);
						flag3 = false;
					}
					else
					{
						((Bounds)(ref val12)).Encapsulate(val14);
					}
				}
			}
			float num = Mathf.Max(((Bounds)(ref val12)).size.x, Mathf.Max(((Bounds)(ref val12)).size.y, ((Bounds)(ref val12)).size.z));
			float num2 = (text.Contains("turnip") ? 0.52f : (text.Contains("carrot") ? 0.6f : (text.Contains("mushroom") ? 0.24f : (text.Contains("meat") ? 0.5f : (text.Contains("berr") ? 0.27f : 0.34f))))) / Mathf.Max(0.001f, num);
			foreach (Transform item3 in transform)
			{
				item3.localPosition -= new Vector3(((Bounds)(ref val12)).center.x, ((Bounds)(ref val12)).min.y, ((Bounds)(ref val12)).center.z);
			}
			transform.localScale = Vector3.one * num2;
			transform.localRotation = Quaternion.Euler(0f, angle, 0f);
			transform.localPosition = position;
		}

		private static Bounds Measure(Transform root, MeshFilter[] filters)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			Bounds result = default(Bounds);
			bool flag = true;
			foreach (MeshFilter val in filters)
			{
				Bounds bounds = val.sharedMesh.bounds;
				for (int j = 0; j < 8; j++)
				{
					Vector3 val2 = ((Bounds)(ref bounds)).center + Vector3.Scale(((Bounds)(ref bounds)).extents, new Vector3((float)(((j & 1) != 0) ? 1 : (-1)), (float)(((j & 2) != 0) ? 1 : (-1)), (float)(((j & 4) != 0) ? 1 : (-1))));
					val2 = root.InverseTransformPoint(((Component)val).transform.TransformPoint(val2));
					if (flag)
					{
						((Bounds)(ref result))..ctor(val2, Vector3.zero);
						flag = false;
					}
					else
					{
						((Bounds)(ref result)).Encapsulate(val2);
					}
				}
			}
			return result;
		}

		private Material StaticMaterial(Material source)
		{
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Expected O, but got Unknown
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Expected O, but got Unknown
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)source))
			{
				return source;
			}
			if (materials.TryGetValue(source, out var value))
			{
				return value;
			}
			string text = (Object.op_Implicit((Object)(object)source.shader) ? ((Object)source.shader).name : "");
			bool flag = text.IndexOf("vegetation", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("grass", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("tree", StringComparison.OrdinalIgnoreCase) >= 0;
			if (!flag && Object.op_Implicit((Object)(object)source.shader) && source.shader.isSupported)
			{
				value = new Material(source)
				{
					name = "RC_Harvested_" + ((Object)source).name
				};
				materials.Add(source, value);
				if (reported.Add("material:" + ((Object)source).name))
				{
					Debug.Log((object)("RippCast native food material: " + ((Object)source).name + " shader=" + text));
				}
				return value;
			}
			if (!Object.op_Implicit((Object)(object)FoodMaterial) || !Object.op_Implicit((Object)(object)FoodMaterial.shader))
			{
				throw new InvalidOperationException("RippCast bundled food material unavailable");
			}
			value = new Material(FoodMaterial)
			{
				name = "RC_StaticFood_" + ((Object)source).name
			};
			if (source.HasProperty("_MainTex"))
			{
				value.SetTexture("_MainTex", source.GetTexture("_MainTex"));
				value.SetTextureScale("_MainTex", source.GetTextureScale("_MainTex"));
				value.SetTextureOffset("_MainTex", source.GetTextureOffset("_MainTex"));
			}
			value.color = (source.HasProperty("_Color") ? source.GetColor("_Color") : Color.white);
			bool flag2 = flag || source.IsKeywordEnabled("_ALPHATEST_ON") || source.GetTag("RenderType", false) == "TransparentCutout";
			value.SetFloat("_Cutoff", (!flag2) ? 0f : (source.HasProperty("_Cutoff") ? Mathf.Max(0.01f, source.GetFloat("_Cutoff")) : 0.4f));
			if (reported.Add("material:" + ((Object)source).name))
			{
				Debug.Log((object)("RippCast food material: " + ((Object)source).name + " shader=" + ((Object)source.shader).name + " texture=" + (Object.op_Implicit((Object)(object)value.mainTexture) ? ((Object)value.mainTexture).name : "none") + " cutoff=" + value.GetFloat("_Cutoff")));
			}
			value.renderQueue = 2450;
			materials.Add(source, value);
			return value;
		}

		private void OnDestroy()
		{
			((MonoBehaviour)this).CancelInvoke();
			foreach (Material value in materials.Values)
			{
				Object.Destroy((Object)(object)value);
			}
			foreach (Mesh bakedMesh in bakedMeshes)
			{
				Object.Destroy((Object)(object)bakedMesh);
			}
		}
	}
	public sealed class RippCastFeeder : MonoBehaviour
	{
		internal static readonly HashSet<RippCastFeeder> Active = new HashSet<RippCastFeeder>();

		internal Container Store;

		internal ZNetView View;

		private readonly Dictionary<ZDOID, float> served = new Dictionary<ZDOID, float>();

		private void Awake()
		{
			Store = ((Component)this).GetComponent<Container>();
			View = ((Component)this).GetComponent<ZNetView>();
			if (Object.op_Implicit((Object)(object)View) && View.IsValid())
			{
				View.Register<ZDOID>("RC_RequestFood", (Action<long, ZDOID>)RequestFood);
				Active.Add(this);
			}
		}

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

		internal Vector3 Approach(Character animal)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//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_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = ((Component)this).transform.InverseTransformPoint(((Component)animal).transform.position);
			return ((Component)this).transform.TransformPoint(new Vector3(Mathf.Clamp(val.x, -0.9f, 0.9f), 0f, 0.83f + Mathf.Max(0.35f, animal.GetRadius())));
		}

		internal ItemData Suitable(MonsterAI ai)
		{
			Inventory val = (Object.op_Implicit((Object)(object)Store) ? Store.GetInventory() : null);
			if (val == null || ai.m_consumeItems == null)
			{
				return null;
			}
			return ((IEnumerable<ItemData>)val.GetAllItems()).FirstOrDefault((Func<ItemData, bool>)((ItemData item) => item.m_stack > 0 && ai.m_consumeItems.Any((ItemDrop food) => Object.op_Implicit((Object)(object)food) && food.m_itemData.m_shared.m_name == item.m_shared.m_name)));
		}

		private void RequestFood(long sender, ZDOID animalId)
		{
			//IL_0020: 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_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			if (!View.IsOwner() || Store.IsInUse())
			{
				return;
			}
			GameObject val = ZNetScene.instance.FindInstance(animalId);
			if (!Object.op_Implicit((Object)(object)val))
			{
				return;
			}
			ZNetView component = val.GetComponent<ZNetView>();
			MonsterAI component2 = val.GetComponent<MonsterAI>();
			Tameable component3 = val.GetComponent<Tameable>();
			Character component4 = val.GetComponent<Character>();
			if (!Object.op_Implicit((Object)(object)component) || !component.IsValid() || component.GetZDO().GetOwner() != sender || !Object.op_Implicit((Object)(object)component2) || !Object.op_Implicit((Object)(object)component3) || !Object.op_Implicit((Object)(object)component4) || component4.IsDead() || ((BaseAI)component2).IsAlerted() || !component3.IsHungry() || Vector3.Distance(val.transform.position, Approach(component4)) > 1.2f || (served.TryGetValue(animalId, out var value) && Time.time - value < 5f))
			{
				return;
			}
			ItemData val2 = Suitable(component2);
			if (val2 != null && Object.op_Implicit((Object)(object)val2.m_dropPrefab))
			{
				string name = ((Object)val2.m_dropPrefab).name;
				if (Store.GetInventory().RemoveItem(val2, 1))
				{
					served[animalId] = Time.time;
					component.InvokeRPC("RC_FoodEaten", new object[2]
					{
						View.GetZDO().m_uid,
						name
					});
					Debug.Log((object)("RippCast feeding: " + ((Object)val).name + " consumed 1 " + name));
				}
			}
		}
	}
	[HarmonyPatch(typeof(MonsterAI), "Awake")]
	internal static class RippCastAnimalSetup
	{
		private static void Postfix(MonsterAI __instance)
		{
			ZNetView view = ((Component)__instance).GetComponent<ZNetView>();
			if (!Object.op_Implicit((Object)(object)view) || !view.IsValid())
			{
				return;
			}
			view.Register<ZDOID, string>("RC_FoodEaten", (Action<long, ZDOID, string>)delegate(long sender, ZDOID troughId, string foodName)
			{
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
				if (view.IsOwner())
				{
					GameObject val = ZNetScene.instance.FindInstance(troughId);
					RippCastFeeder rippCastFeeder = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<RippCastFeeder>() : null);
					if (Object.op_Implicit((Object)(object)rippCastFeeder) && rippCastFeeder.View.GetZDO().GetOwner() == sender)
					{
						GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(foodName);
						ItemDrop drop = (Object.op_Implicit((Object)(object)itemPrefab) ? itemPrefab.GetComponent<ItemDrop>() : null);
						if (Object.op_Implicit((Object)(object)drop) && __instance.m_consumeItems.Any((ItemDrop f) => Object.op_Implicit((Object)(object)f) && f.m_itemData.m_shared.m_name == drop.m_itemData.m_shared.m_name))
						{
							__instance.m_onConsumedItem?.Invoke(drop);
							Humanoid component = ((Component)__instance).GetComponent<Humanoid>();
							if (Object.op_Implicit((Object)(object)component))
							{
								component.m_consumeItemEffects.Create(((Component)__instance).transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID));
							}
							ZSyncAnimation component2 = ((Component)__instance).GetComponent<ZSyncAnimation>();
							if (Object.op_Implicit((Object)(object)component2))
							{
								component2.SetTrigger("consume");
							}
						}
					}
				}
			});
		}
	}
	[HarmonyPatch(typeof(MonsterAI), "UpdateConsumeItem")]
	internal static class RippCastSeekFood
	{
		private static readonly MethodInfo Move = AccessTools.Method(typeof(BaseAI), "MoveTo", new Type[4]
		{
			typeof(float),
			typeof(Vector3),
			typeof(float),
			typeof(bool)
		}, (Type[])null);

		private static readonly MethodInfo Look = AccessTools.Method(typeof(BaseAI), "LookAt", new Type[1] { typeof(Vector3) }, (Type[])null);

		private static readonly Dictionary<ZDOID, float> requested = new Dictionary<ZDOID, float>();

		private static bool Prefix(MonsterAI __instance, float dt, ref bool __result)
		{
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: 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_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			ZNetView component = ((Component)__instance).GetComponent<ZNetView>();
			Tameable component2 = ((Component)__instance).GetComponent<Tameable>();
			Character component3 = ((Component)__instance).GetComponent<Character>();
			if (!Object.op_Implicit((Object)(object)component) || !component.IsValid() || !component.IsOwner() || !Object.op_Implicit((Object)(object)component2) || !component2.IsHungry() || ((BaseAI)__instance).IsAlerted())
			{
				return true;
			}
			RippCastFeeder rippCastFeeder = null;
			float num = __instance.m_consumeSearchRange;
			foreach (RippCastFeeder item in RippCastFeeder.Active)
			{
				if (Object.op_Implicit((Object)(object)item) && Object.op_Implicit((Object)(object)item.Store) && !item.Store.IsInUse() && item.Suitable(__instance) != null)
				{
					float num2 = Vector3.Distance(((Component)__instance).transform.position, item.Approach(component3));
					if (num2 < num)
					{
						rippCastFeeder = item;
						num = num2;
					}
				}
			}
			if (!Object.op_Implicit((Object)(object)rippCastFeeder))
			{
				return true;
			}
			Vector3 val = rippCastFeeder.Approach(component3);
			if (!(bool)Move.Invoke(__instance, new object[4] { dt, val, 0.65f, false }))
			{
				__result = true;
				return false;
			}
			if (Vector3.Distance(((Component)__instance).transform.position, val) > 1.2f)
			{
				return true;
			}
			Look.Invoke(__instance, new object[1] { ((Component)rippCastFeeder).transform.TransformPoint(new Vector3(0f, 0.4f, 0.3f)) });
			ZDOID uid = component.GetZDO().m_uid;
			if (!requested.TryGetValue(uid, out var value) || Time.time - value > 2f)
			{
				requested[uid] = Time.time;
				rippCastFeeder.View.InvokeRPC("RC_RequestFood", new object[1] { uid });
			}
			__result = true;
			return false;
		}
	}
	[BepInPlugin("rippcast.valheim.feedingtrough.mid", "RippCast Feeding Trough - Mid Game", "0.3.4")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public sealed class RippCastFeedingTrough : BaseUnityPlugin
	{
		public const string PluginGuid = "rippcast.valheim.feedingtrough.mid";

		public const string PluginName = "RippCast Feeding Trough - Mid Game";

		public const string PluginVersion = "0.3.4";

		private const string BundleFileName = "rippcast_feedingtrough_mid";

		private const string AssetName = "RippCast_FeedingTrough_Mid";

		private const string PiecePrefabName = "piece_rippcast_feedingtrough_mid";

		private AssetBundle bundle;

		private Harmony harmony;

		private void Awake()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			RegisterTranslations();
			harmony = new Harmony("rippcast.valheim.feedingtrough.mid");
			harmony.PatchAll(typeof(RippCastFeedingTrough).Assembly);
			PrefabManager.OnVanillaPrefabsAvailable += RegisterPiece;
		}

		private void OnDestroy()
		{
			PrefabManager.OnVanillaPrefabsAvailable -= RegisterPiece;
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
		}

		private void RegisterPiece()
		{
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0360: Unknown result type (might be due to invalid IL or missing references)
			//IL_0367: Expected O, but got Unknown
			//IL_03f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0400: Expected O, but got Unknown
			PrefabManager.OnVanillaPrefabsAvailable -= RegisterPiece;
			try
			{
				string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
				if (string.IsNullOrEmpty(directoryName))
				{
					((BaseUnityPlugin)this).Logger.LogError((object)"A plugin telepitesi mappaja nem talalhato.");
					return;
				}
				string text = Path.Combine(directoryName, "rippcast_feedingtrough_mid");
				if (!File.Exists(text))
				{
					((BaseUnityPlugin)this).Logger.LogError((object)("Hianyzik az AssetBundle a DLL melle: " + text));
					return;
				}
				bundle = AssetBundle.LoadFromFile(text);
				if ((Object)(object)bundle == (Object)null)
				{
					((BaseUnityPlugin)this).Logger.LogError((object)("Az AssetBundle betoltese sikertelen. Ellenorizd a Unity-verziot es a fajlt: " + text));
					return;
				}
				GameObject val = bundle.LoadAsset<GameObject>("RippCast_FeedingTrough_Mid");
				if ((Object)(object)val == (Object)null)
				{
					((BaseUnityPlugin)this).Logger.LogError((object)("Hianyzik a prefab az AssetBundle-bol: RippCast_FeedingTrough_Mid | Elso assets: " + string.Join(", ", bundle.GetAllAssetNames())));
					bundle.Unload(false);
					bundle = null;
					return;
				}
				((Object)val).name = "piece_rippcast_feedingtrough_mid";
				if ((Object)(object)val.GetComponent<Piece>() == (Object)null)
				{
					val.AddComponent<Piece>();
				}
				if ((Object)(object)val.GetComponent<ZNetView>() == (Object)null)
				{
					val.AddComponent<ZNetView>();
				}
				val.GetComponent<ZNetView>().m_persistent = true;
				WearNTear val2 = val.GetComponent<WearNTear>() ?? val.AddComponent<WearNTear>();
				val2.m_health = 500f;
				val2.m_noRoofWear = true;
				val2.m_noSupportWear = true;
				val2.m_supports = false;
				val2.m_autoCreateFragments = false;
				GameObject prefab = PrefabManager.Instance.GetPrefab("woodwall");
				if (!Object.op_Implicit((Object)(object)prefab) || !Object.op_Implicit((Object)(object)prefab.GetComponent<Piece>()))
				{
					throw new Exception("Vanilla woodwall unavailable");
				}
				val.GetComponent<Piece>().m_placeEffect = prefab.GetComponent<Piece>().m_placeEffect;
				WearNTear component = prefab.GetComponent<WearNTear>();
				if (Object.op_Implicit((Object)(object)component))
				{
					val2.m_hitEffect = component.m_hitEffect;
					val2.m_destroyedEffect = component.m_destroyedEffect;
				}
				ApplyMaterials(val);
				Container component2 = PrefabManager.Instance.GetPrefab("piece_chest_wood").GetComponent<Container>();
				Container obj = val.AddComponent<Container>();
				obj.m_name = "$rc_trough_name";
				obj.m_width = 5;
				obj.m_height = 1;
				obj.m_bkg = component2.m_bkg;
				obj.m_privacy = component2.m_privacy;
				obj.m_checkGuardStone = component2.m_checkGuardStone;
				obj.m_openEffects = component2.m_openEffects;
				obj.m_closeEffects = component2.m_closeEffects;
				obj.m_destroyedLootPrefab = component2.m_destroyedLootPrefab;
				Material val3 = bundle.LoadAsset<Material>("RC_FoodStatic");
				if (!Object.op_Implicit((Object)(object)val3) || !Object.op_Implicit((Object)(object)val3.shader))
				{
					throw new Exception("Missing bundled food material");
				}
				val.AddComponent<RippCastContents>().FoodMaterial = val3;
				val.AddComponent<RippCastFeeder>();
				int num = LayerMask.NameToLayer("piece");
				if (num < 0)
				{
					throw new Exception("Valheim piece layer unavailable");
				}
				Transform[] componentsInChildren = val.GetComponentsInChildren<Transform>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					((Component)componentsInChildren[i]).gameObject.layer = num;
				}
				((BaseUnityPlugin)this).Logger.LogInfo((object)("Bundle loaded: renderers=" + val.GetComponentsInChildren<Renderer>(true).Length + " colliders=" + val.GetComponentsInChildren<Collider>(true).Length + " persistent=true"));
				PieceConfig val4 = new PieceConfig();
				val4.Name = "$rc_trough_name";
				val4.Description = "$rc_trough_description";
				val4.PieceTable = "Hammer";
				val4.CraftingStation = "piece_workbench";
				val4.Category = "RippCast";
				val4.Usage = new string[1] { PieceUsages.Furniture };
				val4.Icon = LoadTroughIcon(directoryName);
				PieceConfig val5 = val4;
				val5.AddRequirement("Wood", 20, true);
				val5.AddRequirement("FineWood", 10, true);
				val5.AddRequirement("Iron", 4, true);
				CustomPiece val6 = new CustomPiece(val, false, val5);
				PieceManager.Instance.AddPiece(val6);
				((BaseUnityPlugin)this).Logger.LogInfo((object)"RippCast Feeding Trough regisztralva: piece_rippcast_feedingtrough_mid");
				bundle.Unload(false);
				bundle = null;
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("RippCast init hiba: " + ex));
			}
		}

		private void ApplyMaterials(GameObject prefab)
		{
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Expected O, but got Unknown
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<Material, Material> dictionary = new Dictionary<Material, Material>();
			Texture2D val = MakeSurfaceTexture(wood: true);
			Texture2D val2 = MakeSurfaceTexture(wood: false);
			Renderer[] componentsInChildren = prefab.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val3 in componentsInChildren)
			{
				Material[] sharedMaterials = val3.sharedMaterials;
				for (int j = 0; j < sharedMaterials.Length; j++)
				{
					Material val4 = sharedMaterials[j];
					if (!Object.op_Implicit((Object)(object)val4))
					{
						continue;
					}
					if (!dictionary.TryGetValue(val4, out var value))
					{
						string text = ((Object)val4).name.ToLowerInvariant();
						bool num = text.Contains("ygg");
						bool flag = text.Contains("iron");
						bool flag2 = text.Contains("stone") || text.Contains("granite");
						bool flag3 = text.Contains("recessed") || text.Contains("dark grain");
						value = new Material(val4)
						{
							name = "RC_OwnUV_" + ((Object)val4).name
						};
						value.SetFloat("_Metallic", flag ? 0.15f : 0f);
						value.SetFloat("_Glossiness", flag ? 0.12f : 0.04f);
						value.SetFloat("_GlossMapScale", 0f);
						value.SetFloat("_SpecularHighlights", 0f);
						value.SetFloat("_GlossyReflections", 0f);
						value.EnableKeyword("_SPECULARHIGHLIGHTS_OFF");
						value.EnableKeyword("_GLOSSYREFLECTIONS_OFF");
						value.DisableKeyword("_METALLICGLOSSMAP");
						if (!num)
						{
							value.SetTexture("_MainTex", (Texture)(object)((flag || flag2) ? val2 : val));
							value.SetTextureScale("_MainTex", Vector2.one);
							value.SetTextureOffset("_MainTex", Vector2.zero);
							value.color = (flag ? new Color(0.19f, 0.21f, 0.22f, 1f) : (flag2 ? new Color(0.4f, 0.41f, 0.37f, 1f) : (flag3 ? new Color(0.105f, 0.06f, 0.028f, 1f) : new Color(0.39f, 0.265f, 0.16f, 1f))));
						}
						else
						{
							value.color = Color.white;
							if (Object.op_Implicit((Object)(object)value.GetTexture("_BumpMap")))
							{
								value.EnableKeyword("_NORMALMAP");
							}
						}
						dictionary.Add(val4, value);
						((BaseUnityPlugin)this).Logger.LogInfo((object)("Own-UV material: " + ((Object)value).name));
					}
					sharedMaterials[j] = value;
				}
				val3.sharedMaterials = sharedMaterials;
			}
		}

		private static Texture2D MakeSurfaceTexture(bool wood)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(128, 128, (TextureFormat)4, true);
			((Object)val).name = (wood ? "RC_timber_grain" : "RC_mineral_mottling");
			((Texture)val).wrapMode = (TextureWrapMode)0;
			((Texture)val).filterMode = (FilterMode)0;
			for (int i = 0; i < 128; i++)
			{
				for (int j = 0; j < 128; j++)
				{
					float num = (float)j / 128f;
					float num2 = (float)i / 128f;
					float num3 = (wood ? Mathf.PerlinNoise(num * 48f + 2f * Mathf.Sin(num2 * 8f), num2 * 2f) : Mathf.PerlinNoise(num * 14f, num2 * 14f));
					float num4 = Mathf.PerlinNoise(num * 59f + 13f, num2 * 53f + 7f);
					float num5 = (wood ? (0.46f + 0.43f * num3 + 0.11f * num4) : (0.62f + 0.3f * num3 + 0.08f * num4));
					val.SetPixel(j, i, new Color(num5, num5, num5, 1f));
				}
			}
			val.Apply(true, true);
			return val;
		}

		private void RegisterTranslations()
		{
			CustomLocalization localization = LocalizationManager.Instance.GetLocalization();
			string text = "English";
			localization.AddTranslation(ref text, new Dictionary<string, string>
			{
				{ "rc_trough_name", "Feeding Trough" },
				{ "rc_trough_description", "The carved World Tree watches over the gifts of forest and field. Five slots hold food for hungry beasts, each feasting on the morsels it favours." }
			});
			text = "German";
			localization.AddTranslation(ref text, new Dictionary<string, string>
			{
				{ "rc_trough_name", "Futtertrog" },
				{ "rc_trough_description", "Der geschnitzte Weltenbaum wacht über die Gaben von Wald und Feld. Fünf Plätze bergen Futter für hungrige Tiere; jedes labt sich an dem, was ihm schmeckt." }
			});
			text = "Hungarian";
			localization.AddTranslation(ref text, new Dictionary<string, string>
			{
				{ "rc_trough_name", "Etetővályú" },
				{ "rc_trough_description", "Faragott világfa őrzi az erdő és a mező ajándékait. Öt helyén eleség várja az éhes jószágot; mindegyik a kedvére való falatból lakmározik." }
			});
		}

		private static Sprite LoadTroughIcon(string directory)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Expected O, but got Unknown
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
			if (!ImageConversion.LoadImage(val, File.ReadAllBytes(Path.Combine(directory, "feedingtrough_icon.png"))))
			{
				throw new Exception("Invalid feeding trough icon");
			}
			((Object)val).name = "RC_FeedingTrough_Icon";
			((Texture)val).wrapMode = (TextureWrapMode)1;
			return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f);
		}
	}
}