Decompiled source of FlickeringFlashlight v1.0.1

LethalCompanyFlickeringFlashlight.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using LethalCompanyFlickeringFlashlight;
using LethalCompanyFlickeringFlashlight.Patches;
using Unity.Netcode;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("LethalCompanyFlickeringFlashlight")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("LethalCompanyFlickeringFlashlight")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("f7323410-3cdd-44f0-8d62-6bd706359e7f")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
public class FlashlightFlickeringSystem : MonoBehaviour
{
	public ulong flashlightId;

	public bool critical;

	public bool isFlickering;

	public Coroutine flickerRoutine;

	private string info;

	private FlashlightItem flashlight;

	private float nextFlick = 0f;

	public void Init(FlashlightItem _flashlight)
	{
		flashlightId = ((Component)_flashlight).GetComponent<NetworkObject>().NetworkObjectId;
		isFlickering = false;
		critical = false;
		flashlight = _flashlight;
	}

	private void Update()
	{
		if (FlickeringFlashlight.infinityCriticalFlashlight.Value && ((GrabbableObject)flashlight).insertedBattery.charge < 0.05f)
		{
			((GrabbableObject)flashlight).insertedBattery.charge = 0.05f;
		}
		if (isFlickering || !((GrabbableObject)flashlight).isBeingUsed)
		{
			return;
		}
		if (((GrabbableObject)flashlight).insertedBattery.charge <= FlickeringFlashlight.criticalEnergy.Value)
		{
			critical = true;
			info = $"CRITICAL battery, {((GrabbableObject)flashlight).insertedBattery.charge}%";
			StartFlickering();
		}
		else if (((GrabbableObject)flashlight).insertedBattery.charge <= FlickeringFlashlight.lowEnergy.Value && (float)Random.Range(0, 100) < FlickeringFlashlight.lowEnergyFlickerChance.Value)
		{
			critical = false;
			info = $"LOW battery, {((GrabbableObject)flashlight).insertedBattery.charge}%";
			StartFlickering();
		}
		else if (Object.op_Implicit((Object)(object)((GrabbableObject)(flashlight?)).playerHeldBy))
		{
			if (FlickeringFlashlight.fearLevel.Value <= ((GrabbableObject)(flashlight?)).playerHeldBy?.playersManager?.fearLevel)
			{
				critical = true;
				info = $"FEAR level, {((GrabbableObject)(flashlight?)).playerHeldBy?.playersManager?.fearLevel}";
				StartFlickering();
			}
			else if (FlickeringFlashlight.insanityLevel.Value <= ((GrabbableObject)(flashlight?)).playerHeldBy?.insanityLevel / ((GrabbableObject)(flashlight?)).playerHeldBy?.maxInsanityLevel)
			{
				critical = false;
				info = $"INSANITY level, {((GrabbableObject)(flashlight?)).playerHeldBy?.insanityLevel / ((GrabbableObject)(flashlight?)).playerHeldBy?.maxInsanityLevel}";
				StartFlickering();
			}
		}
	}

	private void StartFlickering()
	{
		if (!(nextFlick > Time.time))
		{
			float min = FlickeringFlashlight.minFlickerDelay.Value / (critical ? FlickeringFlashlight.criticalEnergyFlickerMultiplier.Value : FlickeringFlashlight.lowEnergyFlickerMultiplier.Value);
			float max = FlickeringFlashlight.maxFlickerDelay.Value / (critical ? FlickeringFlashlight.criticalEnergyFlickerMultiplier.Value : FlickeringFlashlight.lowEnergyFlickerMultiplier.Value);
			if (flickerRoutine != null)
			{
				CoroutineRunner.Instance.Stop(flickerRoutine);
			}
			flickerRoutine = CoroutineRunner.Instance.Run(Flickering(min, max));
		}
	}

	private IEnumerator Flickering(float min, float max)
	{
		if (((NetworkBehaviour)flashlight).IsOwner)
		{
			((GrabbableObject)flashlight).SyncBatteryServerRpc((int)(((GrabbableObject)flashlight).insertedBattery.charge * 100f));
		}
		if (FlickeringFlashlight.enableDebugLog.Value)
		{
			if (Object.op_Implicit((Object)(object)((GrabbableObject)(flashlight?)).playerHeldBy))
			{
				FlickeringFlashlight.GetLogger().LogInfo((object)(((GrabbableObject)(flashlight?)).playerHeldBy?.playerUsername + "'s flashlight is flickering (" + info + ")."));
			}
			else
			{
				ManualLogSource logger = FlickeringFlashlight.GetLogger();
				string[] obj = new string[5] { "Flashlight (", null, null, null, null };
				FlashlightItem obj2 = flashlight;
				obj[1] = ((obj2 != null) ? ((Object)obj2).name : null);
				obj[2] = ") is flickering (";
				obj[3] = info;
				obj[4] = ").";
				logger.LogInfo((object)string.Concat(obj));
			}
		}
		nextFlick = Time.time + (critical ? FlickeringFlashlight.cooldownCritical.Value : FlickeringFlashlight.cooldownLow.Value);
		isFlickering = true;
		float elapsed = 0f;
		while (true)
		{
			int num;
			if (elapsed < FlickeringFlashlight.flickerDuration.Value / (critical ? 1f : 2f))
			{
				FlashlightItem obj3 = flashlight;
				if (obj3 != null && ((GrabbableObject)obj3).insertedBattery?.charge > 0f)
				{
					num = (isFlickering ? 1 : 0);
					goto IL_027c;
				}
			}
			num = 0;
			goto IL_027c;
			IL_027c:
			if (num == 0)
			{
				break;
			}
			flashlight.SwitchFlashlight(!((GrabbableObject)flashlight).isBeingUsed);
			float delay = Random.Range(min, max);
			yield return (object)new WaitForSeconds(delay);
			elapsed += delay;
		}
		flashlight.SwitchFlashlight(((GrabbableObject)flashlight).insertedBattery.charge > 0f && isFlickering);
		isFlickering = false;
	}
}
public class CoroutineRunner : MonoBehaviour
{
	private static CoroutineRunner _instance;

	public static CoroutineRunner Instance
	{
		get
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			if ((Object)(object)_instance == (Object)null)
			{
				GameObject val = new GameObject("CoroutineRunner");
				Object.DontDestroyOnLoad((Object)(object)val);
				_instance = val.AddComponent<CoroutineRunner>();
			}
			return _instance;
		}
	}

	public Coroutine Run(IEnumerator enumerator)
	{
		return ((MonoBehaviour)this).StartCoroutine(enumerator);
	}

	public void Stop(Coroutine coroutine)
	{
		if (coroutine != null)
		{
			((MonoBehaviour)this).StopCoroutine(coroutine);
		}
	}
}
namespace LethalCompanyFlickeringFlashlight
{
	[BepInPlugin("Juzlus.FlickeringFlashlight", "Flickering Flashlight", "1.0.0")]
	public class FlickeringFlashlight : BaseUnityPlugin
	{
		private const string modGUID = "Juzlus.FlickeringFlashlight";

		private const string modName = "Flickering Flashlight";

		private const string modVersion = "1.0.0";

		private readonly Harmony harmony = new Harmony("Juzlus.FlickeringFlashlight");

		private static FlickeringFlashlight instance;

		internal ManualLogSource mls;

		public static ConfigEntry<float> lowEnergy;

		public static ConfigEntry<float> criticalEnergy;

		public static ConfigEntry<float> flickerDuration;

		public static ConfigEntry<float> minFlickerDelay;

		public static ConfigEntry<float> maxFlickerDelay;

		public static ConfigEntry<float> lowEnergyFlickerChance;

		public static ConfigEntry<float> lowEnergyFlickerMultiplier;

		public static ConfigEntry<float> criticalEnergyFlickerMultiplier;

		public static ConfigEntry<bool> infinityCriticalFlashlight;

		public static ConfigEntry<bool> enableDebugLog;

		public static ConfigEntry<float> fearLevel;

		public static ConfigEntry<float> insanityLevel;

		public static ConfigEntry<float> cooldownLow;

		public static ConfigEntry<float> cooldownCritical;

		public static ManualLogSource GetLogger()
		{
			return instance.mls;
		}

		private void Awake()
		{
			if (!Object.op_Implicit((Object)(object)instance))
			{
				instance = this;
			}
			InitializeLogger();
			CreateConfig();
			SetHarmony();
		}

		private void InitializeLogger()
		{
			mls = Logger.CreateLogSource("Juzlus.FlickeringFlashlight");
			mls.LogInfo((object)"Plugin \"Flickering Flashlight\" is loaded!");
		}

		private static void CreateConfig()
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Expected O, but got Unknown
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Expected O, but got Unknown
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Expected O, but got Unknown
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Expected O, but got Unknown
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Expected O, but got Unknown
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Expected O, but got Unknown
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Expected O, but got Unknown
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Expected O, but got Unknown
			//IL_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0286: Expected O, but got Unknown
			//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c7: Expected O, but got Unknown
			//IL_02fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0308: Expected O, but got Unknown
			lowEnergy = ((BaseUnityPlugin)instance).Config.Bind<float>("Energy Threshold", "Low Energy Threshold", 0.3f, new ConfigDescription("The battery level (%) below which the flashlight starts flickering.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			criticalEnergy = ((BaseUnityPlugin)instance).Config.Bind<float>("Energy Threshold", "Critical Energy Threshold", 0.1f, new ConfigDescription("The battery level (%) at which the flashlight enters critical mode (heavy flickering).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			flickerDuration = ((BaseUnityPlugin)instance).Config.Bind<float>("Duration", "Flicker Duration", 1.5f, new ConfigDescription("Duration (in seconds) of flashlight flickering.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 15f), Array.Empty<object>()));
			minFlickerDelay = ((BaseUnityPlugin)instance).Config.Bind<float>("Duration", "Min Flicker Delay", 0.05f, new ConfigDescription("Minimum delay (in seconds) between flickers.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 2f), Array.Empty<object>()));
			maxFlickerDelay = ((BaseUnityPlugin)instance).Config.Bind<float>("Duration", "Max Flicker Delay", 0.2f, new ConfigDescription("Maximum delay (in seconds) between flickers.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 8f), Array.Empty<object>()));
			cooldownLow = ((BaseUnityPlugin)instance).Config.Bind<float>("Duration", "Next Low Flick", 10f, new ConfigDescription("Minimum delay (in seconds) between flashlight flickers when battery is low.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 60f), Array.Empty<object>()));
			cooldownCritical = ((BaseUnityPlugin)instance).Config.Bind<float>("Duration", "Next Critical Flick", 3f, new ConfigDescription("Delay (in seconds) between flashlight flickers when battery is critically low.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 30f), Array.Empty<object>()));
			lowEnergyFlickerChance = ((BaseUnityPlugin)instance).Config.Bind<float>("Chance", "Low Energy Flicker Chance", 0.01f, new ConfigDescription("Chance (%) that the flashlight will flicker when battery is low.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 10f), Array.Empty<object>()));
			fearLevel = ((BaseUnityPlugin)instance).Config.Bind<float>("Chance", "Minimal Fear Level", 0.4f, new ConfigDescription("Flashlight start flickering when player fear goes above this percentage.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			insanityLevel = ((BaseUnityPlugin)instance).Config.Bind<float>("Chance", "Minimal Insanity Level", 0.9f, new ConfigDescription("Flashlight starts flickering when player insanity goes above this percentage (You gain insanity by being alone).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			lowEnergyFlickerMultiplier = ((BaseUnityPlugin)instance).Config.Bind<float>("Frequency", "Low Energy Flicker Multiplier", 10f, new ConfigDescription("Multiplier applied to flicker frequency when battery is at low level.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 20f), Array.Empty<object>()));
			criticalEnergyFlickerMultiplier = ((BaseUnityPlugin)instance).Config.Bind<float>("Frequency", "Critical Energy Flicker Multiplier", 2f, new ConfigDescription("Multiplier applied to flicker frequency when battery is at critical level.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 20f), Array.Empty<object>()));
			infinityCriticalFlashlight = ((BaseUnityPlugin)instance).Config.Bind<bool>("Other", "Infinity Critical Energy", false, "Prevents the flashlight battery from dropping below 5% (infinity critical energy).");
			enableDebugLog = ((BaseUnityPlugin)instance).Config.Bind<bool>("Debug", "Enable Logs", false, "Show debug messages in the console about flashlight flickering.");
		}

		private void SetHarmony()
		{
			harmony.PatchAll(typeof(FlashlightItemPatch));
		}
	}
}
namespace LethalCompanyFlickeringFlashlight.Patches
{
	[HarmonyPatch(typeof(FlashlightItem))]
	internal class FlashlightItemPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(FlashlightItem), "Start")]
		private static void FlashlightItem_Start(FlashlightItem __instance)
		{
			((Component)__instance).gameObject.AddComponent<FlashlightFlickeringSystem>().Init(__instance);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(FlashlightItem), "ItemActivate")]
		private static void FlashlightItem_ItemActivate(FlashlightItem __instance)
		{
			if (GetState(__instance).isFlickering)
			{
				__instance.SwitchFlashlight(false);
				GetState(__instance).isFlickering = false;
			}
		}

		private static FlashlightFlickeringSystem GetState(FlashlightItem flashlight)
		{
			FlashlightFlickeringSystem flashlightFlickeringSystem = ((Component)flashlight).GetComponent<FlashlightFlickeringSystem>();
			if (!Object.op_Implicit((Object)(object)flashlightFlickeringSystem))
			{
				flashlightFlickeringSystem = ((Component)flashlight).gameObject.AddComponent<FlashlightFlickeringSystem>();
			}
			return flashlightFlickeringSystem;
		}
	}
}