Decompiled source of WildGlow v0.4.12

BepInEx/plugins/WildGlow/WildGlow.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("WildGlow")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.4.12.0")]
[assembly: AssemblyInformationalVersion("0.4.12+f2b5afdfed0215b70a62f72702dcad71c2178ff7")]
[assembly: AssemblyProduct("WildGlow")]
[assembly: AssemblyTitle("WildGlow")]
[assembly: AssemblyVersion("0.4.12.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace WildGlow
{
	internal static class Clusterer
	{
		internal struct Point
		{
			internal int Id;

			internal float X;

			internal float Y;

			internal float Z;
		}

		internal static List<List<int>> Build(IReadOnlyList<Point> points, float diameter)
		{
			List<List<int>> list = new List<List<int>>();
			float num = diameter * diameter;
			foreach (int item in from i in Enumerable.Range(0, points.Count)
				orderby points[i].Id
				select i)
			{
				List<int> list2 = null;
				float num2 = float.MaxValue;
				if (diameter > 0f)
				{
					foreach (List<int> item2 in list)
					{
						float num3 = 0f;
						foreach (int item3 in item2)
						{
							float num4 = points[item].X - points[item3].X;
							float num5 = points[item].Y - points[item3].Y;
							float num6 = points[item].Z - points[item3].Z;
							num3 = Math.Max(num3, num4 * num4 + num5 * num5 + num6 * num6);
							if (num3 > num)
							{
								break;
							}
						}
						if (num3 <= num && num3 < num2)
						{
							list2 = item2;
							num2 = num3;
						}
					}
				}
				if (list2 == null)
				{
					list2 = new List<int>();
					list.Add(list2);
				}
				list2.Add(item);
			}
			return list;
		}
	}
	internal static class CoverageLayout
	{
		internal static MoteMotion.Point Barycentric(float u, float v)
		{
			float num = (float)Math.Sqrt(Math.Max(0f, Math.Min(1f, u)));
			return new MoteMotion.Point(1f - num, num * (1f - v), num * v);
		}

		internal static float Distance2(MoteMotion.Point a, MoteMotion.Point b)
		{
			return (a.X - b.X) * (a.X - b.X) + (a.Y - b.Y) * (a.Y - b.Y) + (a.Z - b.Z) * (a.Z - b.Z);
		}

		internal static int[] Select(IReadOnlyList<MoteMotion.Point> points, int budget, float spacing)
		{
			List<int> list = new List<int>();
			if (points.Count == 0 || budget <= 0)
			{
				return list.ToArray();
			}
			MoteMotion.Point b = default(MoteMotion.Point);
			foreach (MoteMotion.Point point in points)
			{
				b.X += point.X / (float)points.Count;
				b.Y += point.Y / (float)points.Count;
				b.Z += point.Z / (float)points.Count;
			}
			int item = 0;
			float num = float.MaxValue;
			for (int i = 0; i < points.Count; i++)
			{
				float num2 = Distance2(points[i], b);
				if (num2 < num)
				{
					num = num2;
					item = i;
				}
			}
			list.Add(item);
			while (list.Count < budget && list.Count < points.Count)
			{
				int num3 = -1;
				float num4 = spacing * spacing;
				for (int j = 0; j < points.Count; j++)
				{
					if (list.Contains(j))
					{
						continue;
					}
					float num5 = float.MaxValue;
					foreach (int item2 in list)
					{
						num5 = Math.Min(num5, Distance2(points[j], points[item2]));
					}
					if (num5 > num4)
					{
						num4 = num5;
						num3 = j;
					}
				}
				if (num3 < 0)
				{
					break;
				}
				list.Add(num3);
			}
			return list.ToArray();
		}

		internal static float CoverRadius(IReadOnlyList<MoteMotion.Point> points, int[] selected, int count)
		{
			count = Math.Min(count, selected.Length);
			if (count <= 0)
			{
				return 0f;
			}
			float num = 0f;
			foreach (MoteMotion.Point point in points)
			{
				float num2 = float.MaxValue;
				for (int i = 0; i < count; i++)
				{
					num2 = Math.Min(num2, Distance2(point, points[selected[i]]));
				}
				num = Math.Max(num, num2);
			}
			return (float)Math.Sqrt(num);
		}

		internal static int[] Allocate(int[] requested, int budget)
		{
			int[] array = new int[requested.Length];
			for (int i = 0; i < 4; i++)
			{
				if (budget <= 0)
				{
					break;
				}
				for (int j = 0; j < requested.Length; j++)
				{
					if (budget <= 0)
					{
						break;
					}
					if (array[j] < requested[j])
					{
						array[j]++;
						budget--;
					}
				}
			}
			return array;
		}
	}
	internal enum EffectFamily
	{
		Plant,
		Spore,
		Berry,
		Mineral,
		Obsidian,
		Hive,
		Chest,
		Treasure,
		Magic,
		Drift
	}
	internal static class EffectBehavior
	{
		internal static EffectFamily Family(string id)
		{
			switch (id)
			{
			case "blackcore":
			case "frostcore":
			case "moltencore":
			case "dyrnwyn":
				return EffectFamily.Magic;
			case "dragonegg":
			case "crystal":
			case "amber":
			case "ruby":
				return EffectFamily.Treasure;
			case "honey":
				return EffectFamily.Hive;
			case "chest":
				return EffectFamily.Chest;
			case "obsidian":
				return EffectFamily.Obsidian;
			case "meteorite":
			case "blackmetal":
			case "iron":
			case "gold":
			case "flametal":
			case "grausten":
			case "copper":
			case "silver":
			case "chitin":
			case "sulfur":
			case "tin":
			case "blackmarble":
				return EffectFamily.Mineral;
			case "smokepuff":
			case "jotunpuffs":
			case "magecap":
			case "mushroom":
			case "mushroomyellow":
			case "mushroomblue":
				return EffectFamily.Spore;
			case "dandelion":
			case "fiddlehead":
			case "poteitr":
			case "thistle":
			case "onion":
			case "flax":
			case "kale":
			case "seed":
			case "carrot":
			case "turnip":
			case "barley":
			case "oat":
				return EffectFamily.Plant;
			default:
				if (!id.Contains("berry"))
				{
					return EffectFamily.Drift;
				}
				return EffectFamily.Berry;
			}
		}

		internal static bool Geological(EffectFamily f)
		{
			if (f != EffectFamily.Mineral)
			{
				return f == EffectFamily.Obsidian;
			}
			return true;
		}

		internal static float Night(float dayFraction)
		{
			float num = Math.Min(Clamp((dayFraction - 0.2f) / 0.1f), Clamp((0.8f - dayFraction) / 0.1f));
			return 1f - num * num * (3f - 2f * num);
		}

		internal static float Clamp(float x)
		{
			return Math.Max(0f, Math.Min(1f, x));
		}

		private static float Sin(float x)
		{
			return (float)Math.Sin(x);
		}

		private static float Cos(float x)
		{
			return (float)Math.Cos(x);
		}

		internal static float Reach(EffectFamily f)
		{
			switch (f)
			{
			default:
				if (!Geological(f))
				{
					return f switch
					{
						EffectFamily.Chest => 0.26f, 
						EffectFamily.Hive => 0.22f, 
						_ => 0.25f, 
					};
				}
				return 0.13f;
			case EffectFamily.Berry:
				return 0.15f;
			case EffectFamily.Spore:
				return 1f;
			case EffectFamily.Plant:
				return 0.38f;
			case EffectFamily.Treasure:
				return 0.65f;
			case EffectFamily.Magic:
				return 1f;
			}
		}

		internal static MoteMotion.Point Position(EffectFamily f, float p, float t, int key, float r, float h, float twist, float night)
		{
			float num = MoteMotion.Hash(key + 43) * 6.283185f;
			float num2 = num + t * (0.16f + night * 0.07f) * twist;
			float num3 = h * Reach(f);
			switch (f)
			{
			case EffectFamily.Plant:
				return new MoteMotion.Point(Cos(num) * r * 0.45f + Sin(t * 0.6f + num) * r * 0.22f * twist * p, 0.025f + p * num3, Sin(num) * r * 0.45f + Cos(t * 0.4f + num) * r * 0.18f * twist * p);
			case EffectFamily.Spore:
			{
				float num4 = r * (0.18f + 0.65f * (1f - p)) * (1f + night * 0.1f);
				return new MoteMotion.Point(Cos(num2) * num4, 0.05f + p * num3, Sin(num2) * num4);
			}
			case EffectFamily.Berry:
				return new MoteMotion.Point(Cos(num) * r * 0.8f + Sin(num2 * 2f) * r * 0.06f * twist, 0.02f + MoteMotion.Hash(key + 8) * num3 * 0.6f + p * num3 * 0.3f, Sin(num) * r * 0.8f);
			case EffectFamily.Mineral:
				return new MoteMotion.Point(Sin(t * 0.25f + num) * 0.035f * twist * p, 0.012f + p * num3, Cos(num) * 0.035f * p);
			case EffectFamily.Obsidian:
				return new MoteMotion.Point(Sin(num2 * 1.5f) * 0.08f * twist * p, 0.012f + p * num3, Cos(num2) * 0.06f * twist * p);
			case EffectFamily.Hive:
				return new MoteMotion.Point(Cos(num2 + p * 6.28f * twist) * r * (0.65f + 0.2f * Sin(num)), 0.04f + num3 * (0.3f + 0.24f * Sin(num2 * 2f + num)), Sin(num2 + p * 6.28f * twist) * r * 0.65f);
			case EffectFamily.Chest:
			{
				float num5 = MoteMotion.Hash(key + 2) * 2f - 1f;
				return new MoteMotion.Point((key % 2 == 0) ? (num5 * r) : ((key % 4 == 1) ? r : (0f - r)), 0.015f + p * num3, (key % 2 != 0) ? (num5 * r * 0.6f) : (((key % 4 == 0) ? r : (0f - r)) * 0.6f));
			}
			case EffectFamily.Treasure:
				return new MoteMotion.Point(Cos(num2 + p * 3f * twist) * r * (0.3f + 0.4f * Sin(p * 3.14f)), 0.04f + p * num3, Sin(num2 + p * 3f * twist) * r * 0.6f);
			case EffectFamily.Magic:
				if (key % 3 == 0)
				{
					return new MoteMotion.Point(Cos(num2 * 2f) * r * 0.8f, num3 * (0.18f + 0.05f * Sin(num2 * 2f + num)), Sin(num2 * 2f) * r * 0.8f);
				}
				return MoteMotion.Position(p, t, key, r, h, twist);
			default:
				return new MoteMotion.Point(Cos(num2) * r * 0.55f, 0.03f + p * num3, Sin(num2) * r * 0.55f);
			}
		}

		internal static float Alpha(EffectFamily f, float p, float t, int key, float night)
		{
			float num = Clamp(p / 0.12f) * Clamp((1f - p) / 0.2f);
			if (f == EffectFamily.Berry)
			{
				num *= (float)Math.Pow(Math.Max(0f, Sin(t * 1.1f + (float)(key / 4))), 4.0);
			}
			if (f == EffectFamily.Spore)
			{
				num *= 0.5f + 0.5f * Sin(p * 3.14159f);
			}
			if (f == EffectFamily.Magic || f == EffectFamily.Treasure)
			{
				num *= 0.72f + 0.28f * Sin(t * 0.9f + (float)(key / 8));
			}
			return num;
		}

		internal static MoteMotion.Point Path(EffectFamily f, bool column, MoteMotion.Point anchor, float p, float t, int key, float r, float h, float twist, float night)
		{
			MoteMotion.Point point = (column ? MoteMotion.Position(p, t, key, r, h, twist) : Position(f, p, t, key, r, h, twist, night));
			float num = ((column || f == EffectFamily.Spore) ? ((1f - p) * (1f - p)) : 1f);
			return new MoteMotion.Point(point.X + anchor.X * num, point.Y + anchor.Y * num, point.Z + anchor.Z * num);
		}

		internal static MoteMotion.Point TrailPoint(EffectFamily f, bool column, MoteMotion.Point anchor, float p, float t, int key, float r, float h, float speed, float twist, float length, float fraction, float night)
		{
			MoteMotion.Point point = Path(f, column, anchor, p, t, key, r, h, twist, night);
			float num = Math.Min(0.28f * length, p * 6.5f / Math.Max(0.01f, speed)) * fraction;
			MoteMotion.Point point2 = Path(f, column, anchor, Math.Max(0f, p - num * speed / 6.5f), t - num, key, r, h, twist, night);
			float num2 = point2.X - point.X;
			float num3 = point2.Y - point.Y;
			float num4 = point2.Z - point.Z;
			float num5 = (float)Math.Sqrt(num2 * num2 + num3 * num3 + num4 * num4);
			float num6 = 0.22f * length;
			float num7 = ((num5 > num6 && num5 > 0f) ? (num6 / num5) : 1f);
			return new MoteMotion.Point(point.X + num2 * num7, point.Y + num3 * num7, point.Z + num4 * num7);
		}
	}
	internal static class FruitSurface
	{
		private static readonly Vector3[] Tops = (Vector3[])(object)new Vector3[9]
		{
			new Vector3(-0.2694197f, 1.9088567f, 0.3961818f),
			new Vector3(-0.2231439f, 2.4969592f, 0.2076921f),
			new Vector3(0.199457f, 2.813951f, -0.1562577f),
			new Vector3(0.230083f, 2.265424f, -0.0358363f),
			new Vector3(0.1607674f, 1.6506805f, -0.3321521f),
			new Vector3(-0.1815086f, 1.5798448f, -0.2563672f),
			new Vector3(-0.1948867f, 1.688204f, 0.2664113f),
			new Vector3(0.4171014f, 1.824248f, -0.1024285f),
			new Vector3(-0.1076642f, 2.0107777f, -0.0973235f)
		};

		internal static bool IsTree(string name)
		{
			if (!string.Equals(name, "apple_tree", StringComparison.OrdinalIgnoreCase))
			{
				return string.Equals(name, "apple_tree_1", StringComparison.OrdinalIgnoreCase);
			}
			return true;
		}

		internal static bool Prepare(GameObject fruit, List<SurfaceAnchor> anchors, out Bounds bounds)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: 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_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: 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_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: 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)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: 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_0179: Unknown result type (might be due to invalid IL or missing references)
			anchors.Clear();
			bounds = default(Bounds);
			if (!Object.op_Implicit((Object)(object)fruit) || !fruit.activeInHierarchy)
			{
				return false;
			}
			MeshFilter[] componentsInChildren = fruit.GetComponentsInChildren<MeshFilter>(false);
			foreach (MeshFilter val in componentsInChildren)
			{
				Mesh sharedMesh = val.sharedMesh;
				MeshRenderer component = ((Component)val).GetComponent<MeshRenderer>();
				if (!Object.op_Implicit((Object)(object)sharedMesh) || !Object.op_Implicit((Object)(object)component) || !((Renderer)component).enabled || ((Renderer)component).forceRenderingOff || ((Object)sharedMesh).name != "apple" || sharedMesh.vertexCount != 1792)
				{
					continue;
				}
				Bounds bounds2 = sharedMesh.bounds;
				Vector3 val2 = ((Bounds)(ref bounds2)).center - new Vector3(0.07420105f, 2.1038973f, 0.02755487f);
				if (((Vector3)(ref val2)).sqrMagnitude > 1E-06f)
				{
					continue;
				}
				bounds2 = sharedMesh.bounds;
				val2 = ((Bounds)(ref bounds2)).extents - new Vector3(0.41979003f, 0.7100536f, 0.4192455f);
				if (!(((Vector3)(ref val2)).sqrMagnitude > 1E-06f))
				{
					if (anchors.Count == 0)
					{
						bounds = ((Renderer)component).bounds;
					}
					else
					{
						((Bounds)(ref bounds)).Encapsulate(((Renderer)component).bounds);
					}
					Vector3[] tops = Tops;
					foreach (Vector3 val3 in tops)
					{
						SurfaceAnchor item = SurfaceAnchor.At(((Component)val).transform, ((Component)val).transform.TransformPoint(val3 + Vector3.up * 0.01f), null, ((Component)val).transform.TransformDirection(Vector3.up));
						item.Renderer = (Renderer)(object)component;
						item.RequiresRenderer = true;
						anchors.Add(item);
					}
				}
			}
			return anchors.Count > 0;
		}
	}
	internal static class LightingProfile
	{
		internal static float GlowScale(string id)
		{
			if (!id.StartsWith("mushroom", StringComparison.Ordinal))
			{
				switch (id)
				{
				case "jotunpuffs":
				case "magecap":
				case "smokepuff":
					break;
				default:
					if (id.EndsWith("berry", StringComparison.Ordinal))
					{
						return 0.065f;
					}
					if (EffectBehavior.Geological(EffectBehavior.Family(id)))
					{
						return 0.085f;
					}
					return 0.15f;
				}
			}
			return 1.25f;
		}

		internal static bool ExcludedSource(string name)
		{
			if (!name.Equals("Spawner_GreydwarfNest", StringComparison.OrdinalIgnoreCase))
			{
				return name.StartsWith("Spawner_GreydwarfNest_", StringComparison.OrdinalIgnoreCase);
			}
			return true;
		}
	}
	internal sealed class ModelEmission : IDisposable
	{
		private sealed class Glow
		{
			internal Material Material;

			internal string ColorProperty;

			internal Color Baseline;

			internal Color Tint;

			internal float Scale;
		}

		private sealed class Binding
		{
			internal Renderer Renderer;

			internal Material[] Emissive;
		}

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

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

		private readonly List<Binding> bindings = new List<Binding>();

		private readonly List<GameObject> roots = new List<GameObject>();

		private bool applied;

		internal int MaterialCount => materials.Count;

		internal void Refresh(TargetGroup group)
		{
			//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_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Expected O, but got Unknown
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_025a: Unknown result type (might be due to invalid IL or missing references)
			//IL_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			Restore();
			bindings.Clear();
			roots.Clear();
			HashSet<Tuple<Material, float>> used = new HashSet<Tuple<Material, float>>();
			foreach (Target member in group.Members)
			{
				if (!Object.op_Implicit((Object)(object)member.VisualRoot) || member.Style.SurfaceGlow <= 0f)
				{
					continue;
				}
				roots.Add(member.VisualRoot);
				Renderer[] componentsInChildren = member.VisualRoot.GetComponentsInChildren<Renderer>(true);
				foreach (Renderer val in componentsInChildren)
				{
					if (!(val is MeshRenderer) && !(val is SkinnedMeshRenderer))
					{
						continue;
					}
					Material[] sharedMaterials = val.sharedMaterials;
					Material[] array = (Material[])sharedMaterials.Clone();
					bool flag = false;
					for (int j = 0; j < sharedMaterials.Length; j++)
					{
						Material val2 = sharedMaterials[j];
						if (!Object.op_Implicit((Object)(object)val2))
						{
							continue;
						}
						if (originals.TryGetValue(val2, out var value))
						{
							val2 = (sharedMaterials[j] = value);
						}
						string text = (val2.HasProperty("_EmissionColor") ? "_EmissionColor" : (val2.HasProperty("_EmissiveColor") ? "_EmissiveColor" : null));
						if (text == null)
						{
							array[j] = val2;
							continue;
						}
						Tuple<Material, float> tuple = Tuple.Create<Material, float>(val2, member.Style.SurfaceGlow);
						used.Add(tuple);
						if (!materials.TryGetValue(tuple, out var value2))
						{
							Material val3 = new Material(val2)
							{
								name = ((Object)val2).name + " [WildGlow emission]",
								hideFlags = (HideFlags)52
							};
							string text2 = (val3.HasProperty("_EmissiveTex") ? "_EmissiveTex" : (val3.HasProperty("_EmissionMap") ? "_EmissionMap" : null));
							if (text2 != null && val3.HasProperty("_MainTex"))
							{
								val3.SetTexture(text2, (Texture)(((object)val2.GetTexture("_MainTex")) ?? ((object)Texture2D.whiteTexture)));
								val3.SetTextureScale(text2, val2.GetTextureScale("_MainTex"));
								val3.SetTextureOffset(text2, val2.GetTextureOffset("_MainTex"));
							}
							val3.EnableKeyword("_EMISSION");
							value2 = new Glow
							{
								Material = val3,
								ColorProperty = text,
								Scale = member.Style.SurfaceGlow,
								Baseline = val2.GetColor(text),
								Tint = (val2.HasProperty("_Color") ? val2.GetColor("_Color") : Color.white)
							};
							materials.Add(tuple, value2);
							originals.Add(val3, val2);
						}
						array[j] = value2.Material;
						flag = true;
					}
					if (flag)
					{
						bindings.Add(new Binding
						{
							Renderer = val,
							Emissive = array
						});
					}
				}
			}
			Tuple<Material, float>[] array2 = materials.Keys.Where((Tuple<Material, float> item) => !used.Contains(item)).ToArray();
			foreach (Tuple<Material, float> key in array2)
			{
				Material material = materials[key].Material;
				originals.Remove(material);
				materials.Remove(key);
				if (Object.op_Implicit((Object)(object)material))
				{
					Object.Destroy((Object)(object)material);
				}
			}
		}

		internal void Tick(float amount, float night)
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: 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_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			if (amount <= 0.0001f)
			{
				Restore();
				return;
			}
			float num = Mathf.Clamp(amount, 0f, 2f) * Mathf.Lerp(0.18f, 0.65f, night);
			foreach (Glow value in materials.Values)
			{
				if (Object.op_Implicit((Object)(object)value.Material))
				{
					Color val = value.Baseline + value.Tint * (num * value.Scale);
					val.a = value.Baseline.a;
					value.Material.SetColor(value.ColorProperty, val);
				}
			}
			if (applied)
			{
				return;
			}
			foreach (Binding binding in bindings)
			{
				if (Object.op_Implicit((Object)(object)binding.Renderer))
				{
					binding.Renderer.sharedMaterials = binding.Emissive;
				}
			}
			applied = true;
		}

		internal void Restore()
		{
			if (!applied)
			{
				return;
			}
			foreach (Renderer item in bindings.Select((Binding b) => b.Renderer).Concat(roots.Where((GameObject root) => Object.op_Implicit((Object)(object)root)).SelectMany((GameObject root) => root.GetComponentsInChildren<Renderer>(true))).Distinct())
			{
				if (!Object.op_Implicit((Object)(object)item))
				{
					continue;
				}
				Material[] sharedMaterials = item.sharedMaterials;
				bool flag = false;
				for (int num = 0; num < sharedMaterials.Length; num++)
				{
					if (Object.op_Implicit((Object)(object)sharedMaterials[num]) && originals.TryGetValue(sharedMaterials[num], out var value))
					{
						sharedMaterials[num] = value;
						flag = true;
					}
				}
				if (flag)
				{
					item.sharedMaterials = sharedMaterials;
				}
			}
			applied = false;
		}

		public void Dispose()
		{
			Restore();
			foreach (Glow value in materials.Values)
			{
				if (Object.op_Implicit((Object)(object)value.Material))
				{
					Object.Destroy((Object)(object)value.Material);
				}
			}
			bindings.Clear();
			roots.Clear();
			materials.Clear();
			originals.Clear();
		}
	}
	internal sealed class ModelSpill : IDisposable
	{
		private readonly Transform parent;

		private readonly List<Light> lights = new List<Light>();

		internal int ActiveCount { get; private set; }

		internal ModelSpill(Transform parent)
		{
			this.parent = parent;
		}

		internal void Tick(TargetGroup group, Color tint, float amount, float padding, float night)
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: 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_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: 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_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: 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_01e6: 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)
			int num = ((amount > 0.0001f && group != null && group.HasLightBounds) ? group.SpillBudget : 0);
			while (lights.Count > num)
			{
				Light obj = lights[lights.Count - 1];
				((Behaviour)obj).enabled = false;
				Object.Destroy((Object)(object)((Component)obj).gameObject);
				lights.RemoveAt(lights.Count - 1);
			}
			while (lights.Count < num)
			{
				GameObject val = new GameObject("WildGlow soft spill")
				{
					hideFlags = (HideFlags)52
				};
				val.transform.SetParent(parent, false);
				Light val2 = val.AddComponent<Light>();
				((Behaviour)val2).enabled = false;
				val2.type = (LightType)2;
				val2.shadows = (LightShadows)0;
				val2.renderMode = (LightRenderMode)1;
				val2.bounceIntensity = 0f;
				lights.Add(val2);
			}
			ActiveCount = num;
			if (num != 0)
			{
				Bounds lightBounds = group.LightBounds;
				Vector3 extents = ((Bounds)(ref lightBounds)).extents;
				float range = SpillLayout.Range(extents.x, extents.y, extents.z, padding);
				bool flag = group.FruitLightPositions.Count > 0;
				if (flag)
				{
					range = Mathf.Max(2f, ((Vector3)(ref extents)).magnitude * 2f + padding);
				}
				float intensity = SpillLayout.Intensity(amount, night, num);
				for (int i = 0; i < num; i++)
				{
					MoteMotion.Point point = SpillLayout.Position(extents.x, extents.y, extents.z, i, num);
					Light obj2 = lights[i];
					((Component)obj2).transform.position = (flag ? group.FruitLightPositions[i % group.FruitLightPositions.Count] : (((Bounds)(ref lightBounds)).center + new Vector3(point.X, point.Y, point.Z)));
					obj2.range = range;
					obj2.intensity = intensity;
					obj2.color = Color.Lerp(Color.white, tint, 0.18f);
					((Behaviour)obj2).enabled = true;
				}
			}
		}

		internal void Hide()
		{
			foreach (Light light in lights)
			{
				if (Object.op_Implicit((Object)(object)light))
				{
					((Behaviour)light).enabled = false;
				}
			}
			ActiveCount = 0;
		}

		public void Dispose()
		{
			Hide();
			foreach (Light light in lights)
			{
				if (Object.op_Implicit((Object)(object)light))
				{
					Object.Destroy((Object)(object)((Component)light).gameObject);
				}
			}
			lights.Clear();
		}
	}
	internal static class ModelSurface
	{
		internal static bool Prepare(GameObject root, List<SurfaceAnchor> anchors, ref int signature, out Bounds bounds, out bool changed)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: 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_014b: 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_024f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: 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_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_0286: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: 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_0294: Unknown result type (might be due to invalid IL or missing references)
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Unknown result type (might be due to invalid IL or missing references)
			//IL_029f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: 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_0333: Unknown result type (might be due to invalid IL or missing references)
			//IL_0338: Unknown result type (might be due to invalid IL or missing references)
			//IL_034a: Unknown result type (might be due to invalid IL or missing references)
			//IL_034f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0354: Unknown result type (might be due to invalid IL or missing references)
			//IL_0366: Unknown result type (might be due to invalid IL or missing references)
			//IL_036b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0370: Unknown result type (might be due to invalid IL or missing references)
			//IL_038d: Unknown result type (might be due to invalid IL or missing references)
			//IL_038f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0391: Unknown result type (might be due to invalid IL or missing references)
			//IL_0396: Unknown result type (might be due to invalid IL or missing references)
			//IL_0398: Unknown result type (might be due to invalid IL or missing references)
			//IL_039a: Unknown result type (might be due to invalid IL or missing references)
			//IL_039f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a8: 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_03b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c4: 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_03d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e0: 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_03ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fc: Unknown result type (might be due to invalid IL or missing references)
			bounds = default(Bounds);
			changed = false;
			List<MeshFilter> list = new List<MeshFilter>();
			HashSet<Renderer> hashSet = new HashSet<Renderer>();
			LODGroup[] componentsInChildren = root.GetComponentsInChildren<LODGroup>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				LOD[] lODs = componentsInChildren[i].GetLODs();
				for (int j = 1; j < lODs.Length; j++)
				{
					Renderer[] renderers = lODs[j].renderers;
					foreach (Renderer val in renderers)
					{
						if (Object.op_Implicit((Object)(object)val))
						{
							hashSet.Add(val);
						}
					}
				}
				if (lODs.Length != 0)
				{
					Renderer[] renderers = lODs[0].renderers;
					foreach (Renderer item in renderers)
					{
						hashSet.Remove(item);
					}
				}
			}
			int num = 23;
			MeshFilter[] componentsInChildren2 = root.GetComponentsInChildren<MeshFilter>(false);
			foreach (MeshFilter val2 in componentsInChildren2)
			{
				MeshRenderer component = ((Component)val2).GetComponent<MeshRenderer>();
				Mesh sharedMesh = val2.sharedMesh;
				if (Object.op_Implicit((Object)(object)component) && ((Renderer)component).enabled && !((Renderer)component).forceRenderingOff && !hashSet.Contains((Renderer)(object)component) && Object.op_Implicit((Object)(object)sharedMesh) && sharedMesh.isReadable)
				{
					if (list.Count == 0)
					{
						bounds = ((Renderer)component).bounds;
					}
					else
					{
						((Bounds)(ref bounds)).Encapsulate(((Renderer)component).bounds);
					}
					list.Add(val2);
					num = num * 31 + ((Object)val2).GetInstanceID();
					num = num * 31 + ((Object)sharedMesh).GetInstanceID();
					num = num * 31 + ((object)((Renderer)component).bounds/*cast due to .constrained prefix*/).GetHashCode();
					num = num * 31 + sharedMesh.vertexCount;
				}
			}
			if (list.Count == 0)
			{
				return false;
			}
			if (num == signature && anchors.Count > 0)
			{
				return true;
			}
			signature = num;
			changed = true;
			anchors.Clear();
			int num2 = Math.Max(1, 48 / list.Count);
			foreach (MeshFilter item3 in list)
			{
				Mesh sharedMesh2 = item3.sharedMesh;
				Vector3[] vertices = sharedMesh2.vertices;
				int[] triangles = sharedMesh2.triangles;
				float[] array = new float[triangles.Length / 3];
				float num3 = 0f;
				Vector3 val6;
				for (int l = 0; l < array.Length; l++)
				{
					Vector3 val3 = ((Component)item3).transform.TransformPoint(vertices[triangles[l * 3]]);
					Vector3 val4 = ((Component)item3).transform.TransformPoint(vertices[triangles[l * 3 + 1]]);
					Vector3 val5 = ((Component)item3).transform.TransformPoint(vertices[triangles[l * 3 + 2]]);
					float num4 = num3;
					val6 = Vector3.Cross(val4 - val3, val5 - val3);
					num3 = (array[l] = num4 + ((Vector3)(ref val6)).magnitude * 0.5f);
				}
				if (num3 <= 1E-06f)
				{
					continue;
				}
				for (int m = 0; m < num2; m++)
				{
					if (anchors.Count >= 96)
					{
						break;
					}
					float value = ((float)m + 0.5f) / (float)num2 * num3;
					int num5 = Array.BinarySearch(array, value);
					if (num5 < 0)
					{
						num5 = ~num5;
					}
					num5 = Math.Min(num5, array.Length - 1) * 3;
					Vector3 val7 = ((Component)item3).transform.TransformPoint(vertices[triangles[num5]]);
					Vector3 val8 = ((Component)item3).transform.TransformPoint(vertices[triangles[num5 + 1]]);
					Vector3 val9 = ((Component)item3).transform.TransformPoint(vertices[triangles[num5 + 2]]);
					MoteMotion.Point point = CoverageLayout.Barycentric(MoteMotion.Hash(m + 13), MoteMotion.Hash(m + 71));
					val6 = Vector3.Cross(val8 - val7, val9 - val7);
					Vector3 normalized = ((Vector3)(ref val6)).normalized;
					SurfaceAnchor item2 = SurfaceAnchor.At(((Component)item3).transform, val7 * point.X + val8 * point.Y + val9 * point.Z + normalized * 0.01f, null, normalized);
					item2.Renderer = (Renderer)(object)((Component)item3).GetComponent<MeshRenderer>();
					item2.RequiresRenderer = true;
					anchors.Add(item2);
				}
			}
			return anchors.Count > 0;
		}
	}
	internal static class MoteArt
	{
		internal struct Pixel
		{
			internal float R;

			internal float G;

			internal float B;

			internal float A;
		}

		internal static float Clamp(float x)
		{
			return Math.Max(0f, Math.Min(1f, x));
		}

		internal static string Motif(string id)
		{
			if (id.Contains("berry"))
			{
				return "berry";
			}
			if (!id.StartsWith("mushroom"))
			{
				switch (id)
				{
				case "jotunpuffs":
				case "magecap":
				case "smokepuff":
					break;
				default:
					if (id.EndsWith("core"))
					{
						return "core";
					}
					switch (id)
					{
					case "honey":
					case "chitin":
					case "dragonegg":
						return "cell";
					case "fenris":
						return "fiber";
					default:
						return "facet";
					}
				}
			}
			return "spore";
		}

		internal static Pixel Sample(float x, float y, string shape, string motif, int variant, Pixel body, Pixel rim)
		{
			float num = x / (0.84f + (float)variant * 0.045f);
			float num2 = y / (1f - (float)variant * 0.045f);
			num += num2 * ((float)variant - 1.5f) * 0.12f;
			if (motif == "spore")
			{
				float num3 = (float)Math.Atan2(num2, num);
				float num4 = 0.54f + 0.07f * (float)Math.Sin(num3 * (float)(3 + variant) + (float)variant);
				float num5 = (float)Math.Sqrt(num * num + num2 * num2 * (1.1f + (float)variant * 0.2f)) / num4;
				float num6 = Clamp(1f - num5);
				float num7 = 0.75f + 0.25f * (float)Math.Sin(num * 19f + num2 * 13f + (float)variant);
				return new Pixel
				{
					R = body.R * 0.3f + rim.R * 0.7f,
					G = body.G * 0.3f + rim.G * 0.7f,
					B = body.B * 0.3f + rim.B * 0.7f,
					A = num6 * num6 * num7 * 0.78f
				};
			}
			float num8 = (float)Math.Sqrt(num * num + num2 * num2);
			float num9 = shape switch
			{
				"shard" => Math.Abs(num + 0.23f * num2) / ((num2 > 0f) ? 0.53f : 0.66f) + Math.Abs(num2) / 0.92f, 
				"seed" => Math.Abs(num) / 0.56f + Math.Abs(num2) / 0.93f, 
				"leaf" => Math.Abs(num) / 0.53f + num2 * num2 / 0.82f, 
				"hex" => Math.Max(Math.Abs(num2) / 0.78f, (Math.Abs(num) * 0.866f + Math.Abs(num2) * 0.5f) / 0.78f), 
				"star" => (float)(Math.Pow(Math.Abs(num), 0.6) + Math.Pow(Math.Abs(num2), 0.6)), 
				_ => num8 / 0.72f, 
			};
			float a = Clamp((1f - num9) / 0.055f);
			int num10 = (int)Math.Floor(((double)((float)Math.Atan2(num2, num) + (float)variant * 0.37f) + Math.PI * 2.0) / (Math.PI / 3.0));
			float num11 = 0.52f + (float)(num10 % 3) * 0.23f;
			float num12 = Clamp(1f - Math.Abs(num * 0.8f + num2 * 0.23f) / 0.035f) * Clamp(1f - num9);
			float num13 = Math.Max(Clamp((num9 - 0.8f) / 0.15f) * ((num < 0f) ? 0.88f : 0.38f), num12 * 0.3f);
			if (shape == "round")
			{
				num11 = 0.45f + Clamp(1f - num8 / 0.72f) * 0.48f;
				float num14 = Clamp(1f - (float)Math.Sqrt((num + 0.23f) * (num + 0.23f) + (num2 - 0.22f) * (num2 - 0.22f)) / 0.13f);
				num13 = Math.Max(num13, num14 * 0.9f);
			}
			if (shape == "leaf" || motif == "fiber")
			{
				float num15 = ((Math.Abs(num) < 0.025f || Math.Abs((num2 + Math.Abs(num) * 1.1f + 1f) % 0.24f - 0.12f) < 0.015f) ? 0.46f : 0f);
				num13 = Math.Max(num13, num15 * Clamp(1f - num9));
			}
			if (motif == "berry" || motif == "spore")
			{
				float num16 = (num + 1.2f + (float)variant * 0.07f) % 0.28f - 0.14f;
				float num17 = (num2 + 1.2f) % 0.26f - 0.13f;
				float num18 = Clamp(1f - (float)Math.Sqrt(num16 * num16 + num17 * num17) / 0.048f) * Clamp(1f - num9);
				if (motif == "spore")
				{
					num13 = Math.Max(num13, num18 * 0.9f);
				}
				else
				{
					num11 *= 1f - num18 * 0.55f;
				}
			}
			if (motif == "cell" || motif == "core")
			{
				float num19 = Clamp(1f - Math.Abs(num9 - 0.6f) / 0.045f);
				num13 = Math.Max(num13, num19 * 0.6f);
				if (motif == "core")
				{
					num13 = Math.Max(num13, Clamp(1f - num8 / 0.24f) * 0.7f);
				}
			}
			return new Pixel
			{
				R = body.R * num11 * (1f - num13) + rim.R * num13,
				G = body.G * num11 * (1f - num13) + rim.G * num13,
				B = body.B * num11 * (1f - num13) + rim.B * num13,
				A = a
			};
		}
	}
	internal struct Appearance
	{
		internal float Density;

		internal float Radius;

		internal float Height;

		internal float Brightness;

		internal float Speed;

		internal float Dust;

		internal float TrailLength;

		internal float Twist;

		internal float AreaGlow;

		internal float SpillIntensity;

		internal float SpillRange;

		internal float Night;
	}
	internal sealed class MoteEffect : IDisposable
	{
		private readonly GameObject root;

		private readonly ParticleSystem motes;

		private readonly ParticleSystem dust;

		private readonly ParticleSystem glints;

		private readonly Particle[] particles = (Particle[])(object)new Particle[128];

		private readonly Particle[] dustParticles = (Particle[])(object)new Particle[192];

		private readonly Particle[] glintParticles = (Particle[])(object)new Particle[32];

		private readonly Style style;

		private readonly int seed;

		private readonly float created;

		private readonly TrailMesh trails;

		private readonly ModelEmission emission = new ModelEmission();

		private readonly ModelSpill spill;

		private TargetGroup sources;

		private readonly EffectFamily family;

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

		private static readonly List<Texture2D> Textures = new List<Texture2D>();

		internal int EmissiveMaterials => emission.MaterialCount;

		internal int SpillLights => spill.ActiveCount;

		internal MoteEffect(Style style, int id)
		{
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: 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_0111: Unknown result type (might be due to invalid IL or missing references)
			this.style = style;
			family = EffectBehavior.Family(style.Id);
			seed = (int)((uint)id % 997u);
			created = Time.time;
			root = new GameObject("WildGlow_" + style.Id)
			{
				hideFlags = (HideFlags)52
			};
			spill = new ModelSpill(root.transform);
			try
			{
				motes = CreateSystem("Faceted motes", GetMaterial(style, "mote"), 128);
				TextureSheetAnimationModule textureSheetAnimation = motes.textureSheetAnimation;
				((TextureSheetAnimationModule)(ref textureSheetAnimation)).enabled = true;
				((TextureSheetAnimationModule)(ref textureSheetAnimation)).numTilesX = 2;
				((TextureSheetAnimationModule)(ref textureSheetAnimation)).numTilesY = 2;
				((TextureSheetAnimationModule)(ref textureSheetAnimation)).animation = (ParticleSystemAnimationType)0;
				((TextureSheetAnimationModule)(ref textureSheetAnimation)).frameOverTime = new MinMaxCurve(0f);
				((TextureSheetAnimationModule)(ref textureSheetAnimation)).startFrame = new MinMaxCurve(0f, 3.999f);
				dust = CreateSystem("Fine dust", GetMaterial(style, "dust"), 192);
				glints = CreateSystem("Edge glints", GetMaterial(style, "glint"), 32);
				trails = new TrailMesh(root.transform, GetMaterial(style, "trail"));
			}
			catch
			{
				trails?.Dispose();
				Object.Destroy((Object)(object)root);
				throw;
			}
		}

		private ParticleSystem CreateSystem(string name, Material material, int count)
		{
			//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_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: 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_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name)
			{
				hideFlags = (HideFlags)52
			};
			val.transform.SetParent(root.transform, false);
			ParticleSystem obj = val.AddComponent<ParticleSystem>();
			obj.Stop(true, (ParticleSystemStopBehavior)0);
			MainModule main = obj.main;
			((MainModule)(ref main)).playOnAwake = false;
			((MainModule)(ref main)).loop = false;
			((MainModule)(ref main)).maxParticles = count;
			((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)0;
			((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(0f);
			((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(1000f);
			((MainModule)(ref main)).gravityModifier = MinMaxCurve.op_Implicit(0f);
			((MainModule)(ref main)).scalingMode = (ParticleSystemScalingMode)1;
			EmissionModule val2 = obj.emission;
			((EmissionModule)(ref val2)).enabled = false;
			ShapeModule shape = obj.shape;
			((ShapeModule)(ref shape)).enabled = false;
			ParticleSystemRenderer component = ((Component)obj).GetComponent<ParticleSystemRenderer>();
			((Renderer)component).sharedMaterial = material;
			component.renderMode = (ParticleSystemRenderMode)0;
			((Renderer)component).shadowCastingMode = (ShadowCastingMode)0;
			((Renderer)component).receiveShadows = false;
			((Renderer)component).lightProbeUsage = (LightProbeUsage)0;
			((Renderer)component).reflectionProbeUsage = (ReflectionProbeUsage)0;
			component.maxParticleSize = 0.5f;
			component.sortMode = (ParticleSystemSortMode)1;
			obj.Play();
			obj.Pause();
			return obj;
		}

		private static Particle Particle(Vector3 position, float size, Color color, float rotation, uint key)
		{
			//IL_0002: 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_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: 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)
			Particle result = default(Particle);
			((Particle)(ref result)).position = position;
			((Particle)(ref result)).startSize = size;
			((Particle)(ref result)).startColor = Color32.op_Implicit(color);
			((Particle)(ref result)).rotation = rotation;
			((Particle)(ref result)).startLifetime = 1000f;
			((Particle)(ref result)).remainingLifetime = 1000f;
			((Particle)(ref result)).randomSeed = key + 1;
			return result;
		}

		internal void SetVisible(bool visible)
		{
			if (Object.op_Implicit((Object)(object)root))
			{
				root.SetActive(visible);
			}
			if (!visible)
			{
				emission.Restore();
				spill.Hide();
			}
		}

		internal void BindSources(TargetGroup group)
		{
			if (sources != group)
			{
				emission.Refresh(group);
			}
			sources = group;
		}

		internal void DetachSources()
		{
			emission.Restore();
			sources = null;
		}

		private SurfaceAnchor SourceAnchor(int index, bool upward)
		{
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			int num = (sources.IsFruitTree ? (index % sources.Anchors.Count) : ((int)(MoteMotion.Hash(index + 31) * (float)sources.Anchors.Count)));
			if (upward && sources.IsDeposit)
			{
				for (int i = 0; i < sources.Anchors.Count; i++)
				{
					SurfaceAnchor result = sources.Anchors[(num + i) % sources.Anchors.Count];
					if (result.Valid && result.WorldNormal.y >= 0.25f)
					{
						return result;
					}
				}
			}
			return sources.Anchors[num];
		}

		private MoteMotion.Point Anchor(int index, Vector3 center, bool upward = false)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: 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_0036: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: 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)
			if (sources == null || sources.Anchors.Count == 0)
			{
				return default(MoteMotion.Point);
			}
			SurfaceAnchor surfaceAnchor = SourceAnchor(index, upward);
			Vector3 val = (surfaceAnchor.Valid ? (surfaceAnchor.World - center) : Vector3.zero);
			return new MoteMotion.Point(val.x, val.y, val.z);
		}

		private Vector3 AnchorNormal(int index)
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			if (sources == null || !sources.IsDeposit || sources.Anchors.Count == 0)
			{
				return Vector3.zero;
			}
			SurfaceAnchor surfaceAnchor = SourceAnchor(index, upward: false);
			if (!surfaceAnchor.Valid)
			{
				return Vector3.up;
			}
			return surfaceAnchor.WorldNormal;
		}

		internal void Tick(Vector3 center, float time, Appearance a, float fade, Camera camera)
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: 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_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_06e7: 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_0241: Unknown result type (might be due to invalid IL or missing references)
			//IL_055c: 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_024a: 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_0258: 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_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0263: Unknown result type (might be due to invalid IL or missing references)
			//IL_059f: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_05bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0603: Unknown result type (might be due to invalid IL or missing references)
			//IL_0608: Unknown result type (might be due to invalid IL or missing references)
			//IL_060d: Unknown result type (might be due to invalid IL or missing references)
			//IL_060f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0611: Unknown result type (might be due to invalid IL or missing references)
			//IL_065a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0672: Unknown result type (might be due to invalid IL or missing references)
			//IL_067b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0680: Unknown result type (might be due to invalid IL or missing references)
			//IL_0339: Unknown result type (might be due to invalid IL or missing references)
			//IL_0353: Unknown result type (might be due to invalid IL or missing references)
			//IL_037e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0383: Unknown result type (might be due to invalid IL or missing references)
			//IL_0447: Unknown result type (might be due to invalid IL or missing references)
			//IL_0449: Unknown result type (might be due to invalid IL or missing references)
			//IL_0474: Unknown result type (might be due to invalid IL or missing references)
			//IL_0476: Unknown result type (might be due to invalid IL or missing references)
			//IL_047d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0487: Unknown result type (might be due to invalid IL or missing references)
			//IL_048c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0499: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f7: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)root))
			{
				return;
			}
			if (sources != null && sources.IsFruitTree && !sources.Anchors.Exists((SurfaceAnchor surfaceAnchor) => surfaceAnchor.Valid))
			{
				SetVisible(visible: false);
				return;
			}
			root.transform.position = center;
			if (sources != null && sources.Anchors.Count == 0)
			{
				SetVisible(visible: false);
				return;
			}
			float num = a.Brightness * fade * Mathf.Clamp01((time - created) / 0.8f);
			int num2 = Mathf.Clamp(Mathf.RoundToInt(64f * a.Density), 12, 128);
			int num3 = 0;
			float num4 = style.Radius * a.Radius;
			float num5 = style.Height * a.Height;
			bool flag = sources != null && sources.IsFruitTree;
			if (flag)
			{
				num4 = Mathf.Min(num4, 0.1f);
				num5 = Mathf.Min(num5, 0.22f);
			}
			float num6 = ((sources != null && !sources.IsDeposit) ? Mathf.Min(num4, 0.16f) : num4);
			Vector3 cameraLocal = (Vector3)(Object.op_Implicit((Object)(object)camera) ? (((Component)camera).transform.position - center) : new Vector3(0f, 2f, -5f));
			Color val = Color.Lerp(style.Color, style.Accent, 0.8f);
			float num7 = Mathf.Max(num4, (sources != null) ? sources.SurfaceRadius : num4);
			float night = a.Night;
			trails.Begin();
			for (int num8 = 0; num8 < num2; num8++)
			{
				int num9 = num8 + seed;
				float num10 = MoteMotion.Phase(time, a.Speed, num9);
				bool flag2 = !flag && num8 % 3 == 0;
				MoteMotion.Point anchor = Anchor(num8, center, flag2);
				Vector3 p = TrailMesh.ToVector(EffectBehavior.Path(family, flag2, anchor, num10, time, num9, flag2 ? num4 : num6, num5, a.Twist, night));
				Vector3 val2 = (flag2 ? Vector3.zero : AnchorNormal(num8));
				p = TrailMesh.Orient(p, anchor, val2);
				float num11 = 0.82f + 0.18f * Mathf.Sin(time * 1.8f + (float)num9 * 2.7f);
				float num12 = (flag2 ? (Mathf.Clamp01(num10 / 0.12f) * Mathf.Clamp01((1f - num10) / 0.2f)) : EffectBehavior.Alpha(family, num10, time, num9, night)) * num11 * num;
				float num13 = ((style.Shape == "shard") ? 0.085f : 0.066f) * (0.7f + 0.6f * MoteMotion.Hash(num9 + 31));
				num13 *= Mathf.Lerp(1.3f, 1f, night) * ((family == EffectFamily.Spore) ? 0.38f : 1f);
				particles[num8] = Particle(p, num13, new Color(1f, 1f, 1f, Mathf.Clamp01(num12)), MoteMotion.Spin(time, num9, a.Twist * ((family == EffectFamily.Obsidian) ? 1.8f : 1f)), (uint)num9);
				if (num8 % 2 == 0)
				{
					trails.Add(family, flag2, anchor, night, num10, time, num9, flag2 ? num4 : num6, num5, a.Speed, a.Twist, (family == EffectFamily.Spore) ? Mathf.Min(a.TrailLength, 0.35f) : a.TrailLength, num13, num12 * Mathf.Lerp(0.5f, 1f, night), val, cameraLocal, val2);
				}
				if (family != EffectFamily.Spore && num8 % 4 == 0 && num3 < glintParticles.Length)
				{
					float num14 = Mathf.Pow(Mathf.Max(0f, Mathf.Sin(time * 1.2f + (float)num9)), 14f);
					Color color = val;
					color.a = num12 * num14 * Mathf.Lerp(0.4f, 0.9f, night);
					glintParticles[num3++] = Particle(p + Vector3.up * num13 * 0.2f, num13 * 1.25f, color, 15f, (uint)num9);
				}
			}
			motes.SetParticles(particles, num2);
			glints.SetParticles(glintParticles, num3);
			trails.End(num7 + num4, num5);
			int num15 = Mathf.Clamp(Mathf.RoundToInt(80f * a.Density * a.Dust), 0, dustParticles.Length);
			for (int num16 = 0; num16 < num15; num16++)
			{
				int num17 = seed + 1000 + num16;
				float num18 = MoteMotion.Phase(time, a.Speed * 0.65f, num17);
				bool flag3 = !flag && num16 % 4 == 0;
				MoteMotion.Point anchor2 = Anchor(num16 + 19, center, flag3);
				Vector3 p2 = TrailMesh.ToVector(EffectBehavior.Path(family, flag3, anchor2, num18, time, num17, (flag3 ? num4 : num6) * 1.1f, num5 * 0.95f, a.Twist * 0.7f, night));
				p2 = TrailMesh.Orient(p2, anchor2, flag3 ? Vector3.zero : AnchorNormal(num16 + 19));
				p2 += new Vector3(Mathf.Sin(time * 0.45f + (float)num17), Mathf.Sin(time * 0.6f + (float)num17), Mathf.Cos(time * 0.4f + (float)num17)) * 0.025f;
				Color color2 = val;
				color2.a = num * Mathf.Lerp(0.3f, 0.5f, night) * Mathf.Sin(num18 * (float)Math.PI) * (0.6f + 0.4f * MoteMotion.Hash(num17 + 31));
				dustParticles[num16] = Particle(p2, 0.013f + 0.009f * MoteMotion.Hash(num17 + 93), color2, 0f, (uint)num17);
			}
			dust.SetParticles(dustParticles, num15);
			float num19 = fade * Mathf.Clamp01((time - created) / 0.8f);
			emission.Tick(num19 * a.AreaGlow, night);
			spill.Tick(sources, style.Color, num19 * a.SpillIntensity * style.LightSpill, a.SpillRange, night);
		}

		private static Material GetMaterial(Style style, string layer)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: 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)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Expected O, but got Unknown
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			string text = MoteArt.Motif(style.Id);
			string text2 = ((layer == "mote") ? (layer + text + style.Shape + ColorUtility.ToHtmlStringRGB(style.Color) + ColorUtility.ToHtmlStringRGB(style.Accent)) : layer);
			if (Materials.TryGetValue(text2, out var value) && Object.op_Implicit((Object)(object)value))
			{
				return value;
			}
			Shader val = Shader.Find("Particles/Standard Unlit");
			if (!Object.op_Implicit((Object)(object)val))
			{
				val = Shader.Find("Legacy Shaders/Particles/Alpha Blended");
			}
			if (!Object.op_Implicit((Object)(object)val))
			{
				val = Shader.Find("Sprites/Default");
			}
			if (!Object.op_Implicit((Object)(object)val))
			{
				throw new InvalidOperationException("No supported unlit particle shader is loaded.");
			}
			bool flag = layer != "mote" && ((Object)val).name == "Particles/Standard Unlit";
			value = new Material(val)
			{
				name = "WildGlow_" + text2,
				hideFlags = (HideFlags)52,
				renderQueue = 3000
			};
			if (value.HasProperty("_Color"))
			{
				value.SetColor("_Color", Color.white);
			}
			if (value.HasProperty("_TintColor"))
			{
				value.SetColor("_TintColor", new Color(0.5f, 0.5f, 0.5f, 0.5f));
			}
			if (value.HasProperty("_Mode"))
			{
				value.SetFloat("_Mode", (float)(flag ? 4 : 2));
			}
			if (value.HasProperty("_SrcBlend"))
			{
				value.SetInt("_SrcBlend", 5);
			}
			if (value.HasProperty("_DstBlend"))
			{
				value.SetInt("_DstBlend", flag ? 1 : 10);
			}
			if (value.HasProperty("_ZWrite"))
			{
				value.SetInt("_ZWrite", 0);
			}
			if (value.HasProperty("_Cull"))
			{
				value.SetInt("_Cull", 0);
			}
			value.SetOverrideTag("RenderType", "Transparent");
			value.EnableKeyword("_ALPHABLEND_ON");
			value.DisableKeyword("_ALPHATEST_ON");
			value.DisableKeyword("_ALPHAPREMULTIPLY_ON");
			value.DisableKeyword("SOFTPARTICLES_ON");
			value.DisableKeyword("_FADING_ON");
			Texture2D item = (Texture2D)(object)(value.mainTexture = (Texture)(object)MakeTexture(style, layer));
			Materials[text2] = value;
			Textures.Add(item);
			return value;
		}

		private static Texture2D MakeTexture(Style style, string layer)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0295: Unknown result type (might be due to invalid IL or missing references)
			//IL_0297: Unknown result type (might be due to invalid IL or missing references)
			int num = ((layer == "mote") ? 192 : 96);
			Texture2D val = new Texture2D(num, num, (TextureFormat)4, false)
			{
				name = "WildGlow_" + layer,
				wrapMode = (TextureWrapMode)1,
				filterMode = (FilterMode)1,
				hideFlags = (HideFlags)52
			};
			Color[] array = (Color[])(object)new Color[num * num];
			MoteArt.Pixel body = new MoteArt.Pixel
			{
				R = style.Color.r,
				G = style.Color.g,
				B = style.Color.b
			};
			MoteArt.Pixel rim = new MoteArt.Pixel
			{
				R = style.Accent.r,
				G = style.Accent.g,
				B = style.Accent.b
			};
			string motif = MoteArt.Motif(style.Id);
			for (int i = 0; i < num; i++)
			{
				for (int j = 0; j < num; j++)
				{
					float num2 = ((float)(j % 96) + 0.5f) / 96f * 2f - 1f;
					float num3 = ((float)(i % 96) + 0.5f) / 96f * 2f - 1f;
					Color white = Color.white;
					switch (layer)
					{
					case "mote":
					{
						MoteArt.Pixel pixel = MoteArt.Sample(num2, num3, style.Shape, motif, j / 96 + i / 96 * 2, body, rim);
						((Color)(ref white))..ctor(pixel.R, pixel.G, pixel.B, pixel.A);
						break;
					}
					case "trail":
						white.a = Mathf.Pow(Mathf.Max(0f, 1f - Mathf.Abs(num2)), 1.5f);
						break;
					case "glint":
					{
						float num4 = Mathf.Max(0f, 1f - (Mathf.Pow(Mathf.Abs(num2), 0.5f) + Mathf.Pow(Mathf.Abs(num3), 0.5f)));
						white.a = num4 + Mathf.Pow(Mathf.Max(0f, 1f - Mathf.Sqrt(num2 * num2 + num3 * num3)), 6f) * 0.4f;
						break;
					}
					default:
						white.a = Mathf.Pow(Mathf.Max(0f, 1f - Mathf.Sqrt(num2 * num2 + num3 * num3)), (layer == "dust") ? 1.6f : 2.2f);
						break;
					}
					array[i * num + j] = white;
				}
			}
			val.SetPixels(array);
			val.Apply(false, true);
			return val;
		}

		public void Dispose()
		{
			emission.Dispose();
			spill.Dispose();
			trails?.Dispose();
			if (Object.op_Implicit((Object)(object)root))
			{
				Object.Destroy((Object)(object)root);
			}
		}

		internal static void ReleaseMaterials()
		{
			foreach (Material value in Materials.Values)
			{
				if (Object.op_Implicit((Object)(object)value))
				{
					Object.Destroy((Object)(object)value);
				}
			}
			foreach (Texture2D texture in Textures)
			{
				if (Object.op_Implicit((Object)(object)texture))
				{
					Object.Destroy((Object)(object)texture);
				}
			}
			Materials.Clear();
			Textures.Clear();
		}
	}
	internal static class MoteMotion
	{
		internal struct Point
		{
			internal float X;

			internal float Y;

			internal float Z;

			internal Point(float x, float y, float z)
			{
				X = x;
				Y = y;
				Z = z;
			}
		}

		internal const float Lifetime = 6.5f;

		internal static float Hash(int n)
		{
			int num = (n ^ (n >>> 16)) * 2146121005;
			int num2 = (num ^ (num >>> 15)) * -2073254261;
			return (float)(uint)((num2 ^ (num2 >>> 16)) & 0xFFFFFF) / 16777216f;
		}

		internal static float Phase(float time, float speed, int key)
		{
			float num = time * speed / 6.5f + Hash(key);
			return num - (float)Math.Floor(num);
		}

		internal static Point Position(float phase, float time, int key, float radius, float height, float twist)
		{
			float num = Math.Min(1f, Math.Max(0f, phase / 0.65f));
			num = num * num * (3f - 2f * num);
			float num2 = radius * (0.12f + 0.88f * (1f - num)) * (0.3f + 0.7f * (float)Math.Sqrt(Hash(key + 191)));
			float num3 = Hash(key + 43) * (float)Math.PI * 2f + (phase * 4.2f + time * 0.16f) * twist;
			return new Point((float)Math.Cos(num3) * num2, 0.05f + phase * height, (float)Math.Sin(num3) * num2);
		}

		internal static Point TrailPoint(float phase, float time, int key, float radius, float height, float speed, float twist, float length, float fraction)
		{
			Point point = Position(phase, time, key, radius, height, twist);
			float num = Math.Min(0.28f * length, phase * 6.5f / Math.Max(0.01f, speed)) * fraction;
			Point result = Position(Math.Max(0f, phase - num * speed / 6.5f), time - num, key, radius, height, twist);
			float num2 = result.X - point.X;
			float num3 = result.Y - point.Y;
			float num4 = result.Z - point.Z;
			float num5 = (float)Math.Sqrt(num2 * num2 + num3 * num3 + num4 * num4);
			float num6 = 0.22f * length;
			if (num5 > num6 && num5 > 0f)
			{
				float num7 = num6 / num5;
				return new Point(point.X + num2 * num7, point.Y + num3 * num7, point.Z + num4 * num7);
			}
			return result;
		}

		internal static float Spin(float time, int key, float twist)
		{
			return (float)(key * 71) + time * (10f + 10f * Hash(key + 77)) * twist;
		}
	}
	[BepInPlugin("local.valheim.wildglow", "WildGlow", "0.4.12")]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string Guid = "local.valheim.wildglow";

		internal static Plugin Instance;

		internal static ManualLogSource Log;

		internal static ConfigEntry<bool> IncludeBuilt;

		internal static HashSet<string> Excluded = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

		private ConfigEntry<bool> enabledMod;

		private ConfigEntry<string> variantMode;

		private ConfigEntry<float> range;

		private ConfigEntry<float> density;

		private ConfigEntry<float> height;

		private ConfigEntry<float> radius;

		private ConfigEntry<float> brightness;

		private ConfigEntry<float> speed;

		private ConfigEntry<float> dust;

		private ConfigEntry<float> trailLength;

		private ConfigEntry<float> twist;

		private ConfigEntry<float> areaGlow;

		private ConfigEntry<float> spillIntensity;

		private ConfigEntry<float> spillRange;

		private ConfigEntry<float> mergeDistance;

		private ConfigEntry<int> maxEffects;

		private ConfigEntry<int> maxSpillLights;

		private ConfigEntry<string> exclusions;

		private readonly Dictionary<int, GameObject> pending = new Dictionary<int, GameObject>();

		private readonly Dictionary<int, Target> targets = new Dictionary<int, Target>();

		private readonly Dictionary<int, MoteEffect> active = new Dictionary<int, MoteEffect>();

		private readonly List<int> dead = new List<int>();

		private readonly List<Target> near = new List<Target>();

		private readonly Dictionary<int, TargetGroup> groups = new Dictionary<int, TargetGroup>();

		private readonly Dictionary<int, string> activeStyles = new Dictionary<int, string>();

		private Harmony harmony;

		private float nextRefresh;

		private Player lastPlayer;

		private bool configDirty;

		private bool materialsFailed;

		private MoteEffect demonstration;

		private Vector3 demonstrationPosition;

		private float demonstrationUntil;

		private static readonly Type[] Types = new Type[8]
		{
			typeof(Pickable),
			typeof(PickableItem),
			typeof(MineRock),
			typeof(MineRock5),
			typeof(Beehive),
			typeof(Container),
			typeof(DropOnDestroyed),
			typeof(Destructible)
		};

		private void Awake()
		{
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Expected O, but got Unknown
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Expected O, but got Unknown
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Expected O, but got Unknown
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Expected O, but got Unknown
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Expected O, but got Unknown
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Expected O, but got Unknown
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Expected O, but got Unknown
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Expected O, but got Unknown
			//IL_0282: Unknown result type (might be due to invalid IL or missing references)
			//IL_028c: Expected O, but got Unknown
			//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ca: Expected O, but got Unknown
			//IL_02fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0308: Expected O, but got Unknown
			//IL_033c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0346: Expected O, but got Unknown
			//IL_037a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0384: Expected O, but got Unknown
			//IL_03b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c2: Expected O, but got Unknown
			//IL_03f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0400: Expected O, but got Unknown
			//IL_0448: Unknown result type (might be due to invalid IL or missing references)
			//IL_0452: Expected O, but got Unknown
			//IL_04e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ec: Expected O, but got Unknown
			//IL_0517: Unknown result type (might be due to invalid IL or missing references)
			//IL_0521: Expected O, but got Unknown
			//IL_052f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0551: Unknown result type (might be due to invalid IL or missing references)
			//IL_05bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c7: Expected O, but got Unknown
			//IL_0607: Unknown result type (might be due to invalid IL or missing references)
			//IL_0611: Expected O, but got Unknown
			//IL_0621: Unknown result type (might be due to invalid IL or missing references)
			//IL_0627: Expected O, but got Unknown
			//IL_06be: Unknown result type (might be due to invalid IL or missing references)
			//IL_06d2: Expected O, but got Unknown
			//IL_06cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_06e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_06f8: Expected O, but got Unknown
			//IL_06f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_070a: Unknown result type (might be due to invalid IL or missing references)
			//IL_071e: Expected O, but got Unknown
			//IL_0719: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			enabledMod = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable local collectible effects.");
			IncludeBuilt = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "IncludePlayerBuilt", false, "Also mark player-built chests, hives and planted crops.");
			exclusions = ((BaseUnityPlugin)this).Config.Bind<string>("General", "ExcludedPrefabs", "Wood,Stone,RoundLog,FineWood,ElderBark,Pickable_Branch,Pickable_Branch_Snow,Pickable_Stone,Pickable_StoneRock,Pickable_HardRockOffspring", "Comma-separated exact prefab names; evaluated before styles. Add common items here.");
			range = ((BaseUnityPlugin)this).Config.Bind<float>("Performance", "ViewDistance", 45f, new ConfigDescription("Maximum distance in meters; effects fade over the last 10 meters.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 100f), Array.Empty<object>()));
			maxEffects = ((BaseUnityPlugin)this).Config.Bind<int>("Performance", "MaxEffects", 32, new ConfigDescription("Nearest collectible groups visible at once.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 96), Array.Empty<object>()));
			maxSpillLights = ((BaseUnityPlugin)this).Config.Bind<int>("Performance", "MaxSpillLights", 24, new ConfigDescription("Total real spill lights across nearest visible models; 0 disables surrounding illumination. Large models request up to four broad overlapping lights, small models one.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 64), Array.Empty<object>()));
			spillIntensity = ((BaseUnityPlugin)this).Config.Bind<float>("Lighting", "SpillIntensity", 0.6f, new ConfigDescription("Total surrounding light per collectible group, shared across its sources; 0 disables light spill without changing model glow or motes.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>()));
			spillRange = ((BaseUnityPlugin)this).Config.Bind<float>("Lighting", "SpillRange", 3f, new ConfigDescription("Extra light reach beyond the model coverage in meters. This expands falloff, not particle spread.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 8f), Array.Empty<object>()));
			density = ((BaseUnityPlugin)this).Config.Bind<float>("Appearance", "Density", 0.6f, new ConfigDescription("Mote density multiplier (64 motes per effect at 1).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 2f), Array.Empty<object>()));
			height = ((BaseUnityPlugin)this).Config.Bind<float>("Appearance", "Height", 2f, new ConfigDescription("Beam height multiplier; 2 doubles the original columns.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.3f, 4f), Array.Empty<object>()));
			radius = ((BaseUnityPlugin)this).Config.Bind<float>("Appearance", "Radius", 1f, new ConfigDescription("Local mote spread multiplier.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.3f, 2f), Array.Empty<object>()));
			brightness = ((BaseUnityPlugin)this).Config.Bind<float>("Appearance", "Brightness", 1f, new ConfigDescription("Mote opacity multiplier; model glow and light spill have independent controls.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 2f), Array.Empty<object>()));
			speed = ((BaseUnityPlugin)this).Config.Bind<float>("Appearance", "Speed", 0.9f, new ConfigDescription("Rise speed multiplier; 1 gives a slow 6.5 second journey.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 2f), Array.Empty<object>()));
			dust = ((BaseUnityPlugin)this).Config.Bind<float>("Appearance", "Dust", 1f, new ConfigDescription("Fine dust amount; 0 disables it.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>()));
			trailLength = ((BaseUnityPlugin)this).Config.Bind<float>("Appearance", "TrailLength", 2f, new ConfigDescription("Short trail length; 1 caps each tail at 22 cm, 0 disables it.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>()));
			twist = ((BaseUnityPlugin)this).Config.Bind<float>("Appearance", "Twist", 1.45f, new ConfigDescription("Slow orbit and individual spin; 0 produces straight rising motes.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>()));
			areaGlow = ((BaseUnityPlugin)this).Config.Bind<float>("Appearance", "AreaGlow", 1.2f, new ConfigDescription("Dim emission from the original model material; 0 restores original materials. Independent of Lighting.SpillIntensity.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>()));
			mergeDistance = ((BaseUnityPlugin)this).Config.Bind<float>("General", "MergeDistance", 2.5f, new ConfigDescription("Maximum separation in meters between any two objects sharing one effect. 0 disables merging. Mixed groups use the most common style.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 8f), Array.Empty<object>()));
			variantMode = ((BaseUnityPlugin)this).Config.Bind<string>("Appearance", "VariantMode", "Auto", new ConfigDescription("Auto blends daylight/night appearances with the game clock. Day or Night locks the look for comparison.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[3] { "Auto", "Day", "Night" }), Array.Empty<object>()));
			Styles.Load();
			foreach (Style value3 in Styles.ById.Values)
			{
				string text = "Style." + value3.Id;
				((BaseUnityPlugin)this).Config.Bind<bool>(text, "Enabled", true, "Show the " + value3.Label + " effect. False removes its particles, trails, model glow and surrounding illumination. Fallback also controls unlisted/modded collectibles.");
				((BaseUnityPlugin)this).Config.Bind<float>(text, "SurfaceGlow", LightingProfile.GlowScale(value3.Id), new ConfigDescription("Model self-illumination scale, independent of motes and light spill. Mushroom defaults are brighter; bushes and ores are subdued.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>()));
				((BaseUnityPlugin)this).Config.Bind<float>(text, "LightSpill", 1f, new ConfigDescription("Multiplier for surrounding illumination from this collectible style; 0 disables spill for this style.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>()));
				((BaseUnityPlugin)this).Config.Bind<string>(text, "Color", ColorUtility.ToHtmlStringRGB(value3.Color), "Mote RGB hex.");
				((BaseUnityPlugin)this).Config.Bind<string>(text, "Accent", ColorUtility.ToHtmlStringRGB(value3.Accent), "Glint and rim RGB hex.");
				((BaseUnityPlugin)this).Config.Bind<string>(text, "Shape", value3.Shape, new ConfigDescription("Mote silhouette.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[6] { "round", "star", "seed", "leaf", "shard", "hex" }), Array.Empty<object>()));
			}
			ApplyConfig();
			((BaseUnityPlugin)this).Config.SettingChanged += delegate
			{
				configDirty = true;
			};
			harmony = new Harmony("local.valheim.wildglow");
			HarmonyMethod val = new HarmonyMethod(typeof(Plugin), "Register", (Type[])null);
			Type[] types = Types;
			foreach (Type type in types)
			{
				MethodInfo methodInfo = AccessTools.DeclaredMethod(type, (type == typeof(MineRock)) ? "Start" : "Awake", (Type[])null, (Type[])null);
				if (methodInfo != null)
				{
					harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
				else
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("No registration hook for " + type.Name));
				}
			}
			new ConsoleCommand("wildglow_preview", "wildglow_preview <style> — show a local effect for 30 seconds; use stop to clear.", (ConsoleEvent)delegate(ConsoleEventArgs args)
			{
				//IL_00da: 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_00f3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
				Style value;
				if (args.Length < 2)
				{
					args.Context.AddString("Styles: " + string.Join(", ", Styles.ById.Keys));
				}
				else if (args[1] == "stop")
				{
					ClearDemonstration();
				}
				else if (!Object.op_Implicit((Object)(object)Player.m_localPlayer))
				{
					args.Context.AddString("Load a world first.");
				}
				else if (!Styles.ById.TryGetValue(args[1].ToLowerInvariant(), out value))
				{
					args.Context.AddString("Unknown style. Run wildglow_preview for the list.");
				}
				else
				{
					if (enabledMod.Value && value.Enabled)
					{
						ClearDemonstration();
						try
						{
							demonstration = new MoteEffect(value, 11);
							demonstrationPosition = ((Component)Player.m_localPlayer).transform.position + ((Component)Player.m_localPlayer).transform.forward * 2f;
							demonstrationUntil = Time.time + 30f;
							nextRefresh = 0f;
							args.Context.AddString("Previewing " + value.Label + " for 30 seconds, two meters ahead. No item spawned.");
							return;
						}
						catch (Exception ex)
						{
							((BaseUnityPlugin)this).Logger.LogError((object)ex);
							args.Context.AddString("Particle shader unavailable; see the BepInEx log.");
							return;
						}
					}
					args.Context.AddString("This effect is disabled in the WildGlow config.");
				}
			}, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
			new ConsoleCommand("wildglow_reload", "Reload WildGlow's local configuration.", (ConsoleEvent)delegate(ConsoleEventArgs args)
			{
				((BaseUnityPlugin)this).Config.Reload();
				configDirty = true;
				args.Context.AddString("WildGlow configuration reloaded.");
			}, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
			new ConsoleCommand("wildglow_status", "Show the loaded version and nearby model emission diagnostics.", (ConsoleEvent)delegate(ConsoleEventArgs args)
			{
				string text2 = "WildGlow 0.4.12; enabled=" + enabledMod.Value + "; renderer failed=" + materialsFailed + "; active effects=" + active.Count;
				args.Context.AddString(text2);
				((BaseUnityPlugin)this).Logger.LogInfo((object)text2);
				foreach (TargetGroup item in groups.Values.OrderBy((TargetGroup g) => g.Distance).Take(5))
				{
					MoteEffect value;
					MoteEffect value2;
					string text3 = item.Style.Label + ": " + item.Anchors.Count + " surface anchors, " + (active.TryGetValue(item.Id, out value) ? value.EmissiveMaterials : 0) + " emissive materials, " + (active.TryGetValue(item.Id, out value2) ? value2.SpillLights : 0) + " spill lights; " + string.Join(", ", item.Members.Select((Target t) => (!Object.op_Implicit((Object)(object)t.Root)) ? "removed" : ((Object)t.Root).name));
					args.Context.AddString(text3);
					((BaseUnityPlugin)this).Logger.LogInfo((object)text3);
				}
			}, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
			((BaseUnityPlugin)this).Logger.LogInfo((object)("WildGlow 0.4.12 loaded. " + Styles.ById.Count + " styles. Client-only visuals; no save or network data changes."));
		}

		private static void Register(Component __instance)
		{
			//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)
			if (Object.op_Implicit((Object)(object)Instance) && Object.op_Implicit((Object)(object)__instance))
			{
				Scene scene = __instance.gameObject.scene;
				if (((Scene)(ref scene)).IsValid())
				{
					Instance.pending[((Object)__instance.gameObject).GetInstanceID()] = __instance.gameObject;
				}
			}
		}

		private void ApplyConfig()
		{
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: 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_01c4: Unknown result type (might be due to invalid IL or missing references)
			Excluded = new HashSet<string>(from s in exclusions.Value.Split(',')
				select s.Trim() into s
				where s.Length > 0
				select s, StringComparer.OrdinalIgnoreCase);
			Excluded.UnionWith(new string[8] { "Flint", "Pickable_Flint", "SurtlingCore", "Pickable_SurtlingCoreStand", "FirTree", "FirTree_log", "FirTree_log_half", "FirTree_Stub" });
			ConfigEntry<bool> val = default(ConfigEntry<bool>);
			ConfigEntry<float> val2 = default(ConfigEntry<float>);
			ConfigEntry<float> val3 = default(ConfigEntry<float>);
			ConfigEntry<string> val4 = default(ConfigEntry<string>);
			Color color = default(Color);
			ConfigEntry<string> val5 = default(ConfigEntry<string>);
			Color accent = default(Color);
			ConfigEntry<string> val6 = default(ConfigEntry<string>);
			foreach (Style value in Styles.ById.Values)
			{
				string text = "Style." + value.Id;
				if (((BaseUnityPlugin)this).Config.TryGetEntry<bool>(text, "Enabled", ref val))
				{
					value.Enabled = val.Value;
				}
				if (((BaseUnityPlugin)this).Config.TryGetEntry<float>(text, "SurfaceGlow", ref val2))
				{
					value.SurfaceGlow = val2.Value;
				}
				if (((BaseUnityPlugin)this).Config.TryGetEntry<float>(text, "LightSpill", ref val3))
				{
					value.LightSpill = val3.Value;
				}
				if (((BaseUnityPlugin)this).Config.TryGetEntry<string>(text, "Color", ref val4) && ColorUtility.TryParseHtmlString("#" + val4.Value.TrimStart('#'), ref color))
				{
					value.Color = color;
				}
				if (((BaseUnityPlugin)this).Config.TryGetEntry<string>(text, "Accent", ref val5) && ColorUtility.TryParseHtmlString("#" + val5.Value.TrimStart('#'), ref accent))
				{
					value.Accent = accent;
				}
				if (((BaseUnityPlugin)this).Config.TryGetEntry<string>(text, "Shape", ref val6))
				{
					value.Shape = val6.Value;
				}
			}
			Styles.ClearAutomatic();
		}

		private void Update()
		{
			//IL_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_0317: 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_02cb: Expected O, but got Unknown
			//IL_03c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0408: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if (configDirty)
			{
				configDirty = false;
				ApplyConfig();
				ClearEffects();
				ClearDemonstration();
				MoteEffect.ReleaseMaterials();
				foreach (KeyValuePair<int, Target> target in targets)
				{
					if (Object.op_Implicit((Object)(object)target.Value.Root))
					{
						pending[target.Key] = target.Value.Root;
					}
				}
				targets.Clear();
				lastPlayer = null;
				materialsFailed = false;
			}
			if (!Object.op_Implicit((Object)(object)localPlayer) || !enabledMod.Value || materialsFailed)
			{
				if (active.Count > 0)
				{
					ClearEffects();
				}
				ClearDemonstration();
				if (!Object.op_Implicit((Object)(object)localPlayer) && Object.op_Implicit((Object)(object)lastPlayer))
				{
					targets.Clear();
					pending.Clear();
					lastPlayer = null;
				}
				return;
			}
			Appearance a = new Appearance
			{
				Density = density.Value,
				Radius = radius.Value,
				Height = height.Value,
				Brightness = brightness.Value,
				Speed = speed.Value,
				Dust = dust.Value,
				TrailLength = trailLength.Value,
				Twist = twist.Value,
				AreaGlow = areaGlow.Value,
				SpillIntensity = spillIntensity.Value,
				SpillRange = spillRange.Value,
				Night = ((variantMode.Value == "Night") ? 1f : ((variantMode.Value == "Day") ? 0f : (Object.op_Implicit((Object)(object)EnvMan.instance) ? EffectBehavior.Night(EnvMan.instance.GetDayFraction()) : 1f)))
			};
			Camera main = Camera.main;
			if (demonstration != null)
			{
				if (Time.time >= demonstrationUntil)
				{
					ClearDemonstration();
				}
				else
				{
					demonstration.Tick(demonstrationPosition, Time.time, a, 1f, main);
				}
			}
			if ((Object)(object)localPlayer != (Object)(object)lastPlayer)
			{
				lastPlayer = localPlayer;
				Type[] types = Types;
				for (int i = 0; i < types.Length; i++)
				{
					Object[] array = Object.FindObjectsByType(types[i], (FindObjectsSortMode)0);
					for (int j = 0; j < array.Length; j++)
					{
						Register((Component)array[j]);
					}
				}
				nextRefresh = 0f;
			}
			if (Time.unscaledTime >= nextRefresh)
			{
				nextRefresh = Time.unscaledTime + 0.6f;
				Refresh(((Component)localPlayer).transform.position);
			}
			foreach (KeyValuePair<int, MoteEffect> item in active)
			{
				TargetGroup targetGroup = groups[item.Key];
				if (!targetGroup.TryCenter(out var center))
				{
					item.Value.SetVisible(visible: false);
					continue;
				}
				try
				{
					item.Value.BindSources(targetGroup);
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)this).Logger.LogError((object)("Surface renderer unavailable; disabling effects safely: " + ex));
					materialsFailed = true;
					break;
				}
				item.Value.SetVisible(visible: true);
				float num = Vector3.Distance(((Component)localPlayer).transform.position, center);
				float fade = Mathf.Clamp01((range.Value - num) / Mathf.Min(10f, range.Value * 0.3f));
				item.Value.Tick(center, Time.time, a, fade, main);
			}
		}

		private void Refresh(Vector3 player)
		{
			//IL_0174: 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_017a: 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_02d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d8: Unknown result type (might be due to invalid IL or missing references)
			foreach (MoteEffect value2 in active.Values)
			{
				value2.DetachSources();
			}
			foreach (KeyValuePair<int, GameObject> item in pending)
			{
				if (!Object.op_Implicit((Object)(object)item.Value) || targets.ContainsKey(item.Key))
				{
					continue;
				}
				try
				{
					Target target = Target.Create(item.Value);
					if (target != null)
					{
						targets[item.Key] = target;
					}
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)this).Logger.LogDebug((object)("Skipped " + ((Object)item.Value).name + ": " + ex.Message));
				}
			}
			pending.Clear();
			near.Clear();
			dead.Clear();
			Vector3 val;
			foreach (KeyValuePair<int, Target> target2 in targets)
			{
				Target value = target2.Value;
				if (!Object.op_Implicit((Object)(object)value.Root))
				{
					dead.Add(target2.Key);
				}
				else
				{
					if (!value.Style.Enabled)
					{
						continue;
					}
					val = value.Center - player;
					value.Distance = ((Vector3)(ref val)).sqrMagnitude;
					if (value.Distance > range.Value * range.Value)
					{
						continue;
					}
					try
					{
						if (value.Available())
						{
							near.Add(value);
						}
					}
					catch (Exception ex2)
					{
						((BaseUnityPlugin)this).Logger.LogDebug((object)("Availability: " + ex2.Message));
					}
				}
			}
			List<Target> mergeable = near.Where((Target t) => !t.IsDeposit && !t.IsFruitTree).ToList();
			List<Clusterer.Point> points = mergeable.Select(delegate(Target t)
			{
				//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_0023: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				//IL_003d: Unknown result type (might be due to invalid IL or missing references)
				Vector3 center2 = t.Center;
				return new Clusterer.Point
				{
					Id = ((Object)t.Root).GetInstanceID(),
					X = center2.x,
					Y = center2.y,
					Z = center2.z
				};
			}).ToList();
			groups.Clear();
			foreach (List<int> item2 in Clusterer.Build(points, mergeDistance.Value))
			{
				TargetGroup targetGroup = new TargetGroup(item2.Select((int i) => mergeable[i]).ToList());
				if (targetGroup.TryCenter(out var center))
				{
					val = center - player;
					targetGroup.Distance = ((Vector3)(ref val)).sqrMagnitude;
					groups.Add(targetGroup.Id, targetGroup);
				}
			}
			foreach (Target item3 in near.Where((Target t) => t.IsDeposit || t.IsFruitTree))
			{
				TargetGroup targetGroup2 = new TargetGroup(new List<Target> { item3 })
				{
					Distance = item3.Distance
				};
				groups.Add(targetGroup2.Id, targetGroup2);
			}
			List<TargetGroup> list = (from g in groups.Values
				orderby g.Distance, g.Id
				select g).Take(maxEffects.Value).ToList();
			foreach (TargetGroup item4 in list)
			{
				item4.PrepareSurface();
			}
			int[] array = CoverageLayout.Allocate(list.Select(delegate(TargetGroup g)
			{
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				if (!g.HasLightBounds || !(g.Style.LightSpill > 0f))
				{
					return 0;
				}
				return (!g.IsFruitTree) ? SpillLayout.Requested(((Bounds)(ref g.LightBounds)).extents.x, ((Bounds)(ref g.LightBounds)).extents.z) : g.FruitLightPositions.Count;
			}).ToArray(), (spillIntensity.Value > 0f) ? maxSpillLights.Value : 0);
			for (int num = 0; num < list.Count; num++)
			{
				list[num].SpillBudget = array[num];
			}
			HashSet<int> chosen = new HashSet<int>(list.Select((TargetGroup g) => g.Id));
			int[] array2 = active.Keys.Where((int id) => !chosen.Contains(id) || activeStyles[id] != groups[id].Style.Id).ToArray();
			foreach (int key in array2)
			{
				active[key].Dispose();
				active.Remove(key);
				activeStyles.Remove(key);
			}
			foreach (int item5 in dead)
			{
				targets.Remove(item5);
			}
			foreach (int item6 in chosen)
			{
				if (!active.ContainsKey(item6))
				{
					try
					{
						active[item6] = new MoteEffect(groups[item6].Style, item6);
						activeStyles[item6] = groups[item6].Style.Id;
					}
					catch (Exception ex3)
					{
						((BaseUnityPlugin)this).Logger.LogError((object)("Particle renderer unavailable; disabling effects safely: " + ex3));
						materialsFailed = true;
						ClearEffects();
						break;
					}
				}
			}
			if (materialsFailed)
			{
				return;
			}
			try
			{
				foreach (KeyValuePair<int, MoteEffect> item7 in active)
				{
					item7.Value.BindSources(groups[item7.Key]);
				}
			}
			catch (Exception ex4)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Surface renderer unavailable; disabling effects safely: " + ex4));
				materialsFailed = true;
				ClearEffects();
			}
		}

		private void ClearEffects()
		{
			foreach (MoteEffect value in active.Values)
			{
				value.Dispose();
			}
			active.Clear();
			activeStyles.Clear();
			groups.Clear();
		}

		private void ClearDemonstration()
		{
			demonstration?.Dispose();
			demonstration = null;
			nextRefresh = 0f;
		}

		private void OnDestroy()
		{
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
			ClearEffects();
			ClearDemonstration();
			MoteEffect.ReleaseMaterials();
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}
	}
	internal static class SpillLayout
	{
		internal static int Requested(float x, float z)
		{
			if (!(Math.Max(x, z) > 2f))
			{
				return 1;
			}
			return 4;
		}

		internal static MoteMotion.Point Position(float x, float y, float z, int index, int count)
		{
			float num = Math.Max(0.65f, Math.Max(x, z) * 0.65f);
			if (count <= 1)
			{
				return new MoteMotion.Point(0f, y + num, 0f);
			}
			float x2 = (float)((index != 0 && index != 3) ? 1 : (-1)) * x * 0.5f;
			float z2 = (float)((index % 2 != 0) ? 1 : (-1)) * z * 0.5f;
			return new MoteMotion.Point(x2, y + num, z2);
		}

		internal static float Range(float x, float y, float z, float padding)
		{
			float num = Math.Max(0.65f, Math.Max(x, z) * 0.65f);
			float num2 = (float)Math.Sqrt(x * x * 2.25f + z * z * 2.25f + (2f * y + num) * (2f * y + num));
			return Math.Max(2f, num2 + padding);
		}

		internal static float Intensity(float amount, float night, int count)
		{
			if (count > 0)
			{
				return Math.Max(0f, Math.Min(2f, amount)) * (0.18f + 0.82f * night) / (float)count;
			}
			return 0f;
		}
	}
	internal static class StructureFilter
	{
		internal static bool Excluded(string name, bool buildingComponent, bool doorComponent, bool collectibleComponent)
		{
			if (name.Equals("lox_ribs", StringComparison.OrdinalIgnoreCase) || name.StartsWith("lox_ribs_", StringComparison.OrdinalIgnoreCase))
			{
				return true;
			}
			if (doorComponent)
			{
				return true;
			}
			string[] array = new string[11]
			{
				"goblin_roof", "goblin_woodwall", "goblin_fence", "goblin_pole", "goblin_stairs", "goblin_stepladder", "goblin_bed", "goblin_banner", "goblin_totempole", "goblin_strawpile",
				"goblin_trashpile"
			};
			foreach (string text in array)
			{
				if (name.Equals(text, StringComparison.OrdinalIgnoreCase) || name.StartsWith(text + "_", StringComparison.OrdinalIgnoreCase))
				{
					return true;
				}
			}
			if (collectibleComponent)
			{
				return false;
			}
			if (buildingComponent)
			{
				return true;
			}
			array = name.Split('_', '-', ' ');
			for (int i = 0; i < array.Length; i++)
			{
				switch (array[i].TrimEnd('0', '1', '2', '3', '4', '5', '6', '7', '8', '9').ToLowerInvariant())
				{
				case "roof":
				case "ruin":
				case "wall":
				case "beam":
				case "pole":
				case "door":
				case "gate":
				case "arch":
				case "irongate":
				case "woodwall":
				case "stair":
				case "ruins":
				case "floor":
				case "house":
				case "table":
				case "fence":
				case "chair":
				case "pillar":
				case "stairs":
				case "bridge":
				case "column":
				case "bed":
				case "hut":
				case "furniture":
					return true;
				}
			}
			return false;
		}
	}
	internal sealed class Style
	{
		public string Id;

		public string Label;

		public string Shape;

		public bool Enabled = true;

		public Color Color;

		public Color Accent;

		public float Radius;

		public float Height;

		public float SurfaceGlow = 1f;

		public float LightSpill = 1f;

		public Style Copy()
		{
			return (Style)MemberwiseClone();
		}
	}
	internal static class Styles
	{
		internal static readonly Dictionary<string, Style> ById = new Dictionary<string, Style>();

		private static readonly Dictionary<string, Style> Aliases = new Dictionary<string, Style>(StringComparer.OrdinalIgnoreCase);

		private static readonly Dictionary<string, Style> Automatic = new Dictionary<string, Style>(StringComparer.OrdinalIgnoreCase);

		internal static string Clean(string name)
		{
			return (name ?? "").Replace("(Clone)", "").Trim();
		}

		internal static void Load()
		{
			//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_005e: Unknown resu