Decompiled source of PieGuy v1.0.0

PieGuy.CobOven.S11.dll

Decompiled 3 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
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: 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 DelGryphon.PieGuy.CobOvenS1
{
	[BepInPlugin("delgryphon.pieguy.coboven.s1", "PieGuy Cob Oven S11", "0.1.11")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class CobOvenS11Plugin : BaseUnityPlugin
	{
		private const string OvenPrefab = "Piece_CobOven";

		private bool registered;

		private float nextAttempt;

		private void Awake()
		{
			PrefabManager.OnVanillaPrefabsAvailable += Register;
			ItemManager.OnItemsRegistered += RefreshRegisteredPrefab;
			PieceManager.OnPiecesRegistered += RefreshRegisteredPrefab;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"[Cob Oven S11] No-smoke textured oven, narrow colliders and interactions, workbench gating, original-game fire particles, forward 80%-size pie slot, plus native physical chimney smoke only.");
		}

		private void OnDestroy()
		{
			PrefabManager.OnVanillaPrefabsAvailable -= Register;
			ItemManager.OnItemsRegistered -= RefreshRegisteredPrefab;
			PieceManager.OnPiecesRegistered -= RefreshRegisteredPrefab;
		}

		private void Start()
		{
			if (!registered)
			{
				Register();
			}
		}

		private void Update()
		{
			if (!registered && !(Time.time < nextAttempt))
			{
				nextAttempt = Time.time + 4f;
				Register();
			}
		}

		private void Register()
		{
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: 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_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Expected O, but got Unknown
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Expected O, but got Unknown
			if (registered)
			{
				return;
			}
			try
			{
				if ((Object)(object)PrefabManager.Instance.GetPrefab("piece_oven") == (Object)null)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)"[Cob Oven S11] Native stone oven not yet available");
					return;
				}
				Sprite icon = null;
				try
				{
					icon = S1Visuals.LoadIcon();
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("[Cob Oven S11] Icon unavailable; using vanilla oven icon: " + ex.Message));
					GameObject prefab = PrefabManager.Instance.GetPrefab("piece_oven");
					Piece val = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<Piece>() : null);
					if ((Object)(object)val != (Object)null)
					{
						icon = val.m_icon;
					}
				}
				PieceConfig val2 = new PieceConfig
				{
					Name = "Cob Oven",
					Description = "A rustic wood-fired oven for baking pies and other oven foods. Add wood, then bake one item at a time.",
					PieceTable = "Hammer",
					Category = "Crafting",
					CraftingStation = "piece_workbench",
					Icon = icon
				};
				val2.AddRequirement("Wood", 3, true);
				val2.AddRequirement("Stone", 10, true);
				val2.AddRequirement("Flint", 2, true);
				CustomPiece val3 = new CustomPiece("Piece_CobOven", "piece_oven", val2);
				GameObject piecePrefab = val3.PiecePrefab;
				if ((Object)(object)piecePrefab == (Object)null)
				{
					throw new InvalidOperationException("Stone Oven cloning failed");
				}
				GameObject prefab2 = PrefabManager.Instance.GetPrefab("piece_workbench");
				Piece component = piecePrefab.GetComponent<Piece>();
				CraftingStation val4 = (((Object)(object)prefab2 != (Object)null) ? prefab2.GetComponent<CraftingStation>() : null);
				if ((Object)(object)component == (Object)null || (Object)(object)val4 == (Object)null)
				{
					throw new InvalidOperationException("Missing Piece or workbench prefab; refusing to register Artisan-locked oven");
				}
				component.m_craftingStation = val4;
				if (!PieceManager.Instance.AddPiece(val3))
				{
					throw new InvalidOperationException("Jotunn rejected Piece_CobOven");
				}
				registered = true;
				((BaseUnityPlugin)this).Logger.LogInfo((object)"[Cob Oven S11] Piece_CobOven REGISTERED in Hammer. Applying native cooking, appearance, and no-smoke changes separately.");
				try
				{
					ConfigureNativeCooking(piecePrefab, piecePrefab.GetComponent<CookingStation>() ?? piecePrefab.GetComponentInChildren<CookingStation>(true));
				}
				catch (Exception ex2)
				{
					((BaseUnityPlugin)this).Logger.LogError((object)("[Cob Oven S11] Cooking config failed; registered native oven remains: " + ex2));
				}
				try
				{
					int num = S1Visuals.InstallAppearance(piecePrefab);
					((BaseUnityPlugin)this).Logger.LogInfo((object)("[Cob Oven S11] Recovered cob appearance; replaced surface materials=" + num));
				}
				catch (Exception ex3)
				{
					((BaseUnityPlugin)this).Logger.LogError((object)("[Cob Oven S11] Visual asset loading failed; registered oven remains (vanilla look): " + ex3));
				}
				try
				{
					if ((Object)(object)piecePrefab.GetComponent<S1OvenConversionBinder>() == (Object)null)
					{
						piecePrefab.AddComponent<S1OvenConversionBinder>();
					}
				}
				catch (Exception ex4)
				{
					((BaseUnityPlugin)this).Logger.LogError((object)("[Cob Oven S11] Pie conversion binder failed: " + ex4));
				}
				try
				{
					if ((Object)(object)piecePrefab.GetComponent<S11HearthFlame>() == (Object)null)
					{
						piecePrefab.AddComponent<S11HearthFlame>();
					}
				}
				catch (Exception ex5)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("[Cob Oven S11] Campfire animation unavailable: " + ex5.Message));
				}
				try
				{
					if ((Object)(object)piecePrefab.GetComponent<S11PhysicalChimneySmoke>() == (Object)null)
					{
						piecePrefab.AddComponent<S11PhysicalChimneySmoke>();
					}
				}
				catch (Exception ex6)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("[Cob Oven S11] Native physical smoke unavailable: " + ex6.Message));
				}
				try
				{
					if ((Object)(object)piecePrefab.GetComponent<S11PieDisplay>() == (Object)null)
					{
						piecePrefab.AddComponent<S11PieDisplay>();
					}
				}
				catch (Exception ex7)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("[Cob Oven S11] Pie display unavailable: " + ex7.Message));
				}
				RefreshRegisteredPrefab();
				((BaseUnityPlugin)this).Logger.LogInfo((object)"[Cob Oven S11] Oven registration complete. Core inventory/food items untouched. No scene-wide smoke scanning.");
			}
			catch (Exception ex8)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("[Cob Oven S11] Registration: " + ex8));
			}
		}

		private static void ConfigureNativeCooking(GameObject root, CookingStation oven)
		{
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Expected O, but got Unknown
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_036f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0374: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)oven == (Object)null)
			{
				throw new InvalidOperationException("Registered native oven has no CookingStation");
			}
			oven.m_name = "Cob Oven";
			oven.m_useFuel = true;
			oven.m_requireFire = false;
			oven.m_maxFuel = 10;
			oven.m_secPerFuel = 2000;
			if (oven.m_slots == null || oven.m_slots.Length < 1 || (Object)(object)oven.m_slots[0] == (Object)null)
			{
				throw new InvalidOperationException("Vanilla oven cooking slot missing");
			}
			Transform val = oven.m_slots[0];
			val.SetParent(root.transform, false);
			val.localPosition = new Vector3(0f, 0.99f, -0.37f);
			val.localRotation = Quaternion.identity;
			val.localScale = Vector3.one;
			((Component)val).gameObject.SetActive(true);
			oven.m_slots = (Transform[])(object)new Transform[1] { val };
			Logger.CreateLogSource("PieGuy RC2 Slots").LogInfo((object)("Preserved native cooking slot '" + ((Object)val).name + "' with " + val.childCount + " children; custom pie meshes remain independent"));
			GameObject val2 = new GameObject("S1_FrontPieOutput");
			val2.transform.SetParent(root.transform, false);
			val2.transform.localPosition = new Vector3(0f, 1.0430456f, -0.7265461f);
			val2.transform.localRotation = Quaternion.LookRotation(Vector3.back, Vector3.up);
			oven.m_spawnPoint = val2.transform;
			oven.m_spawnForce = 3.3f;
			Switch addFoodSwitch = oven.m_addFoodSwitch;
			Switch addFuelSwitch = oven.m_addFuelSwitch;
			if ((Object)(object)addFoodSwitch == (Object)null || (Object)(object)addFuelSwitch == (Object)null)
			{
				throw new InvalidOperationException("Native stone oven missing the independent food/fuel switches");
			}
			PlaceSwitch(root.transform, addFoodSwitch, 1.25f, -0.7f);
			PlaceSwitch(root.transform, addFuelSwitch, 0.7f, -0.7f);
			BoxCollider val3 = root.GetComponent<BoxCollider>();
			if ((Object)(object)val3 == (Object)null)
			{
				val3 = root.AddComponent<BoxCollider>();
			}
			val3.center = new Vector3(0f, 0.54f, 0.06f);
			val3.size = new Vector3(0.94f, 1.08f, 1.05f);
			((Collider)val3).isTrigger = false;
			((Collider)val3).enabled = true;
			int num = 0;
			Collider[] componentsInChildren = root.GetComponentsInChildren<Collider>(true);
			foreach (Collider val4 in componentsInChildren)
			{
				if (!((Object)(object)val4 == (Object)null) && !((Object)(object)val4 == (Object)(object)val3))
				{
					bool num2 = (Object)(object)((Component)val4).transform == (Object)(object)((Component)addFoodSwitch).transform;
					bool flag = (Object)(object)((Component)val4).transform == (Object)(object)((Component)addFuelSwitch).transform;
					if (!(num2 || flag))
					{
						val4.enabled = false;
						num++;
					}
				}
			}
			Logger.CreateLogSource("PieGuy S11 Colliders").LogInfo((object)("Narrow oven: extra native colliders disabled=" + num + "; separate front food and wood targets retained"));
			SmokeSpawner[] componentsInChildren2 = root.GetComponentsInChildren<SmokeSpawner>(true);
			foreach (SmokeSpawner val5 in componentsInChildren2)
			{
				if ((Object)(object)val5 != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)val5);
				}
			}
			Fireplace[] componentsInChildren3 = root.GetComponentsInChildren<Fireplace>(true);
			foreach (Fireplace val6 in componentsInChildren3)
			{
				if ((Object)(object)val6 != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)val6);
				}
			}
			int num3 = 0;
			ParticleSystem[] componentsInChildren4 = root.GetComponentsInChildren<ParticleSystem>(true);
			foreach (ParticleSystem val7 in componentsInChildren4)
			{
				if (!((Object)(object)val7 == (Object)null))
				{
					val7.Stop(true, (ParticleSystemStopBehavior)0);
					EmissionModule emission = val7.emission;
					((EmissionModule)(ref emission)).enabled = false;
					ParticleSystemRenderer component = ((Component)val7).GetComponent<ParticleSystemRenderer>();
					if ((Object)(object)component != (Object)null)
					{
						((Renderer)component).enabled = false;
					}
					num3++;
				}
			}
			oven.m_haveFireObject = MakeInertState(root, "S11_HasFire_SmokeIsolation");
			oven.m_haveFuelObject = MakeInertState(root, "S11_HasFuel_SmokeIsolation");
			Logger.CreateLogSource("PieGuy S11 Smoke").LogInfo((object)("Native oven effects silenced: spawners/fireplaces removed, " + num3 + " inherited particle systems muted; inert native FX states"));
		}

		private static void PlaceSwitch(Transform root, Switch target, float height, float front)
		{
			//IL_001a: 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_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			((Component)target).transform.SetParent(root, false);
			((Component)target).transform.localPosition = new Vector3(0f, height, front);
			((Component)target).transform.localRotation = Quaternion.identity;
			((Component)target).transform.localScale = Vector3.one;
			((Component)target).gameObject.SetActive(true);
			BoxCollider val = ((Component)target).GetComponent<BoxCollider>();
			if ((Object)(object)val == (Object)null)
			{
				val = ((Component)target).gameObject.AddComponent<BoxCollider>();
			}
			val.center = Vector3.zero;
			val.size = new Vector3(0.55f, 0.2f, 0.18f);
			((Collider)val).isTrigger = false;
			((Collider)val).enabled = true;
			Collider[] componentsInChildren = ((Component)target).GetComponentsInChildren<Collider>(true);
			foreach (Collider val2 in componentsInChildren)
			{
				if ((Object)(object)val2 != (Object)(object)val)
				{
					val2.enabled = false;
				}
			}
		}

		private static GameObject MakeInertState(GameObject root, string name)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			GameObject val = new GameObject(name);
			val.transform.SetParent(root.transform, false);
			return val;
		}

		private void RefreshRegisteredPrefab()
		{
			if (!registered)
			{
				return;
			}
			try
			{
				GameObject prefab = PrefabManager.Instance.GetPrefab("Piece_CobOven");
				if (!((Object)(object)prefab == (Object)null))
				{
					S1OvenConversionBinder component = prefab.GetComponent<S1OvenConversionBinder>();
					if ((Object)(object)component != (Object)null)
					{
						component.Refresh();
					}
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("[Cob Oven S11] Conversion refresh: " + ex.Message));
			}
		}
	}
	public sealed class S1OvenConversionBinder : MonoBehaviour
	{
		private static readonly string[,] Pies = new string[12, 2]
		{
			{ "UncookedPorkHandPie", "PorkHandPie" },
			{ "UncookedMixedBerryPie", "MixedBerryPie" },
			{ "UncookedVegetablePie", "VegetablePie" },
			{ "UncookedWolfMeatPie", "WolfMeatPie" },
			{ "UncookedSweetChutneyPie", "SweetChutneyPie" },
			{ "UncookedMushroomPie", "MushroomPie" },
			{ "UncookedSavoryQuiche", "SavoryQuiche" },
			{ "UncookedSeekerMeatPie", "SeekerMeatPie" },
			{ "UncookedChickenPotPie", "ChickenPotPie" },
			{ "UncookedVenisonPie", "VenisonPie" },
			{ "UncookedFourBerryGalette", "FourBerryGalette" },
			{ "UncookedNordicFishPie", "NordicFishPie" }
		};

		private bool complete;

		private void Start()
		{
			Refresh();
		}

		private void OnEnable()
		{
			if (!complete)
			{
				Refresh();
			}
		}

		private static ItemDrop Find(string key)
		{
			GameObject val = null;
			try
			{
				if ((Object)(object)ObjectDB.instance != (Object)null)
				{
					val = ObjectDB.instance.GetItemPrefab(key);
				}
			}
			catch
			{
			}
			try
			{
				if ((Object)(object)val == (Object)null)
				{
					val = PrefabManager.Instance.GetPrefab(key);
				}
			}
			catch
			{
			}
			if (!((Object)(object)val != (Object)null))
			{
				return null;
			}
			return val.GetComponent<ItemDrop>();
		}

		public void Refresh()
		{
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Expected O, but got Unknown
			if (complete)
			{
				return;
			}
			CookingStation val = ((Component)this).GetComponent<CookingStation>() ?? ((Component)this).GetComponentInChildren<CookingStation>(true);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			if (val.m_conversion == null)
			{
				val.m_conversion = new List<ItemConversion>();
			}
			int num = 0;
			for (int i = 0; i < Pies.GetLength(0); i++)
			{
				ItemDrop val2 = Find(Pies[i, 0]);
				ItemDrop val3 = Find(Pies[i, 1]);
				if ((Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null)
				{
					continue;
				}
				num++;
				ItemConversion val4 = null;
				foreach (ItemConversion item in val.m_conversion)
				{
					if (item != null && (Object)(object)item.m_from != (Object)null && ((Object)item.m_from).name == ((Object)val2).name)
					{
						val4 = item;
						break;
					}
				}
				if (val4 == null)
				{
					val.m_conversion.Add(new ItemConversion
					{
						m_from = val2,
						m_to = val3,
						m_cookTime = 50f
					});
				}
				else
				{
					val4.m_from = val2;
					val4.m_to = val3;
					val4.m_cookTime = 50f;
				}
			}
			if (num == Pies.GetLength(0))
			{
				complete = true;
				((MonoBehaviour)this).CancelInvoke("Refresh");
			}
			else if (Application.isPlaying && ((Component)this).gameObject.activeInHierarchy && !((MonoBehaviour)this).IsInvoking("Refresh"))
			{
				((MonoBehaviour)this).InvokeRepeating("Refresh", 2f, 5f);
			}
		}
	}
	public sealed class S11HearthFlame : MonoBehaviour
	{
		private static readonly ManualLogSource Log = Logger.CreateLogSource("PieGuy S11 Hearth");

		private CookingStation station;

		private ZNetView view;

		private GameObject fx;

		private Light hearthLight;

		private readonly List<ParticleSystem> emitters = new List<ParticleSystem>();

		private bool installed;

		private bool lit;

		private float nextCheck;

		private static readonly MethodInfo GetFuelMethod = typeof(CookingStation).GetMethod("GetFuel", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);

		private void Start()
		{
			Install();
		}

		private void OnEnable()
		{
			if (!installed)
			{
				Install();
			}
		}

		private static bool SmokeFX(ParticleSystem ps)
		{
			if ((Object)(object)ps == (Object)null)
			{
				return true;
			}
			Transform val = ((Component)ps).transform;
			while ((Object)(object)val != (Object)null)
			{
				string text = (((Object)val).name ?? "").ToLowerInvariant();
				if (text.Contains("smoke") || text.Contains("steam") || text.Contains("soot") || text.Contains("smokeball"))
				{
					return true;
				}
				val = val.parent;
			}
			ParticleSystemRenderer component = ((Component)ps).GetComponent<ParticleSystemRenderer>();
			string text2 = (((Object)(object)component != (Object)null && (Object)(object)((Renderer)component).sharedMaterial != (Object)null) ? ((Object)((Renderer)component).sharedMaterial).name : "").ToLowerInvariant();
			if (!text2.Contains("smoke") && !text2.Contains("steam"))
			{
				return text2.Contains("soot");
			}
			return true;
		}

		private static int FlameScore(ParticleSystem ps)
		{
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			if (SmokeFX(ps))
			{
				return -1000;
			}
			string text = (((Object)ps).name ?? "").ToLowerInvariant();
			ParticleSystemRenderer component = ((Component)ps).GetComponent<ParticleSystemRenderer>();
			if ((Object)(object)component == (Object)null || (Object)(object)((Renderer)component).sharedMaterial == (Object)null)
			{
				return -1000;
			}
			string text2 = ((Object)((Renderer)component).sharedMaterial).name.ToLowerInvariant();
			if (text.Contains("burst") || text.Contains("explos") || text.Contains("cinder") || text.Contains("spark") || text.Contains("ember") || text.Contains("firework") || text2.Contains("burst") || text2.Contains("explos") || text2.Contains("spark") || text2.Contains("ember") || text2.Contains("cinder"))
			{
				return -1000;
			}
			int num = 0;
			if (text2.Contains("flame"))
			{
				num += 30;
			}
			if (text2.Contains("fire"))
			{
				num += 15;
			}
			if (text.Contains("flame"))
			{
				num += 25;
			}
			if (text.Contains("fire") || text.Contains("burn"))
			{
				num += 8;
			}
			MainModule main = ps.main;
			if (((MainModule)(ref main)).loop)
			{
				num += 8;
			}
			EmissionModule emission = ps.emission;
			MinMaxCurve rateOverTime;
			if (((EmissionModule)(ref emission)).enabled)
			{
				rateOverTime = ((EmissionModule)(ref emission)).rateOverTime;
				if (((MinMaxCurve)(ref rateOverTime)).constantMax > 0.02f)
				{
					num += 10;
				}
			}
			rateOverTime = ((EmissionModule)(ref emission)).rateOverTime;
			if (((MinMaxCurve)(ref rateOverTime)).constantMax <= 0.02f)
			{
				num -= 100;
			}
			return num;
		}

		private void EnsureLight()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)hearthLight != (Object)null))
			{
				GameObject val = new GameObject("S11_WarmHearthLight");
				val.transform.SetParent(((Component)this).transform, false);
				val.transform.localPosition = new Vector3(0f, 0.86f, -0.48f);
				hearthLight = val.AddComponent<Light>();
				hearthLight.type = (LightType)2;
				hearthLight.color = new Color(1f, 0.5f, 0.23f);
				hearthLight.range = 5f;
				hearthLight.intensity = 0f;
				hearthLight.shadows = (LightShadows)0;
			}
		}

		private void Install()
		{
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Expected O, but got Unknown
			//IL_0160: 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_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_0314: Unknown result type (might be due to invalid IL or missing references)
			//IL_0319: Unknown result type (might be due to invalid IL or missing references)
			//IL_031e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0327: Unknown result type (might be due to invalid IL or missing references)
			//IL_032e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0335: Unknown result type (might be due to invalid IL or missing references)
			//IL_033c: Unknown result type (might be due to invalid IL or missing references)
			//IL_034d: 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_0391: 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_03b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0449: Unknown result type (might be due to invalid IL or missing references)
			//IL_044e: Unknown result type (might be due to invalid IL or missing references)
			if (installed)
			{
				return;
			}
			station = ((Component)this).GetComponent<CookingStation>() ?? ((Component)this).GetComponentInChildren<CookingStation>(true);
			view = ((Component)this).GetComponent<ZNetView>() ?? ((Component)this).GetComponentInChildren<ZNetView>(true);
			if ((Object)(object)station == (Object)null)
			{
				return;
			}
			EnsureLight();
			try
			{
				GameObject prefab = PrefabManager.Instance.GetPrefab("fire_pit");
				if ((Object)(object)prefab == (Object)null)
				{
					Log.LogWarning((object)"fire_pit missing: retrying");
					return;
				}
				ParticleSystem[] componentsInChildren = prefab.GetComponentsInChildren<ParticleSystem>(true);
				List<ParticleSystem> list = new List<ParticleSystem>();
				ParticleSystem[] array = componentsInChildren;
				foreach (ParticleSystem val in array)
				{
					if (FlameScore(val) >= 30)
					{
						list.Add(val);
					}
				}
				list.Sort((ParticleSystem a, ParticleSystem b) => FlameScore(b).CompareTo(FlameScore(a)));
				if (list.Count == 0)
				{
					Log.LogError((object)("Campfire has no continuous flame emitter. Found " + componentsInChildren.Length + " particle systems. See S8 diagnostics; no unrelated FX will be substituted."));
					nextCheck = Time.time + 5f;
					return;
				}
				fx = new GameObject("S11_HalfScale_CampfireContinuousFlames");
				fx.transform.SetParent(((Component)this).transform, false);
				fx.transform.localPosition = new Vector3(0f, 0.72f, -0.43f);
				fx.transform.localRotation = Quaternion.identity;
				fx.transform.localScale = new Vector3(0.5f, 0.25f, 0.5f);
				int num = Math.Min(list.Count, 3);
				for (int num2 = 0; num2 < num; num2++)
				{
					ParticleSystem val2 = list[num2];
					GameObject val3 = Object.Instantiate<GameObject>(((Component)val2).gameObject);
					((Object)val3).name = "S11_CampfireNativeFlame_" + num2;
					for (int num3 = val3.transform.childCount - 1; num3 >= 0; num3--)
					{
						Object.DestroyImmediate((Object)(object)((Component)val3.transform.GetChild(num3)).gameObject);
					}
					MonoBehaviour[] components = val3.GetComponents<MonoBehaviour>();
					foreach (MonoBehaviour val4 in components)
					{
						if ((Object)(object)val4 != (Object)null)
						{
							Object.DestroyImmediate((Object)(object)val4);
						}
					}
					SmokeSpawner[] components2 = val3.GetComponents<SmokeSpawner>();
					foreach (SmokeSpawner val5 in components2)
					{
						if ((Object)(object)val5 != (Object)null)
						{
							Object.DestroyImmediate((Object)(object)val5);
						}
					}
					Collider[] components3 = val3.GetComponents<Collider>();
					foreach (Collider val6 in components3)
					{
						if ((Object)(object)val6 != (Object)null)
						{
							val6.enabled = false;
						}
					}
					Light[] components4 = val3.GetComponents<Light>();
					foreach (Light val7 in components4)
					{
						if ((Object)(object)val7 != (Object)null)
						{
							((Behaviour)val7).enabled = false;
						}
					}
					val3.transform.SetParent(fx.transform, false);
					Vector3 val8 = prefab.transform.InverseTransformPoint(((Component)val2).transform.position);
					val3.transform.localPosition = new Vector3(val8.x, val8.y, val8.z);
					val3.transform.localRotation = Quaternion.identity;
					val3.transform.localScale = Vector3.one;
					val3.SetActive(true);
					ParticleSystem component = val3.GetComponent<ParticleSystem>();
					if ((Object)(object)component == (Object)null)
					{
						Object.Destroy((Object)(object)val3);
						continue;
					}
					MainModule main = component.main;
					((MainModule)(ref main)).loop = true;
					((MainModule)(ref main)).playOnAwake = false;
					((MainModule)(ref main)).scalingMode = (ParticleSystemScalingMode)0;
					EmissionModule emission = component.emission;
					((EmissionModule)(ref emission)).enabled = true;
					ParticleSystemRenderer component2 = val3.GetComponent<ParticleSystemRenderer>();
					if ((Object)(object)component2 != (Object)null)
					{
						((Renderer)component2).enabled = true;
					}
					emitters.Add(component);
					ManualLogSource log = Log;
					string[] obj = new string[6]
					{
						"Native campfire flame selected: ",
						((Object)val2).name,
						", material=",
						((Object)(object)component2 != (Object)null && (Object)(object)((Renderer)component2).sharedMaterial != (Object)null) ? ((Object)((Renderer)component2).sharedMaterial).name : "none",
						", original emission=",
						null
					};
					MinMaxCurve rateOverTime = ((EmissionModule)(ref emission)).rateOverTime;
					obj[5] = ((MinMaxCurve)(ref rateOverTime)).constantMax.ToString();
					log.LogInfo((object)string.Concat(obj));
				}
				if (emitters.Count == 0)
				{
					Object.Destroy((Object)(object)fx);
					fx = null;
					Log.LogError((object)"No usable campfire flame components cloned");
				}
				else
				{
					fx.SetActive(false);
					installed = true;
					Log.LogInfo((object)("S11 ready: " + emitters.Count + " continuous original campfire flame emitter(s) at 50% scale; ZERO native smoke systems cloned"));
				}
			}
			catch (Exception ex)
			{
				if ((Object)(object)fx != (Object)null)
				{
					Object.Destroy((Object)(object)fx);
				}
				fx = null;
				emitters.Clear();
				Log.LogError((object)("Unable to install campfire flame: " + ex));
			}
		}

		private float Fuel()
		{
			float num = -1f;
			try
			{
				if (GetFuelMethod != null && (Object)(object)station != (Object)null)
				{
					num = Convert.ToSingle(GetFuelMethod.Invoke(station, null));
				}
			}
			catch (Exception)
			{
			}
			try
			{
				if ((Object)(object)view == (Object)null)
				{
					view = ((Component)this).GetComponent<ZNetView>() ?? ((Component)this).GetComponentInChildren<ZNetView>(true);
				}
				if ((Object)(object)view != (Object)null && view.GetZDO() != null)
				{
					num = Mathf.Max(num, view.GetZDO().GetFloat(ZDOVars.s_fuel, 0f));
				}
			}
			catch (Exception)
			{
			}
			return Mathf.Max(0f, num);
		}

		private void Update()
		{
			if ((Object)(object)hearthLight == (Object)null)
			{
				EnsureLight();
			}
			bool flag = Fuel() > 0.025f;
			if ((Object)(object)hearthLight != (Object)null)
			{
				hearthLight.intensity = (flag ? (2.2f + 0.16f * Mathf.Sin(Time.time * 8f)) : 0f);
			}
			if (!installed)
			{
				if (Time.time >= nextCheck)
				{
					nextCheck = Time.time + 3f;
					Install();
				}
			}
			else
			{
				if (flag == lit)
				{
					return;
				}
				lit = flag;
				fx.SetActive(lit);
				foreach (ParticleSystem emitter in emitters)
				{
					if (!((Object)(object)emitter == (Object)null))
					{
						if (lit)
						{
							((Component)emitter).gameObject.SetActive(true);
							emitter.Clear(true);
							emitter.Play(true);
						}
						else
						{
							emitter.Stop(true, (ParticleSystemStopBehavior)0);
						}
					}
				}
				Log.LogInfo((object)("S11 campfire flames " + (lit ? "ON" : "OFF") + ", fuel=" + Fuel()));
			}
		}
	}
	public sealed class S11PhysicalChimneySmoke : MonoBehaviour
	{
		private static readonly ManualLogSource Log = Logger.CreateLogSource("PieGuy S11 PhysicalSmoke");

		private static readonly MethodInfo GetFuelMethod = typeof(CookingStation).GetMethod("GetFuel", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);

		private CookingStation station;

		private ZNetView view;

		private SmokeSpawner spawner;

		private GameObject source;

		private float retryAt;

		private bool active;

		private int attempts;

		private void Start()
		{
			Install();
		}

		private void OnEnable()
		{
			if ((Object)(object)spawner == (Object)null)
			{
				Install();
			}
		}

		private float Fuel()
		{
			float num = -1f;
			try
			{
				if (GetFuelMethod != null && (Object)(object)station != (Object)null)
				{
					num = Convert.ToSingle(GetFuelMethod.Invoke(station, null));
				}
			}
			catch (Exception)
			{
			}
			try
			{
				if ((Object)(object)view == (Object)null)
				{
					view = ((Component)this).GetComponent<ZNetView>() ?? ((Component)this).GetComponentInChildren<ZNetView>(true);
				}
				if ((Object)(object)view != (Object)null && view.GetZDO() != null)
				{
					num = Mathf.Max(num, view.GetZDO().GetFloat(ZDOVars.s_fuel, 0f));
				}
			}
			catch (Exception)
			{
			}
			return Mathf.Max(num, 0f);
		}

		private void Install()
		{
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Expected O, but got Unknown
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)spawner != (Object)null)
			{
				return;
			}
			station = ((Component)this).GetComponent<CookingStation>() ?? ((Component)this).GetComponentInChildren<CookingStation>(true);
			view = ((Component)this).GetComponent<ZNetView>() ?? ((Component)this).GetComponentInChildren<ZNetView>(true);
			if ((Object)(object)station == (Object)null)
			{
				return;
			}
			GameObject val = null;
			try
			{
				GameObject prefab = PrefabManager.Instance.GetPrefab("fire_pit");
				if ((Object)(object)prefab == (Object)null)
				{
					retryAt = Time.time + 5f;
					return;
				}
				SmokeSpawner val2 = null;
				SmokeSpawner[] componentsInChildren = prefab.GetComponentsInChildren<SmokeSpawner>(true);
				foreach (SmokeSpawner val3 in componentsInChildren)
				{
					if ((Object)(object)val3 != (Object)null && (Object)(object)val3.m_smokePrefab != (Object)null)
					{
						val2 = val3;
						break;
					}
				}
				if ((Object)(object)val2 == (Object)null)
				{
					retryAt = Time.time + 5f;
					if (++attempts <= 3)
					{
						Log.LogWarning((object)"Campfire physical SmokeSpawner not yet available; retrying");
					}
					return;
				}
				val = new GameObject("S11_RealSmokeBallSpawner_AtChimney");
				val.SetActive(false);
				val.transform.SetParent(((Component)this).transform, false);
				val.transform.localPosition = new Vector3(0f, 1.9f, 0.2f);
				val.transform.localRotation = Quaternion.identity;
				val.transform.localScale = Vector3.one;
				SmokeSpawner val4 = val.AddComponent<SmokeSpawner>();
				((Behaviour)val4).enabled = false;
				val4.m_smokePrefab = val2.m_smokePrefab;
				val4.m_interval = val2.m_interval * 2f;
				val4.m_testRadius = val2.m_testRadius;
				val4.m_spawnRadius = 0f;
				val4.m_stopFireOnStart = false;
				val.SetActive(true);
				source = val;
				spawner = val4;
				active = false;
				Log.LogInfo((object)("Physical SmokeSpawner installed at chimney: SmokeBall=" + (((Object)(object)val4.m_smokePrefab != (Object)null) ? ((Object)val4.m_smokePrefab).name : "MISSING") + ", interval=" + val4.m_interval + ", test radius=" + val4.m_testRadius + ", local point=(0,1.90,0.20); no cosmetic plume; hearth fire unchanged"));
			}
			catch (Exception ex)
			{
				if ((Object)(object)val != (Object)null)
				{
					Object.Destroy((Object)(object)val);
				}
				source = null;
				spawner = null;
				retryAt = Time.time + 5f;
				Log.LogError((object)("Could not install physical chimney smoke: " + ex));
			}
		}

		private void Update()
		{
			if ((Object)(object)spawner == (Object)null)
			{
				if (Time.time >= retryAt)
				{
					retryAt = Time.time + 5f;
					Install();
				}
				return;
			}
			bool flag = Fuel() > 0.025f;
			if (flag != active)
			{
				active = flag;
				((Behaviour)spawner).enabled = flag;
				Log.LogInfo((object)("Physical chimney smoke " + (active ? "ON" : "OFF") + "; fuel=" + Fuel() + "; SmokeBall spawner=" + ((Behaviour)spawner).enabled));
			}
		}

		private void OnDestroy()
		{
			if ((Object)(object)spawner != (Object)null)
			{
				((Behaviour)spawner).enabled = false;
			}
			if ((Object)(object)source != (Object)null)
			{
				Object.Destroy((Object)(object)source);
			}
		}
	}
	public sealed class S11PieDisplay : MonoBehaviour
	{
		private static readonly ManualLogSource Log = Logger.CreateLogSource("PieGuy S11 PieDisplay");

		private static readonly HashSet<string> PieNames = new HashSet<string>(StringComparer.Ordinal)
		{
			"UncookedPorkHandPie", "PorkHandPie", "UncookedMixedBerryPie", "MixedBerryPie", "UncookedVegetablePie", "VegetablePie", "UncookedWolfMeatPie", "WolfMeatPie", "UncookedSweetChutneyPie", "SweetChutneyPie",
			"UncookedMushroomPie", "MushroomPie", "UncookedSavoryQuiche", "SavoryQuiche", "UncookedSeekerMeatPie", "SeekerMeatPie", "UncookedChickenPotPie", "ChickenPotPie", "UncookedVenisonPie", "VenisonPie",
			"UncookedFourBerryGalette", "FourBerryGalette", "UncookedNordicFishPie", "NordicFishPie"
		};

		private ZNetView view;

		private CookingStation station;

		private Transform anchor;

		private GameObject visible;

		private string shownName = "";

		private float nextCheck;

		private float retryPie;

		private int diagnostics;

		private void Start()
		{
			Setup();
		}

		private void Setup()
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)anchor != (Object)null))
			{
				station = ((Component)this).GetComponent<CookingStation>() ?? ((Component)this).GetComponentInChildren<CookingStation>(true);
				view = ((Component)this).GetComponent<ZNetView>() ?? ((Component)this).GetComponentInChildren<ZNetView>(true);
				GameObject val = new GameObject("S11_TrueSizePieDisplay_IndependentOfVanillaAttach");
				anchor = val.transform;
				anchor.SetParent(((Component)this).transform, false);
				anchor.localPosition = new Vector3(0f, 0.99f, -0.37f);
				anchor.localRotation = Quaternion.identity;
				anchor.localScale = Vector3.one;
			}
		}

		private static Transform PieHolder(Transform root)
		{
			Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren<Transform>(true);
			foreach (Transform val in componentsInChildren)
			{
				if ((Object)(object)val != (Object)null && ((Object)val).name.StartsWith("PieGuy_R34_", StringComparison.Ordinal))
				{
					return val;
				}
			}
			return null;
		}

		private static GameObject Resolve(string name)
		{
			GameObject val = null;
			try
			{
				if ((Object)(object)ObjectDB.instance != (Object)null)
				{
					val = ObjectDB.instance.GetItemPrefab(name);
				}
			}
			catch (Exception)
			{
			}
			try
			{
				if ((Object)(object)val == (Object)null)
				{
					val = PrefabManager.Instance.GetPrefab(name);
				}
			}
			catch (Exception)
			{
			}
			return val;
		}

		private void HideVanillaSlotPie()
		{
			if ((Object)(object)station == (Object)null || station.m_slots == null)
			{
				return;
			}
			Transform[] slots = station.m_slots;
			foreach (Transform val in slots)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				MeshRenderer[] componentsInChildren = ((Component)val).GetComponentsInChildren<MeshRenderer>(true);
				foreach (MeshRenderer val2 in componentsInChildren)
				{
					if ((Object)(object)val2 != (Object)null)
					{
						((Renderer)val2).enabled = false;
					}
				}
				SkinnedMeshRenderer[] componentsInChildren2 = ((Component)val).GetComponentsInChildren<SkinnedMeshRenderer>(true);
				foreach (SkinnedMeshRenderer val3 in componentsInChildren2)
				{
					if ((Object)(object)val3 != (Object)null)
					{
						((Renderer)val3).enabled = false;
					}
				}
			}
		}

		private void Draw(string name)
		{
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)visible != (Object)null)
			{
				Object.Destroy((Object)(object)visible);
			}
			visible = null;
			shownName = name;
			if (string.IsNullOrEmpty(name) || !PieNames.Contains(name))
			{
				return;
			}
			GameObject val = Resolve(name);
			if ((Object)(object)val == (Object)null)
			{
				Log.LogWarning((object)("No item prefab for oven slot: " + name));
				return;
			}
			Transform val2 = PieHolder(val.transform);
			if ((Object)(object)val2 == (Object)null)
			{
				Log.LogWarning((object)("R41 3D holder missing on " + name + "; cannot show oven model"));
				return;
			}
			visible = Object.Instantiate<GameObject>(((Component)val2).gameObject);
			((Object)visible).name = "S11_Visible_" + name;
			visible.transform.SetParent(anchor, false);
			visible.transform.localPosition = Vector3.zero;
			visible.transform.localRotation = Quaternion.identity;
			visible.transform.localScale = Vector3.one * 0.8f;
			visible.SetActive(true);
			int num = 0;
			MeshRenderer[] componentsInChildren = visible.GetComponentsInChildren<MeshRenderer>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				((Renderer)componentsInChildren[i]).enabled = true;
				num++;
			}
			HideVanillaSlotPie();
			Log.LogInfo((object)("Showing " + name + " using " + num + " existing R41 mesh renderers at 80% scale, internal shelf y=0.99 z=-0.37"));
		}

		private void Update()
		{
			if (Time.time < nextCheck)
			{
				return;
			}
			nextCheck = Time.time + 0.25f;
			if ((Object)(object)anchor == (Object)null)
			{
				Setup();
			}
			if ((Object)(object)view == (Object)null)
			{
				view = ((Component)this).GetComponent<ZNetView>() ?? ((Component)this).GetComponentInChildren<ZNetView>(true);
			}
			if ((Object)(object)view == (Object)null || view.GetZDO() == null)
			{
				return;
			}
			string text = "";
			try
			{
				text = view.GetZDO().GetString("slot0", "");
			}
			catch (Exception ex)
			{
				if (diagnostics++ < 2)
				{
					Log.LogWarning((object)("Unable to read slot0: " + ex.Message));
				}
				return;
			}
			int num = 0;
			try
			{
				num = view.GetZDO().GetInt("slotstatus0", 0);
			}
			catch (Exception)
			{
			}
			string text2 = text;
			if (num == 1 && text.StartsWith("Uncooked", StringComparison.Ordinal))
			{
				text2 = text.Substring("Uncooked".Length);
			}
			if (text2 != shownName)
			{
				Draw(text2);
			}
			else if (PieNames.Contains(text2) && (Object)(object)visible == (Object)null && Time.time > retryPie)
			{
				retryPie = Time.time + 3f;
				Draw(text2);
			}
			if (PieNames.Contains(text))
			{
				HideVanillaSlotPie();
			}
		}

		private void OnDestroy()
		{
			if ((Object)(object)visible != (Object)null)
			{
				Object.Destroy((Object)(object)visible);
			}
		}
	}
	internal static class S1Visuals
	{
		private static readonly Dictionary<string, Texture2D> TextureCache = new Dictionary<string, Texture2D>();

		private static Texture2D Load(string label)
		{
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			if (TextureCache.TryGetValue(label, out var value))
			{
				return value;
			}
			using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("PGS1_" + label);
			if (stream == null)
			{
				throw new InvalidOperationException("Missing Cob Oven S1 texture: " + label);
			}
			using GZipStream gZipStream = new GZipStream(stream, CompressionMode.Decompress);
			using MemoryStream memoryStream = new MemoryStream();
			gZipStream.CopyTo(memoryStream);
			byte[] array = memoryStream.ToArray();
			if (array.Length != 1048576)
			{
				throw new InvalidOperationException("Cob Oven S1 texture dimensions invalid: " + label);
			}
			Texture2D val = new Texture2D(512, 512, (TextureFormat)4, false);
			((Object)val).name = "S1_" + label;
			((Texture)val).wrapMode = (TextureWrapMode)0;
			((Texture)val).filterMode = (FilterMode)1;
			val.LoadRawTextureData(array);
			val.Apply(false, false);
			TextureCache[label] = val;
			return val;
		}

		public static Sprite LoadIcon()
		{
			//IL_001e: 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)
			return Sprite.Create(Load("OvenIcon"), new Rect(0f, 0f, 512f, 512f), new Vector2(0.5f, 0.5f), 100f);
		}

		public static int InstallAppearance(GameObject oven)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			GetOriginalAppearance(out var mesh, out var materials);
			Mesh val = Object.Instantiate<Mesh>(mesh);
			((Object)val).name = "S11_CobOven_ApprovedGeometry_NaturalUV";
			Material[] array = (Material[])(object)new Material[materials.Length];
			bool[] array2 = new bool[materials.Length];
			int num = 0;
			for (int i = 0; i < materials.Length; i++)
			{
				Material val2 = materials[i];
				if ((Object)(object)val2 == (Object)null)
				{
					continue;
				}
				Material val3 = new Material(val2);
				Texture mainTexture = val2.mainTexture;
				Texture2D val4 = (Texture2D)(object)((mainTexture is Texture2D) ? mainTexture : null);
				string text = FinishFor(val4);
				bool flag = ((Object)(object)val4 != (Object)null && ((Object)val4).name.IndexOf("CobOven_tex4", StringComparison.OrdinalIgnoreCase) >= 0) || (((Object)val2).name != null && ((Object)val2).name.IndexOf("fire", StringComparison.OrdinalIgnoreCase) >= 0);
				if (text == null && !flag && materials.Length == 5)
				{
					switch (i)
					{
					case 0:
						text = "OvenClay";
						break;
					case 1:
					case 2:
						text = "OvenStone";
						break;
					case 3:
						text = "OvenArch";
						break;
					}
				}
				if (text != null)
				{
					Texture2D val5 = (Texture2D)(object)(val3.mainTexture = (Texture)(object)Load(text));
					if (val3.HasProperty("_MainTex"))
					{
						val3.SetTexture("_MainTex", (Texture)(object)val5);
					}
					if (val3.HasProperty("_Color"))
					{
						val3.SetColor("_Color", Color.white);
					}
					if (val3.HasProperty("_Glossiness"))
					{
						val3.SetFloat("_Glossiness", 0.07f);
					}
					if (val3.HasProperty("_Metallic"))
					{
						val3.SetFloat("_Metallic", 0f);
					}
					array2[i] = true;
					num++;
				}
				array[i] = val3;
			}
			if (num == 0)
			{
				throw new InvalidOperationException("Cob Oven surface atlas was not resolved; refusing to hide original masonry");
			}
			ApplyNaturalUVSelective(val, array2);
			if (materials.Length == 5 && val.subMeshCount >= 5)
			{
				val.SetTriangles(new int[0], 4);
			}
			GameObject val7 = new GameObject("S11_CobOven_ApprovedGeometry");
			val7.transform.SetParent(oven.transform, false);
			val7.AddComponent<MeshFilter>().sharedMesh = val;
			MeshRenderer val8 = val7.AddComponent<MeshRenderer>();
			((Renderer)val8).sharedMaterials = array;
			((Renderer)val8).enabled = true;
			MeshRenderer[] componentsInChildren = oven.GetComponentsInChildren<MeshRenderer>(true);
			foreach (MeshRenderer val9 in componentsInChildren)
			{
				if (!((Object)(object)val9 == (Object)null) && !((Object)(object)val9 == (Object)(object)val8) && !IsFireVisual(val9))
				{
					((Renderer)val9).enabled = false;
				}
			}
			return num;
		}

		private static bool IsFireVisual(MeshRenderer renderer)
		{
			string text = (((Object)((Component)renderer).gameObject).name ?? "").ToLowerInvariant();
			if (text.Contains("fire") || text.Contains("flame") || text.Contains("ember") || text.Contains("spark") || text.Contains("glow"))
			{
				return true;
			}
			Material[] sharedMaterials = ((Renderer)renderer).sharedMaterials;
			foreach (Material val in sharedMaterials)
			{
				if (!((Object)(object)val == (Object)null))
				{
					string text2 = (((Object)val).name ?? "").ToLowerInvariant();
					if (text2.Contains("flame") || text2.Contains("fire") || text2.Contains("ember") || text2.Contains("spark"))
					{
						return true;
					}
				}
			}
			return false;
		}

		private static string FinishFor(Texture2D texture)
		{
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)texture == (Object)null)
			{
				return null;
			}
			string text = ((Object)texture).name ?? "";
			if (text.IndexOf("CobOven_tex0", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return "OvenClay";
			}
			if (text.IndexOf("CobOven_tex1", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return "OvenStone";
			}
			if (text.IndexOf("CobOven_tex2", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return "OvenStone";
			}
			if (text.IndexOf("CobOven_tex3", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return "OvenArch";
			}
			if (text.IndexOf("CobOven_tex4", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return null;
			}
			try
			{
				Color pixel = texture.GetPixel(0, 0);
				if (Mathf.Abs(pixel.r - pixel.g) < 0.045f && Mathf.Abs(pixel.g - pixel.b) < 0.045f && pixel.r > 0.5f && pixel.r < 0.69f)
				{
					return "OvenStone";
				}
				if (pixel.r > 0.76f && pixel.g > 0.61f && pixel.g < 0.75f && pixel.b > 0.36f && pixel.b < 0.58f)
				{
					return "OvenClay";
				}
			}
			catch
			{
			}
			return null;
		}

		private static void ApplyNaturalUVSelective(Mesh mesh, bool[] surfaceMaterial)
		{
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: 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_00fb: 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_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: 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_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: 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)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			Vector3[] vertices = mesh.vertices;
			Vector3[] normals = mesh.normals;
			Vector2[] array = mesh.uv;
			if (array == null || array.Length != vertices.Length)
			{
				array = (Vector2[])(object)new Vector2[vertices.Length];
			}
			bool[] array2 = new bool[vertices.Length];
			for (int i = 0; i < mesh.subMeshCount; i++)
			{
				if (i < surfaceMaterial.Length && surfaceMaterial[i])
				{
					continue;
				}
				int[] triangles = mesh.GetTriangles(i);
				foreach (int num in triangles)
				{
					if (num >= 0 && num < array2.Length)
					{
						array2[num] = true;
					}
				}
			}
			for (int k = 0; k < vertices.Length; k++)
			{
				if (!array2[k])
				{
					Vector3 val = vertices[k];
					Vector3 val2 = ((normals != null && k < normals.Length) ? normals[k] : Vector3.up);
					if (Mathf.Abs(val2.y) > 0.66f)
					{
						array[k] = new Vector2(val.x * 2.4f, val.z * 2.4f);
					}
					else if (Mathf.Abs(val2.x) > Mathf.Abs(val2.z))
					{
						array[k] = new Vector2(val.z * 2.4f, val.y * 2.4f);
					}
					else
					{
						array[k] = new Vector2(val.x * 2.4f, val.y * 2.4f);
					}
				}
			}
			mesh.uv = array;
		}

		private static void GetOriginalAppearance(out Mesh mesh, out Material[] materials)
		{
			Type type = null;
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			for (int i = 0; i < assemblies.Length; i++)
			{
				type = assemblies[i].GetType("DelGryphon.PieGuy.PieGuyPlugin", throwOnError: false);
				if (type != null)
				{
					break;
				}
			}
			if (type == null)
			{
				throw new InvalidOperationException("R41 PieGuy core resource provider missing");
			}
			Object[] array = Resources.FindObjectsOfTypeAll(type);
			if (array == null || array.Length == 0)
			{
				throw new InvalidOperationException("R41 PieGuy core plugin instance unavailable");
			}
			object obj = array[0];
			BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
			MethodInfo method = type.GetMethod("LoadMesh", bindingAttr);
			MethodInfo method2 = type.GetMethod("LoadMaterials", bindingAttr);
			if (method == null || method2 == null)
			{
				throw new InvalidOperationException("Original cob mesh/material loaders not found");
			}
			object? obj2 = method.Invoke(obj, new object[1] { "CobOven" });
			mesh = (Mesh)((obj2 is Mesh) ? obj2 : null);
			materials = method2.Invoke(obj, new object[1] { "CobOven" }) as Material[];
			if ((Object)(object)mesh == (Object)null || materials == null || materials.Length == 0)
			{
				throw new InvalidOperationException("Approved cob oven mesh or materials not available");
			}
		}
	}
}

PieGuy.WildWheat.dll

Decompiled 3 days ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
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: 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 DelGryphon.PieGuy.WildWheat
{
	[BepInPlugin("delgryphon.pieguy.wildwheatr39", "PieGuy Wild Wheat Meadows", "0.1.90")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class WildWheatPlugin : BaseUnityPlugin
	{
		private bool _added;

		private void Awake()
		{
			PrefabManager.OnVanillaPrefabsAvailable += RegisterIfReady;
			ZoneManager.OnVanillaLocationsAvailable += RegisterIfReady;
		}

		private void OnDestroy()
		{
			PrefabManager.OnVanillaPrefabsAvailable -= RegisterIfReady;
			ZoneManager.OnVanillaLocationsAvailable -= RegisterIfReady;
		}

		private static GameObject FindWildWheatPrefab()
		{
			GameObject val = null;
			try
			{
				val = PrefabManager.Instance.GetPrefab("Pickable_Wheat_Wild");
			}
			catch
			{
			}
			if ((Object)(object)val == (Object)null)
			{
				try
				{
					val = PrefabManager.Instance.GetPrefab("PG_WheatWild");
				}
				catch
				{
				}
			}
			if ((Object)(object)val == (Object)null && (Object)(object)ZNetScene.instance != (Object)null)
			{
				try
				{
					val = ZNetScene.instance.GetPrefab("Pickable_Wheat_Wild");
				}
				catch
				{
				}
			}
			return val;
		}

		private void RegisterIfReady()
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: 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_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: 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_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Expected O, but got Unknown
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Expected O, but got Unknown
			if (_added)
			{
				return;
			}
			try
			{
				GameObject val = FindWildWheatPrefab();
				if ((Object)(object)val == (Object)null)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)"[PieGuy R39 WildWheat] Harvestable wheat prefab not yet available. Will retry at zone registration; no substitute prefab spawned.");
					return;
				}
				VegetationConfig val2 = new VegetationConfig
				{
					Biome = (Biome)1,
					BlockCheck = true,
					Min = 1f,
					Max = 2f,
					GroupSizeMin = 3,
					GroupSizeMax = 5,
					GroupRadius = 5f,
					MinAltitude = 1f,
					MaxAltitude = 1000f,
					MaxTilt = 25f,
					MinOceanDepth = 0f,
					MaxOceanDepth = 0f,
					ScaleMin = 0.92f,
					ScaleMax = 1.08f
				};
				CustomVegetation val3 = new CustomVegetation(val, false, val2);
				if (!ZoneManager.Instance.AddCustomVegetation(val3))
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)"[PieGuy R39 WildWheat] Jotunn rejected wheat vegetation registration; no extra wheat generated.");
					return;
				}
				_added = true;
				((BaseUnityPlugin)this).Logger.LogInfo((object)"[PieGuy R39 WildWheat] Registered Meadows wild wheat: 1-2 patches/zone; 3-5 plants/patch; radius 5m. New/unexplored zones only.");
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("[PieGuy R39 WildWheat] Registration failed: " + ex));
			}
		}
	}
}

PieGuy.dll

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

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("PieGuy")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.12.0")]
[assembly: AssemblyInformationalVersion("0.1.12+1d5fab05793be83d903cd0346bbd0f85bb5e4bf9")]
[assembly: AssemblyProduct("PieGuy")]
[assembly: AssemblyTitle("PieGuy")]
[assembly: AssemblyVersion("0.1.12.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 DelGryphon.PieGuy
{
	[BepInPlugin("delgryphon.pieguy", "PieGuy", "0.1.12")]
	[BepInDependency("com.jotunn.jotunn", "2.30.2")]
	public sealed class PieGuyPlugin : BaseUnityPlugin
	{
		public sealed class CobOvenSmokeWhileCooking : MonoBehaviour
		{
			public CookingStation Station;

			public GameObject ChimneySmoke;

			private ZNetView view;

			private float nextPoll;

			private void Awake()
			{
				view = ((Component)this).GetComponent<ZNetView>();
			}

			private void Update()
			{
			}
		}

		public sealed class WheatDropTumble : MonoBehaviour
		{
			private void Start()
			{
				//IL_0061: Unknown result type (might be due to invalid IL or missing references)
				ZNetView component = ((Component)this).GetComponent<ZNetView>();
				if (!((Object)(object)component != (Object)null) || (component.IsValid() && component.IsOwner()))
				{
					Rigidbody component2 = ((Component)this).GetComponent<Rigidbody>();
					if (!((Object)(object)component2 == (Object)null))
					{
						component2.maxAngularVelocity = 8f;
						component2.AddTorque(new Vector3(Random.Range(0.15f, 0.36f), 0f, Random.Range(0.13f, 0.32f)), (ForceMode)1);
					}
				}
			}
		}

		private Dictionary<string, byte[]> embedded;

		private readonly Dictionary<string, Mesh> meshes = new Dictionary<string, Mesh>();

		private readonly Dictionary<string, Sprite> icons = new Dictionary<string, Sprite>();

		private readonly Dictionary<string, Material[]> visuals = new Dictionary<string, Material[]>();

		private bool registered;

		private GameObject wheatPrefab;

		private void Awake()
		{
			PrefabManager.OnVanillaPrefabsAvailable += Register;
		}

		private void OnDestroy()
		{
			PrefabManager.OnVanillaPrefabsAvailable -= Register;
		}

		private void Register()
		{
			if (!registered)
			{
				registered = true;
				PrefabManager.OnVanillaPrefabsAvailable -= Register;
				((BaseUnityPlugin)this).Logger.LogInfo((object)"PieGuy 0.1.12: oven interaction and item output alignment, visible cooking chimney smoke and vanilla-strength firelight");
				TryAdd("Wheat inventory item", RegisterWheatItem);
				TryAdd("Wheat crop", RegisterWheatCrop);
				TryAdd("Cob Oven", RegisterCookingOven);
				TryAdd("Quern", delegate
				{
					RegisterPiece("PG_Quern", "Quern", "Quern", "PieGuy original hand mill. Preview build, grinding not yet enabled.", "Crafting", "Stone");
				});
			}
		}

		private void TryAdd(string label, Action register)
		{
			try
			{
				register();
				((BaseUnityPlugin)this).Logger.LogInfo((object)("PieGuy registered: " + label));
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Sapling_Wheat" + label + "): " + ex));
			}
		}

		private void RegisterWheatItem()
		{
			//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_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: 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_0054: Expected O, but got Unknown
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			Sprite val = LoadIcon("Wheat");
			ItemConfig val2 = new ItemConfig
			{
				Name = "Wheat",
				Description = "A bundle of wheat stalks. Plant it on cultivated soil using the Cultivator. Milling and baking are coming later.",
				Icon = val,
				CraftingStation = "piece_workbench",
				Amount = 1,
				Weight = 0.5f,
				StackSize = 50
			};
			val2.AddRequirement("Wood", 1, 0);
			CustomItem val3 = new CustomItem("Wheat", true, val2);
			if ((Object)(object)val3.ItemPrefab == (Object)null || (Object)(object)val3.ItemDrop == (Object)null)
			{
				throw new InvalidOperationException("Wheat independent item prefab unavailable");
			}
			ApplyMesh(val3.ItemPrefab, "Wheat", 1f);
			ItemData itemData = val3.ItemDrop.m_itemData;
			itemData.m_shared.m_itemType = (ItemType)1;
			itemData.m_shared.m_weight = 0.5f;
			itemData.m_shared.m_maxStackSize = 50;
			itemData.m_shared.m_icons = (Sprite[])(object)new Sprite[1] { val };
			itemData.m_dropPrefab = val3.ItemPrefab;
			Rigidbody val4 = val3.ItemPrefab.GetComponent<Rigidbody>();
			if ((Object)(object)val4 == (Object)null)
			{
				val4 = val3.ItemPrefab.AddComponent<Rigidbody>();
			}
			val4.mass = 0.4f;
			val4.useGravity = true;
			val4.collisionDetectionMode = (CollisionDetectionMode)2;
			val4.angularDrag = 0.15f;
			val4.centerOfMass = new Vector3(0f, 0.73f, 0f);
			BoxCollider component = val3.ItemPrefab.GetComponent<BoxCollider>();
			if ((Object)(object)component != (Object)null)
			{
				component.center = new Vector3(0f, 0.48f, 0f);
				component.size = new Vector3(0.19f, 0.94f, 0.19f);
			}
			val3.ItemPrefab.AddComponent<WheatDropTumble>();
			if (!ItemManager.Instance.AddItem(val3))
			{
				throw new InvalidOperationException("Jotunn rejected Wheat item");
			}
			wheatPrefab = val3.ItemPrefab;
		}

		private void RegisterWheatCrop()
		{
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Expected O, but got Unknown
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Expected O, but got Unknown
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Expected O, but got Unknown
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)wheatPrefab == (Object)null)
			{
				throw new InvalidOperationException("Wheat item did not register");
			}
			GameObject val = PrefabManager.Instance.CreateClonedPrefab("Pickable_Wheat_Wild", "Pickable_Barley");
			if ((Object)(object)val == (Object)null)
			{
				throw new InvalidOperationException("Native Pickable_Barley unavailable");
			}
			Pickable component = val.GetComponent<Pickable>();
			if ((Object)(object)component == (Object)null)
			{
				throw new InvalidOperationException("Wheat mature prefab needs Pickable");
			}
			component.m_itemPrefab = wheatPrefab;
			component.m_amount = 2;
			component.m_overrideName = "Wheat";
			component.m_respawnTimeMinutes = 0f;
			ReplaceCropVisual(val, 1f, "Wheat_Ripe");
			PrefabManager.Instance.AddPrefab(val);
			PieceConfig val2 = new PieceConfig();
			val2.Name = "Wheat";
			val2.Description = "Plant wheat on cultivated ground. Harvest the mature stalks for two wheat.";
			val2.PieceTable = "_CultivatorPieceTable";
			val2.Category = "Misc";
			val2.Icon = LoadIcon("Wheat");
			val2.Requirements = (RequirementConfig[])(object)new RequirementConfig[1]
			{
				new RequirementConfig("Wheat", 1, 0, true)
			};
			PieceConfig val3 = val2;
			CustomPiece val4 = new CustomPiece("Sapling_Wheat", "sapling_barley", val3);
			if ((Object)(object)val4.PiecePrefab == (Object)null || (Object)(object)val4.Piece == (Object)null)
			{
				throw new InvalidOperationException("Native sapling_barley unavailable");
			}
			Plant component2 = val4.PiecePrefab.GetComponent<Plant>();
			if ((Object)(object)component2 == (Object)null)
			{
				throw new InvalidOperationException("Cloned wheat seedling has no Plant component");
			}
			val4.Piece.m_cultivatedGroundOnly = true;
			component2.m_needCultivatedGround = true;
			component2.m_name = "Wheat";
			component2.m_biome = (Biome)25;
			component2.m_grownPrefabs = (GameObject[])(object)new GameObject[1] { val };
			component2.m_growTime = 4000f;
			component2.m_growTimeMax = 5000f;
			ReplaceGrowingWheatVisuals(val4.PiecePrefab, component2);
			if (!PieceManager.Instance.AddPiece(val4))
			{
				throw new InvalidOperationException("Jotunn rejected cultivator wheat");
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)"PieGuy: wheat cultivar registered; crop grows into PG_WheatMature and yields PG_Wheat x2.");
		}

		private void ReplaceCropVisual(GameObject prefab, float scale, string visualName)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: 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)
			Renderer[] componentsInChildren = prefab.GetComponentsInChildren<Renderer>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				componentsInChildren[i].enabled = false;
			}
			GameObject val = new GameObject("PG_" + visualName + "_Mesh");
			val.transform.SetParent(prefab.transform, false);
			val.transform.localPosition = Vector3.zero;
			val.transform.localRotation = Quaternion.identity;
			val.transform.localScale = Vector3.one * scale;
			val.AddComponent<MeshFilter>().sharedMesh = LoadMesh("Wheat");
			MeshRenderer obj = val.AddComponent<MeshRenderer>();
			((Renderer)obj).sharedMaterials = LoadMaterials("Wheat");
			((Renderer)obj).enabled = true;
			int num = LayerMask.NameToLayer("piece");
			if (num >= 0)
			{
				val.layer = num;
			}
		}

		private void ReplaceGrowingWheatVisuals(GameObject prefab, Plant plant)
		{
			Renderer[] componentsInChildren = prefab.GetComponentsInChildren<Renderer>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				componentsInChildren[i].enabled = false;
			}
			GameObject val = CreateWheatPhase(prefab, "WheatYoung", "Wheat_Young_Healthy", unhealthy: false);
			GameObject val2 = CreateWheatPhase(prefab, "WheatMid", "Wheat_Mid_Healthy", unhealthy: false);
			GameObject val3 = CreateWheatPhase(prefab, "WheatYoung", "Wheat_Young_Unhealthy", unhealthy: true);
			GameObject val4 = CreateWheatPhase(prefab, "WheatMid", "Wheat_Mid_Unhealthy", unhealthy: true);
			BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic;
			SetPlantVisual(plant, "m_healthy", val, flags);
			SetPlantVisual(plant, "m_unhealthy", val3, flags);
			SetPlantVisual(plant, "m_healthyGrown", val2, flags);
			SetPlantVisual(plant, "m_unhealthyGrown", val4, flags);
			val.SetActive(true);
			val2.SetActive(false);
			val3.SetActive(false);
			val4.SetActive(false);
		}

		private static void SetPlantVisual(Plant plant, string name, GameObject go, BindingFlags flags)
		{
			FieldInfo? field = typeof(Plant).GetField(name, flags);
			if (field == null)
			{
				throw new MissingFieldException("Plant." + name);
			}
			field.SetValue(plant, go);
		}

		private GameObject CreateWheatPhase(GameObject root, string meshName, string objName, bool unhealthy)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("PG_" + objName);
			val.transform.SetParent(root.transform, false);
			val.transform.localPosition = Vector3.zero;
			val.transform.localRotation = Quaternion.identity;
			val.transform.localScale = Vector3.one;
			val.AddComponent<MeshFilter>().sharedMesh = LoadMesh(meshName);
			MeshRenderer obj = val.AddComponent<MeshRenderer>();
			((Renderer)obj).sharedMaterials = LoadMaterials(meshName);
			((Renderer)obj).enabled = true;
			int num = LayerMask.NameToLayer("piece");
			if (num >= 0)
			{
				val.layer = num;
			}
			return val;
		}

		private void RegisterCookingOven()
		{
		}

		private void RepositionOvenEffects(GameObject prefab, CookingStation station)
		{
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02be: Expected O, but got Unknown
			//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e0: Expected O, but got Unknown
			//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0309: Unknown result type (might be due to invalid IL or missing references)
			//IL_030e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0327: Unknown result type (might be due to invalid IL or missing references)
			//IL_0338: Unknown result type (might be due to invalid IL or missing references)
			//IL_0349: Unknown result type (might be due to invalid IL or missing references)
			//IL_0369: Unknown result type (might be due to invalid IL or missing references)
			//IL_036e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0381: Unknown result type (might be due to invalid IL or missing references)
			//IL_0386: Unknown result type (might be due to invalid IL or missing references)
			//IL_038f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0399: Unknown result type (might be due to invalid IL or missing references)
			//IL_039e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0526: Unknown result type (might be due to invalid IL or missing references)
			//IL_051d: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04de: Expected O, but got Unknown
			//IL_084c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0853: Expected O, but got Unknown
			//IL_0877: Unknown result type (might be due to invalid IL or missing references)
			//IL_0888: Unknown result type (might be due to invalid IL or missing references)
			//IL_088d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0892: Unknown result type (might be due to invalid IL or missing references)
			//IL_0990: Unknown result type (might be due to invalid IL or missing references)
			//IL_09aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_08de: Unknown result type (might be due to invalid IL or missing references)
			//IL_08e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_08f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_090d: Unknown result type (might be due to invalid IL or missing references)
			//IL_082c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0831: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = prefab.transform;
			Vector3 localPosition = default(Vector3);
			((Vector3)(ref localPosition))..ctor(0f, 0.72f, -0.57f);
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(0f, 1.7505661f, 0.25802574f);
			int num = 0;
			int num2 = 0;
			Component[] componentsInChildren = prefab.GetComponentsInChildren<Component>(true);
			foreach (Component val2 in componentsInChildren)
			{
				Behaviour val3 = (Behaviour)(object)((val2 is SmokeSpawner) ? val2 : null);
				if (val3 != null)
				{
					val3.enabled = false;
					num++;
				}
				val3 = (Behaviour)(object)((val2 is Collider) ? val2 : null);
				if (val3 != null)
				{
					((Collider)val3).isTrigger = true;
				}
			}
			HashSet<ParticleSystem> hashSet = new HashSet<ParticleSystem>();
			Transform[] slots = station.m_slots;
			ParticleSystem[] componentsInChildren2;
			foreach (Transform val4 in slots)
			{
				if (!((Object)(object)val4 == (Object)null))
				{
					componentsInChildren2 = ((Component)val4).GetComponentsInChildren<ParticleSystem>(true);
					foreach (ParticleSystem item in componentsInChildren2)
					{
						hashSet.Add(item);
					}
				}
			}
			if (station.m_donePS != null)
			{
				componentsInChildren2 = station.m_donePS;
				foreach (ParticleSystem val5 in componentsInChildren2)
				{
					if ((Object)(object)val5 != (Object)null)
					{
						hashSet.Add(val5);
					}
				}
			}
			if (station.m_burntPS != null)
			{
				componentsInChildren2 = station.m_burntPS;
				foreach (ParticleSystem val6 in componentsInChildren2)
				{
					if ((Object)(object)val6 != (Object)null)
					{
						hashSet.Add(val6);
					}
				}
			}
			componentsInChildren2 = prefab.GetComponentsInChildren<ParticleSystem>(true);
			foreach (ParticleSystem val7 in componentsInChildren2)
			{
				if (!hashSet.Contains(val7))
				{
					EmissionModule emission = val7.emission;
					((EmissionModule)(ref emission)).enabled = false;
					val7.Stop(true, (ParticleSystemStopBehavior)0);
					num2++;
				}
			}
			GameObject haveFireObject = station.m_haveFireObject;
			Light val8 = null;
			float num3 = -1f;
			Light[] componentsInChildren3 = prefab.GetComponentsInChildren<Light>(true);
			foreach (Light val9 in componentsInChildren3)
			{
				float num4 = val9.intensity * val9.range;
				if (num4 > num3)
				{
					val8 = val9;
					num3 = num4;
				}
			}
			if ((Object)(object)haveFireObject != (Object)null && (Object)(object)haveFireObject != (Object)(object)prefab)
			{
				haveFireObject.SetActive(false);
			}
			GameObject haveFuelObject = station.m_haveFuelObject;
			station.m_haveFuelObject = null;
			if ((Object)(object)haveFuelObject != (Object)null && (Object)(object)haveFuelObject != (Object)(object)prefab && ((Object)(object)station.m_addFoodSwitch == (Object)null || !((Component)station.m_addFoodSwitch).transform.IsChildOf(haveFuelObject.transform)) && ((Object)(object)station.m_addFuelSwitch == (Object)null || !((Component)station.m_addFuelSwitch).transform.IsChildOf(haveFuelObject.transform)))
			{
				haveFuelObject.SetActive(false);
			}
			GameObject val10 = new GameObject("PG_WoodFuelVisibleFlames");
			val10.transform.SetParent(transform, false);
			station.m_haveFireObject = val10;
			GameObject val11 = new GameObject("PG_InnerFireOverLogs");
			val11.transform.SetParent(val10.transform, false);
			val11.transform.localPosition = localPosition;
			ParticleSystem obj = val11.AddComponent<ParticleSystem>();
			MainModule main = obj.main;
			((MainModule)(ref main)).loop = true;
			((MainModule)(ref main)).playOnAwake = true;
			((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(0.5f);
			((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(0.3f);
			((MainModule)(ref main)).startSize = MinMaxCurve.op_Implicit(0.23f);
			((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(new Color(1f, 0.51f, 0.11f, 0.95f));
			((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)0;
			EmissionModule emission2 = obj.emission;
			((EmissionModule)(ref emission2)).rateOverTime = MinMaxCurve.op_Implicit(26f);
			ShapeModule shape = obj.shape;
			((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)4;
			((ShapeModule)(ref shape)).radius = 0.16f;
			((ShapeModule)(ref shape)).angle = 17f;
			ParticleSystemRenderer component = val11.GetComponent<ParticleSystemRenderer>();
			component.renderMode = (ParticleSystemRenderMode)0;
			Material val12 = null;
			Material val13 = null;
			GameObject prefab2 = PrefabManager.Instance.GetPrefab("fire_pit");
			if ((Object)(object)prefab2 != (Object)null)
			{
				componentsInChildren2 = prefab2.GetComponentsInChildren<ParticleSystem>(true);
				foreach (ParticleSystem val14 in componentsInChildren2)
				{
					ParticleSystemRenderer component2 = ((Component)val14).GetComponent<ParticleSystemRenderer>();
					if (!((Object)(object)component2 == (Object)null) && !((Object)(object)((Renderer)component2).sharedMaterial == (Object)null))
					{
						string text = ((Object)val14).name.ToLowerInvariant();
						if ((Object)(object)val13 == (Object)null && text.Contains("smoke"))
						{
							val13 = ((Renderer)component2).sharedMaterial;
						}
						if ((Object)(object)val12 == (Object)null && (text.Contains("fire") || text.Contains("flame")))
						{
							val12 = ((Renderer)component2).sharedMaterial;
						}
					}
				}
			}
			if ((Object)(object)val12 == (Object)null)
			{
				Shader val15 = Shader.Find("Legacy Shaders/Particles/Additive");
				if ((Object)(object)val15 == (Object)null)
				{
					val15 = Shader.Find("Particles/Standard Unlit");
				}
				if ((Object)(object)val15 != (Object)null)
				{
					val12 = new Material(val15);
				}
			}
			if ((Object)(object)val12 != (Object)null)
			{
				((Renderer)component).sharedMaterial = val12;
			}
			Light val16 = val11.AddComponent<Light>();
			val16.type = (LightType)2;
			val16.color = (Color)(((Object)(object)val8 != (Object)null) ? val8.color : new Color(1f, 0.48f, 0.18f));
			val16.intensity = (((Object)(object)val8 != (Object)null && val8.intensity > 0f) ? val8.intensity : 2.5f);
			val16.range = (((Object)(object)val8 != (Object)null && val8.range > 1f) ? val8.range : 6f);
			val16.shadows = (LightShadows)0;
			((BaseUnityPlugin)this).Logger.LogInfo((object)("PieGuy: copied Stone Oven firelight: intensity=" + val16.intensity + ", range=" + val16.range));
			int num5 = station.m_slots.Length;
			for (int k = 0; k < num5; k++)
			{
				Transform val17 = station.m_slots[k];
				if (!((Object)(object)val17 == (Object)null))
				{
					float num6 = ((num5 == 1) ? 0f : Mathf.Lerp(-0.3f, 0.3f, (float)k / (float)(num5 - 1)));
					val17.position = transform.TransformPoint(new Vector3(num6, 0.93f, -0.25802574f));
				}
			}
			GameObject val18 = new GameObject("PG_CobOven_ForwardOutput");
			val18.transform.SetParent(transform, false);
			val18.transform.localPosition = new Vector3(0f, 1.0430456f, -0.7265461f);
			val18.transform.localRotation = Quaternion.LookRotation(Vector3.back, Vector3.up);
			station.m_spawnPoint = val18.transform;
			station.m_spawnForce = 3.3f;
			if ((Object)(object)station.m_addFuelSwitch != (Object)null)
			{
				Switch addFuelSwitch = station.m_addFuelSwitch;
				((Component)addFuelSwitch).transform.position = transform.TransformPoint(new Vector3(0f, 0.77f, -0.68f));
				((Component)addFuelSwitch).transform.rotation = transform.rotation;
				ExpandInteraction(addFuelSwitch, new Vector3(0.66f, 0.3f, 0.23f));
			}
			station.m_addFoodSwitch = null;
			BoxCollider obj2 = prefab.AddComponent<BoxCollider>();
			obj2.center = new Vector3(0f, 0.825f, 0.03f);
			obj2.size = new Vector3(1.04f, 1.65f, 1.06f);
			((Collider)obj2).isTrigger = false;
		}

		private static void ExpandInteraction(Switch sw, Vector3 size)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			BoxCollider obj = ((Component)sw).gameObject.AddComponent<BoxCollider>();
			obj.center = Vector3.zero;
			obj.size = size;
			((Collider)obj).isTrigger = true;
		}

		private void RegisterPiece(string prefabId, string model, string title, string description, string category, string cost)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected O, but got Unknown
			PieceConfig val = new PieceConfig();
			val.Name = title;
			val.Description = description;
			val.PieceTable = "Hammer";
			val.Category = category;
			val.Icon = LoadIcon(model);
			val.Requirements = (RequirementConfig[])(object)new RequirementConfig[1]
			{
				new RequirementConfig(cost, 1, 0, true)
			};
			PieceConfig val2 = val;
			CustomPiece val3 = new CustomPiece(prefabId, true, val2);
			if ((Object)(object)val3.PiecePrefab == (Object)null || (Object)(object)val3.Piece == (Object)null)
			{
				throw new InvalidOperationException("Independent piece prefab unavailable: " + prefabId);
			}
			ApplyMesh(val3.PiecePrefab, model, 1f);
			if (!PieceManager.Instance.AddPiece(val3))
			{
				throw new InvalidOperationException("Jotunn rejected piece " + prefabId);
			}
		}

		private void ApplyMesh(GameObject prefab, string model, float modelScale)
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			Mesh val = LoadMesh(model);
			Material[] sharedMaterials = LoadMaterials(model);
			MeshFilter component = prefab.GetComponent<MeshFilter>();
			MeshRenderer component2 = prefab.GetComponent<MeshRenderer>();
			BoxCollider component3 = prefab.GetComponent<BoxCollider>();
			if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null || (Object)(object)component3 == (Object)null)
			{
				throw new InvalidOperationException("PieGuy primitive lacks renderer or collider for " + model);
			}
			component.sharedMesh = val;
			((Renderer)component2).sharedMaterials = sharedMaterials;
			((Renderer)component2).enabled = true;
			prefab.transform.localScale = Vector3.one * modelScale;
			Bounds bounds = val.bounds;
			component3.center = ((Bounds)(ref bounds)).center;
			Vector3 size = ((Bounds)(ref bounds)).size;
			component3.size = new Vector3(Mathf.Max(0.18f, size.x), Mathf.Max(0.08f, size.y), Mathf.Max(0.18f, size.z));
			((Collider)component3).isTrigger = false;
		}

		private Mesh LoadMesh(string name)
		{
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: 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_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Expected O, but got Unknown
			if (meshes.TryGetValue(name, out var value))
			{
				return value;
			}
			using BinaryReader binaryReader = new BinaryReader(new MemoryStream(ReadAsset(name + ".pgm")));
			if (Encoding.ASCII.GetString(binaryReader.ReadBytes(4)) != "PGM2")
			{
				throw new InvalidDataException("Pickable_Wheat_Wild" + name);
			}
			int num = checked((int)binaryReader.ReadUInt32());
			int num2 = binaryReader.ReadByte();
			if (num < 3 || num > 120000 || num2 < 1 || num2 > 16)
			{
				throw new InvalidDataException("Invalid mesh counts: " + name);
			}
			Color[] array = (Color[])(object)new Color[num2];
			for (int i = 0; i < num2; i++)
			{
				array[i] = new Color(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle(), 1f);
			}
			Vector3[] array2 = (Vector3[])(object)new Vector3[num];
			Vector2[] array3 = (Vector2[])(object)new Vector2[num];
			for (int j = 0; j < num; j++)
			{
				float num3 = binaryReader.ReadSingle();
				float num4 = binaryReader.ReadSingle();
				float num5 = binaryReader.ReadSingle();
				array2[j] = new Vector3(num3, num4, num5);
				array3[j] = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle());
			}
			Mesh val = new Mesh();
			((Object)val).name = "PG_Original_" + name;
			if (num > 65000)
			{
				val.indexFormat = (IndexFormat)1;
			}
			val.vertices = array2;
			val.uv = array3;
			val.subMeshCount = num2;
			for (int k = 0; k < num2; k++)
			{
				int num6 = checked((int)binaryReader.ReadUInt32());
				if (num6 < 3 || num6 > 100000 || num6 % 3 != 0)
				{
					throw new InvalidDataException("Invalid triangle count: " + name);
				}
				int[] array4 = new int[num6];
				for (int l = 0; l < num6; l++)
				{
					int num7 = checked((int)binaryReader.ReadUInt32());
					if (num7 >= num)
					{
						throw new InvalidDataException("Invalid vertex index in " + name);
					}
					array4[l] = num7;
				}
				val.SetTriangles(array4, k, false);
			}
			if (binaryReader.BaseStream.Position != binaryReader.BaseStream.Length)
			{
				throw new InvalidDataException("Unexpected bytes in PieGuy mesh " + name);
			}
			val.RecalculateNormals();
			val.RecalculateBounds();
			meshes.Add(name, val);
			return val;
		}

		private Material[] LoadMaterials(string name)
		{
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Expected O, but got Unknown
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0347: Unknown result type (might be due to invalid IL or missing references)
			if (visuals.TryGetValue(name, out var value))
			{
				return value;
			}
			Color[] array;
			using (BinaryReader binaryReader = new BinaryReader(new MemoryStream(ReadAsset(name + ".pgm"))))
			{
				binaryReader.ReadBytes(4);
				binaryReader.ReadUInt32();
				int num = binaryReader.ReadByte();
				array = (Color[])(object)new Color[num];
				for (int i = 0; i < num; i++)
				{
					array[i] = new Color(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle(), 1f);
				}
			}
			Material val = null;
			string[] array2 = new string[3] { "piece_workbench", "wood_wall", "stone_wall_2x1" };
			foreach (string text in array2)
			{
				GameObject prefab = PrefabManager.Instance.GetPrefab(text);
				if ((Object)(object)prefab == (Object)null)
				{
					continue;
				}
				MeshRenderer[] componentsInChildren = prefab.GetComponentsInChildren<MeshRenderer>(true);
				foreach (MeshRenderer val2 in componentsInChildren)
				{
					if (!((Object)(object)((Renderer)val2).sharedMaterial == (Object)null))
					{
						val = ((Renderer)val2).sharedMaterial;
						break;
					}
				}
				if ((Object)(object)val != (Object)null)
				{
					break;
				}
			}
			bool flag = true;
			Shader val3 = null;
			if (flag)
			{
				val3 = Shader.Find("Standard");
				if ((Object)(object)val3 == (Object)null)
				{
					val3 = Shader.Find("Legacy Shaders/Diffuse");
				}
				if ((Object)(object)val3 == (Object)null)
				{
					GameObject prefab2 = PrefabManager.Instance.GetPrefab("stone_wall_2x1");
					if ((Object)(object)prefab2 != (Object)null)
					{
						MeshRenderer[] componentsInChildren = prefab2.GetComponentsInChildren<MeshRenderer>(true);
						foreach (MeshRenderer val4 in componentsInChildren)
						{
							if (!((Object)(object)((Renderer)val4).sharedMaterial == (Object)null))
							{
								val3 = ((Renderer)val4).sharedMaterial.shader;
								break;
							}
						}
					}
				}
				if ((Object)(object)val3 == (Object)null)
				{
					throw new InvalidOperationException("Cannot find any static building shader for " + name);
				}
				((BaseUnityPlugin)this).Logger.LogInfo((object)("PieGuy " + name + ": static shader " + ((Object)val3).name));
			}
			if (!flag && (Object)(object)val == (Object)null)
			{
				throw new InvalidOperationException("No existing Wheat material available");
			}
			Material[] array3 = (Material[])(object)new Material[array.Length];
			for (int l = 0; l < array.Length; l++)
			{
				Material val5 = (flag ? new Material(val3) : new Material(val));
				((Object)val5).name = "PG_" + name + "_Material_" + l;
				Texture2D val6 = (Texture2D)(object)(val5.mainTexture = (Texture)(object)LoadSurfaceTexture(name, l));
				val5.color = Color.white;
				if (val5.HasProperty("_MainTex"))
				{
					val5.SetTexture("_MainTex", (Texture)(object)val6);
				}
				if (val5.HasProperty("_BaseMap"))
				{
					val5.SetTexture("_BaseMap", (Texture)(object)val6);
				}
				if (val5.HasProperty("_Color"))
				{
					val5.SetColor("_Color", Color.white);
				}
				if (val5.HasProperty("_BaseColor"))
				{
					val5.SetColor("_BaseColor", Color.white);
				}
				if (val5.HasProperty("_Glossiness"))
				{
					val5.SetFloat("_Glossiness", 0.12f);
				}
				if (val5.HasProperty("_Metallic"))
				{
					val5.SetFloat("_Metallic", 0f);
				}
				if (val5.HasProperty("_EmissionColor"))
				{
					val5.SetColor("_EmissionColor", Color.black);
				}
				val5.DisableKeyword("_NORMALMAP");
				val5.DisableKeyword("_PARALLAXMAP");
				val5.DisableKeyword("_DETAIL_MULX2");
				val5.DisableKeyword("_EMISSION");
				if (val5.HasProperty("_BumpMap"))
				{
					val5.SetTexture("_BumpMap", (Texture)null);
				}
				if (val5.HasProperty("_DetailNormalMap"))
				{
					val5.SetTexture("_DetailNormalMap", (Texture)null);
				}
				if (val5.HasProperty("_ParallaxMap"))
				{
					val5.SetTexture("_ParallaxMap", (Texture)null);
				}
				if (val5.HasProperty("_OcclusionMap"))
				{
					val5.SetTexture("_OcclusionMap", (Texture)null);
				}
				if (val5.HasProperty("_DetailAlbedoMap"))
				{
					val5.SetTexture("_DetailAlbedoMap", (Texture)null);
				}
				if (val5.HasProperty("_BumpScale"))
				{
					val5.SetFloat("_BumpScale", 0f);
				}
				if (name == "CobOven" || name == "Quern")
				{
					val5.SetOverrideTag("RenderType", "Opaque");
					val5.renderQueue = 2000;
					val5.DisableKeyword("_ALPHATEST_ON");
					val5.DisableKeyword("_ALPHABLEND_ON");
					val5.DisableKeyword("_ALPHAPREMULTIPLY_ON");
					if (val5.HasProperty("_Cutoff"))
					{
						val5.SetFloat("_Cutoff", 0f);
					}
					if (val5.HasProperty("_AlphaClip"))
					{
						val5.SetFloat("_AlphaClip", 0f);
					}
					if (val5.HasProperty("_Surface"))
					{
						val5.SetFloat("_Surface", 0f);
					}
					if (val5.HasProperty("_SrcBlend"))
					{
						val5.SetInt("_SrcBlend", 1);
					}
					if (val5.HasProperty("_DstBlend"))
					{
						val5.SetInt("_DstBlend", 0);
					}
					if (val5.HasProperty("_ZWrite"))
					{
						val5.SetInt("_ZWrite", 1);
					}
					if (val5.HasProperty("_Cull"))
					{
						val5.SetInt("_Cull", 2);
					}
				}
				array3[l] = val5;
			}
			visuals.Add(name, array3);
			return array3;
		}

		private Texture2D LoadSurfaceTexture(string name, int materialIndex)
		{
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: 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_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Expected O, but got Unknown
			using BinaryReader binaryReader = new BinaryReader(new MemoryStream(ReadAsset(name + "_tex" + materialIndex + ".pgt")));
			if (Encoding.ASCII.GetString(binaryReader.ReadBytes(4)) != "PGT1")
			{
				throw new InvalidDataException("Bad PieGuy material texture " + name);
			}
			int num = binaryReader.ReadUInt16();
			int num2 = binaryReader.ReadUInt16();
			if (num < 8 || num2 < 8 || num > 512 || num2 > 512)
			{
				throw new InvalidDataException("Bad PieGuy material dimensions " + name);
			}
			byte[] array = binaryReader.ReadBytes(num * num2 * 4);
			if (array.Length != num * num2 * 4 || binaryReader.BaseStream.Position != binaryReader.BaseStream.Length)
			{
				throw new InvalidDataException("Incomplete PieGuy surface " + name);
			}
			Color32[] array2 = (Color32[])(object)new Color32[num * num2];
			int num3 = 0;
			int num4 = 0;
			while (num3 < array2.Length)
			{
				array2[num3] = new Color32(array[num4], array[num4 + 1], array[num4 + 2], array[num4 + 3]);
				num3++;
				num4 += 4;
			}
			Texture2D val = new Texture2D(num, num2, (TextureFormat)4, false)
			{
				name = "PG_" + name + "_Surface_" + materialIndex
			};
			val.SetPixels32(array2);
			val.Apply(false, false);
			((Texture)val).wrapMode = (TextureWrapMode)(!(name == "Wheat"));
			((Texture)val).filterMode = (FilterMode)1;
			return val;
		}

		private Sprite LoadIcon(string name)
		{
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			if (icons.TryGetValue(name, out var value))
			{
				return value;
			}
			Texture2D val = AssetUtils.LoadImage(ReadAsset(name + ".png"));
			if ((Object)(object)val == (Object)null || ((Texture)val).width != 256 || ((Texture)val).height != 256)
			{
				throw new InvalidDataException("Could not decode icon for " + name);
			}
			((Texture)val).filterMode = (FilterMode)1;
			((Texture)val).wrapMode = (TextureWrapMode)1;
			Sprite val2 = Sprite.Create(val, new Rect(0f, 0f, 256f, 256f), new Vector2(0.5f, 0.5f), 100f);
			((Object)val2).name = "PG_" + name + "_Icon";
			icons.Add(name, val2);
			return val2;
		}

		private byte[] ReadAsset(string name)
		{
			if (embedded == null)
			{
				Dictionary<string, byte[]> dictionary = new Dictionary<string, byte[]>(StringComparer.Ordinal);
				using (FileStream fileStream = File.OpenRead(((BaseUnityPlugin)this).Info.Location))
				{
					using BinaryReader binaryReader = new BinaryReader(fileStream);
					if (fileStream.Length < 12)
					{
						throw new InvalidDataException("PieGuy graphics footer missing");
					}
					fileStream.Seek(-8L, SeekOrigin.End);
					int num = binaryReader.ReadInt32();
					if (Encoding.ASCII.GetString(binaryReader.ReadBytes(4)) != "PGAE" || num < 10 || num > 8000000 || num > fileStream.Length - 8)
					{
						throw new InvalidDataException("PieGuy graphics footer invalid");
					}
					long num2 = fileStream.Length - 8 - num;
					fileStream.Seek(num2, SeekOrigin.Begin);
					if (Encoding.ASCII.GetString(binaryReader.ReadBytes(4)) != "PGAP")
					{
						throw new InvalidDataException("PieGuy embedded art signature invalid");
					}
					int num3 = binaryReader.ReadUInt16();
					if (num3 != 19)
					{
						throw new InvalidDataException("PieGuy expects nineteen embedded assets");
					}
					for (int i = 0; i < num3; i++)
					{
						int count = binaryReader.ReadByte();
						string text = Encoding.UTF8.GetString(binaryReader.ReadBytes(count));
						int num4 = binaryReader.ReadInt32();
						if (num4 < 1 || num4 > 2800000 || fileStream.Position + num4 > num2 + num)
						{
							throw new InvalidDataException("Invalid art length: " + text);
						}
						byte[] array = binaryReader.ReadBytes(num4);
						if (array.Length != num4 || dictionary.ContainsKey(text))
						{
							throw new InvalidDataException("Corrupted art: " + text);
						}
						dictionary.Add(text, array);
					}
					if (fileStream.Position != num2 + num)
					{
						throw new InvalidDataException("Piece_CobOven");
					}
				}
				embedded = dictionary;
				((BaseUnityPlugin)this).Logger.LogInfo((object)("PieGuy: loaded " + dictionary.Count + " embedded mesh, icon and texture files"));
			}
			if (!embedded.TryGetValue(name, out var value))
			{
				throw new FileNotFoundException("PieGuy art unavailable: " + name);
			}
			return value;
		}
	}
}

PieGuy.QuernCrank.dll

Decompiled 3 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Logging;
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: 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 DelGryphon.PieGuy.QuernCrank
{
	[BepInPlugin("delgryphon.pieguy.querncrankr29", "PieGuy Hand-Crank Quern R29", "0.1.80")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class QuernCrankPlugin : BaseUnityPlugin
	{
		private const string EnginePrefab = "Piece_Quern";

		private GameObject engine;

		private bool registered;

		private bool processorConfigured;

		private bool wheatFlourAttempted;

		private bool canonicalWheatAttempted;

		private bool warnedWheatMissing;

		private bool legacyQuernRemoved;

		private bool wheatLegacyChecked;

		private float nextIconRetry;

		private bool diagnosticShown;

		private string registrationStatus = "WAITING FOR PREFABS";

		private void Awake()
		{
			PrefabManager.OnVanillaPrefabsAvailable += Register;
			ItemManager.OnItemsRegistered += RefreshConversions;
			ItemManager.OnItemsRegistered += FinalizeRegisteredItems;
			PieceManager.OnPiecesRegistered += RefreshConversions;
			PieceManager.OnPiecesRegistered += FinalizeRegisteredPieces;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"[QuernCrank R29] Unified PieGuy R29 loaded. Original oven preserved, single functional Quern, final wheat prefab names.");
		}

		private void OnDestroy()
		{
			PrefabManager.OnVanillaPrefabsAvailable -= Register;
			ItemManager.OnItemsRegistered -= RefreshConversions;
			ItemManager.OnItemsRegistered -= FinalizeRegisteredItems;
			PieceManager.OnPiecesRegistered -= RefreshConversions;
			PieceManager.OnPiecesRegistered -= FinalizeRegisteredPieces;
		}

		private void Update()
		{
			if (Time.time >= nextIconRetry)
			{
				nextIconRetry = Time.time + 3f;
				try
				{
					EnsureCanonicalWheat();
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("[QuernCrank R29] Canonical Wheat retry: " + ex.Message));
				}
				try
				{
					RefreshConversions();
				}
				catch (Exception ex2)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("[QuernCrank R29] Conversion retry: " + ex2.Message));
				}
				try
				{
					R29Cleanup.MigratePlayerWheat();
				}
				catch (Exception ex3)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("[QuernCrank R29] Inventory migration: " + ex3.Message));
				}
				try
				{
					QuernItemIcons.ApplyAll();
				}
				catch (Exception ex4)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("[QuernCrank R29] Icon retry: " + ex4.Message));
				}
				try
				{
					R29Cleanup.RefreshVisibleEntries();
				}
				catch (Exception ex5)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("[QuernCrank R29] Menu refresh: " + ex5.Message));
				}
				try
				{
					R29Cleanup.RetireOldPrefabs();
				}
				catch (Exception ex6)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("[QuernCrank R29] Legacy cleanup: " + ex6.Message));
				}
			}
			if (!diagnosticShown && !((Object)(object)Player.m_localPlayer == (Object)null) && !((Object)(object)MessageHud.instance == (Object)null))
			{
				diagnosticShown = true;
				string text = "QUERN R29: " + (processorConfigured ? "HAND-CRANK QUERN REGISTERED" : (registered ? ("ENGINE REGISTERED, PROCESSOR FAILED: " + registrationStatus) : ("PLUGIN LOADED, ENGINE NOT REGISTERED: " + registrationStatus)));
				((BaseUnityPlugin)this).Logger.LogInfo((object)("[QuernCrank R29] " + text));
			}
		}

		private void Register()
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: 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)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Expected O, but got Unknown
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Expected O, but got Unknown
			if (registered)
			{
				return;
			}
			try
			{
				EnsureCanonicalWheat();
				if ((Object)(object)PrefabManager.Instance.GetPrefab("smelter") == (Object)null)
				{
					registrationStatus = "VANILLA SMELTER NOT FOUND";
					((BaseUnityPlugin)this).Logger.LogError((object)("[QuernCrank R29] " + registrationStatus));
					return;
				}
				PieceConfig val = new PieceConfig
				{
					Name = "Quern",
					Description = "Hand-powered quern. Holds 20 grain. Turn the crank to grind each portion of flour in 30 seconds.",
					PieceTable = "Hammer",
					Category = "Crafting",
					Icon = QuernItemIcons.GetIcon("Quern"),
					CraftingStation = "piece_workbench"
				};
				val.AddRequirement("Wood", 8, true);
				val.AddRequirement("Stone", 4, true);
				val.AddRequirement("Flint", 2, true);
				CustomPiece val2 = new CustomPiece("Piece_Quern", "smelter", val);
				engine = val2.PiecePrefab;
				if ((Object)(object)engine == (Object)null)
				{
					throw new Exception("Jotunn returned no cloned prefab");
				}
				if (!PieceManager.Instance.AddPiece(val2))
				{
					throw new Exception("PieceManager.AddPiece returned FALSE");
				}
				registered = true;
				registrationStatus = "REGISTERED";
				((BaseUnityPlugin)this).Logger.LogInfo((object)("[QuernCrank R29] Verified engine piece added to Jotunn manager, prefab=" + ((Object)engine).name));
				try
				{
					SetupProcessor(engine);
					processorConfigured = true;
					((BaseUnityPlugin)this).Logger.LogInfo((object)"[QuernCrank R29] Native processor configured; Quern v3 embedded visuals and ramp installed");
				}
				catch (Exception ex)
				{
					registrationStatus = "PIECE REGISTERED; PROCESSOR SETUP FAILED";
					((BaseUnityPlugin)this).Logger.LogError((object)("[QuernCrank R29] Piece registered but setup failed: " + ex));
				}
				if (processorConfigured)
				{
					RefreshConversions();
				}
			}
			catch (Exception ex2)
			{
				registrationStatus = "REGISTRATION EXCEPTION";
				((BaseUnityPlugin)this).Logger.LogError((object)("[QuernCrank R29] Registration exception: " + ex2));
			}
		}

		private static void SetupProcessor(GameObject prefab)
		{
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Expected O, but got Unknown
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Expected O, but got Unknown
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Expected O, but got Unknown
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: 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_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: 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)
			if ((Object)(object)prefab == (Object)null)
			{
				throw new Exception("Cloned smelter prefab is null.");
			}
			Smelter component = prefab.GetComponent<Smelter>();
			if ((Object)(object)component == (Object)null || (Object)(object)component.m_addOreSwitch == (Object)null || (Object)(object)component.m_addWoodSwitch == (Object)null)
			{
				throw new Exception("Native smelter, input switch, or fuel switch is missing.");
			}
			if ((Object)(object)prefab.GetComponent<ZNetView>() == (Object)null)
			{
				throw new Exception("Native smelter has no ZNetView.");
			}
			component.m_conversion = new List<ItemConversion>();
			component.m_maxOre = 20;
			component.m_secPerProduct = 30f;
			component.m_maxFuel = 20;
			component.m_fuelPerProduct = 1;
			component.m_requiresRoof = false;
			component.m_windmill = null;
			component.m_smokeSpawner = null;
			component.m_oreAddedEffects = new EffectList();
			component.m_fuelAddedEffects = new EffectList();
			component.m_produceEffects = new EffectList();
			component.m_addOreAnimationDuration = 0f;
			component.m_spawnStack = true;
			component.m_name = "Quern";
			QuernNoFire.DetachVisualStates(component);
			prefab.AddComponent<QuernNoFire>();
			prefab.AddComponent<QuernCrankSwitch>();
			prefab.AddComponent<QuernV3Visuals>();
			prefab.AddComponent<QuernBatchOutput>();
			GameObject val = new GameObject("QuernV3_FlourRamp_Switch");
			val.transform.SetParent(prefab.transform, false);
			val.transform.localPosition = new Vector3(0f, 2.047619f, 1.3809524f);
			val.layer = ((Component)component.m_addOreSwitch).gameObject.layer;
			BoxCollider obj = val.AddComponent<BoxCollider>();
			((Collider)obj).isTrigger = false;
			obj.size = new Vector3(1f, 0.5476191f, 16f / 21f);
			Switch val2 = val.AddComponent<Switch>();
			val2.m_name = "Flour collection ramp";
			val2.m_holdRepeatInterval = -1f;
			component.m_emptyOreSwitch = val2;
			val.AddComponent<QuernRampCollection>();
			prefab.transform.localScale = new Vector3(0.42f, 0.42f, 0.42f);
		}

		private void FinalizeRegisteredPieces()
		{
			try
			{
				R29Cleanup.RefreshVisibleEntries();
				R29Cleanup.RetireOldPrefabs();
				((BaseUnityPlugin)this).Logger.LogInfo((object)"[QuernCrank R29] Finalized piece menu + oven icon/description");
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("[QuernCrank R29] Finalizing pieces: " + ex.Message));
			}
		}

		private void FinalizeRegisteredItems()
		{
			try
			{
				R29Cleanup.RefreshVisibleEntries();
				R29Cleanup.RetireOldPrefabs();
				((BaseUnityPlugin)this).Logger.LogInfo((object)"[QuernCrank R29] Finalized inventory wheat icons and legacy wheat registration");
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("[QuernCrank R29] Finalizing items: " + ex.Message));
			}
		}

		private void RefreshConversions()
		{
			if (!registered || !processorConfigured)
			{
				return;
			}
			try
			{
				EnsureCanonicalWheat();
				EnsureWheatFlour();
				ApplyConversions(engine);
				try
				{
					QuernItemIcons.ApplyAll();
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("[QuernCrank R29] Icons: " + ex));
				}
				try
				{
					ItemDrop item = GetItem("Wheat");
					if ((Object)(object)item != (Object)null)
					{
						QuernItemSparkles.Attach(((Component)item).gameObject);
					}
					ItemDrop item2 = GetItem("WheatFlour");
					if ((Object)(object)item2 != (Object)null)
					{
						QuernItemSparkles.Attach(((Component)item2).gameObject);
					}
				}
				catch (Exception ex2)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("[QuernCrank R29] Item sparkles: " + ex2));
				}
			}
			catch (Exception ex3)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("[QuernCrank R29] Flour conversions: " + ex3));
			}
		}

		private static ItemDrop GetItem(params string[] names)
		{
			foreach (string text in names)
			{
				GameObject val = PrefabManager.Instance.GetPrefab(text);
				if ((Object)(object)val == (Object)null && (Object)(object)ObjectDB.instance != (Object)null)
				{
					val = ObjectDB.instance.GetItemPrefab(text);
				}
				if ((Object)(object)val != (Object)null)
				{
					ItemDrop component = val.GetComponent<ItemDrop>();
					if ((Object)(object)component != (Object)null)
					{
						return component;
					}
				}
			}
			return null;
		}

		private void EnsureCanonicalWheat()
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Expected O, but got Unknown
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Expected O, but got Unknown
			if ((Object)(object)GetItem("Wheat") != (Object)null || canonicalWheatAttempted || (Object)(object)GetItem("PG_Wheat") == (Object)null)
			{
				return;
			}
			canonicalWheatAttempted = true;
			try
			{
				ItemConfig val = new ItemConfig
				{
					Name = "Wheat",
					Description = "Harvested wheat. Grind it into flour using the quern.",
					Enabled = false
				};
				CustomItem val2 = new CustomItem("Wheat", "PG_Wheat", val);
				ItemManager.Instance.AddItem(val2);
				((BaseUnityPlugin)this).Logger.LogInfo((object)"[QuernCrank R29] Created canonical Wheat item from existing PG_Wheat prefab.");
			}
			catch (Exception ex)
			{
				canonicalWheatAttempted = false;
				((BaseUnityPlugin)this).Logger.LogWarning((object)("[QuernCrank R29] Wheat alias creation failed: " + ex.Message));
			}
		}

		private void EnsureWheatFlour()
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Expected O, but got Unknown
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Expected O, but got Unknown
			if ((Object)(object)GetItem("WheatFlour") != (Object)null || wheatFlourAttempted || (Object)(object)GetItem("BarleyFlour") == (Object)null)
			{
				return;
			}
			wheatFlourAttempted = true;
			try
			{
				ItemConfig val = new ItemConfig
				{
					Name = "Wheat Flour",
					Description = "Stone-ground wheat flour for pies and bread.",
					Enabled = false
				};
				CustomItem val2 = new CustomItem("WheatFlour", "BarleyFlour", val);
				try
				{
					WheatFlourBagVisuals.Install(val2.ItemPrefab);
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("[QuernCrank R29] Wheat bag visuals: " + ex));
				}
				try
				{
					QuernItemSparkles.Attach(val2.ItemPrefab);
				}
				catch (Exception ex2)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("[QuernCrank R29] Wheat flour sparkles: " + ex2));
				}
				ItemManager.Instance.AddItem(val2);
				((BaseUnityPlugin)this).Logger.LogInfo((object)"[QuernCrank R29] Added WheatFlour with custom OBJ bag model and distinct sack icon.");
			}
			catch (Exception ex3)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("[QuernCrank R29] Wheat flour clone failed: " + ex3));
			}
		}

		private void ApplyConversions(GameObject prefab)
		{
			if ((Object)(object)prefab == (Object)null)
			{
				return;
			}
			Smelter component = prefab.GetComponent<Smelter>();
			if ((Object)(object)component == (Object)null)
			{
				return;
			}
			ItemDrop item = GetItem("Barley");
			ItemDrop item2 = GetItem("BarleyFlour");
			ItemDrop item3 = GetItem("Oats", "Oat");
			ItemDrop item4 = GetItem("OatFlour", "OatsFlour");
			ItemDrop item5 = GetItem("Wheat");
			ItemDrop item6 = GetItem("PG_Wheat");
			ItemDrop item7 = GetItem("WheatFlour");
			if (component.m_conversion == null)
			{
				component.m_conversion = new List<ItemConversion>();
			}
			bool flag = false;
			if ((Object)(object)item7 != (Object)null)
			{
				bool flag2 = (Object)(object)item5 == (Object)null;
				bool flag3 = (Object)(object)item6 == (Object)null;
				foreach (ItemConversion item8 in component.m_conversion)
				{
					if ((Object)(object)item5 != (Object)null && (Object)(object)item8.m_from == (Object)(object)item5 && (Object)(object)item8.m_to == (Object)(object)item7)
					{
						flag2 = true;
					}
					if ((Object)(object)item6 != (Object)null && (Object)(object)item8.m_from == (Object)(object)item6 && (Object)(object)item8.m_to == (Object)(object)item7)
					{
						flag3 = true;
					}
				}
				flag = flag2 && flag3 && component.m_conversion.Count > 0;
			}
			if (!flag)
			{
				component.m_conversion.Clear();
				AddConversion(component, item, item2);
				AddConversion(component, item3, item4);
				AddConversion(component, item5, item7);
				if ((Object)(object)item6 != (Object)null && (Object)(object)item6 != (Object)(object)item5)
				{
					AddConversion(component, item6, item7);
				}
				((BaseUnityPlugin)this).Logger.LogInfo((object)("[QuernCrank R29] " + ((Object)prefab).name + ": conversion count=" + component.m_conversion.Count + "; barley=" + ((Object)(object)item != (Object)null && (Object)(object)item2 != (Object)null) + "; oats=" + ((Object)(object)item3 != (Object)null && (Object)(object)item4 != (Object)null) + "; Wheat=" + ((Object)(object)item5 != (Object)null && (Object)(object)item7 != (Object)null) + "; PG_Wheat compatibility=" + ((Object)(object)item6 != (Object)null && (Object)(object)item7 != (Object)null)));
			}
		}

		private static void AddConversion(Smelter mill, ItemDrop from, ItemDrop to)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			if (!((Object)(object)from == (Object)null) && !((Object)(object)to == (Object)null))
			{
				mill.m_conversion.Add(new ItemConversion
				{
					m_from = from,
					m_to = to
				});
			}
		}
	}
	public sealed class QuernCrankSwitch : MonoBehaviour
	{
		private Smelter smelter;

		private bool installed;

		private float nextTry;

		private void Start()
		{
			TryAttach();
		}

		private void LateUpdate()
		{
			if (!installed && !(Time.time < nextTry))
			{
				nextTry = Time.time + 1f;
				TryAttach();
			}
		}

		private void TryAttach()
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Expected O, but got Unknown
			if (installed)
			{
				return;
			}
			if ((Object)(object)smelter == (Object)null)
			{
				smelter = ((Component)this).GetComponent<Smelter>();
			}
			if (!((Object)(object)smelter == (Object)null) && !((Object)(object)smelter.m_addWoodSwitch == (Object)null))
			{
				Switch addWoodSwitch = smelter.m_addWoodSwitch;
				if (addWoodSwitch.m_onUse != null)
				{
					addWoodSwitch.m_onUse = new Callback(Turn);
					addWoodSwitch.m_onHover = new TooltipCallback(Hover);
					addWoodSwitch.m_holdRepeatInterval = -1f;
					installed = true;
				}
			}
		}

		private float Power()
		{
			if ((Object)(object)smelter == (Object)null)
			{
				return 0f;
			}
			ZNetView component = ((Component)smelter).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || !component.IsValid() || component.GetZDO() == null)
			{
				return 0f;
			}
			return component.GetZDO().GetFloat(ZDOVars.s_fuel, 0f);
		}

		private string Hover()
		{
			float num = Power();
			if (num >= 19.98f)
			{
				return "Quern — fully cranked (20/20)";
			}
			return "Quern — " + Mathf.FloorToInt(Mathf.Clamp(num + 0.0001f, 0f, 20f)) + "/20 turns\n[E] Turn quern (+1 flour power)";
		}

		private bool Turn(Switch sw, Humanoid user, ItemData item)
		{
			if ((Object)(object)user == (Object)null || (Object)(object)smelter == (Object)null || Power() >= 19.98f)
			{
				return false;
			}
			ZNetView component = ((Component)smelter).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || !component.IsValid())
			{
				return false;
			}
			component.InvokeRPC("RPC_AddFuel", new object[0]);
			return true;
		}
	}
	public sealed class QuernRampCollection : MonoBehaviour
	{
		private Switch sw;

		private Smelter mill;

		private bool attached;

		private float nextTry;

		private void Start()
		{
			TryAttach();
		}

		private void LateUpdate()
		{
			if (!attached && !(Time.time < nextTry))
			{
				nextTry = Time.time + 1f;
				TryAttach();
			}
		}

		private void TryAttach()
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			if (!attached)
			{
				sw = ((Component)this).GetComponent<Switch>();
				mill = ((Component)this).GetComponentInParent<Smelter>();
				if (!((Object)(object)sw == (Object)null) && !((Object)(object)mill == (Object)null))
				{
					sw.m_onUse = new Callback(Collect);
					sw.m_onHover = new TooltipCallback(Hover);
					sw.m_holdRepeatInterval = -1f;
					attached = true;
				}
			}
		}

		private int Ready()
		{
			if ((Object)(object)mill == (Object)null)
			{
				return 0;
			}
			ZNetView component = ((Component)mill).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || !component.IsValid() || component.GetZDO() == null)
			{
				return 0;
			}
			return component.GetZDO().GetInt(ZDOVars.s_spawnAmount, 0);
		}

		private string Hover()
		{
			int num = Ready();
			if (num <= 0)
			{
				return "Flour collection ramp (empty)";
			}
			return "Flour collection ramp (" + num + " ready)\n[E] Collect flour";
		}

		private bool Collect(Switch which, Humanoid user, ItemData item)
		{
			if ((Object)(object)user == (Object)null || (Object)(object)mill == (Object)null || Ready() <= 0)
			{
				return false;
			}
			ZNetView component = ((Component)mill).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || !component.IsValid())
			{
				return false;
			}
			component.InvokeRPC("RPC_EmptyProcessed", new object[0]);
			return true;
		}
	}
	public static class WheatFlourBagVisuals
	{
		public static void Install(GameObject prefab)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)prefab == (Object)null)
			{
				throw new Exception("No flour prefab");
			}
			if ((Object)(object)prefab.transform.Find("PG_WheatBag_R23") != (Object)null)
			{
				return;
			}
			List<QuernV3Visuals.PackedMesh> geometryForBag = QuernV3Visuals.GetGeometryForBag();
			if (geometryForBag.Count < 1)
			{
				throw new Exception("No WheatBag mesh data");
			}
			GameObject val = new GameObject("PG_WheatBag_R23");
			val.transform.SetParent(prefab.transform, false);
			val.transform.localPosition = new Vector3(0f, 0f, 0f);
			val.transform.localRotation = Quaternion.identity;
			foreach (QuernV3Visuals.PackedMesh item in geometryForBag)
			{
				QuernV3Visuals.CreateVisual(item, val.transform, "WheatBag");
			}
			AddSolidInsert(val.transform, "SolidClothLiner", new Vector3(0f, 0.215f, 0f), new Vector3(0.129f, 0.15f, 0.108f), flour: false);
			AddSolidInsert(val.transform, "VisibleFlourFill", new Vector3(0f, 0.342f, 0f), new Vector3(0.102f, 0.026f, 0.082f), flour: true);
			LODGroup[] componentsInChildren = prefab.GetComponentsInChildren<LODGroup>(true);
			foreach (LODGroup val2 in componentsInChildren)
			{
				if ((Object)(object)val2 != (Object)null && !((Component)val2).transform.IsChildOf(val.transform))
				{
					val2.enabled = false;
				}
			}
			Renderer[] componentsInChildren2 = prefab.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val3 in componentsInChildren2)
			{
				if ((Object)(object)val3 != (Object)null && !((Component)val3).transform.IsChildOf(val.transform))
				{
					val3.enabled = false;
				}
			}
			ParticleSystem[] componentsInChildren3 = prefab.GetComponentsInChildren<ParticleSystem>(true);
			foreach (ParticleSystem val4 in componentsInChildren3)
			{
				if (!((Object)(object)val4 == (Object)null) && !((Component)val4).transform.IsChildOf(val.transform))
				{
					val4.Stop(true, (ParticleSystemStopBehavior)0);
					EmissionModule emission = val4.emission;
					((EmissionModule)(ref emission)).enabled = false;
				}
			}
		}

		private static void AddSolidInsert(Transform root, string label, Vector3 center, Vector3 radii, bool flour)
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: 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_0087: 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_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Expected O, but got Unknown
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: 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)
			Vector3[] array = (Vector3[])(object)new Vector3[325];
			Vector2[] array2 = (Vector2[])(object)new Vector2[array.Length];
			int[] array3 = new int[1728];
			for (int i = 0; i <= 12; i++)
			{
				float num = MathF.PI * (float)i / 12f;
				for (int j = 0; j <= 24; j++)
				{
					float num2 = MathF.PI * 2f * (float)j / 24f;
					int num3 = i * 25 + j;
					float num4 = Mathf.Sin(num);
					array[num3] = center + new Vector3(radii.x * num4 * Mathf.Cos(num2), radii.y * Mathf.Cos(num), radii.z * num4 * Mathf.Sin(num2));
					array2[num3] = new Vector2((float)j / 24f, (float)i / 12f);
				}
			}
			int num5 = 0;
			for (int k = 0; k < 12; k++)
			{
				for (int l = 0; l < 24; l++)
				{
					int num6 = k * 25 + l;
					int num7 = num6 + 24 + 1;
					array3[num5++] = num6;
					array3[num5++] = num6 + 1;
					array3[num5++] = num7;
					array3[num5++] = num7;
					array3[num5++] = num6 + 1;
					array3[num5++] = num7 + 1;
				}
			}
			Mesh val = new Mesh();
			((Object)val).name = "PG_R23_" + label;
			val.vertices = array;
			val.uv = array2;
			val.triangles = array3;
			val.RecalculateNormals();
			val.RecalculateBounds();
			GameObject val2 = new GameObject(label);
			val2.transform.SetParent(root, false);
			val2.AddComponent<MeshFilter>().sharedMesh = val;
			((Renderer)val2.AddComponent<MeshRenderer>()).sharedMaterial = QuernV3Visuals.GetBagMaterial(flour);
		}
	}
	public sealed class QuernBatchOutput : MonoBehaviour
	{
		private float nextCheck;

		private float nextEmpty;

		private Smelter mill;

		private void Start()
		{
			mill = ((Component)this).GetComponent<Smelter>();
		}

		private void Update()
		{
			if (Time.time < nextCheck)
			{
				return;
			}
			nextCheck = Time.time + 1f;
			if ((Object)(object)mill == (Object)null)
			{
				return;
			}
			ZNetView component = ((Component)mill).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || !component.IsValid() || !component.IsOwner())
			{
				return;
			}
			ZDO zDO = component.GetZDO();
			if (zDO != null)
			{
				int num = zDO.GetInt(ZDOVars.s_queued, 0);
				int num2 = zDO.GetInt(ZDOVars.s_spawnAmount, 0);
				if (num == 0 && num2 > 0 && Time.time >= nextEmpty)
				{
					nextEmpty = Time.time + 3f;
					component.InvokeRPC("RPC_EmptyProcessed", new object[0]);
				}
			}
		}
	}
	public static class QuernItemSparkles
	{
		public static void Attach(GameObject itemPrefab)
		{
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)itemPrefab == (Object)null)
			{
				return;
			}
			ItemDrop component = itemPrefab.GetComponent<ItemDrop>();
			if ((Object)(object)component == (Object)null || (Object)(object)itemPrefab.transform.Find("PG_R24_Sparkles") != (Object)null)
			{
				return;
			}
			GameObject val = null;
			string[] array = new string[5] { "OnionSoup", "Vineberry", "TurnipStew", "Bread", "Raspberry" };
			foreach (string text in array)
			{
				GameObject val2 = PrefabManager.Instance.GetPrefab(text);
				if ((Object)(object)val2 == (Object)null && (Object)(object)ObjectDB.instance != (Object)null)
				{
					val2 = ObjectDB.instance.GetItemPrefab(text);
				}
				if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val2 == (Object)(object)itemPrefab))
				{
					ItemDrop component2 = val2.GetComponent<ItemDrop>();
					if ((Object)(object)component2 != (Object)null && (Object)(object)component2.m_pieceDisabledObj != (Object)null)
					{
						val = component2.m_pieceDisabledObj;
						break;
					}
				}
			}
			if (!((Object)(object)val == (Object)null))
			{
				GameObject val3 = Object.Instantiate<GameObject>(val);
				((Object)val3).name = "PG_R24_Sparkles";
				val3.transform.SetParent(itemPrefab.transform, false);
				val3.transform.localPosition = new Vector3(0f, 0.12f, 0f);
				val3.transform.localRotation = Quaternion.identity;
				component.m_pieceDisabledObj = val3;
			}
		}
	}
	public sealed class QuernNoFire : MonoBehaviour
	{
		private float nextCheck;

		public static void DetachVisualStates(Smelter mill)
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			if (!((Object)(object)mill == (Object)null) && !((Object)(object)((Component)mill).transform.Find("PG_R24_InertVisualStates") != (Object)null))
			{
				_ = new GameObject[5] { mill.m_enabledObject, mill.m_disabledObject, mill.m_haveFuelObject, mill.m_haveOreObject, mill.m_noOreObject };
				GameObject val = new GameObject("PG_R24_InertVisualStates");
				val.transform.SetParent(((Component)mill).transform, false);
				mill.m_enabledObject = AddEmptyState(val.transform, "Enabled");
				mill.m_disabledObject = AddEmptyState(val.transform, "Disabled");
				mill.m_haveFuelObject = AddEmptyState(val.transform, "HasPower");
				mill.m_haveOreObject = AddEmptyState(val.transform, "HasGrain");
				mill.m_noOreObject = AddEmptyState(val.transform, "NoGrain");
			}
		}

		private static GameObject AddEmptyState(Transform parent, string label)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			GameObject val = new GameObject("PG_R24_" + label);
			val.transform.SetParent(parent, false);
			return val;
		}

		private void Start()
		{
			Suppress();
		}

		private void LateUpdate()
		{
			if (!(Time.time < nextCheck))
			{
				nextCheck = Time.time + 0.35f;
				Suppress();
			}
		}

		private void Suppress()
		{
			//IL_00f5: 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)
			Smelter component = ((Component)this).GetComponent<Smelter>();
			if ((Object)(object)component == (Object)null)
			{
				return;
			}
			DetachVisualStates(component);
			Transform val = ((Component)this).transform.Find("QuernV3_Visuals_Only");
			Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val2 in componentsInChildren)
			{
				if ((Object)(object)val2 != (Object)null && ((Object)(object)val == (Object)null || !((Component)val2).transform.IsChildOf(val)))
				{
					val2.enabled = false;
				}
			}
			Light[] componentsInChildren2 = ((Component)this).GetComponentsInChildren<Light>(true);
			foreach (Light val3 in componentsInChildren2)
			{
				if ((Object)(object)val3 != (Object)null && ((Object)(object)val == (Object)null || !((Component)val3).transform.IsChildOf(val)))
				{
					((Behaviour)val3).enabled = false;
				}
			}
			ParticleSystem[] componentsInChildren3 = ((Component)this).GetComponentsInChildren<ParticleSystem>(true);
			foreach (ParticleSystem val4 in componentsInChildren3)
			{
				if (!((Object)(object)val4 == (Object)null) && (!((Object)(object)val != (Object)null) || !((Component)val4).transform.IsChildOf(val)))
				{
					val4.Stop(true, (ParticleSystemStopBehavior)0);
					EmissionModule emission = val4.emission;
					((EmissionModule)(ref emission)).enabled = false;
				}
			}
			SmokeSpawner[] componentsInChildren4 = ((Component)this).GetComponentsInChildren<SmokeSpawner>(true);
			foreach (SmokeSpawner val5 in componentsInChildren4)
			{
				if ((Object)(object)val5 != (Object)null)
				{
					((Behaviour)val5).enabled = false;
				}
			}
			Behaviour[] componentsInChildren5 = ((Component)this).GetComponentsInChildren<Behaviour>(true);
			foreach (Behaviour val6 in componentsInChildren5)
			{
				if (!((Object)(object)val6 == (Object)null) && (!((Object)(object)val != (Object)null) || !((Component)val6).transform.IsChildOf(val)))
				{
					string name = ((object)val6).GetType().Name;
					if (name == "LightFlicker" || name == "LightLod")
					{
						val6.enabled = false;
					}
				}
			}
		}
	}
	public sealed class QuernMillstoneAnimator : MonoBehaviour
	{
		private const float SpeedDegreesPerSecond = 60f;

		private Transform upperPivot;

		private ZNetView view;

		private float nextSample;

		private bool grinding;

		public void Attach(Transform pivot)
		{
			upperPivot = pivot;
			view = ((Component)this).GetComponent<ZNetView>();
			nextSample = 0f;
		}

		private void Update()
		{
			if ((Object)(object)upperPivot == (Object)null)
			{
				return;
			}
			if (Time.time >= nextSample)
			{
				nextSample = Time.time + 0.12f;
				if ((Object)(object)view == (Object)null)
				{
					view = ((Component)this).GetComponent<ZNetView>();
				}
				grinding = false;
				if ((Object)(object)view != (Object)null && view.IsValid())
				{
					ZDO zDO = view.GetZDO();
					if (zDO != null)
					{
						int num = zDO.GetInt(ZDOVars.s_queued, 0);
						float num2 = zDO.GetFloat(ZDOVars.s_fuel, 0f);
						grinding = num > 0 && num2 > 0.001f;
					}
				}
			}
			if (grinding)
			{
				upperPivot.Rotate(0f, 60f * Time.deltaTime, 0f, (Space)1);
			}
		}
	}
	public sealed class QuernV3Visuals : MonoBehaviour
	{
		internal sealed class PackedMesh
		{
			public string Name;

			public uint Color;

			public Mesh Mesh;
		}

		private const float NativeScale = 0.42f;

		private GameObject fullBin;

		private GameObject emptyBin;

		private GameObject fullBowl;

		private GameObject emptyBowl;

		private static readonly Vector3 UpperStoneCenter = new Vector3(0.275f, 1.4f, -0.13f);

		private Smelter mill;

		private bool installed;

		private float nextTry;

		private float nextState;

		private static readonly Dictionary<string, Material> Materials = new Dictionary<string, Material>();

		private static readonly Dictionary<string, List<PackedMesh>> GeometryCache = new Dictionary<string, List<PackedMesh>>();

		private static readonly Dictionary<string, Texture2D> TextureCache = new Dictionary<string, Texture2D>();

		private void Start()
		{
			TryInstall();
		}

		private void Update()
		{
			if (!installed)
			{
				if (Time.time >= nextTry)
				{
					nextTry = Time.time + 2f;
					TryInstall();
				}
			}
			else
			{
				if (Time.time < nextState || (Object)(object)mill == (Object)null)
				{
					return;
				}
				nextState = Time.time + 0.35f;
				ZNetView component = ((Component)mill).GetComponent<ZNetView>();
				if (!((Object)(object)component == (Object)null) && component.IsValid() && component.GetZDO() != null)
				{
					ZDO zDO = component.GetZDO();
					bool flag = zDO.GetInt(ZDOVars.s_queued, 0) > 0;
					bool flag2 = zDO.GetInt(ZDOVars.s_spawnAmount, 0) > 0;
					if ((Object)(object)emptyBin != (Object)null)
					{
						emptyBin.SetActive(!flag);
					}
					if ((Object)(object)fullBin != (Object)null)
					{
						fullBin.SetActive(flag);
					}
					if ((Object)(object)emptyBowl != (Object)null)
					{
						emptyBowl.SetActive(!flag2);
					}
					if ((Object)(object)fullBowl != (Object)null)
					{
						fullBowl.SetActive(flag2);
					}
				}
			}
		}

		private void TryInstall()
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Expected O, but got Unknown
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Expected O, but got Unknown
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Expected O, but got Unknown
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0310: Unknown result type (might be due to invalid IL or missing references)
			//IL_0315: Unknown result type (might be due to invalid IL or missing references)
			//IL_0419: Unknown result type (might be due to invalid IL or missing references)
			//IL_0423: Expected O, but got Unknown
			//IL_0429: Unknown result type (might be due to invalid IL or missing references)
			//IL_0433: Expected O, but got Unknown
			//IL_0439: Unknown result type (might be due to invalid IL or missing references)
			//IL_0443: Expected O, but got Unknown
			//IL_0481: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0500: Unknown result type (might be due to invalid IL or missing references)
			//IL_0505: Unknown result type (might be due to invalid IL or missing references)
			if (installed)
			{
				return;
			}
			mill = ((Component)this).GetComponent<Smelter>();
			if ((Object)(object)mill == (Object)null)
			{
				return;
			}
			try
			{
				List<PackedMesh> geometry = GetGeometry("QuernV3");
				if (geometry.Count < 30)
				{
					throw new Exception("Incomplete Quern v3 mesh data");
				}
				GameObject val = new GameObject("QuernV3_Visuals_Only");
				val.transform.SetParent(((Component)this).transform, false);
				val.transform.localScale = Vector3.one / 0.42f;
				GameObject val2 = new GameObject("FullGrainBin");
				val2.transform.SetParent(val.transform, false);
				GameObject val3 = new GameObject("FullFlourBowl");
				val3.transform.SetParent(val.transform, false);
				GameObject val4 = new GameObject("QuernV3_UpperStonePivot");
				val4.transform.SetParent(val.transform, false);
				val4.transform.localPosition = UpperStoneCenter;
				foreach (PackedMesh item in geometry)
				{
					bool flag = item.Name.StartsWith("obj_17/");
					GameObject val5 = CreateVisual(item, flag ? val4.transform : val.transform, "QuernV3");
					if (flag)
					{
						val5.transform.localPosition = -UpperStoneCenter;
					}
					if (item.Name.StartsWith("obj_25/"))
					{
						emptyBin = val5;
					}
					if (item.Name.StartsWith("obj_30/"))
					{
						emptyBowl = val5;
					}
				}
				foreach (PackedMesh item2 in GetGeometry("FullBin"))
				{
					CreateVisual(item2, val2.transform, "FullBin");
				}
				foreach (PackedMesh item3 in GetGeometry("FullBowl"))
				{
					CreateVisual(item3, val3.transform, "FullBowl");
				}
				fullBin = val2;
				fullBowl = val3;
				fullBin.SetActive(false);
				fullBowl.SetActive(false);
				Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>(true);
				foreach (Renderer val6 in componentsInChildren)
				{
					if ((Object)(object)val6 != (Object)null && !((Component)val6).transform.IsChildOf(val.transform))
					{
						val6.enabled = false;
					}
				}
				SmokeSpawner[] componentsInChildren2 = ((Component)this).GetComponentsInChildren<SmokeSpawner>(true);
				foreach (SmokeSpawner val7 in componentsInChildren2)
				{
					if ((Object)(object)val7 != (Object)null && !((Component)val7).transform.IsChildOf(val.transform))
					{
						((Behaviour)val7).enabled = false;
					}
				}
				ParticleSystem[] componentsInChildren3 = ((Component)this).GetComponentsInChildren<ParticleSystem>(true);
				foreach (ParticleSystem val8 in componentsInChildren3)
				{
					if (!((Object)(object)val8 == (Object)null) && !((Component)val8).transform.IsChildOf(val.transform))
					{
						val8.Stop(true, (ParticleSystemStopBehavior)0);
						EmissionModule emission = val8.emission;
						((EmissionModule)(ref emission)).enabled = false;
						if ((Object)(object)((Component)val8).gameObject != (Object)(object)((Component)this).gameObject && (Object)(object)((Component)val8).gameObject.GetComponent<Smelter>() == (Object)null && ((Component)val8).gameObject.GetComponentsInChildren<Switch>(true).Length == 0)
						{
							((Component)val8).gameObject.SetActive(false);
						}
					}
				}
				Light[] componentsInChildren4 = ((Component)this).GetComponentsInChildren<Light>(true);
				foreach (Light val9 in componentsInChildren4)
				{
					if ((Object)(object)val9 != (Object)null && !((Component)val9).transform.IsChildOf(val.transform))
					{
						((Behaviour)val9).enabled = false;
					}
				}
				AudioSource[] componentsInChildren5 = ((Component)this).GetComponentsInChildren<AudioSource>(true);
				foreach (AudioSource val10 in componentsInChildren5)
				{
					if ((Object)(object)val10 != (Object)null && !((Component)val10).transform.IsChildOf(val.transform))
					{
						((Behaviour)val10).enabled = false;
					}
				}
				mill.m_smokeSpawner = null;
				mill.m_oreAddedEffects = new EffectList();
				mill.m_fuelAddedEffects = new EffectList();
				mill.m_produceEffects = new EffectList();
				mill.m_addOreAnimationDuration = 0f;
				if ((Object)(object)mill.m_addOreSwitch != (Object)null)
				{
					MoveSwitch(mill.m_addOreSwitch, new Vector3(-0.53f, 1.4f, -0.19f));
				}
				if ((Object)(object)mill.m_addWoodSwitch != (Object)null)
				{
					MoveSwitch(mill.m_addWoodSwitch, new Vector3(0.54f, 1.54f, -0.18f));
				}
				if ((Object)(object)mill.m_outputPoint != (Object)null)
				{
					mill.m_outputPoint.position = ((Component)this).transform.TransformPoint(new Vector3(0f, 0.83f, 0.6f) / 0.42f);
				}
				QuernMillstoneAnimator quernMillstoneAnimator = ((Component)this).GetComponent<QuernMillstoneAnimator>();
				if ((Object)(object)quernMillstoneAnimator == (Object)null)
				{
					quernMillstoneAnimator = ((Component)this).gameObject.AddComponent<QuernMillstoneAnimator>();
				}
				quernMillstoneAnimator.Attach(val4.transform);
				installed = true;
				Logger.CreateLogSource("Quern V3 R29").LogInfo((object)"V3 visuals installed; upper stone + handle pivot animated at 60 deg/s only when processing.");
			}
			catch (Exception ex)
			{
				Logger.CreateLogSource("Quern V3 R29").LogError((object)("Visual install failed; native engine remains available: " + ex));
			}
		}

		private void MoveSwitch(Switch sw, Vector3 positionMeters)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			((Component)sw).transform.position = ((Component)this).transform.TransformPoint(positionMeters / 0.42f);
		}

		internal static GameObject CreateVisual(PackedMesh p, Transform parent, string asset)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			GameObject val = new GameObject("V3_" + p.Name.Replace('/', '_'));
			val.transform.SetParent(parent, false);
			val.layer = ((Component)parent).gameObject.layer;
			val.AddComponent<MeshFilter>().sharedMesh = p.Mesh;
			((Renderer)val.AddComponent<MeshRenderer>()).sharedMaterial = GetMaterial(p.Color, asset, p.Name);
			return val;
		}

		private static int Hash(int x, int y, int seed)
		{
			int num = x * 374761393 + y * 668265263 + seed * 1442695041;
			int num2 = (num ^ (num >> 13)) * 1274126177;
			return num2 ^ (num2 >> 16);
		}

		private static float FracNoise(int x, int y, int seed)
		{
			return (float)(Hash(x, y, seed) & 0xFFFF) / 65535f;
		}

		private static Texture2D Pattern(string kind)
		{
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Expected O, but got Unknown
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Expected O, but got Unknown
			//IL_0459: Unknown result type (might be due to invalid IL or missing references)
			//IL_045b: Unknown result type (might be due to invalid IL or missing references)
			if (TextureCache.TryGetValue(kind, out var value))
			{
				return value;
			}
			switch (kind)
			{
			case "wood":
			case "stone":
			case "stone_normal":
			case "linen":
			case "linen_normal":
			case "stoneware":
			case "flour":
			{
				string text = kind switch
				{
					"stoneware" => "PGQ_StonewareTexture", 
					"linen_normal" => "PGQ_LinenNormal", 
					"linen" => "PGQ_LinenTexture", 
					"stone_normal" => "PGQ_StoneNormal", 
					"stone" => "PGQ_StoneTexture", 
					"wood" => "PGQ_WoodTexture", 
					_ => "PGQ_FlourTexture", 
				};
				using Stream stream = typeof(QuernV3Visuals).Assembly.GetManifestResourceStream(text);
				if (stream == null)
				{
					throw new Exception("Missing material texture " + text);
				}
				using GZipStream gZipStream = new GZipStream(stream, CompressionMode.Decompress);
				using MemoryStream memoryStream = new MemoryStream();
				gZipStream.CopyTo(memoryStream);
				byte[] array2 = memoryStream.ToArray();
				if (array2.Length != 1048576)
				{
					throw new Exception("Invalid RGBA texture " + text);
				}
				Texture2D val3 = new Texture2D(512, 512, (TextureFormat)4, false);
				((Object)val3).name = "PG_R23_" + kind;
				((Texture)val3).wrapMode = (TextureWrapMode)0;
				((Texture)val3).filterMode = (FilterMode)1;
				val3.LoadRawTextureData(array2);
				val3.Apply(false, true);
				TextureCache[kind] = val3;
				return val3;
			}
			default:
			{
				Texture2D val = new Texture2D(256, 256, (TextureFormat)4, false);
				((Object)val).name = "PG_R23_" + kind;
				((Texture)val).wrapMode = (TextureWrapMode)0;
				((Texture)val).filterMode = (FilterMode)1;
				Color[] array = (Color[])(object)new Color[65536];
				Color val2 = default(Color);
				for (int i = 0; i < 256; i++)
				{
					for (int j = 0; j < 256; j++)
					{
						float num = FracNoise(j, i, 23) - 0.5f;
						switch (kind)
						{
						case "wood":
						{
							float num4 = Mathf.Sin((float)i * 0.22f + 1.7f * Mathf.Sin((float)j * 0.038f + (float)i * 0.013f));
							float num5 = Mathf.Pow(Mathf.Abs(Mathf.Sin((float)i * 1.25f + 0.25f * Mathf.Sin((float)j * 0.08f))), 11f);
							float num3 = Mathf.Clamp01(0.8f + num4 * 0.095f - num5 * 0.17f + num * 0.085f);
							((Color)(ref val2))..ctor(0.79f * num3, 0.52f * num3, 0.3f * num3, 1f);
							break;
						}
						case "grain":
						{
							float num6 = FracNoise(j / 4, i / 7, 141);
							float num7 = Mathf.Sin((float)(j + 2 * i) * 0.29f) * 0.045f;
							float num3 = Mathf.Clamp01(0.77f + 0.21f * num6 + num7 + num * 0.15f);
							((Color)(ref val2))..ctor(0.96f * num3, 0.73f * num3, 0.32f * num3, 1f);
							break;
						}
						case "flour":
						{
							float num3 = Mathf.Clamp01(0.93f + 0.035f * Mathf.Sin((float)j * 0.085f + (float)i * 0.042f) + num * 0.065f);
							((Color)(ref val2))..ctor(0.985f * num3, 0.965f * num3, 0.89f * num3, 1f);
							break;
						}
						default:
						{
							float num2 = ((j % 7 <= 1) ? (-0.08f) : 0.018f) + ((i % 7 <= 1) ? (-0.07f) : 0.014f);
							float num3 = Mathf.Clamp01(0.88f + num2 + num * 0.11f);
							((Color)(ref val2))..ctor(0.86f * num3, 0.76f * num3, 0.63f * num3, 1f);
							break;
						}
						}
						array[i * 256 + j] = val2;
					}
				}
				val.SetPixels(array);
				val.Apply(false, true);
				TextureCache[kind] = val;
				return val;
			}
			}
		}

		private static Material GetMaterial(uint tint, string asset, string meshName)
		{
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Expected O, but got Unknown
			//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			string text = "plain";
			if (asset == "WheatBag")
			{
				text = ((tint == 15981512) ? "flour" : "linen");
			}
			else if (asset == "FullBin" && !meshName.StartsWith("obj_3/"))
			{
				text = "grain";
			}
			else if (asset == "FullBowl" && tint == 15981512)
			{
				text = "flour";
			}
			else if ((asset == "QuernV3" && meshName.StartsWith("obj_30/")) || (asset == "FullBowl" && tint == 10988977))
			{
				text = "stoneware";
			}
			else if (asset == "QuernV3" && tint == 10988977 && (meshName.StartsWith("obj_0/") || meshName.StartsWith("obj_17/")))
			{
				text = "stone";
			}
			else if (tint == 14860437 || tint == 11107152)
			{
				text = "wood";
			}
			string text2 = asset + ":" + text + ":" + tint;
			if (Materials.TryGetValue(text2, out var value))
			{
				return value;
			}
			Shader val = Shader.Find("Standard");
			if ((Object)(object)val == (Object)null)
			{
				val = Shader.Find("Custom/Piece");
			}
			if ((Object)(object)val == (Object)null)
			{
				val = Shader.Find("Legacy Shaders/Diffuse");
			}
			if ((Object)(object)val == (Object)null)
			{
				throw new Exception("No available Unity surface shader");
			}
			value = new Material(val);
			((Object)value).name = "PG_QuernR23_" + text2;
			if (text != "plain")
			{
				Texture2D val2 = (Texture2D)(object)(value.mainTexture = (Texture)(object)Pattern(text));
				if (value.HasProperty("_MainTex"))
				{
					value.SetTexture("_MainTex", (Texture)(object)val2);
				}
				value.color = Color.white;
				if ((text == "stone" || text == "linen") && value.HasProperty("_BumpMap"))
				{
					value.SetTexture("_BumpMap", (Texture)(object)Pattern((text == "stone") ? "stone_normal" : "linen_normal"));
					if (value.HasProperty("_BumpScale"))
					{
						value.SetFloat("_BumpScale", (text == "stone") ? 0.48f : 0.57f);
					}
					value.EnableKeyword("_NORMALMAP");
				}
			}
			else
			{
				value.color = new Color((float)((tint >> 16) & 0xFF) / 255f, (float)((tint >> 8) & 0xFF) / 255f, (float)(tint & 0xFF) / 255f, 1f);
			}
			if (value.HasProperty("_Cull"))
			{
				value.SetInt("_Cull", (asset == "WheatBag") ? 2 : 0);
			}
			if (asset == "WheatBag")
			{
				value.SetOverrideTag("RenderType", "Opaque");
				value.renderQueue = 2000;
				if (value.HasProperty("_Mode"))
				{
					value.SetFloat("_Mode", 0f);
				}
				if (value.HasProperty("_Surface"))
				{
					value.SetFloat("_Surface", 0f);
				}
				if (value.HasProperty("_SrcBlend"))
				{
					value.SetInt("_SrcBlend", 1);
				}
				if (value.HasProperty("_DstBlend"))
				{
					value.SetInt("_DstBlend", 0);
				}
				if (value.HasProperty("_ZWrite"))
				{
					value.SetInt("_ZWrite", 1);
				}
				value.DisableKeyword("_ALPHATEST_ON");
				value.DisableKeyword("_ALPHABLEND_ON");
				value.DisableKeyword("_ALPHAPREMULTIPLY_ON");
			}
			if (value.HasProperty("_Glossiness"))
			{
				value.SetFloat("_Glossiness", 0.04f);
			}
			if (value.HasProperty("_Metallic"))
			{
				value.SetFloat("_Metallic", 0f);
			}
			Materials[text2] = value;
			return value;
		}

		internal static Material GetBagMaterial(bool flour)
		{
			return GetMaterial(flour ? 15981512u : 13348492u, "WheatBag", flour ? "SolidFlourInsert" : "SolidClothInsert");
		}

		private static Mesh RepairStoneUV(Mesh source)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: 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_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: 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_0081: 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)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0264: Unknown result type (might be due to invalid IL or missing references)
			//IL_026b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0282: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0291: Expected O, but got Unknown
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: 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_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			Vector3[] vertices = source.vertices;
			Vector3[] normals = source.normals;
			int[] triangles = source.triangles;
			Vector3[] array = (Vector3[])(object)new Vector3[triangles.Length];
			Vector3[] array2 = (Vector3[])(object)new Vector3[triangles.Length];
			Vector2[] array3 = (Vector2[])(object)new Vector2[triangles.Length];
			int[] array4 = new int[triangles.Length];
			Bounds bounds = source.bounds;
			Vector3 center = ((Bounds)(ref bounds)).center;
			for (int i = 0; i < triangles.Length; i += 3)
			{
				Vector3 val = vertices[triangles[i]];
				Vector3 val2 = vertices[triangles[i + 1]];
				Vector3 val3 = vertices[triangles[i + 2]];
				Vector3 val4 = Vector3.Cross(val2 - val, val3 - val);
				bool flag = ((Vector3)(ref val4)).sqrMagnitude > 1E-08f && Mathf.Abs(((Vector3)(ref val4)).normalized.y) > 0.68f;
				float[] array5 = new float[3];
				for (int j = 0; j < 3; j++)
				{
					int num = triangles[i + j];
					Vector3 val5 = (array[i + j] = vertices[num]);
					array2[i + j] = normals[num];
					array4[i + j] = i + j;
					if (flag)
					{
						array3[i + j] = new Vector2(val5.x * 3.8f, val5.z * 3.8f);
						continue;
					}
					float num2 = Mathf.Atan2(val5.z - center.z, val5.x - center.x);
					array5[j] = (num2 / (MathF.PI * 2f) + 0.5f) * 3f;
					array3[i + j] = new Vector2(array5[j], val5.y * 3f);
				}
				if (flag)
				{
					continue;
				}
				float num3 = Mathf.Min(array5[0], Mathf.Min(array5[1], array5[2]));
				if (!(Mathf.Max(array5[0], Mathf.Max(array5[1], array5[2])) - num3 > 1.5f))
				{
					continue;
				}
				for (int k = 0; k < 3; k++)
				{
					if (array5[k] < 1.5f)
					{
						Vector2 val6 = array3[i + k];
						val6.x += 3f;
						array3[i + k] = val6;
					}
				}
			}
			Mesh val7 = new Mesh
			{
				name = ((Object)source).name + "_UV_R22",
				indexFormat = (IndexFormat)1,
				vertices = array,
				normals = array2,
				uv = array3,
				triangles = array4
			};
			val7.RecalculateBounds();
			return val7;
		}

		internal static List<PackedMesh> GetGeometryForBag()
		{
			return GetGeometry("WheatBag");
		}

		private static List<PackedMesh> GetGeometry(string shortName)
		{
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: 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_0189: Expected O, but got Unknown
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_0287: Unknown result type (might be due to invalid IL or missing references)
			//IL_0293: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02af: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02be: Unknown result type (might be due to invalid IL or missing references)
			if (GeometryCache.TryGetValue(shortName, out var value))
			{
				return value;
			}
			string text = "PGQ_" + shortName;
			using Stream stream = typeof(QuernV3Visuals).Assembly.GetManifestResourceStream(text);
			if (stream == null)
			{
				throw new Exception("Embedded mesh missing: " + text);
			}
			using GZipStream input = new GZipStream(stream, CompressionMode.Decompress);
			using BinaryReader binaryReader = new BinaryReader(input);
			string text2 = new string(binaryReader.ReadChars(4));
			if (text2 != "PGQ3")
			{
				throw new Exception("Bad mesh header " + text2);
			}
			int num = binaryReader.ReadInt32();
			List<PackedMesh> list = new List<PackedMesh>(num);
			for (int i = 0; i < num; i++)
			{
				string text3 = Encoding.UTF8.GetString(binaryReader.ReadBytes(binaryReader.ReadInt32()));
				uint num2 = binaryReader.ReadUInt32();
				int num3 = binaryReader.ReadInt32();
				if (num3 <= 0 || num3 > 250000)
				{
					throw new Exception("Invalid OBJ vertex count " + num3);
				}
				Vector3[] array = (Vector3[])(object)new Vector3[num3];
				for (int j = 0; j < num3; j++)
				{
					array[j] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
				}
				int num4 = binaryReader.ReadInt32();
				if (num4 <= 0 || num4 > 1200000)
				{
					throw new Exception("Invalid OBJ index count " + num4);
				}
				int[] array2 = new int[num4];
				for (int k = 0; k < num4; k++)
				{
					array2[k] = (int)binaryReader.ReadUInt32();
				}
				Mesh val = new Mesh();
				((Object)val).name = shortName + "_" + text3;
				val.indexFormat = (IndexFormat)1;
				val.vertices = array;
				if (shortName == "WheatBag")
				{
					for (int l = 0; l < array2.Length; l += 3)
					{
						int num5 = array2[l + 1];
						array2[l + 1] = array2[l + 2];
						array2[l + 2] = num5;
					}
				}
				val.triangles = array2;
				val.RecalculateNormals();
				val.RecalculateBounds();
				Vector3[] normals = val.normals;
				Vector2[] array3 = (Vector2[])(object)new Vector2[num3];
				for (int m = 0; m < num3; m++)
				{
					Vector3 val2 = array[m];
					Vector3 val3 = normals[m];
					float num6 = ((shortName == "WheatBag") ? 2.55f : 3.8f);
					if (Mathf.Abs(val3.y) > 0.55f)
					{
						array3[m] = new Vector2(val2.x * num6, val2.z * num6);
					}
					else if (Mathf.Abs(val3.z) > Mathf.Abs(val3.x))
					{
						array3[m] = new Vector2(val2.x * num6, val2.y * num6);
					}
					else
					{
						array3[m] = new Vector2(val2.z * num6, val2.y * num6);
					}
				}
				val.uv = array3;
				if (shortName == "QuernV3" && num2 == 10988977 && (text3.StartsWith("obj_0/") || text3.StartsWith("obj_17/")))
				{
					val = RepairStoneUV(val);
				}
				list.Add(new PackedMesh
				{
					Name = text3,
					Color = num2,
					Mesh = val
				});
			}
			GeometryCache[shortName] = list;
			return list;
		}
	}
	public static class QuernItemIcons
	{
		private static readonly Dictionary<string, Sprite> Cache = new Dictionary<string, Sprite>();

		private static Sprite Read(string key)
		{
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: 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_00f0: Expected O, but got Unknown
			if (Cache.TryGetValue(key, out var value))
			{
				return value;
			}
			using Stream stream = typeof(QuernItemIcons).Assembly.GetManifestResourceStream("PGQ_Icon_" + key);
			if (stream == null)
			{
				throw new Exception("Missing icon: " + key);
			}
			using GZipStream gZipStream = new GZipStream(stream, CompressionMode.Decompress);
			using MemoryStream memoryStream = new MemoryStream();
			gZipStream.CopyTo(memoryStream);
			byte[] array = memoryStream.ToArray();
			if (array.Length != 1048576)
			{
				throw new Exception("Invalid icon RGBA: " + key);
			}
			Texture2D val = new Texture2D(512, 512, (TextureFormat)4, false)
			{
				name = "QuernR29_" + key,
				filterMode = (FilterMode)1,
				wrapMode = (TextureWrapMode)1
			};
			val.LoadRawTextureData(array);
			val.Apply(false, true);
			Sprite val2 = Sprite.Create(val, new Rect(0f, 0f, 512f, 512f), new Vector2(0.5f, 0.5f), 100f);
			((Object)val2).name = "QuernR29_" + key;
			Cache[key] = val2;
			return val2;
		}

		private static void SetItem(string prefabName, string key)
		{
			GameObject val = PrefabManager.Instance.GetPrefab(prefabName);
			if ((Object)(object)val == (Object)null && (Object)(object)ObjectDB.instance != (Object)null)
			{
				val = ObjectDB.instance.GetItemPrefab(prefabName);
			}
			if (!((Object)(object)val == (Object)null))
			{
				ItemDrop component = val.GetComponent<ItemDrop>();
				if ((Object)(object)component != (Object)null && component.m_itemData != null && component.m_itemData.m_shared != null)
				{
					component.m_itemData.m_shared.m_icons = (Sprite[])(object)new Sprite[1] { Read(key) };
				}
			}
		}

		public static Sprite GetIcon(string key)
		{
			return Read(key);
		}

		private static void SetPiece(string prefabName, string key)
		{
			GameObject prefab = PrefabManager.Instance.GetPrefab(prefabName);
			if ((Object)(object)prefab == (Object)null)
			{
				return;
			}
			Piece component = prefab.GetComponent<Piece>();
			if (!((Object)(object)component == (Object)null))
			{
				component.m_icon = Read(key);
				if (key == "Oven")
				{
					component.m_description = "A rustic wood-fired cob oven for baking food. Add wood to fuel the fire, then place food inside to cook.";
				}
				if (key == "Quern")
				{
					component.m_name = "Quern";
				}
			}
		}

		public static void ApplyAll()
		{
			SetItem("Wheat", "Wheat");
			SetItem("PG_Wheat", "Wheat");
			SetItem("WheatFlour", "FlourBag");
			SetPiece("Sapling_Wheat", "Wheat");
			SetPiece("Piece_CobOven", "Oven");
			SetPiece("PG_CobOven", "Oven");
			SetPiece("Piece_Quern", "Quern");
		}
	}
	public static class R29Cleanup
	{
		public const string CobOvenDescription = "A rustic wood-fired cob oven for baking food. Add wood to fuel the fire, then place food inside to cook.";

		private static readonly string[] RemovedLegacyNames = new string[7] { "PG_Wheat", "PG_WheatMature", "PG_WheatStalk", "WheatMature", "WheatStalk", "PG_Quern", "Pickable_Wheat_Willd" };

		private static bool OldPieceManagerRemoved;

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

		public static void MigratePlayerWheat()
		{
			if ((Object)(object)Player.m_localPlayer == (Object)null)
			{
				return;
			}
			Inventory inventory = ((Humanoid)Player.m_localPlayer).GetInventory();
			if (inventory == null)
			{
				return;
			}
			GameObject val = PrefabManager.Instance.GetPrefab("Wheat");
			if ((Object)(object)val == (Object)null && (Object)(object)ObjectDB.instance != (Object)null)
			{
				val = ObjectDB.instance.GetItemPrefab("Wheat");
			}
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			ItemDrop component = val.GetComponent<ItemDrop>();
			if ((Object)(object)component == (Object)null)
			{
				return;
			}
			foreach (ItemData allItem in inventory.GetAllItems())
			{
				if (allItem != null && !((Object)(object)allItem.m_dropPrefab == (Object)null) && !(((Object)allItem.m_dropPrefab).name != "PG_Wheat"))
				{
					allItem.m_dropPrefab = val;
					allItem.m_shared = component.m_itemData.m_shared;
				}
			}
		}

		private static void ApplyPiece(GameObject go)
		{
			if (!Object.op_Implicit((Object)(object)go))
			{
				return;
			}
			Piece component = go.GetComponent<Piece>();
			if (Object.op_Implicit((Object)(object)component))
			{
				if (((Object)go).name == "Piece_CobOven" || ((Object)go).name == "PG_CobOven" || component.m_name == "Cob Oven")
				{
					component.m_icon = QuernItemIcons.GetIcon("Oven");
					component.m_name = "Cob Oven";
					component.m_description = "A rustic wood-fired cob oven for baking food. Add wood to fuel the fire, then place food inside to cook.";
				}
				else if (((Object)go).name == "Piece_Quern")
				{
					component.m_icon = QuernItemIcons.GetIcon("Quern");
					component.m_name = "Quern";
				}
			}
		}

		public static void RefreshVisibleEntries()
		{
			QuernItemIcons.ApplyAll();
			foreach (PieceTable pieceTable in PieceManager.Instance.GetPieceTables())
			{
				if (!Object.op_Implicit((Object)(object)pieceTable) || pieceTable.m_pieces == null)
				{
					continue;
				}
				for (int num = pieceTable.m_pieces.Count - 1; num >= 0; num--)
				{
					GameObject val = pieceTable.m_pieces[num];
					if (Object.op_Implicit((Object)(object)val))
					{
						if (((Object)val).name == "PG_Quern")
						{
							pieceTable.m_pieces.RemoveAt(num);
						}
						else
						{
							ApplyPiece(val);
						}
					}
				}
			}
			if ((Object)(object)ObjectDB.instance != (Object)null && ObjectDB.instance.m_items != null)
			{
				Sprite icon = QuernItemIcons.GetIcon("Wheat");
				Sprite icon2 = QuernItemIcons.GetIcon("FlourBag");
				foreach (GameObject item in ObjectDB.instance.m_items)
				{
					if (!Object.op_Implicit((Object)(object)item))
					{
						continue;
					}
					ItemDrop component = item.GetComponent<ItemDrop>();
					if (Object.op_Implicit((Object)(object)component) && component.m_itemData != null && component.m_itemData.m_shared != null)
					{
						if (((Object)item).name == "Wheat" || ((Object)item).name == "PG_Wheat")
						{
							component.m_itemData.m_shared.m_icons = (Sprite[])(object)new Sprite[1] { icon };
							component.m_itemData.m_shared.m_description = "Harvested wheat for grinding into flour at a quern.";
						}
						else if (((Object)item).name == "WheatFlour")
						{
							component.m_itemData.m_shared.m_icons = (Sprite[])(object)new Sprite[1] { icon2 };
						}
					}
				}
			}
			if (!((Object)(object)Player.m_localPlayer != (Object)null))
			{
				return;
			}
			Inventory inventory = ((Humanoid)Player.m_localPlayer).GetInventory();
			if (inventory == null)
			{
				return;
			}
			foreach (ItemData allItem in inventory.GetAllItems())
			{
				if (allItem != null && !((Object)(object)allItem.m_dropPrefab == (Object)null) && allItem.m_shared != null)
				{
					if (((Object)allItem.m_dropPrefab).name == "Wheat" || ((Object)allItem.m_dropPrefab).name == "PG_Wheat")
					{
						allItem.m_shared.m_icons = (Sprite[])(object)new Sprite[1] { QuernItemIcons.GetIcon("Wheat") };
					}
					else if (((Object)allItem.m_dropPrefab).name == "WheatFlour")
					{
						allItem.m_shared.m_icons = (Sprite[])(object)new Sprite[1] { QuernItemIcons.GetIcon("FlourBag") };
					}
				}
			}
		}

		public static void RetireOldPrefabs()
		{
			string[] removedLegacyNames = RemovedLegacyNames;
			foreach (string text in removedLegacyNames)
			{
				if (Retired.Contains(text))
				{
					continue;
				}
				object obj;
				switch (text)
				{
				default:
					obj = "Pickable_Wheat_Wild";
					break;
				case "WheatStalk":
				case "PG_WheatStalk":
					obj = "Sapling_Wheat";
					break;
				case "PG_Wheat":
					obj = "Wheat";
					break;
				case "PG_Quern":
					obj = "Piece_Quern";
					break;
				}
				string text2 = (string)obj;
				if ((Object)(object)PrefabManager.Instance.GetPrefab(text2) == (Object)null)
				{
					continue;
				}
				if (text == "PG_Wheat")
				{
					if ((Object)(object)Player.m_localPlayer == (Object)null)
					{
						continue;
					}
					MigratePlayerWheat();
					bool flag = false;
					Inventory inventory = ((Humanoid)Player.m_localPlayer).GetInventory();
					if (inventory != null)
					{
						foreach (ItemData allItem in inventory.GetAllItems())
						{
							if (allItem != null && (Object)(object)allItem.m_dropPrefab != (Object)null && ((Object)allItem.m_dropPrefab).name == "PG_Wheat")
							{
								flag = true;
							}
						}
					}
					if (flag)
					{
						continue;
					}
				}
				try
				{
					if (text == "PG_Quern" && !OldPieceManagerRemoved)
					{
						PieceManager.Instance.RemovePiece(text);
						OldPieceManagerRemoved = true;
					}
					switch (text)
					{
					case "PG_Wheat":
					case "WheatMature":
					case "WheatStalk":
					case "PG_WheatMature":
					case "PG_WheatStalk":
						ItemManager.Instance.RemoveItem(text);
						break;
					}
					if ((Object)(object)PrefabManager.Instance.GetPrefab(text) != (Object)null)
					{
						PrefabManager.Instance.DestroyPrefab(text);
					}
					Retired.Add(text);
				}
				catch (Exception)
				{
				}
			}
		}
	}
}

PieGuy.Pies.dll

Decompiled 3 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
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: 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 DelGryphon.PieGuy.Pies
{
	[BepInPlugin("delgryphon.pieguy.piesr30", "PieGuy 12 Custom Pies R34", "0.1.85")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class PieItemsPlugin : BaseUnityPlugin
	{
		private sealed class Ingredient
		{
			public string Prefab;

			public int Count;

			public Ingredient(string prefab, int count)
			{
				Prefab = prefab;
				Count = count;
			}
		}

		private sealed class PieDef
		{
			public string Id;

			public string Name;

			public string Asset;

			public int Health;

			public int Stamina;

			public int Eitr;

			public int Heal;

			public int Minutes;

			public Ingredient[] Ingredients;

			public string Raw => "Uncooked" + Id;

			public string Cooked => Id;

			public PieDef(string id, string name, string asset, int hp, int stamina, int eitr, int heal, int minutes, Ingredient[] ingredients)
			{
				Id = id;
				Name = name;
				Asset = asset;
				Health = hp;
				Stamina = stamina;
				Eitr = eitr;
				Heal = heal;
				Minutes = minutes;
				Ingredients = ingredients;
			}
		}

		private static readonly PieDef[] Pies = new PieDef[12]
		{
			new PieDef("PorkHandPie", "Pork Handpie", "porkhandpie", 42, 15, 0, 3, 30, new Ingredient[3]
			{
				new Ingredient("WheatFlour", 3),
				new Ingredient("CookedMeat", 1),
				new Ingredient("Mushroom", 1)
			}),
			new PieDef("MixedBerryPie", "Mixed-Berry Pie", "mixedberrypie", 18, 52, 0, 2, 30, new Ingredient[3]
			{
				new Ingredient("WheatFlour", 4),
				new Ingredient("QueensJam", 1),
				new Ingredient("Honey", 1)
			}),
			new PieDef("VegetablePie", "Vegetable Pie", "vegetablepie", 38, 42, 0, 3, 30, new Ingredient[4]
			{
				new Ingredient("WheatFlour", 4),
				new Ingredient("Carrot", 2),
				new Ingredient("Turnip", 2),
				new Ingredient("Mushroom", 2)
			}),
			new PieDef("WolfMeatPie", "Wolf Meat Pie", "wolfmeatpie", 63, 22, 0, 3, 30, new Ingredient[3]
			{
				new Ingredient("WheatFlour", 3),
				new Ingredient("CookedWolfMeat", 1),
				new Ingredient("Onion", 1)
			}),
			new PieDef("SweetChutneyPie", "Sweet Chutney Pie", "sweetchutneypie", 27, 78, 0, 3, 30, new Ingredient[4]
			{
				new Ingredient("WheatFlour", 4),
				new Ingredient("Onion", 1),
				new Ingredient("Cloudberry", 2),
				new Ingredient("Honey", 1)
			}),
			new PieDef("MushroomPie", "Mushroom Pie", "mushroompie", 33, 16, 88, 4, 30, new Ingredient[5]
			{
				new Ingredient("WheatFlour", 4),
				new Ingredient("Mushroom", 2),
				new Ingredient("MushroomYellow", 2),
				new Ingredient("MushroomMagecap", 2),
				new Ingredient("MushroomJotunPuffs", 2)
			}),
			new PieDef("SavoryQuiche", "Savory Quiche", "savoryquiche", 60, 50, 0, 4, 40, new Ingredient[4]
			{
				new Ingredient("WheatFlour", 4),
				new Ingredient("ChickenEgg", 3),
				new Ingredient("Mushroom", 1),
				new Ingredient("Onion", 1)
			}),
			new PieDef("SeekerMeatPie", "Seeker Meat Pie", "seekermeatpie", 82, 27, 0, 5, 40, new Ingredient[3]
			{
				new Ingredient("BarleyFlour", 4),
				new Ingredient("CookedBugMeat", 2),
				new Ingredient("Onion", 1)
			}),
			new PieDef("ChickenPotPie", "Chicken Pot Pie", "chickenpotpie", 60, 40, 30, 6, 40, new Ingredient[6]
			{
				new Ingredient("BarleyFlour", 4),
				new Ingredient("CookedChickenMeat", 1),
				new Ingredient("Carrot", 1),
				new Ingredient("Turnip", 1),
				new Ingredient("Onion", 1),
				new Ingredient("Vineberry", 2)
			}),
			new PieDef("VenisonPie", "Venison Pie", "venisonpie", 112, 40, 0, 7, 40, new Ingredient[4]
			{
				new Ingredient("OatFlour", 4),
				new Ingredient("CookedMooseMeat", 1),
				new Ingredient("CookedDeerMeat", 1),
				new Ingredient("Lingonberries", 2)
			}),
			new PieDef("FourBerryGalette", "Four-Berry Galette", "fourberrygalette", 42, 118, 0, 5, 40, new Ingredient[6]
			{
				new Ingredient("OatFlour", 4),
				new Ingredient("Lingonberries", 2),
				new Ingredient("Cloudberry", 2),
				new Ingredient("Blueberries", 2),
				new Ingredient("Raspberry", 2),
				new Ingredient("Honey", 2)
			}),
			new PieDef("NordicFishPie", "Nordic Fish Pie", "fishandpoteitrpie", 82, 82, 0, 7, 40, new Ingredient[6]
			{
				new Ingredient("OatFlour", 4),
				new Ingredient("FishCooked", 2),
				new Ingredient("Poteitr", 2),
				new Ingredient("Carrot", 1),
				new Ingredient("Turnip", 1),
				new Ingredient("Onion", 1)
			})
		};

		private static readonly Dictionary<string, string[]> Aliases = new Dictionary<string, string[]>(StringComparer.Ordinal)
		{
			{
				"CookedMeat",
				new string[2] { "CookedMeat", "CookedBoarMeat" }
			},
			{
				"QueensJam",
				new string[2] { "QueensJam", "Queensjam" }
			},
			{
				"Cloudberry",
				new string[2] { "Cloudberry", "Cloudberries" }
			},
			{
				"MushroomYellow",
				new string[2] { "MushroomYellow", "MushroomYellowCap" }
			},
			{
				"MushroomMagecap",
				new string[2] { "MushroomMagecap", "Magecap" }
			},
			{
				"MushroomJotunPuffs",
				new string[2] { "MushroomJotunPuffs", "JotunPuffs" }
			},
			{
				"ChickenEgg",
				new string[2] { "ChickenEgg", "Egg" }
			},
			{
				"CookedBugMeat",
				new string[2] { "CookedBugMeat", "CookedSeekerMeat" }
			},
			{
				"CookedChickenMeat",
				new string[2] { "CookedChickenMeat", "ChickenMeatCooked" }
			},
			{
				"Vineberry",
				new string[3] { "Vineberry", "VineberryCluster", "Vineberries" }
			},
			{
				"OatFlour",
				new string[2] { "OatFlour", "OatsFlour" }
			},
			{
				"Lingonberries",
				new string[2] { "Lingonberries", "Lingonberry" }
			},
			{
				"FishCooked",
				new string[2] { "FishCooked", "CookedFish" }
			},
			{
				"Poteitr",
				new string[2] { "Poteitr", "PoteitrRaw" }
			},
			{
				"WheatFlour",
				new string[2] { "WheatFlour", "PG_WheatFlour" }
			}
		};

		private bool registered;

		private bool piesFailedWarningLogged;

		private float nextRetry;

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

		private readonly HashSet<string> deferredIngredientNames = new HashSet<string>(StringComparer.Ordinal);

		private readonly HashSet<string> loggedMissingAfterRegistration = new HashSet<string>(StringComparer.Ordinal);

		private bool conversionsSubmitted;

		private static ManualLogSource Log;

		private void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			PrefabManager.OnVanillaPrefabsAvailable += Register;
			ItemManager.OnVanillaItemsAvailable += Register;
			ItemManager.OnItemsRegisteredFejd += Register;
			ItemManager.OnItemsRegistered += VerifyItemsAfterDatabaseLoad;
			ItemManager.OnItemsRegistered += RefreshOvens;
			PieceManager.OnPiecesRegistered += RefreshOvens;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"[PieGuy R34] 12 CUSTOM pie pairs; 4 vanilla CSV recipes left untouched. Bakery registration pending.");
		}

		private void OnDestroy()
		{
			PrefabManager.OnVanillaPrefabsAvailable -= Register;
			ItemManager.OnVanillaItemsAvailable -= Register;
			ItemManager.OnItemsRegisteredFejd -= Register;
			ItemManager.OnItemsRegistered -= VerifyItemsAfterDatabaseLoad;
			ItemManager.OnItemsRegistered -= RefreshOvens;
			PieceManager.OnPiecesRegistered -= RefreshOvens;
		}

		private void Start()
		{
			if (!registered)
			{
				Register();
			}
		}

		private void Update()
		{
			if (Time.time < nextRetry)
			{
				return;
			}
			nextRetry = Time.time + 3f;
			if (!registered)
			{
				Register();
				return;
			}
			try
			{
				RefreshOvens();
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("[PieGuy] Late oven conversion retry: " + ex.Message));
			}
		}

		private void VerifyItemsAfterDatabaseLoad()
		{
			int num = CountObjectDbPiePrefabs();
			if (num != 24)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("[PieGuy R41] Only " + num + "/24 pie prefabs found inside ObjectDB; pie inventories may be at risk. See preceding item-registration errors."));
			}
			else
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)"[PieGuy R41] Verified all 24 pies in the game ObjectDB.");
			}
			foreach (string deferredIngredientName in deferredIngredientNames)
			{
				if ((Object)(object)FindPrefab(deferredIngredientName) == (Object)null && loggedMissingAfterRegistration.Add(deferredIngredientName))
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("[PieGuy R41] Ingredient still unavailable after item registration: " + deferredIngredientName + ". Recipes using it may be unavailable."));
				}
			}
		}

		private static int CountObjectDbPiePrefabs()
		{
			int num = 0;
			if ((Object)(object)ObjectDB.instance == (Object)null)
			{
				return 0;
			}
			PieDef[] pies = Pies;
			foreach (PieDef pieDef in pies)
			{
				if ((Object)(object)ObjectDB.instance.GetItemPrefab(pieDef.Raw) != (Object)null)
				{
					num++;
				}
				if ((Object)(object)ObjectDB.instance.GetItemPrefab(pieDef.Cooked) != (Object)null)
				{
					num++;
				}
			}
			return num;
		}

		private static int CountAvailablePiePrefabs()
		{
			int num = 0;
			PieDef[] pies = Pies;
			foreach (PieDef obj in pies)
			{
				if ((Object)(object)FindPrefab(obj.Raw) != (Object)null)
				{
					num++;
				}
				if ((Object)(object)FindPrefab(obj.Cooked) != (Object)null)
				{
					num++;
				}
			}
			return num;
		}

		private static GameObject FindPrefab(string key)
		{
			GameObject val = null;
			try
			{
				val = PrefabManager.Instance.GetPrefab(key);
			}
			catch
			{
			}
			if ((Object)(object)val == (Object)null && (Object)(object)ObjectDB.instance != (Object)null)
			{
				val = ObjectDB.instance.GetItemPrefab(key);
			}
			return val;
		}

		private static string FindIngredient(string name)
		{
			if (!Aliases.TryGetValue(name, out var value))
			{
				return name;
			}
			string[] array = value;
			foreach (string text in array)
			{
				if ((Object)(object)FindPrefab(text) != (Object)null)
				{
					return text;
				}
			}
			return value[0];
		}

		private void Register()
		{
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Expected O, but got Unknown
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Expected O, but got Unknown
			if (registered)
			{
				return;
			}
			if ((Object)(object)FindPrefab("LoxPieUncooked") == (Object)null || (Object)(object)FindPrefab("LoxPie") == (Object)null)
			{
				if (!piesFailedWarningLogged)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)"[PieGuy R41] LoxPie templates unavailable. Retrying pie registration without affecting the oven/quern.");
					piesFailedWarningLogged = true;
				}
				return;
			}
			int num = 0;
			PieDef[] pies = Pies;
			foreach (PieDef pieDef in pies)
			{
				bool[] array = new bool[2] { false, true };
				foreach (bool flag in array)
				{
					string text = (flag ? pieDef.Cooked : pieDef.Raw);
					if (!((Object)(object)FindPrefab(text) != (Object)null))
					{
						try
						{
							MakeItem(pieDef, flag);
							num++;
						}
						catch (Exception ex)
						{
							((BaseUnityPlugin)this).Logger.LogError((object)("[PieGuy R41] Failed to register " + text + ": " + ex));
						}
					}
				}
			}
			int num2 = CountAvailablePiePrefabs();
			if (num2 != 24)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("[PieGuy R41] Pies available " + num2 + "/24 after item-registration attempt; retry scheduled. Newly added: " + num));
				return;
			}
			registered = true;
			int num3 = 0;
			pies = Pies;
			foreach (PieDef pieDef2 in pies)
			{
				try
				{
					RecipeConfig val = new RecipeConfig();
					val.Name = "Recipe_PieGuy_" + pieDef2.Raw;
					val.Item = pieDef2.Raw;
					val.CraftingStation = "piece_cauldron";
					val.MinStationLevel = 1;
					val.Amount = 1;
					Ingredient[] ingredients = pieDef2.Ingredients;
					foreach (Ingredient ingredient in ingredients)
					{
						string text2 = FindIngredient(ingredient.Prefab);
						if ((Object)(object)FindPrefab(text2) == (Object)null)
						{
							deferredIngredientNames.Add(text2);
						}
						val.AddRequirement(text2, ingredient.Count, 0);
					}
					ItemManager.Instance.AddRecipe(new CustomRecipe(val));
					num3++;
				}
				catch (Exception ex2)
				{
					((BaseUnityPlugin)this).Logger.LogError((object)("[PieGuy R41] Recipe for " + pieDef2.Name + ": " + ex2));
				}
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)("[PieGuy R41] Confirmed all 24 pie prefabs, registered " + num3 + " recipes."));
			if (deferredIngredientNames.Count > 0)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)("[PieGuy R41] Deferred ingredient lookup until item registration: " + string.Join(", ", deferredIngredientNames)));
			}
			RegisterBakingConversions();
			RefreshOvens();
		}

		private void RegisterBakingConversions()
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			if (conversionsSubmitted)
			{
				return;
			}
			conversionsSubmitted = true;
			int num = 0;
			PieDef[] pies = Pies;
			foreach (PieDef pieDef in pies)
			{
				string[] array = new string[2] { "piece_oven", "Piece_CobOven" };
				foreach (string text in array)
				{
					try
					{
						CookingConversionConfig val = new CookingConversionConfig();
						((ConversionConfig)val).FromItem = pieDef.Raw;
						((ConversionConfig)val).ToItem = pieDef.Cooked;
						((ConversionConfig)val).Station = text;
						val.CookTime = 50f;
						if (ItemManager.Instance.AddItemConversion(new CustomItemConversion((ConversionConfig)(object)val)))
						{
							num++;
							continue;
						}
						((BaseUnityPlugin)this).Logger.LogWarning((object)("[PieGuy R34] Conversion registration rejected: " + pieDef.Raw + " -> " + pieDef.Cooked + " on " + text));
					}
					catch (Exception ex)
					{
						((BaseUnityPlugin)this).Logger.LogWarning((object)("[PieGuy R34] Baking conversion for " + pieDef.Raw + " at " + text + ": " + ex.Message));
					}
				}
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)("[PieGuy R34] Queued " + num + "/" + Pies.Length * 2 + " Jotunn baking conversions (12 pies x 2 active oven prefabs)."));
		}

		private static void MakeItem(PieDef pie, bool cooked)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: 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)
			//IL_00bc: Expected O, but got Unknown
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Expected O, but got Unknown
			string text = (cooked ? pie.Cooked : pie.Raw);
			string text2 = (cooked ? "LoxPie" : "LoxPieUncooked");
			ItemConfig val = new ItemConfig
			{
				Name = (cooked ? pie.Name : ("Uncooked " + pie.Name)),
				Description = (cooked ? ("Freshly baked " + pie.Name.ToLowerInvariant() + ".") : ("Ready for the oven: " + pie.Name.ToLowerInvariant() + ".")),
				Enabled = false,
				StackSize = 10,
				Icon = PieVisuals.ReadIcon((cooked ? "cooked_" : "uncooked_") + pie.Asset)
			};
			CustomItem val2 = new CustomItem(text, text2, val);
			if ((Object)(object)val2.ItemPrefab == (Object)null)
			{
				throw new Exception("Clone returned no prefab for " + text);
			}
			PieVisuals.Install(val2.ItemPrefab, (cooked ? "cooked_" : "uncooked_") + pie.Asset);
			ItemDrop component = val2.ItemPrefab.GetComponent<ItemDrop>();
			if ((Object)(object)component != (Object)null && component.m_itemData != null && component.m_itemData.m_shared != null)
			{
				component.m_itemData.m_shared.m_icons = (Sprite[])(object)new Sprite[1] { PieVisuals.ReadIcon((cooked ? "cooked_" : "uncooked_") + pie.Asset) };
			}
			if (cooked)
			{
				ItemDrop component2 = val2.ItemPrefab.GetComponent<ItemDrop>();
				if ((Object)(object)component2 == (Object)null || component2.m_itemData == null || component2.m_itemData.m_shared == null)
				{
					throw new Exception("Cooked template has no item SharedData");
				}
				SharedData shared = component2.m_itemData.m_shared;
				SetFloat(shared, "m_food", pie.Health);
				SetFloat(shared, "m_foodStamina", pie.Stamina);
				SetFloat(shared, "m_foodEitr", pie.Eitr);
				SetFloat(shared, "m_foodRegen", pie.Heal);
				SetFloat(shared, "m_foodBurnTime", pie.Minutes * 60);
			}
			if (!ItemManager.Instance.AddItem(val2))
			{
				throw new Exception("ItemManager rejected " + text);
			}
		}

		private static void SetFloat(object obj, string field, float value)
		{
			FieldInfo field2 = obj.GetType().GetField(field, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field2 == null)
			{
				Log.LogWarning((object)("[PieGuy R34] Food field missing: " + field));
			}
			else
			{
				field2.SetValue(obj, Convert.ChangeType(value, field2.FieldType));
			}
		}

		private static ItemDrop FindItem(string key)
		{
			GameObject val = null;
			try
			{
				if ((Object)(object)ObjectDB.instance != (Object)null)
				{
					val = ObjectDB.instance.GetItemPrefab(key);
				}
			}
			catch
			{
			}
			if ((Object)(object)val == (Object)null)
			{
				val = FindPrefab(key);
			}
			if (!((Object)(object)val != (Object)null))
			{
				return null;
			}
			return val.GetComponent<ItemDrop>();
		}

		private void RefreshOvens()
		{
			if (!registered)
			{
				return;
			}
			TryOven("piece_oven");
			TryOven("Piece_CobOven");
			TryOven("PG_CobOven");
			CookingStation[] array = Resources.FindObjectsOfTypeAll<CookingStation>();
			foreach (CookingStation val in array)
			{
				if (!((Object)(object)val == (Object)null) && IsPieOven(val))
				{
					try
					{
						ApplyConversions(val, ((Object)((Component)val).gameObject).name);
					}
					catch (Exception ex)
					{
						((BaseUnityPlugin)this).Logger.LogWarning((object)("[PieGuy R34] Oven patch: " + ex.Message));
					}
				}
			}
		}

		private void TryOven(string prefabName)
		{
			GameObject val = FindPrefab(prefabName);
			if (!((Object)(object)val == (Object)null))
			{
				CookingStation val2 = val.GetComponent<CookingStation>() ?? val.GetComponentInChildren<CookingStation>(true);
				if ((Object)(object)val2 != (Object)null)
				{
					ApplyConversions(val2, prefabName);
				}
			}
		}

		private static bool IsPieOven(CookingStation station)
		{
			Transform val = ((Component)station).transform;
			while ((Object)(object)val != (Object)null)
			{
				string name = ((Object)((Component)val).gameObject).name;
				if (name.StartsWith("piece_oven", StringComparison.OrdinalIgnoreCase) || name.StartsWith("Piece_CobOven", StringComparison.OrdinalIgnoreCase) || name.StartsWith("PG_CobOven", StringComparison.OrdinalIgnoreCase))
				{
					return true;
				}
				Piece component = ((Component)val).GetComponent<Piece>();
				if ((Object)(object)component != (Object)null && (component.m_name == "Cob Oven" || component.m_name == "$piece_coboven"))
				{
					return true;
				}
				val = val.parent;
			}
			return false;
		}

		private void ApplyConversions(CookingStation oven, string label)
		{
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Expected O, but got Unknown
			if (oven.m_conversion == null)
			{
				oven.m_conversion = new List<ItemConversion>();
			}
			int num = 0;
			int num2 = 0;
			PieDef[] pies = Pies;
			foreach (PieDef obj in pies)
			{
				ItemDrop val = FindItem(obj.Raw);
				ItemDrop val2 = FindItem(obj.Cooked);
				if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null)
				{
					continue;
				}
				ItemConversion val3 = null;
				foreach (ItemConversion item in oven.m_conversion)
				{
					if (item != null && (Object)(object)item.m_from != (Object)null && ((Object)item.m_from).name == ((Object)val).name)
					{
						val3 = item;
						break;
					}
				}
				if (val3 != null)
				{
					if ((Object)(object)val3.m_from != (Object)(object)val || (Object)(object)val3.m_to != (Object)(object)val2 || Math.Abs(val3.m_cookTime - 50f) > 0.1f)
					{
						val3.m_from = val;
						val3.m_to = val2;
						val3.m_cookTime = 50f;
						num2++;
					}
				}
				else
				{
					oven.m_conversion.Add(new ItemConversion
					{
						m_from = val,
						m_to = val2,
						m_cookTime = 50f
					});
					num++;
				}
			}
			if (num > 0 || num2 > 0)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)("[PieGuy R34] Oven " + label + ": added " + num + " / refreshed " + num2 + " pie conversions (" + oven.m_conversion.Count + " total)."));
			}
		}
	}
	internal static class PieVisuals
	{
		internal sealed class Part
		{
			public Mesh Geometry;

			public uint Color;
		}

		private static readonly Dictionary<string, List<Part>> MeshCache = new Dictionary<string, List<Part>>();

		private static readonly Dictionary<string, Material> MaterialCache = new Dictionary<string, Material>();

		private static readonly Dictionary<string, Sprite> SpriteCache = new Dictionary<string, Sprite>();

		internal static void Install(GameObject prefab, string key)
		{
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Expected O, but got Unknown
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: 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)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			MeshRenderer[] componentsInChildren = prefab.GetComponentsInChildren<MeshRenderer>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				((Renderer)componentsInChildren[i]).enabled = false;
			}
			SkinnedMeshRenderer[] componentsInChildren2 = prefab.GetComponentsInChildren<SkinnedMeshRenderer>(true);
			for (int i = 0; i < componentsInChildren2.Length; i++)
			{
				((Renderer)componentsInChildren2[i]).enabled = false;
			}
			Transform val = FindDescendant(prefab.transform, "attach");
			if ((Object)(object)val == (Object)null)
			{
				GameObject val2 = new GameObject("attach");
				val2.transform.SetParent(prefab.transform, false);
				val = val2.transform;
			}
			GameObject val3 = new GameObject("PieGuy_R34_" + key);
			val3.transform.SetParent(val, false);
			val3.transform.localRotation = Quaternion.Inverse(Quaternion.Inverse(prefab.transform.rotation) * val.rotation);
			bool uncooked = key.StartsWith("uncooked_", StringComparison.Ordinal);
			foreach (Part item in ReadMeshes(key))
			{
				GameObject val4 = new GameObject("PieModel");
				val4.transform.SetParent(val3.transform, false);
				val4.layer = ((Component)val).gameObject.layer;
				val4.AddComponent<MeshFilter>().sharedMesh = item.Geometry;
				((Renderer)val4.AddComponent<MeshRenderer>()).sharedMaterial = GetMaterial(item.Color, uncooked);
			}
		}

		private static Transform FindDescendant(Transform root, string name)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			foreach (Transform item in root)
			{
				Transform val = item;
				if (((Object)val).name.Equals(name, StringComparison.OrdinalIgnoreCase))
				{
					return val;
				}
				Transform val2 = FindDescendant(val, name);
				if ((Object)(object)val2 != (Object)null)
				{
					return val2;
				}
			}
			return null;
		}

		private static Material GetMaterial(uint color, bool uncooked)
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Expected O, but got Unknown
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			string text = color.ToString("X8") + (uncooked ? "_raw" : "_baked");
			if (MaterialCache.TryGetValue(text, out var value))
			{
				return value;
			}
			Shader obj = Shader.Find("Standard") ?? Shader.Find("Custom/Piece") ?? Shader.Find("Legacy Shaders/Diffuse");
			if ((Object)(object)obj == (Object)null)
			{
				throw new Exception("No Unity surface shader available");
			}
			value = new Material(obj);
			((Object)value).name = "PieGuy_R34_" + text;
			float num = (float)((color >> 16) & 0xFF) / 255f;
			float num2 = (float)((color >> 8) & 0xFF) / 255f;
			float num3 = (float)(color & 0xFF) / 255f;
			float num4 = (uncooked ? 0.79f : 0.92f);
			value.color = new Color(num * num4, num2 * num4, num3 * num4, 1f);
			if (value.HasProperty("_Glossiness"))
			{
				value.SetFloat("_Glossiness", 0.01f);
			}
			if (value.HasProperty("_Metallic"))
			{
				value.SetFloat("_Metallic", 0f);
			}
			if (value.HasProperty("_Surface"))
			{
				value.SetFloat("_Surface", 0f);
			}
			if (value.HasProperty("_Mode"))
			{
				value.SetFloat("_Mode", 0f);
			}
			if (value.HasProperty("_Cull"))
			{
				value.SetInt("_Cull", 2);
			}
			MaterialCache[text] = value;
			return value;
		}

		private static List<Part> ReadMeshes(string key)
		{
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Expected O, but got Unknown
			if (MeshCache.TryGetValue(key, out var value))
			{
				return value;
			}
			using (Stream stream = typeof(PieVisuals).Assembly.GetManifestResourceStream("PieModel_" + key))
			{
				if (stream == null)
				{
					throw new Exception("Embedded pie OBJ mesh missing: " + key);
				}
				using GZipStream input = new GZipStream(stream, CompressionMode.Decompress);
				using BinaryReader binaryReader = new BinaryReader(input);
				if (new string(binaryReader.ReadChars(4)) != "PGQ3")
				{
					throw new Exception("Invalid geometry header " + key);
				}
				int num = binaryReader.ReadInt32();
				if (num < 1 || num > 40)
				{
					throw new Exception("Unexpected mesh count " + num);
				}
				value = new List<Part>(num);
				for (int i = 0; i < num; i++)
				{
					int count = binaryReader.ReadInt32();
					binaryReader.ReadBytes(count);
					uint color = binaryReader.ReadUInt32();
					int num2 = binaryReader.ReadInt32();
					if (num2 < 3 || num2 > 250000)
					{
						throw new Exception("Pie model exceeds mesh safety limit: " + key);
					}
					Vector3[] array = (Vector3[])(object)new Vector3[num2];
					for (int j = 0; j < num2; j++)
					{
						array[j] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
					}
					int num3 = binaryReader.ReadInt32();
					if (num3 < 3 || num3 > 1200000)
					{
						throw new Exception("Bad triangle count: " + key);
					}
					int[] array2 = new int[num3];
					for (int k = 0; k < num3; k++)
					{
						array2[k] = (int)binaryReader.ReadUInt32();
					}
					for (int l = 0; l + 2 < num3; l += 3)
					{
						int num4 = array2[l + 1];
						array2[l + 1] = array2[l + 2];
						array2[l + 2] = num4;
					}
					Mesh val = new Mesh();
					val.indexFormat = (IndexFormat)1;
					val.vertices = array;
					val.triangles = array2;
					val.RecalculateNormals();
					val.RecalculateBounds();
					value.Add(new Part
					{
						Geometry = val,
						Color = color
					});
				}
			}
			MeshCache[key] = value;
			return value;
		}

		public static Sprite ReadIcon(string key)
		{
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			if (SpriteCache.TryGetValue(key, out var value))
			{
				return value;
			}
			using Stream stream = typeof(PieVisuals).Assembly.GetManifestResourceStream("PieIcon_" + key);
			if (stream == null)
			{
				throw new Exception("Pie icon missing: " + key);
			}
			using GZipStream gZipStream = new GZipStream(stream, CompressionMode.Decompress);
			using MemoryStream memoryStream = new MemoryStream();
			gZipStream.CopyTo(memoryStream);
			byte[] array = memoryStream.ToArray();
			if (array.Length != 65536)
			{
				throw new Exception("Bad icon pixels for " + key);
			}
			Texture2D val = new Texture2D(128, 128, (TextureFormat)4, false);
			((Object)val).name = "PieGuy_" + key;
			byte[] array2 = new byte[array.Length];
			for (int i = 0; i < 128; i++)
			{
				Buffer.BlockCopy(array, (127 - i) * 512, array2, i * 512, 512);
			}
			val.LoadRawTextureData(array2);
			val.Apply(false, true);
			value = Sprite.Create(val, new Rect(0f, 0f, 128f, 128f), new Vector2(0.5f, 0.5f), 100f);
			((Object)value).name = key;
			SpriteCache[key] = value;
			return value;
		}
	}
}