Decompiled source of SakeysLight v1.0.1

BepInEx/plugins/Sakey's Light/Sakey's Light.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("Sakey's Light")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Sakey's Light")]
[assembly: AssemblyTitle("Sakey's Light")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace SakeysLight;

internal sealed class ConfigurationManagerAttributes
{
	public bool? ShowRangeAsPercent;

	public Action<ConfigEntryBase> CustomDrawer;

	public bool? Browsable;

	public string Category;

	public object DefaultValue;

	public bool? HideDefaultButton;

	public bool? HideSettingName;

	public string Description;

	public string DispName;

	public int? Order;

	public bool? ReadOnly;

	public bool? IsAdvanced;

	public Func<object, string> ObjToStr;

	public Func<string, object> StrToObj;
}
internal static class SakeysLightConfigLocalization
{
	internal static bool IsJapanese
	{
		get
		{
			try
			{
				Localization instance = Localization.instance;
				return string.Equals((instance != null) ? instance.GetSelectedLanguage() : null, "Japanese", StringComparison.OrdinalIgnoreCase);
			}
			catch
			{
				return false;
			}
		}
	}

	internal static string Category
	{
		get
		{
			if (!IsJapanese)
			{
				return "Light Settings";
			}
			return "ライト設定";
		}
	}

	internal static string BrightnessName
	{
		get
		{
			if (!IsJapanese)
			{
				return "Light Brightness";
			}
			return "光の明るさ";
		}
	}

	internal static string BrightnessDescription
	{
		get
		{
			if (!IsJapanese)
			{
				return "Adjusts the brightness of the light. 100% = original brightness, 50% = half brightness. 0% = off.";
			}
			return "ライトの明るさを調整します。100%で元の明るさ、50%で半分の明るさです。0%で消灯します。";
		}
	}

	internal static string RangeName
	{
		get
		{
			if (!IsJapanese)
			{
				return "Light Range";
			}
			return "光の届く範囲";
		}
	}

	internal static string RangeDescription
	{
		get
		{
			if (!IsJapanese)
			{
				return "Adjusts how far the light reaches. 100% = original range, 50% = half range. 0% = off.";
			}
			return "ライトが照らせる距離を調整します。100%で元の範囲、50%で半分の範囲です。0%で消灯します。";
		}
	}

	internal static string ShadowName
	{
		get
		{
			if (!IsJapanese)
			{
				return "Shadow Strength";
			}
			return "影の強さ";
		}
	}

	internal static string ShadowDescription
	{
		get
		{
			if (!IsJapanese)
			{
				return "Adjusts the strength of shadows cast by the light. 0% = no shadows, 100% = maximum.";
			}
			return "ライトによってできる影の強さを調整します。0%で影なし、100%で最大の強さです。";
		}
	}
}
[BepInPlugin("com.sakey.light", "Sakey's Light", "1.0.1")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public sealed class SakeysLightPlugin : BaseUnityPlugin
{
	public const string PluginGUID = "com.sakey.light";

	public const string PluginName = "Sakey's Light";

	public const string PluginVersion = "1.0.1";

	internal const string PrefabName = "SakeysLight";

	internal const string BasePrefabName = "Lantern_DN";

	internal const ItemType HipItemType = (ItemType)56;

	internal const ItemType BackAttachType = (ItemType)19;

	private Harmony _harmony;

	internal static ConfigEntry<float> LightIntensityMultiplier;

	internal static ConfigEntry<float> LightRangeMultiplier;

	internal static ConfigEntry<float> ShadowStrength;

	private void Awake()
	{
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Expected O, but got Unknown
		//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Expected O, but got Unknown
		//IL_014a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0154: Expected O, but got Unknown
		//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ab: Expected O, but got Unknown
		LightIntensityMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Light Settings", "Light Intensity Multiplier", 0.66f, new ConfigDescription(SakeysLightConfigLocalization.BrightnessDescription, (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Category = SakeysLightConfigLocalization.Category,
				DispName = SakeysLightConfigLocalization.BrightnessName,
				Description = SakeysLightConfigLocalization.BrightnessDescription,
				ShowRangeAsPercent = true
			}
		}));
		LightRangeMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Light Settings", "Light Range Multiplier", 0.776f, new ConfigDescription(SakeysLightConfigLocalization.RangeDescription, (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Category = SakeysLightConfigLocalization.Category,
				DispName = SakeysLightConfigLocalization.RangeName,
				Description = SakeysLightConfigLocalization.RangeDescription,
				ShowRangeAsPercent = true
			}
		}));
		ShadowStrength = ((BaseUnityPlugin)this).Config.Bind<float>("Light Settings", "Shadow Strength", 0.75f, new ConfigDescription(SakeysLightConfigLocalization.ShadowDescription, (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), new object[1]
		{
			new ConfigurationManagerAttributes
			{
				Category = SakeysLightConfigLocalization.Category,
				DispName = SakeysLightConfigLocalization.ShadowName,
				Description = SakeysLightConfigLocalization.ShadowDescription,
				ShowRangeAsPercent = true
			}
		}));
		LightIntensityMultiplier.SettingChanged += OnLightSettingChanged;
		LightRangeMultiplier.SettingChanged += OnLightSettingChanged;
		ShadowStrength.SettingChanged += OnLightSettingChanged;
		_harmony = new Harmony("com.sakey.light");
		_harmony.PatchAll();
		LocalizationManager.OnLocalizationAdded += AddCustomLocalizations;
		AddCustomLocalizations();
		PrefabManager.OnVanillaPrefabsAvailable += RegisterItem;
	}

	private void Update()
	{
	}

	private void AddCustomLocalizations()
	{
		try
		{
			LocalizationManager instance = LocalizationManager.Instance;
			CustomLocalization val = ((instance != null) ? instance.GetLocalization() : null);
			if (val != null)
			{
				string text = "Japanese";
				val.AddTranslation(ref text, new Dictionary<string, string>
				{
					{ "item_sakeys_light", "Sakey's Light" },
					{ "item_sakeys_light_desc", "腰に装備して周囲を照らすライト。" }
				});
				text = "English";
				val.AddTranslation(ref text, new Dictionary<string, string>
				{
					{ "item_sakeys_light", "Sakey's Light" },
					{ "item_sakeys_light_desc", "A light equipped at your waist that illuminates the surroundings." }
				});
			}
		}
		catch (Exception ex)
		{
			Debug.LogError((object)("Sakey's Light localization failed: " + ex));
		}
	}

	private void RegisterItem()
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: 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_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Expected O, but got Unknown
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Expected O, but got Unknown
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			ItemConfig val = new ItemConfig
			{
				Name = "$item_sakeys_light",
				Description = "$item_sakeys_light_desc",
				CraftingStation = null,
				Amount = 1
			};
			val.AddRequirement("Stone", 1, 1);
			CustomItem val2 = new CustomItem("SakeysLight", "Lantern_DN", val);
			GameObject itemPrefab = val2.ItemPrefab;
			ItemDrop component = itemPrefab.GetComponent<ItemDrop>();
			if ((Object)(object)component == (Object)null)
			{
				throw new InvalidOperationException("Lantern_DN clone has no ItemDrop.");
			}
			PatchPrefabAttachment(itemPrefab);
			ItemData itemData = component.m_itemData;
			SharedData shared = itemData.m_shared;
			shared.m_itemType = (ItemType)56;
			shared.m_attachOverride = (ItemType)19;
			shared.m_movementModifier = 0f;
			shared.m_useDurability = false;
			shared.m_maxDurability = 0f;
			shared.m_useDurabilityDrain = 0f;
			shared.m_durabilityDrain = 0f;
			shared.m_destroyBroken = false;
			shared.m_canBeReparied = false;
			itemData.m_durability = 0f;
			itemData.m_dropPrefab = itemPrefab;
			if (!ItemManager.Instance.AddItem(val2))
			{
				throw new InvalidOperationException("Jötunn rejected SakeysLight.");
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Sakey's Light: Registered from Lantern_DN with HipLantern-style back attachment routing.");
		}
		catch (Exception ex)
		{
			Debug.LogError((object)("Sakey's Light registration failed: " + ex));
		}
		finally
		{
			PrefabManager.OnVanillaPrefabsAvailable -= RegisterItem;
		}
	}

	private static void PatchPrefabAttachment(GameObject prefab)
	{
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f7: 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_0300: Unknown result type (might be due to invalid IL or missing references)
		//IL_0305: Unknown result type (might be due to invalid IL or missing references)
		//IL_0309: Unknown result type (might be due to invalid IL or missing references)
		//IL_0310: Unknown result type (might be due to invalid IL or missing references)
		//IL_0317: Unknown result type (might be due to invalid IL or missing references)
		//IL_0323: Unknown result type (might be due to invalid IL or missing references)
		//IL_0328: Unknown result type (might be due to invalid IL or missing references)
		Transform val = prefab.transform.Find("attach");
		if ((Object)(object)val != (Object)null)
		{
			Object.DestroyImmediate((Object)(object)((Component)val).gameObject);
		}
		Transform obj = prefab.transform.Find("attach_back");
		if ((Object)(object)obj == (Object)null)
		{
			throw new InvalidOperationException("Lantern_DN has no attach_back transform.");
		}
		Transform val2 = obj.Find("default");
		if ((Object)(object)val2 == (Object)null)
		{
			throw new InvalidOperationException("Lantern_DN attach_back has no default child.");
		}
		val2.localScale = Vector3.one * 0.25f;
		val2.localPosition = new Vector3(-0.22f, -0.1f, 0.1f);
		val2.localEulerAngles = new Vector3(306.55f, 215.5f, 117.64f);
		Transform obj2 = val2.Find("Point Light");
		if ((Object)(object)obj2 == (Object)null)
		{
			throw new InvalidOperationException("Lantern_DN attach_back/default has no Point Light.");
		}
		Light component = ((Component)obj2).GetComponent<Light>();
		if ((Object)(object)component == (Object)null)
		{
			throw new InvalidOperationException("Lantern_DN Point Light has no Light component.");
		}
		int mask = LayerMask.GetMask(new string[12]
		{
			"Default", "static_solid", "Default_small", "piece", "piece_nonsolid", "terrain", "character_net", "character_ghost", "hitbox", "character_noenv",
			"vehicle", "item"
		});
		int mask2 = LayerMask.GetMask(new string[1] { "character" });
		component.cullingMask = mask;
		GameObject obj3 = Object.Instantiate<GameObject>(((Component)component).gameObject, ((Component)component).transform.parent);
		((Object)obj3).name = "Spot Light";
		Light component2 = obj3.GetComponent<Light>();
		if ((Object)(object)component2 == (Object)null)
		{
			throw new InvalidOperationException("Failed to create Sakey's Light Spot Light.");
		}
		component2.cullingMask = mask2;
		component2.shadows = (LightShadows)0;
		component2.range = 1.5f;
		component2.intensity = 2f;
		component2.shadowStrength = 0f;
		LightLod component3 = ((Component)component).GetComponent<LightLod>();
		LightFlicker component4 = ((Component)component).GetComponent<LightFlicker>();
		LightLod component5 = ((Component)component2).GetComponent<LightLod>();
		LightFlicker component6 = ((Component)component2).GetComponent<LightFlicker>();
		SakeyLightReflection.SetFloat(component3, "m_lightDistance", 40f);
		SakeyLightReflection.SetFloat(component3, "m_baseRange", component.range);
		SakeyLightReflection.SetFloat(component3, "m_baseShadowStrength", component.shadowStrength);
		SakeyLightReflection.SetFloat(component5, "m_lightDistance", 40f);
		SakeyLightReflection.SetFloat(component5, "m_baseRange", component2.range);
		SakeyLightReflection.SetBool(component5, "m_shadowLod", value: false);
		SakeyLightReflection.SetFloat(component4, "m_baseIntensity", component.intensity);
		SakeyLightReflection.SetFloat(component6, "m_baseIntensity", component2.intensity);
		SakeyLightReflection.MultiplyFloat(component4, "m_flickerIntensity", 0.6f);
		SakeyLightReflection.MultiplyFloat(component4, "m_flickerSpeed", 0.6f);
		SakeyLightReflection.SetFloat(component4, "m_movement", 0.02f);
		Transform val3 = val2.Find("flare");
		if ((Object)(object)val3 != (Object)null)
		{
			ParticleSystem component7 = ((Component)val3).GetComponent<ParticleSystem>();
			if ((Object)(object)component7 != (Object)null)
			{
				MainModule main = component7.main;
				MinMaxGradient startColor = ((MainModule)(ref main)).startColor;
				Color color = ((MinMaxGradient)(ref startColor)).color;
				((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(new Color(color.r, color.g, color.b, 0.025f));
			}
		}
		SakeyLightController sakeyLightController = ((Component)val2).GetComponent<SakeyLightController>();
		if ((Object)(object)sakeyLightController == (Object)null)
		{
			sakeyLightController = ((Component)val2).gameObject.AddComponent<SakeyLightController>();
		}
		sakeyLightController.MainLight = component;
		sakeyLightController.PlayerLight = component2;
	}

	private static void OnLightSettingChanged(object sender, EventArgs e)
	{
		HipLightState.ApplyLightSettingsToAll();
	}

	private void OnDestroy()
	{
		LocalizationManager.OnLocalizationAdded -= AddCustomLocalizations;
		if (LightIntensityMultiplier != null)
		{
			LightIntensityMultiplier.SettingChanged -= OnLightSettingChanged;
		}
		if (LightRangeMultiplier != null)
		{
			LightRangeMultiplier.SettingChanged -= OnLightSettingChanged;
		}
		if (ShadowStrength != null)
		{
			ShadowStrength.SettingChanged -= OnLightSettingChanged;
		}
		Harmony harmony = _harmony;
		if (harmony != null)
		{
			harmony.UnpatchSelf();
		}
		_harmony = null;
	}
}
internal static class SakeyLightReflection
{
	private static readonly Dictionary<string, FieldInfo> FieldCache = new Dictionary<string, FieldInfo>();

	private static FieldInfo GetField(Type type, string fieldName)
	{
		if (type == null || string.IsNullOrEmpty(fieldName))
		{
			return null;
		}
		string key = type.FullName + ":" + fieldName;
		if (FieldCache.TryGetValue(key, out var value))
		{
			return value;
		}
		FieldInfo fieldInfo = AccessTools.Field(type, fieldName);
		FieldCache[key] = fieldInfo;
		return fieldInfo;
	}

	internal static void SetFloat(object target, string fieldName, float value)
	{
		if (target != null)
		{
			FieldInfo field = GetField(target.GetType(), fieldName);
			if (field != null && field.FieldType == typeof(float))
			{
				field.SetValue(target, value);
			}
		}
	}

	internal static void SetBool(object target, string fieldName, bool value)
	{
		if (target != null)
		{
			FieldInfo field = GetField(target.GetType(), fieldName);
			if (field != null && field.FieldType == typeof(bool))
			{
				field.SetValue(target, value);
			}
		}
	}

	internal static void MultiplyFloat(object target, string fieldName, float multiplier)
	{
		if (target != null)
		{
			FieldInfo field = GetField(target.GetType(), fieldName);
			if (!(field == null) && !(field.FieldType != typeof(float)))
			{
				float num = (float)field.GetValue(target);
				field.SetValue(target, num * multiplier);
			}
		}
	}
}
internal sealed class SakeyLightController : MonoBehaviour
{
	internal Light MainLight;

	internal Light PlayerLight;

	private float _mainBaseIntensity;

	private float _mainBaseRange;

	private float _playerBaseIntensity;

	private float _playerBaseRange;

	private bool _initialized;

	private void Awake()
	{
		Initialize();
		ApplyNow();
	}

	private void OnEnable()
	{
		Initialize();
		ApplyNow();
	}

	private void Update()
	{
		ApplyNow();
	}

	private void Initialize()
	{
		if (_initialized)
		{
			return;
		}
		if ((Object)(object)MainLight == (Object)null)
		{
			Transform val = ((Component)this).transform.Find("Point Light");
			if ((Object)(object)val != (Object)null)
			{
				MainLight = ((Component)val).GetComponent<Light>();
			}
		}
		if ((Object)(object)PlayerLight == (Object)null)
		{
			Transform val2 = ((Component)this).transform.Find("Spot Light");
			if ((Object)(object)val2 != (Object)null)
			{
				PlayerLight = ((Component)val2).GetComponent<Light>();
			}
		}
		if ((Object)(object)MainLight == (Object)null || (Object)(object)PlayerLight == (Object)null)
		{
			Light[] componentsInChildren = ((Component)this).GetComponentsInChildren<Light>(true);
			foreach (Light val3 in componentsInChildren)
			{
				if (!((Object)(object)val3 == (Object)null))
				{
					if (string.Equals(((Object)((Component)val3).gameObject).name, "Spot Light", StringComparison.Ordinal))
					{
						PlayerLight = val3;
					}
					else if (string.Equals(((Object)((Component)val3).gameObject).name, "Point Light", StringComparison.Ordinal))
					{
						MainLight = val3;
					}
				}
			}
		}
		if (!((Object)(object)MainLight == (Object)null) && !((Object)(object)PlayerLight == (Object)null))
		{
			_mainBaseIntensity = MainLight.intensity;
			_mainBaseRange = MainLight.range;
			_playerBaseIntensity = PlayerLight.intensity;
			_playerBaseRange = PlayerLight.range;
			_initialized = true;
		}
	}

	private void UpdateFlare(bool off)
	{
		Transform val = ((Component)this).transform.Find("flare");
		if ((Object)(object)val == (Object)null)
		{
			return;
		}
		ParticleSystem component = ((Component)val).GetComponent<ParticleSystem>();
		if ((Object)(object)component == (Object)null)
		{
			return;
		}
		if (off)
		{
			component.Stop(true, (ParticleSystemStopBehavior)0);
			((Component)component).gameObject.SetActive(false);
			return;
		}
		if (!((Component)component).gameObject.activeSelf)
		{
			((Component)component).gameObject.SetActive(true);
		}
		if (!component.isPlaying)
		{
			component.Play();
		}
	}

	internal void ApplyNow()
	{
		//IL_023a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0240: Invalid comparison between Unknown and I4
		Initialize();
		if (_initialized)
		{
			float num = SakeysLightPlugin.LightIntensityMultiplier?.Value ?? 0.66f;
			float num2 = SakeysLightPlugin.LightRangeMultiplier?.Value ?? 0.776f;
			float num3 = SakeysLightPlugin.ShadowStrength?.Value ?? 0.75f;
			UpdateFlare(num <= 0.0001f || num2 <= 0.0001f);
			int mask = LayerMask.GetMask(new string[12]
			{
				"Default", "static_solid", "Default_small", "piece", "piece_nonsolid", "terrain", "character_net", "character_ghost", "hitbox", "character_noenv",
				"vehicle", "item"
			});
			int mask2 = LayerMask.GetMask(new string[1] { "character" });
			float num4 = Mathf.Max(0f, _mainBaseIntensity * num);
			float num5 = Mathf.Max(0f, _mainBaseRange * num2);
			float num6 = Mathf.Max(0f, _playerBaseIntensity * num);
			float num7 = Mathf.Max(0f, _playerBaseRange * num2);
			if ((Object)(object)MainLight != (Object)null)
			{
				MainLight.cullingMask = mask;
				MainLight.intensity = num4;
				MainLight.range = num5;
				MainLight.shadowStrength = Mathf.Clamp01(num3);
				MainLight.shadows = (LightShadows)((MainLight.shadowStrength > 0f) ? 2 : 0);
				((Behaviour)MainLight).enabled = num4 > 0.0001f && num5 > 0.0001f;
				LightFlicker component = ((Component)MainLight).GetComponent<LightFlicker>();
				LightLod component2 = ((Component)MainLight).GetComponent<LightLod>();
				SakeyLightReflection.SetFloat(component, "m_baseIntensity", num4);
				SakeyLightReflection.SetFloat(component2, "m_baseRange", num5);
				SakeyLightReflection.SetFloat(component2, "m_baseShadowStrength", Mathf.Clamp01(num3));
				SakeyLightReflection.SetFloat(component2, "m_lightDistance", Mathf.Max(num5 + 10f, 40f));
				SakeyLightReflection.SetBool(component2, "m_shadowLod", (int)MainLight.shadows > 0);
			}
			if ((Object)(object)PlayerLight != (Object)null)
			{
				PlayerLight.cullingMask = mask2;
				PlayerLight.shadows = (LightShadows)0;
				PlayerLight.shadowStrength = 0f;
				PlayerLight.intensity = num6;
				PlayerLight.range = num7;
				((Behaviour)PlayerLight).enabled = num6 > 0.0001f && num7 > 0.0001f;
				LightFlicker component3 = ((Component)PlayerLight).GetComponent<LightFlicker>();
				LightLod component4 = ((Component)PlayerLight).GetComponent<LightLod>();
				SakeyLightReflection.SetFloat(component3, "m_baseIntensity", num6);
				SakeyLightReflection.SetFloat(component4, "m_baseRange", num7);
				SakeyLightReflection.SetFloat(component4, "m_lightDistance", 40f);
				SakeyLightReflection.SetBool(component4, "m_shadowLod", value: false);
			}
		}
	}
}
internal static class HipLightState
{
	private sealed class HumanoidState
	{
		internal ItemData Item;
	}

	private sealed class VisState
	{
		internal string ItemName = "";

		internal List<GameObject> Instances;

		internal int CurrentHash;
	}

	private static readonly ConditionalWeakTable<Humanoid, HumanoidState> humanoids = new ConditionalWeakTable<Humanoid, HumanoidState>();

	private static readonly ConditionalWeakTable<VisEquipment, VisState> visuals = new ConditionalWeakTable<VisEquipment, VisState>();

	private static readonly MethodInfo SetupEquipmentMethod = AccessTools.Method(typeof(Humanoid), "SetupEquipment", (Type[])null, (Type[])null);

	private static readonly MethodInfo AttachBackItemMethod = AccessTools.Method(typeof(VisEquipment), "AttachBackItem", new Type[4]
	{
		typeof(int),
		typeof(int),
		typeof(bool),
		typeof(int)
	}, (Type[])null);

	internal static void ApplyLightSettingsToAll()
	{
	}

	internal static ItemData Get(Humanoid humanoid)
	{
		if (!((Object)(object)humanoid == (Object)null))
		{
			return humanoids.GetOrCreateValue(humanoid).Item;
		}
		return null;
	}

	internal static void Set(Humanoid humanoid, ItemData item)
	{
		if ((Object)(object)humanoid != (Object)null)
		{
			humanoids.GetOrCreateValue(humanoid).Item = item;
		}
	}

	internal static bool Is(ItemData item)
	{
		if (item != null && (Object)(object)item.m_dropPrefab != (Object)null)
		{
			return ((Object)item.m_dropPrefab).name == "SakeysLight";
		}
		return false;
	}

	internal static void SetupEquipment(Humanoid humanoid)
	{
		if (!((Object)(object)humanoid == (Object)null) && !(SetupEquipmentMethod == null))
		{
			SetupEquipmentMethod.Invoke(humanoid, null);
		}
	}

	internal static void SetVisualItem(VisEquipment visEquipment, string name)
	{
		if (!((Object)(object)visEquipment == (Object)null))
		{
			visuals.GetOrCreateValue(visEquipment).ItemName = name ?? "";
		}
	}

	internal static void UpdateVisual(VisEquipment visEquipment)
	{
		if ((Object)(object)visEquipment == (Object)null)
		{
			return;
		}
		VisState orCreateValue = visuals.GetOrCreateValue(visEquipment);
		int num = ((!string.IsNullOrEmpty(orCreateValue.ItemName)) ? StringExtensionMethods.GetStableHashCode(orCreateValue.ItemName) : 0);
		if (orCreateValue.CurrentHash == num)
		{
			return;
		}
		if (orCreateValue.Instances != null)
		{
			foreach (GameObject instance in orCreateValue.Instances)
			{
				if ((Object)(object)instance != (Object)null)
				{
					Object.Destroy((Object)(object)instance);
				}
			}
			orCreateValue.Instances = null;
		}
		orCreateValue.CurrentHash = num;
		if (num != 0 && !(AttachBackItemMethod == null))
		{
			object? obj = AttachBackItemMethod.Invoke(visEquipment, new object[4] { num, -1, false, 0 });
			GameObject val = (GameObject)((obj is GameObject) ? obj : null);
			if ((Object)(object)val != (Object)null)
			{
				orCreateValue.Instances = new List<GameObject> { val };
				val.GetComponentInChildren<SakeyLightController>(true)?.ApplyNow();
			}
		}
	}
}
[HarmonyPatch(typeof(Humanoid), "EquipItem")]
internal static class HumanoidEquipPatch
{
	private static void Postfix(Humanoid __instance, ItemData item, ref bool __result, bool triggerEquipEffects, VisEquipment ___m_visEquipment)
	{
		if (!HipLightState.Is(item))
		{
			return;
		}
		ItemData val = HipLightState.Get(__instance);
		if (val != null && val != item)
		{
			__instance.UnequipItem(val, triggerEquipEffects);
			if (___m_visEquipment != null)
			{
				___m_visEquipment.UpdateEquipmentVisuals();
			}
		}
		HipLightState.Set(__instance, item);
		item.m_equipped = true;
		__result = true;
		HipLightState.SetupEquipment(__instance);
	}
}
[HarmonyPatch(typeof(Humanoid), "UnequipItem")]
internal static class HumanoidUnequipPatch
{
	private static void Postfix(Humanoid __instance, ItemData item)
	{
		if (item != null && item == HipLightState.Get(__instance))
		{
			HipLightState.Set(__instance, null);
			HipLightState.SetupEquipment(__instance);
		}
	}
}
[HarmonyPatch(typeof(Humanoid), "UnequipAllItems")]
internal static class HumanoidUnequipAllPatch
{
	private static void Postfix(Humanoid __instance)
	{
		ItemData val = HipLightState.Get(__instance);
		if (val != null)
		{
			__instance.UnequipItem(val, false);
		}
	}
}
[HarmonyPatch(typeof(Humanoid), "IsItemEquiped")]
internal static class HumanoidIsEquippedPatch
{
	private static void Postfix(Humanoid __instance, ItemData item, ref bool __result)
	{
		if (item != null && item == HipLightState.Get(__instance))
		{
			__result = true;
		}
	}
}
[HarmonyPatch(typeof(ItemData), "IsEquipable")]
internal static class ItemIsEquipablePatch
{
	private static void Postfix(ItemData __instance, ref bool __result)
	{
		if (HipLightState.Is(__instance))
		{
			__result = true;
		}
	}
}
[HarmonyPatch(typeof(Humanoid), "GetEquipmentWeight")]
internal static class HumanoidEquipmentWeightPatch
{
	private static void Postfix(Humanoid __instance, ref float __result)
	{
		ItemData val = HipLightState.Get(__instance);
		if (val != null)
		{
			__result += val.m_shared.m_weight;
		}
	}
}
[HarmonyPatch(typeof(Humanoid), "SetupVisEquipment")]
internal static class HumanoidSetupVisPatch
{
	private static void Postfix(Humanoid __instance, VisEquipment visEq, bool isRagdoll)
	{
		ItemData val = HipLightState.Get(__instance);
		HipLightState.SetVisualItem(visEq, HipLightState.Is(val) ? ((Object)val.m_dropPrefab).name : "");
	}
}
[HarmonyPatch(typeof(VisEquipment), "UpdateEquipmentVisuals")]
internal static class VisEquipmentUpdatePatch
{
	private static void Prefix(VisEquipment __instance)
	{
		HipLightState.UpdateVisual(__instance);
	}
}
[HarmonyPatch(typeof(Inventory), "Changed")]
internal static class InventoryChangedPatch
{
	private static void Prefix(Inventory __instance)
	{
		Player localPlayer = Player.m_localPlayer;
		if (!((Object)(object)localPlayer == (Object)null) && __instance == ((Humanoid)localPlayer).GetInventory())
		{
			ItemData val = HipLightState.Get((Humanoid)(object)localPlayer);
			if (val != null && !__instance.ContainsItem(val))
			{
				HipLightState.Set((Humanoid)(object)localPlayer, null);
				HipLightState.SetupEquipment((Humanoid)(object)localPlayer);
			}
		}
	}
}