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;
}
}
}