Decompiled source of Enchanted String Lights v1.0.0

BepInEx/plugins/StringLights/StringLights.dll

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

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace DelGryphon.StringLights
{
	[BepInPlugin("delgryphon.stringlights", "Enchanted Crystal String Lights", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class StringLightsPlugin : BaseUnityPlugin
	{
		private class SubMesh
		{
			public string name;

			public Vector3[] verts;

			public int[] triangles;
		}

		private const string PieceName = "piece_StringLights";

		private static readonly string[] GemNames = new string[5] { "Uncut_Green_Stone", "Uncut_Purple_Stone", "Uncut_Yellow_Stone", "Uncut_Blue_Stone", "Uncut_Red_Stone" };

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

		private ConfigEntry<float> emission;

		private ConfigEntry<float> lightPower;

		private ConfigEntry<float> lightRange;

		private ConfigEntry<bool> pointLights;

		private ConfigEntry<bool> breathing;

		private ConfigEntry<bool> halos;

		private ConfigEntry<float> haloOpacity;

		private bool registered;

		private Texture2D haloTexture;

		private void Awake()
		{
			emission = ((BaseUnityPlugin)this).Config.Bind<float>("Cinematic Gems v0.6.5", "Core emission", 1.5f, "Saturated center glow; the ends remain dimmer.");
			lightPower = ((BaseUnityPlugin)this).Config.Bind<float>("Cinematic Gems v0.6.5", "Colored light strength", 2.4f, "Stronger individual colored light pools on the surrounding wood.");
			lightRange = ((BaseUnityPlugin)this).Config.Bind<float>("Cinematic Gems v0.6.5", "Colored light radius", 1.65f, "Smaller falloff reduces color mixing into pastel white.");
			pointLights = ((BaseUnityPlugin)this).Config.Bind<bool>("Cinematic Gems v0.6.5", "Enable physical illumination", true, "Disable to reduce rendering cost.");
			breathing = ((BaseUnityPlugin)this).Config.Bind<bool>("Cinematic Gems v0.6.5", "Gentle pulse and flicker", true, "Softly modulates the gems and their colored light.");
			halos = ((BaseUnityPlugin)this).Config.Bind<bool>("Cinematic Gems v0.6.5", "Enable crystal halos", true, "Subtle camera-facing additive glow around each crystal; requires a particle additive shader.");
			haloOpacity = ((BaseUnityPlugin)this).Config.Bind<float>("Cinematic Gems v0.6.5", "Crystal halo intensity", 0.32f, "Adjust the subtle additive halo intensity, 0 disables it.");
			PrefabManager.OnVanillaPrefabsAvailable += Register;
		}

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

		private void Register()
		{
			//IL_0275: Unknown result type (might be due to invalid IL or missing references)
			//IL_027c: Expected O, but got Unknown
			//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Expected O, but got Unknown
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			if (registered)
			{
				return;
			}
			try
			{
				string text = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "StringLights.model");
				if (!File.Exists(text))
				{
					throw new FileNotFoundException("StringLights.model must sit beside StringLights.dll", text);
				}
				List<SubMesh> list = ReadModel(text);
				if (list.Count < 20 || list.FindAll((SubMesh x) => x.name.StartsWith("Crystal_", StringComparison.Ordinal)).Count != 10)
				{
					throw new InvalidDataException("Expected ten independent crystal meshes");
				}
				string text2 = "piece_FairylightGarland";
				GameObject prefab = PrefabManager.Instance.GetPrefab(text2);
				if ((Object)(object)prefab == (Object)null)
				{
					text2 = "piece_CelebrationGarland";
					prefab = PrefabManager.Instance.GetPrefab(text2);
				}
				if ((Object)(object)prefab == (Object)null)
				{
					throw new InvalidOperationException("No Valheim garland base prefab available");
				}
				Piece component = prefab.GetComponent<Piece>();
				if ((Object)(object)component == (Object)null)
				{
					throw new InvalidOperationException("Base prefab lacks Piece component");
				}
				PieceConfig val = new PieceConfig();
				val.Name = "Enchanted Crystal String Lights";
				val.Description = "Handcrafted glowing uncut gemstones on braided copper wiring.";
				val.PieceTable = PieceTables.Hammer;
				val.CraftingStation = CraftingStations.Workbench;
				val.Category = PieceCategories.Furniture;
				val.Usage = new string[2]
				{
					PieceUsages.Lighting,
					PieceUsages.Decor
				};
				val.Enabled = true;
				string text3 = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "StringLights-icon.png");
				Sprite val2 = component.m_icon;
				if (File.Exists(text3))
				{
					try
					{
						Texture2D val3 = AssetUtils.LoadTexture(text3, false);
						if ((Object)(object)val3 != (Object)null)
						{
							val2 = Sprite.Create(val3, new Rect(0f, 0f, (float)((Texture)val3).width, (float)((Texture)val3).height), new Vector2(0.5f, 0.5f), 100f);
							((Object)val2).name = "EnchantedCrystalStringLightsIcon";
							((BaseUnityPlugin)this).Logger.LogInfo((object)"Custom Hammer icon loaded from StringLights-icon.png");
						}
						else
						{
							((BaseUnityPlugin)this).Logger.LogWarning((object)"Custom icon could not be loaded; using default Hammer icon.");
						}
					}
					catch (Exception ex)
					{
						((BaseUnityPlugin)this).Logger.LogWarning((object)("Custom icon unavailable: " + ex.Message));
					}
				}
				else
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)"StringLights-icon.png not found beside DLL");
				}
				val.Icon = val2;
				string[] gemNames = GemNames;
				foreach (string text4 in gemNames)
				{
					val.AddRequirement(text4, 2, true);
				}
				val.AddRequirement("Copper", 2, true);
				CustomPiece val4 = new CustomPiece("piece_StringLights", text2, val);
				if ((Object)(object)val4.PiecePrefab == (Object)null)
				{
					throw new Exception("Jotunn failed to clone base piece");
				}
				ApplyModel(val4.PiecePrefab, list);
				Piece component2 = val4.PiecePrefab.GetComponent<Piece>();
				if ((Object)(object)component2 == (Object)null)
				{
					throw new Exception("Custom lights have no Piece component");
				}
				component2.m_comfort = 2;
				component2.m_comfortGroup = (ComfortGroup)0;
				if (!PieceManager.Instance.AddPiece(val4))
				{
					throw new Exception("Jotunn rejected piece registration");
				}
				registered = true;
				PrefabManager.OnVanillaPrefabsAvailable -= Register;
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Enchanted StringLights v1.0.0 registered: 10 gems, jewelcrafting, saturated light spill, comfort +2");
			}
			catch (Exception ex2)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Enchanted StringLights registration FAILED: " + ex2));
			}
		}

		private static List<SubMesh> ReadModel(string path)
		{
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			List<SubMesh> list = new List<SubMesh>();
			using FileStream input = File.OpenRead(path);
			using BinaryReader binaryReader = new BinaryReader(input);
			if (Encoding.ASCII.GetString(binaryReader.ReadBytes(4)) != "SLM2")
			{
				throw new InvalidDataException("Invalid model signature");
			}
			int num = (int)binaryReader.ReadUInt32();
			if (num < 10 || num > 150)
			{
				throw new InvalidDataException("Invalid model mesh count");
			}
			for (int i = 0; i < num; i++)
			{
				int num2 = binaryReader.ReadUInt16();
				if (num2 < 1 || num2 > 200)
				{
					throw new InvalidDataException("Invalid mesh name length");
				}
				string text = Encoding.UTF8.GetString(binaryReader.ReadBytes(num2));
				int num3 = (int)binaryReader.ReadUInt32();
				int num4 = (int)binaryReader.ReadUInt32();
				if (num3 < 3 || num3 > 65000 || num4 < 3 || num4 > 180000 || num4 % 3 != 0)
				{
					throw new InvalidDataException("Invalid model mesh sizes " + text);
				}
				Vector3[] array = (Vector3[])(object)new Vector3[num3];
				int[] array2 = new int[num4];
				for (int j = 0; j < num3; j++)
				{
					array[j] = new Vector3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle());
				}
				for (int k = 0; k < num4; k++)
				{
					array2[k] = binaryReader.ReadInt32();
					if (array2[k] < 0 || array2[k] >= num3)
					{
						throw new InvalidDataException("Invalid index in " + text);
					}
				}
				list.Add(new SubMesh
				{
					name = text,
					verts = array,
					triangles = array2
				});
			}
			return list;
		}

		private void ApplyModel(GameObject prefab, List<SubMesh> meshes)
		{
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Expected O, but got Unknown
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Expected O, but got Unknown
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Expected O, but got Unknown
			//IL_030e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0313: 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_0344: Unknown result type (might be due to invalid IL or missing references)
			//IL_0349: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: 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_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: 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_025c: 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_02a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04de: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_051b: Unknown result type (might be due to invalid IL or missing references)
			//IL_042b: Unknown result type (might be due to invalid IL or missing references)
			//IL_064b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0650: Unknown result type (might be due to invalid IL or missing references)
			//IL_06b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_06d0: Unknown result type (might be due to invalid IL or missing references)
			Renderer[] componentsInChildren = prefab.GetComponentsInChildren<Renderer>(true);
			Collider[] componentsInChildren2 = prefab.GetComponentsInChildren<Collider>(true);
			Light[] componentsInChildren3 = prefab.GetComponentsInChildren<Light>(true);
			ParticleSystem[] componentsInChildren4 = prefab.GetComponentsInChildren<ParticleSystem>(true);
			Shader val = Shader.Find("Standard");
			if ((Object)(object)val == (Object)null)
			{
				val = Shader.Find("Unlit/Color");
			}
			if ((Object)(object)val == (Object)null && componentsInChildren.Length != 0 && (Object)(object)componentsInChildren[0].sharedMaterial != (Object)null)
			{
				val = componentsInChildren[0].sharedMaterial.shader;
			}
			if ((Object)(object)val == (Object)null)
			{
				throw new Exception("No available Unity shader");
			}
			GameObject val2 = new GameObject("StringLights_Tinkercad_Visuals");
			val2.transform.SetParent(prefab.transform, false);
			val2.layer = prefab.layer;
			Dictionary<int, Vector3> dictionary = new Dictionary<int, Vector3>();
			Dictionary<int, GemLightPulse> dictionary2 = new Dictionary<int, GemLightPulse>();
			try
			{
				foreach (SubMesh mesh in meshes)
				{
					GameObject val3 = new GameObject(mesh.name);
					val3.layer = prefab.layer;
					val3.transform.SetParent(val2.transform, false);
					MeshFilter val4 = val3.AddComponent<MeshFilter>();
					MeshRenderer val5 = val3.AddComponent<MeshRenderer>();
					Mesh val6 = new Mesh();
					((Object)val6).name = mesh.name;
					val6.vertices = mesh.verts;
					val6.triangles = mesh.triangles;
					int num = CrystalId(mesh.name);
					if (num > 0)
					{
						float num2 = float.MaxValue;
						float num3 = float.MinValue;
						Vector3[] verts = mesh.verts;
						foreach (Vector3 val7 in verts)
						{
							if (val7.y < num2)
							{
								num2 = val7.y;
							}
							if (val7.y > num3)
							{
								num3 = val7.y;
							}
						}
						float num4 = Mathf.Max(0.001f, num3 - num2);
						Vector3 val8 = Vector3.zero;
						verts = mesh.verts;
						foreach (Vector3 val9 in verts)
						{
							val8 += val9;
						}
						val8 /= (float)mesh.verts.Length;
						Vector2[] array = (Vector2[])(object)new Vector2[mesh.verts.Length];
						for (int j = 0; j < array.Length; j++)
						{
							float num5 = (Mathf.Atan2(mesh.verts[j].z - val8.z, mesh.verts[j].x - val8.x) + (float)Math.PI) / ((float)Math.PI * 2f);
							float num6 = Mathf.Clamp01((mesh.verts[j].y - num2) / num4);
							array[j] = new Vector2(num5, num6);
						}
						val6.uv = array;
					}
					((Renderer)val5).sharedMaterial = MaterialFor(mesh.name, val);
					val6.RecalculateNormals();
					val6.RecalculateBounds();
					val4.sharedMesh = val6;
					((Renderer)val5).shadowCastingMode = (ShadowCastingMode)0;
					((Renderer)val5).receiveShadows = false;
					if (num > 0)
					{
						Bounds bounds = val6.bounds;
						dictionary[num] = ((Bounds)(ref bounds)).center;
						if (breathing.Value)
						{
							GemLightPulse gemLightPulse = val3.AddComponent<GemLightPulse>();
							gemLightPulse.CrystalRenderer = (Renderer)(object)val5;
							gemLightPulse.EmissionColor = GemEmission(num);
							gemLightPulse.EmissionPower = Mathf.Clamp(emission.Value, 0f, 3f);
							gemLightPulse.Phase = (float)num * 0.79f;
							dictionary2[num] = gemLightPulse;
						}
					}
				}
				if (dictionary.Count != 10)
				{
					throw new Exception("Crystal centers incomplete");
				}
				if (halos.Value && haloOpacity.Value > 0.001f)
				{
					Shader val10 = Shader.Find("Particles/Additive");
					if ((Object)(object)val10 == (Object)null)
					{
						val10 = Shader.Find("Legacy Shaders/Particles/Additive");
					}
					if ((Object)(object)val10 != (Object)null)
					{
						foreach (KeyValuePair<int, Vector3> item in dictionary)
						{
							GemHaloBillboard gemHaloBillboard = AddHalo(val2.transform, item.Value, item.Key, val10);
							if ((Object)(object)gemHaloBillboard != (Object)null && dictionary2.ContainsKey(item.Key))
							{
								dictionary2[item.Key].Halo = gemHaloBillboard;
							}
						}
					}
					else
					{
						((BaseUnityPlugin)this).Logger.LogWarning((object)"Additive particle shader unavailable; skipping halos while retaining crystals and point lights.");
					}
				}
				if (pointLights.Value)
				{
					foreach (KeyValuePair<int, Vector3> item2 in dictionary)
					{
						GameObject val11 = new GameObject("CrystalPointLight_" + item2.Key);
						val11.transform.SetParent(val2.transform, false);
						val11.transform.localPosition = item2.Value;
						Light val12 = val11.AddComponent<Light>();
						val12.type = (LightType)2;
						val12.color = LightColorFor(item2.Key);
						val12.intensity = Mathf.Clamp(lightPower.Value, 0f, 3f);
						val12.range = Mathf.Clamp(lightRange.Value, 0.2f, 5f);
						val12.shadows = (LightShadows)0;
						val12.renderMode = (LightRenderMode)1;
						if (breathing.Value && dictionary2.ContainsKey(item2.Key))
						{
							GemLightPulse gemLightPulse2 = dictionary2[item2.Key];
							gemLightPulse2.Source = val12;
							gemLightPulse2.BaseIntensity = val12.intensity;
						}
					}
				}
				Renderer[] array2 = componentsInChildren;
				foreach (Renderer val13 in array2)
				{
					if ((Object)(object)val13 != (Object)null)
					{
						val13.enabled = false;
					}
				}
				Light[] array3 = componentsInChildren3;
				foreach (Light val14 in array3)
				{
					if ((Object)(object)val14 != (Object)null)
					{
						((Behaviour)val14).enabled = false;
					}
				}
				ParticleSystem[] array4 = componentsInChildren4;
				foreach (ParticleSystem val15 in array4)
				{
					if ((Object)(object)val15 != (Object)null)
					{
						EmissionModule val16 = val15.emission;
						((EmissionModule)(ref val16)).enabled = false;
						val15.Stop(true, (ParticleSystemStopBehavior)0);
					}
				}
				Collider[] array5 = componentsInChildren2;
				foreach (Collider val17 in array5)
				{
					if ((Object)(object)val17 != (Object)null)
					{
						val17.enabled = false;
					}
				}
				BoxCollider obj = prefab.AddComponent<BoxCollider>();
				obj.center = new Vector3(0f, -0.46f, 0f);
				obj.size = new Vector3(4.04f, 0.99f, 0.15f);
				((Collider)obj).isTrigger = false;
			}
			catch
			{
				Object.Destroy((Object)(object)val2);
				throw;
			}
		}

		private static int CrystalId(string name)
		{
			if (!name.StartsWith("Crystal_", StringComparison.Ordinal) || name.Length < 10)
			{
				return -1;
			}
			if (int.TryParse(name.Substring(8, 2), NumberStyles.None, CultureInfo.InvariantCulture, out var result) && result >= 1 && result <= 10)
			{
				return result;
			}
			return -1;
		}

		private static Color LightColorFor(int id)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			return (Color)(((id - 1) % 5) switch
			{
				0 => new Color(0.08f, 0.86f, 0.22f), 
				1 => new Color(0.58f, 0.13f, 0.92f), 
				2 => new Color(1f, 0.64f, 0.013f), 
				3 => new Color(0.08f, 0.36f, 1f), 
				_ => new Color(1f, 0.008f, 0.014f), 
			});
		}

		private static Color GemTint(int id)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			return (Color)(((id - 1) % 5) switch
			{
				0 => new Color(0.025f, 0.35f, 0.09f), 
				1 => new Color(0.22f, 0.037f, 0.34f), 
				2 => new Color(0.49f, 0.39f, 0.014f), 
				3 => new Color(0.025f, 0.12f, 0.42f), 
				_ => new Color(0.35f, 0.002f, 0.012f), 
			});
		}

		private static Color GemEmission(int id)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			return (Color)(((id - 1) % 5) switch
			{
				0 => new Color(0.04f, 0.8f, 0.12f), 
				1 => new Color(0.52f, 0.07f, 0.92f), 
				2 => new Color(0.98f, 0.78f, 0.018f), 
				3 => new Color(0.035f, 0.35f, 0.98f), 
				_ => new Color(0.9f, 0.002f, 0.009f), 
			});
		}

		private static Texture2D GradientTexture(bool emissive)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(64, 128, (TextureFormat)4, false, true);
			((Object)val).name = (emissive ? "StringLights_CrystalEmissionGradient" : "StringLights_CrystalAlbedoGradient");
			((Texture)val).wrapMode = (TextureWrapMode)1;
			((Texture)val).filterMode = (FilterMode)1;
			Color[] array = (Color[])(object)new Color[8192];
			for (int i = 0; i < 128; i++)
			{
				float num = (float)i / 127f;
				float num2 = Mathf.Clamp01(1f - Mathf.Abs(num - 0.48f) / 0.54f);
				float num3 = Mathf.Pow(Mathf.SmoothStep(0f, 1f, num2), 1.55f);
				for (int j = 0; j < 64; j++)
				{
					float num4 = (float)j / 63f;
					float num5 = 0.84f + 0.16f * Mathf.Pow(Mathf.Abs(Mathf.Sin(num4 * 17f + 1.2f)), 4f);
					float num6 = (emissive ? ((0.025f + 0.975f * num3) * num5) : ((0.25f + 0.53f * num3) * num5));
					array[i * 64 + j] = new Color(num6, num6, num6, 1f);
				}
			}
			val.SetPixels(array);
			val.Apply(false, true);
			return val;
		}

		private Texture2D RadialGlowTexture()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)haloTexture != (Object)null)
			{
				return haloTexture;
			}
			Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false, true);
			((Object)val).name = "StringLights_SoftRadialHalo";
			((Texture)val).wrapMode = (TextureWrapMode)1;
			((Texture)val).filterMode = (FilterMode)1;
			for (int i = 0; i < 64; i++)
			{
				for (int j = 0; j < 64; j++)
				{
					float num = ((float)j + 0.5f - 32f) / 32f;
					float num2 = ((float)i + 0.5f - 32f) / 32f;
					float num3 = Mathf.Sqrt(num * num + num2 * num2);
					float num4 = Mathf.Clamp01(1f - num3);
					float num5 = num4 * num4 * num4;
					val.SetPixel(j, i, new Color(1f, 1f, 1f, num5));
				}
			}
			val.Apply(false, true);
			haloTexture = val;
			return val;
		}

		private GemHaloBillboard AddHalo(Transform root, Vector3 pos, int id, Shader shader)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			//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_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: 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_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Expected O, but got Unknown
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Clamp01(haloOpacity.Value);
			if (num < 0.001f)
			{
				return null;
			}
			GameObject val = new GameObject("StringLights_CrystalHalo_" + id);
			val.layer = ((Component)root).gameObject.layer;
			val.transform.SetParent(root, false);
			val.transform.localPosition = pos;
			MeshFilter val2 = val.AddComponent<MeshFilter>();
			MeshRenderer val3 = val.AddComponent<MeshRenderer>();
			Mesh val4 = new Mesh();
			((Object)val4).name = "StringLights_CrystalHaloQuad";
			val4.vertices = (Vector3[])(object)new Vector3[4]
			{
				new Vector3(-0.18f, -0.21f, 0f),
				new Vector3(0.18f, -0.21f, 0f),
				new Vector3(0.18f, 0.21f, 0f),
				new Vector3(-0.18f, 0.21f, 0f)
			};
			val4.uv = (Vector2[])(object)new Vector2[4]
			{
				new Vector2(0f, 0f),
				new Vector2(1f, 0f),
				new Vector2(1f, 1f),
				new Vector2(0f, 1f)
			};
			val4.triangles = new int[6] { 0, 1, 2, 0, 2, 3 };
			val4.RecalculateBounds();
			val2.sharedMesh = val4;
			Material val5 = new Material(shader);
			((Object)val5).name = "StringLights_GlowHalo_" + id;
			if (val5.HasProperty("_MainTex"))
			{
				val5.SetTexture("_MainTex", (Texture)(object)RadialGlowTexture());
			}
			Color val6 = LightColorFor(id);
			if (val5.HasProperty("_TintColor"))
			{
				val5.SetColor("_TintColor", new Color(val6.r, val6.g, val6.b, num));
			}
			else if (val5.HasProperty("_Color"))
			{
				val5.SetColor("_Color", new Color(val6.r, val6.g, val6.b, num));
			}
			((Renderer)val3).sharedMaterial = val5;
			((Renderer)val3).shadowCastingMode = (ShadowCastingMode)0;
			((Renderer)val3).receiveShadows = false;
			return val.AddComponent<GemHaloBillboard>();
		}

		private Material MaterialFor(string name, Shader shader)
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: 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_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			int num = CrystalId(name);
			string text = ((num > 0) ? ("GemGradient" + (num - 1) % 5) : (name.StartsWith("Copper_Strand") ? "Copper" : (name.StartsWith("Wire_Wrap") ? "Wrap" : "Hemp")));
			if (materials.TryGetValue(text, out var value))
			{
				return value;
			}
			value = new Material(shader);
			((Object)value).name = "StringLights_" + text;
			Color val = (value.color = (Color)((num > 0) ? GemTint(num) : ((text == "Copper") ? new Color(0.26f, 0.15f, 0.075f) : ((text == "Wrap") ? new Color(0.55f, 0.28f, 0.12f) : new Color(0.32f, 0.22f, 0.13f)))));
			if (value.HasProperty("_Color"))
			{
				value.SetColor("_Color", val);
			}
			if (value.HasProperty("_Metallic"))
			{
				value.SetFloat("_Metallic", (num > 0) ? 0f : 0.3f);
			}
			if (value.HasProperty("_Glossiness"))
			{
				value.SetFloat("_Glossiness", (num > 0) ? 0.12f : 0.19f);
			}
			if (num > 0)
			{
				if (value.HasProperty("_MainTex"))
				{
					value.SetTexture("_MainTex", (Texture)(object)GradientTexture(emissive: false));
				}
				if (value.HasProperty("_EmissionColor"))
				{
					value.EnableKeyword("_EMISSION");
					value.SetColor("_EmissionColor", GemEmission(num) * Mathf.Clamp(emission.Value, 0f, 3f));
					if (value.HasProperty("_EmissionMap"))
					{
						value.SetTexture("_EmissionMap", (Texture)(object)GradientTexture(emissive: true));
					}
				}
			}
			materials[text] = value;
			return value;
		}
	}
	public sealed class GemHaloBillboard : MonoBehaviour
	{
		private float pulse = 1f;

		public void SetPulse(float p)
		{
			pulse = p;
		}

		private void LateUpdate()
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			Camera main = Camera.main;
			if ((Object)(object)main != (Object)null)
			{
				((Component)this).transform.rotation = ((Component)main).transform.rotation;
			}
			((Component)this).transform.localScale = Vector3.one * (0.92f + 0.08f * pulse);
		}
	}
	public sealed class GemLightPulse : MonoBehaviour
	{
		public Light Source;

		public GemHaloBillboard Halo;

		public Renderer CrystalRenderer;

		public Color EmissionColor;

		public float EmissionPower;

		public float BaseIntensity;

		public float Phase;

		private MaterialPropertyBlock crystalBlock;

		private void Awake()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			crystalBlock = new MaterialPropertyBlock();
		}

		private void Update()
		{
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Expected O, but got Unknown
			float time = Time.time;
			float num = 0.085f * Mathf.Sin(time * 1.3f + Phase);
			float num2 = 0.022f * Mathf.Sin(time * 2.7f + Phase * 1.73f);
			float num3 = 0.018f * Mathf.Max(0f, Mathf.Sin(time * 9.4f + Phase * 2.8f)) * Mathf.Max(0f, Mathf.Sin(time * 0.44f + Phase * 1.3f));
			float num4 = Mathf.Clamp(1f + num + num2 + num3, 0.86f, 1.14f);
			if ((Object)(object)Source != (Object)null)
			{
				Source.intensity = BaseIntensity * num4;
			}
			if ((Object)(object)Halo != (Object)null)
			{
				Halo.SetPulse(num4);
			}
			if (!((Object)(object)CrystalRenderer == (Object)null))
			{
				if (crystalBlock == null)
				{
					crystalBlock = new MaterialPropertyBlock();
				}
				crystalBlock.SetColor("_EmissionColor", EmissionColor * EmissionPower * num4);
				CrystalRenderer.SetPropertyBlock(crystalBlock);
			}
		}
	}
}