Decompiled source of WindstridesSmokingHerbs v1.0.2

WindstridesSmokingHerbs.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("WindstridesSmokingHerbs")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.2.0")]
[assembly: AssemblyInformationalVersion("1.0.2")]
[assembly: AssemblyProduct("WindstridesSmokingHerbs")]
[assembly: AssemblyTitle("WindstridesSmokingHerbs")]
[assembly: AssemblyVersion("1.0.2.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 ValheimHerbSmoking
{
	internal static class BudAssets
	{
		private static Mesh mesh;

		private static Material darkForest;

		private static Material swamp;

		private static Material mistlands;

		private static bool Ready => (Object)(object)mesh != (Object)null;

		private static byte[] Resource(string name)
		{
			using Stream stream = typeof(Plugin).Assembly.GetManifestResourceStream("HerbAssets." + name) ?? throw new InvalidOperationException("Missing bud asset " + name);
			using MemoryStream memoryStream = new MemoryStream();
			stream.CopyTo(memoryStream);
			return memoryStream.ToArray();
		}

		private static Texture2D Texture(string name, bool linear = false)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: 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_001d: Expected O, but got Unknown
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true, linear)
			{
				name = name
			};
			if (!ImageConversion.LoadImage(val, Resource(name)))
			{
				throw new InvalidDataException("Invalid bud texture " + name);
			}
			((Texture)val).wrapMode = (TextureWrapMode)0;
			((Texture)val).filterMode = (FilterMode)2;
			((Texture)val).anisoLevel = 4;
			return val;
		}

		internal static void Load()
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: 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_0139: 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)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: 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_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//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_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0286: Unknown result type (might be due to invalid IL or missing references)
			//IL_0290: Unknown result type (might be due to invalid IL or missing references)
			//IL_0295: Unknown result type (might be due to invalid IL or missing references)
			//IL_0299: Unknown result type (might be due to invalid IL or missing references)
			//IL_029e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c1: 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_02d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e6: Expected O, but got Unknown
			if (Ready)
			{
				return;
			}
			using (BinaryReader binaryReader = new BinaryReader(new MemoryStream(Resource("bud.bin"))))
			{
				if (binaryReader.ReadInt32() != 826561858)
				{
					throw new InvalidDataException("Bud data version");
				}
				int num = binaryReader.ReadInt32();
				int num2 = binaryReader.ReadInt32();
				Vector3[] array = (Vector3[])(object)new Vector3[num];
				for (int i = 0; i < num; i++)
				{
					array[i] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
				}
				Vector3[] array2 = (Vector3[])(object)new Vector3[num2 * 3];
				Vector3[] array3 = (Vector3[])(object)new Vector3[num2 * 3];
				Vector3[] array4 = (Vector3[])(object)new Vector3[num];
				int[] array5 = new int[num2 * 3];
				Vector2[] array6 = (Vector2[])(object)new Vector2[num2 * 3];
				int[] array7 = new int[num2 * 3];
				int[] array8 = new int[3] { 0, 1, 2 };
				Vector3 val;
				for (int j = 0; j < num2; j++)
				{
					int[] array9 = new int[3]
					{
						binaryReader.ReadInt32(),
						binaryReader.ReadInt32(),
						binaryReader.ReadInt32()
					};
					Vector2[] array10 = (Vector2[])(object)new Vector2[3]
					{
						new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle()),
						new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle()),
						new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle())
					};
					val = Vector3.Cross(array[array9[1]] - array[array9[0]], array[array9[2]] - array[array9[0]]);
					Vector3 normalized = ((Vector3)(ref val)).normalized;
					for (int k = 0; k < 3; k++)
					{
						ref Vector3 reference = ref array4[array9[k]];
						reference += normalized;
					}
					for (int l = 0; l < 3; l++)
					{
						int num3 = j * 3 + l;
						array5[num3] = array9[array8[l]];
						array2[num3] = array[array5[num3]];
						array6[num3] = array10[array8[l]];
						array7[num3] = num3;
					}
				}
				Dictionary<(int, int, int), Vector3> dictionary = new Dictionary<(int, int, int), Vector3>();
				for (int m = 0; m < array.Length; m++)
				{
					(int, int, int) key = Key(array[m]);
					dictionary[key] = (dictionary.TryGetValue(key, out var value) ? (value + array4[m]) : array4[m]);
				}
				for (int n = 0; n < array3.Length; n++)
				{
					int num4 = n;
					val = dictionary[Key(array[array5[n]])];
					array3[num4] = ((Vector3)(ref val)).normalized;
				}
				mesh = new Mesh
				{
					name = "Authored herb bud",
					vertices = array2,
					normals = array3,
					uv = array6,
					triangles = array7
				};
				mesh.RecalculateTangents();
				mesh.RecalculateBounds();
			}
			Material val2 = PrefabManager.Instance.GetPrefab("Tankard").GetComponentsInChildren<MeshRenderer>(true).SelectMany((MeshRenderer renderer) => ((Renderer)renderer).sharedMaterials)
				.First((Material material) => Object.op_Implicit((Object)(object)material) && Object.op_Implicit((Object)(object)material.shader) && !((Object)material.shader).name.Contains("Particles"));
			darkForest = MakeMaterial(val2, "Black Forest bud", Texture("bud_darkforest.png"));
			swamp = MakeMaterial(val2, "Swamp bud", Texture("bud_swamp.png"));
			mistlands = MakeMaterial(val2, "Mistlands bud", Texture("bud_misty.png"));
			Plugin.Log.LogInfo((object)$"Bud assets ready: {mesh.vertexCount} render vertices; {mesh.triangles.Length / 3} triangles; shader {((Object)val2.shader).name}.");
			static (int, int, int) Key(Vector3 v)
			{
				//IL_0000: 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_0022: Unknown result type (might be due to invalid IL or missing references)
				return (Mathf.RoundToInt(v.x * 100000f), Mathf.RoundToInt(v.y * 100000f), Mathf.RoundToInt(v.z * 100000f));
			}
		}

		private static Material MakeMaterial(Material template, string name, Texture2D albedo)
		{
			//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_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			Material val = new Material(template)
			{
				name = name,
				mainTexture = (Texture)(object)albedo,
				color = Color.white
			};
			val.SetColor("_Color", Color.white);
			val.SetTexture("_EmissionMap", (Texture)(object)albedo);
			val.SetColor("_EmissionColor", new Color(0.55f, 0.55f, 0.55f, 1f));
			val.EnableKeyword("_EMISSION");
			val.SetTexture("_ParallaxMap", (Texture)null);
			val.DisableKeyword("_PARALLAXMAP");
			val.SetFloat("_SpecularHighlights", 0f);
			val.EnableKeyword("_SPECULARHIGHLIGHTS_OFF");
			val.SetFloat("_GlossyReflections", 0f);
			val.EnableKeyword("_GLOSSYREFLECTIONS_OFF");
			Texture2D val2 = Texture("bud_normal.png", linear: true);
			Color[] pixels = val2.GetPixels();
			for (int i = 0; i < pixels.Length; i++)
			{
				pixels[i] = new Color(1f, pixels[i].g, 1f, pixels[i].r);
			}
			val2.SetPixels(pixels);
			val2.Apply(true, false);
			val.SetTexture("_BumpMap", (Texture)(object)val2);
			val.SetFloat("_BumpScale", 0.25f);
			val.EnableKeyword("_NORMALMAP");
			Texture2D val3 = Texture("bud_metallic.png", linear: true);
			Texture2D obj = Texture("bud_roughness.png", linear: true);
			Color[] pixels2 = val3.GetPixels();
			Color[] pixels3 = obj.GetPixels();
			if (pixels2.Length == pixels3.Length)
			{
				for (int j = 0; j < pixels2.Length; j++)
				{
					pixels2[j] = new Color(pixels2[j].r, 0f, 0f, 1f - pixels3[j].r);
				}
				val3.SetPixels(pixels2);
				val3.Apply();
			}
			val.SetTexture("_MetallicGlossMap", (Texture)(object)val3);
			val.SetFloat("_Metallic", 0f);
			val.SetFloat("_Glossiness", 0.05f);
			val.SetFloat("_GlossMapScale", 0.65f);
			val.EnableKeyword("_METALLICGLOSSMAP");
			val.SetTexture("_OcclusionMap", (Texture)(object)Texture("bud_ao.png", linear: true));
			val.SetFloat("_OcclusionStrength", 1f);
			val.EnableKeyword("_OCCLUSIONMAP");
			return val;
		}

		private static Material For(string itemName)
		{
			if (!itemName.Contains("Swamp"))
			{
				if (!itemName.Contains("Mist"))
				{
					return darkForest;
				}
				return mistlands;
			}
			return swamp;
		}

		internal static void ReplaceBushBerries(string itemName, GameObject prefab)
		{
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: 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_0109: 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_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			Load();
			Transform[] array = (from transform in prefab.GetComponentsInChildren<Transform>(true)
				where string.Equals(((Object)transform).name, "Berrys", StringComparison.OrdinalIgnoreCase)
				select transform).ToArray();
			int num = 0;
			Transform[] array2 = array;
			for (int num2 = 0; num2 < array2.Length; num2++)
			{
				MeshFilter[] array3 = (from filter in ((Component)array2[num2]).GetComponentsInChildren<MeshFilter>(true)
					where Object.op_Implicit((Object)(object)filter) && (Object)(object)filter.sharedMesh != (Object)null
					select filter).ToArray();
				foreach (MeshFilter val in array3)
				{
					if ((Object)(object)val.sharedMesh != (Object)null && !((Object)val.sharedMesh).name.StartsWith("HerbBushBud_", StringComparison.Ordinal))
					{
						Bounds target = val.sharedMesh.bounds;
						Bounds source = mesh.bounds;
						float scale = 1.9f * Mathf.Max(((Bounds)(ref target)).size.x, Mathf.Max(((Bounds)(ref target)).size.y, ((Bounds)(ref target)).size.z)) / Mathf.Max(((Bounds)(ref source)).size.x, Mathf.Max(((Bounds)(ref source)).size.y, ((Bounds)(ref source)).size.z));
						Mesh val2 = Object.Instantiate<Mesh>(mesh);
						((Object)val2).name = "HerbBushBud_" + ((Object)val.sharedMesh).name;
						val2.vertices = mesh.vertices.Select((Vector3 vertex) => (vertex - ((Bounds)(ref source)).center) * scale + ((Bounds)(ref target)).center).ToArray();
						val2.RecalculateBounds();
						val.sharedMesh = val2;
					}
					MeshRenderer component = ((Component)val).GetComponent<MeshRenderer>();
					if ((Object)(object)component != (Object)null)
					{
						((Renderer)component).sharedMaterial = For(itemName);
						((Renderer)component).enabled = true;
					}
					num++;
				}
			}
			Plugin.Log.LogInfo((object)$"Replaced {num} vanilla berry meshes with {itemName} bud meshes on {((Object)prefab).name}.");
		}

		internal static MeshFilter[] FindBushBudMeshes(GameObject prefab)
		{
			return (from filter in (from transform in prefab.GetComponentsInChildren<Transform>(true)
					where string.Equals(((Object)transform).name, "Berrys", StringComparison.OrdinalIgnoreCase)
					select transform).SelectMany((Transform cluster) => ((Component)cluster).GetComponentsInChildren<MeshFilter>(true))
				where Object.op_Implicit((Object)(object)filter) && (Object)(object)filter.sharedMesh != (Object)null && ((Object)filter.sharedMesh).name.StartsWith("HerbBushBud_", StringComparison.Ordinal)
				select filter).Distinct().ToArray();
		}

		internal static void ReplaceItem(string itemName, GameObject prefab)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: 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)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: 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_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//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_0158: 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_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Expected O, but got Unknown
			//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_0111: 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_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Expected O, but got Unknown
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			Load();
			Transform val = prefab.transform.Find("attach") ?? prefab.transform;
			Renderer[] componentsInChildren = ((Component)val).GetComponentsInChildren<Renderer>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				componentsInChildren[i].enabled = false;
			}
			GameObject val2 = new GameObject("AuthoredBud");
			val2.transform.SetParent(val, false);
			val2.transform.localScale = Vector3.one * 10.125f;
			val2.AddComponent<MeshFilter>().sharedMesh = mesh;
			MeshRenderer val3 = val2.AddComponent<MeshRenderer>();
			((Renderer)val3).sharedMaterial = For(itemName);
			if (!Application.isBatchMode)
			{
				val2.transform.localScale = Vector3.one * 6.75f;
				Material sharedMaterial = ((Renderer)val3).sharedMaterial;
				Shader val4 = Shader.Find("Unlit/Texture") ?? Shader.Find("Unlit/Transparent") ?? Shader.Find("UI/Default");
				Material val5 = null;
				if (Object.op_Implicit((Object)(object)val4))
				{
					val5 = (((Renderer)val3).sharedMaterial = new Material(val4)
					{
						name = itemName + " neutral icon",
						mainTexture = sharedMaterial.mainTexture,
						color = Color.white
					});
				}
				Sprite val7 = RenderManager.Instance.Render(new RenderRequest(val2)
				{
					Rotation = Quaternion.Euler(24f, 45f, -18f),
					Width = 256,
					Height = 256,
					DistanceMultiplier = 0.68f,
					ParticleSimulationTime = -1f
				});
				if (Object.op_Implicit((Object)(object)val7))
				{
					prefab.GetComponent<ItemDrop>().m_itemData.m_shared.m_icons = (Sprite[])(object)new Sprite[1] { IconStyling.AddSoftShadow(val7) };
				}
				((Renderer)val3).sharedMaterial = sharedMaterial;
				if (Object.op_Implicit((Object)(object)val5))
				{
					Object.Destroy((Object)(object)val5);
				}
				else
				{
					Plugin.Log.LogWarning((object)"No unlit shader was available for neutral bud icon rendering.");
				}
				val2.transform.localScale = Vector3.one * 10.125f;
			}
			GameObject val8 = new GameObject("DroppedBudMotes");
			val8.transform.SetParent(val, false);
			Transform transform = val8.transform;
			Vector3 localPosition = val2.transform.localPosition;
			Bounds bounds = mesh.bounds;
			transform.localPosition = localPosition + Vector3.Scale(((Bounds)(ref bounds)).center, val2.transform.localScale);
			val8.AddComponent<HerbMoteCloud>().Configure(itemName);
		}
	}
	internal sealed class Config
	{
		public readonly ConfigEntry<float> WildChance;

		public readonly ConfigEntry<bool> DebugCommands;

		public readonly ConfigEntry<float> SkogDuration;

		public readonly ConfigEntry<float> MyrDuration;

		public readonly ConfigEntry<float> MistDuration;

		public readonly ConfigEntry<float> SkogStaminaRegen;

		public readonly ConfigEntry<float> SkogMovementSpeed;

		public readonly ConfigEntry<float> MyrHealthRegen;

		public readonly ConfigEntry<float> MyrPoisonResistance;

		public readonly ConfigEntry<float> MistStaminaRegen;

		public readonly ConfigEntry<float> MistHealthRegen;

		public readonly ConfigEntry<float> MistEitrRegen;

		public readonly ConfigEntry<float> GrindingSeedQuality;

		public readonly ConfigEntry<float> GrindingSeedChance;

		public readonly ConfigEntry<int> PipeFineWoodCost;

		public readonly ConfigEntry<int> PipeSurtlingCoreCost;

		public readonly ConfigEntry<int> PipeResinCost;

		public readonly ConfigEntry<int> BudParticleCount;

		public readonly ConfigEntry<float> BudParticleMinimumSize;

		public readonly ConfigEntry<float> BudParticleMaximumSize;

		public readonly ConfigEntry<float> BudParticleRadius;

		public readonly ConfigEntry<float> BudParticleCameraOffset;

		private static ConfigEntry<T> Bind<T>(ConfigFile file, string section, string key, T value, string description)
		{
			//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_009c: Expected O, but got Unknown
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Expected O, but got Unknown
			AcceptableValueBase val = null;
			if (value is int)
			{
				val = (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100);
			}
			if (value is float)
			{
				float num = (key.Contains("seconds") ? 1f : 0f);
				float num2 = (key.Contains("seconds") ? 86400f : ((key.Contains("chance") || key.Contains("resistance")) ? 1f : 10f));
				val = (AcceptableValueBase)(object)new AcceptableValueRange<float>(num, num2);
			}
			return file.Bind<T>(section, key, value, new ConfigDescription(description, val, new object[1] { (object)new ConfigurationManagerAttributes
			{
				IsAdminOnly = true
			} }));
		}

		public Config(ConfigFile file)
		{
			WildChance = Bind(file, "World", "Wild plant chance", 0.05f, "Probability per eligible 64x64m biome zone (0 to 1), for both new terrain and retrofitted existing terrain.");
			DebugCommands = Bind(file, "Development", "Enable debug console commands", value: false, "Enables administrator-only setup, spawn and retrofit commands for testing.");
			SkogDuration = Bind(file, "Effects", "Skog duration seconds", 300f, "Smoke effect duration.");
			MyrDuration = Bind(file, "Effects", "Myr duration seconds", 300f, "Smoke effect duration.");
			MistDuration = Bind(file, "Effects", "Mist duration seconds", 300f, "Smoke effect duration.");
			SkogStaminaRegen = Bind(file, "Effects", "Skog stamina regeneration bonus", 0.3f, "Additive stamina regeneration multiplier.");
			SkogMovementSpeed = Bind(file, "Effects", "Skog movement speed bonus", 0.05f, "Movement-speed modifier while active.");
			MyrHealthRegen = Bind(file, "Effects", "Myr healing per tick", 4f, "Health restored every normal ten-second food-regeneration tick.");
			MyrPoisonResistance = Bind(file, "Effects", "Myr poison resistance", 0.25f, "Fraction of poison damage prevented while active.");
			MistStaminaRegen = Bind(file, "Effects", "Veilweed stamina regeneration bonus", 0.1f, "Additive stamina regeneration multiplier.");
			MistHealthRegen = Bind(file, "Effects", "Veilweed healing per tick", 2f, "Health restored every normal ten-second food-regeneration tick.");
			MistEitrRegen = Bind(file, "Effects", "Veilweed eitr regeneration bonus", 0.3f, "Additive eitr regeneration multiplier.");
			GrindingSeedQuality = Bind(file, "Mortar", "Seed quality threshold", 0.9f, "Grinding quality that must be exceeded for a recovered seed (0 to 1).");
			GrindingSeedChance = Bind(file, "Mortar", "Excellent grind seed chance", 1f, "Maximum chance to recover a matching seed from a perfect grind (0 to 1).");
			PipeFineWoodCost = Bind(file, "Recipes", "Pipe fine wood cost", 4, "Fine wood required for the Runed Pipe.");
			PipeSurtlingCoreCost = Bind(file, "Recipes", "Pipe surtling core cost", 1, "Surtling cores required for the Runed Pipe.");
			PipeResinCost = Bind(file, "Recipes", "Pipe resin cost", 2, "Resin required for the Runed Pipe.");
			BudParticleCount = Bind(file, "Visuals", "Bud particle count", 7, "Particles emitted by every bud. Shared by Skog, Myr and Veilweed.");
			BudParticleMinimumSize = Bind(file, "Visuals", "Bud particle minimum size", 0.0045f, "Minimum particle size shared by every strain.");
			BudParticleMaximumSize = Bind(file, "Visuals", "Bud particle maximum size", 0.0105f, "Maximum particle size shared by every strain.");
			BudParticleRadius = Bind(file, "Visuals", "Bud particle radius", 0.105f, "Maximum particle spread around every bud.");
			BudParticleCameraOffset = Bind(file, "Visuals", "Bud particle camera offset", 0.12f, "Moves each particle cloud toward the camera so foliage cannot hide it.");
		}
	}
	internal static class DebugCommands
	{
		private sealed class GrowHerbsCommand : ConsoleCommand
		{
			public override string Name => "herb_grow";

			public override string Help => "Force-matures planted herb seedlings nearby: herb_grow [radius].";

			public override bool IsCheat => false;

			public override void Run(string[] args, Terminal context)
			{
				//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
				//IL_010b: Unknown result type (might be due to invalid IL or missing references)
				Player localPlayer = Player.m_localPlayer;
				if ((Object)(object)localPlayer == (Object)null || (Object)(object)ZNet.instance == (Object)null)
				{
					context.AddString("Enter a world first.");
					return;
				}
				if (!Plugin.Settings.DebugCommands.Value || !SynchronizationManager.Instance.PlayerIsAdmin)
				{
					context.AddString("Debug growing is disabled or requires admin status.");
					return;
				}
				if (!ZNet.instance.IsServer())
				{
					context.AddString("Run herb_grow on the world host/server.");
					return;
				}
				float result = 30f;
				if (args.Length != 0 && (!float.TryParse(args[0], out result) || result < 1f || result > 200f))
				{
					context.AddString("Usage: herb_grow [radius 1-200]");
					return;
				}
				MethodInfo methodInfo = AccessTools.Method(typeof(Plant), "Grow", (Type[])null, (Type[])null);
				if (methodInfo == null)
				{
					context.AddString("Plant growth method was not found in this game version.");
					return;
				}
				int num = 0;
				Plant[] array = Object.FindObjectsOfType<Plant>();
				foreach (Plant val in array)
				{
					if (Object.op_Implicit((Object)(object)val) && ((Object)val).name.StartsWith("HerbSmoking_Plant", StringComparison.Ordinal) && !(Vector3.Distance(((Component)localPlayer).transform.position, ((Component)val).transform.position) > result))
					{
						methodInfo.Invoke(val, Array.Empty<object>());
						num++;
					}
				}
				context.AddString($"Forced {num} nearby herb seedling(s) to run their growth step. Use this for iteration; use skiptime 21600 to test normal biome and ground restrictions.");
			}
		}

		private sealed class CountHerbBushesCommand : ConsoleCommand
		{
			private static readonly FieldRef<ZDOMan, Dictionary<ZDOID, ZDO>> WorldObjects = AccessTools.FieldRefAccess<ZDOMan, Dictionary<ZDOID, ZDO>>("m_objectsByID");

			public override string Name => "herb_bush_count";

			public override string Help => "Counts saved wild and cultivated herb bushes throughout the hosted world.";

			public override bool IsCheat => false;

			public override void Run(string[] args, Terminal context)
			{
				if (ZDOMan.instance == null || (Object)(object)ZNet.instance == (Object)null)
				{
					context.AddString("Enter a world first.");
					return;
				}
				if (!ZNet.instance.IsServer())
				{
					context.AddString("Whole-world bush counts are available only to the world host/server.");
					return;
				}
				int num = Count("HerbSmoking_PlantSkog_Wild");
				int num2 = Count("HerbSmoking_PlantMyr_Wild");
				int num3 = Count("HerbSmoking_PlantMist_Wild");
				int num4 = Count("HerbSmoking_PlantSkog_Grown");
				int num5 = Count("HerbSmoking_PlantMyr_Grown");
				int num6 = Count("HerbSmoking_PlantMist_Grown");
				context.AddString($"Wild herb bushes saved in world: {num + num2 + num3} total — Black Forest {num}, Swamp {num2}, Mistlands {num3}.");
				context.AddString($"Cultivated mature bushes: {num4 + num5 + num6} total — Black Forest {num4}, Swamp {num5}, Mistlands {num6}.");
			}

			private static int Count(string prefabName)
			{
				int stableHashCode = StringExtensionMethods.GetStableHashCode(prefabName);
				int num = 0;
				foreach (ZDO value in WorldObjects.Invoke(ZDOMan.instance).Values)
				{
					if (value != null && value.GetPrefab() == stableHashCode)
					{
						num++;
					}
				}
				return num;
			}
		}

		private sealed class RetrofitHerbCommand : ConsoleCommand
		{
			public override string Name => "herb_retrofit";

			public override string Help => "Processes loaded, already-generated zones for deterministic wild herb spawning.";

			public override bool IsCheat => false;

			public override void Run(string[] args, Terminal context)
			{
				if ((Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)ZNet.instance == (Object)null)
				{
					context.AddString("Enter a world first.");
				}
				else if (!Plugin.Settings.DebugCommands.Value || !SynchronizationManager.Instance.PlayerIsAdmin)
				{
					context.AddString("Herb retrofit requires enabled debug commands and admin status.");
				}
				else if (!ZNet.instance.IsServer())
				{
					context.AddString("Run herb_retrofit on the world host/server. Automatic retrofit is server-authoritative.");
				}
				else
				{
					((MonoBehaviour)Plugin.Instance).StartCoroutine(VegetationRetrofit.ProcessLoadedAroundPlayer(context));
				}
			}
		}

		private sealed class SpawnHerbBushCommand : ConsoleCommand
		{
			public override string Name => "herb_spawn_bush";

			public override string Help => "Spawns an authored herb bush: herb_spawn_bush [skog|myr|veilweed].";

			public override bool IsCheat => false;

			public override void Run(string[] args, Terminal context)
			{
				//IL_019d: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
				//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
				//IL_01be: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ca: 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)
				//IL_01d4: 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_021b: Unknown result type (might be due to invalid IL or missing references)
				//IL_022a: 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)
				Player localPlayer = Player.m_localPlayer;
				if ((Object)(object)localPlayer == (Object)null)
				{
					context.AddString("Enter a world first.");
					return;
				}
				if (!Plugin.Settings.DebugCommands.Value || !SynchronizationManager.Instance.PlayerIsAdmin)
				{
					context.AddString("Debug bush spawning is disabled or requires admin status.");
					return;
				}
				string text = ((args.Length != 0) ? args[0].ToLowerInvariant() : "black");
				string text2;
				switch (text)
				{
				case "black":
				case "skog":
				case "forest":
					text2 = "HerbSmoking_PlantSkog_Grown";
					break;
				case "swamp":
				case "myr":
					text2 = "HerbSmoking_PlantMyr_Grown";
					break;
				case "mist":
				case "veilweed":
				case "mistlands":
					text2 = "HerbSmoking_PlantMist_Grown";
					break;
				default:
					text2 = null;
					break;
				}
				string text3 = text2;
				if (text3 == null)
				{
					context.AddString("Usage: herb_spawn_bush [skog|myr|veilweed]");
					return;
				}
				ZNetScene instance = ZNetScene.instance;
				GameObject val = ((instance != null) ? instance.GetPrefab(text3) : null);
				if ((Object)(object)val == (Object)null)
				{
					context.AddString("Herb bush prefab is not registered.");
					return;
				}
				Vector3 val2 = ((Component)localPlayer).transform.position + ((Component)localPlayer).transform.forward * 3f;
				RaycastHit val3 = default(RaycastHit);
				if (Physics.Raycast(val2 + Vector3.up * 10f, Vector3.down, ref val3, 50f, LayerMask.GetMask(new string[1] { "terrain" })))
				{
					val2.y = ((RaycastHit)(ref val3)).point.y;
				}
				Object.Instantiate<GameObject>(val, val2, Quaternion.Euler(0f, ((Component)localPlayer).transform.eulerAngles.y, 0f));
				context.AddString("Spawned " + text + " herb bush (" + text3 + ").");
			}
		}

		private sealed class PoseTraceCommand : ConsoleCommand
		{
			public override string Name => "herb_pose_trace";

			public override string Help => "Toggle local smoke blend-out pose diagnostics in the BepInEx log.";

			public override bool IsCheat => false;

			public override void Run(string[] args, Terminal context)
			{
				PipePerformance.TraceEnabled = !PipePerformance.TraceEnabled;
				context.AddString("Pipe pose trace: " + PipePerformance.TraceEnabled);
			}
		}

		private sealed class SetupHerbCommand : ConsoleCommand
		{
			private static readonly (string Prefab, int Amount)[] Kit = new(string, int)[19]
			{
				("HerbSmoking_WoodenPipe", 1),
				("HerbSmoking_MortarAndPestle", 1),
				("HerbSmoking_SeedBlack", 4),
				("HerbSmoking_SeedSwamp", 4),
				("HerbSmoking_SeedMist", 4),
				("HerbSmoking_RawBlack", 6),
				("HerbSmoking_RawSwamp", 6),
				("HerbSmoking_RawMist", 6),
				("HerbSmoking_CuredBlack", 3),
				("HerbSmoking_CuredSwamp", 3),
				("HerbSmoking_CuredMist", 3),
				("Cultivator", 1),
				("Hoe", 1),
				("FineWood", 20),
				("Stone", 16),
				("Resin", 20),
				("SurtlingCore", 4),
				("Ooze", 12),
				("BlackCore", 4)
			};

			public override string Name => "herb_setup";

			public override string Help => "Gives the herb test kit: herbs, seeds, tools, and pipe/mortar crafting materials.";

			public override bool IsCheat => false;

			public override void Run(string[] args, Terminal context)
			{
				Player localPlayer = Player.m_localPlayer;
				if ((Object)(object)localPlayer == (Object)null)
				{
					context.AddString("Enter a world first.");
					return;
				}
				if (!Plugin.Settings.DebugCommands.Value || !SynchronizationManager.Instance.PlayerIsAdmin)
				{
					context.AddString("Debug setup is disabled or requires admin status.");
					return;
				}
				ObjectDB instance = ObjectDB.instance;
				if ((Object)(object)instance == (Object)null)
				{
					context.AddString("Item database is not ready.");
					return;
				}
				Inventory inventory = ((Humanoid)localPlayer).GetInventory();
				if (inventory.GetAllItems().Count > 12)
				{
					context.AddString("Empty at least 20 inventory slots, then run herb_setup again.");
					return;
				}
				(string, int)[] kit = Kit;
				for (int i = 0; i < kit.Length; i++)
				{
					(string, int) tuple = kit[i];
					if ((Object)(object)instance.GetItemPrefab(tuple.Item1) == (Object)null)
					{
						context.AddString("Missing item registration: " + tuple.Item1);
						return;
					}
				}
				kit = Kit;
				for (int i = 0; i < kit.Length; i++)
				{
					(string, int) tuple2 = kit[i];
					AddItem(inventory, instance.GetItemPrefab(tuple2.Item1), tuple2.Item2);
				}
				context.AddString("Herb test kit added. Equip the Mortar and Pestle, open your inventory to load a bud, then left-click to grind. Run herb_validate for registration checks.");
			}

			private static void AddItem(Inventory inventory, GameObject prefab, int amount)
			{
				int maxStackSize = prefab.GetComponent<ItemDrop>().m_itemData.m_shared.m_maxStackSize;
				while (amount > 0)
				{
					int num = Math.Min(amount, maxStackSize);
					inventory.AddItem(prefab, num);
					amount -= num;
				}
			}
		}

		private sealed class GiveHerbCommand : ConsoleCommand
		{
			public override string Name => "herb_give";

			public override string Help => "Gives prototype herb-smoking items to the local player.";

			public override bool IsCheat => false;

			public override void Run(string[] args, Terminal context)
			{
				if ((Object)(object)Player.m_localPlayer == (Object)null)
				{
					context.AddString("Enter a world first.");
					return;
				}
				if (!Plugin.Settings.DebugCommands.Value || !SynchronizationManager.Instance.PlayerIsAdmin)
				{
					context.AddString("Debug item grants are disabled or require admin status.");
					return;
				}
				if (args.Length == 0)
				{
					context.AddString("Usage: herb_give <pipe|mortar|raw_black|raw_swamp|raw_mist|cured_black|cured_swamp|cured_mist> [amount]");
					return;
				}
				string text;
				switch (args[0].ToLowerInvariant())
				{
				case "pipe":
					text = "HerbSmoking_WoodenPipe";
					break;
				case "mortar":
				case "pestle":
					text = "HerbSmoking_MortarAndPestle";
					break;
				case "seed_black":
					text = "HerbSmoking_SeedBlack";
					break;
				case "seed_swamp":
					text = "HerbSmoking_SeedSwamp";
					break;
				case "seed_mist":
					text = "HerbSmoking_SeedMist";
					break;
				case "raw_black":
					text = "HerbSmoking_RawBlack";
					break;
				case "raw_swamp":
					text = "HerbSmoking_RawSwamp";
					break;
				case "raw_mist":
					text = "HerbSmoking_RawMist";
					break;
				case "cured_black":
				case "ground_black":
					text = "HerbSmoking_CuredBlack";
					break;
				case "cured_swamp":
				case "ground_swamp":
					text = "HerbSmoking_CuredSwamp";
					break;
				case "cured_mist":
				case "ground_mist":
					text = "HerbSmoking_CuredMist";
					break;
				default:
					text = null;
					break;
				}
				string text2 = text;
				if (text2 == null)
				{
					context.AddString("Unknown herb item.");
					return;
				}
				int result;
				int num = ((args.Length <= 1 || !int.TryParse(args[1], out result)) ? 1 : Mathf.Clamp(result, 1, 50));
				ObjectDB instance = ObjectDB.instance;
				GameObject val = ((instance != null) ? instance.GetItemPrefab(text2) : null);
				if ((Object)(object)val == (Object)null)
				{
					context.AddString("Missing item registration.");
					return;
				}
				Inventory inventory = ((Humanoid)Player.m_localPlayer).GetInventory();
				if (!inventory.CanAddItem(val, num))
				{
					context.AddString("Not enough inventory space.");
					return;
				}
				int num2 = num;
				while (num2 > 0)
				{
					int num3 = Math.Min(num2, val.GetComponent<ItemDrop>().m_itemData.m_shared.m_maxStackSize);
					if (!inventory.AddItem(val, num3))
					{
						context.AddString($"Added only {num - num2} items.");
						return;
					}
					num2 -= num3;
				}
				context.AddString($"Gave {num} {text2}.");
			}
		}

		private sealed class ValidateHerbCommand : ConsoleCommand
		{
			public override string Name => "herb_validate";

			public override string Help => "Reports herb-smoking registrations in the current world.";

			public override bool IsCheat => false;

			public override void Run(string[] args, Terminal context)
			{
				ObjectDB db = ObjectDB.instance;
				if ((Object)(object)db == (Object)null || (Object)(object)Player.m_localPlayer == (Object)null)
				{
					context.AddString("Enter a world first.");
					return;
				}
				string[] array = new string[11]
				{
					"HerbSmoking_RawBlack", "HerbSmoking_RawSwamp", "HerbSmoking_RawMist", "HerbSmoking_SeedBlack", "HerbSmoking_SeedSwamp", "HerbSmoking_SeedMist", "HerbSmoking_CuredBlack", "HerbSmoking_CuredSwamp", "HerbSmoking_CuredMist", "HerbSmoking_WoodenPipe",
					"HerbSmoking_MortarAndPestle"
				};
				RuntimeTests.Validate(context);
				string text = string.Join(", ", Array.FindAll(array, (string name) => (Object)(object)db.GetItemPrefab(name) == (Object)null));
				context.AddString((text.Length == 0) ? "Items: all 11 registered." : ("Missing items: " + text));
				context.AddString("Handheld mortar: " + (((Object)(object)db.GetItemPrefab("HerbSmoking_MortarAndPestle") != (Object)null) ? "registered" : "missing") + "; plants: " + $"{CountPlants()}/3 registered; effects: {CountEffects()}/3 registered.");
			}

			private static int CountPlants()
			{
				return Array.FindAll(new string[3] { "HerbSmoking_PlantSkog", "HerbSmoking_PlantMyr", "HerbSmoking_PlantMist" }, delegate(string name)
				{
					ZNetScene instance = ZNetScene.instance;
					return (Object)(object)((instance != null) ? instance.GetPrefab(name) : null) != (Object)null;
				}).Length;
			}

			private static int CountEffects()
			{
				return Array.FindAll(new string[3] { "SkogSmoke", "MyrSmoke", "MistSmoke" }, (string name) => (Object)(object)ObjectDB.instance.GetStatusEffect(StringExtensionMethods.GetStableHashCode(name)) != (Object)null).Length;
			}
		}

		public static void Register(bool enabled)
		{
			if (enabled)
			{
				CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new GiveHerbCommand());
				CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new SetupHerbCommand());
				CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new RuntimeTests());
				CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new ValidateHerbCommand());
				CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new PoseTraceCommand());
				CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new SpawnHerbBushCommand());
				CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new RetrofitHerbCommand());
				CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new CountHerbBushesCommand());
				CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new GrowHerbsCommand());
				Plugin.Log.LogInfo((object)"Debug commands registered: herb_give, herb_setup, herb_spawn_bush, herb_grow, herb_retrofit, herb_bush_count, herb_validate and herb_test.");
			}
		}
	}
	internal static class GroundHerbAssets
	{
		private static Mesh mesh;

		private static Material skog;

		private static Material myr;

		private static Material mist;

		private static byte[] Resource(string name)
		{
			using Stream stream = typeof(Plugin).Assembly.GetManifestResourceStream("HerbAssets." + name) ?? throw new InvalidOperationException("Missing ground-herb asset " + name);
			using MemoryStream memoryStream = new MemoryStream();
			stream.CopyTo(memoryStream);
			return memoryStream.ToArray();
		}

		private static Texture2D Texture(string name)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: 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_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			//IL_0045: 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_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true, false)
			{
				name = name,
				wrapMode = (TextureWrapMode)0,
				filterMode = (FilterMode)0,
				anisoLevel = 1
			};
			if (!ImageConversion.LoadImage(val, Resource(name)))
			{
				throw new InvalidDataException("Invalid ground-herb texture " + name);
			}
			((Texture)val).wrapMode = (TextureWrapMode)0;
			((Texture)val).filterMode = (FilterMode)0;
			((Texture)val).anisoLevel = 1;
			return val;
		}

		internal static void Load()
		{
			if (!Object.op_Implicit((Object)(object)mesh))
			{
				mesh = LoadObj(Encoding.UTF8.GetString(Resource("ground_herb.obj")));
				Material template = PrefabManager.Instance.GetPrefab("Tankard").GetComponentsInChildren<MeshRenderer>(true).SelectMany((MeshRenderer renderer) => ((Renderer)renderer).sharedMaterials)
					.First((Material material) => Object.op_Implicit((Object)(object)material) && Object.op_Implicit((Object)(object)material.shader) && ((Object)material.shader).name == "Standard");
				skog = MakeMaterial(template, "Ground Skog herb", Texture("ground_herb_darkforest.png"));
				myr = MakeMaterial(template, "Ground Myr herb", Texture("ground_herb_swamp.png"));
				mist = MakeMaterial(template, "Ground Mist herb", Texture("ground_herb_mist.png"));
				Plugin.Log.LogInfo((object)$"Ground herb asset ready: {mesh.vertexCount} render vertices, {mesh.triangles.Length / 3} triangles, 32x32 double-sided materials.");
			}
		}

		private static Material MakeMaterial(Material template, string name, Texture2D albedo)
		{
			//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_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: 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_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: 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_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: 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_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: 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_00fa: 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_0112: Expected O, but got Unknown
			Material val = new Material(template)
			{
				name = name,
				mainTexture = (Texture)(object)albedo,
				color = Color.white,
				doubleSidedGI = true
			};
			val.SetColor("_Color", Color.white);
			val.SetTexture("_EmissionMap", (Texture)(object)albedo);
			val.SetColor("_EmissionColor", new Color(0.55f, 0.55f, 0.55f, 1f));
			val.EnableKeyword("_EMISSION");
			val.SetInt("_Cull", 0);
			val.SetFloat("_Metallic", 0f);
			val.SetFloat("_Glossiness", 0.08f);
			val.SetFloat("_GlossMapScale", 0f);
			val.SetFloat("_SpecularHighlights", 0f);
			val.EnableKeyword("_SPECULARHIGHLIGHTS_OFF");
			val.SetFloat("_GlossyReflections", 0f);
			val.EnableKeyword("_GLOSSYREFLECTIONS_OFF");
			val.SetTexture("_BumpMap", (Texture)null);
			val.DisableKeyword("_NORMALMAP");
			val.SetTexture("_MetallicGlossMap", (Texture)null);
			val.DisableKeyword("_METALLICGLOSSMAP");
			return val;
		}

		private static Material For(string itemName)
		{
			if (!itemName.Contains("Swamp"))
			{
				if (!itemName.Contains("Mist"))
				{
					return skog;
				}
				return mist;
			}
			return myr;
		}

		internal static void ReplaceItem(string itemName, GameObject prefab)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected O, but got Unknown
			//IL_0065: 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_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: 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_01e4: 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_01f7: 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_0127: 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_014c: 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_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Expected O, but got Unknown
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: 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_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Expected O, but got Unknown
			Load();
			Transform val = prefab.transform.Find("attach") ?? prefab.transform;
			Renderer[] componentsInChildren = ((Component)val).GetComponentsInChildren<Renderer>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				componentsInChildren[i].enabled = false;
			}
			GameObject val2 = new GameObject("AuthoredGroundHerb");
			val2.transform.SetParent(val, false);
			val2.transform.localScale = Vector3.one * 1.5f;
			val2.AddComponent<MeshFilter>().sharedMesh = mesh;
			MeshRenderer val3 = val2.AddComponent<MeshRenderer>();
			((Renderer)val3).sharedMaterial = For(itemName);
			if (!Application.isBatchMode)
			{
				Material sharedMaterial = ((Renderer)val3).sharedMaterial;
				Shader val4 = Shader.Find("Unlit/Texture") ?? Shader.Find("Unlit/Transparent") ?? Shader.Find("UI/Default");
				Material val5 = null;
				if (Object.op_Implicit((Object)(object)val4))
				{
					val5 = (((Renderer)val3).sharedMaterial = new Material(val4)
					{
						name = itemName + " ground-herb icon",
						mainTexture = sharedMaterial.mainTexture,
						color = Color.white
					});
				}
				Sprite val7 = RenderManager.Instance.Render(new RenderRequest(val2)
				{
					Rotation = Quaternion.Euler(28f, 135f, -8f),
					Width = 256,
					Height = 256,
					DistanceMultiplier = 0.78f,
					ParticleSimulationTime = -1f
				});
				if (Object.op_Implicit((Object)(object)val7))
				{
					prefab.GetComponent<ItemDrop>().m_itemData.m_shared.m_icons = (Sprite[])(object)new Sprite[1] { IconStyling.AddSoftShadow(val7) };
				}
				((Renderer)val3).sharedMaterial = sharedMaterial;
				if (Object.op_Implicit((Object)(object)val5))
				{
					Object.Destroy((Object)(object)val5);
				}
			}
			Bounds bounds = mesh.bounds;
			Vector3 localPosition = ((Bounds)(ref bounds)).center * 1.5f;
			GameObject val8 = new GameObject("GroundHerbEffects");
			val8.transform.SetParent(val, false);
			val8.transform.localPosition = localPosition;
			val8.AddComponent<HerbMoteCloud>().Configure(itemName);
		}

		private static Mesh LoadObj(string obj)
		{
			//IL_0329: 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_0350: Unknown result type (might be due to invalid IL or missing references)
			//IL_0355: Unknown result type (might be due to invalid IL or missing references)
			//IL_0359: Unknown result type (might be due to invalid IL or missing references)
			//IL_0360: Unknown result type (might be due to invalid IL or missing references)
			//IL_036e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0375: Unknown result type (might be due to invalid IL or missing references)
			//IL_037c: 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_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_039c: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_040c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0412: Unknown result type (might be due to invalid IL or missing references)
			//IL_0419: Expected O, but got Unknown
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: 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_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
			List<Vector3> list = new List<Vector3>();
			List<Vector3> list2 = new List<Vector3>();
			List<Vector2> list3 = new List<Vector2>();
			List<Vector3> list4 = new List<Vector3>();
			List<Vector3> list5 = new List<Vector3>();
			List<Vector2> list6 = new List<Vector2>();
			List<int> list7 = new List<int>();
			CultureInfo culture = CultureInfo.InvariantCulture;
			string[] array = obj.Split(new char[2] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
			for (int i = 0; i < array.Length; i++)
			{
				string text = array[i].Trim();
				if (text.Length == 0 || text[0] == '#')
				{
					continue;
				}
				string[] array2 = text.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
				if (array2[0] == "v")
				{
					list.Add(new Vector3(float.Parse(array2[1], culture), float.Parse(array2[2], culture), float.Parse(array2[3], culture)));
				}
				else if (array2[0] == "vn")
				{
					Vector3 val = new Vector3(float.Parse(array2[1], culture), float.Parse(array2[2], culture), float.Parse(array2[3], culture));
					list2.Add(((Vector3)(ref val)).normalized);
				}
				else if (array2[0] == "vt")
				{
					list3.Add(new Vector2(float.Parse(array2[1], culture), float.Parse(array2[2], culture)));
				}
				else
				{
					if (!(array2[0] == "f"))
					{
						continue;
					}
					List<(Vector3, Vector2, Vector3)> list8 = new List<(Vector3, Vector2, Vector3)>();
					for (int j = 1; j < array2.Length; j++)
					{
						string[] array3 = array2[j].Split('/');
						Vector3 item = list[Index(array3[0], list.Count)];
						Vector2 item2 = ((array3.Length > 1 && array3[1].Length > 0) ? list3[Index(array3[1], list3.Count)] : Vector2.zero);
						Vector3 item3 = ((array3.Length > 2 && array3[2].Length > 0) ? list2[Index(array3[2], list2.Count)] : Vector3.up);
						list8.Add((item, item2, item3));
					}
					for (int k = 1; k + 1 < list8.Count; k++)
					{
						(Vector3, Vector2, Vector3)[] array4 = new(Vector3, Vector2, Vector3)[3]
						{
							list8[0],
							list8[k],
							list8[k + 1]
						};
						for (int l = 0; l < array4.Length; l++)
						{
							(Vector3, Vector2, Vector3) tuple = array4[l];
							list4.Add(tuple.Item1);
							list6.Add(tuple.Item2);
							list5.Add(tuple.Item3);
							list7.Add(list7.Count);
						}
					}
				}
			}
			Vector3 val2 = list.Aggregate((Vector3 a, Vector3 b) => Vector3.Min(a, b));
			Vector3 val3 = list.Aggregate((Vector3 a, Vector3 b) => Vector3.Max(a, b));
			Vector3 val4 = default(Vector3);
			((Vector3)(ref val4))..ctor((val2.x + val3.x) * 0.5f, val2.y, (val2.z + val3.z) * 0.5f);
			for (int num = 0; num < list4.Count; num++)
			{
				list4[num] = (list4[num] - val4) * 0.01f;
			}
			Mesh val5 = new Mesh
			{
				name = "Authored grounded herb",
				vertices = list4.ToArray(),
				normals = list5.ToArray(),
				uv = list6.ToArray(),
				triangles = list7.ToArray()
			};
			val5.RecalculateTangents();
			val5.RecalculateBounds();
			return val5;
			int Index(string value, int count)
			{
				int num2 = int.Parse(value, culture);
				if (num2 >= 0)
				{
					return num2 - 1;
				}
				return count + num2;
			}
		}
	}
	internal static class HerbBushRegistry
	{
		internal const string PrefabName = "HerbSmoking_HerbBush";

		private static Texture2D blackFoliage;

		private static Texture2D swampFoliage;

		private static Texture2D mistFoliage;

		internal static GameObject BushPrefab { get; private set; }

		internal static void Register()
		{
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Expected O, but got Unknown
			//IL_00c4: 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_00d4: Expected O, but got Unknown
			object obj = PrefabManager.Instance.GetPrefab("BlueberryBush");
			if (obj == null)
			{
				ZNetScene instance = ZNetScene.instance;
				obj = ((instance != null) ? instance.GetPrefab("BlueberryBush") : null);
			}
			GameObject val = (GameObject)obj;
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Log.LogError((object)"Missing vanilla BlueberryBush source prefab.");
				return;
			}
			BushPrefab = PrefabManager.Instance.CreateClonedPrefab("HerbSmoking_HerbBush", val);
			ApplyAuthoredFoliage(BushPrefab, "HerbSmoking_RawBlack");
			BudAssets.ReplaceBushBerries("HerbSmoking_RawBlack", BushPrefab);
			Pickable component = BushPrefab.GetComponent<Pickable>();
			BindHarvestVisual(BushPrefab);
			GameObject prefab = PrefabManager.Instance.GetPrefab("HerbSmoking_RawBlack");
			if ((Object)(object)component != (Object)null && (Object)(object)prefab != (Object)null)
			{
				component.m_itemPrefab = prefab;
				component.m_amount = 2;
				component.m_dontScale = true;
				component.m_pickRaiseSkill = (SkillType)0;
				component.m_extraDrops = new DropTable();
				component.m_overrideName = prefab.GetComponent<ItemDrop>().m_itemData.m_shared.m_name;
				component.m_respawnTimeMinutes = 360f;
			}
			PrefabManager.Instance.AddPrefab(new CustomPrefab(BushPrefab, false));
			Plugin.Log.LogInfo((object)"Registered authored herb bush from vanilla BlueberryBush; foliage diffuse is the only material override.");
		}

		internal static void ApplyAuthoredFoliage(GameObject prefab, string rawItemName)
		{
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Expected O, but got Unknown
			Texture2D texture = GetTexture(rawItemName);
			int num = 0;
			Renderer[] componentsInChildren = prefab.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				Material[] sharedMaterials = val.sharedMaterials;
				bool flag = false;
				for (int j = 0; j < sharedMaterials.Length; j++)
				{
					Material val2 = sharedMaterials[j];
					Texture val3 = (((Object)(object)val2 != (Object)null && val2.HasProperty("_MainTex")) ? val2.GetTexture("_MainTex") : null);
					if (!((Object)(object)val3 == (Object)null) && (string.Equals(((Object)val3).name, "Bush01_d", StringComparison.OrdinalIgnoreCase) || ((Object)val3).name.StartsWith("HerbFoliage_", StringComparison.OrdinalIgnoreCase)))
					{
						Material val4 = new Material(val2)
						{
							name = ((Object)val2).name + "_HerbFoliage"
						};
						val4.SetTexture("_MainTex", (Texture)(object)texture);
						sharedMaterials[j] = val4;
						num++;
						flag = true;
					}
				}
				if (flag)
				{
					val.sharedMaterials = sharedMaterials;
				}
			}
			if (num == 0)
			{
				Plugin.Log.LogWarning((object)("No Bush01_d material slots found on " + ((Object)prefab).name + "."));
				return;
			}
			Plugin.Log.LogInfo((object)$"Applied authored {((Texture)texture).width}x{((Texture)texture).height} HerbFoliage_d to {num} vanilla foliage material slots on {((Object)prefab).name}.");
		}

		private static Texture2D GetTexture(string rawItemName)
		{
			if (rawItemName.Contains("Swamp"))
			{
				return swampFoliage ?? (swampFoliage = LoadTexture("swamp"));
			}
			if (rawItemName.Contains("Mist"))
			{
				return mistFoliage ?? (mistFoliage = LoadTexture("mist"));
			}
			return blackFoliage ?? (blackFoliage = LoadTexture("black"));
		}

		private static Texture2D LoadTexture(string strain)
		{
			//IL_00ad: 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_0097: 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_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_0268: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0283: 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: Unknown result type (might be due to invalid IL or missing references)
			//IL_0299: Expected O, but got Unknown
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: 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)
			//IL_011d: 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)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = LoadSource("herb_foliage_" + strain + "_d.png", linear: false);
			Texture2D val2 = LoadSource("herb_foliage_a.png", linear: true);
			if (((Texture)val).width != ((Texture)val2).width || ((Texture)val).height != ((Texture)val2).height)
			{
				throw new InvalidDataException("Herb foliage diffuse and alpha dimensions differ.");
			}
			Color[] pixels = val.GetPixels();
			Color[] pixels2 = val2.GetPixels();
			Color val3 = ((strain == "swamp") ? new Color(0.72f, 0.48f, 0.82f) : ((strain == "mist") ? new Color(0.68f, 0.94f, 1f) : new Color(0.76f, 0.78f, 0.48f)));
			float num = default(float);
			float num2 = default(float);
			float num3 = default(float);
			for (int i = 0; i < pixels.Length; i++)
			{
				Color val4 = pixels[i];
				val4.a = (pixels2[i].r + pixels2[i].g + pixels2[i].b) / 3f;
				if (strain == "black" && val4.a > 0.1f)
				{
					Color.RGBToHSV(val4, ref num, ref num2, ref num3);
					num = Mathf.LerpAngle(num * 360f, 103f, 0.28f) / 360f;
					num2 *= 0.78f;
					num3 = Mathf.Clamp01(num3 * 1.13f + 0.025f);
					val4 = Color.HSVToRGB(num, num2, num3);
					val4.a = (pixels2[i].r + pixels2[i].g + pixels2[i].b) / 3f;
				}
				float num4 = Mathf.Max(val4.r, Mathf.Max(val4.g, val4.b));
				if (val4.a > 0.35f && num4 > 0.52f)
				{
					val4 = Color.Lerp(val4, new Color(val3.r, val3.g, val3.b, val4.a), Mathf.InverseLerp(0.52f, 0.9f, num4) * 0.22f);
				}
				pixels[i] = val4;
			}
			Texture2D val5 = new Texture2D(((Texture)val).width, ((Texture)val).height, (TextureFormat)4, true, false)
			{
				name = "HerbFoliage_" + strain + "_d"
			};
			val5.SetPixels(pixels);
			val5.Apply(true, false);
			Object.DestroyImmediate((Object)(object)val);
			Object.DestroyImmediate((Object)(object)val2);
			((Texture)val5).wrapMode = (TextureWrapMode)0;
			((Texture)val5).filterMode = (FilterMode)0;
			((Texture)val5).anisoLevel = 1;
			return val5;
		}

		internal static void EnhanceBushEffects(GameObject wild, string rawItemName, bool enlargeWildBush)
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: 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_0199: 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_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			Plugin.Log.LogInfo((object)("Creating discovery motes for " + ((Object)wild).name + " (" + rawItemName + ")."));
			if (enlargeWildBush)
			{
				Transform transform = wild.transform;
				transform.localScale *= 1.12f;
			}
			GameObject harvestVisual = FindHarvestVisual(wild);
			if ((Object)(object)harvestVisual != (Object)null)
			{
				Transform[] array = (from transform2 in harvestVisual.GetComponentsInChildren<Transform>(true)
					where (Object)(object)transform2 != (Object)(object)harvestVisual.transform && (((Object)transform2).name == "HerbDiscoveryMotes" || ((Object)transform2).name == "BudLocalMotes")
					orderby HierarchyDepth(transform2) descending
					select transform2).ToArray();
				foreach (Transform val in array)
				{
					if (Object.op_Implicit((Object)(object)val))
					{
						Object.DestroyImmediate((Object)(object)((Component)val).gameObject);
					}
				}
			}
			Color val2 = HerbMoteCloud.ColorFor(rawItemName);
			int num2 = 0;
			if ((Object)(object)harvestVisual != (Object)null)
			{
				MeshFilter[] array2 = BudAssets.FindBushBudMeshes(wild);
				foreach (MeshFilter val3 in array2)
				{
					Bounds bounds = val3.sharedMesh.bounds;
					GameObject val4 = new GameObject("BudLocalMotes");
					val4.transform.SetParent(((Component)val3).transform, false);
					val4.transform.localPosition = ((Bounds)(ref bounds)).center;
					val4.AddComponent<HerbMoteCloud>().Configure(rawItemName);
					num2++;
				}
			}
			Plugin.Log.LogInfo((object)$"Discovery motes ready for {((Object)wild).name}: animated transform cloud, color={val2}, lifetime=5.3125-8.125s, global count=0, particles per bud=6.25 average, local bud emitters={num2}.");
		}

		private static int HierarchyDepth(Transform transform)
		{
			int num = 0;
			while ((Object)(object)transform.parent != (Object)null)
			{
				num++;
				transform = transform.parent;
			}
			return num;
		}

		internal static void BindHarvestVisual(GameObject prefab)
		{
			Pickable component = prefab.GetComponent<Pickable>();
			GameObject val = FindHarvestVisual(prefab);
			if ((Object)(object)component != (Object)null && (Object)(object)val != (Object)null)
			{
				component.m_hideWhenPicked = val;
			}
			else
			{
				Plugin.Log.LogWarning((object)("Could not bind the harvest visual on " + ((Object)prefab).name + "."));
			}
		}

		private static GameObject? FindHarvestVisual(GameObject prefab)
		{
			Transform? obj = ((IEnumerable<Transform>)prefab.GetComponentsInChildren<Transform>(true)).FirstOrDefault((Func<Transform, bool>)((Transform transform) => string.Equals(((Object)transform).name, "Berrys", StringComparison.OrdinalIgnoreCase)));
			if (obj == null)
			{
				return null;
			}
			return ((Component)obj).gameObject;
		}

		private static Texture2D LoadSource(string name, bool linear)
		{
			//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_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Expected O, but got Unknown
			//IL_0074: Expected O, but got Unknown
			using Stream stream = typeof(Plugin).Assembly.GetManifestResourceStream("HerbAssets." + name) ?? throw new InvalidOperationException("Missing herb foliage resource " + name);
			using MemoryStream memoryStream = new MemoryStream();
			stream.CopyTo(memoryStream);
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false, linear)
			{
				name = name
			};
			if (!ImageConversion.LoadImage(val, memoryStream.ToArray(), false))
			{
				throw new InvalidDataException("Invalid herb foliage resource " + name);
			}
			return val;
		}
	}
	internal sealed class HerbMoteCloud : MonoBehaviour
	{
		private sealed class Mote
		{
			internal Transform Node;

			internal Vector3 Position;

			internal Vector3 Velocity;

			internal float Age;

			internal float Life;

			internal float Size;

			internal float Phase;

			internal float Duty = 1f;
		}

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

		private static Mesh? sharedMoteMesh;

		[SerializeField]
		private Color configuredColor;

		private const float MinimumRadius = 0.015f;

		private Mote[] motes = Array.Empty<Mote>();

		private Material material;

		private Color baseColor;

		private Color brightColor;

		private Random random;

		private float radiusMin;

		private float radiusMax;

		private float sizeMin;

		private float sizeMax;

		private Vector3 localAnchor;

		private bool configured;

		internal static Color ColorFor(string itemName)
		{
			//IL_0062: 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_002e: Unknown result type (might be due to invalid IL or missing references)
			if (!itemName.Contains("Swamp"))
			{
				if (!itemName.Contains("Mist"))
				{
					return new Color(0.32f, 1f, 0.16f, 1f);
				}
				return new Color(0.2f, 0.88f, 1f, 1f);
			}
			return new Color(0.78f, 0.25f, 1f, 1f);
		}

		internal void Configure(string itemName)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			configuredColor = ColorFor(itemName);
			localAnchor = ((Component)this).transform.localPosition;
			InitializeRuntime();
		}

		private void Awake()
		{
			if (configuredColor.a > 0f && !configured)
			{
				InitializeRuntime();
			}
		}

		private void InitializeRuntime()
		{
			//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_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: 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_0045: 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_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Expected O, but got Unknown
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			Color val = configuredColor;
			int num = Mathf.Max(1, Plugin.Settings.BudParticleCount.Value);
			baseColor = val;
			baseColor.a = 0.6f;
			brightColor = Color.Lerp(val, Color.white, 0.48f);
			brightColor.a = 0.78f;
			radiusMin = 0.015f;
			radiusMax = Mathf.Max(0.015f, Plugin.Settings.BudParticleRadius.Value);
			sizeMin = Mathf.Max(0.0001f, Plugin.Settings.BudParticleMinimumSize.Value);
			sizeMax = Mathf.Max(sizeMin, Plugin.Settings.BudParticleMaximumSize.Value);
			random = new Random(9137);
			if (Object.op_Implicit((Object)(object)material))
			{
				Object.Destroy((Object)(object)material);
			}
			material = new Material(GetRuntimeMaterial(val));
			Mesh sharedMesh = (Object.op_Implicit((Object)(object)sharedMoteMesh) ? sharedMoteMesh : (sharedMoteMesh = CreateMoteMesh()));
			motes = new Mote[num];
			for (int i = 0; i < motes.Length; i++)
			{
				string text = $"Mote_{i:00}";
				Transform val2 = ((Component)this).transform.Find(text);
				GameObject val3 = (GameObject)(((Object)(object)val2 != (Object)null) ? ((object)((Component)val2).gameObject) : ((object)new GameObject(text)));
				if ((Object)(object)val2 == (Object)null)
				{
					val3.transform.SetParent(((Component)this).transform, false);
				}
				(val3.GetComponent<MeshFilter>() ?? val3.AddComponent<MeshFilter>()).sharedMesh = sharedMesh;
				MeshRenderer obj = val3.GetComponent<MeshRenderer>() ?? val3.AddComponent<MeshRenderer>();
				((Renderer)obj).sharedMaterial = material;
				((Renderer)obj).enabled = true;
				val3.SetActive(true);
				((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0;
				((Renderer)obj).receiveShadows = false;
				Mote mote = new Mote
				{
					Node = val3.transform,
					Duty = 1f
				};
				motes[i] = mote;
				ResetMote(mote, initial: true);
				ApplyMoteTransform(mote, Time.time);
			}
			configured = true;
		}

		private void OnDestroy()
		{
			if (Object.op_Implicit((Object)(object)material))
			{
				Object.Destroy((Object)(object)material);
			}
		}

		private static Mesh CreateMoteMesh()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: 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_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: 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_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: 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_00a3: 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_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: 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_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			Mesh val = new Mesh
			{
				name = "Herb discovery mote"
			};
			val.vertices = (Vector3[])(object)new Vector3[6]
			{
				Vector3.right,
				Vector3.left,
				Vector3.up,
				Vector3.down,
				Vector3.forward,
				Vector3.back
			};
			val.normals = (Vector3[])(object)new Vector3[6]
			{
				Vector3.right,
				Vector3.left,
				Vector3.up,
				Vector3.down,
				Vector3.forward,
				Vector3.back
			};
			val.triangles = new int[24]
			{
				2, 0, 4, 2, 4, 1, 2, 1, 5, 2,
				5, 0, 3, 4, 0, 3, 1, 4, 3, 5,
				1, 3, 0, 5
			};
			val.colors = (Color[])(object)new Color[6]
			{
				Color.white,
				Color.white,
				Color.white,
				Color.white,
				Color.white,
				Color.white
			};
			val.RecalculateBounds();
			return val;
		}

		private void ResetMote(Mote mote, bool initial)
		{
			//IL_0048: 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_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: 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_00a5: 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_00d0: 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_00da: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = new Vector3((float)random.NextDouble() * 2f - 1f, (float)random.NextDouble() * 2f - 1f, (float)random.NextDouble() * 2f - 1f);
			Vector3 normalized = ((Vector3)(ref val)).normalized;
			normalized.y = Mathf.Abs(normalized.y) * 0.65f - 0.15f;
			((Vector3)(ref normalized)).Normalize();
			mote.Position = normalized * Mathf.Lerp(radiusMin, radiusMax, (float)random.NextDouble());
			mote.Velocity = normalized * Mathf.Lerp(0.055f, 0.11f, (float)random.NextDouble()) + Vector3.up * 0.022f;
			mote.Life = Mathf.Lerp(5.3125f, 8.125f, (float)random.NextDouble());
			mote.Age = (initial ? ((float)random.NextDouble() * mote.Life / mote.Duty) : 0f);
			mote.Size = Mathf.Lerp(sizeMin, sizeMax, (float)random.NextDouble());
			mote.Phase = (float)random.NextDouble() * MathF.PI * 2f;
		}

		private void Update()
		{
			//IL_0029: 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_003b: 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_0073: 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_0282: Unknown result type (might be due to invalid IL or missing references)
			//IL_0288: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: Unknown result type (might be due to invalid IL or missing references)
			//IL_0299: 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_00c4: 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_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ce: 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_00e7: 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_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0304: 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_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: 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_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			if (!configured)
			{
				return;
			}
			if (Object.op_Implicit((Object)(object)((Component)this).transform.parent))
			{
				Vector3 lossyScale = ((Component)this).transform.parent.lossyScale;
				((Component)this).transform.localScale = new Vector3(1f / Mathf.Max(Mathf.Abs(lossyScale.x), 0.0001f), 1f / Mathf.Max(Mathf.Abs(lossyScale.y), 0.0001f), 1f / Mathf.Max(Mathf.Abs(lossyScale.z), 0.0001f));
				Camera val = (Object.op_Implicit((Object)(object)GameCamera.instance) ? ((Component)GameCamera.instance).GetComponent<Camera>() : Camera.main);
				Vector3 val2 = ((Component)this).transform.parent.TransformPoint(localAnchor);
				((Component)this).transform.position = (Object.op_Implicit((Object)(object)val) ? (val2 - ((Component)val).transform.forward * Plugin.Settings.BudParticleCameraOffset.Value) : val2);
			}
			float time = Time.time;
			float deltaTime = Time.deltaTime;
			float num = 0f;
			Mote[] array = motes;
			foreach (Mote mote in array)
			{
				mote.Age += deltaTime;
				if (mote.Age >= mote.Life / mote.Duty)
				{
					ResetMote(mote, initial: false);
				}
				float num2 = time * 0.72f + mote.Phase;
				Vector3 val3 = new Vector3(Mathf.Sin(num2 * 1.13f), 0.25f + Mathf.Sin(num2 * 0.67f + 1.4f) * 0.2f, Mathf.Cos(num2 * 0.91f + 0.6f)) * 0.018f;
				Vector3 val4 = ((((Vector3)(ref mote.Position)).sqrMagnitude > 0.001f) ? (((Vector3)(ref mote.Position)).normalized * 0.045f) : (Vector3.up * 0.045f)) + val3 * 4.5f + Vector3.up * 0.018f;
				mote.Velocity = Vector3.Lerp(mote.Velocity, val4, deltaTime * 0.72f);
				mote.Position += mote.Velocity * deltaTime;
				num = Mathf.Max(num, ApplyMoteTransform(mote, time));
			}
			Color val5 = Color.Lerp(baseColor, brightColor, num * 0.32f);
			val5.a = Mathf.Lerp(0.5f, 0.76f, num);
			if (material.HasProperty("_Color"))
			{
				material.SetColor("_Color", val5);
			}
			if (material.HasProperty("_EmissionColor"))
			{
				material.SetColor("_EmissionColor", Color.Lerp(baseColor, brightColor, num * 0.5f) * Mathf.Lerp(1.8f, 3.2f, num));
			}
		}

		private float ApplyMoteTransform(Mote mote, float time)
		{
			//IL_0097: 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_00ad: Unknown result type (might be due to invalid IL or missing references)
			float num = mote.Age / mote.Life;
			float num2 = Mathf.SmoothStep(0f, 1f, Mathf.Clamp01(num / 0.12f)) * Mathf.SmoothStep(0f, 1f, Mathf.Clamp01((1f - num) / 0.22f));
			float num3 = Mathf.Pow(0.5f + 0.5f * Mathf.Sin(time * 2.1f + mote.Phase), 3.2f);
			float num4 = mote.Size * num2 * Mathf.Lerp(0.82f, 1.22f, num3);
			mote.Node.localPosition = mote.Position;
			mote.Node.localScale = Vector3.one * num4;
			return num3;
		}

		private static Material GetRuntimeMaterial(Color color)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: 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_0079: Expected O, but got Unknown
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: 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_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: 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_013c: 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)
			int stableHashCode = StringExtensionMethods.GetStableHashCode(ColorUtility.ToHtmlStringRGB(color));
			if (Materials.TryGetValue(stableHashCode, out Material value) && Object.op_Implicit((Object)(object)value))
			{
				return value;
			}
			Shader val = Shader.Find("Sprites/Default") ?? Shader.Find("Unlit/Color");
			if (!Object.op_Implicit((Object)(object)val))
			{
				throw new InvalidOperationException("No unlit shader available for herb motes.");
			}
			Material val2 = new Material(val)
			{
				name = "Herb bud motes " + ColorUtility.ToHtmlStringRGB(color),
				renderQueue = 3000
			};
			if (val2.HasProperty("_RendererColor"))
			{
				val2.SetColor("_RendererColor", Color.white);
			}
			Plugin.Log.LogInfo((object)$"Herb motes use consistent shader '{((Object)val).name}' for {color}.");
			if (val2.HasProperty("_MainTex"))
			{
				val2.SetTexture("_MainTex", (Texture)(object)Texture2D.whiteTexture);
			}
			if (val2.HasProperty("_Color"))
			{
				val2.SetColor("_Color", new Color(color.r, color.g, color.b, 0.6f));
			}
			if (val2.HasProperty("_EmissionColor"))
			{
				val2.EnableKeyword("_EMISSION");
				val2.SetColor("_EmissionColor", new Color(color.r, color.g, color.b, 1f) * 2.2f);
			}
			if (val2.HasProperty("_SrcBlend"))
			{
				val2.SetInt("_SrcBlend", 1);
			}
			if (val2.HasProperty("_DstBlend"))
			{
				val2.SetInt("_DstBlend", 10);
			}
			if (val2.HasProperty("_ZWrite"))
			{
				val2.SetInt("_ZWrite", 0);
			}
			val2.DisableKeyword("_ALPHATEST_ON");
			val2.EnableKeyword("_ALPHABLEND_ON");
			Materials[stableHashCode] = val2;
			return val2;
		}
	}
	internal sealed class HerbMoteFlicker : MonoBehaviour
	{
		private ParticleSystem particles;

		private Particle[] buffer = (Particle[])(object)new Particle[32];

		private Color baseColor = new Color(0.32f, 1f, 0.16f, 1f);

		private Color brightColor = new Color(0.72f, 1f, 0.58f, 1f);

		internal void Configure(Color color)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			baseColor = color;
			brightColor = Color.Lerp(color, Color.white, 0.48f);
			baseColor.a = (brightColor.a = 1f);
		}

		private void Awake()
		{
			particles = ((Component)this).GetComponent<ParticleSystem>();
		}

		private void LateUpdate()
		{
			//IL_005d: 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_013b: 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_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)particles == (Object)null))
			{
				int particleCount = particles.particleCount;
				if (particleCount > buffer.Length)
				{
					buffer = (Particle[])(object)new Particle[Mathf.NextPowerOfTwo(particleCount)];
				}
				particleCount = particles.GetParticles(buffer);
				float time = Time.time;
				for (int i = 0; i < particleCount; i++)
				{
					Particle val = buffer[i];
					float num = (float)(((Particle)(ref val)).randomSeed % 1009) * 0.037f;
					float num2 = 0.5f + 0.5f * Mathf.Sin(time * 2.1f + num);
					float num3 = 0.5f + 0.5f * Mathf.Sin(time * 4.7f + num * 1.83f);
					float num4 = Mathf.Pow(Mathf.Clamp01(num2 * 0.72f + num3 * 0.28f), 3.1f);
					float num5 = 1f - ((Particle)(ref val)).remainingLifetime / Mathf.Max(0.001f, ((Particle)(ref val)).startLifetime);
					float num6 = Mathf.SmoothStep(0f, 1f, Mathf.Clamp01(num5 / 0.12f)) * Mathf.SmoothStep(0f, 1f, Mathf.Clamp01((1f - num5) / 0.22f));
					Color val2 = Color.Lerp(baseColor, brightColor, num4 * 0.42f);
					val2.a = Mathf.Lerp(0.5f, 0.74f, num4) * num6;
					((Particle)(ref val)).startColor = Color32.op_Implicit(val2);
					float num7 = time * 0.72f + num;
					Vector3 val3 = new Vector3(Mathf.Sin(num7 * 1.13f), 0.28f + Mathf.Sin(num7 * 0.67f + 1.4f) * 0.22f, Mathf.Cos(num7 * 0.91f + 0.6f)) * 0.022f;
					((Particle)(ref val)).velocity = Vector3.Lerp(((Particle)(ref val)).velocity, val3, Time.deltaTime * 0.72f);
					buffer[i] = val;
				}
				particles.SetParticles(buffer, particleCount);
			}
		}
	}
	internal static class IconStyling
	{
		internal static Sprite AddSoftShadow(Sprite source, int offset = 8, int radius = 3)
		{
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: 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_0216: Expected O, but got Unknown
			//IL_00ce: Unknown re