Decompiled source of LightUpYourWorld v1.3.0

BepInEx/plugins/LightUpYourWorld/LightUpYourWorld.dll

Decompiled 3 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyFileVersion("0.1.12.0")]
[assembly: AssemblyVersion("0.1.12.0")]
namespace LightUpYourWorld;

[BepInPlugin("valheim.lightupyourworld", "LightUpYourWorld", "0.1.12")]
public sealed class LightUpYourWorldPlugin : BaseUnityPlugin
{
	internal const string PluginId = "valheim.lightupyourworld";

	internal static LightUpYourWorldPlugin Instance;

	private Harmony harmony;

	private ConfigEntry<KeyCode> openKey;

	private WorldLight target;

	private readonly ColourSession session = new ColourSession();

	private bool visible;

	private bool captured;

	private bool previousVisible;

	private bool previousRequested;

	private bool wheelDragging;

	private CursorLockMode previousLock;

	private float hue;

	private float saturation;

	private float brightness;

	private float acceptAfter;

	private float blockUntil;

	private string targetName;

	private string message = "";

	private Texture2D wheel;

	private GUIStyle title;

	private GUIStyle heading;

	private GUIStyle body;

	private GUIStyle button;

	private GUIStyle centered;

	private GUIStyle small;

	private bool flameChannel;

	private bool favouritesMode;

	private int favouriteSlot;

	private int favouriteDirection;

	private float favouriteRepeat;

	private string cachedPrompt;

	private bool promptController;

	private KeyCode promptKey;

	private float nextPromptBindings;

	private static readonly MethodInfo TakeInputMethod = AccessTools.Method(typeof(Player), "TakeInput", (Type[])null, (Type[])null);

	private bool controller => ZInput.IsGamepadActive();

	internal bool IsOpen => visible;

	internal bool BlocksGameplay
	{
		get
		{
			if (!visible)
			{
				return Time.unscaledTime < blockUntil;
			}
			return true;
		}
	}

	private int ChannelSaved
	{
		get
		{
			if (!flameChannel)
			{
				return target.Saved;
			}
			return target.SavedFlame;
		}
	}

	private string ChannelName
	{
		get
		{
			if (!flameChannel)
			{
				return "Glow";
			}
			return "Flame";
		}
	}

	internal string HoverPrompt
	{
		get
		{
			//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_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			bool flag = controller;
			if (cachedPrompt != null && flag == promptController && promptKey == openKey.Value && (!flag || Time.unscaledTime < nextPromptBindings))
			{
				return cachedPrompt;
			}
			promptController = flag;
			promptKey = openKey.Value;
			nextPromptBindings = Time.unscaledTime + 1f;
			if (!flag)
			{
				return cachedPrompt = "[<color=yellow><b>" + ((object)openKey.Value/*cast due to .constrained prefix*/).ToString() + "</b></color>] Change light colour";
			}
			string binding = ((ZInput.instance != null) ? ZInput.instance.GetBoundKeyString("JoyLBumper", true) : "");
			string binding2 = ((ZInput.instance != null) ? ZInput.instance.GetBoundKeyString("JoyUse", true) : "");
			return cachedPrompt = NativeBinding(binding, "LB") + " + " + NativeBinding(binding2, "Interact") + " Change light colour";
		}
	}

	private static string NativeBinding(string binding, string fallback)
	{
		if (string.IsNullOrEmpty(binding))
		{
			binding = fallback;
		}
		if (!binding.Contains("<sprite="))
		{
			return "[<color=yellow><b>" + Localize(binding) + "</b></color>]";
		}
		return binding;
	}

	internal static bool CanTakeInput(Player player)
	{
		if (Object.op_Implicit((Object)(object)player) && TakeInputMethod != null)
		{
			return (bool)TakeInputMethod.Invoke(player, null);
		}
		return false;
	}

	internal static string Localize(string key)
	{
		try
		{
			Type type = AccessTools.TypeByName("Localization");
			PropertyInfo propertyInfo = ((type != null) ? type.GetProperty("instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) : null);
			object obj = ((propertyInfo != null) ? propertyInfo.GetValue(null, null) : null);
			MethodInfo methodInfo = ((type != null) ? type.GetMethod("Localize", new Type[1] { typeof(string) }) : null);
			return (obj != null && methodInfo != null) ? ((string)methodInfo.Invoke(obj, new object[1] { key })) : key;
		}
		catch
		{
			return key;
		}
	}

	private void Awake()
	{
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Expected O, but got Unknown
		Instance = this;
		openKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "OpenColourMenu", (KeyCode)103, "Look at a placed torch, lamp or campfire and press this key. Controller: hold LB and press your normal Interact button.");
		harmony = new Harmony("valheim.lightupyourworld");
		harmony.PatchAll(typeof(LightUpYourWorldPlugin).Assembly);
		CreateWheel();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"LightUpYourWorld 0.1.12 loaded. G / LB+Interact changes a placed light. No Dye Your Gear dependency.");
	}

	private void OnDestroy()
	{
		Close();
		foreach (WorldLight source in WorldLight.Sources)
		{
			if (Object.op_Implicit((Object)(object)source))
			{
				source.RestoreForUnload();
			}
		}
		if (harmony != null)
		{
			harmony.UnpatchSelf();
		}
		if (Object.op_Implicit((Object)(object)wheel))
		{
			Object.Destroy((Object)(object)wheel);
		}
		Instance = null;
	}

	private void OnDisable()
	{
		Close();
	}

	private void Update()
	{
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: 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_02af: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_02db: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0311: Unknown result type (might be due to invalid IL or missing references)
		//IL_0318: Unknown result type (might be due to invalid IL or missing references)
		Player localPlayer = Player.m_localPlayer;
		if (!visible)
		{
			if (Object.op_Implicit((Object)(object)localPlayer) && Input.GetKeyDown(openKey.Value) && !BlocksGameplay && CanTakeInput(localPlayer) && !((Character)localPlayer).InPlaceMode())
			{
				Open(WorldLight.Find(((Humanoid)localPlayer).GetHoverObject()));
			}
		}
		else if (!Object.op_Implicit((Object)(object)localPlayer) || !Object.op_Implicit((Object)(object)target) || !target.Ready || ((Character)localPlayer).IsDead() || ((Character)localPlayer).IsTeleporting() || Vector3.Distance(((Component)localPlayer).transform.position, ((Component)target).transform.position) > 8f || Menu.IsVisible() || InventoryGui.IsVisible() || TextInput.IsVisible() || Console.IsVisible() || (Object.op_Implicit((Object)(object)Chat.instance) && Chat.instance.HasFocus()) || Input.GetKeyDown((KeyCode)27) || ZInput.GetButtonDown("JoyMenu"))
		{
			Close();
		}
		else
		{
			if (Time.unscaledTime < acceptAfter)
			{
				return;
			}
			if (ZInput.GetButtonDown("JoyButtonB"))
			{
				ZInput.ResetButtonStatus("JoyButtonB");
				if (favouritesMode)
				{
					favouritesMode = false;
				}
				else if (session.Dirty)
				{
					CancelPreview();
				}
				else
				{
					Close();
				}
				return;
			}
			if (Input.GetKeyDown((KeyCode)9))
			{
				favouritesMode = !favouritesMode;
			}
			if (ZInput.GetButtonDown("JoyButtonY"))
			{
				ZInput.ResetButtonStatus("JoyButtonY");
				if (favouritesMode)
				{
					SaveFavourite();
				}
				else
				{
					favouritesMode = true;
				}
			}
			if (Input.GetKeyDown((KeyCode)102))
			{
				SaveFavourite();
			}
			if (favouritesMode)
			{
				UpdateFavourites();
				ConsumeDirections();
				return;
			}
			if (Input.GetKeyDown((KeyCode)99) || ZInput.GetButtonDown("JoyDPadLeft") || ZInput.GetButtonDown("JoyDPadRight") || ZInput.GetButtonDown("JoyHotbarLeft") || ZInput.GetButtonDown("JoyHotbarRight"))
			{
				SwitchChannel(!flameChannel);
			}
			float num = ZInput.GetJoyRightStickX();
			float num2 = ZInput.GetJoyRightStickY();
			if (Input.GetKey((KeyCode)276))
			{
				num = -1f;
			}
			if (Input.GetKey((KeyCode)275))
			{
				num = 1f;
			}
			if (Input.GetKey((KeyCode)273))
			{
				num2 = -1f;
			}
			if (Input.GetKey((KeyCode)274))
			{
				num2 = 1f;
			}
			if (Mathf.Abs(num) > 0.25f || Mathf.Abs(num2) > 0.25f)
			{
				Vector2 val = new Vector2(Mathf.Cos(hue * 2f * MathF.PI), 0f - Mathf.Sin(hue * 2f * MathF.PI)) * saturation;
				val += new Vector2(num, num2) * Mathf.Min(Time.unscaledDeltaTime, 0.05f) * 0.9f;
				if (((Vector2)(ref val)).sqrMagnitude > 1f)
				{
					((Vector2)(ref val)).Normalize();
				}
				saturation = ((Vector2)(ref val)).magnitude;
				if (saturation > 0.001f)
				{
					hue = Mathf.Repeat(Mathf.Atan2(0f - val.y, val.x) / (MathF.PI * 2f), 1f);
				}
				Preview();
			}
			if (ZInput.GetButtonDown("JoyLBumper") || Input.GetKeyDown((KeyCode)45) || Input.GetKeyDown((KeyCode)269))
			{
				brightness = Mathf.Clamp01(brightness - 0.05f);
				Preview();
			}
			if (ZInput.GetButtonDown("JoyRBumper") || Input.GetKeyDown((KeyCode)61) || Input.GetKeyDown((KeyCode)270))
			{
				brightness = Mathf.Clamp01(brightness + 0.05f);
				Preview();
			}
			if (Input.GetKeyDown((KeyCode)13) || Input.GetKeyDown((KeyCode)271) || ZInput.GetButtonDown("JoyButtonA"))
			{
				Apply();
				ZInput.ResetButtonStatus("JoyButtonA");
				ZInput.ResetButtonStatus("JoyUse");
			}
			if (Input.GetKeyDown((KeyCode)127) || ZInput.GetButtonDown("JoyButtonX"))
			{
				RestoreDefault();
				ZInput.ResetButtonStatus("JoyButtonX");
			}
			ConsumeDirections();
		}
	}

	private static void ConsumeDirections()
	{
		string[] array = new string[7] { "JoyDPadLeft", "JoyDPadRight", "JoyDPadUp", "JoyDPadDown", "JoyHotbarLeft", "JoyHotbarRight", "JoyHotbarUse" };
		for (int i = 0; i < array.Length; i++)
		{
			ZInput.ResetButtonStatus(array[i]);
		}
	}

	private void UpdateFavourites()
	{
		float joyLeftStickX = ZInput.GetJoyLeftStickX();
		float joyLeftStickY = ZInput.GetJoyLeftStickY();
		int num = ((Mathf.Max(Mathf.Abs(joyLeftStickX), Mathf.Abs(joyLeftStickY)) > 0.5f) ? ((!(Mathf.Abs(joyLeftStickX) > Mathf.Abs(joyLeftStickY))) ? ((joyLeftStickY < 0f) ? (-2) : 2) : ((!(joyLeftStickX < 0f)) ? 1 : (-1))) : 0);
		int num2 = 0;
		if (Input.GetKeyDown((KeyCode)276) || ZInput.GetButtonDown("JoyDPadLeft"))
		{
			num2 = -1;
		}
		else if (Input.GetKeyDown((KeyCode)275) || ZInput.GetButtonDown("JoyDPadRight"))
		{
			num2 = 1;
		}
		else if (Input.GetKeyDown((KeyCode)273) || ZInput.GetButtonDown("JoyDPadUp"))
		{
			num2 = -2;
		}
		else if (Input.GetKeyDown((KeyCode)274) || ZInput.GetButtonDown("JoyDPadDown"))
		{
			num2 = 2;
		}
		if (num2 != 0)
		{
			favouriteSlot = (favouriteSlot + num2 + 10) % 10;
		}
		else if (num != 0 && (num != favouriteDirection || Time.unscaledTime >= favouriteRepeat))
		{
			favouriteSlot = (favouriteSlot + num + 10) % 10;
			favouriteRepeat = Time.unscaledTime + ((num != favouriteDirection) ? 0.4f : 0.18f);
		}
		favouriteDirection = num;
		if (ZInput.GetButtonDown("JoyButtonA") || Input.GetKeyDown((KeyCode)13))
		{
			PreviewFavourite();
			ZInput.ResetButtonStatus("JoyButtonA");
			ZInput.ResetButtonStatus("JoyUse");
		}
		if (ZInput.GetButtonDown("JoyButtonX") || Input.GetKeyDown((KeyCode)127))
		{
			RemoveFavourite();
			ZInput.ResetButtonStatus("JoyButtonX");
		}
	}

	private void PreviewFavourite()
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		if (!LightFavourites.TryGet(Player.m_localPlayer, favouriteSlot, out var colour))
		{
			message = "Empty slot. Save your current colour first.";
			return;
		}
		Color.RGBToHSV(colour, ref hue, ref saturation, ref brightness);
		Preview();
		favouritesMode = false;
		message = "Favourite " + (favouriteSlot + 1) + " previewed. Apply to save on this light.";
	}

	private void SaveFavourite()
	{
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		LightFavourites.Set(Player.m_localPlayer, favouriteSlot, Color.HSVToRGB(hue, saturation, brightness));
		message = "Colour saved in favourite " + (favouriteSlot + 1) + ".";
	}

	private void RemoveFavourite()
	{
		LightFavourites.Remove(Player.m_localPlayer, favouriteSlot);
		message = "Favourite " + (favouriteSlot + 1) + " cleared. Light colour unchanged.";
	}

	private void LateUpdate()
	{
		foreach (WorldLight source in WorldLight.Sources)
		{
			if (Object.op_Implicit((Object)(object)source))
			{
				source.Tick();
			}
		}
		KeepCursor();
	}

	internal void Open(WorldLight source)
	{
		//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)
		if (!visible && Object.op_Implicit((Object)(object)source))
		{
			if (!source.CanEdit(Player.m_localPlayer, flash: true))
			{
				((Character)Player.m_localPlayer).Message((MessageType)2, "You cannot change this light here.", 0, (Sprite)null, false);
				return;
			}
			target = source;
			target.RefreshLights();
			targetName = source.DisplayName;
			flameChannel = false;
			session.Open(source.Saved);
			LoadWheel();
			message = "";
			favouritesMode = false;
			favouriteSlot = LightFavourites.FirstEmpty(Player.m_localPlayer);
			favouriteDirection = 0;
			visible = true;
			wheelDragging = false;
			acceptAfter = Time.unscaledTime + 0.3f;
			previousLock = Cursor.lockState;
			previousVisible = Cursor.visible;
			previousRequested = ZCursor.IsRequested;
			captured = true;
			ZInput.ResetButtonStatus("JoyUse");
			ZInput.ResetButtonStatus("JoyButtonA");
			ZInput.ResetButtonStatus("JoyButtonX");
			KeepCursor();
		}
	}

	private void SwitchChannel(bool flame)
	{
		if (flame != flameChannel)
		{
			if (flame && !target.HasFlame)
			{
				message = "No supported flame effect on this light.";
				return;
			}
			if (session.Dirty)
			{
				message = "Apply or cancel this preview before switching.";
				return;
			}
			target.EndPreview();
			flameChannel = flame;
			session.Open(ChannelSaved);
			LoadWheel();
			message = ChannelName + " selected. C / D-pad left or right switches channel.";
		}
	}

	private void LoadWheel()
	{
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		Color.RGBToHSV((session.Saved != 0) ? WorldLight.Unpack(session.Saved) : (flameChannel ? target.OriginalFlameColour : target.OriginalColour), ref hue, ref saturation, ref brightness);
		brightness = Mathf.Clamp01(brightness);
	}

	private void Preview()
	{
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		int num = WorldLight.Pack(Color.HSVToRGB(hue, saturation, brightness));
		session.Preview(num);
		if (flameChannel)
		{
			target.PreviewFlame(num);
		}
		else
		{
			target.Preview(num);
		}
		message = "";
	}

	private void Apply()
	{
		if (session.Dirty)
		{
			if (!Object.op_Implicit((Object)(object)target) || !(flameChannel ? target.CommitFlame(session.Selected) : target.Commit(session.Selected)))
			{
				message = "Could not save. Check distance and ward access.";
				return;
			}
			session.Applied();
			message = ChannelName + " colour applied and saved.";
		}
	}

	private void RestoreDefault()
	{
		if (!Object.op_Implicit((Object)(object)target) || !(flameChannel ? target.CommitFlame(0) : target.Commit(0)))
		{
			message = "Could not reset. Check distance and ward access.";
			return;
		}
		wheelDragging = false;
		GUIUtility.hotControl = 0;
		session.Open(0);
		LoadWheel();
		message = "Original " + ChannelName + " colours restored. No colour override.";
	}

	private void CancelPreview()
	{
		if (!Object.op_Implicit((Object)(object)target))
		{
			Close();
			return;
		}
		target.EndPreview();
		session.Cancel(ChannelSaved);
		LoadWheel();
		message = "Preview discarded.";
	}

	internal void Close()
	{
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		bool num = visible;
		visible = false;
		wheelDragging = false;
		favouritesMode = false;
		if (Object.op_Implicit((Object)(object)target))
		{
			target.EndPreview();
		}
		target = null;
		if (captured)
		{
			if (previousRequested)
			{
				ZCursor.Show();
			}
			else
			{
				ZCursor.Hide();
			}
			ZCursor.LockState = previousLock;
			Cursor.lockState = previousLock;
			Cursor.visible = previousVisible;
			captured = false;
		}
		if (num)
		{
			blockUntil = Time.unscaledTime + 0.15f;
		}
	}

	internal void KeepCursor()
	{
		if (visible)
		{
			ZCursor.Show();
			ZCursor.LockState = (CursorLockMode)0;
			Cursor.lockState = (CursorLockMode)0;
			Cursor.visible = !controller;
		}
	}

	private void Styles()
	{
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Expected O, but got Unknown
		//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_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Expected O, but got Unknown
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Expected O, but got Unknown
		//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_00a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: Expected O, but got Unknown
		//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cd: Expected O, but got Unknown
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e6: Expected O, but got Unknown
		//IL_0126: Unknown result type (might be due to invalid IL or missing references)
		if (title == null)
		{
			title = new GUIStyle(GUI.skin.label)
			{
				fontSize = 34,
				fontStyle = (FontStyle)1,
				alignment = (TextAnchor)4
			};
			heading = new GUIStyle(GUI.skin.label)
			{
				fontSize = 25,
				fontStyle = (FontStyle)1,
				alignment = (TextAnchor)4,
				wordWrap = true
			};
			body = new GUIStyle(GUI.skin.label)
			{
				fontSize = 21,
				wordWrap = true
			};
			button = new GUIStyle(GUI.skin.button)
			{
				fontSize = 20,
				fontStyle = (FontStyle)1,
				wordWrap = true
			};
			centered = new GUIStyle(body)
			{
				alignment = (TextAnchor)4
			};
			small = new GUIStyle(body)
			{
				fontSize = 18
			};
			GUIStyle[] array = (GUIStyle[])(object)new GUIStyle[5] { title, heading, body, centered, small };
			for (int i = 0; i < array.Length; i++)
			{
				array[i].normal.textColor = Color.white;
			}
		}
	}

	private void OnGUI()
	{
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0093: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00de: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0101: Unknown result type (might be due to invalid IL or missing references)
		//IL_010c: Unknown result type (might be due to invalid IL or missing references)
		if (visible)
		{
			Styles();
			float num = MenuLayout.Scale(Screen.width, Screen.height);
			Matrix4x4 matrix = GUI.matrix;
			Color color = GUI.color;
			GUI.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, Vector3.one * num);
			float num2 = (float)Screen.width / num;
			float num3 = (float)Screen.height / num;
			Rect val = new Rect(num2 - 600f, (num3 - 890f) / 2f, 580f, 890f);
			GUI.color = new Color(0.065f, 0.08f, 0.1f, 0.98f);
			GUI.DrawTexture(val, (Texture)(object)Texture2D.whiteTexture);
			GUI.color = Color.white;
			GUI.BeginGroup(val);
			DrawMenu();
			GUI.EndGroup();
			Rect val2 = new Rect(20f, (num3 - 750f) / 2f, 280f, 750f);
			GUI.color = new Color(0.065f, 0.08f, 0.1f, 0.98f);
			GUI.DrawTexture(val2, (Texture)(object)Texture2D.whiteTexture);
			GUI.color = Color.white;
			GUI.BeginGroup(val2);
			DrawFavourites();
			GUI.EndGroup();
			GUI.color = color;
			GUI.matrix = matrix;
		}
	}

	private void DrawMenu()
	{
		//IL_0014: 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)
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_011e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0133: Unknown result type (might be due to invalid IL or missing references)
		//IL_016e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0174: Invalid comparison between Unknown and I4
		//IL_0194: Unknown result type (might be due to invalid IL or missing references)
		//IL_019a: Invalid comparison between Unknown and I4
		//IL_0145: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0200: Unknown result type (might be due to invalid IL or missing references)
		//IL_0205: Unknown result type (might be due to invalid IL or missing references)
		//IL_020a: Unknown result type (might be due to invalid IL or missing references)
		//IL_020b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0215: Unknown result type (might be due to invalid IL or missing references)
		//IL_0221: Unknown result type (might be due to invalid IL or missing references)
		//IL_0237: Unknown result type (might be due to invalid IL or missing references)
		//IL_0246: Unknown result type (might be due to invalid IL or missing references)
		//IL_0250: 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_0272: 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_02be: 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_0185: Unknown result type (might be due to invalid IL or missing references)
		//IL_015a: Unknown result type (might be due to invalid IL or missing references)
		//IL_015f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0368: Unknown result type (might be due to invalid IL or missing references)
		//IL_038c: Unknown result type (might be due to invalid IL or missing references)
		//IL_03aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_045f: Unknown result type (might be due to invalid IL or missing references)
		//IL_04ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_0531: Unknown result type (might be due to invalid IL or missing references)
		//IL_0570: Unknown result type (might be due to invalid IL or missing references)
		GUI.Label(new Rect(20f, 12f, 540f, 50f), "LightUpYourWorld", title);
		GUI.Label(new Rect(25f, 62f, 530f, 34f), targetName, heading);
		if (GUI.Button(new Rect(30f, 101f, 250f, 40f), ((!flameChannel) ? "✓ " : "") + "Glow · illumination", button))
		{
			SwitchChannel(flame: false);
		}
		bool enabled = GUI.enabled;
		GUI.enabled = target.HasFlame;
		if (GUI.Button(new Rect(300f, 101f, 250f, 40f), (flameChannel ? "✓ " : "") + "Flame · visible fire", button))
		{
			SwitchChannel(flame: true);
		}
		GUI.enabled = enabled;
		Rect val = default(Rect);
		((Rect)(ref val))..ctor(90f, 147f, 390f, 390f);
		GUI.DrawTexture(val, (Texture)(object)wheel, (ScaleMode)0, true);
		Event current = Event.current;
		if ((int)current.type == 0 && current.button == 0 && ((Rect)(ref val)).Contains(current.mousePosition))
		{
			wheelDragging = true;
			SetFromMouse(current.mousePosition, val);
			current.Use();
		}
		else if ((int)current.type == 3 && wheelDragging)
		{
			SetFromMouse(current.mousePosition, val);
			current.Use();
		}
		else if ((int)current.type == 1 && wheelDragging)
		{
			wheelDragging = false;
			current.Use();
		}
		Vector2 val2 = ((Rect)(ref val)).center + new Vector2(Mathf.Cos(hue * 2f * MathF.PI), 0f - Mathf.Sin(hue * 2f * MathF.PI)) * (saturation * (((Rect)(ref val)).width / 2f));
		GUI.color = Color.black;
		GUI.DrawTexture(new Rect(val2.x - 7f, val2.y - 7f, 14f, 14f), (Texture)(object)Texture2D.whiteTexture);
		GUI.color = Color.white;
		GUI.DrawTexture(new Rect(val2.x - 4f, val2.y - 4f, 8f, 8f), (Texture)(object)Texture2D.whiteTexture);
		GUI.Label(new Rect(30f, 550f, 160f, 32f), "Brightness", body);
		float num = GUI.HorizontalSlider(new Rect(200f, 560f, 345f, 25f), brightness, 0f, 1f);
		if (Mathf.Abs(num - brightness) > 0.0001f)
		{
			brightness = num;
			Preview();
		}
		string text = (session.Dirty ? ("Unsaved " + ChannelName + " preview") : ((session.Saved != 0) ? (ChannelName + " colour applied") : ("Original " + ChannelName + " colour")));
		GUI.Label(new Rect(30f, 588f, 520f, 32f), text, centered);
		GUI.color = Color.HSVToRGB(hue, saturation, brightness);
		GUI.DrawTexture(new Rect(30f, 631f, 520f, 38f), (Texture)(object)Texture2D.whiteTexture);
		GUI.color = Color.white;
		bool enabled2 = GUI.enabled;
		GUI.enabled = session.Dirty;
		if (GUI.Button(new Rect(20f, 690f, 172f, 60f), (controller && !favouritesMode) ? "A · Apply" : "Apply colour", button))
		{
			Apply();
		}
		GUI.enabled = Object.op_Implicit((Object)(object)target) && (ChannelSaved != 0 || session.Dirty);
		if (GUI.Button(new Rect(204f, 690f, 172f, 60f), (controller && !favouritesMode) ? "X · Default" : "Restore default", button))
		{
			RestoreDefault();
		}
		GUI.enabled = enabled2;
		if (GUI.Button(new Rect(388f, 690f, 172f, 60f), (!controller || favouritesMode) ? (session.Dirty ? "Cancel preview" : "Close") : (session.Dirty ? "B · Cancel" : "B · Close"), button))
		{
			if (session.Dirty)
			{
				CancelPreview();
			}
			else
			{
				Close();
			}
		}
		GUI.Label(new Rect(30f, 761f, 520f, 40f), (message.Length > 0) ? message : "See the chosen light in the world. Apply saves it.", small);
		GUI.Label(new Rect(30f, 801f, 520f, 86f), controller ? "Right stick: colour · LB/RB: brightness\nA: apply · X: default · B: cancel / close\nD-pad left/right: Flame / Glow · Y: favourites" : "Click / drag the wheel; slider: brightness\nArrow keys: colour · +/-: brightness\nEnter: apply · Delete: default · Esc: close\nC: Flame / Glow · Tab: favourites · F: save", small);
	}

	private void DrawFavourites()
	{
		//IL_0014: 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)
		//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_024e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00de: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_010d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0106: Unknown result type (might be due to invalid IL or missing references)
		//IL_02de: Unknown result type (might be due to invalid IL or missing references)
		//IL_0147: Unknown result type (might be due to invalid IL or missing references)
		//IL_0156: Unknown result type (might be due to invalid IL or missing references)
		//IL_015c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0193: 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_01fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_032b: Unknown result type (might be due to invalid IL or missing references)
		GUI.Label(new Rect(10f, 20f, 260f, 45f), "Favourite colours", heading);
		GUI.Label(new Rect(15f, 76f, 250f, 55f), (!controller) ? "10 slots saved with your character" : (favouritesMode ? "Choose a slot" : "Y · Open favourites"), centered);
		Rect val = default(Rect);
		for (int i = 0; i < 10; i++)
		{
			((Rect)(ref val))..ctor((float)(20 + i % 2 * 125), (float)(120 + i / 2 * 64), 115f, 56f);
			Color colour;
			bool flag = LightFavourites.TryGet(Player.m_localPlayer, i, out colour);
			Color color = GUI.color;
			GUI.color = ((i == favouriteSlot) ? new Color(1f, 0.72f, 0.15f) : new Color(0.4f, 0.43f, 0.46f));
			GUI.DrawTexture(val, (Texture)(object)Texture2D.whiteTexture);
			GUI.color = (Color)(flag ? colour : new Color(0.1f, 0.12f, 0.14f));
			GUI.DrawTexture(new Rect(((Rect)(ref val)).x + 4f, ((Rect)(ref val)).y + 4f, ((Rect)(ref val)).width - 8f, ((Rect)(ref val)).height - 8f), (Texture)(object)Texture2D.whiteTexture);
			GUI.color = color;
			if (GUI.Button(val, "", GUIStyle.none))
			{
				favouriteSlot = i;
				if (flag)
				{
					PreviewFavourite();
				}
			}
			GUI.color = new Color(0f, 0f, 0f, 0.8f);
			GUI.DrawTexture(new Rect(((Rect)(ref val)).x + 4f, ((Rect)(ref val)).y + 24f, ((Rect)(ref val)).width - 8f, 28f), (Texture)(object)Texture2D.whiteTexture);
			GUI.color = color;
			GUI.Label(new Rect(((Rect)(ref val)).x, ((Rect)(ref val)).y + 22f, ((Rect)(ref val)).width, 30f), i + 1 + (flag ? "" : " · Empty"), centered);
		}
		if (GUI.Button(new Rect(20f, 452f, 240f, 48f), (controller && favouritesMode) ? ("Y · Save in slot " + (favouriteSlot + 1)) : ("Save in slot " + (favouriteSlot + 1)), button))
		{
			SaveFavourite();
		}
		bool enabled = GUI.enabled;
		GUI.enabled = LightFavourites.TryGet(Player.m_localPlayer, favouriteSlot, out var _);
		if (GUI.Button(new Rect(20f, 510f, 240f, 48f), (controller && favouritesMode) ? "X · Clear favourite" : "Clear favourite", button))
		{
			RemoveFavourite();
		}
		GUI.enabled = enabled;
		GUI.Label(new Rect(20f, 584f, 240f, 150f), controller ? "In favourites:\nLeft stick / D-pad: slot\nA: preview · Y: save\nX: clear · B: return\nThen A applies to the light." : "Click a saved slot to preview its colour. Apply saves it on the light.\n\nSelect any slot, then Save to store or replace it.", small);
	}

	private void SetFromMouse(Vector2 position, Rect rect)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0003: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: 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)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		Vector2 val = position - ((Rect)(ref rect)).center;
		saturation = Mathf.Clamp01(((Vector2)(ref val)).magnitude / (((Rect)(ref rect)).width * 0.5f));
		if (((Vector2)(ref val)).sqrMagnitude > 0.001f)
		{
			hue = Mathf.Repeat(Mathf.Atan2(0f - val.y, val.x) / (MathF.PI * 2f), 1f);
		}
		Preview();
	}

	private void CreateWheel()
	{
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Expected O, but got Unknown
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		wheel = new Texture2D(400, 400, (TextureFormat)4, false);
		((Object)wheel).name = "LightUpYourWorld_ColourWheel";
		((Texture)wheel).wrapMode = (TextureWrapMode)1;
		Color32[] array = (Color32[])(object)new Color32[160000];
		float num = 199.5f;
		for (int i = 0; i < 400; i++)
		{
			for (int j = 0; j < 400; j++)
			{
				float num2 = ((float)j - num) / num;
				float num3 = ((float)i - num) / num;
				float num4 = Mathf.Sqrt(num2 * num2 + num3 * num3);
				array[i * 400 + j] = (Color32)((num4 <= 1f) ? Color32.op_Implicit(Color.HSVToRGB(Mathf.Repeat(Mathf.Atan2(num3, num2) / (MathF.PI * 2f), 1f), num4, 1f)) : new Color32((byte)0, (byte)0, (byte)0, (byte)0));
			}
		}
		wheel.SetPixels32(array);
		wheel.Apply(false, true);
	}
}
[HarmonyPatch(typeof(Piece), "Awake")]
internal static class AttachLightPatch
{
	private static void Postfix(Piece __instance)
	{
		WorldLight.Attach(__instance);
	}
}
[HarmonyPatch(typeof(Player), "Interact")]
internal static class LightInteractionPatch
{
	private static bool Prefix(Player __instance, GameObject __0, bool __1)
	{
		LightUpYourWorldPlugin instance = LightUpYourWorldPlugin.Instance;
		if (!Object.op_Implicit((Object)(object)instance) || (Object)(object)__instance != (Object)(object)Player.m_localPlayer)
		{
			return true;
		}
		if (instance.BlocksGameplay)
		{
			return false;
		}
		if (!ZInput.GetButton("JoyLBumper"))
		{
			return true;
		}
		WorldLight worldLight = WorldLight.Find(__0);
		if (!Object.op_Implicit((Object)(object)worldLight))
		{
			return true;
		}
		if (!__1)
		{
			instance.Open(worldLight);
		}
		return false;
	}
}
[HarmonyPatch(typeof(Player), "TakeInput")]
internal static class PlayerInputPatch
{
	private static void Postfix(ref bool __result)
	{
		if (Object.op_Implicit((Object)(object)LightUpYourWorldPlugin.Instance) && LightUpYourWorldPlugin.Instance.BlocksGameplay)
		{
			__result = false;
		}
	}
}
[HarmonyPatch(typeof(PlayerController), "TakeInput")]
internal static class ControllerInputPatch
{
	private static void Postfix(ref bool __result)
	{
		if (Object.op_Implicit((Object)(object)LightUpYourWorldPlugin.Instance) && LightUpYourWorldPlugin.Instance.BlocksGameplay)
		{
			__result = false;
		}
	}
}
[HarmonyPatch(typeof(HotkeyBar), "Update")]
internal static class HotbarPatch
{
	private static bool Prefix()
	{
		if (Object.op_Implicit((Object)(object)LightUpYourWorldPlugin.Instance))
		{
			return !LightUpYourWorldPlugin.Instance.BlocksGameplay;
		}
		return true;
	}
}
[HarmonyPatch(typeof(GameCamera), "UpdateMouseCapture")]
internal static class CursorPatch
{
	private static void Postfix()
	{
		if (Object.op_Implicit((Object)(object)LightUpYourWorldPlugin.Instance))
		{
			LightUpYourWorldPlugin.Instance.KeepCursor();
		}
	}
}
[HarmonyPatch(typeof(Character), "Damage")]
internal static class DamagePatch
{
	private static void Prefix(Character __instance)
	{
		if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer && Object.op_Implicit((Object)(object)LightUpYourWorldPlugin.Instance))
		{
			LightUpYourWorldPlugin.Instance.Close();
		}
	}
}
public sealed class WorldLight : MonoBehaviour
{
	private sealed class PieceKind
	{
		internal bool IsBoat;

		internal float NextProbe;

		internal bool Probed;
	}

	internal static readonly HashSet<WorldLight> Sources = new HashSet<WorldLight>();

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

	private readonly FlameVisuals flames = new FlameVisuals();

	private int savedFlame;

	private int previewFlame;

	private bool flamePreview;

	private ZNetView view;

	private Piece piece;

	private int saved;

	private int applied = -1;

	private bool initialized;

	private bool preview;

	private int previewColour;

	private float nextRead;

	private float nextDiscovery;

	private float nextFullDiscovery;

	private int hierarchyCount = -1;

	private bool flameDiscoveryNeeded = true;

	private bool flamesRequested;

	private static readonly ConditionalWeakTable<Piece, PieceKind> Kinds = new ConditionalWeakTable<Piece, PieceKind>();

	private bool refreshRequested = true;

	internal bool HasFlame => flames.Available;

	internal Color OriginalFlameColour => flames.OriginalColour(OriginalColour);

	internal int SavedFlame
	{
		get
		{
			if (!Ready)
			{
				return 0;
			}
			return LightColour.Normalize(view.GetZDO().GetInt("LightUpYourWorld.Flame", 0));
		}
	}

	internal bool Ready
	{
		get
		{
			if (initialized && Object.op_Implicit((Object)(object)view) && view.IsValid())
			{
				return originals.Count > 0;
			}
			return false;
		}
	}

	internal int Saved
	{
		get
		{
			if (!Ready)
			{
				return 0;
			}
			return LightColour.Normalize(view.GetZDO().GetInt("LightUpYourWorld.Colour", 0));
		}
	}

	internal string DisplayName
	{
		get
		{
			if (!Object.op_Implicit((Object)(object)piece))
			{
				return "Light";
			}
			return LightUpYourWorldPlugin.Localize(piece.m_name);
		}
	}

	internal Color OriginalColour
	{
		get
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			foreach (KeyValuePair<Light, Color> original in originals)
			{
				if (Object.op_Implicit((Object)(object)original.Key))
				{
					return original.Value;
				}
			}
			return Color.white;
		}
	}

	private static bool IsSupportedPiece(Piece owner)
	{
		if (Object.op_Implicit((Object)(object)owner))
		{
			return !Kinds.GetValue(owner, (Piece piece) => new PieceKind
			{
				IsBoat = Object.op_Implicit((Object)(object)((Component)piece).GetComponentInChildren<Ship>(true))
			}).IsBoat;
		}
		return false;
	}

	internal static WorldLight Find(GameObject obj)
	{
		if (!Object.op_Implicit((Object)(object)obj))
		{
			return null;
		}
		Piece componentInParent = obj.GetComponentInParent<Piece>();
		if (!IsSupportedPiece(componentInParent))
		{
			return null;
		}
		ZNetView component = ((Component)componentInParent).GetComponent<ZNetView>();
		if (!Object.op_Implicit((Object)(object)component) || !component.IsValid())
		{
			return null;
		}
		WorldLight worldLight = ((Component)componentInParent).GetComponent<WorldLight>();
		if (!Object.op_Implicit((Object)(object)worldLight))
		{
			PieceKind value = Kinds.GetValue(componentInParent, (Piece p) => new PieceKind());
			if (value.Probed && Time.unscaledTime < value.NextProbe)
			{
				return null;
			}
			value.Probed = true;
			value.NextProbe = Time.unscaledTime + 2f;
			if (Object.op_Implicit((Object)(object)((Component)componentInParent).GetComponentInChildren<Light>(true)))
			{
				worldLight = ((Component)componentInParent).gameObject.AddComponent<WorldLight>();
			}
		}
		if (!Object.op_Implicit((Object)(object)worldLight) || !worldLight.Ready)
		{
			return null;
		}
		return worldLight;
	}

	internal static void Attach(Piece owner)
	{
		if (IsSupportedPiece(owner))
		{
			ZNetView component = ((Component)owner).GetComponent<ZNetView>();
			if (Object.op_Implicit((Object)(object)component) && component.IsValid() && !Object.op_Implicit((Object)(object)((Component)owner).GetComponent<WorldLight>()) && Object.op_Implicit((Object)(object)((Component)owner).GetComponentInChildren<Light>(true)))
			{
				((Component)owner).gameObject.AddComponent<WorldLight>();
			}
		}
	}

	private void OnEnable()
	{
		Sources.Add(this);
	}

	private void OnDisable()
	{
		Sources.Remove(this);
		EndPreview();
	}

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

	private void Start()
	{
		piece = ((Component)this).GetComponent<Piece>();
		view = ((Component)this).GetComponent<ZNetView>();
		if (!IsSupportedPiece(piece) || !Object.op_Implicit((Object)(object)view) || !view.IsValid())
		{
			((Behaviour)this).enabled = false;
		}
		else
		{
			initialized = true;
		}
	}

	internal void RefreshLights()
	{
		if (initialized)
		{
			DiscoverLights();
			flames.Discover(this);
			flamesRequested = true;
			flameDiscoveryNeeded = false;
			hierarchyCount = ((Component)this).transform.hierarchyCount;
			refreshRequested = false;
			nextDiscovery = Time.unscaledTime + 2f;
			nextFullDiscovery = Time.unscaledTime + 10f;
		}
	}

	private void DiscoverLights()
	{
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		Light[] componentsInChildren = ((Component)this).GetComponentsInChildren<Light>(true);
		foreach (Light val in componentsInChildren)
		{
			if (Object.op_Implicit((Object)(object)val) && !((Object)(object)((Component)val).GetComponentInParent<Piece>() != (Object)(object)piece) && !originals.ContainsKey(val))
			{
				originals.Add(val, val.color);
				applied = -1;
			}
		}
	}

	private void OnTransformChildrenChanged()
	{
		refreshRequested = true;
	}

	internal void Tick()
	{
		//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_01b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_014a: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
		if (!initialized || !Object.op_Implicit((Object)(object)view) || !view.IsValid())
		{
			return;
		}
		if (refreshRequested || Time.unscaledTime >= nextDiscovery)
		{
			int num = ((Component)this).transform.hierarchyCount;
			if (refreshRequested || num != hierarchyCount || ((saved != 0 || savedFlame != 0 || preview || flamePreview) && Time.unscaledTime >= nextFullDiscovery))
			{
				DiscoverLights();
				hierarchyCount = num;
				flameDiscoveryNeeded = true;
				nextFullDiscovery = Time.unscaledTime + 10f;
			}
			refreshRequested = false;
			nextDiscovery = Time.unscaledTime + 2f;
		}
		if (Time.unscaledTime >= nextRead)
		{
			savedFlame = SavedFlame;
			saved = Saved;
			nextRead = Time.unscaledTime + 0.25f;
		}
		int num2 = (preview ? previewColour : saved);
		if (num2 == 0)
		{
			if (applied != 0)
			{
				foreach (KeyValuePair<Light, Color> original in originals)
				{
					if (Object.op_Implicit((Object)(object)original.Key))
					{
						original.Key.color = original.Value;
					}
				}
			}
		}
		else
		{
			Color val = Unpack(num2);
			foreach (KeyValuePair<Light, Color> original2 in originals)
			{
				if (Object.op_Implicit((Object)(object)original2.Key) && ((Component)original2.Key).gameObject.activeInHierarchy && original2.Key.color != val)
				{
					original2.Key.color = val;
				}
			}
		}
		applied = num2;
		if (flameDiscoveryNeeded && (flamesRequested || flamePreview || savedFlame != 0))
		{
			flames.Discover(this);
			flamesRequested = true;
			flameDiscoveryNeeded = false;
		}
		flames.Apply(flamePreview ? previewFlame : savedFlame);
	}

	internal static int Pack(Color colour)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//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_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		Color32 val = Color32.op_Implicit(colour);
		return LightColour.Pack(val.r, val.g, val.b);
	}

	internal static Color Unpack(int colour)
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		return Color32.op_Implicit(new Color32(LightColour.Red(colour), LightColour.Green(colour), LightColour.Blue(colour), byte.MaxValue));
	}

	internal void Preview(int colour)
	{
		preview = true;
		previewColour = LightColour.Normalize(colour);
		Tick();
	}

	internal void PreviewFlame(int colour)
	{
		flamePreview = true;
		previewFlame = LightColour.Normalize(colour);
		Tick();
	}

	internal bool CommitFlame(int colour)
	{
		if (!HasFlame || !LightColour.IsValid(colour) || !CanEdit(Player.m_localPlayer, flash: true))
		{
			return false;
		}
		view.ClaimOwnership();
		if (!view.IsOwner())
		{
			return false;
		}
		view.GetZDO().Set("LightUpYourWorld.Flame", colour);
		flamePreview = false;
		nextRead = 0f;
		Tick();
		return true;
	}

	internal void EndPreview()
	{
		flamePreview = false;
		preview = false;
		nextRead = 0f;
		Tick();
	}

	internal bool CanEdit(Player player, bool flash)
	{
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		if (Object.op_Implicit((Object)(object)player) && Ready && !((Character)player).IsDead() && Vector3.Distance(((Component)player).transform.position, ((Component)this).transform.position) <= 8f)
		{
			return PrivateArea.CheckAccess(((Component)this).transform.position, 0f, flash, false);
		}
		return false;
	}

	internal bool Commit(int colour)
	{
		if (!LightColour.IsValid(colour) || !CanEdit(Player.m_localPlayer, flash: true))
		{
			return false;
		}
		view.ClaimOwnership();
		if (!view.IsOwner())
		{
			return false;
		}
		view.GetZDO().Set("LightUpYourWorld.Colour", colour);
		saved = colour;
		preview = false;
		nextRead = 0f;
		Tick();
		return true;
	}

	internal void RestoreForUnload()
	{
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		flames.Restore();
		foreach (KeyValuePair<Light, Color> original in originals)
		{
			if (Object.op_Implicit((Object)(object)original.Key))
			{
				original.Key.color = original.Value;
			}
		}
	}
}
internal sealed class FlameVisuals
{
	private sealed class Entry
	{
		internal bool gradientMapped;

		internal string[] colours;

		internal ParticleColours particles;

		internal Renderer renderer;

		internal int slot;

		internal Material material;

		internal MaterialPropertyBlock original;

		internal MaterialPropertyBlock working;
	}

	private readonly List<Entry> entries = new List<Entry>();

	private readonly Dictionary<Renderer, Material[]> inspected = new Dictionary<Renderer, Material[]>();

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

	private int applied = -1;

	private float nextApply;

	private static readonly string[] Keys = new string[10] { "_Color", "_TintColor", "_BaseColor", "_EmissionColor", "_ColorTop", "_ColorBottom", "_Color1", "_Color2", "_StartColor", "_EndColor" };

	internal bool Available => entries.Count > 0;

	internal Color OriginalColour(Color fallback)
	{
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: Unknown result type (might be due to invalid IL or missing references)
		Color colour;
		foreach (Entry entry in entries)
		{
			if (entry.gradientMapped && entry.particles.TryOriginalColour(out colour))
			{
				return colour;
			}
		}
		foreach (Entry entry2 in entries)
		{
			if (entry2.particles.TryOriginalColour(out colour))
			{
				return colour;
			}
		}
		foreach (Entry entry3 in entries)
		{
			if (entry3.colours.Length != 0)
			{
				return entry3.material.GetColor(entry3.colours[0]);
			}
		}
		return fallback;
	}

	internal static bool IsFlame(string name)
	{
		string text = name.ToLowerInvariant();
		if (text.Contains("smoke") || text.Contains("spark") || text.Contains("ash") || text.Contains("steam"))
		{
			return false;
		}
		if (!text.Contains("flame") && !text.Contains("fire"))
		{
			return text.Contains("burn");
		}
		return true;
	}

	private static Renderer NativeRenderer(WorldLight owner, Renderer live)
	{
		ZNetView component = ((Component)owner).GetComponent<ZNetView>();
		if (!Object.op_Implicit((Object)(object)ZNetScene.instance) || !Object.op_Implicit((Object)(object)component) || !component.IsValid())
		{
			return null;
		}
		GameObject prefab = ZNetScene.instance.GetPrefab(component.GetZDO().GetPrefab());
		if (!Object.op_Implicit((Object)(object)prefab) || (Object)(object)prefab == (Object)(object)((Component)owner).gameObject)
		{
			return null;
		}
		List<Transform> list = new List<Transform>();
		Transform val = ((Component)live).transform;
		while (Object.op_Implicit((Object)(object)val) && (Object)(object)val != (Object)(object)((Component)owner).transform)
		{
			list.Add(val);
			val = val.parent;
		}
		Transform val2 = prefab.transform;
		for (int num = list.Count - 1; num >= 0; num--)
		{
			int siblingIndex = list[num].GetSiblingIndex();
			if (siblingIndex >= val2.childCount)
			{
				return null;
			}
			val2 = val2.GetChild(siblingIndex);
			if (((Object)val2).name != ((Object)list[num]).name)
			{
				return null;
			}
		}
		Renderer component2 = ((Component)val2).GetComponent<Renderer>();
		if (!Object.op_Implicit((Object)(object)component2) || !(((object)component2).GetType() == ((object)live).GetType()))
		{
			return null;
		}
		return component2;
	}

	internal void Discover(WorldLight owner)
	{
		//IL_047f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0486: Expected O, but got Unknown
		//IL_0566: Unknown result type (might be due to invalid IL or missing references)
		//IL_0570: Expected O, but got Unknown
		//IL_04eb: Unknown result type (might be due to invalid IL or missing references)
		dead.Clear();
		foreach (KeyValuePair<Renderer, Material[]> item in inspected)
		{
			if (!Object.op_Implicit((Object)(object)item.Key))
			{
				dead.Add(item.Key);
			}
		}
		foreach (Renderer item2 in dead)
		{
			inspected.Remove(item2);
		}
		entries.RemoveAll((Entry e) => !Object.op_Implicit((Object)(object)e.renderer));
		Piece component = ((Component)owner).GetComponent<Piece>();
		Renderer[] componentsInChildren = ((Component)owner).GetComponentsInChildren<Renderer>(true);
		foreach (Renderer renderer in componentsInChildren)
		{
			if ((Object)(object)((Component)renderer).GetComponentInParent<Piece>() != (Object)(object)component)
			{
				continue;
			}
			bool flag = ((object)renderer).GetType().Name == "ParticleSystemRenderer";
			Material[] sharedMaterials = renderer.sharedMaterials;
			if (inspected.TryGetValue(renderer, out var value) && SameMaterials(value, sharedMaterials))
			{
				continue;
			}
			inspected[renderer] = sharedMaterials;
			entries.RemoveAll((Entry e) => (Object)(object)e.renderer == (Object)(object)renderer);
			Renderer val = NativeRenderer(owner, renderer);
			int slot;
			for (slot = 0; slot < sharedMaterials.Length; slot++)
			{
				Material val2 = sharedMaterials[slot];
				if (!Object.op_Implicit((Object)(object)val2))
				{
					continue;
				}
				string text = (Object.op_Implicit((Object)(object)val2.shader) ? ((Object)val2.shader).name : "");
				if (!IsFlame(((Object)renderer).name + " " + ((Object)val2).name + " " + text) || (!flag && !IsFireMesh(((Object)val2).name, text)) || entries.Exists((Entry e) => (Object)(object)e.renderer == (Object)(object)renderer && e.slot == slot))
				{
					continue;
				}
				bool gradientMapped = text == "Custom/Gradient Mapped Particle (Unlit)";
				Material val3 = ((Object.op_Implicit((Object)(object)val) && slot < val.sharedMaterials.Length) ? val.sharedMaterials[slot] : val2);
				if (!Object.op_Implicit((Object)(object)val3) || !Object.op_Implicit((Object)(object)val3.shader) || ((Object)val3.shader).name != text)
				{
					val3 = val2;
				}
				ParticleColours particleColours = new ParticleColours(((Component)renderer).GetComponent("ParticleSystem"), gradientMapped, Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent("ParticleSystem") : null);
				List<string> list = new List<string>();
				if (Object.op_Implicit((Object)(object)val2.shader))
				{
					Type type = ((object)val2.shader).GetType();
					MethodInfo method = type.GetMethod("GetPropertyCount", Type.EmptyTypes);
					MethodInfo method2 = type.GetMethod("GetPropertyType", new Type[1] { typeof(int) });
					MethodInfo method3 = type.GetMethod("GetPropertyName", new Type[1] { typeof(int) });
					if (method != null && method2 != null && method3 != null)
					{
						for (int num2 = 0; num2 < (int)method.Invoke(val2.shader, null); num2++)
						{
							if (method2.Invoke(val2.shader, new object[1] { num2 }).ToString() == "Color")
							{
								list.Add((string)method3.Invoke(val2.shader, new object[1] { num2 }));
							}
						}
					}
				}
				string[] keys = Keys;
				foreach (string text2 in keys)
				{
					if (val2.HasProperty(text2) && !list.Contains(text2))
					{
						list.Add(text2);
					}
				}
				if (!particleColours.Available && list.Count <= 0)
				{
					continue;
				}
				MaterialPropertyBlock val4 = new MaterialPropertyBlock();
				if (Object.op_Implicit((Object)(object)val))
				{
					val.GetPropertyBlock(val4, slot);
				}
				else
				{
					renderer.GetPropertyBlock(val4, slot);
				}
				if (Object.op_Implicit((Object)(object)val))
				{
					foreach (string item3 in list)
					{
						if (val3.HasProperty(item3))
						{
							val4.SetColor(item3, val3.GetColor(item3));
						}
					}
				}
				entries.Add(new Entry
				{
					gradientMapped = gradientMapped,
					colours = list.ToArray(),
					particles = particleColours,
					renderer = renderer,
					slot = slot,
					material = val3,
					original = val4,
					working = new MaterialPropertyBlock()
				});
				applied = -1;
			}
		}
	}

	private static bool SameMaterials(Material[] a, Material[] b)
	{
		if (a.Length != b.Length)
		{
			return false;
		}
		for (int i = 0; i < a.Length; i++)
		{
			if ((Object)(object)a[i] != (Object)(object)b[i])
			{
				return false;
			}
		}
		return true;
	}

	internal static bool IsFireMesh(string material, string shader)
	{
		string text = material.ToLowerInvariant();
		string text2 = shader.ToLowerInvariant();
		if (!text.Contains("flame") && !text2.Contains("flame"))
		{
			return text2.Contains("fire");
		}
		return true;
	}

	internal void Apply(int packed)
	{
		//IL_009f: 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_00d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00da: 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: Unknown result type (might be due to invalid IL or missing references)
		//IL_0103: Unknown result type (might be due to invalid IL or missing references)
		//IL_010c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0115: Unknown result type (might be due to invalid IL or missing references)
		//IL_011e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0125: Unknown result type (might be due to invalid IL or missing references)
		bool flag = packed != applied;
		if (!flag && (packed == 0 || Time.unscaledTime < nextApply))
		{
			return;
		}
		nextApply = Time.unscaledTime + 0.25f;
		foreach (Entry entry in entries)
		{
			if (!Object.op_Implicit((Object)(object)entry.renderer))
			{
				continue;
			}
			entry.particles.Apply(packed, flag);
			if (packed == 0)
			{
				entry.renderer.SetPropertyBlock(entry.original, entry.slot);
				continue;
			}
			entry.renderer.GetPropertyBlock(entry.working, entry.slot);
			Color val = WorldLight.Unpack(packed);
			string[] colours = entry.colours;
			foreach (string text in colours)
			{
				if (entry.material.HasProperty(text))
				{
					Color color = entry.material.GetColor(text);
					float num = Mathf.Max(color.r, Mathf.Max(color.g, color.b));
					entry.working.SetColor(text, new Color(val.r * num, val.g * num, val.b * num, color.a));
				}
			}
			entry.renderer.SetPropertyBlock(entry.working, entry.slot);
		}
		applied = packed;
	}

	internal void Restore()
	{
		applied = -1;
		Apply(0);
	}
}
internal sealed class ParticleColours
{
	private sealed class Setting
	{
		internal object module;

		internal object original;

		internal object mapped;

		internal PropertyInfo property;

		internal bool primary;
	}

	private sealed class CustomSetting
	{
		internal object stream;

		internal object original;

		internal object mapped;
	}

	private readonly List<Setting> settings = new List<Setting>();

	private readonly List<CustomSetting> customSettings = new List<CustomSetting>();

	private object customModule;

	private object baselineSystem;

	private MethodInfo setCustomColor;

	private MethodInfo getCustomColor;

	private object system;

	private MethodInfo getParticles;

	private MethodInfo setParticles;

	private Type particleType;

	private PropertyInfo particleColor;

	private bool tinted;

	private int mappedColour = -1;

	internal string CustomDescription { get; private set; } = "not requested";

	internal bool Available => settings.Count > 0;

	internal string CustomReadback()
	{
		List<string> list = new List<string>();
		foreach (CustomSetting customSetting in customSettings)
		{
			object obj = getCustomColor.Invoke(customModule, new object[1] { customSetting.stream });
			MethodInfo method = obj.GetType().GetMethod("Evaluate", new Type[2]
			{
				typeof(float),
				typeof(float)
			});
			list.Add(customSetting.stream?.ToString() + "=" + ((method == null) ? "unavailable" : method.Invoke(obj, new object[2] { 0.5f, 0.5f }).ToString()));
		}
		return string.Join(";", list);
	}

	private void CaptureCustomColours()
	{
		List<string> list = new List<string>();
		try
		{
			customModule = system.GetType().GetProperty("customData")?.GetValue(system, null);
			if (customModule == null)
			{
				CustomDescription = "customData unavailable";
				return;
			}
			Type type = customModule.GetType();
			object obj = baselineSystem.GetType().GetProperty("customData")?.GetValue(baselineSystem, null) ?? customModule;
			MethodInfo method = type.GetMethod("GetMode");
			getCustomColor = type.GetMethod("GetColor");
			setCustomColor = type.GetMethod("SetColor");
			if (method == null || getCustomColor == null || setCustomColor == null)
			{
				CustomDescription = "customData methods unavailable";
				return;
			}
			list.Add("enabled=" + type.GetProperty("enabled")?.GetValue(customModule, null));
			Type parameterType = method.GetParameters()[0].ParameterType;
			string[] array = new string[2] { "Custom1", "Custom2" };
			foreach (string text in array)
			{
				object obj2 = Enum.Parse(parameterType, text);
				string text2 = method.Invoke(obj, new object[1] { obj2 }).ToString();
				list.Add(text + "=" + text2);
				if (text2 == "Color")
				{
					customSettings.Add(new CustomSetting
					{
						stream = obj2,
						original = Snapshot(getCustomColor.Invoke(obj, new object[1] { obj2 }))
					});
				}
			}
			CustomDescription = string.Join(";", list);
		}
		catch (Exception ex)
		{
			CustomDescription = "capture failed: " + ex.GetBaseException().Message;
		}
	}

	internal bool TryOriginalColour(out Color colour)
	{
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		object obj = ((customSettings.Count > 0) ? customSettings[0].original : settings.Find((Setting s) => s.primary)?.original);
		MethodInfo methodInfo = obj?.GetType().GetMethod("Evaluate", new Type[2]
		{
			typeof(float),
			typeof(float)
		});
		colour = (Color)((methodInfo == null) ? Color.white : ((Color)methodInfo.Invoke(obj, new object[2] { 0.5f, 0.5f })));
		return methodInfo != null;
	}

	internal ParticleColours(object particleSystem, bool gradientMapped = false, object nativeSystem = null)
	{
		if (particleSystem != null)
		{
			system = particleSystem;
			baselineSystem = nativeSystem ?? particleSystem;
			if (gradientMapped)
			{
				CaptureCustomColours();
			}
			Capture("main", "startColor", primary: true);
			Capture("colorOverLifetime", "color", primary: false);
			Capture("colorBySpeed", "color", primary: false);
			Type type = system.GetType();
			particleType = type.GetNestedType("Particle", BindingFlags.Public);
			if (!(particleType == null))
			{
				Type type2 = particleType.MakeArrayType();
				getParticles = type.GetMethod("GetParticles", new Type[1] { type2 });
				setParticles = type.GetMethod("SetParticles", new Type[2]
				{
					type2,
					typeof(int)
				});
				particleColor = particleType.GetProperty("startColor");
			}
		}
	}

	private void Capture(string moduleName, string propertyName, bool primary)
	{
		PropertyInfo property = system.GetType().GetProperty(moduleName);
		if (!(property == null))
		{
			object value = property.GetValue(system, null);
			PropertyInfo property2 = value.GetType().GetProperty(propertyName);
			if (!(property2 == null) && property2.CanWrite)
			{
				object value2 = property.GetValue(baselineSystem, null);
				settings.Add(new Setting
				{
					module = value,
					property = property2,
					original = Snapshot(property2.GetValue(value2, null)),
					primary = primary
				});
			}
		}
	}

	internal static object Snapshot(object original)
	{
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Expected O, but got Unknown
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		object objectValue = RuntimeHelpers.GetObjectValue(original);
		string[] array = new string[3] { "gradient", "gradientMin", "gradientMax" };
		foreach (string name in array)
		{
			PropertyInfo property = objectValue.GetType().GetProperty(name);
			if (!(property == null) && property.CanWrite)
			{
				object? value = property.GetValue(original, null);
				Gradient val = (Gradient)((value is Gradient) ? value : null);
				if (val != null)
				{
					Gradient val2 = new Gradient();
					val2.SetKeys((GradientColorKey[])val.colorKeys.Clone(), (GradientAlphaKey[])val.alphaKeys.Clone());
					val2.mode = val.mode;
					property.SetValue(objectValue, val2, null);
				}
			}
		}
		return objectValue;
	}

	internal static Color Recolour(Color original, Color chosen)
	{
		//IL_0000: 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_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		float num = Mathf.Max(original.r, Mathf.Max(original.g, original.b));
		return new Color(chosen.r * num, chosen.g * num, chosen.b * num, original.a);
	}

	private static Gradient RecolourGradient(Gradient original, Color chosen)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Expected O, but got Unknown
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		if (original == null)
		{
			return null;
		}
		Gradient val = new Gradient();
		GradientColorKey[] array = (GradientColorKey[])original.colorKeys.Clone();
		for (int i = 0; i < array.Length; i++)
		{
			array[i].color = Recolour(array[i].color, chosen);
		}
		val.SetKeys(array, (GradientAlphaKey[])original.alphaKeys.Clone());
		val.mode = original.mode;
		return val;
	}

	internal static object Map(object original, Color chosen)
	{
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: Expected O, but got Unknown
		object objectValue = RuntimeHelpers.GetObjectValue(original);
		Type type = objectValue.GetType();
		string[] array = new string[3] { "color", "colorMin", "colorMax" };
		foreach (string name in array)
		{
			PropertyInfo property = type.GetProperty(name);
			if (property != null && property.CanWrite)
			{
				property.SetValue(objectValue, Recolour((Color)property.GetValue(original, null), chosen), null);
			}
		}
		array = new string[3] { "gradient", "gradientMin", "gradientMax" };
		foreach (string name2 in array)
		{
			PropertyInfo property2 = type.GetProperty(name2);
			if (property2 != null && property2.CanWrite)
			{
				property2.SetValue(objectValue, RecolourGradient((Gradient)property2.GetValue(original, null), chosen), null);
			}
		}
		return objectValue;
	}

	internal void Apply(int packed, bool recolourLive = true)
	{
		//IL_0046: 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_00a9: 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)
		//IL_0290: Unknown result type (might be due to invalid IL or missing references)
		//IL_029c: Unknown result type (might be due to invalid IL or missing references)
		//IL_033a: Unknown result type (might be due to invalid IL or missing references)
		//IL_033f: Unknown result type (might be due to invalid IL or missing references)
		//IL_03aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_03be: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ca: Unknown result type (might be due to invalid IL or missing references)
		if (system == null || (packed == 0 && !tinted))
		{
			return;
		}
		if (mappedColour != packed)
		{
			foreach (CustomSetting customSetting in customSettings)
			{
				customSetting.mapped = ((packed == 0) ? Snapshot(customSetting.original) : Map(customSetting.original, WorldLight.Unpack(packed)));
			}
			foreach (Setting setting2 in settings)
			{
				setting2.mapped = ((packed == 0) ? Snapshot(setting2.original) : Map(setting2.original, setting2.primary ? WorldLight.Unpack(packed) : Color.white));
			}
			mappedColour = packed;
		}
		foreach (CustomSetting customSetting2 in customSettings)
		{
			setCustomColor.Invoke(customModule, new object[2] { customSetting2.stream, customSetting2.mapped });
		}
		foreach (Setting setting3 in settings)
		{
			setting3.property.SetValue(setting3.module, setting3.mapped, null);
		}
		tinted = packed != 0;
		if (packed == 0)
		{
			MethodInfo method = system.GetType().GetMethod("Clear", new Type[1] { typeof(bool) });
			if (method != null)
			{
				method.Invoke(system, new object[1] { false });
				return;
			}
		}
		if (!recolourLive || getParticles == null || setParticles == null || particleColor == null)
		{
			return;
		}
		PropertyInfo property = system.GetType().GetProperty("particleCount");
		int num = ((property != null) ? ((int)property.GetValue(system, null)) : 0);
		if (num > 0)
		{
			Array array = Array.CreateInstance(particleType, num);
			num = (int)getParticles.Invoke(system, new object[1] { array });
			Color chosen = ((packed == 0) ? Color.white : WorldLight.Unpack(packed));
			Setting setting = settings.Find((Setting s) => s.primary);
			MethodInfo methodInfo = setting?.original.GetType().GetMethod("Evaluate", new Type[2]
			{
				typeof(float),
				typeof(float)
			});
			PropertyInfo property2 = particleType.GetProperty("randomSeed");
			for (int num2 = 0; num2 < num; num2++)
			{
				object value = array.GetValue(num2);
				Color32 val = (Color32)particleColor.GetValue(value, null);
				float num3 = ((property2 == null) ? 0.5f : ((float)((uint)property2.GetValue(value, null) % 65536) / 65535f));
				Color val2 = (Color)((methodInfo == null) ? Color32.op_Implicit(val) : ((Color)methodInfo.Invoke(setting.original, new object[2] { num3, num3 })));
				particleColor.SetValue(value, Color32.op_Implicit((packed == 0) ? val2 : Recolour(val2, chosen)), null);
				array.SetValue(value, num2);
			}
			setParticles.Invoke(system, new object[2] { array, num });
		}
	}
}
internal static class PermanentFire
{
	internal const string FuelKey = "LightUpYourWorld.PermanentFuel";

	internal static bool Fueled(Fireplace fire)
	{
		if (!Object.op_Implicit((Object)(object)fire) || !Object.op_Implicit((Object)(object)((Component)fire).GetComponent<Piece>()) || !Object.op_Implicit((Object)(object)fire.m_fuelItem))
		{
			return false;
		}
		ZNetView component = ((Component)fire).GetComponent<ZNetView>();
		if (!Object.op_Implicit((Object)(object)component) || !component.IsValid())
		{
			return false;
		}
		ZDO zDO = component.GetZDO();
		if (!(zDO.GetFloat(ZDOVars.s_fuel, 0f) > 0f))
		{
			return zDO.GetFloat("LightUpYourWorld.PermanentFuel", 0f) > 0f;
		}
		return true;
	}
}
[HarmonyPatch(typeof(Fireplace), "UpdateFireplace")]
internal static class PreserveFireFuel
{
	private static void Prefix(Fireplace __instance, out bool __state)
	{
		__state = __instance.m_infiniteFuel;
		if (!PermanentFire.Fueled(__instance))
		{
			return;
		}
		__instance.m_infiniteFuel = true;
		ZNetView component = ((Component)__instance).GetComponent<ZNetView>();
		if (component.IsOwner())
		{
			ZDO zDO = component.GetZDO();
			float num = zDO.GetFloat("LightUpYourWorld.PermanentFuel", 0f);
			float num2 = zDO.GetFloat(ZDOVars.s_fuel, 0f);
			if (num <= 0f && num2 > 0f)
			{
				zDO.Set("LightUpYourWorld.PermanentFuel", num2);
			}
			else if (num > 0f && num2 <= 0f)
			{
				zDO.Set(ZDOVars.s_fuel, num);
			}
		}
	}

	private static void Finalizer(Fireplace __instance, bool __state)
	{
		__instance.m_infiniteFuel = __state;
	}
}
[HarmonyPatch(typeof(Fireplace), "IsBurning")]
internal static class KeepFueledFireBurning
{
	private static bool Prefix(Fireplace __instance, ref bool __result)
	{
		if (!PermanentFire.Fueled(__instance))
		{
			return true;
		}
		__result = true;
		return false;
	}
}
internal static class LightColour
{
	internal const string SaveKey = "LightUpYourWorld.Colour";

	internal static int Pack(byte r, byte g, byte b)
	{
		return 0x1000000 | (r << 16) | (g << 8) | b;
	}

	internal static bool IsValid(int value)
	{
		if (value != 0)
		{
			return (value & -16777216) == 16777216;
		}
		return true;
	}

	internal static int Normalize(int value)
	{
		if (!IsValid(value))
		{
			return 0;
		}
		return value;
	}

	internal static byte Red(int value)
	{
		return (byte)(value >> 16);
	}

	internal static byte Green(int value)
	{
		return (byte)(value >> 8);
	}

	internal static byte Blue(int value)
	{
		return (byte)value;
	}
}
internal sealed class ColourSession
{
	internal int Saved { get; private set; }

	internal int Selected { get; private set; }

	internal bool Dirty { get; private set; }

	internal void Open(int saved)
	{
		int saved2 = (Selected = LightColour.Normalize(saved));
		Saved = saved2;
		Dirty = false;
	}

	internal void Preview(int value)
	{
		Selected = LightColour.Normalize(value);
		Dirty = Selected != Saved;
	}

	internal void Applied()
	{
		Saved = Selected;
		Dirty = false;
	}

	internal void Cancel(int latestSaved)
	{
		Open(latestSaved);
	}
}
internal static class MenuLayout
{
	internal static float Scale(float width, float height)
	{
		return Math.Min(height / 1100f, width / 1900f);
	}
}
internal static class LightFavourites
{
	internal const int Slots = 10;

	private const string Prefix = "LightUpYourWorld.Favourite.";

	private static readonly FieldInfo CustomData = AccessTools.Field(typeof(Player), "m_customData");

	private static Dictionary<string, string> Data(Player player)
	{
		if (!Object.op_Implicit((Object)(object)player) || !(CustomData != null))
		{
			return null;
		}
		return CustomData.GetValue(player) as Dictionary<string, string>;
	}

	internal static bool TryGet(Player player, int slot, out Color colour)
	{
		//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_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		colour = Color.white;
		if (slot < 0 || slot >= 10)
		{
			return false;
		}
		Dictionary<string, string> dictionary = Data(player);
		if (dictionary == null || !dictionary.TryGetValue("LightUpYourWorld.Favourite." + slot, out var value) || value == null || value.Length != 6)
		{
			return false;
		}
		if (!int.TryParse(value, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var result))
		{
			return false;
		}
		colour = new Color((float)((result >> 16) & 0xFF) / 255f, (float)((result >> 8) & 0xFF) / 255f, (float)(result & 0xFF) / 255f, 1f);
		return true;
	}

	internal static void Set(Player player, int slot, Color colour)
	{
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		if (slot >= 0 && slot < 10)
		{
			Dictionary<string, string> dictionary = Data(player);
			if (dictionary != null)
			{
				Color32 val = Color32.op_Implicit(colour);
				dictionary["LightUpYourWorld.Favourite." + slot] = val.r.ToString("X2") + val.g.ToString("X2") + val.b.ToString("X2");
			}
		}
	}

	internal static void Remove(Player player, int slot)
	{
		Dictionary<string, string> dictionary = Data(player);
		if (slot >= 0 && slot < 10)
		{
			dictionary?.Remove("LightUpYourWorld.Favourite." + slot);
		}
	}

	internal static int FirstEmpty(Player player)
	{
		for (int i = 0; i < 10; i++)
		{
			if (!TryGet(player, i, out var _))
			{
				return i;
			}
		}
		return 0;
	}
}
[HarmonyPatch(typeof(Hud), "UpdateCrosshair")]
internal static class NativeLightPrompt
{
	private static WorldLight lastLight;

	private static string lastNative;

	private static string lastPrompt;

	private static string combined;

	private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
	{
		//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: Expected O, but got Unknown
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d3: Expected O, but got Unknown
		List<CodeInstruction> list = new List<CodeInstruction>(instructions);
		int num = -1;
		int num2 = 0;
		for (int i = 0; i < list.Count; i++)
		{
			if (list[i].operand is MethodInfo { Name: "GetHoverText" } methodInfo && methodInfo.DeclaringType == typeof(Hoverable) && methodInfo.ReturnType == typeof(string) && methodInfo.GetParameters().Length == 0)
			{
				num = i;
				num2++;
			}
		}
		if (num2 != 1)
		{
			Debug.LogWarning((object)"[LightUpYourWorld] Unsupported hover method layout: prompt extension skipped. Colour-menu hotkey remains available.");
			return list;
		}
		list.Insert(num + 1, new CodeInstruction(OpCodes.Ldarg_1, (object)null));
		list.Insert(num + 2, new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(NativeLightPrompt), "Append", (Type[])null, (Type[])null)));
		return list;
	}

	private static string Append(string original, Player player)
	{
		LightUpYourWorldPlugin instance = LightUpYourWorldPlugin.Instance;
		if (string.IsNullOrEmpty(original) || !Object.op_Implicit((Object)(object)instance) || instance.IsOpen || !Object.op_Implicit((Object)(object)player) || (Object)(object)player != (Object)(object)Player.m_localPlayer || ((Character)player).InPlaceMode() || !LightUpYourWorldPlugin.CanTakeInput(player))
		{
			return original;
		}
		WorldLight worldLight = WorldLight.Find(((Humanoid)player).GetHoverObject());
		if (!Object.op_Implicit((Object)(object)worldLight))
		{
			return original;
		}
		string hoverPrompt = instance.HoverPrompt;
		if ((Object)(object)worldLight == (Object)(object)lastLight && original == lastNative && hoverPrompt == lastPrompt)
		{
			return combined;
		}
		lastLight = worldLight;
		lastNative = original;
		lastPrompt = hoverPrompt;
		combined = (original.Contains(hoverPrompt) ? original : (original.TrimEnd() + "\n" + hoverPrompt));
		return combined;
	}
}