Decompiled source of BetterLanternsAndLights v1.1.3

BetterLanternsAndLights/BetterLanternsAndLights.dll

Decompiled 3 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("BetterLanternsAndLights")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("https://github.com/bryon82/SailwindBetterLanternsAndLights")]
[assembly: AssemblyCompany("raddude")]
[assembly: AssemblyProduct("BetterLanternsAndLights")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("609d6bc4-2d2c-4fb9-98b4-b62976cadb47")]
[assembly: AssemblyFileVersion("1.1.3.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.3.0")]
[module: UnverifiableCode]
namespace BetterLanternsAndLights
{
	[BepInPlugin("com.raddude.betterlanternsandlights", "Better Lanterns and Lights", "1.1.3")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class BLL_Plugin : BaseUnityPlugin
	{
		public const string PLUGIN_GUID = "com.raddude.betterlanternsandlights";

		public const string PLUGIN_NAME = "Better Lanterns and Lights";

		public const string PLUGIN_VERSION = "1.1.3";

		public const string DYNAMIC_LIGHTS_GUID = "com.nandbrew.dynamiclights";

		public const string BETTER_NPC_BOATS_GUID = "com.raddude.betternpcboats";

		private static ManualLogSource _logger;

		public static Light PlayerLight { get; internal set; }

		internal static BLL_Plugin Instance { get; private set; }

		internal static void LogDebug(string message)
		{
			_logger.LogDebug((object)message);
		}

		internal static void LogInfo(string message)
		{
			_logger.LogInfo((object)message);
		}

		internal static void LogWarning(string message)
		{
			_logger.LogWarning((object)message);
		}

		internal static void LogError(string message)
		{
			_logger.LogError((object)message);
		}

		private void Awake()
		{
			if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
				return;
			}
			Instance = this;
			_logger = ((BaseUnityPlugin)this).Logger;
			Configs.InitializeConfigs();
			Harmony harmony = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "com.raddude.betterlanternsandlights");
			bool flag = false;
			bool flag2 = false;
			foreach (PluginInfo value in Chainloader.PluginInfos.Values)
			{
				if (value.Metadata.GUID == "com.nandbrew.dynamiclights")
				{
					LogInfo("Enabling compatibility with Dynamic Lights.");
					DynamicLights.ApplyPatch(harmony);
					flag = true;
				}
				else if (value.Metadata.GUID == "com.raddude.betternpcboats")
				{
					LogInfo("Enabling compatibility with Better NPC Boats.");
					BetterNPCBoats.ApplyPatch(harmony);
					flag2 = true;
				}
				if (flag && flag2)
				{
					break;
				}
			}
			SceneManager.sceneLoaded += DragonCliffs.SceneLoaded;
		}
	}
	internal class BetterNPCBoats
	{
		public static void ApplyPatch(Harmony harmony)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			Type type = AccessTools.TypeByName("BetterNPCBoats.BetterNPCFishingBoat");
			MethodInfo methodInfo = AccessTools.Method(type, "ToggleLanterns", (Type[])null, (Type[])null);
			harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(BetterNPCBoats), "ToggleLanternsPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		private static void ToggleLanternsPostfix(object __instance, bool state)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			Component val = (Component)__instance;
			LanternFlicker componentInChildren = val.GetComponentInChildren<LanternFlicker>();
			if (!((Object)(object)componentInChildren == (Object)null))
			{
				componentInChildren.SetFlicker(state);
			}
		}
	}
	internal class DynamicLights
	{
		public static void ApplyPatch(Harmony harmony)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			Type type = AccessTools.TypeByName("Dynamic_Lights.IslandStreetlightFire");
			MethodInfo methodInfo = AccessTools.Method(type, "SetLight", (Type[])null, (Type[])null);
			harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(DynamicLights), "SetLightPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		private static void SetLightPostfix(object __instance, bool newState)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			Component val = (Component)__instance;
			LanternFlicker component = val.GetComponent<LanternFlicker>();
			if (!((Object)(object)component == (Object)null))
			{
				component.SetFlicker(newState);
			}
		}
	}
	internal class InteriorPatches
	{
		[HarmonyPatch(typeof(InteriorEffectsTrigger))]
		internal static class InteriorEffectsTriggerPatch
		{
			[HarmonyPatch("OnTriggerEnter")]
			[HarmonyPostfix]
			private static void OnTriggerEnter(Collider other)
			{
				if (!((Object)(object)other == (Object)null))
				{
					LanternFlicker componentInParent = ((Component)other).GetComponentInParent<LanternFlicker>();
					if (!((Object)(object)componentInParent == (Object)null))
					{
						componentInParent.isInside = true;
					}
				}
			}

			[HarmonyPatch("OnTriggerExit")]
			[HarmonyPostfix]
			private static void OnTriggerExit(Collider other)
			{
				if (!((Object)(object)other == (Object)null))
				{
					LanternFlicker componentInParent = ((Component)other).GetComponentInParent<LanternFlicker>();
					if (!((Object)(object)componentInParent == (Object)null))
					{
						componentInParent.isInside = false;
					}
				}
			}
		}
	}
	internal class IslandLightsPatches
	{
		[HarmonyPatch(typeof(IslandStreetlightsManager), "Awake")]
		internal class IslandlightsAwakePatch
		{
			public static void Postfix(IslandStreetlightsManager __instance)
			{
				Light[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<Light>();
				Light[] array = componentsInChildren;
				foreach (Light val in array)
				{
					if (((Object)((Component)val).transform.parent).name.Contains("candle") || ((Object)val).name.Contains("Brazier") || ((Object)((Component)val).transform.parent).name.Contains("shop stove"))
					{
						LanternFlicker lanternFlicker = ((Component)val).gameObject.AddComponent<LanternFlicker>();
						lanternFlicker.SetFlicker(enable: true);
					}
				}
			}
		}
	}
	internal class LanternPatches
	{
		[HarmonyPatch(typeof(PrefabsDirectory), "PopulateShipItems")]
		internal class AddPaperLanternFlickerPatch
		{
			public static void Postfix(PrefabsDirectory __instance)
			{
				int[] array = new int[7] { 110, 111, 112, 113, 114, 133, 134 };
				int[] array2 = array;
				foreach (int num in array2)
				{
					__instance.directory[num].AddComponent<LanternFlicker>();
				}
			}
		}

		[HarmonyPatch(typeof(ShipItemLight), "SetLight")]
		internal class ShipItemLightSetLightPatch
		{
			public static void Postfix(ShipItemLight __instance, bool state)
			{
				LanternFlicker component = ((Component)__instance).GetComponent<LanternFlicker>();
				if (!((Object)(object)component == (Object)null))
				{
					component.SetFlicker(state);
				}
			}
		}

		[HarmonyPatch(typeof(GPButtonInventorySlot), "Awake")]
		public class AddInventoryLantern
		{
			public static void Postfix(GPButtonInventorySlot __instance)
			{
				InventoryLantern inventoryLantern = ((Component)__instance).gameObject.AddComponent<InventoryLantern>();
				inventoryLantern.InventorySlot = __instance;
			}
		}
	}
	internal class PlayerLightPatches
	{
		[HarmonyPatch(typeof(PlayerControllerMirror), "Awake")]
		internal class PlayerControllerMirrorAwakePatch
		{
			public static void Postfix()
			{
				Camera main = Camera.main;
				BLL_Plugin.PlayerLight = ((main != null) ? ((Component)main).GetComponent<Light>() : null);
				((Behaviour)BLL_Plugin.PlayerLight).enabled = Configs.enablePlayerLight.Value;
			}
		}
	}
	internal class StreetLightPatches
	{
		[HarmonyPatch(typeof(IslandStreetlight))]
		internal class IslandStreetlightPatches
		{
			[HarmonyPostfix]
			[HarmonyPatch("Awake")]
			public static void AddFlicker(IslandStreetlight __instance, Light ___light)
			{
				if (!(((Object)___light).name == "senna_lantern_light"))
				{
					((Component)__instance).gameObject.AddComponent<LanternFlicker>();
				}
			}

			[HarmonyPostfix]
			[HarmonyPatch("SetLight")]
			public static void AddFlickerToLight(IslandStreetlight __instance, bool newState)
			{
				LanternFlicker component = ((Component)__instance).GetComponent<LanternFlicker>();
				if (!((Object)(object)component == (Object)null))
				{
					component.SetFlicker(newState);
				}
			}
		}
	}
	internal class DragonCliffs
	{
		internal const string DRAGON_CLIFFS_SCENE = "island 9 E Dragon Cliffs";

		internal static List<GameObject> DCGateLightGOs { get; private set; }

		internal static void SceneLoaded(Scene scene, LoadSceneMode _)
		{
			if (((Scene)(ref scene)).name == "island 9 E Dragon Cliffs")
			{
				Initialize();
			}
		}

		internal static void Initialize()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			DCGateLightGOs = new List<GameObject>();
			Vector3[] array = (Vector3[])(object)new Vector3[2]
			{
				new Vector3(0f, 3.35f, 3.1f),
				new Vector3(0f, -3.35f, 3.1f)
			};
			GameObject val = GameObject.Find("island 9 E (dragon cliffs) scenery");
			Transform val2 = ((IEnumerable<Transform>)((Component)val.transform).GetComponentsInChildren<Transform>(true)).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name.Equals("east_gate (4)")));
			Transform child = ((IEnumerable<Transform>)((Component)val.transform).GetComponentsInChildren<Transform>(true)).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name.Equals("east_street_rope (1)"))).GetChild(0);
			Vector3[] array2 = array;
			foreach (Vector3 localPosition in array2)
			{
				GameObject val3 = Object.Instantiate<GameObject>(((Component)child).gameObject, val2);
				val3.transform.localScale = new Vector3(1.33f, 1.33f, 1.33f);
				val3.transform.localPosition = localPosition;
				val3.transform.localEulerAngles = new Vector3(0f, 0f, 270f);
				val3.GetComponent<Light>().range = 50f;
				val3.GetComponent<Light>().intensity = 1.5f;
				DCGateLightGOs.Add(val3);
				val3.SetActive(Configs.addDcGateLights.Value);
			}
			BLL_Plugin.LogDebug("Dragon Cliffs gate lights added");
		}
	}
	internal class InventoryLantern : MonoBehaviour
	{
		internal GPButtonInventorySlot InventorySlot { get; set; }

		private void LateUpdate()
		{
			if (Configs.enableInventoryLantern.Value && ((GoPointerButton)InventorySlot).IsLookedAt())
			{
				ShipItem currentItem = InventorySlot.currentItem;
				if (currentItem is ShipItemLight && (GameInput.GetKeyDown((InputName)9) || Input.GetMouseButtonDown(1)))
				{
					((GoPointerButton)currentItem).OnAltActivate();
				}
			}
		}
	}
	internal class LanternFlicker : MonoBehaviour
	{
		private bool isStreetLight = false;

		internal Coroutine flickerCoroutine;

		private Material paperMaterial;

		private Material paperOnMat;

		private Material paperOffMat;

		private Light light;

		private Color baseEmission;

		private float minIntensity = 1f;

		internal float maxIntensity = 1.5f;

		private float minEmission = 0.5f;

		private float maxEmission = 0.8f;

		private float minWindSpeed = 20f;

		private float maxWindSpeed = 40f;

		private float minFlickerSpeed = 0.5f;

		private float maxFlickerSpeed = 2f;

		private float minFastSpeed = 6f;

		private float maxFastSpeed = 15f;

		private float minFastAmount = 0.2f;

		private float maxFastAmount = 0.5f;

		internal float lightIntensity;

		internal bool isInside = false;

		private void Awake()
		{
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			light = ((Component)this).GetComponentInChildren<Light>();
			maxIntensity = light.intensity;
			minIntensity = light.intensity - 0.5f;
			ShipItemLight component = ((Component)this).GetComponent<ShipItemLight>();
			Renderer val = null;
			if ((Object)(object)component != (Object)null)
			{
				val = component.GetPrivateField<Renderer>("paperRenderer");
				paperOffMat = component.GetPrivateField<Material>("paperOffMat");
				paperOnMat = ((val != null) ? val.sharedMaterial : null);
			}
			IslandStreetlight component2 = ((Component)this).GetComponent<IslandStreetlight>();
			if ((Object)(object)component2 != (Object)null)
			{
				val = component2.GetPrivateField<Renderer>("renderer");
				paperOffMat = component2.GetPrivateField<Material>("offMat");
				paperOnMat = ((val != null) ? val.sharedMaterial : null);
				isStreetLight = true;
			}
			if ((Object)(object)val != (Object)null)
			{
				paperMaterial = val.material;
			}
			if ((Object)(object)paperOnMat != (Object)null)
			{
				baseEmission = paperOnMat.GetColor("_EmissionColor");
			}
		}

		internal void SetFlicker(bool enable)
		{
			if (((Component)this).gameObject.activeInHierarchy)
			{
				if (Configs.enableLanternFlicker.Value && enable && flickerCoroutine == null)
				{
					flickerCoroutine = ((MonoBehaviour)this).StartCoroutine(Flicker());
				}
				else if (!enable && flickerCoroutine != null)
				{
					((MonoBehaviour)this).StopCoroutine(flickerCoroutine);
					flickerCoroutine = null;
				}
			}
		}

		private IEnumerator Flicker()
		{
			float slowTime = Random.value * 100f;
			float fastTime = Random.value * 100f;
			while (true)
			{
				float windSpeed = ((Vector3)(ref Wind.currentWind)).magnitude;
				if (isInside || isStreetLight)
				{
					windSpeed = 0f;
				}
				float windAmount = Mathf.InverseLerp(minWindSpeed, maxWindSpeed, windSpeed);
				float slowSpeed = Mathf.Lerp(minFlickerSpeed, maxFlickerSpeed, windAmount);
				float fastSpeed = Mathf.Lerp(minFastSpeed, maxFastSpeed, windAmount);
				slowTime += Time.deltaTime * slowSpeed;
				fastTime += Time.deltaTime * fastSpeed;
				float slow = Mathf.PerlinNoise(slowTime, 0f);
				float fast = Mathf.PerlinNoise(fastTime, 100f);
				float fastAmount = Mathf.Lerp(minFastAmount, maxFastAmount, windAmount);
				float slowAmount = 1f - fastAmount;
				float flicker = slow * slowAmount + fast * fastAmount;
				flicker = Mathf.Clamp01(flicker);
				lightIntensity = Mathf.Lerp(minIntensity, maxIntensity, flicker);
				light.intensity = lightIntensity;
				if ((Object)(object)paperOffMat == (Object)null)
				{
					yield return null;
					continue;
				}
				float materialAmount = Mathf.Lerp(0.9f, 1f, flicker);
				paperMaterial.Lerp(paperOffMat, paperOnMat, materialAmount);
				float emissionStrength = Mathf.Lerp(minEmission, maxEmission, flicker);
				paperMaterial.SetColor("_EmissionColor", baseEmission * emissionStrength);
				yield return null;
			}
		}
	}
	internal class Configs
	{
		internal static ConfigEntry<bool> enableLanternFlicker;

		internal static ConfigEntry<bool> addDcGateLights;

		internal static ConfigEntry<bool> enablePlayerLight;

		internal static ConfigEntry<bool> enableInventoryLantern;

		internal static void InitializeConfigs()
		{
			ConfigFile config = ((BaseUnityPlugin)BLL_Plugin.Instance).Config;
			enableLanternFlicker = config.Bind<bool>("Settings", "Enable lantern flicker", true, (ConfigDescription)null);
			addDcGateLights = config.Bind<bool>("Settings", "Add Dragon Cliffs Gate Lights", true, (ConfigDescription)null);
			enablePlayerLight = config.Bind<bool>("Settings", "Ambient Player Light", false, "Light emanating from the player.");
			enableInventoryLantern = config.Bind<bool>("Settings", "Activate Lantern In Inventory", true, "The ability to activate the lantern while it is in an inventory slot.");
			enablePlayerLight.SettingChanged += delegate
			{
				UpdatePlayerLight();
			};
			addDcGateLights.SettingChanged += delegate
			{
				UpdateDCGateLights();
			};
		}

		internal static void UpdateDCGateLights()
		{
			//IL_0006: 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)
			Scene sceneByName = SceneManager.GetSceneByName("island 9 E Dragon Cliffs");
			if (((Scene)(ref sceneByName)).isLoaded && DragonCliffs.DCGateLightGOs == null)
			{
				return;
			}
			foreach (GameObject dCGateLightGO in DragonCliffs.DCGateLightGOs)
			{
				if ((Object)(object)dCGateLightGO != (Object)null)
				{
					dCGateLightGO.SetActive(addDcGateLights.Value);
				}
			}
		}

		internal static void UpdatePlayerLight()
		{
			if ((Object)(object)BLL_Plugin.PlayerLight != (Object)null)
			{
				((Behaviour)BLL_Plugin.PlayerLight).enabled = enablePlayerLight.Value;
			}
		}
	}
	internal static class Extensions
	{
		public static T GetPrivateField<T>(this object obj, string field)
		{
			return (T)Traverse.Create(obj).Field(field).GetValue();
		}
	}
}
namespace BetterLanternsAndLights.Patches
{
	internal class StovePatches
	{
		[HarmonyPatch(typeof(PrefabsDirectory), "PopulateShipItems")]
		internal class AddPaperLanternFlickerPatch
		{
			public static void Postfix(PrefabsDirectory __instance)
			{
				int[] array = new int[6] { 105, 106, 107, 377, 378, 379 };
				int[] array2 = array;
				foreach (int num in array2)
				{
					__instance.directory[num].AddComponent<LanternFlicker>();
				}
			}
		}

		[HarmonyPatch(typeof(ShipItemStove))]
		internal class StoveFuelTriggerUpdatePatch
		{
			[HarmonyPostfix]
			[HarmonyPatch("ExtraLateUpdate")]
			public static void SetLightFlicker(ShipItemStove __instance, StoveFuelTrigger ___fuelTrigger)
			{
				if (!((Object)(object)___fuelTrigger == (Object)null))
				{
					LanternFlicker component = ((Component)__instance).GetComponent<LanternFlicker>();
					if (!((Object)(object)component == (Object)null) && component.flickerCoroutine != null)
					{
						___fuelTrigger.GetPrivateField<Light>("light").intensity = component.lightIntensity;
					}
				}
			}

			[HarmonyPostfix]
			[HarmonyPatch("OnItemClick")]
			public static void ToggleFlicker(ShipItemStove __instance, StoveFuelTrigger ___fuelTrigger, PickupableItem heldItem)
			{
				if (!((Object)(object)___fuelTrigger == (Object)null))
				{
					LanternFlicker component = ((Component)__instance).GetComponent<LanternFlicker>();
					if (!((Object)(object)component == (Object)null) && component.flickerCoroutine == null && !((Object)(object)((Component)heldItem).GetComponent<StoveFuel>() == (Object)null))
					{
						component.maxIntensity = (float)(___fuelTrigger.GetPrivateField<int>("currentFuel") / ___fuelTrigger.GetPrivateField<int>("maxFuel")) * ___fuelTrigger.GetPrivateField<float>("initialLightIntensity");
						component.SetFlicker(enable: true);
					}
				}
			}
		}

		[HarmonyPatch(typeof(StoveFuelTrigger), "UnregisterBurntFuel")]
		internal class StoveFuelTriggerUnregisterBurntFuelPatch
		{
			[HarmonyPostfix]
			[HarmonyPatch("UnregisterBurntFuel")]
			public static void StopFlicker(ShipItemStove ___stove, float ___initialLightIntensity, int ___currentFuel, int ___maxFuel)
			{
				LanternFlicker component = ((Component)___stove).GetComponent<LanternFlicker>();
				if (!((Object)(object)component == (Object)null))
				{
					component.maxIntensity = (float)(___currentFuel / ___maxFuel) * ___initialLightIntensity;
					if (___currentFuel <= 0)
					{
						component.SetFlicker(enable: false);
					}
				}
			}
		}
	}
}