Decompiled source of HipLantern v1.1.0

HipLantern.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using AzuExtendedPlayerInventory;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using ExtraSlotsAPI;
using HarmonyLib;
using HipLantern;
using HipLantern.Compatibility;
using JetBrains.Annotations;
using LocalizationManager;
using Microsoft.CodeAnalysis;
using ServerSync;
using Splatform;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using YamlDotNet.Serialization;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("Hip Lantern")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Hip Lantern")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("74d9df24-bd3c-4f53-b58e-f4171c9bd3ff")]
[assembly: AssemblyFileVersion("1.1.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.0.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace LocalizationManager
{
	[PublicAPI]
	public class Localizer
	{
		[CompilerGenerated]
		private sealed class <Load>d__12 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <Load>d__12(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0040: Unknown result type (might be due to invalid IL or missing references)
				//IL_004a: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitUntil((Func<bool>)(() => PlatformManager.DistributionPlatform != null && PlatformInitializer.PreferencesInitialized));
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if (string.IsNullOrEmpty(PlatformPrefs.GetString("language", "")))
					{
						PlatformPrefs.SetString("language", "English");
					}
					LoadLocalization(Localization.instance, Localization.instance.GetSelectedLanguage());
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private const string defaultLanguage = "English";

		private static readonly Dictionary<string, Dictionary<string, Func<string>>> PlaceholderProcessors;

		private static readonly Dictionary<string, Dictionary<string, string>> loadedTexts;

		private static readonly ConditionalWeakTable<Localization, string> localizationLanguage;

		private static readonly List<WeakReference<Localization>> localizationObjects;

		private static BaseUnityPlugin? _plugin;

		private static readonly List<string> fileExtensions;

		private static BaseUnityPlugin Plugin
		{
			get
			{
				//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b2: Expected O, but got Unknown
				if (_plugin == null)
				{
					IEnumerable<TypeInfo> source;
					try
					{
						source = Assembly.GetExecutingAssembly().DefinedTypes.ToList();
					}
					catch (ReflectionTypeLoadException ex)
					{
						source = from t in ex.Types
							where t != null
							select t.GetTypeInfo();
					}
					_plugin = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)source.First((TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t)));
				}
				return _plugin;
			}
		}

		private static void UpdatePlaceholderText(Localization localization, string key)
		{
			localizationLanguage.TryGetValue(localization, out string value);
			string text = loadedTexts[value][key];
			if (PlaceholderProcessors.TryGetValue(key, out Dictionary<string, Func<string>> value2))
			{
				text = value2.Aggregate(text, (string current, KeyValuePair<string, Func<string>> kv) => current.Replace("{" + kv.Key + "}", kv.Value()));
			}
			localization.AddWord(key, text);
		}

		public static void AddPlaceholder<T>(string key, string placeholder, ConfigEntry<T> config, Func<T, string>? convertConfigValue = null) where T : notnull
		{
			string key2 = key;
			string placeholder2 = placeholder;
			Func<T, string> convertConfigValue2 = convertConfigValue;
			ConfigEntry<T> config2 = config;
			if (convertConfigValue2 == null)
			{
				convertConfigValue2 = (T val) => val.ToString();
			}
			if (!PlaceholderProcessors.ContainsKey(key2))
			{
				PlaceholderProcessors[key2] = new Dictionary<string, Func<string>>();
			}
			config2.SettingChanged += delegate
			{
				UpdatePlaceholder();
			};
			if (loadedTexts.ContainsKey(Localization.instance.GetSelectedLanguage()))
			{
				UpdatePlaceholder();
			}
			void UpdatePlaceholder()
			{
				PlaceholderProcessors[key2][placeholder2] = () => convertConfigValue2(config2.Value);
				UpdatePlaceholderText(Localization.instance, key2);
			}
		}

		public static void AddText(string key, string text)
		{
			List<WeakReference<Localization>> list = new List<WeakReference<Localization>>();
			foreach (WeakReference<Localization> localizationObject in localizationObjects)
			{
				if (localizationObject.TryGetTarget(out var target))
				{
					Dictionary<string, string> dictionary = loadedTexts[localizationLanguage.GetOrCreateValue(target)];
					if (!target.m_translations.ContainsKey(key))
					{
						dictionary[key] = text;
						target.AddWord(key, text);
					}
				}
				else
				{
					list.Add(localizationObject);
				}
			}
			foreach (WeakReference<Localization> item in list)
			{
				localizationObjects.Remove(item);
			}
		}

		[IteratorStateMachine(typeof(<Load>d__12))]
		public static IEnumerator Load()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <Load>d__12(0);
		}

		private static void LoadLocalization(Localization __instance, string language)
		{
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Expected O, but got Unknown
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Expected O, but got Unknown
			if (!localizationLanguage.Remove(__instance))
			{
				localizationObjects.Add(new WeakReference<Localization>(__instance));
			}
			localizationLanguage.Add(__instance, language);
			Dictionary<string, string> localizationFiles = new Dictionary<string, string>();
			string[] prefixes = new string[2]
			{
				Plugin.Info.Metadata.Name + ".",
				Plugin.Info.Metadata.Name.Replace(" ", "") + "."
			};
			Scan(Paths.ConfigPath, warn: true);
			Scan(Paths.PluginPath, warn: false);
			byte[] array = LoadTranslationFromAssembly("English");
			if (array == null)
			{
				throw new Exception("Found no English localizations in mod " + Plugin.Info.Metadata.Name + ". Expected an embedded resource Translations/English.json or Translations/English.yml.");
			}
			Dictionary<string, string> dictionary = ((BuilderSkeleton<DeserializerBuilder>)new DeserializerBuilder()).IgnoreFields().Build().Deserialize<Dictionary<string, string>>(Encoding.UTF8.GetString(array));
			if (dictionary == null)
			{
				throw new Exception("Localization for mod " + Plugin.Info.Metadata.Name + " failed: Localization file was empty.");
			}
			string text = null;
			if (language != "English")
			{
				if (localizationFiles.ContainsKey(language))
				{
					text = File.ReadAllText(localizationFiles[language]);
				}
				else
				{
					byte[] array2 = LoadTranslationFromAssembly(language);
					if (array2 != null)
					{
						text = Encoding.UTF8.GetString(array2);
					}
				}
			}
			if (text == null && localizationFiles.ContainsKey("English"))
			{
				text = File.ReadAllText(localizationFiles["English"]);
			}
			if (text != null)
			{
				Dictionary<string, string> dictionary2;
				try
				{
					dictionary2 = ((BuilderSkeleton<DeserializerBuilder>)new DeserializerBuilder()).IgnoreFields().Build().Deserialize<Dictionary<string, string>>(text) ?? new Dictionary<string, string>();
				}
				catch (Exception arg)
				{
					global::HipLantern.HipLantern.LogInfo($"Failed to deserialize localization for language '{language}'. Using base localization only.\n{arg}");
					dictionary2 = new Dictionary<string, string>();
				}
				foreach (KeyValuePair<string, string> item in dictionary2)
				{
					dictionary[item.Key] = item.Value;
				}
			}
			loadedTexts[language] = dictionary;
			foreach (KeyValuePair<string, string> item2 in dictionary)
			{
				UpdatePlaceholderText(__instance, item2.Key);
			}
			void Scan(string root, bool warn)
			{
				foreach (string item3 in from f in Directory.GetFiles(root, "*.*", SearchOption.AllDirectories)
					where fileExtensions.Contains(Path.GetExtension(f))
					select f)
				{
					string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(item3);
					string[] array3 = prefixes;
					foreach (string text2 in array3)
					{
						if (fileNameWithoutExtension.StartsWith(text2))
						{
							string text3 = fileNameWithoutExtension.Substring(text2.Length);
							if (!string.IsNullOrWhiteSpace(text3))
							{
								if (localizationFiles.ContainsKey(text3))
								{
									if (warn)
									{
										global::HipLantern.HipLantern.LogInfo("Duplicate localization '" + text3 + "' for " + Plugin.Info.Metadata.Name + ". Skipping " + item3);
									}
								}
								else
								{
									localizationFiles[text3] = item3;
								}
							}
							break;
						}
					}
				}
			}
		}

		static Localizer()
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			PlaceholderProcessors = new Dictionary<string, Dictionary<string, Func<string>>>();
			loadedTexts = new Dictionary<string, Dictionary<string, string>>();
			localizationLanguage = new ConditionalWeakTable<Localization, string>();
			localizationObjects = new List<WeakReference<Localization>>();
			fileExtensions = new List<string> { ".json", ".yml" };
			Harmony val = new Harmony("org.bepinex.helpers.LocalizationManager");
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "LoadCSV", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "LoadLocalization", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		private static byte[]? LoadTranslationFromAssembly(string language)
		{
			foreach (string fileExtension in fileExtensions)
			{
				byte[] array = ReadEmbeddedFileBytes("Translations." + language + fileExtension);
				if (array != null)
				{
					return array;
				}
			}
			return null;
		}

		public static byte[]? ReadEmbeddedFileBytes(string resourceFileName, Assembly? containingAssembly = null)
		{
			string resourceFileName2 = resourceFileName;
			using MemoryStream memoryStream = new MemoryStream();
			if ((object)containingAssembly == null)
			{
				containingAssembly = Assembly.GetCallingAssembly();
			}
			string text = containingAssembly.GetManifestResourceNames().FirstOrDefault((string str) => str.EndsWith(resourceFileName2, StringComparison.Ordinal));
			if (text != null)
			{
				containingAssembly.GetManifestResourceStream(text)?.CopyTo(memoryStream);
			}
			return (memoryStream.Length == 0L) ? null : memoryStream.ToArray();
		}
	}
}
namespace HipLantern
{
	[Serializable]
	public class HumanoidHipLantern
	{
		public ItemData lantern;

		public HumanoidHipLantern()
		{
			lantern = null;
		}
	}
	public static class HumanoidExtension
	{
		[HarmonyPatch(typeof(Humanoid), "SetupVisEquipment")]
		public static class Humanoid_SetupVisEquipment_CustomItemType
		{
			private static void Postfix(Humanoid __instance, VisEquipment visEq)
			{
				if (!HipLantern.itemSlotUtility.Value)
				{
					ItemData hipLantern = __instance.GetHipLantern();
					visEq.SetLanternItem((hipLantern != null) ? ((Object)hipLantern.m_dropPrefab).name : "", LanternItem.IsLightEnabled(hipLantern), LanternItem.IsHeatEnabled(hipLantern));
				}
			}
		}

		[HarmonyPatch(typeof(Humanoid), "GetEquipmentWeight")]
		public static class Humanoid_GetEquipmentWeight_CustomItemType
		{
			private static void Postfix(Humanoid __instance, ref float __result)
			{
				if (!HipLantern.itemSlotUtility.Value)
				{
					ItemData hipLantern = __instance.GetHipLantern();
					if (hipLantern != null)
					{
						__result += hipLantern.m_shared.m_weight;
					}
				}
			}
		}

		private static readonly ConditionalWeakTable<Humanoid, HumanoidHipLantern> data = new ConditionalWeakTable<Humanoid, HumanoidHipLantern>();

		public static HumanoidHipLantern GetLanternData(this Humanoid humanoid)
		{
			return data.GetOrCreateValue(humanoid);
		}

		public static ItemData GetHipLantern(this Humanoid humanoid)
		{
			return humanoid.GetLanternData().lantern;
		}

		public static ItemData SetHipLantern(this Humanoid humanoid, ItemData item)
		{
			return humanoid.GetLanternData().lantern = item;
		}
	}
	[Serializable]
	public class VisEquipmentHipLantern
	{
		public string m_lanternItem = "";

		public List<GameObject> m_lanternItemInstances;

		public int m_currentlanternItemHash = 0;

		public static readonly int s_lanternItem = StringExtensionMethods.GetStableHashCode("LanternItem");
	}
	public static class VisEquipmentExtension
	{
		[HarmonyPatch(typeof(VisEquipment), "UpdateEquipmentVisuals")]
		public static class VisEquipment_UpdateEquipmentVisuals_CustomItemType
		{
			private static void Prefix(VisEquipment __instance)
			{
				if (HipLantern.itemSlotUtility.Value)
				{
					return;
				}
				int hash = 0;
				ZDO zDO = __instance.m_nview.GetZDO();
				if (zDO != null)
				{
					hash = zDO.GetInt(VisEquipmentHipLantern.s_lanternItem, 0);
				}
				else
				{
					VisEquipmentHipLantern lanternData = __instance.GetLanternData();
					if (!string.IsNullOrEmpty(lanternData.m_lanternItem))
					{
						hash = StringExtensionMethods.GetStableHashCode(lanternData.m_lanternItem);
					}
				}
				if (__instance.SetLanternEquipped(hash))
				{
					__instance.UpdateLodgroup();
				}
			}
		}

		private static readonly ConditionalWeakTable<VisEquipment, VisEquipmentHipLantern> data = new ConditionalWeakTable<VisEquipment, VisEquipmentHipLantern>();

		public static VisEquipmentHipLantern GetLanternData(this VisEquipment visEquipment)
		{
			return data.GetOrCreateValue(visEquipment);
		}

		public static void SetLanternItem(this VisEquipment visEquipment, string name, bool lightEnabled, bool heatEnabled)
		{
			VisEquipmentHipLantern lanternData = visEquipment.GetLanternData();
			if (!(lanternData.m_lanternItem == name))
			{
				lanternData.m_lanternItem = name;
				if (visEquipment.m_nview.GetZDO() != null && visEquipment.m_nview.IsOwner())
				{
					visEquipment.m_nview.GetZDO().Set(VisEquipmentHipLantern.s_lanternItem, (!string.IsNullOrEmpty(name)) ? StringExtensionMethods.GetStableHashCode(name) : 0, false);
				}
			}
			ZDO zDO = visEquipment.m_nview.GetZDO();
			if (zDO != null && visEquipment.m_nview.IsOwner())
			{
				zDO.Set(LanternItem.s_lanternLightEnabled, lightEnabled);
				zDO.Set(LanternItem.s_lanternHeatEnabled, heatEnabled);
			}
		}

		public static bool SetLanternEquipped(this VisEquipment visEquipment, int hash)
		{
			VisEquipmentHipLantern lanternData = visEquipment.GetLanternData();
			if (lanternData.m_currentlanternItemHash == hash)
			{
				return false;
			}
			if (lanternData.m_lanternItemInstances != null)
			{
				foreach (GameObject lanternItemInstance in lanternData.m_lanternItemInstances)
				{
					if (Object.op_Implicit((Object)(object)visEquipment.m_lodGroup))
					{
						Utils.RemoveFromLodgroup(visEquipment.m_lodGroup, lanternItemInstance);
					}
					Object.Destroy((Object)(object)lanternItemInstance);
				}
				lanternData.m_lanternItemInstances = null;
			}
			lanternData.m_currentlanternItemHash = hash;
			if (hash != 0)
			{
				lanternData.m_lanternItemInstances = visEquipment.AttachArmor(hash, -1);
			}
			return true;
		}
	}
	internal static class CustomItemType
	{
		[HarmonyPatch(typeof(Humanoid), "EquipItem")]
		public static class Humanoid_EquipItem_CustomItemType
		{
			private static void Postfix(Humanoid __instance, ItemData item, ref bool __result, bool triggerEquipEffects)
			{
				if (!HipLantern.itemSlotUtility.Value && LanternItem.IsLanternItem(item))
				{
					if (__instance.GetHipLantern() != null)
					{
						__instance.UnequipItem(__instance.GetHipLantern(), triggerEquipEffects);
						__instance.m_visEquipment.UpdateEquipmentVisuals();
					}
					__instance.SetHipLantern(item);
					if (__instance.IsItemEquiped(item))
					{
						item.m_equipped = true;
						__result = true;
					}
					__instance.SetupEquipment();
				}
			}
		}

		[HarmonyPatch(typeof(Humanoid), "UnequipItem")]
		public static class Humanoid_UnequipItem_CustomItemType
		{
			private static void Postfix(Humanoid __instance, ItemData item)
			{
				if (!HipLantern.itemSlotUtility.Value && LanternItem.IsLanternItem(item) && __instance.GetHipLantern() == item)
				{
					__instance.SetHipLantern(null);
					__instance.SetupEquipment();
				}
			}
		}

		[HarmonyPatch(typeof(Humanoid), "UnequipAllItems")]
		public class Humanoid_UnequipAllItems_CustomItemType
		{
			public static void Postfix(Humanoid __instance)
			{
				if (!HipLantern.itemSlotUtility.Value)
				{
					__instance.UnequipItem(__instance.GetHipLantern(), false);
				}
			}
		}

		[HarmonyPatch(typeof(Humanoid), "IsItemEquiped")]
		public static class Humanoid_IsItemEquiped_CustomItemType
		{
			private static void Postfix(Humanoid __instance, ItemData item, ref bool __result)
			{
				if (!HipLantern.itemSlotUtility.Value && LanternItem.IsLanternItem(item))
				{
					__result = __result || __instance.GetHipLantern() == item;
				}
			}
		}

		[HarmonyPatch(typeof(ItemData), "IsEquipable")]
		public static class ItemDropItemData_IsEquipable_CustomItemType
		{
			private static void Postfix(ItemData __instance, ref bool __result)
			{
				if (!HipLantern.itemSlotUtility.Value)
				{
					__result = __result || LanternItem.IsLanternType(__instance);
				}
			}
		}

		[HarmonyPatch(typeof(Inventory), "Changed")]
		public static class Inventory_Changed_CustomItemType
		{
			private static void Prefix(Inventory __instance)
			{
				Player localPlayer = Player.m_localPlayer;
				if (__instance == ((localPlayer != null) ? ((Humanoid)localPlayer).GetInventory() : null) && ((Humanoid)(object)Player.m_localPlayer).GetHipLantern() != null && !__instance.ContainsItem(((Humanoid)(object)Player.m_localPlayer).GetHipLantern()))
				{
					((Humanoid)(object)Player.m_localPlayer).SetHipLantern(null);
					((Humanoid)Player.m_localPlayer).SetupEquipment();
				}
			}
		}

		[HarmonyPatch(typeof(ItemStand), "Awake")]
		public static class ItemStand_Awake_LanternStand
		{
			private static void Postfix(ItemStand __instance)
			{
				//IL_0016: 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)
				if (__instance.m_supportedTypes.Contains((ItemType)19) && !__instance.m_supportedTypes.Contains(LanternItem.GetItemType()))
				{
					__instance.m_supportedTypes.Add(LanternItem.GetItemType());
				}
			}
		}
	}
	[BepInPlugin("shudnal.HipLantern", "Hip Lantern", "1.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class HipLantern : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(ZNetView), "Awake")]
		public static class ZNetView_Awake_AddPrefab
		{
			[HarmonyPriority(800)]
			private static bool Prefix()
			{
				return !prefabInit;
			}
		}

		[HarmonyPatch(typeof(ZSyncTransform), "Awake")]
		public static class ZSyncTransform_Awake_AddPrefab
		{
			[HarmonyPriority(800)]
			private static bool Prefix()
			{
				return !prefabInit;
			}
		}

		[HarmonyPatch(typeof(ZSyncTransform), "OnEnable")]
		public static class ZSyncTransform_OnEnable_AddPrefab
		{
			[HarmonyPriority(800)]
			private static bool Prefix()
			{
				return !prefabInit;
			}
		}

		[HarmonyPatch(typeof(ItemDrop), "Awake")]
		public static class ItemDrop_Awake_AddPrefab
		{
			[HarmonyPriority(800)]
			private static bool Prefix()
			{
				return !prefabInit;
			}
		}

		[HarmonyPatch(typeof(ItemDrop), "Start")]
		public static class ItemDrop_Start_AddPrefab
		{
			[HarmonyPriority(800)]
			private static bool Prefix()
			{
				return !prefabInit;
			}
		}

		public const string pluginID = "shudnal.HipLantern";

		public const string pluginName = "Hip Lantern";

		public const string pluginVersion = "1.1.0";

		private readonly Harmony harmony = new Harmony("shudnal.HipLantern");

		internal static readonly ConfigSync configSync = new ConfigSync("shudnal.HipLantern")
		{
			DisplayName = "Hip Lantern",
			CurrentVersion = "1.1.0",
			MinimumRequiredVersion = "1.1.0"
		};

		internal static HipLantern instance;

		private static ConfigEntry<bool> configLocked;

		private static ConfigEntry<bool> loggingEnabled;

		public static ConfigEntry<string> itemCraftingStation;

		public static ConfigEntry<int> itemMinStationLevel;

		public static ConfigEntry<string> itemRecipe;

		public static ConfigEntry<float> equipDuration;

		public static ConfigEntry<string> refuelCraftingStation;

		public static ConfigEntry<string> refuelRecipe;

		public static ConfigEntry<int> fuelMinutes;

		public static ConfigEntry<int> itemSlotType;

		public static ConfigEntry<bool> itemSlotUtility;

		public static ConfigEntry<bool> itemSlotAzuEPI;

		public static ConfigEntry<string> itemSlotNameAzuEPI;

		public static ConfigEntry<int> itemSlotIndexAzuEPI;

		public static ConfigEntry<bool> itemSlotExtraSlots;

		public static ConfigEntry<string> itemSlotNameExtraSlots;

		public static ConfigEntry<int> itemSlotIndexExtraSlots;

		public static ConfigEntry<bool> itemSlotExtraSlotsDiscovery;

		public static ConfigEntry<Color> lightColor;

		public static ConfigEntry<float> lightIntensityOutdoors;

		public static ConfigEntry<float> lightRangeOutdoors;

		public static ConfigEntry<float> lightShadowsOutdoors;

		public static ConfigEntry<float> lightIntensityIndoors;

		public static ConfigEntry<float> lightRangeIndoors;

		public static ConfigEntry<float> lightShadowsIndoors;

		public static ConfigEntry<float> lightIntensityStand;

		public static ConfigEntry<float> lightRangeStand;

		public static ConfigEntry<float> lightShadowsStand;

		public static ConfigEntry<float> attachScale;

		public static ConfigEntry<Vector3> attachPosition;

		public static ConfigEntry<Vector3> attachEuler;

		public static ConfigEntry<bool> lanternEnchantableEpicLoot;

		public static ConfigEntry<bool> lanternSocketableJewelcrafting;

		public static ConfigEntry<bool> heatEnabled;

		public static ConfigEntry<float> heatDurabilityMultiplier;

		public static ConfigEntry<float> heatRadius;

		public static ConfigEntry<bool> preventHeatInMountains;

		public static ConfigEntry<bool> preventHeatInDeepNorth;

		public static ConfigEntry<bool> keepHeatWhenColdProtected;

		public static ConfigEntry<bool> emitSoundEffects;

		private const string c_rootObjectName = "_shudnalRoot";

		private const string c_rootPrefabsName = "Prefabs";

		private static GameObject rootObject;

		private static GameObject rootPrefabs;

		public static GameObject hipLanternPrefab;

		public static Sprite itemIcon;

		public static Sprite itemIconOff;

		public static Sprite itemIconHeat;

		public static ConfigEntry<KeyboardShortcut> toggleLanternShortcut;

		public static ConfigEntry<KeyboardShortcut> toggleLanternHeatShortcut;

		public static bool prefabInit = false;

		private void Awake()
		{
			instance = this;
			ConfigInit();
			configSync.AddLockingConfigEntry<bool>(configLocked);
			harmony.PatchAll();
			Game.isModded = true;
			LoadIcons();
			UpdateCustomEquipSlot();
			((MonoBehaviour)this).StartCoroutine(Localizer.Load());
		}

		private void OnDestroy()
		{
			((BaseUnityPlugin)this).Config.Save();
			instance = null;
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
		}

		public static void LogInfo(object data)
		{
			if (loggingEnabled.Value)
			{
				((BaseUnityPlugin)instance).Logger.LogInfo(data);
			}
		}

		public void ConfigInit()
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_05bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_072e: Unknown result type (might be due to invalid IL or missing references)
			//IL_075d: Unknown result type (might be due to invalid IL or missing references)
			config("General", "NexusID", 2748, "Nexus mod ID for updates", synchronizedSetting: false);
			configLocked = config("General", "Lock Configuration", defaultValue: true, "Configuration is locked and can be changed by server admins only");
			loggingEnabled = config("General", "Logging enabled", defaultValue: false, "Enable logging. [Not Synced with Server]", synchronizedSetting: false);
			toggleLanternShortcut = config<KeyboardShortcut>("General", "Toggle lantern shortcut", new KeyboardShortcut((KeyCode)104, Array.Empty<KeyCode>()), "Toggle hip lantern light on/off for equipped lantern.");
			heatEnabled = config("Heat", "Enable heat mode", defaultValue: true, "Enable controllable heat mode for hip lantern.");
			heatDurabilityMultiplier = config("Heat", "Durability drain multiplier", 5f, "Durability drain multiplier when heat mode is enabled.");
			heatRadius = config("Heat", "Aura radius", 3f, "Heat aura radius.");
			toggleLanternHeatShortcut = config<KeyboardShortcut>("Heat", "Toggle lantern heat shortcut", new KeyboardShortcut((KeyCode)104, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }), "Toggle hip lantern heat aura on/off for equipped lantern.");
			preventHeatInMountains = config("Heat", "Disable heat in Mountains", defaultValue: true, "Going into Mountains will temporary disable heat mode.");
			preventHeatInDeepNorth = config("Heat", "Disable heat in Deep North", defaultValue: true, "Going into Deep North will temporary disable heat mode.");
			keepHeatWhenColdProtected = config("Heat", "Keep heat when cold protected", defaultValue: true, "Going into Deep North or Mountains will not temporary disable heat mode if player has protection from cold.");
			emitSoundEffects = config("Heat", "Emit sound effects on switch", defaultValue: true, "Emit different sound effects when light/heat is switched.");
			itemCraftingStation = config("Item", "Crafting station", "$piece_forge", "Station to craft item. Leave empty to craft with hands");
			itemMinStationLevel = config("Item", "Crafting station level", 1, "Minimum level of station required to craft and repair");
			itemRecipe = config("Item", "Recipe", "SurtlingCore:3,BronzeNails:10,FineWood:4", "Item recipe");
			equipDuration = config("Item", "Equip duration", 1f, "Equip duration in seconds.");
			itemCraftingStation.SettingChanged += delegate
			{
				LanternItem.SetLanternRecipes();
			};
			itemMinStationLevel.SettingChanged += delegate
			{
				LanternItem.SetLanternRecipes();
			};
			itemRecipe.SettingChanged += delegate
			{
				LanternItem.SetLanternRecipes();
			};
			equipDuration.SettingChanged += delegate
			{
				LanternItem.PatchLanternItemOnConfigChange();
			};
			refuelCraftingStation = config("Item - Fuel", "Crafting station", "", "Station to refuel item. Leave empty to refuel with hands");
			refuelRecipe = config("Item - Fuel", "Refuel recipe", "SurtlingCore:1", "Item recipe for refueling");
			fuelMinutes = config("Item - Fuel", "Fuel minutes", 240, "Time in minutes required to consume all fuel");
			refuelCraftingStation.SettingChanged += delegate
			{
				LanternItem.SetLanternRecipes();
			};
			refuelRecipe.SettingChanged += delegate
			{
				LanternItem.SetLanternRecipes();
			};
			fuelMinutes.SettingChanged += delegate
			{
				LanternItem.SetLanternRecipes();
			};
			refuelCraftingStation.SettingChanged += delegate
			{
				LanternItem.PatchLanternItemOnConfigChange();
			};
			refuelRecipe.SettingChanged += delegate
			{
				LanternItem.PatchLanternItemOnConfigChange();
			};
			fuelMinutes.SettingChanged += delegate
			{
				LanternItem.PatchLanternItemOnConfigChange();
			};
			itemSlotType = config("Item - Slot", "Slot type", 56, "Custom item slot type. Change it only if you have issues with other mods compatibility. Game restart is not needed.");
			itemSlotUtility = config("Item - Slot", "Use utility slot", defaultValue: false, "Just use utility slot. Custom slot setting will be ignored. Game restart is not needed.");
			itemSlotType.SettingChanged += delegate
			{
				LanternItem.PatchLanternItemOnConfigChange();
			};
			itemSlotUtility.SettingChanged += delegate
			{
				LanternItem.PatchLanternItemOnConfigChange();
				UpdateCustomEquipSlot();
			};
			itemSlotAzuEPI = config("Item - Slot", "AzuEPI - Create slot", defaultValue: false, "Create custom equipment slot with AzuExtendedPlayerInventory. Slot will be created/removed on config change.");
			itemSlotNameAzuEPI = config("Item - Slot", "AzuEPI - Slot name", "$hiplantern_slot", "Custom equipment slot name. Game restart is recommended after change.");
			itemSlotIndexAzuEPI = config("Item - Slot", "AzuEPI - Slot index", -1, "Slot index (position). Remove and add slot to apply changes.");
			itemSlotAzuEPI.SettingChanged += delegate
			{
				UpdateCustomEquipSlot();
			};
			itemSlotExtraSlots = config("Item - Slot", "ExtraSlots - Create slot", defaultValue: false, "Create custom equipment slot with ExtraSlots. Slot will be created/removed on config change.");
			itemSlotNameExtraSlots = config("Item - Slot", "ExtraSlots - Slot name", "$hiplantern_slot", "Custom equipment slot name.");
			itemSlotIndexExtraSlots = config("Item - Slot", "ExtraSlots - Slot index", -1, "Slot index (position). Remove and add slot to apply changes.");
			itemSlotExtraSlotsDiscovery = config("Item - Slot", "ExtraSlots - Available after discovery", defaultValue: true, "If enabled - slot will be active only if you know Lantern item.");
			itemSlotExtraSlots.SettingChanged += delegate
			{
				UpdateCustomEquipSlot();
				ExtraSlotsAPI.API.UpdateSlots();
			};
			lightColor = config<Color>("Light", "Color", new Color(1f, 0.62f, 0.48f), "Color of lantern light");
			lightIntensityOutdoors = config("Light - Outdoors", "Intensity", 1f, "Intensity of light");
			lightRangeOutdoors = config("Light - Outdoors", "Range", 30f, "Range of light");
			lightShadowsOutdoors = config("Light - Outdoors", "Shadows strength", 0.8f, "Strength of shadows");
			lightIntensityIndoors = config("Light - Indoors", "Intensity", 0.8f, "Intensity of light when in dungeons");
			lightRangeIndoors = config("Light - Indoors", "Range", 25f, "Range of light when in dungeons");
			lightShadowsIndoors = config("Light - Indoors", "Shadows strength", 0.9f, "Strength of shadows when in dungeons");
			lightIntensityStand = config("Light - Stand", "Intensity", 0.8f, "Intensity of light when attached to item stand");
			lightRangeStand = config("Light - Stand", "Range", 20f, "Range of light when attached to item stand");
			lightShadowsStand = config("Light - Stand", "Shadows strength", 0f, "Strength of shadows when attached to item stand");
			attachScale = config("Prefab - Attach", "Scale", 0.25f, "Local scale of attached prefab (localScale). Game restart required.");
			attachPosition = config<Vector3>("Prefab - Attach", "Position", new Vector3(-0.22f, -0.1f, 0.1f), "Local position of attached prefab (localPosition). Game restart required.");
			attachEuler = config<Vector3>("Prefab - Attach", "Rotation", new Vector3(306.55f, 215.5f, 117.64f), "Local rotation of attached prefab (localEulerAngles). Game restart required.");
			lanternEnchantableEpicLoot = config("Compatibility", "Make Lantern enchantable by EpicLoot", defaultValue: false, "Lantern will be made enchantable with enchants for Utility slot");
			lanternSocketableJewelcrafting = config("Compatibility", "Make Lantern socketable by Jewelcrafting", defaultValue: false, "Lantern will be made socketable with gems effect from Utility slot");
		}

		private ConfigEntry<T> config<T>(string group, string name, T defaultValue, ConfigDescription description, bool synchronizedSetting = true)
		{
			ConfigEntry<T> val = ((BaseUnityPlugin)this).Config.Bind<T>(group, name, defaultValue, description);
			SyncedConfigEntry<T> syncedConfigEntry = configSync.AddConfigEntry<T>(val);
			syncedConfigEntry.SynchronizedConfig = synchronizedSetting;
			return val;
		}

		private ConfigEntry<T> config<T>(string group, string name, T defaultValue, string description, bool synchronizedSetting = true)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			return config(group, name, defaultValue, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()), synchronizedSetting);
		}

		private void LoadIcons()
		{
			LoadIcon("lantern.png", ref itemIcon);
			LoadIcon("lantern_off.png", ref itemIconOff);
			LoadIcon("lantern_heat.png", ref itemIconHeat);
		}

		private void LoadIcon(string filename, ref Sprite icon)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected O, but got Unknown
			//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)
			Texture2D tex = new Texture2D(2, 2);
			if (LoadTexture(filename, ref tex))
			{
				icon = Sprite.Create(tex, new Rect(0f, 0f, (float)((Texture)tex).width, (float)((Texture)tex).height), Vector2.zero);
			}
		}

		private bool LoadTexture(string filename, ref Texture2D tex)
		{
			string text = Path.Combine(Paths.PluginPath, filename);
			if (File.Exists(text))
			{
				LogInfo("Loaded image: " + text);
				return ImageConversion.LoadImage(tex, File.ReadAllBytes(text));
			}
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			string name = executingAssembly.GetManifestResourceNames().Single((string str) => str.EndsWith(filename));
			Stream manifestResourceStream = executingAssembly.GetManifestResourceStream(name);
			byte[] array = new byte[manifestResourceStream.Length];
			manifestResourceStream.Read(array, 0, array.Length);
			return ImageConversion.LoadImage(tex, array, true);
		}

		public static void UpdateCustomEquipSlot()
		{
			if (AzuExtendedPlayerInventory.API.IsLoaded())
			{
				bool flag = AzuExtendedPlayerInventory.API.GetSlots().SlotNames.Any((string slotName) => slotName == itemSlotNameAzuEPI.Value);
				if (flag && (itemSlotUtility.Value || !itemSlotAzuEPI.Value))
				{
					AzuExtendedPlayerInventory.API.RemoveSlot(itemSlotNameAzuEPI.Value);
				}
				else if (!flag && !itemSlotUtility.Value && itemSlotAzuEPI.Value)
				{
					AzuExtendedPlayerInventory.API.AddSlot(itemSlotNameAzuEPI.Value, (Player player) => ((Humanoid)(object)player).GetHipLantern(), (ItemData item) => LanternItem.IsLanternItem(item), itemSlotIndexAzuEPI.Value);
				}
			}
			else
			{
				if (!ExtraSlotsAPI.API.IsReady() || Chainloader.PluginInfos.ContainsKey("shudnal.ExtraSlotsCustomSlots"))
				{
					return;
				}
				bool flag2 = ExtraSlotsAPI.API.FindSlot("HipLantern") != null;
				if (!flag2 && !itemSlotUtility.Value && itemSlotExtraSlots.Value)
				{
					if (itemSlotIndexExtraSlots.Value < 0)
					{
						ExtraSlotsAPI.API.AddSlotAfter("HipLantern", () => itemSlotNameExtraSlots.Value, (ItemData item) => LanternItem.IsLanternItem(item), () => LanternItem.IsLanternSlotAvailable(), "CircletExtended");
					}
					else
					{
						ExtraSlotsAPI.API.AddSlotWithIndex("HipLantern", itemSlotIndexExtraSlots.Value, () => itemSlotNameExtraSlots.Value, (ItemData item) => LanternItem.IsLanternItem(item), () => LanternItem.IsLanternSlotAvailable());
					}
				}
				else if (flag2 && (itemSlotUtility.Value || !itemSlotExtraSlots.Value))
				{
					ExtraSlotsAPI.API.RemoveSlot("HipLantern");
				}
			}
		}

		public static bool IsShortcutDown(KeyboardShortcut shortcut)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			return (int)((KeyboardShortcut)(ref shortcut)).MainKey != 0 && ZInput.GetKeyDown(((KeyboardShortcut)(ref shortcut)).MainKey, true) && ((KeyboardShortcut)(ref shortcut)).Modifiers.All((KeyCode key) => ZInput.GetKey(key, true));
		}

		private static void InitRootObject()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Expected O, but got Unknown
			if ((Object)(object)rootObject == (Object)null)
			{
				rootObject = (GameObject)(((object)GameObject.Find("_shudnalRoot")) ?? ((object)new GameObject("_shudnalRoot")));
			}
			Object.DontDestroyOnLoad((Object)(object)rootObject);
			if ((Object)(object)rootPrefabs == (Object)null)
			{
				Transform obj = rootObject.transform.Find("Prefabs");
				rootPrefabs = ((obj != null) ? ((Component)obj).gameObject : null);
				if ((Object)(object)rootPrefabs == (Object)null)
				{
					rootPrefabs = new GameObject("Prefabs");
					rootPrefabs.transform.SetParent(rootObject.transform, false);
					rootPrefabs.SetActive(false);
				}
			}
		}

		internal static GameObject InitPrefabClone(GameObject prefabToClone, string prefabName)
		{
			InitRootObject();
			if ((Object)(object)rootPrefabs.transform.Find(prefabName) != (Object)null)
			{
				return ((Component)rootPrefabs.transform.Find(prefabName)).gameObject;
			}
			prefabInit = true;
			GameObject val = Object.Instantiate<GameObject>(prefabToClone, rootPrefabs.transform, false);
			prefabInit = false;
			((Object)val).name = prefabName;
			return val;
		}
	}
	internal static class LanternItem
	{
		[Serializable]
		private class LanternStateData
		{
			public bool lightEnabled = true;

			public bool heatEnabled = false;
		}

		[HarmonyPatch(typeof(ItemData), "GetTooltip", new Type[]
		{
			typeof(ItemData),
			typeof(int),
			typeof(bool),
			typeof(float),
			typeof(int)
		})]
		private class ItemDropItemData_GetTooltip_ItemTooltip
		{
			[HarmonyPriority(0)]
			private static void Postfix(ItemData item, ref string __result)
			{
				if (IsLanternItem(item))
				{
					__result = __result.Replace("$item_durability", "$piece_fire_fuel");
					UpdateLanternVariant(item);
				}
			}
		}

		[HarmonyPatch(typeof(Player), "Update")]
		private static class Player_Update_ToggleLanternModes
		{
			private static void Postfix(Player __instance)
			{
				//IL_0028: Unknown result type (might be due to invalid IL or missing references)
				//IL_003e: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer)
				{
					return;
				}
				bool flag = HipLantern.heatEnabled.Value && HipLantern.IsShortcutDown(HipLantern.toggleLanternHeatShortcut.Value);
				bool flag2 = !flag && HipLantern.IsShortcutDown(HipLantern.toggleLanternShortcut.Value);
				if (!flag2 && !flag)
				{
					return;
				}
				ItemData equippedLantern = GetEquippedLantern((Humanoid)(object)__instance);
				if (!IsLanternItem(equippedLantern))
				{
					return;
				}
				bool flag3 = IsLightEnabled(equippedLantern);
				bool flag4 = IsHeatEnabled(equippedLantern);
				bool flag5 = flag3;
				bool flag6 = flag4;
				if (flag2)
				{
					flag5 = !flag5;
					if (!flag5)
					{
						flag6 = false;
					}
				}
				if (flag)
				{
					flag6 = !flag6;
					if (flag6)
					{
						flag5 = true;
					}
				}
				bool flag7 = false;
				flag7 |= SetLightEnabled(equippedLantern, flag5);
				if (flag7 | SetHeatEnabled(equippedLantern, flag6))
				{
					((Humanoid)__instance).SetupEquipment();
					Inventory inventory = ((Humanoid)__instance).GetInventory();
					if (inventory != null)
					{
						inventory.Changed();
					}
				}
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "Awake")]
		private static class InventoryGui_Awake_AddLanternTooltipHint
		{
			private static bool s_initialized;

			private static void Postfix(InventoryGui __instance)
			{
				//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a6: Expected O, but got Unknown
				//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
				if (s_initialized)
				{
					return;
				}
				InventoryGrid playerGrid = __instance.m_playerGrid;
				object obj;
				if (playerGrid == null)
				{
					obj = null;
				}
				else
				{
					GameObject elementPrefab = playerGrid.m_elementPrefab;
					obj = ((elementPrefab != null) ? elementPrefab.GetComponent<UITooltip>() : null);
				}
				UITooltip val = (UITooltip)obj;
				if (!((Object)(object)val == (Object)null))
				{
					GameObject tooltipPrefab = val.m_tooltipPrefab;
					Transform val2 = ((tooltipPrefab != null) ? tooltipPrefab.transform.Find("Bkg") : null);
					object obj2;
					if (val2 == null)
					{
						obj2 = null;
					}
					else
					{
						Transform obj3 = val2.Find("Text");
						obj2 = ((obj3 != null) ? ((Component)obj3).GetComponent<TextMeshProUGUI>() : null);
					}
					TextMeshProUGUI val3 = (TextMeshProUGUI)obj2;
					if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val3 == (Object)null))
					{
						GameObject val4 = new GameObject("HipLanternSwitchHint");
						val4.transform.SetParent(val2, false);
						TextMeshProUGUI val5 = val4.AddComponent<TextMeshProUGUI>();
						((TMP_Text)val5).font = ((TMP_Text)val3).font;
						((TMP_Text)val5).fontSize = ((TMP_Text)val3).fontSize;
						((TMP_Text)val5).alignment = (TextAlignmentOptions)514;
						((Graphic)val5).color = ((Graphic)val3).color;
						((Graphic)val5).raycastTarget = false;
						ContentSizeFitter val6 = val4.AddComponent<ContentSizeFitter>();
						val6.horizontalFit = (FitMode)2;
						val6.verticalFit = (FitMode)2;
						val4.SetActive(false);
						((Component)val).gameObject.AddComponent<HipLanternTooltipState>();
						s_initialized = true;
					}
				}
			}
		}

		[HarmonyPatch(typeof(InventoryGrid), "CreateItemTooltip")]
		private static class InventoryGrid_CreateItemTooltip_LanternHint
		{
			private static void Postfix(ItemData item, UITooltip tooltip)
			{
				HipLanternTooltipState hipLanternTooltipState = ((tooltip != null) ? ((Component)tooltip).GetComponent<HipLanternTooltipState>() : null);
				if (!((Object)(object)hipLanternTooltipState == (Object)null))
				{
					hipLanternTooltipState.text = BuildLanternTooltipHint(item);
					ApplyLanternTooltipHint(tooltip, hipLanternTooltipState.text);
				}
			}
		}

		[HarmonyPatch(typeof(UITooltip), "UpdateTextElements")]
		private static class UITooltip_UpdateTextElements_LanternHint
		{
			private static void Postfix(UITooltip __instance)
			{
				GameObject tooltip = UITooltip.m_tooltip;
				Transform val = ((tooltip != null) ? tooltip.transform.Find("Bkg/HipLanternSwitchHint") : null);
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				HipLanternTooltipState component = ((Component)__instance).GetComponent<HipLanternTooltipState>();
				TextMeshProUGUI component2 = ((Component)val).GetComponent<TextMeshProUGUI>();
				if (!((Object)(object)component2 == (Object)null))
				{
					if ((Object)(object)component != (Object)null)
					{
						ApplyLanternTooltipHint(__instance, component.text);
					}
					else
					{
						((Component)val).gameObject.SetActive(false);
					}
				}
			}
		}

		[HarmonyPatch(typeof(ItemStand), "UseItem")]
		private static class ItemStand_UseItem_SyncLanternLight
		{
			private static void Postfix(ItemStand __instance, bool __result, ItemData item)
			{
				if (__result && IsLanternItem(item))
				{
					ZDO zDO = __instance.m_nview.GetZDO();
					if (zDO != null && __instance.m_nview.IsOwner())
					{
						zDO.Set(s_lanternLightEnabled, IsLightEnabled(item));
						zDO.Set(s_lanternHeatEnabled, IsHeatEnabled(item));
					}
				}
			}
		}

		[HarmonyPatch(typeof(ItemStand), "DropItem")]
		private static class ItemStand_DropItem_ClearLanternLightState
		{
			private static void Prefix(ItemStand __instance)
			{
				ZDO zDO = __instance.m_nview.GetZDO();
				if (zDO != null && __instance.m_nview.IsOwner() && IsLanternItemName(zDO.GetString(ZDOVars.s_item, "")))
				{
					zDO.Set(s_lanternLightEnabled, true);
					zDO.Set(s_lanternHeatEnabled, false);
				}
			}
		}

		private class HipLanternTooltipState : MonoBehaviour
		{
			public string text;
		}

		[HarmonyPatch(typeof(Humanoid), "UpdateEquipment")]
		public static class Humanoid_UpdateEquipment_CustomItemType
		{
			private static void Finalizer(Humanoid __instance, float dt)
			{
				if (((Character)__instance).IsPlayer())
				{
					ItemData hipLantern = __instance.GetHipLantern();
					if (hipLantern != null && hipLantern.m_shared.m_useDurability && (!hipLantern.m_shared.m_canBeReparied || (Object)(object)((Player)((__instance is Player) ? __instance : null)).GetCurrentCraftingStation() == (Object)null))
					{
						float num = ((IsHeatEnabled(hipLantern) && !IsHeatBlockedForPlayer((Player)(object)((__instance is Player) ? __instance : null))) ? Mathf.Max(1f, HipLantern.heatDurabilityMultiplier.Value) : 1f);
						__instance.DrainEquipedItemDurability(hipLantern, dt * num);
					}
				}
			}
		}

		[HarmonyPatch(typeof(ObjectDB), "Awake")]
		public static class ObjectDB_Awake_AddPrefab
		{
			private static void Postfix(ObjectDB __instance)
			{
				if (__instance.m_items.Count != 0 && !((Object)(object)__instance.GetItemPrefab("Wood") == (Object)null))
				{
					RegisterHipLanternPrefab();
				}
			}
		}

		[HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")]
		public static class ObjectDB_CopyOtherDB_AddPrefab
		{
			private static void Postfix(ObjectDB __instance)
			{
				if (__instance.m_items.Count != 0 && !((Object)(object)__instance.GetItemPrefab("Wood") == (Object)null))
				{
					RegisterHipLanternPrefab();
				}
			}
		}

		[HarmonyPatch(typeof(FejdStartup), "OnDestroy")]
		public static class FejdStartup_OnDestroy_AddPrefab
		{
			private static void Prefix()
			{
				ClearPrefabReferences();
			}
		}

		[HarmonyPatch(typeof(Player), "AddKnownItem")]
		public static class Player_AddKnownItem_LanternStats
		{
			private static void Postfix(ref ItemData item)
			{
				if (IsLanternItem(item))
				{
					PatchLanternItemData(item);
				}
			}
		}

		[HarmonyPatch(typeof(Player), "OnSpawned")]
		public class Player_OnSpawned_LanternStats
		{
			public static void Postfix(Player __instance)
			{
				if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
				{
					PatchInventory(((Humanoid)__instance).GetInventory());
				}
			}
		}

		[HarmonyPatch(typeof(Inventory), "Load")]
		public class Inventory_Load_LanternStats
		{
			public static void Postfix(Inventory __instance)
			{
				PatchInventory(__instance);
			}
		}

		[HarmonyPatch(typeof(ItemDrop), "Start")]
		public static class ItemDrop_Start_LanternStats
		{
			private static void Postfix(ref ItemDrop __instance)
			{
				if (IsLanternItem(__instance))
				{
					PatchLanternItemData(__instance.m_itemData);
				}
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "DoCrafting")]
		public class InventoryGui_DoCrafting_PreserveCustomData
		{
			public static readonly List<ItemData> lanternsBefore = new List<ItemData>();

			public static readonly List<ItemData> lanternsAfter = new List<ItemData>();

			public static void Prefix(InventoryGui __instance)
			{
				if (__instance.m_craftUpgradeItem == null && !((Object)(object)__instance.m_craftRecipe == (Object)null) && IsLanternItem(__instance.m_craftRecipe.m_item))
				{
					lanternsBefore.AddRange(((Humanoid)Player.m_localPlayer).GetInventory().GetAllItems().Where(IsLanternItem));
					lanternsAfter.Clear();
				}
			}

			[HarmonyPriority(0)]
			public static void Postfix()
			{
				//IL_0118: 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)
				if (lanternsBefore.Count == 0)
				{
					return;
				}
				ItemData val = lanternsBefore.Find((ItemData item) => !((Humanoid)Player.m_localPlayer).GetInventory().m_inventory.Contains(item));
				if (val != null && val.m_customData.Any())
				{
					lanternsAfter.AddRange(((Humanoid)Player.m_localPlayer).GetInventory().GetAllItems().Where(IsLanternItem));
					ItemData newLantern = lanternsAfter.Find((ItemData item) => !lanternsBefore.Contains(item));
					if (newLantern != null)
					{
						CollectionExtensions.Do<KeyValuePair<string, string>>((IEnumerable<KeyValuePair<string, string>>)val.m_customData, (Action<KeyValuePair<string, string>>)delegate(KeyValuePair<string, string> kvp)
						{
							newLantern.m_customData[kvp.Key] = kvp.Value;
						});
						if (EpicLootCompat.IsInstalled)
						{
							((Humanoid)Player.m_localPlayer).GetInventory().RemoveItem(newLantern);
							ItemDrop val2 = ItemDrop.DropItem(newLantern, 1, ((Component)Player.m_localPlayer).transform.position, ((Component)Player.m_localPlayer).transform.rotation);
							val2.OnPlayerDrop();
							((Humanoid)Player.m_localPlayer).Pickup(((Component)val2).gameObject, true, false);
						}
					}
				}
				lanternsBefore.Clear();
				lanternsAfter.Clear();
			}
		}

		public const string itemName = "HipLantern";

		public static int itemHash = StringExtensionMethods.GetStableHashCode("HipLantern");

		public const string itemDropName = "$item_hiplantern";

		public const string itemDropDescription = "$item_hiplantern_description";

		public const string c_customDataState = "HipLanternState";

		public static readonly int s_lanternLightEnabled = StringExtensionMethods.GetStableHashCode("HipLanternLightEnabled");

		public static readonly int s_lanternHeatEnabled = StringExtensionMethods.GetStableHashCode("HipLanternHeatEnabled");

		public static int s_lightMaskNonPlayer;

		public static int s_lightMaskPlayer;

		public const string c_pointLightName = "Point Light";

		public const string c_spotLightName = "Spot Light";

		public const float c_lightLodDistance = 40f;

		internal static bool IsLanternType(ItemData item)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			return item != null && item.m_shared.m_itemType == GetItemType();
		}

		internal static ItemType GetItemType()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			if (HipLantern.itemSlotUtility.Value)
			{
				return (ItemType)18;
			}
			return (ItemType)HipLantern.itemSlotType.Value;
		}

		internal static bool IsLanternItem(ItemDrop item)
		{
			return (Object)(object)item != (Object)null && (IsLanternItemName(item.GetPrefabName(((Object)item).name)) || IsLanternItem(item.m_itemData)) && IsLanternType(item.m_itemData);
		}

		public static bool IsLanternItem(ItemData item)
		{
			return item != null && IsLanternItemByName(item) && IsLanternType(item);
		}

		public static bool IsLanternItem(SharedData item)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			return item != null && item.m_itemType == GetItemType() && IsLanternItemDropName(item.m_name);
		}

		internal static bool IsLanternItemByName(ItemData item)
		{
			return item != null && (((Object)(object)item.m_dropPrefab != (Object)null && IsLanternItemName(((Object)item.m_dropPrefab).name)) || IsLanternItemDropName(item.m_shared.m_name));
		}

		internal static bool IsLanternItemDropName(string name)
		{
			return name == "$item_hiplantern";
		}

		internal static bool IsLanternItemName(string name)
		{
			return name == "HipLantern";
		}

		internal static bool IsLanternKnown()
		{
			if (!Object.op_Implicit((Object)(object)Player.m_localPlayer) || Player.m_localPlayer.m_isLoading)
			{
				return true;
			}
			return Player.m_localPlayer.IsKnownMaterial("$item_hiplantern");
		}

		internal static bool IsLanternSlotAvailable()
		{
			return HipLantern.itemSlotExtraSlots.Value && (!HipLantern.itemSlotExtraSlotsDiscovery.Value || IsLanternKnown());
		}

		internal static bool IsLightEnabled(ItemData item)
		{
			if (item == null)
			{
				return true;
			}
			return GetLanternState(item).lightEnabled;
		}

		internal static bool SetLightEnabled(ItemData item, bool enabled)
		{
			if (item == null)
			{
				return false;
			}
			bool result = IsLightEnabled(item) != enabled;
			LanternStateData lanternState = GetLanternState(item);
			lanternState.lightEnabled = enabled;
			if (!enabled)
			{
				lanternState.heatEnabled = false;
			}
			SaveLanternState(item, lanternState);
			UpdateLanternVariant(item);
			return result;
		}

		internal static bool IsHeatEnabled(ItemData item)
		{
			if (item == null || !HipLantern.heatEnabled.Value || !IsLightEnabled(item))
			{
				return false;
			}
			return GetLanternState(item).heatEnabled;
		}

		internal static bool SetHeatEnabled(ItemData item, bool enabled, bool force = false)
		{
			if (item == null)
			{
				return false;
			}
			bool flag = enabled && (force || (HipLantern.heatEnabled.Value && IsLightEnabled(item)));
			bool result = IsHeatEnabled(item) != flag;
			LanternStateData lanternState = GetLanternState(item);
			lanternState.heatEnabled = flag;
			SaveLanternState(item, lanternState);
			UpdateLanternVariant(item);
			return result;
		}

		private static LanternStateData GetLanternState(ItemData item)
		{
			LanternStateData lanternStateData = new LanternStateData();
			if (item?.m_customData == null || !item.m_customData.TryGetValue("HipLanternState", out var value) || string.IsNullOrWhiteSpace(value))
			{
				return lanternStateData;
			}
			return JsonUtility.FromJson<LanternStateData>(value) ?? lanternStateData;
		}

		private static void SaveLanternState(ItemData item, LanternStateData state)
		{
			if (item?.m_customData != null)
			{
				item.m_customData["HipLanternState"] = JsonUtility.ToJson((object)state);
			}
		}

		internal static void UpdateLanternVariant(ItemData item)
		{
			if (item != null)
			{
				item.m_variant = ((!IsLightEnabled(item)) ? 1 : (IsHeatEnabled(item) ? 2 : 0));
			}
		}

		private static ItemData GetEquippedLantern(Humanoid humanoid)
		{
			ItemData val = humanoid?.GetHipLantern();
			if (IsLanternItem(val))
			{
				return val;
			}
			if (((humanoid != null) ? humanoid.GetInventory() : null) == null)
			{
				return null;
			}
			return ((IEnumerable<ItemData>)humanoid.GetInventory().GetEquippedItems()).FirstOrDefault((Func<ItemData, bool>)IsLanternItem);
		}

		private static Transform AddCollider(Transform transform, string name, Type type)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			Transform transform2 = new GameObject(name, new Type[1] { type }).transform;
			transform2.SetParent(transform, false);
			return transform2;
		}

		private static void CreateHipLanternPrefab()
		{
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Expected O, but got Unknown
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_032a: Unknown result type (might be due to invalid IL or missing references)
			//IL_032f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0335: Unknown result type (might be due to invalid IL or missing references)
			//IL_033a: Unknown result type (might be due to invalid IL or missing references)
			//IL_033e: Unknown result type (might be due to invalid IL or missing references)
			//IL_034a: Unknown result type (might be due to invalid IL or missing references)
			//IL_034f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0353: Unknown result type (might be due to invalid IL or missing references)
			//IL_035f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0364: 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_0377: Unknown result type (might be due to invalid IL or missing references)
			//IL_037c: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0418: Unknown result type (might be due to invalid IL or missing references)
			//IL_0501: Unknown result type (might be due to invalid IL or missing references)
			//IL_050b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0527: Unknown result type (might be due to invalid IL or missing references)
			//IL_0565: Unknown result type (might be due to invalid IL or missing references)
			//IL_059d: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_063c: Unknown result type (might be due to invalid IL or missing references)
			GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("Lantern");
			if ((Object)(object)itemPrefab == (Object)null)
			{
				return;
			}
			if (s_lightMaskNonPlayer == 0)
			{
				s_lightMaskNonPlayer = LayerMask.GetMask(new string[12]
				{
					"Default", "static_solid", "Default_small", "piece", "piece_nonsolid", "terrain", "character_net", "character_ghost", "hitbox", "character_noenv",
					"vehicle", "item"
				});
			}
			if (s_lightMaskPlayer == 0)
			{
				s_lightMaskPlayer = LayerMask.GetMask(new string[1] { "character" });
			}
			HipLantern.hipLanternPrefab = HipLantern.InitPrefabClone(itemPrefab, "HipLantern");
			Object.DestroyImmediate((Object)(object)((Component)HipLantern.hipLanternPrefab.transform.Find("attach")).gameObject);
			Transform val = HipLantern.hipLanternPrefab.transform.Find("attach_back");
			((Object)val).name = "attach_BackTool_attach";
			Transform val2 = val.Find("default");
			val2.localScale = Vector3.one * HipLantern.attachScale.Value;
			val2.localPosition = HipLantern.attachPosition.Value;
			val2.localEulerAngles = HipLantern.attachEuler.Value;
			MeshRenderer component = ((Component)val2).GetComponent<MeshRenderer>();
			((Renderer)component).sharedMaterial = new Material(((Renderer)component).sharedMaterial)
			{
				name = ((Object)HipLantern.hipLanternPrefab).name + "_mat"
			};
			Transform val3 = val2.Find("Point Light");
			GameObject val4 = Object.Instantiate<GameObject>(((Component)val3).gameObject, val2);
			((Object)val4).name = "Spot Light";
			Light component2 = val4.GetComponent<Light>();
			component2.color = HipLantern.lightColor.Value;
			component2.cullingMask = s_lightMaskPlayer;
			component2.shadows = (LightShadows)0;
			component2.range = 1.5f;
			component2.intensity = 2f;
			LightLod component3 = val4.GetComponent<LightLod>();
			component3.m_lightDistance = 40f;
			component3.m_baseRange = component2.range;
			val4.GetComponent<LightFlicker>().m_baseIntensity = component2.intensity;
			Light component4 = ((Component)val3).GetComponent<Light>();
			component4.color = HipLantern.lightColor.Value;
			component4.cullingMask = s_lightMaskNonPlayer;
			component4.range = HipLantern.lightRangeOutdoors.Value;
			component4.intensity = HipLantern.lightIntensityOutdoors.Value;
			component4.shadowStrength = HipLantern.lightShadowsOutdoors.Value;
			LightFlicker component5 = ((Component)val3).GetComponent<LightFlicker>();
			component5.m_baseIntensity = component4.intensity;
			component5.m_flickerIntensity *= 0.6f;
			component5.m_flickerSpeed *= 0.6f;
			component5.m_movement = 0.02f;
			LightLod component6 = ((Component)val3).GetComponent<LightLod>();
			component6.m_lightDistance = 40f;
			component6.m_baseRange = component4.range;
			component6.m_baseShadowStrength = component4.shadowStrength;
			MainModule main = ((Component)val2.Find("flare")).GetComponent<ParticleSystem>().main;
			MinMaxGradient startColor = ((MainModule)(ref main)).startColor;
			float r = ((MinMaxGradient)(ref startColor)).color.r;
			startColor = ((MainModule)(ref main)).startColor;
			float g = ((MinMaxGradient)(ref startColor)).color.g;
			startColor = ((MainModule)(ref main)).startColor;
			((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(new Color(r, g, ((MinMaxGradient)(ref startColor)).color.b, 0.025f));
			((Component)val2).gameObject.AddComponent<LanternLightController>();
			GameObject gameObject = ((Component)AddCollider(val2, "HeatWarmth", typeof(SphereCollider))).gameObject;
			gameObject.layer = 14;
			gameObject.transform.localPosition = new Vector3(0f, 0.22f, 0f);
			SphereCollider component7 = gameObject.GetComponent<SphereCollider>();
			component7.radius = HipLantern.heatRadius.Value;
			((Collider)component7).isTrigger = true;
			((Collider)component7).enabled = true;
			EffectArea val5 = gameObject.gameObject.AddComponent<EffectArea>();
			val5.m_type = (Type)3;
			val5.m_playerOnly = true;
			val5.m_isHeatType = true;
			Transform val6 = val2.Find("SFX");
			if (val6 != null)
			{
				val6.SetParent(gameObject.transform);
				((Component)val6).GetComponent<AudioSource>().volume = 2f;
			}
			if (Object.op_Implicit((Object)(object)ObjectDB.instance))
			{
				GameObject itemPrefab2 = ObjectDB.instance.GetItemPrefab("Torch");
				if (itemPrefab2 != null)
				{
					Transform val7 = itemPrefab2.transform.Find("attach/equiped/fx_Torch_Carried/Local Flames");
					Transform val8 = Object.Instantiate<Transform>(val7, gameObject.transform);
					val8.localScale = Vector3.one * 0.4f;
					((Object)val8).name = "Heat Flames";
				}
			}
			Transform val9 = HipLantern.hipLanternPrefab.transform.Find("default");
			((Object)val9).name = "attach";
			val9.localScale = Vector3.one * 0.57f;
			val9.localPosition = new Vector3(0f, 0.012f, 0f);
			((Renderer)((Component)val9).GetComponent<MeshRenderer>()).sharedMaterial = ((Renderer)component).sharedMaterial;
			LightLod componentInChildren = ((Component)val9).GetComponentInChildren<LightLod>(true);
			((Component)componentInChildren).transform.localPosition = new Vector3(0f, 0.2f, 0f);
			((Component)componentInChildren).gameObject.SetActive(true);
			Transform val10 = val9.Find("flare");
			val10.localPosition = new Vector3(0f, 0.2f, 0f);
			((Component)val10).gameObject.SetActive(true);
			Ship? obj = ((IEnumerable<Ship>)Resources.FindObjectsOfTypeAll<Ship>()).FirstOrDefault((Func<Ship, bool>)((Ship ws) => ((Object)ws).name == "VikingShip"));
			Transform val11 = ((obj != null) ? ((Component)obj).transform.Find("ship/visual/Customize/TraderLamp/insects") : null);
			if (Object.op_Implicit((Object)(object)val11))
			{
				val11 = Object.Instantiate<Transform>(val11, val9);
				((Object)val11).name = "insects";
				((Component)val11).gameObject.SetActive(false);
				val11.localPosition = new Vector3(0f, 0.2f, 0f);
			}
			((Component)val9).gameObject.AddComponent<LanternLightController>();
			HipLantern.LogInfo("Created prefab " + ((Object)HipLantern.hipLanternPrefab).name);
		}

		internal static void PatchLanternItemData(ItemData itemData, bool inventoryItemUpdate = true)
		{
			if (itemData != null)
			{
				itemData.m_dropPrefab = HipLantern.hipLanternPrefab;
				PatchLanternSharedData(itemData.m_shared);
				UpdateLanternVariant(itemData);
				if (!inventoryItemUpdate)
				{
					itemData.m_durability = itemData.m_shared.m_maxDurability;
				}
			}
		}

		internal static void PatchLanternSharedData(SharedData itemSharedData)
		{
			//IL_008e: 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_00c4: Unknown result type (might be due to invalid IL or missing references)
			if (itemSharedData.m_icons == null || itemSharedData.m_icons.Length != 3)
			{
				itemSharedData.m_icons = (Sprite[])(object)new Sprite[3];
			}
			itemSharedData.m_icons[0] = HipLantern.itemIcon;
			itemSharedData.m_icons[1] = (Object.op_Implicit((Object)(object)HipLantern.itemIconOff) ? HipLantern.itemIconOff : HipLantern.itemIcon);
			itemSharedData.m_icons[2] = (Object.op_Implicit((Object)(object)HipLantern.itemIconHeat) ? HipLantern.itemIconHeat : HipLantern.itemIcon);
			itemSharedData.m_name = "$item_hiplantern";
			itemSharedData.m_description = "$item_hiplantern_description";
			itemSharedData.m_itemType = GetItemType();
			itemSharedData.m_maxStackSize = 1;
			itemSharedData.m_maxQuality = 1;
			itemSharedData.m_movementModifier = 0f;
			itemSharedData.m_equipDuration = HipLantern.equipDuration.Value;
			itemSharedData.m_attachOverride = (ItemType)19;
			itemSharedData.m_useDurability = UseFuel();
			itemSharedData.m_maxDurability = (UseFuel() ? HipLantern.fuelMinutes.Value : 200);
			itemSharedData.m_useDurabilityDrain = (UseFuel() ? 1f : 0f);
			itemSharedData.m_durabilityDrain = (UseFuel() ? (Time.fixedDeltaTime * (5f / 6f)) : 0f);
			itemSharedData.m_destroyBroken = false;
			itemSharedData.m_canBeReparied = !UseRefuel();
		}

		private static void RegisterHipLanternPrefab()
		{
			ClearPrefabReferences();
			if (!Object.op_Implicit((Object)(object)HipLantern.hipLanternPrefab))
			{
				CreateHipLanternPrefab();
			}
			if (!Object.op_Implicit((Object)(object)HipLantern.hipLanternPrefab))
			{
				return;
			}
			ItemData val = HipLantern.hipLanternPrefab.GetComponent<ItemDrop>()?.m_itemData;
			PatchLanternItemData(val, inventoryItemUpdate: false);
			if (Object.op_Implicit((Object)(object)ObjectDB.instance) && !ObjectDB.instance.m_itemByHash.ContainsKey(itemHash))
			{
				ObjectDB.instance.m_items.Add(HipLantern.hipLanternPrefab);
				ObjectDB.instance.m_itemByHash.Add(itemHash, HipLantern.hipLanternPrefab);
				if (val != null)
				{
					ObjectDB.instance.m_itemByData[val.m_shared] = HipLantern.hipLanternPrefab;
				}
			}
			if (Object.op_Implicit((Object)(object)ZNetScene.instance) && !ZNetScene.instance.m_namedPrefabs.ContainsKey(itemHash))
			{
				ZNetScene.instance.m_prefabs.Add(HipLantern.hipLanternPrefab);
				ZNetScene.instance.m_namedPrefabs.Add(itemHash, HipLantern.hipLanternPrefab);
			}
			SetLanternRecipes();
		}

		internal static void SetLanternRecipes()
		{
			//IL_02e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0306: Expected O, but got Unknown
			//IL_0241: 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_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0260: Expected O, but got Unknown
			//IL_03a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c6: Expected O, but got Unknown
			if (!Object.op_Implicit((Object)(object)ObjectDB.instance))
			{
				return;
			}
			if (ObjectDB.instance.m_recipes.RemoveAll((Recipe x) => IsLanternItemName(((Object)x).name)) > 0)
			{
				HipLantern.LogInfo("Replaced recipe HipLantern");
			}
			CraftingStation val = ((IEnumerable<Recipe>)ObjectDB.instance.m_recipes).FirstOrDefault((Func<Recipe, bool>)((Recipe rec) => rec.m_craftingStation?.m_name == "$piece_workbench"))?.m_craftingStation;
			CraftingStation val2 = (string.IsNullOrWhiteSpace(HipLantern.itemCraftingStation.Value) ? null : ((IEnumerable<Recipe>)ObjectDB.instance.m_recipes).FirstOrDefault((Func<Recipe, bool>)((Recipe rec) => rec.m_craftingStation?.m_name == HipLantern.itemCraftingStation.Value))?.m_craftingStation);
			CraftingStation val3 = (string.IsNullOrWhiteSpace(HipLantern.refuelCraftingStation.Value) ? null : ((IEnumerable<Recipe>)ObjectDB.instance.m_recipes).FirstOrDefault((Func<Recipe, bool>)((Recipe rec) => rec.m_craftingStation?.m_name == HipLantern.refuelCraftingStation.Value))?.m_craftingStation);
			ItemDrop component = HipLantern.hipLanternPrefab.GetComponent<ItemDrop>();
			Recipe val4 = ScriptableObject.CreateInstance<Recipe>();
			((Object)val4).name = "HipLantern";
			val4.m_amount = 1;
			val4.m_item = component;
			val4.m_enabled = true;
			val4.m_craftingStation = val2;
			val4.m_minStationLevel = ((!Object.op_Implicit((Object)(object)val2)) ? 1 : HipLantern.itemMinStationLevel.Value);
			val4.m_repairStation = (Object.op_Implicit((Object)(object)val2) ? null : (val3 ?? val));
			List<Requirement> list = new List<Requirement>();
			string[] array = HipLantern.itemRecipe.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries);
			foreach (string text in array)
			{
				string[] array2 = text.Split(new char[1] { ':' }, StringSplitOptions.RemoveEmptyEntries);
				if (array2.Length != 2)
				{
					continue;
				}
				int num = int.Parse(array2[1]);
				if (num > 0)
				{
					GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(array2[0].Trim());
					if (!((Object)(object)itemPrefab == (Object)null))
					{
						list.Add(new Requirement
						{
							m_amount = num,
							m_resItem = itemPrefab.GetComponent<ItemDrop>()
						});
					}
				}
			}
			val4.m_resources = list.ToArray();
			ObjectDB.instance.m_recipes.Add(val4);
			if (!UseRefuel())
			{
				return;
			}
			Recipe val5 = ScriptableObject.CreateInstance<Recipe>();
			((Object)val5).name = "HipLantern";
			val5.m_amount = 1;
			val5.m_minStationLevel = 1;
			val5.m_item = component;
			val5.m_enabled = true;
			val5.m_craftingStation = val3;
			List<Requirement> list2 = new List<Requirement>
			{
				new Requirement
				{
					m_amount = 1,
					m_resItem = component,
					m_recover = false
				}
			};
			string[] array3 = HipLantern.refuelRecipe.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries);
			foreach (string text2 in array3)
			{
				string[] array4 = text2.Split(new char[1] { ':' }, StringSplitOptions.RemoveEmptyEntries);
				if (array4.Length != 2)
				{
					continue;
				}
				int num2 = int.Parse(array4[1]);
				if (num2 > 0)
				{
					GameObject itemPrefab2 = ObjectDB.instance.GetItemPrefab(array4[0].Trim());
					if (!((Object)(object)itemPrefab2 == (Object)null))
					{
						list2.Add(new Requirement
						{
							m_amount = num2,
							m_resItem = itemPrefab2.GetComponent<ItemDrop>(),
							m_recover = false
						});
					}
				}
			}
			val5.m_resources = list2.ToArray();
			ObjectDB.instance.m_recipes.Add(val5);
		}

		private static void ClearPrefabReferences()
		{
			if (Object.op_Implicit((Object)(object)ObjectDB.instance) && ObjectDB.instance.m_itemByHash.ContainsKey(itemHash))
			{
				ObjectDB.instance.m_items.Remove(ObjectDB.instance.m_itemByHash[itemHash]);
				ObjectDB.instance.m_itemByHash.Remove(itemHash);
			}
			if (Object.op_Implicit((Object)(object)ZNetScene.instance) && ZNetScene.instance.m_namedPrefabs.ContainsKey(itemHash))
			{
				ZNetScene.instance.m_prefabs.Remove(ZNetScene.instance.m_namedPrefabs[itemHash]);
				ZNetScene.instance.m_namedPrefabs.Remove(itemHash);
			}
		}

		internal static bool UseFuel()
		{
			return HipLantern.fuelMinutes.Value > 0;
		}

		internal static bool UseRefuel()
		{
			return UseFuel() && !string.IsNullOrEmpty(HipLantern.refuelRecipe.Value);
		}

		internal static void PatchInventory(Inventory inventory)
		{
			if (inventory != null)
			{
				CollectionExtensions.DoIf<ItemData>((IEnumerable<ItemData>)inventory.GetAllItems(), (Func<ItemData, bool>)IsLanternItemByName, (Action<ItemData>)delegate(ItemData item)
				{
					PatchLanternItemData(item);
				});
			}
		}

		internal static void PatchLanternItemOnConfigChange()
		{
			GameObject hipLanternPrefab = HipLantern.hipLanternPrefab;
			PatchLanternItemData((hipLanternPrefab == null) ? null : hipLanternPrefab.GetComponent<ItemDrop>()?.m_itemData, inventoryItemUpdate: false);
			Player localPlayer = Player.m_localPlayer;
			PatchInventory((localPlayer != null) ? ((Humanoid)localPlayer).GetInventory() : null);
		}

		private static string GetHotkeyText(KeyboardShortcut shortcut)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			return $"[<color=yellow><b>{shortcut}</b></color>]";
		}

		private static string BuildLanternTooltipHint(ItemData item)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			if (!IsLanternItem(item))
			{
				return null;
			}
			if (!HipLantern.heatEnabled.Value)
			{
				return Localization.instance.Localize("$hiplantern_switch_light", new string[1] { GetHotkeyText(HipLantern.toggleLanternShortcut.Value) });
			}
			string text = (IsHeatBlockedForPlayer(Player.m_localPlayer) ? "$hiplantern_heat_mode_blocked" : (IsHeatEnabled(item) ? "$hiplantern_heat_mode" : ""));
			return Localization.instance.Localize("$hiplantern_switch_light\n$hiplantern_switch_heat\n" + text, new string[2]
			{
				GetHotkeyText(HipLantern.toggleLanternShortcut.Value),
				GetHotkeyText(HipLantern.toggleLanternHeatShortcut.Value)
			}).TrimEnd();
		}

		private static void ApplyLanternTooltipHint(UITooltip tooltip, string text)
		{
			GameObject tooltip2 = UITooltip.m_tooltip;
			Transform val = ((tooltip2 != null) ? tooltip2.transform.Find("Bkg/HipLanternSwitchHint") : null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			TextMeshProUGUI component = ((Component)val).GetComponent<TextMeshProUGUI>();
			if (!((Object)(object)component == (Object)null))
			{
				bool flag = !string.IsNullOrEmpty(text);
				((Component)val).gameObject.SetActive(flag);
				if (flag)
				{
					((TMP_Text)component).text = text;
				}
			}
		}

		internal static bool IsHeatBlockedForPlayer(Player player)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Invalid comparison between Unknown and I4
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Invalid comparison between Unknown and I4
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Invalid comparison between Unknown and I4
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Invalid comparison between Unknown and I4
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Invalid comparison between Unknown and I4
			if ((Object)(object)player == (Object)null)
			{
				return false;
			}
			Biome currentBiome = player.GetCurrentBiome();
			if (((int)currentBiome != 4 || !HipLantern.preventHeatInMountains.Value) && ((int)currentBiome != 64 || !HipLantern.preventHeatInDeepNorth.Value))
			{
				return false;
			}
			if (((Character)player).InInterior() || player.InShelter() || ShieldGenerator.IsInsideShield(((Component)player).transform.position))
			{
				return false;
			}
			if (!HipLantern.keepHeatWhenColdProtected.Value)
			{
				return true;
			}
			DamageModifiers damageModifiers = ((Character)player).GetDamageModifiers((WeakSpot)null);
			DamageModifier modifier = ((DamageModifiers)(ref damageModifiers)).GetModifier((DamageType)64);
			if ((int)modifier == 1 || (int)modifier == 5 || (int)modifier == 7 || (int)modifier == 3)
			{
				return false;
			}
			return true;
		}
	}
	public class LanternLightController : MonoBehaviour
	{
		[HarmonyPatch(typeof(Humanoid), "SetupEquipment")]
		public static class Humanoid_SetupVisEquipment_AttachLayersFix
		{
			private static void Postfix(Humanoid __instance)
			{
				UpdateVisualsLayers(((Character)__instance).m_visual);
			}
		}

		private Light m_mainLight;

		private LightFlicker m_mainLightFlicker;

		private LightLod m_mainLightLod;

		private Light m_spotLight;

		private Character m_character;

		private Material m_material;

		private ItemDrop m_itemDrop;

		private EffectArea m_effectArea;

		private ItemStand m_itemStand;

		private GameObject m_visual;

		private GameObject m_insects;

		private GameObject m_flare;

		private float m_updateVisualTimer = 0f;

		private bool m_isLightEnabled;

		private bool m_isHeatEnabled;

		private static readonly List<LanternLightController> Instances = new List<LanternLightController>();

		private static readonly List<GameObject> visualsToPatch = new List<GameObject>();

		public static readonly EffectList lampEffects = new EffectList();

		public const int effectLightEnable = 0;

		public const int effectLightDisable = 1;

		public const int effectHeatEnable = 2;

		public const int effectHeatDisable = 3;

		private const int c_characterLayer = 9;

		private const int c_defaultLayer = 0;

		private void Awake()
		{
			m_mainLight = ((Component)((Component)this).transform.Find("Point Light")).GetComponent<Light>();
			m_mainLightFlicker = ((Component)m_mainLight).GetComponent<LightFlicker>();
			m_mainLightLod = ((Component)m_mainLight).GetComponent<LightLod>();
			Transform obj = ((Component)this).transform.Find("Spot Light");
			m_spotLight = ((obj != null) ? ((Component)obj).GetComponent<Light>() : null);
			m_material = ((Renderer)((Component)this).GetComponent<MeshRenderer>()).sharedMaterial;
			Transform obj2 = ((Component)this).transform.Find("insects");
			m_insects = ((obj2 != null) ? ((Component)obj2).gameObject : null);
			Transform obj3 = ((Component)this).transform.Find("flare");
			m_flare = ((obj3 != null) ? ((Component)obj3).gameObject : null);
			m_itemDrop = ((Component)this).GetComponentInParent<ItemDrop>();
			m_effectArea = ((Component)this).GetComponentInChildren<EffectArea>();
			CheckEffects();
		}

		private void Start()
		{
			//IL_0091: 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)
			m_character = ((Component)((Component)this).transform.root).GetComponent<Character>();
			Character character = m_character;
			m_visual = ((character != null) ? character.GetVisual() : null);
			m_itemStand = ((Component)((Component)this).transform.root).GetComponent<ItemStand>();
			UpdateVisualLayers();
			if ((Object)(object)m_itemStand != (Object)null && Utils.GetPrefabName(((Component)m_itemStand).gameObject) == "itemstand")
			{
				((Component)this).transform.localPosition = new Vector3(0f, 0.086f, -0.1f);
				((Component)this).transform.localEulerAngles = new Vector3(90f, 0f, 0f);
			}
			if ((Object)(object)m_character != (Object)null && (Object)(object)m_effectArea != (Object)null)
			{
				m_effectArea.m_collidedWithCharacter.Add(m_character);
				EffectArea effectArea = m_effectArea;
				effectArea.m_collisions++;
			}
		}

		private void EmitSwitchEffect(int variant)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if (HipLantern.emitSoundEffects.Value)
			{
				lampEffects.Create(((Component)this).transform.position, ((Component)this).transform.rotation, (Transform)null, 1f, variant);
			}
		}

		private void Update()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: 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_02b5: Invalid comparison between Unknown and I4
			//IL_05c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0609: Unknown result type (might be due to invalid IL or missing references)
			//IL_047f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0494: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04be: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0325: Unknown result type (might be due to invalid IL or missing references)
			//IL_034e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0377: Unknown result type (might be due to invalid IL or missing references)
			//IL_0381: Unknown result type (might be due to invalid IL or missing references)
			m_mainLight.color = HipLantern.lightColor.Value;
			if (Object.op_Implicit((Object)(object)m_spotLight))
			{
				m_spotLight.color = HipLantern.lightColor.Value;
			}
			if (m_isLightEnabled != (m_isLightEnabled = IsLightEnabled()))
			{
				EmitSwitchEffect((!m_isLightEnabled) ? 1 : 0);
			}
			if (m_isHeatEnabled != (m_isHeatEnabled = IsHeatEnabled()))
			{
				EmitSwitchEffect(m_isHeatEnabled ? 2 : 3);
			}
			Light spotLight = m_spotLight;
			if (spotLight != null)
			{
				((Component)spotLight).gameObject.SetActive(m_isLightEnabled);
			}
			Light mainLight = m_mainLight;
			if (mainLight != null)
			{
				((Component)mainLight).gameObject.SetActive(m_isLightEnabled);
			}
			EffectArea effectArea = m_effectArea;
			if (effectArea != null)
			{
				((Component)effectArea).gameObject.SetActive(m_isLightEnabled && m_isHeatEnabled);
			}
			if (!m_isLightEnabled)
			{
				((Component)m_mainLight).gameObject.SetActive(false);
				Light spotLight2 = m_spotLight;
				if (spotLight2 != null)
				{
					((Component)spotLight2).gameObject.SetActive(false);
				}
				GameObject insects = m_insects;
				if (insects != null)
				{
					insects.SetActive(false);
				}
				GameObject flare = m_flare;
				if (flare != null)
				{
					flare.SetActive(false);
				}
				m_material.SetColor("_EmissionColor", Color.black);
			}
			else if ((Object)(object)m_itemDrop != (Object)null)
			{
				((Component)m_mainLight).gameObject.SetActive(false);
				GameObject flare2 = m_flare;
				if (flare2 != null)
				{
					flare2.SetActive(IsTimeToLight());
				}
				m_material.SetColor("_EmissionColor", HipLantern.lightColor.Value);
			}
			else if ((Object)(object)m_character == (Object)null)
			{
				m_mainLight.intensity = HipLantern.lightIntensityStand.Value;
				m_mainLightFlicker.m_baseIntensity = HipLantern.lightIntensityStand.Value;
				m_mainLight.range = HipLantern.lightRangeStand.Value;
				m_mainLight.shadowStrength = HipLantern.lightShadowsStand.Value;
				m_mainLightLod.m_lightDistance = 80f;
				m_mainLightLod.m_baseRange = HipLantern.lightRangeStand.Value;
				m_mainLightLod.m_baseShadowStrength = HipLantern.lightShadowsStand.Value;
				m_mainLight.shadows = (LightShadows)((m_mainLight.shadowStrength > 0f) ? 2 : 0);
				m_mainLightLod.m_shadowLod = (int)m_mainLight.shadows > 0;
				GameObject insects2 = m_insects;
				if (insects2 != null)
				{
					insects2.SetActive(IsNightTime());
				}
				GameObject flare3 = m_flare;
				if (flare3 != null)
				{
					flare3.SetActive(IsTimeToLight());
				}
				m_material.SetColor("_EmissionColor", new Color(HipLantern.lightColor.Value.r + (m_flare.activeSelf ? 0.25f : 0.1f), HipLantern.lightColor.Value.g + (m_flare.activeSelf ? 0.25f : 0.1f), HipLantern.lightColor.Value.b + (m_flare.activeSelf ? 0.25f : 0.1f), HipLantern.lightColor.Value.a));
			}
			else if (m_character.InInterior())
			{
				m_mainLight.intensity = HipLantern.lightIntensityIndoors.Value;
				m_mainLightFlicker.m_baseIntensity = HipLantern.lightIntensityIndoors.Value;
				m_mainLight.range = HipLantern.lightRangeIndoors.Value;
				m_mainLight.shadowStrength = HipLantern.lightShadowsIndoors.Value;
				m_mainLightLod.m_lightDistance = Mathf.Max(HipLantern.lightRangeIndoors.Value + 10f, 40f);
				m_mainLightLod.m_baseRange = HipLantern.lightRangeIndoors.Value;
				m_mainLightLod.m_baseShadowStrength = HipLantern.lightShadowsIndoors.Value;
				m_mainLight.shadows = (LightShadows)((m_mainLight.shadowStrength > 0f) ? 2 : 0);
				m_material.SetColor("_EmissionColor", new Color(HipLantern.lightColor.Value.r + 0.25f, HipLantern.lightColor.Value.g + 0.25f, HipLantern.lightColor.Value.b + 0.25f, HipLantern.lightColor.Value.a));
			}
			else
			{
				m_mainLight.intensity = HipLantern.lightIntensityOutdoors.Value;
				m_mainLightFlicker.m_baseIntensity = HipLantern.lightIntensityOutdoors.Value;
				m_mainLight.range = HipLantern.lightRangeOutdoors.Value;
				m_mainLight.shadowStrength = HipLantern.lightShadowsOutdoors.Value;
				m_mainLightLod.m_lightDistance = Mathf.Max(HipLantern.lightRangeOutdoors.Value + 10f, 40f);
				m_mainLightLod.m_baseRange = HipLantern.lightRangeOutdoors.Value;
				m_mainLightLod.m_baseShadowStrength = HipLantern.lightShadowsOutdoors.Value;
				m_mainLight.shadows = (LightShadows)(((Object)(object)m_character != (Object)null && m_mainLight.shadowStrength > 0f) ? 2 : 0);
				m_material.SetColor("_EmissionColor", new Color(HipLantern.lightColor.Value.r + 0.25f, HipLantern.lightColor.Value.g + 0.25f, HipLantern.lightColor.Value.b + 0.25f, HipLantern.lightColor.Value.a));
			}
		}

		private void FixedUpdate()
		{
			if (m_updateVisualTimer > 0f)
			{
				m_updateVisualTimer = Mathf.Max(0f, m_updateVisualTimer - Time.fixedDeltaTime);
				if (m_updateVisualTimer == 0f)
				{
					UpdateVisualLayers();
				}
			}
		}

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

		private void OnDisable()
		{
			Instances.Remove(this);
		}

		private void UpdateVisualLayers()
		{
			HashSet<GameObject> lanternCharacters = (from lantern in Instances
				where (Object)(object)lantern.m_visual != (Object)null
				select lantern.m_visual).ToHashSet();
			foreach (GameObject visual in visualsToPatch.Where((GameObject vis) => (Object)(object)vis != (Object)null))
			{
				GameObject obj = visual;
				if (obj == null)
				{
					continue;
				}
				Renderer[] componentsInChildren = obj.GetComponentsInChildren<Renderer>(true);
				if (componentsInChildren != null)
				{
					CollectionExtensions.DoIf<Renderer>((IEnumerable<Renderer>)componentsInChildren, (Func<Renderer, bool>)((Renderer ren) => (Object)(object)ren != (Object)null), (Action<Renderer>)delegate(Renderer ren)
					{
						((Component)ren).gameObject.layer = (lanternCharacters.Contains(visual) ? 9 : 0);
					});
				}
			}
			visualsToPatch.Clear();
		}

		private void StartUpdateVisualLayers()
		{
			m_updateVisualTimer = 0.5f;
		}

		internal static void UpdateVisualsLayers(GameObject visual)
		{
			visualsToPatch.Add(visual);
			LanternLightController lanternLightController = Instances.FirstOrDefault();
			if ((Object)(object)lanternLightController == (Object)null)
			{
				visualsToPatch.RemoveAll((GameObject vis) => (Object)(object)vis == (Object)null);
			}
			else
			{
				lanternLightController.StartUpdateVisualLayers();
			}
		}

		private bool IsNightTime()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			return ((Component)this).transform.position.y > 3000f || EnvMan.IsNight();
		}

		private bool IsTimeToLight()
		{
			if (IsNightTime())
			{
				return true;
			}
			if (!EnvMan.IsDaylight() || !Object.op_Implicit((Object)(object)EnvMan.instance))
			{
				return true;
			}
			float dayFraction = EnvMan.instance.GetDayFraction();
			if (!(dayFraction <= 0.3f))
			{
				return dayFraction >= 0.69f;
			}
			return true;
		}

		private bool IsLightEnabled()
		{
			if ((Object)(object)m_itemDrop != (Object)null)
			{
				return LanternItem.IsLightEnabled(m_itemDrop.m_itemData);
			}
			if ((Object)(object)m_character != (Object)null)
			{
				ZNetView nview = m_character.m_nview;
				int result;
				if (nview == null)
				{
					result = 0;
				}
				else
				{
					ZDO zDO = nview.GetZDO();
					result = (((zDO != null) ? new bool?(zDO.GetBool(LanternItem.s_lanternLightEnabled, true)) : null).GetValueOrDefault() ? 1 : 0);
				}
				return (byte)result != 0;
			}
			ItemStand itemStand = m_itemStand;
			int result2;
			if (itemStand == null)
			{
				result2 = 0;
			}
			else
			{
				ZNetView nview2 = itemStand.m_nview;
				bool? obj;
				if (nview2 == null)
				{
					obj = null;
				}
				else
				{
					ZDO zDO2 = nview2.GetZDO();
					obj = ((zDO2 != null) ? new bool?(zDO2.GetBool(LanternItem.s_lanternLightEnabled, true)) : null);
				}
				bool? flag = obj;
				result2 = (flag.GetValueOrDefault() ? 1 : 0);
			}
			return (byte)result2 != 0;
		}

		private bool IsHeatEnabled()
		{
			if (!HipLantern.heatEnabled.Value || !IsLightEnabled())
			{
				return false;
			}
			if ((Object)(object)m_itemDrop != (Object)null)
			{
				return false;
			}
			if ((Object)(object)m_character == (Object)null || !m_character.IsPlayer())
			{
				return false;
			}
			Character character = m_character;
			if (LanternItem.IsHeatBlockedForPlayer((Player)(object)((character is Player) ? character : null)))
			{
				return false;
			}
			ZNetView nview = m_character.m_nview;
			int result;
			if (nview == null)
			{
				result = 0;
			}
			else
			{
				ZDO zDO = nview.GetZDO();
				result = (((zDO != null) ? new bool?(zDO.GetBool(LanternItem.s_lanternHeatEnabled, false)) : null).GetValueOrDefault() ? 1 : 0);
			}
			return (byte)result != 0;
		}

		private static void CheckEffects()
		{
			List<EffectData> effectPrefabs;
			if (!lampEffects.HasEffects() && Object.op_Implicit((Object)(object)ZNetScene.instance))
			{
				effectPrefabs = new List<EffectData>();
				AddEffect(0, "fx_candle_addfuel");
				AddEffect(1, "fx_candle_on");
				AddEffect(2, "sfx_FireAddFuel");
				AddEffect(3, "fx_candle_off");
				lampEffects.m_effectPrefabs = effectPrefabs.ToArray();
			}
			void AddEffect(int variant, string prefabName)
			{
				//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_0020: 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_0039: Expected O, but got Unknown
				GameObject prefab = ZNetScene.instance.GetPrefab(prefabName);
				effectPrefabs.Insert(variant, new EffectData
				{
					m_prefab = prefab,
					m_enabled = ((Object)(object)prefab != (Object)null),
					m_variant = variant
				});
			}
		}
	}
}
namespace HipLantern.Compatibility
{
	internal static class EpicLootCompat
	{
		[HarmonyPatch]
		public static class EpicLoot_EnchantCostsHelper_CanBeMagicItem_TreatLanternAsUtility
		{
			public static List<MethodBase> targets;

			public static List<MethodBase> GetTargets()
			{
				if ((object)assembly == null)
				{
					assembly = Assembly.GetAssembly(((object)Chainloader.PluginInfos["randyknapp.mods.epicloot"].Instance).GetType());
				}
				List<MethodBase> list = new List<MethodBase>();
				MethodInfo methodInfo = AccessTools.Method(assembly.GetType("EpicLoot.Crafting.EnchantCostsHelper"), "GetSacrificeProducts", new Type[1] { typeof(ItemData) }, (Type[])null);
				if ((object)methodInfo != null)
				{
					HipLantern.LogInfo("EpicLoot.Crafting.EnchantCostsHelper:GetSacrificeProducts method is patched to make it work with custom backpack item type");
					list.Add(methodInfo);
				}
				else
				{
					HipLantern.LogInfo("EpicLoot.Crafting.EnchantCostsHelper:GetSacrificeProducts method was not found");
				}
				MethodInfo methodInfo2 = AccessTools.Method(assembly.GetType("EpicLoot.Crafting.EnchantCostsHelper"), "GetEnchantCost", (Type[])null, (Type[])null);
				if ((object)methodInfo2 != null)
				{
					HipLantern.LogInfo("EpicLoot.Crafting.EnchantCostsHelper:GetEnchantCost method is patched to make it work with custom backpack item type");
					list.Add(methodInfo2);
				}
				else
				{
					HipLantern.LogInfo("EpicLoot.Crafting.EnchantCostsHelper:GetEnchantCost method was not found");
				}
				MethodInfo methodInfo3 = AccessTools.Method(assembly.GetType("EpicLoot.Crafting.EnchantCostsHelper"), "GetAugmentCost", (Type[])null, (Type[])null);
				if ((object)methodInfo3 != null)
				{
					HipLantern.LogInfo("EpicLoot.Crafting.EnchantCostsHelper:GetAugmentCost method is patched to make it work with custom backpack item type");
					list.Add(methodInfo3);
				}
				else
				{
					HipLantern.LogInfo("EpicLoot.Crafting.EnchantCostsHelper:GetAugmentCost method was not found");
				}
				MethodInfo methodInfo4 = AccessTools.Method(assembly.GetType("EpicLoot.Crafting.EnchantCostsHelper"), "GetReAugmentCost", (Type[])null, (Type[])null);
				if ((object)methodInfo4 != null)
				{
					HipLantern.LogInfo("EpicLoot.Crafting.EnchantCostsHelper:GetReAugmentCost method is patched to make it work with custom backpack item type");
					list.Add(methodInfo4);
				}
				else
				{
					HipLantern.LogInfo("EpicLoot.Crafting.EnchantCostsHelper:GetReAugmentCost method was not found");
				}
				MethodInfo methodInfo5 = AccessTools.Method(assembly.GetType("EpicLoot.EpicLoot"), "CanBeMagicItem", (Type[])null, (Type[])null);
				if ((object)methodInfo5 != null)
				{
					HipLantern.LogInfo("EpicLoot.EpicLoot:CanBeMagicItem method is patched to make it work with custom backpack item type");
					list.Add(methodInfo5);
				}
				else
				{
					HipLantern.LogInfo("EpicLoot.EpicLoot:CanBeMagicItem method was not found");
				}
				return list;
			}

			public static bool Prepare()
			{
				return IsInstalled && (targets ?? (targets = GetTargets())).Count > 0;
			}

			private static IEnumerable<MethodBase> TargetMethods()
			{
				return targets;
			}

			public static void Prefix(ItemData item, ref bool __state)
			{
				//IL_002b: Unknown result type (might be due to invalid IL or missing references)
				if (HipLantern.lanternEnchantableEpicLoot.Value && (__state = LanternItem.IsLanternItem(item)))
				{
					item.m_shared.m_itemType = (ItemType)18;
				}
			}

			public static void Postfix(ItemData item, bool __state)
			{
				if (__state)
				{
					LanternItem.PatchLanternItemData(item);
				}
			}
		}

		[HarmonyPatch]
		public static class EpicLoot_MagicItemEffectRequirements_argItemData_TreatLanternAsUtility
		{
			public static List<MethodBase> targets;

			public static List<MethodBase> GetTargets()
			{
				if ((object)assembly == null)
				{
					assembly = Assembly.GetAssembly(((object)Chainloader.PluginInfos["randyknapp.mods.epicloot"].Instance).GetType());
				}
				List<MethodBase> list = new List<MethodBase>();
				MethodInfo methodInfo = AccessTools.Method(assembly.GetType("EpicLoot.MagicItemEffectRequirements"), "AllowByItemType", (Type[])null, (Type[])null);
				if ((object)methodInfo != null)
				{
					HipLantern.LogInfo("EpicLoot.MagicItemEffectRequirements:AllowByItemType method is patched to make it work with custom backpack item type");
					list.Add(methodInfo);
				}
				else
				{
					HipLantern.LogInfo("EpicLoot.MagicItemEffectRequirements:AllowByItemType method was not found");
				}
				MethodInfo methodInfo2 = AccessTools.Method(assembly.GetType("EpicLoot.MagicItemEffectRequirements"), "ExcludeByItemType", (Type[])null, (Type[])null);
				if ((object)methodInfo2 != null)
				{
					HipLantern.LogInfo("EpicLoot.MagicItemEffectRequirements:ExcludeByItemType method is patched to make it work with custom backpack item type");
					list.Add(methodInfo2);
				}
				else
				{
					HipLantern.LogInfo("EpicLoot.MagicItemEffectRequirements:ExcludeByItemType method was not found");
				}
				MethodInfo methodInfo3 = AccessTools.Method(assembly.GetType("EpicLoot.MagicItemEffectRequirements"), "CheckRequirements", (Type[])null, (Type[])null);
				if ((object)methodInfo3 != null)
				{
					HipLantern.LogInfo("EpicLoot.MagicItemEffectRequirements:CheckRequirements method is patched to make it work with custom backpack item type");
					list.Add(methodInfo3);
				}
				else
				{
					HipLantern.LogInfo("EpicLoot.MagicItemEffectRequirements:CheckRequirements method was not found");
				}
				return list;
			}

			public static bool Prepare()
			{
				return IsInstalled && (targets ?? (targets = GetTargets())).Count > 0;
			}

			private static IEnumerable<MethodBase> TargetMethods()
			{
				return targets;
			}

			public static void Prefix(ItemData itemData, ref bool __state)
			{
				//IL_002b: Unknown result type (might be due to invalid IL or missing references)
				if (HipLantern.lanternEnchantableEpicLoot.Value && (__state = LanternItem.IsLanternItem(itemData)))
				{
					itemData.m_shared.m_itemType = (ItemType)18;
				}
			}

			public static void Postfix(ItemData itemData, bool __state)
			{
				if (__state)
				{
					LanternItem.PatchLanternItemData(itemData);
				}
			}
		}

		public const string modGUID = "randyknapp.mods.epicloot";

		public static Assembly assembly;

		public static bool IsInstalled => Chainloader.PluginInfos.ContainsKey("randyknapp.mods.epicloot");
	}
	internal class JewelcraftingCompat