using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using Agents; using BepInEx; using BepInEx.Configuration; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using Enemies; using GameData; using Gear; using HarmonyLib; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSystem.Collections.Generic; using LevelGeneration; using Microsoft.CodeAnalysis; using Player; using UnityEngine; using UnityEngine.Events; using UnityEngine.Rendering; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("FlashlightOverhaul")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Realistic soft-edge flashlight for GTFO using light sandwich technique")] [assembly: AssemblyFileVersion("2.0.0.0")] [assembly: AssemblyInformationalVersion("2.0.0+2cb5a57295b1efac41542353d9335b042c826c3c")] [assembly: AssemblyProduct("FlashlightOverhaul")] [assembly: AssemblyTitle("FlashlightOverhaul")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] 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; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace GTFO_SuperFlashlight { [BepInPlugin("FlashlightOverhaul", "Flashlight Overhaul", "2.0.0")] public class Plugin : BasePlugin { public static ConfigEntry HazeEnabled = null; public static ConfigEntry HazeStrength = null; public static ConfigEntry FogBeamEnabled = null; public static ConfigEntry FogBeamNearDensity = null; public static ConfigEntry FogBeamFarDensity = null; public static ConfigEntry HazeTierA = null; public static ConfigEntry HazeTierB = null; public static ConfigEntry HazeTierC = null; public static ConfigEntry HazeTierD = null; public static ConfigEntry HazeTierE = null; internal static ManualLogSource Logger = null; internal static readonly Dictionary _customBuildup = new Dictionary(); internal static readonly Dictionary _customDetectionCurrent = new Dictionary(); internal static readonly Dictionary _lastUpdateTime = new Dictionary(); internal static readonly HashSet _triggeredEnemies = new HashSet(); internal static readonly HashSet _headlightTriggeredEnemies = new HashSet(); internal static Func? _hibGetDetectionCurrent; internal static Action? _hibSetDetectionCurrent; internal static Func? _hibGetDetectionTarget; internal static Action? _hibSetWantToWakeUp; internal static Action? _hibSetHeartbeatActive; internal static MethodInfo? _hibMethodMasterStartDetection; internal static MethodInfo? _dmgMethodBulletDamage; internal static Type? _hibType; internal static Type? _dmgType; private static Dictionary _lastDamageTime = new Dictionary(); private const float PinchRetryInterval = 2f; private static bool _hibDiagDone = false; public static ConfigEntry Enabled = null; public static ConfigEntry Mode = null; public static ConfigEntry AttachLightToWeaponBone = null; public static ConfigEntry Step1 = null; public static ConfigEntry I1 = null; public static ConfigEntry R1 = null; public static ConfigEntry MidStepFraction = null; public static ConfigEntry I2 = null; public static ConfigEntry R2 = null; public static ConfigEntry Step2 = null; public static ConfigEntry MeleeAngle = null; public static ConfigEntry MeleeIntensity = null; public static ConfigEntry MeleeRange = null; public static ConfigEntry FlickerEnabled = null; public static ConfigEntry FlickerSpeed = null; public static ConfigEntry FlickerAmplitude = null; public static ConfigEntry RareFlickerEnabled = null; public static ConfigEntry RareFlickerIntervalMin = null; public static ConfigEntry RareFlickerIntervalMax = null; public static ConfigEntry HorrorFlickerEnabled = null; public static ConfigEntry HorrorFlickerIntervalMin = null; public static ConfigEntry HorrorFlickerIntervalMax = null; public static ConfigEntry BrownoutEnabled = null; public static ConfigEntry BrownoutIntervalMin = null; public static ConfigEntry BrownoutIntervalMax = null; public static ConfigEntry StutterEnabled = null; public static ConfigEntry StutterIntervalMin = null; public static ConfigEntry StutterIntervalMax = null; public static ConfigEntry RestrikeEnabled = null; public static ConfigEntry RestrikeIntervalMin = null; public static ConfigEntry RestrikeIntervalMax = null; public static ConfigEntry P_Short_CoreAngle = null; public static ConfigEntry P_Short_CoreIntensity = null; public static ConfigEntry P_Short_CoreRange = null; public static ConfigEntry P_Short_MidAngle = null; public static ConfigEntry P_Short_MidIntensity = null; public static ConfigEntry P_Short_MidRange = null; public static ConfigEntry P_Short_FallAngle = null; public static ConfigEntry P_Short_FallIntensity = null; public static ConfigEntry P_Short_FallRange = null; public static ConfigEntry P_Med1_CoreAngle = null; public static ConfigEntry P_Med1_CoreIntensity = null; public static ConfigEntry P_Med1_CoreRange = null; public static ConfigEntry P_Med1_MidAngle = null; public static ConfigEntry P_Med1_MidIntensity = null; public static ConfigEntry P_Med1_MidRange = null; public static ConfigEntry P_Med1_FallAngle = null; public static ConfigEntry P_Med1_FallIntensity = null; public static ConfigEntry P_Med1_FallRange = null; public static ConfigEntry P_Med2_CoreAngle = null; public static ConfigEntry P_Med2_CoreIntensity = null; public static ConfigEntry P_Med2_CoreRange = null; public static ConfigEntry P_Med2_MidAngle = null; public static ConfigEntry P_Med2_MidIntensity = null; public static ConfigEntry P_Med2_MidRange = null; public static ConfigEntry P_Med2_FallAngle = null; public static ConfigEntry P_Med2_FallIntensity = null; public static ConfigEntry P_Med2_FallRange = null; public static ConfigEntry P_Wide_CoreAngle = null; public static ConfigEntry P_Wide_CoreIntensity = null; public static ConfigEntry P_Wide_CoreRange = null; public static ConfigEntry P_Wide_MidAngle = null; public static ConfigEntry P_Wide_MidIntensity = null; public static ConfigEntry P_Wide_MidRange = null; public static ConfigEntry P_Wide_FallAngle = null; public static ConfigEntry P_Wide_FallIntensity = null; public static ConfigEntry P_Wide_FallRange = null; public static ConfigEntry P_Ext_CoreAngle = null; public static ConfigEntry P_Ext_CoreIntensity = null; public static ConfigEntry P_Ext_CoreRange = null; public static ConfigEntry P_Ext_MidAngle = null; public static ConfigEntry P_Ext_MidIntensity = null; public static ConfigEntry P_Ext_MidRange = null; public static ConfigEntry P_Ext_FallAngle = null; public static ConfigEntry P_Ext_FallIntensity = null; public static ConfigEntry P_Ext_FallRange = null; public static ConfigEntry DustEnabled = null; public static ConfigEntry DustOpacity = null; public static ConfigEntry Pick_Angle = null; public static ConfigEntry Pick_Intensity = null; public static ConfigEntry Pick_Range = null; public static ConfigEntry Pick_RareWeight = null; public static ConfigEntry Pick_MaxPerLevel = null; public static ConfigEntry Pick_GuaranteeFloor = null; public static ConfigEntry I3 = null; public static ConfigEntry I4 = null; public static ConfigEntry I5 = null; public static ConfigEntry R3 = null; public static ConfigEntry R4 = null; public static ConfigEntry R5 = null; public static ConfigEntry Step3 = null; public static ConfigEntry Step4 = null; public static ConfigEntry Step5 = null; internal static float HelmetAngle; internal static float HelmetIntensity; internal static float HelmetRange; internal static float HelmetFallRange; internal static float PickAngle; internal static float PickIntensity; internal static float PickRange; internal static Color PickColor = new Color(1f, 0.84f, 0.6f); private void BindConfigHaze() { HazeEnabled = ((BasePlugin)this).Config.Bind("17 - Haze (atmospheric fog in the beam)", "Haze_Enabled", true, "EN: Subtle 'thick air' glow inside the flashlight beam (in Core\n + Middle layers). Fades smoothly toward the cone edges so it\n blends naturally with the rest of the scene. Turn off if you\n don't want any extra atmosphere on top of the dust motes.\nUA: Легке відчуття 'густого повітря' всередині променя (в шарах\n Core + Middle). Плавно згасає до країв конуса, гармонійно\n зливаючись зі сценою. Вимкни, якщо не хочеш додаткової\n атмосфери поверх пилу."); HazeStrength = ((BasePlugin)this).Config.Bind("17 - Haze (atmospheric fog in the beam)", "Haze_Strength", 1f, "EN: Overall potency. 1.0 = the tuned baseline (intentionally\n very faint). 0.5 = half as visible, 2.0 = twice as visible.\n The haze also 'breathes' on its own — drifts smoothly between\n values inside a band that depends on the rundown letter (A..E),\n re-rolling every 15-65 minutes. This setting just multiplies\n the final result.\nUA: Загальна сила. 1.0 = базове (свідомо ледь помітне). 0.5 —\n вдвічі слабше, 2.0 — вдвічі сильніше. Димка також сама\n 'дихає' — плавно гуляє в межах, які залежать від літери\n глибини рандауну (A..E), і змінює ціль кожні 15-65 хв.\n Це налаштування просто множить підсумок."); FogBeamEnabled = ((BasePlugin)this).Config.Bind("17 - Haze (atmospheric fog in the beam)", "FogBeam_Enabled", true, "EN: Enables the volumetric FogSphere chain (GTFO's native GPU fog\n pipeline). Independent of Haze_Enabled — you can keep the\n billboard quad on the helmet without the volumetric spheres,\n or vice versa.\nUA: Вмикає ланцюжок об'ємних FogSphere (власний GPU-конвеєр GTFO).\n Незалежно від Haze_Enabled — можна тримати квад-overlay на\n шоломі без об'ємних сфер, або навпаки."); FogBeamNearDensity = ((BasePlugin)this).Config.Bind("17 - Haze (atmospheric fog in the beam)", "FogBeam_NearDensity", 0.0025f, "EN: Density of the volumetric fog sphere nearest to the beam apex\n (first 25 % of cone range). The chain lerps from this value\n toward FogBeam_FarDensity. Set to 0 to disable the near\n cluster entirely. Hard-capped at 0.0086 to prevent\n visibility blackout. Also scaled by Haze_Strength and the\n per-tier multiplier (Haze_TierA..E).\nUA: Густота об'ємного туману у ближній сфері (перші 25% дальності\n конуса). Ланцюжок плавно переходить від цього значення до\n FogBeam_FarDensity. 0 = вимкнути ближній кластер. Жорстко\n обмежено 0.0086 щоб не перекривати видимість. Також\n множиться на Haze_Strength та множник рівня (Haze_TierA..E)."); FogBeamFarDensity = ((BasePlugin)this).Config.Bind("17 - Haze (atmospheric fog in the beam)", "FogBeam_FarDensity", 0.0005f, "EN: Density of the fog sphere furthest from the apex (at 50 % of\n cone range). Spheres beyond this depth are not placed. Keep\n this lower than FogBeam_NearDensity for a natural near-to-\n far density gradient.\nUA: Густота туману у найдальшій сфері (50% дальності конуса).\n Сфери далі цієї точки не розміщуються. Тримай менше ніж\n FogBeam_NearDensity для природного градієнту."); HazeTierA = ((BasePlugin)this).Config.Bind("17 - Haze (atmospheric fog in the beam)", "Haze_TierA", 0.12f, "EN: Base haze multiplier for rundown tier A (shallowest).\n The breathing system drifts ±13 % around this value.\nUA: Базовий множник димки для рівня A (найменша глибина).\n Система 'дихання' гуляє ±13 % навколо цього значення."); HazeTierB = ((BasePlugin)this).Config.Bind("17 - Haze (atmospheric fog in the beam)", "Haze_TierB", 0.19f, "EN: Base haze multiplier for rundown tier B.\nUA: Базовий множник димки для рівня B."); HazeTierC = ((BasePlugin)this).Config.Bind("17 - Haze (atmospheric fog in the beam)", "Haze_TierC", 0.26f, "EN: Base haze multiplier for rundown tier C.\nUA: Базовий множник димки для рівня C."); HazeTierD = ((BasePlugin)this).Config.Bind("17 - Haze (atmospheric fog in the beam)", "Haze_TierD", 0.32f, "EN: Base haze multiplier for rundown tier D.\nUA: Базовий множник димки для рівня D."); HazeTierE = ((BasePlugin)this).Config.Bind("17 - Haze (atmospheric fog in the beam)", "Haze_TierE", 0.38f, "EN: Base haze multiplier for rundown tier E (deepest).\n At 1.0 the effect reaches the maximum breathing ceiling.\nUA: Базовий множник димки для рівня E (найбільша глибина).\n При 1.0 ефект на максимальній стелі дихання."); } internal static AgentTarget? TryBuildFlashlightTarget(EnemyAgent enemy, float detectionRel) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0088: 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_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: 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_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Expected O, but got Unknown //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: 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) if ((Object)(object)enemy == (Object)null) { return null; } try { if (!PlayerManager.HasLocalPlayerAgent()) { return null; } Agent localPlayerAgent = (Agent)(object)PlayerManager.GetLocalPlayerAgent(); if ((Object)(object)localPlayerAgent == (Object)null) { return null; } Vector3 position = localPlayerAgent.Position; Vector3 aimTargetPosition = position; Vector3 navigationPosition = position; try { aimTargetPosition = localPlayerAgent.EyePosition; } catch { } try { navigationPosition = localPlayerAgent.NavigationPosition; } catch { } Vector3 position2 = enemy.Position; Vector3 val = position - position2; float magnitude = ((Vector3)(ref val)).magnitude; val = ((!(magnitude > 0.0001f)) ? ((Agent)enemy).Forward : (val / magnitude)); return new AgentTarget { m_globalID = localPlayerAgent.GlobalID, m_agent = localPlayerAgent, m_position = position, m_navigationPosition = navigationPosition, m_aimTargetPosition = aimTargetPosition, m_viewDir = localPlayerAgent.Forward, m_dir = val, m_viewDot = Mathf.Clamp01(Vector3.Dot(((Agent)enemy).Forward, val)), m_distance = magnitude, m_inTargetsLOS = true, m_hasLineOfSight = true, m_isOccluded = false, m_autoDetect = false, m_wakesHibernators = true, m_detectionType = (AgentTargetDetectionType)2, m_propagation = (AgentTargetPropagationType)0, m_score = Mathf.Max(1f, detectionRel), m_detectionBuildup = Mathf.Clamp01(detectionRel), m_lightDetectionBuildup = Mathf.Clamp01(detectionRel), m_attackBuildup = 0f, m_offGraphBuildup = 0f, m_rndWeight = 1f }; } catch (Exception ex) { Logger.LogWarning((object)("[FO] Build flashlight AgentTarget failed: " + ex.Message)); return null; } } private static void FireWakeupPinch(EnemyAgent agent, float damage = 0.01f) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)agent == (Object)null || (Object)(object)agent.Damage == (Object)null) { return; } try { Agent val = null; try { if (PlayerManager.HasLocalPlayerAgent()) { val = (Agent)(object)PlayerManager.GetLocalPlayerAgent(); } } catch { } Vector3 position = agent.Position; Vector3 val2 = ((Agent)agent).Forward; if ((Object)(object)val != (Object)null) { Vector3 val3 = position - ((Component)val).transform.position; if (((Vector3)(ref val3)).sqrMagnitude > 0.0001f) { val2 = ((Vector3)(ref val3)).normalized; } } agent.Damage.BulletDamage(damage, val, position, val2, -val2, false, 0, 1f, 1f, 0u); } catch (Exception ex) { Logger.LogWarning((object)("[FO] BulletDamage pinch failed: " + ex.Message)); } } internal static void RetryWakeupPinchIfDue(EnemyAgent agent, int id) { if (!((Object)(object)agent == (Object)null) && !((Object)(object)agent.Damage == (Object)null)) { float time = Time.time; _lastDamageTime.TryGetValue(id, out var value); if (!(time - value <= 2f)) { _lastDamageTime[id] = time; Logger.LogInfo((object)("[FO] Wakeup PINCH retry id=" + id)); FireWakeupPinch(agent, _headlightTriggeredEnemies.Contains(id) ? 0.2f : 0.01f); } } } public override void Load() { //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Expected O, but got Unknown //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Expected O, but got Unknown //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Expected O, but got Unknown //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Expected O, but got Unknown //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Expected O, but got Unknown //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Expected O, but got Unknown Logger = ((BasePlugin)this).Log; BindConfig(); BindConfigHaze(); ApplyPreset(Mode.Value); SceneManager.sceneLoaded += UnityAction.op_Implicit((Action)delegate { //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Expected O, but got Unknown LightSandwich.RebuildAll(); LightSandwich.ProcessAllSpotLights(); PickableFlashlightTracker.Reset(); FlashlightEnemyDetection.Reset(); _customBuildup.Clear(); _customDetectionCurrent.Clear(); _lastUpdateTime.Clear(); _triggeredEnemies.Clear(); _headlightTriggeredEnemies.Clear(); if (!_hibDiagDone) { try { Il2CppArrayBase val7 = Object.FindObjectsOfType(); if (val7 != null && val7.Length > 0) { _hibDiagDone = true; EnemyAgent val8 = val7[0]; ManualLogSource logger4 = Logger; bool flag3 = default(bool); BepInExInfoLogInterpolatedStringHandler val9 = new BepInExInfoLogInterpolatedStringHandler(23, 2, ref flag3); if (flag3) { ((BepInExLogInterpolatedStringHandler)val9).AppendLiteral("[FO] DiagAgent: "); ((BepInExLogInterpolatedStringHandler)val9).AppendFormatted((val8 != null) ? ((Object)val8).name : null); ((BepInExLogInterpolatedStringHandler)val9).AppendLiteral(" count="); ((BepInExLogInterpolatedStringHandler)val9).AppendFormatted(val7.Length); } logger4.LogInfo(val9); EnemyLocomotion val10 = ((val8 != null) ? val8.Locomotion : null); if ((Object)(object)val10 != (Object)null) { Type type = ((object)val10).GetType(); PropertyInfo[] properties2 = type.GetProperties(BindingFlags.Instance | BindingFlags.Public); foreach (PropertyInfo propertyInfo2 in properties2) { Logger.LogInfo((object)("[FO] Loc-PROP: " + propertyInfo2.PropertyType.Name + " " + propertyInfo2.Name)); } FieldInfo[] fields2 = type.GetFields(BindingFlags.Instance | BindingFlags.Public); foreach (FieldInfo fieldInfo2 in fields2) { Logger.LogInfo((object)("[FO] Loc-FIELD: " + fieldInfo2.FieldType.Name + " " + fieldInfo2.Name)); } MethodInfo[] methods2 = type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public); foreach (MethodInfo methodInfo3 in methods2) { Logger.LogInfo((object)("[FO] Loc-MTD: " + methodInfo3.ReturnType.Name + " " + methodInfo3.Name)); } ES_Hibernate hibernate = val10.Hibernate; if (hibernate != null) { Type type2 = ((object)hibernate).GetType(); Logger.LogInfo((object)("[FO] Hib-TYPE: " + type2.FullName)); properties2 = type2.GetProperties(BindingFlags.Instance | BindingFlags.Public); foreach (PropertyInfo propertyInfo3 in properties2) { Logger.LogInfo((object)("[FO] Hib-PROP: " + propertyInfo3.PropertyType.Name + " " + propertyInfo3.Name)); } fields2 = type2.GetFields(BindingFlags.Instance | BindingFlags.Public); foreach (FieldInfo fieldInfo3 in fields2) { Logger.LogInfo((object)("[FO] Hib-FIELD: " + fieldInfo3.FieldType.Name + " " + fieldInfo3.Name)); } methods2 = type2.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public); foreach (MethodInfo methodInfo4 in methods2) { Logger.LogInfo((object)("[FO] Hib-MTD: " + methodInfo4.ReturnType.Name + " " + methodInfo4.Name)); } } EnemyAI aI = val8.AI; if ((Object)(object)aI != (Object)null) { Type type3 = ((object)aI).GetType(); Logger.LogInfo((object)("[FO] AI-TYPE: " + type3.FullName)); methods2 = type3.GetMethods(BindingFlags.Instance | BindingFlags.Public); foreach (MethodInfo methodInfo5 in methods2) { Logger.LogInfo((object)("[FO] AI-MTD: " + methodInfo5.ReturnType.Name + " " + methodInfo5.Name)); } } Dam_EnemyDamageBase damage2 = val8.Damage; if ((Object)(object)damage2 != (Object)null) { Type type4 = ((object)damage2).GetType(); Logger.LogInfo((object)("[FO] DMG-TYPE: " + type4.FullName)); methods2 = type4.GetMethods(BindingFlags.Instance | BindingFlags.Public); foreach (MethodInfo methodInfo6 in methods2) { Logger.LogInfo((object)("[FO] DMG-MTD: " + methodInfo6.ReturnType.Name + " " + methodInfo6.Name + "(" + string.Join(",", Array.ConvertAll(methodInfo6.GetParameters(), (ParameterInfo p) => p.ParameterType.Name)) + ")")); } } else { Logger.LogWarning((object)"[FO] Hib-DIAG: loc.Hibernate is null"); } } else { Logger.LogWarning((object)"[FO] Hib-DIAG: agent.Locomotion is null"); } } else { Logger.LogInfo((object)"[FO] Hib-DIAG: no EnemyAgents in scene yet"); } } catch (Exception ex6) { Logger.LogWarning((object)("[FO] Hib-DIAG sceneLoad threw: " + ex6.Message)); } } }); FlashlightEnemyDetection.OnEnemyInBeam = (Action)Delegate.Combine(FlashlightEnemyDetection.OnEnemyInBeam, (Action)delegate(EnemyAgent agent, float dist, float angle) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Invalid comparison between Unknown and I4 try { if (!((Object)(object)agent == (Object)null) && !((Object)(object)agent.AI == (Object)null)) { int instanceID = ((Object)agent).GetInstanceID(); if ((int)((AgentAI)agent.AI).Mode == 1) { if (_triggeredEnemies.Contains(instanceID)) { Logger.LogInfo((object)("[FO] Enemy " + instanceID + " is now Agressive. Clearing tracking.")); _triggeredEnemies.Remove(instanceID); } _headlightTriggeredEnemies.Remove(instanceID); _customBuildup.Remove(instanceID); _customDetectionCurrent.Remove(instanceID); _lastUpdateTime.Remove(instanceID); _lastDamageTime.Remove(instanceID); } else if (_triggeredEnemies.Contains(instanceID)) { if (_headlightTriggeredEnemies.Contains(instanceID)) { RetryWakeupPinchIfDue(agent, instanceID); } else { if (_hibSetDetectionCurrent != null && _hibGetDetectionTarget != null) { EnemyLocomotion locomotion = agent.Locomotion; ES_Hibernate val5 = ((locomotion != null) ? locomotion.Hibernate : null); if (val5 != null) { float num = 1f; try { num = _hibGetDetectionTarget(val5); } catch { } try { _hibSetDetectionCurrent(val5, num * 1.05f); } catch { } if (_hibSetHeartbeatActive != null) { try { _hibSetHeartbeatActive(val5, arg2: true); } catch { } } } } RetryWakeupPinchIfDue(agent, instanceID); } } else { EnemyLocomotion locomotion2 = agent.Locomotion; ES_Hibernate val6 = ((locomotion2 != null) ? locomotion2.Hibernate : null); if (val6 == null) { _customBuildup.Remove(instanceID); _customDetectionCurrent.Remove(instanceID); _lastUpdateTime.Remove(instanceID); } else { if (_hibType == null) { _hibType = ((object)val6).GetType(); (Func? getter, Action? setter) tuple = ResolveAccessors(_hibType, "m_detectionCurrent", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); _hibGetDetectionCurrent = tuple.getter; _hibSetDetectionCurrent = tuple.setter; _hibGetDetectionTarget = ResolveAccessors(_hibType, "m_detectionTarget", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).getter; _hibSetWantToWakeUp = ResolveAccessors(_hibType, "m_wantToWakeUp", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).setter; _hibSetHeartbeatActive = ResolveAccessors(_hibType, "m_heartbeatActive", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).setter; _hibMethodMasterStartDetection = _hibType.GetMethod("MasterStartDetection", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); Dam_EnemyDamageBase damage = agent.Damage; if ((Object)(object)damage != (Object)null) { _dmgType = ((object)damage).GetType(); MethodInfo[] methods = _dmgType.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { if (methodInfo.Name == "BulletDamage" && methodInfo.GetParameters().Length == 10) { _dmgMethodBulletDamage = methodInfo; break; } } Logger.LogInfo((object)("[FO] DMG-RESOLVE type=" + _dmgType.FullName)); Logger.LogInfo((object)("[FO] BulletDamage found: " + (_dmgMethodBulletDamage != null))); } Logger.LogInfo((object)("[FO] Hib-RESOLVE type=" + _hibType.FullName)); Logger.LogInfo((object)("[FO] m_detectionCurrent : get=" + (_hibGetDetectionCurrent != null) + " set=" + (_hibSetDetectionCurrent != null))); Logger.LogInfo((object)("[FO] m_detectionTarget : get=" + (_hibGetDetectionTarget != null))); Logger.LogInfo((object)("[FO] m_wantToWakeUp : set=" + (_hibSetWantToWakeUp != null))); Logger.LogInfo((object)("[FO] MasterStartDetection: " + (_hibMethodMasterStartDetection != null))); if (_hibSetWantToWakeUp == null) { Logger.LogWarning((object)"[FO] m_wantToWakeUp not found. Dumping bool members:"); PropertyInfo[] properties = _hibType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (PropertyInfo propertyInfo in properties) { if (propertyInfo.PropertyType == typeof(bool)) { Logger.LogWarning((object)("[FO] BOOL-PROP " + propertyInfo.Name + " R=" + propertyInfo.CanRead + " W=" + propertyInfo.CanWrite)); } } FieldInfo[] fields = _hibType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { if (fieldInfo.FieldType == typeof(bool)) { Logger.LogWarning((object)("[FO] BOOL-FIELD " + fieldInfo.Name)); } } Logger.LogWarning((object)"[FO] All methods on ES_Hibernate:"); MethodInfo[] methods = _hibType.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo2 in methods) { Logger.LogWarning((object)("[FO] MTD " + methodInfo2.ReturnType.Name + " " + methodInfo2.Name + "(" + string.Join(",", Array.ConvertAll(methodInfo2.GetParameters(), (ParameterInfo p2) => p2.ParameterType.Name)) + ")")); } } } float unscaledTime = Time.unscaledTime; float value; float num2 = (_lastUpdateTime.TryGetValue(instanceID, out value) ? (unscaledTime - value) : Time.deltaTime); _lastUpdateTime[instanceID] = unscaledTime; if (!_customBuildup.TryGetValue(instanceID, out var value2)) { value2 = 0f; } float lastBeamRange = FlashlightEnemyDetection.LastBeamRange; float lastBeamIntensity = FlashlightEnemyDetection.LastBeamIntensity; float num3 = Mathf.Clamp01(1f - dist / Mathf.Max(lastBeamRange, 1f)); float num4 = Mathf.Clamp01(1f - angle / 45f); float num5 = Mathf.Clamp01(lastBeamIntensity); float num6 = num3 * num4 * num5; float num7 = ((value2 > 0.7f) ? 2.2f : 1.5f); value2 = Mathf.Clamp01(value2 + num7 * num6 * num2); _customBuildup[instanceID] = value2; if (!_lastUpdateTime.TryGetValue(~instanceID, out var value3) || !(unscaledTime - value3 < 0.5f)) { _lastUpdateTime[~instanceID] = unscaledTime; Logger.LogInfo((object)("[FO] Buildup id=" + instanceID + " buildup=" + value2.ToString("F3") + " exposure=" + num6.ToString("F3") + " dist=" + dist.ToString("F1") + " angle=" + angle.ToString("F1"))); } if (_hibSetDetectionCurrent != null) { float num8 = 1f; if (_hibGetDetectionTarget != null) { try { num8 = _hibGetDetectionTarget(val6); } catch { } } if (!_customDetectionCurrent.TryGetValue(instanceID, out var value4)) { value4 = 0f; if (_hibGetDetectionCurrent != null) { try { value4 = _hibGetDetectionCurrent(val6); } catch { } } } float num9 = value2 * num8; float num10 = 2f; float num11 = Mathf.Lerp(value4, num9, 1f - Mathf.Exp((0f - num10) * num2)); float num12 = Mathf.Max(value4, num11); _customDetectionCurrent[instanceID] = num12; try { _hibSetDetectionCurrent(val6, num12); } catch { } } if (value2 >= 1f) { _customBuildup[instanceID] = 1f; bool flag2 = _triggeredEnemies.Add(instanceID); bool lastBeamIsHeadlight = FlashlightEnemyDetection.LastBeamIsHeadlight; if (lastBeamIsHeadlight) { _headlightTriggeredEnemies.Add(instanceID); } float num13 = 1f; if (_hibGetDetectionTarget != null) { try { num13 = _hibGetDetectionTarget(val6); } catch { } } float num14 = num13 * 1.05f; _customDetectionCurrent[instanceID] = num14; if (_hibSetDetectionCurrent != null) { try { _hibSetDetectionCurrent(val6, num14); } catch { } } if (_hibSetHeartbeatActive != null) { try { _hibSetHeartbeatActive(val6, arg2: true); } catch { } } if (!lastBeamIsHeadlight && flag2 && _hibMethodMasterStartDetection != null) { try { _hibMethodMasterStartDetection.Invoke(val6, null); Logger.LogInfo((object)("[FO] MasterStartDetection once id=" + instanceID)); } catch (Exception ex4) { Logger.LogWarning((object)("[FO] MasterStartDetection failed id=" + instanceID + " err=" + ex4.Message)); } } Logger.LogInfo((object)("[FO] Wakeup PINCH firing id=" + instanceID)); _lastDamageTime[instanceID] = Time.time; FireWakeupPinch(agent, lastBeamIsHeadlight ? 0.2f : 0.01f); } } } } } catch (Exception ex5) { Logger.LogWarning((object)("[FO] OnEnemyInBeam threw: " + ex5.Message)); } }); Harmony val = new Harmony("FlashlightOverhaul"); bool flag = default(bool); try { val.PatchAll(); } catch (Exception ex) { ManualLogSource logger = Logger; BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(29, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[FO] Harmony PatchAll threw: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex); } logger.LogError(val2); } try { MethodInfo method = typeof(EnemyDetection).GetMethod("UpdateHibernationDetection", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method != null) { MethodInfo method2 = typeof(Patch_HibernationDetectionUpdate).GetMethod("Postfix", BindingFlags.Static | BindingFlags.NonPublic); if (method2 != null) { val.Patch((MethodBase)method, (HarmonyMethod)null, new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } Logger.LogInfo((object)"[FO] HibernationDetection patch applied."); } else { Logger.LogWarning((object)"[FO] UpdateHibernationDetection not found — detection-decay patch skipped."); } } catch (Exception ex2) { Logger.LogWarning((object)("[FO] HibernationDetection patch failed (non-critical): " + ex2.Message)); } try { ClassInjector.RegisterTypeInIl2Cpp(); ClassInjector.RegisterTypeInIl2Cpp(); GameObject val3 = new GameObject("LightUpdater"); Object.DontDestroyOnLoad((Object)val3); ((Object)val3).hideFlags = (HideFlags)61; val3.AddComponent(); } catch (Exception ex3) { ManualLogSource logger2 = Logger; BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(41, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[FO] ClassInjector / AddComponent threw: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex3); } logger2.LogError(val2); } ManualLogSource logger3 = Logger; BepInExInfoLogInterpolatedStringHandler val4 = new BepInExInfoLogInterpolatedStringHandler(18, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted("Flashlight Overhaul"); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" v"); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted("2.0.0"); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" loaded (Mode="); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(Mode.Value); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(")."); } logger3.LogInfo(val4); static (Func? getter, Action? setter) ResolveAccessors(Type t, string name, BindingFlags f) where T : notnull { PropertyInfo prop = t.GetProperty(name, f); if (prop != null) { Func item = (prop.CanRead ? ((Func)((object o) => (T)prop.GetValue(o))) : null); Action item2 = (prop.CanWrite ? ((Action)delegate(object o, T v) { prop.SetValue(o, v); }) : null); return (item, item2); } FieldInfo field = t.GetField(name, f); if (field != null) { Func item3 = (object o) => (T)field.GetValue(o); Action item4 = delegate(object o, T v) { field.SetValue(o, v); }; return (item3, item4); } return (null, null); } } private void BindConfig() { Enabled = ((BasePlugin)this).Config.Bind("01 - General", "Enabled", true, "EN: Master switch for the entire mod. False = fully disabled.\nUA: Головний вимикач мода. False = повністю вимкнено."); Mode = ((BasePlugin)this).Config.Bind("01 - General", "Mode", FlashLightMode.MINIMAL, "EN: Pick the flashlight style you want.\n MINIMAL — For near-vanilla gameplay. Just a clean\n main beam and a soft outer glow. (Default)\n CASUAL — I think it's balanced.\n VERY_CASUAL — A bit wider and a bit further than CASUAL.\n ITS_2050_BRUH — Sleepers will hear you, but they probably\n won't see you. Shine!\n VANILLA — Fully disables all mod changes.\nUA: Обери стиль ліхтариків.\n MINIMAL — Для около-ванільного геймплею. Просто чистий\n основний промінь і м'яке зовнішнє світло. (Дефолт)\n CASUAL — По-моєму, збалансовано.\n VERY_CASUAL — Трохи ширше і трохи далі за CASUAL.\n ITS_2050_BRUH — Сплячі тебе почують, але побачити вже\n навряд. Сяй!\n VANILLA — Повністю вимикає всі зміни мода."); AttachLightToWeaponBone = ((BasePlugin)this).Config.Bind("01 - General", "AttachLightToWeaponBone", true, "EN: True — the flashlight rides along with the gun model, so the\n beam moves during reload and weapon-swap animations instead of\n staring straight ahead. False — beam locked rigidly to the\n camera.\nUA: True — ліхтарик їздить разом з моделлю зброї, тож промінь\n рухається під час перезарядки та зміни зброї, а не дивиться\n рівно вперед. False — промінь жорстко прив'язаний до камери."); Step1 = ((BasePlugin)this).Config.Bind("02 - Core Layer (RF_Core)", "AngleStep", 30f, "EN: Widens the beam of the pickable (found) flashlight and\n environment lights in the level. Does not affect\n weapon flashlights — those have their own width settings\n in sections 09-13.\nUA: Розширює промінь підбираного ліхтарика і освітлення\n на рівні. На ліхтарики зброї не впливає — в них є\n власні налаштування ширини у секціях 09-13."); I1 = ((BasePlugin)this).Config.Bind("03 - Middle Layer (RF_L1) — multiplier path", "IntensityFraction", 0.625f, "EN: How bright the middle glow ring is, as a fraction of the\n inner beam's brightness. Affects the pickable flashlight\n and environment lights only.\nUA: Яскравість середнього кільця відносно центру.\n Стосується лише підбираного ліхтарика і освітлення на рівні."); R1 = ((BasePlugin)this).Config.Bind("03 - Middle Layer (RF_L1) — multiplier path", "RangeFraction", 0.62f, "EN: How far the middle glow ring reaches, as a fraction of the\n inner beam's reach. Affects the pickable flashlight\n and environment lights only.\nUA: Як далеко сягає середнє кільце відносно дальності центру.\n Стосується лише підбираного ліхтарика і освітлення на рівні."); MidStepFraction = ((BasePlugin)this).Config.Bind("03 - Middle Layer (RF_L1) — multiplier path", "AngleStepFraction", 0.252f, "EN: How much wider the middle glow ring is than the inner beam,\n relative to the outer glow's width.\nUA: Наскільки середнє кільце ширше за центр, відносно\n ширини зовнішнього кільця."); I2 = ((BasePlugin)this).Config.Bind("04 - Falloff Layer (RF_L2) — multiplier path", "IntensityFraction", 0.3125f, "EN: How bright the soft outer glow is, as a fraction of the\n inner beam (pickable / map lights only).\nUA: Яскравість м'якого зовнішнього світла, відносно центру\n (лише для підбираного ліхтарика і світла на рівні)."); R2 = ((BasePlugin)this).Config.Bind("04 - Falloff Layer (RF_L2) — multiplier path", "RangeFraction", 0.38f, "EN: How far the soft outer glow reaches, as a fraction of the\n inner beam's reach (pickable / map lights only).\nUA: Як далеко сягає м'яке зовнішнє світло, відносно дальності\n центру (лише для підбираного ліхтарика і світла на рівні)."); Step2 = ((BasePlugin)this).Config.Bind("04 - Falloff Layer (RF_L2) — multiplier path", "AngleStep", 119f, "EN: How much wider the soft outer glow is than the inner beam,\n in degrees.\nUA: Наскільки м'яке зовнішнє світло ширше за центр, у градусах."); MeleeAngle = ((BasePlugin)this).Config.Bind("05 - Helmet Synth (melee/tools) — CASUAL", "Angle", 85f, "EN: How wide the helmet light is, in degrees.\nUA: Наскільки широке світло шолома, у градусах."); MeleeIntensity = ((BasePlugin)this).Config.Bind("05 - Helmet Synth (melee/tools) — CASUAL", "Intensity", 1f, "EN: How bright the helmet light is.\nUA: Наскільки яскраве світло шолома."); MeleeRange = ((BasePlugin)this).Config.Bind("05 - Helmet Synth (melee/tools) — CASUAL", "Range", 13f, "EN: How far the helmet light reaches, in metres.\nUA: Як далеко світить шолом, у метрах."); FlickerEnabled = ((BasePlugin)this).Config.Bind("06 - Perlin Flicker (continuous tremor)", "Enabled", true, "EN: Subtle, always-on light tremor — like a real flashlight.\nUA: Тонкий постійний тремор світла — як у справжнього ліхтарика."); FlickerSpeed = ((BasePlugin)this).Config.Bind("06 - Perlin Flicker (continuous tremor)", "Speed", 2.5f, "EN: How fast the tremor wobbles. Higher = faster.\nUA: Швидкість тремору. Більше = швидше."); FlickerAmplitude = ((BasePlugin)this).Config.Bind("06 - Perlin Flicker (continuous tremor)", "Amplitude", 0.04f, "EN: How strong the tremor is (0.04 = ±4% brightness).\nUA: Сила тремору (0.04 = ±4% яскравості)."); RareFlickerEnabled = ((BasePlugin)this).Config.Bind("07 - Rare Flicker (bad-contact bursts)", "Enabled", true, "EN: Occasional bursts of 3-7 quick blinks, like a loose battery.\nUA: Випадкові серії з 3-7 швидких миготінь — наче поганий\n контакт батареї."); RareFlickerIntervalMin = ((BasePlugin)this).Config.Bind("07 - Rare Flicker (bad-contact bursts)", "IntervalMinSeconds", 180f, "EN: Minimum seconds between blink bursts.\nUA: Мінімум секунд між серіями миготінь."); RareFlickerIntervalMax = ((BasePlugin)this).Config.Bind("07 - Rare Flicker (bad-contact bursts)", "IntervalMaxSeconds", 420f, "EN: Maximum seconds between blink bursts.\nUA: Максимум секунд між серіями миготінь."); HorrorFlickerEnabled = ((BasePlugin)this).Config.Bind("08 - Horror Flicker (long dark pause)", "Enabled", true, "EN: Horror-movie blinks: 6-14 flickers with one long dark pause.\n Pretty creepy.\nUA: Хоррор-миготіння: 6-14 спалахів з однією довгою темною\n паузою. Доволі моторошно."); HorrorFlickerIntervalMin = ((BasePlugin)this).Config.Bind("08 - Horror Flicker (long dark pause)", "IntervalMinSeconds", 240f, "EN: Minimum seconds between horror events.\nUA: Мінімум секунд між хоррор-подіями."); HorrorFlickerIntervalMax = ((BasePlugin)this).Config.Bind("08 - Horror Flicker (long dark pause)", "IntervalMaxSeconds", 600f, "EN: Maximum seconds between horror events.\nUA: Максимум секунд між хоррор-подіями."); BrownoutEnabled = ((BasePlugin)this).Config.Bind("08a - Brownout (slow dim-hold-recover)", "Enabled", true, "EN: The light slowly dims to about half brightness, holds, then\n recovers. No blinks — feels like the battery is sagging.\nUA: Світло плавно тьмяніє приблизно до половини, тримається,\n потім відновлюється. Без миготінь — наче батарея просіла."); BrownoutIntervalMin = ((BasePlugin)this).Config.Bind("08a - Brownout (slow dim-hold-recover)", "IntervalMinSeconds", 600f, "EN: Minimum seconds between battery sags.\nUA: Мінімум секунд між просіданнями."); BrownoutIntervalMax = ((BasePlugin)this).Config.Bind("08a - Brownout (slow dim-hold-recover)", "IntervalMaxSeconds", 2400f, "EN: Maximum seconds between battery sags.\nUA: Максимум секунд між просіданнями."); StutterEnabled = ((BasePlugin)this).Config.Bind("08b - Stutter (high-frequency flutter)", "Enabled", true, "EN: A short bout of nervous flutter — like a loose, vibrating\n contact.\nUA: Короткий нервовий трепет світла — наче торохтить контакт."); StutterIntervalMin = ((BasePlugin)this).Config.Bind("08b - Stutter (high-frequency flutter)", "IntervalMinSeconds", 900f, "EN: Minimum seconds between flutter bursts.\nUA: Мінімум секунд між нервовими спалахами."); StutterIntervalMax = ((BasePlugin)this).Config.Bind("08b - Stutter (high-frequency flutter)", "IntervalMaxSeconds", 2700f, "EN: Maximum seconds between flutter bursts.\nUA: Максимум секунд між нервовими спалахами."); RestrikeEnabled = ((BasePlugin)this).Config.Bind("08c - Restrike (LED bulb restart)", "Enabled", true, "EN: The light cuts out, gives a weak strike, cuts again, then\n comes back — like an LED bulb restarting after a power hiccup.\n The rarest event.\nUA: Світло гасне, дає слабкий проблиск, знову гасне і повертається\n — наче LED-лампа перезапускається після стрибка живлення.\n Найрідкісніша подія."); RestrikeIntervalMin = ((BasePlugin)this).Config.Bind("08c - Restrike (LED bulb restart)", "IntervalMinSeconds", 1200f, "EN: Minimum seconds between LED restarts.\nUA: Мінімум секунд між перезапусками лампи."); RestrikeIntervalMax = ((BasePlugin)this).Config.Bind("08c - Restrike (LED bulb restart)", "IntervalMaxSeconds", 3600f, "EN: Maximum seconds between LED restarts.\nUA: Максимум секунд між перезапусками лампи."); P_Short_CoreAngle = Cfg("09 - Preset Short Range — CASUAL", "Core_Angle", 50f, "Pistols/revolvers — width of the bright inner beam (°). / Ширина яскравого центру для пістолетів і револьверів (°)."); P_Short_CoreIntensity = Cfg("09 - Preset Short Range — CASUAL", "Core_Intensity", 0.5f, "Pistols/revolvers — brightness of the inner beam. / Яскравість центру для пістолетів і револьверів."); P_Short_CoreRange = Cfg("09 - Preset Short Range — CASUAL", "Core_Range", 18f, "Pistols/revolvers — how far the inner beam reaches (m). / Як далеко б'є центр для пістолетів і револьверів (м)."); P_Short_MidAngle = Cfg("09 - Preset Short Range — CASUAL", "Mid_Angle", 80f, "Pistols/revolvers — width of the middle glow (°). / Ширина середнього світла для пістолетів і револьверів (°)."); P_Short_MidIntensity = Cfg("09 - Preset Short Range — CASUAL", "Mid_Intensity", 0.4f, "Pistols/revolvers — brightness of the middle glow. / Яскравість середнього світла для пістолетів і револьверів."); P_Short_MidRange = Cfg("09 - Preset Short Range — CASUAL", "Mid_Range", 12.4f, "Pistols/revolvers — how far the middle glow reaches (m). / Як далеко сягає середнє світло для пістолетів і револьверів (м)."); P_Short_FallAngle = Cfg("09 - Preset Short Range — CASUAL", "Fall_Angle", 169f, "Pistols/revolvers — width of the soft outer glow (°). / Ширина м'якого зовнішнього світла для пістолетів і револьверів (°)."); P_Short_FallIntensity = Cfg("09 - Preset Short Range — CASUAL", "Fall_Intensity", 0.45f, "Pistols/revolvers — brightness of the soft outer glow. / Яскравість м'якого зовнішнього світла для пістолетів і револьверів."); P_Short_FallRange = Cfg("09 - Preset Short Range — CASUAL", "Fall_Range", 5.6f, "Pistols/revolvers — how far the soft outer glow reaches (m). / Як далеко сягає м'яке зовнішнє світло для пістолетів і револьверів (м)."); P_Med1_CoreAngle = Cfg("10 - Preset Medium Range 1 — CASUAL", "Core_Angle", 50f, "SMGs/ARs — width of the bright inner beam (°). / Ширина яскравого центру для SMG і автоматів (°)."); P_Med1_CoreIntensity = Cfg("10 - Preset Medium Range 1 — CASUAL", "Core_Intensity", 0.5f, "SMGs/ARs — brightness of the inner beam. / Яскравість центру для SMG і автоматів."); P_Med1_CoreRange = Cfg("10 - Preset Medium Range 1 — CASUAL", "Core_Range", 21f, "SMGs/ARs — how far the inner beam reaches (m). / Як далеко б'є центр для SMG і автоматів (м)."); P_Med1_MidAngle = Cfg("10 - Preset Medium Range 1 — CASUAL", "Mid_Angle", 80f, "SMGs/ARs — width of the middle glow (°). / Ширина середнього світла для SMG і автоматів (°)."); P_Med1_MidIntensity = Cfg("10 - Preset Medium Range 1 — CASUAL", "Mid_Intensity", 0.4f, "SMGs/ARs — brightness of the middle glow. / Яскравість середнього світла для SMG і автоматів."); P_Med1_MidRange = Cfg("10 - Preset Medium Range 1 — CASUAL", "Mid_Range", 14.3f, "SMGs/ARs — how far the middle glow reaches (m). / Як далеко сягає середнє світло для SMG і автоматів (м)."); P_Med1_FallAngle = Cfg("10 - Preset Medium Range 1 — CASUAL", "Fall_Angle", 169f, "SMGs/ARs — width of the soft outer glow (°). / Ширина м'якого зовнішнього світла для SMG і автоматів (°)."); P_Med1_FallIntensity = Cfg("10 - Preset Medium Range 1 — CASUAL", "Fall_Intensity", 0.45f, "SMGs/ARs — brightness of the soft outer glow. / Яскравість м'якого зовнішнього світла для SMG і автоматів."); P_Med1_FallRange = Cfg("10 - Preset Medium Range 1 — CASUAL", "Fall_Range", 6.7f, "SMGs/ARs — how far the soft outer glow reaches (m). / Як далеко сягає м'яке зовнішнє світло для SMG і автоматів (м)."); P_Med2_CoreAngle = Cfg("11 - Preset Medium Range 2 — CASUAL", "Core_Angle", 40f, "DMRs/precision guns — width of the bright inner beam (°). / Ширина яскравого центру для DMR і точної зброї (°)."); P_Med2_CoreIntensity = Cfg("11 - Preset Medium Range 2 — CASUAL", "Core_Intensity", 0.5f, "DMRs/precision guns — brightness of the inner beam. / Яскравість центру для DMR і точної зброї."); P_Med2_CoreRange = Cfg("11 - Preset Medium Range 2 — CASUAL", "Core_Range", 21f, "DMRs/precision guns — how far the inner beam reaches (m). / Як далеко б'є центр для DMR і точної зброї (м)."); P_Med2_MidAngle = Cfg("11 - Preset Medium Range 2 — CASUAL", "Mid_Angle", 75f, "DMRs/precision guns — width of the middle glow (°). / Ширина середнього світла для DMR і точної зброї (°)."); P_Med2_MidIntensity = Cfg("11 - Preset Medium Range 2 — CASUAL", "Mid_Intensity", 0.4f, "DMRs/precision guns — brightness of the middle glow. / Яскравість середнього світла для DMR і точної зброї."); P_Med2_MidRange = Cfg("11 - Preset Medium Range 2 — CASUAL", "Mid_Range", 14.3f, "DMRs/precision guns — how far the middle glow reaches (m). / Як далеко сягає середнє світло для DMR і точної зброї (м)."); P_Med2_FallAngle = Cfg("11 - Preset Medium Range 2 — CASUAL", "Fall_Angle", 169f, "DMRs/precision guns — width of the soft outer glow (°). / Ширина м'якого зовнішнього світла для DMR і точної зброї (°)."); P_Med2_FallIntensity = Cfg("11 - Preset Medium Range 2 — CASUAL", "Fall_Intensity", 0.45f, "DMRs/precision guns — brightness of the soft outer glow. / Яскравість м'якого зовнішнього світла для DMR і точної зброї."); P_Med2_FallRange = Cfg("11 - Preset Medium Range 2 — CASUAL", "Fall_Range", 6.7f, "DMRs/precision guns — how far the soft outer glow reaches (m). / Як далеко сягає м'яке зовнішнє світло для DMR і точної зброї (м)."); P_Wide_CoreAngle = Cfg("12 - Preset Wide Range — CASUAL", "Core_Angle", 50f, "Shotguns — width of the bright inner beam (°). / Ширина яскравого центру для дробовиків (°)."); P_Wide_CoreIntensity = Cfg("12 - Preset Wide Range — CASUAL", "Core_Intensity", 0.5f, "Shotguns — brightness of the inner beam. / Яскравість центру для дробовиків."); P_Wide_CoreRange = Cfg("12 - Preset Wide Range — CASUAL", "Core_Range", 24f, "Shotguns — how far the inner beam reaches (m). / Як далеко б'є центр для дробовиків (м)."); P_Wide_MidAngle = Cfg("12 - Preset Wide Range — CASUAL", "Mid_Angle", 90f, "Shotguns — width of the middle glow (°). / Ширина середнього світла для дробовиків (°)."); P_Wide_MidIntensity = Cfg("12 - Preset Wide Range — CASUAL", "Mid_Intensity", 0.47f, "Shotguns — brightness of the middle glow. / Яскравість середнього світла для дробовиків."); P_Wide_MidRange = Cfg("12 - Preset Wide Range — CASUAL", "Mid_Range", 16.1f, "Shotguns — how far the middle glow reaches (m). / Як далеко сягає середнє світло для дробовиків (м)."); P_Wide_FallAngle = Cfg("12 - Preset Wide Range — CASUAL", "Fall_Angle", 169f, "Shotguns — width of the soft outer glow (°). / Ширина м'якого зовнішнього світла для дробовиків (°)."); P_Wide_FallIntensity = Cfg("12 - Preset Wide Range — CASUAL", "Fall_Intensity", 0.45f, "Shotguns — brightness of the soft outer glow. / Яскравість м'якого зовнішнього світла для дробовиків."); P_Wide_FallRange = Cfg("12 - Preset Wide Range — CASUAL", "Fall_Range", 7.9f, "Shotguns — how far the soft outer glow reaches (m). / Як далеко сягає м'яке зовнішнє світло для дробовиків (м)."); P_Ext_CoreAngle = Cfg("13 - Preset Extended Range — CASUAL", "Core_Angle", 50f, "Snipers/long-range guns — width of the bright inner beam (°). / Ширина яскравого центру для снайперок і дальнобоїв (°)."); P_Ext_CoreIntensity = Cfg("13 - Preset Extended Range — CASUAL", "Core_Intensity", 0.5f, "Snipers/long-range guns — brightness of the inner beam. / Яскравість центру для снайперок і дальнобоїв."); P_Ext_CoreRange = Cfg("13 - Preset Extended Range — CASUAL", "Core_Range", 24f, "Snipers/long-range guns — how far the inner beam reaches (m). / Як далеко б'є центр для снайперок і дальнобоїв (м)."); P_Ext_MidAngle = Cfg("13 - Preset Extended Range — CASUAL", "Mid_Angle", 80f, "Snipers/long-range guns — width of the middle glow (°). / Ширина середнього світла для снайперок і дальнобоїв (°)."); P_Ext_MidIntensity = Cfg("13 - Preset Extended Range — CASUAL", "Mid_Intensity", 0.4f, "Snipers/long-range guns — brightness of the middle glow. / Яскравість середнього світла для снайперок і дальнобоїв."); P_Ext_MidRange = Cfg("13 - Preset Extended Range — CASUAL", "Mid_Range", 16.1f, "Snipers/long-range guns — how far the middle glow reaches (m). / Як далеко сягає середнє світло для снайперок і дальнобоїв (м)."); P_Ext_FallAngle = Cfg("13 - Preset Extended Range — CASUAL", "Fall_Angle", 169f, "Snipers/long-range guns — width of the soft outer glow (°). / Ширина м'якого зовнішнього світла для снайперок і дальнобоїв (°)."); P_Ext_FallIntensity = Cfg("13 - Preset Extended Range — CASUAL", "Fall_Intensity", 0.45f, "Snipers/long-range guns — brightness of the soft outer glow. / Яскравість м'якого зовнішнього світла для снайперок і дальнобоїв."); P_Ext_FallRange = Cfg("13 - Preset Extended Range — CASUAL", "Fall_Range", 7.9f, "Snipers/long-range guns — how far the soft outer glow reaches (m). / Як далеко сягає м'яке зовнішнє світло для снайперок і дальнобоїв (м)."); Pick_Angle = ((BasePlugin)this).Config.Bind("14 - Pickable Flashlight — CASUAL", "Angle", 50f, "EN: The big pick-up flashlight — how wide its main beam is (°).\nUA: Підбираний ліхтарик — наскільки широкий основний промінь (°)."); Pick_Intensity = ((BasePlugin)this).Config.Bind("14 - Pickable Flashlight — CASUAL", "Intensity", 0.7f, "EN: The big pick-up flashlight — how bright its main beam is.\nUA: Підбираний ліхтарик — наскільки яскравий основний промінь."); Pick_Range = ((BasePlugin)this).Config.Bind("14 - Pickable Flashlight — CASUAL", "Range", 40f, "EN: The big pick-up flashlight — how far its main beam reaches (m).\nUA: Підбираний ліхтарик — як далеко б'є основний промінь (м)."); Pick_RareWeight = ((BasePlugin)this).Config.Bind("15 - Pickable Flashlight Rarity", "RareWeight", 0.001f, "EN: Spawn weight applied to every loot-table entry that drops the\n consumable flashlight. Lower = rarer, higher = more common.\n Reference scale (rolls are random against the table totals):\n 0.001 (DEFAULT) — near-zero natural rolls. The guarantee\n floor below force-promotes one mid-level\n so the player still gets ~1 per run.\n Feels like a special upgrade find.\n 0.01 — still very rare; ~10× more likely than\n default but most levels still rely on\n the guarantee.\n 0.1 — noticeably uncommon; 0-2 natural rolls\n per level on top of the guarantee.\n 1.0 — normal item rarity (same weight as a\n regular pickup); several per level,\n MaxPerLevel cap kicks in regularly.\n 10.0+ — flooded; almost every container.\n The MaxPerLevel cap (section below) clamps over-quota rolls\n by replacing them with a category-matching item, so even at\n very high weights you won't see more flashlights than that\n cap allows.\nUA: Вага появи (spawn weight) для consumable-ліхтарика у лут-\n таблицях. Менше = рідше, більше = частіше.\n Орієнтовна шкала (рандом проти суми ваг у таблиці):\n 0.001 (DEFAULT) — майже ніколи не випадає природно.\n Нижній «гарантійний поріг» примусово\n ставить ~1 ліхтарик на рівень, тож\n без нього теж не залишишся. Відчуття:\n рідкісний апгрейд-предмет.\n 0.01 — все ще дуже рідко; у ~10× ймовірніше\n за default, але рівні все одно тримають\n на гарантії.\n 0.1 — помітно нечасто; 0-2 природних випадки\n на рівень понад гарантію.\n 1.0 — звичайна рідкість предмета (як інший\n ресурс); кілька на рівень, ліміт\n MaxPerLevel спрацьовує регулярно.\n 10.0+ — буквально в кожному ящику.\n Ліміт MaxPerLevel (нижче) обріже зайві випадання, заміняючи\n їх на інший предмет тієї ж категорії — тож навіть при дуже\n високій вазі ти не побачиш більше ліхтариків ніж ліміт."); Pick_MaxPerLevel = ((BasePlugin)this).Config.Bind("15 - Pickable Flashlight Rarity", "MaxPerLevel", 2, "EN: Hard cap on how many consumable flashlights can appear in a\n single level. Over-quota rolls are replaced with a different\n item from the same loot category (so containers never end up\n empty). 2 (DEFAULT) keeps the upgrade feeling scarce; raise\n to 4-6 for a flashlight-rich run, set to 1 for hardcore.\nUA: Жорсткий ліміт скільки consumable-ліхтариків взагалі може\n зʼявитись на рівні. Понад-лімітні випадання заміняються на\n інший предмет тієї ж категорії (контейнери не лишаються\n порожніми). 2 (DEFAULT) тримає апгрейд дефіцитним; постав\n 4-6 для забагів-ліхтариків, 1 для хардкору."); Pick_GuaranteeFloor = ((BasePlugin)this).Config.Bind("15 - Pickable Flashlight Rarity", "GuaranteeAfterNPickups", 300, "EN: If RareWeight is so low that natural rolls don't produce a\n flashlight, after this many non-flashlight pickups in a level\n the NEXT pickup is force-converted into one. Ensures the\n player gets at least one flashlight per run even with the\n default RareWeight=0.001. Set to a very high number (e.g.\n 9999) to disable the guarantee — you'll then rely purely on\n RareWeight.\nUA: Якщо RareWeight настільки малий, що природні випадання не\n дають ліхтарика, то після стількох не-ліхтариків на рівні\n НАСТУПНИЙ пікап буде примусово замінений на ліхтарик. Це\n гарантує, що гравець отримає хоча б один за пробіг навіть\n при default RareWeight=0.001. Постав велике число (наприклад\n 9999) щоб вимкнути гарантію — тоді все залежить лише від\n RareWeight."); DustEnabled = ((BasePlugin)this).Config.Bind("16 - Dust Effect", "Dust_Enabled", true, "EN: Tiny dust motes drifting in the flashlight beam. They're\n only visible when caught by the light, like real dust in a\n torch beam. Turn off if your PC struggles or you just don't\n like the look.\nUA: Дрібні пилинки, які плавають у промені ліхтарика. Вони\n видимі тільки тоді, коли світло на них падає — як справжній\n пил у промені. Вимкни, якщо комп слабкий або просто не\n подобається ефект."); DustOpacity = ((BasePlugin)this).Config.Bind("16 - Dust Effect", "Dust_Opacity", 1f, "EN: Opacity multiplier for all dust mote types (soft, star, medium).\n 1.0 = default tuned opacity. 0.5 = half as visible. 2.0 = twice\n as visible. Values below 0 are clamped to 0 (invisible but pool\n still runs — use Dust_Enabled = false to save CPU/GPU instead).\nUA: Множник непрозорості для всіх типів пилинок (soft, star, medium).\n 1.0 = забалансована базова прозорість. 0.5 = вдвічі слабше. 2.0 = вдвічі\n сильніше. Значення нижче 0 затискається до 0 (невидимі, але пул\n все одно працює — для економії ресурсів вимкни Dust_Enabled)."); I3 = ((BasePlugin)this).Config.Bind("99 - Legacy", "I3_unused", 0f, "EN: Unused. / UA: Не використовується."); I4 = ((BasePlugin)this).Config.Bind("99 - Legacy", "I4_unused", 0f, "EN: Unused. / UA: Не використовується."); I5 = ((BasePlugin)this).Config.Bind("99 - Legacy", "I5_unused", 0f, "EN: Unused. / UA: Не використовується."); R3 = ((BasePlugin)this).Config.Bind("99 - Legacy", "R3_unused", 0f, "EN: Unused. / UA: Не використовується."); R4 = ((BasePlugin)this).Config.Bind("99 - Legacy", "R4_unused", 0f, "EN: Unused. / UA: Не використовується."); R5 = ((BasePlugin)this).Config.Bind("99 - Legacy", "R5_unused", 0f, "EN: Unused. / UA: Не використовується."); Step3 = ((BasePlugin)this).Config.Bind("99 - Legacy", "Step3_unused", 0f, "EN: Unused. / UA: Не використовується."); Step4 = ((BasePlugin)this).Config.Bind("99 - Legacy", "Step4_unused", 0f, "EN: Unused. / UA: Не використовується."); Step5 = ((BasePlugin)this).Config.Bind("99 - Legacy", "Step5_unused", 0f, "EN: Unused. / UA: Не використовується."); } private ConfigEntry Cfg(string section, string key, float defaultValue, string desc) { return ((BasePlugin)this).Config.Bind(section, key, defaultValue, "EN/UA: " + desc); } internal static void ApplyPreset(FlashLightMode m) { //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) ModeAdjustments modeAdjustments = ModePresets.For(m); RangedPresets.BuildFromConfig(modeAdjustments.Ranged, m == FlashLightMode.MINIMAL); HelmetAngle = MeleeAngle.Value; HelmetIntensity = MeleeIntensity.Value; HelmetRange = MeleeRange.Value - 6f; HelmetFallRange = HelmetRange + 2f + 6f + 0f; PickAngle = Mathf.Min(Pick_Angle.Value + modeAdjustments.PickAngleOffset, 89f); PickIntensity = Mathf.Max(0f, Pick_Intensity.Value + modeAdjustments.PickIntensityOffset); PickRange = Pick_Range.Value + modeAdjustments.PickRangeOffset; PickColor = (Color)(((??)modeAdjustments.PickColorOverride) ?? new Color(1f, 0.84f, 0.6f)); } } internal static class FlashlightEnemyDetection { private static readonly Dictionary _agents = new Dictionary(); internal static Action? OnEnemyInBeam; internal static float LastBeamRange = 24f; internal static float LastBeamIntensity = 0.75f; internal static bool LastBeamIsHeadlight = false; private static bool _tickEverCalled = false; private static bool _enemyLayerLogged = false; private static float _lastDiagAt = -999f; private static float _lastRegistryRefreshAt = -999f; internal static void RegisterAgent(EnemyAgent agent) { if ((Object)(object)agent == (Object)null) { return; } try { int instanceID = ((Object)agent).GetInstanceID(); _agents[instanceID] = agent; } catch { } } internal static void UnregisterAgent(EnemyAgent agent) { if ((Object)(object)agent == (Object)null) { return; } try { _agents.Remove(((Object)agent).GetInstanceID()); } catch { } } private static void RefreshRegistryFromScene(float now, bool force) { if (!force && now - _lastRegistryRefreshAt < 10f) { return; } _lastRegistryRefreshAt = now; try { Il2CppArrayBase val = Object.FindObjectsOfType(); if (val == null || val.Length == 0) { return; } int count = _agents.Count; int num = 0; foreach (EnemyAgent item in val) { if (!((Object)(object)item == (Object)null)) { int instanceID; try { instanceID = ((Object)item).GetInstanceID(); } catch { continue; } if (!_agents.ContainsKey(instanceID)) { num++; } _agents[instanceID] = item; } } if (force || num > 0) { Plugin.Logger.LogInfo((object)("[FO] Registry refresh: before=" + count + " found=" + val.Length + " added=" + num + " total=" + _agents.Count)); } } catch (Exception ex) { Plugin.Logger.LogWarning((object)("[FO] Registry refresh threw: " + ex.Message)); } } internal static void LogEnemyLayer(EnemyAgent agent) { if (_enemyLayerLogged) { return; } _enemyLayerLogged = true; try { int layer = ((Component)agent).gameObject.layer; Plugin.Logger.LogInfo((object)("[FO] EnemyAgent root layer: " + layer + " (\"" + LayerMask.LayerToName(layer) + "\") agent=" + ((Object)((Component)agent).gameObject).name)); Il2CppArrayBase componentsInChildren = ((Component)agent).GetComponentsInChildren(true); if (componentsInChildren == null) { return; } HashSet hashSet = new HashSet(); StringBuilder stringBuilder = new StringBuilder(); foreach (Collider item in componentsInChildren) { if (!((Object)(object)item == (Object)null)) { int layer2 = ((Component)item).gameObject.layer; if (hashSet.Add(layer2)) { stringBuilder.Append(layer2).Append('(').Append(LayerMask.LayerToName(layer2)) .Append(") "); } } } Plugin.Logger.LogInfo((object)("[FO] EnemyAgent child collider layers: " + stringBuilder.ToString().TrimEnd())); } catch (Exception ex) { Plugin.Logger.LogWarning((object)("[FO] EnemyLayer probe threw: " + ex.Message)); } } internal static void Tick(Transform coneRoot, Light coneLight, float? detectionRangeOverride = null, float? spotAngleOverride = null, float intensityScale = 1f, bool isHeadlight = false) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Invalid comparison between Unknown and I4 //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) float unscaledTime = Time.unscaledTime; float num = spotAngleOverride ?? coneLight.spotAngle; float num2 = num * 0.5f; float num3 = detectionRangeOverride ?? coneLight.range; Vector3 position = coneRoot.position; Vector3 forward = coneRoot.forward; LastBeamRange = num3; LastBeamIntensity = coneLight.intensity * Mathf.Max(0f, intensityScale); LastBeamIsHeadlight = isHeadlight; RefreshRegistryFromScene(unscaledTime, _agents.Count == 0); if (!_tickEverCalled) { _tickEverCalled = true; Plugin.Logger.LogInfo((object)("[FO] Tick first call: spotAngle=" + num.ToString("F1") + " range=" + num3.ToString("F1") + " registry=" + _agents.Count)); } if (_agents.Count == 0 && unscaledTime - _lastDiagAt > 10f) { _lastDiagAt = unscaledTime; Plugin.Logger.LogInfo((object)"[FO] Tick diag: registry empty — no EnemyAgent instances found yet."); return; } int num4 = 0; int num5 = 0; foreach (KeyValuePair agent in _agents) { EnemyAgent value = agent.Value; if ((Object)(object)value == (Object)null) { continue; } num4++; try { if ((Object)(object)value.AI == (Object)null || (int)((AgentAI)value.AI).Mode == 1) { continue; } goto IL_0199; } catch { } continue; IL_0199: Vector3 val; float magnitude; try { val = ((Component)value).transform.position - position; magnitude = ((Vector3)(ref val)).magnitude; } catch { continue; } if (magnitude > num3 || magnitude < 0.1f) { continue; } float num6 = Vector3.Angle(forward, val); if (num6 > num2) { continue; } try { if (Physics.Raycast(position, val / magnitude, magnitude, 257, (QueryTriggerInteraction)1)) { continue; } } catch { continue; } num5++; try { OnEnemyInBeam?.Invoke(value, magnitude, num6); } catch { } } if (unscaledTime - _lastDiagAt > 5f && num4 > 0) { _lastDiagAt = unscaledTime; Plugin.Logger.LogInfo((object)("[FO] Tick diag: registry=" + _agents.Count + " checked=" + num4 + " inBeam=" + num5 + " range=" + num3.ToString("F1"))); } } internal static void Reset() { _agents.Clear(); _tickEverCalled = false; _enemyLayerLogged = false; _lastDiagAt = -999f; _lastRegistryRefreshAt = -999f; } } internal static class RangedPresets { internal struct Preset { public string Name; public Color Tint; public bool HasMid; public float CoreAngle; public float CoreIntensity; public float CoreRange; public float MidAngle; public float MidIntensity; public float MidRange; public float FallAngle; public float FallIntensity; public float FallRange; } internal static readonly Color CoolWhite = new Color(0.85f, 0.93f, 1f); internal static readonly Color WarmYellow = new Color(1f, 0.93f, 0.75f); internal static Preset ShortRange; internal static Preset MediumRange1; internal static Preset MediumRange2; internal static Preset WideRange; internal static Preset ExtendedRange; internal static Preset Default; internal static readonly Dictionary ByPID = new Dictionary(); private static readonly Dictionary _ownerPresetCache = new Dictionary(); private static readonly HashSet _loggedProbes = new HashSet(); internal static void BuildFromConfig(PresetOffset offset, bool minimalMode = false) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_0229: 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_0430: Unknown result type (might be due to invalid IL or missing references) //IL_0435: Unknown result type (might be due to invalid IL or missing references) bool hasMid = true; Preset shortRange = default(Preset); shortRange.Name = "Short range (Yellow, Wide)"; shortRange.Tint = WarmYellow; shortRange.HasMid = hasMid; shortRange.CoreAngle = Plugin.P_Short_CoreAngle.Value + offset.CoreAngle; shortRange.CoreIntensity = Plugin.P_Short_CoreIntensity.Value + offset.CoreIntensity; shortRange.CoreRange = Plugin.P_Short_CoreRange.Value + offset.CoreRange; shortRange.MidAngle = Plugin.P_Short_MidAngle.Value + offset.MidAngle; shortRange.MidIntensity = Plugin.P_Short_MidIntensity.Value + offset.MidIntensity; shortRange.MidRange = Plugin.P_Short_MidRange.Value + offset.MidRange; shortRange.FallAngle = Plugin.P_Short_FallAngle.Value + offset.FallAngle; shortRange.FallIntensity = Plugin.P_Short_FallIntensity.Value + offset.FallIntensity; shortRange.FallRange = Plugin.P_Short_FallRange.Value + offset.FallRange; ShortRange = shortRange; shortRange = default(Preset); shortRange.Name = "Medium range #1 (White, Medium)"; shortRange.Tint = CoolWhite; shortRange.HasMid = hasMid; shortRange.CoreAngle = Plugin.P_Med1_CoreAngle.Value + offset.CoreAngle; shortRange.CoreIntensity = Plugin.P_Med1_CoreIntensity.Value + offset.CoreIntensity; shortRange.CoreRange = Plugin.P_Med1_CoreRange.Value + offset.CoreRange; shortRange.MidAngle = Plugin.P_Med1_MidAngle.Value + offset.MidAngle; shortRange.MidIntensity = Plugin.P_Med1_MidIntensity.Value + offset.MidIntensity; shortRange.MidRange = Plugin.P_Med1_MidRange.Value + offset.MidRange; shortRange.FallAngle = Plugin.P_Med1_FallAngle.Value + offset.FallAngle; shortRange.FallIntensity = Plugin.P_Med1_FallIntensity.Value + offset.FallIntensity; shortRange.FallRange = Plugin.P_Med1_FallRange.Value + offset.FallRange; MediumRange1 = shortRange; shortRange = default(Preset); shortRange.Name = "Medium range #2 (White, Tight)"; shortRange.Tint = CoolWhite; shortRange.HasMid = hasMid; shortRange.CoreAngle = Plugin.P_Med2_CoreAngle.Value + offset.CoreAngle; shortRange.CoreIntensity = Plugin.P_Med2_CoreIntensity.Value + offset.CoreIntensity; shortRange.CoreRange = Plugin.P_Med2_CoreRange.Value + offset.CoreRange; shortRange.MidAngle = Plugin.P_Med2_MidAngle.Value + offset.MidAngle; shortRange.MidIntensity = Plugin.P_Med2_MidIntensity.Value + offset.MidIntensity; shortRange.MidRange = Plugin.P_Med2_MidRange.Value + offset.MidRange; shortRange.FallAngle = Plugin.P_Med2_FallAngle.Value + offset.FallAngle; shortRange.FallIntensity = Plugin.P_Med2_FallIntensity.Value + offset.FallIntensity; shortRange.FallRange = Plugin.P_Med2_FallRange.Value + offset.FallRange; MediumRange2 = shortRange; shortRange = default(Preset); shortRange.Name = "Wide range (White, Wide)"; shortRange.Tint = CoolWhite; shortRange.HasMid = hasMid; shortRange.CoreAngle = Plugin.P_Wide_CoreAngle.Value + offset.CoreAngle; shortRange.CoreIntensity = Plugin.P_Wide_CoreIntensity.Value + offset.CoreIntensity; shortRange.CoreRange = Plugin.P_Wide_CoreRange.Value + offset.CoreRange; shortRange.MidAngle = Plugin.P_Wide_MidAngle.Value + offset.MidAngle; shortRange.MidIntensity = Plugin.P_Wide_MidIntensity.Value + offset.MidIntensity; shortRange.MidRange = Plugin.P_Wide_MidRange.Value + offset.MidRange; shortRange.FallAngle = Plugin.P_Wide_FallAngle.Value + offset.FallAngle; shortRange.FallIntensity = Plugin.P_Wide_FallIntensity.Value + offset.FallIntensity; shortRange.FallRange = Plugin.P_Wide_FallRange.Value + offset.FallRange; WideRange = shortRange; shortRange = default(Preset); shortRange.Name = "Extended range (White, Tight) — base"; shortRange.Tint = CoolWhite; shortRange.HasMid = hasMid; shortRange.CoreAngle = Plugin.P_Ext_CoreAngle.Value + offset.CoreAngle; shortRange.CoreIntensity = Plugin.P_Ext_CoreIntensity.Value + offset.CoreIntensity; shortRange.CoreRange = Plugin.P_Ext_CoreRange.Value + offset.CoreRange; shortRange.MidAngle = Plugin.P_Ext_MidAngle.Value + offset.MidAngle; shortRange.MidIntensity = Plugin.P_Ext_MidIntensity.Value + offset.MidIntensity; shortRange.MidRange = Plugin.P_Ext_MidRange.Value + offset.MidRange; shortRange.FallAngle = Plugin.P_Ext_FallAngle.Value + offset.FallAngle; shortRange.FallIntensity = Plugin.P_Ext_FallIntensity.Value + offset.FallIntensity; shortRange.FallRange = Plugin.P_Ext_FallRange.Value + offset.FallRange; ExtendedRange = shortRange; if (minimalMode) { CollapseMidToCore(ref ShortRange); CollapseMidToCore(ref MediumRange1); CollapseMidToCore(ref MediumRange2); CollapseMidToCore(ref WideRange); CollapseMidToCore(ref ExtendedRange); } ClampFallAngle(ref ShortRange, 165f); ClampFallAngle(ref MediumRange1, 165f); ClampFallAngle(ref MediumRange2, 165f); ClampFallAngle(ref WideRange, 165f); ClampFallAngle(ref ExtendedRange, 165f); Default = ExtendedRange; } private static void ClampFallAngle(ref Preset p, float deg) { if (p.FallAngle > deg) { p.FallAngle = deg; } } private static void CollapseMidToCore(ref Preset p) { p.MidAngle = p.CoreAngle; p.MidRange = p.CoreRange; } internal static Preset Classify(string blockName, float origAngle, float origRange) { string obj = blockName ?? ""; bool flag = obj.IndexOf("wide", StringComparison.OrdinalIgnoreCase) >= 0; bool flag2 = obj.IndexOf("tight", StringComparison.OrdinalIgnoreCase) >= 0; bool flag3 = obj.IndexOf("medium", StringComparison.OrdinalIgnoreCase) >= 0; bool flag4 = obj.IndexOf("short", StringComparison.OrdinalIgnoreCase) >= 0; bool flag5 = obj.IndexOf("extend", StringComparison.OrdinalIgnoreCase) >= 0; if (flag4) { return ShortRange; } if (flag3 && flag2) { return MediumRange2; } if (flag3) { return MediumRange1; } if (flag && flag5) { return WideRange; } if (flag) { return WideRange; } if (flag5) { return ExtendedRange; } if (flag2) { return ExtendedRange; } bool flag6 = origAngle <= 40f; bool flag7 = origAngle >= 55f; bool flag8 = origRange <= 12f; bool flag9 = origRange >= 17f; if (flag7 && flag8) { return ShortRange; } if (flag6 && flag9) { return ExtendedRange; } if (flag7 && flag9) { return WideRange; } if (flag7) { return WideRange; } if (flag6) { return MediumRange2; } return MediumRange1; } internal static void ClearOwnerCaches() { _ownerPresetCache.Clear(); } internal static void ClearOwnerCacheEntry(ItemEquippable? owner) { if (!((Object)(object)owner == (Object)null)) { int instanceID; try { instanceID = ((Object)owner).GetInstanceID(); } catch { return; } _ownerPresetCache.Remove(instanceID); } } internal static Preset? ResolveByOwner(ItemEquippable? owner) { if ((Object)(object)owner == (Object)null) { return null; } int instanceID; try { instanceID = ((Object)owner).GetInstanceID(); } catch { return null; } if (_ownerPresetCache.TryGetValue(instanceID, out var value)) { return value; } StringBuilder stringBuilder = new StringBuilder(256); try { GameObject gameObject = ((Component)owner).gameObject; if ((Object)(object)gameObject != (Object)null) { stringBuilder.Append(" goName=").Append(((Object)gameObject).name); } } catch { } try { Transform val = ((Component)owner).transform; int num = 8; stringBuilder.Append(" path="); bool flag = true; while ((Object)(object)val != (Object)null && num-- > 0) { if (!flag) { stringBuilder.Append('/'); } stringBuilder.Append(((Object)val).name ?? "?"); flag = false; val = val.parent; } } catch { } try { Transform transform = ((Component)owner).transform; if ((Object)(object)transform != (Object)null) { int childCount = transform.childCount; stringBuilder.Append(" children=["); for (int i = 0; i < childCount && i < 12; i++) { Transform child = transform.GetChild(i); if (i > 0) { stringBuilder.Append(','); } stringBuilder.Append(((Object)child).name ?? "?"); } stringBuilder.Append(']'); } } catch { } try { Transform transform2 = ((Component)owner).transform; if ((Object)(object)transform2 != (Object)null) { StringBuilder stringBuilder2 = new StringBuilder(); CollectDescendantNamesContaining(transform2, "Flashlight", stringBuilder2, 8, 6); if (stringBuilder2.Length > 0) { stringBuilder.Append(" flashlightGOs=[").Append(stringBuilder2).Append(']'); } stringBuilder2.Clear(); CollectDescendantNamesContaining(transform2, "WPN_", stringBuilder2, 8, 6); if (stringBuilder2.Length > 0) { stringBuilder.Append(" wpnGOs=[").Append(stringBuilder2).Append(']'); } } } catch { } string text = stringBuilder.ToString(); Preset? preset = MatchKeywords(text); _ownerPresetCache[instanceID] = preset; try { string text2 = (preset.HasValue ? (preset.Value.Name ?? "Unnamed") : "null"); string text3 = text + " => " + text2; if (_loggedProbes.Add(text3)) { Plugin.Logger.LogInfo((object)("[RF] OwnerNameProbe " + text3)); } } catch { } return preset; } private static void CollectDescendantNamesContaining(Transform t, string substring, StringBuilder sink, int maxDepth, int maxResults) { if ((Object)(object)t == (Object)null || maxDepth < 0) { return; } try { int childCount = t.childCount; for (int i = 0; i < childCount; i++) { Transform child = t.GetChild(i); string text = ((Object)child).name ?? ""; if (text.IndexOf(substring, StringComparison.OrdinalIgnoreCase) >= 0) { if (sink.Length > 0) { sink.Append(','); } sink.Append(text); if (sink.Length >= maxResults * 32) { break; } } if (maxDepth > 0) { CollectDescendantNamesContaining(child, substring, sink, maxDepth - 1, maxResults); } } } catch { } } private static Preset? MatchKeywords(string s) { string s2 = s; if (C("Flashlight_A")) { return ShortRange; } if (C("Flashlight_B")) { return MediumRange2; } if (C("Flashlight_C")) { return ExtendedRange; } if (C("Flashlight_D")) { return WideRange; } if (C("Flashlight_E")) { return MediumRange1; } if (C("Sniper")) { return ExtendedRange; } if (C("HELRifle") || (C("HEL") && C("Rifle") && !C("HELShotgun"))) { return ExtendedRange; } if (C("BurstRifle")) { return ExtendedRange; } if (C("Veruta")) { return WideRange; } if (C("Arbalist")) { return WideRange; } if (C("BurstCannon")) { return WideRange; } if (C("PDW")) { return WideRange; } if (C("Bullpup")) { return MediumRange1; } if (C("HELShotgun") || C("HELGun")) { return MediumRange1; } if (C("HeavyAssault")) { return MediumRange1; } if (C("Scattergun")) { return MediumRange1; } if (C("DoubleTap")) { return MediumRange1; } if (C("SlugShotgun")) { return MediumRange1; } if (C("ChokeMod")) { return MediumRange1; } if (C("DMR")) { return MediumRange2; } if (C("Carbine")) { return MediumRange2; } if (C("MachinePistol")) { return MediumRange2; } if (C("Sawed")) { return MediumRange2; } if (C("HELRevolver")) { return MediumRange2; } if (C("HELAuto") && C("Pistol")) { return MediumRange2; } if (C("HighCal") && C("Pistol")) { return MediumRange2; } if (C("BurstPistol")) { return MediumRange2; } if (C("AssaultRifle")) { return MediumRange2; } if (C("ShortRifle")) { return MediumRange2; } if (C("HeavySMG")) { return MediumRange2; } if (C("Pistol")) { return MediumRange2; } if (C("Revolver")) { return ShortRange; } if (C("CombatShotgun")) { return ShortRange; } if (C("PrecisionRifle")) { return ShortRange; } if (C("SMG")) { return ShortRange; } if (C("Shotgun")) { return ShortRange; } if (C("Rifle")) { return MediumRange1; } return null; bool C(string k) { return s2.IndexOf(k, StringComparison.OrdinalIgnoreCase) >= 0; } } internal static Preset ResolveByLight(Light light) { if ((Object)(object)light == (Object)null || ByPID.Count == 0) { return Default; } float spotAngle = light.spotAngle; float range = light.range; float intensity = light.intensity; foreach (KeyValuePair item in ByPID) { Preset value = item.Value; float num = value.CoreAngle - Plugin.Step1.Value; if (Mathf.Abs(spotAngle - num) <= 1f && Mathf.Abs(range - value.CoreRange) <= 1f && Mathf.Abs(intensity - value.CoreIntensity) <= 0.005f) { return value; } } return Default; } } internal static class LightSandwich { internal enum ManagedKind { None, Pickable, MeleeOrTool, Ranged } internal const string RFCORE = "RF_Core"; internal const string L1 = "RF_L1"; internal const string L2 = "RF_L2"; internal const string SPILL = "RF_Spill"; internal const string DUST = "RF_Dust"; internal const string L3 = "RF_L3"; internal const string L4 = "RF_L4"; internal const string L5 = "RF_L5"; private static readonly string[] AllLayers = new string[3] { "RF_Core", "RF_L1", "RF_L2" }; private const float CoreLayerOverlap = 0.28f; private const float MidLayerOverlap = 0.2f; private static readonly string[] LegacyLayers = new string[8] { "RF_Core", "RF_L1", "RF_L2", "RF_Spill", "RF_Dust", "RF_L3", "RF_L4", "RF_L5" }; private static readonly Dictionary _managed = new Dictionary(); internal static readonly Dictionary _lightPreset = new Dictionary(); private static Texture2D? _smoothCookie; private static Texture2D? _coreCookie; private static Texture2D? _midCookie; private static Texture2D? _falloffCookie; internal static readonly HashSet HelmetEditedIDs = new HashSet(); private static float WithLayerOverlap(float nominalAngle, int idx) { return Mathf.Min(nominalAngle * (1f + idx switch { 1 => 0.2f, 0 => 0.28f, _ => 0f, }), 179f); } internal static ManagedKind GetManagedKind(Light l) { if (!((Object)(object)l != (Object)null) || !_managed.TryGetValue(((Object)l).GetInstanceID(), out var value)) { return ManagedKind.None; } return value; } private static float Ss(float t) { return t * t * t * (t * (t * 6f - 15f) + 10f); } internal static Texture2D GetSmoothCookie() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown //IL_00a7: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_smoothCookie != (Object)null) { return _smoothCookie; } Texture2D val = new Texture2D(128, 128, (TextureFormat)4, false); ((Texture)val).wrapMode = (TextureWrapMode)1; ((Texture)val).filterMode = (FilterMode)1; ((Object)val).hideFlags = (HideFlags)61; float num = 63.5f; for (int i = 0; i < 128; i++) { for (int j = 0; j < 128; j++) { float num2 = ((float)j - num) / num; float num3 = ((float)i - num) / num; float num4 = Mathf.Sqrt(num2 * num2 + num3 * num3); float num5 = ((!(num4 >= 1f)) ? ((1f + Mathf.Cos(num4 * (float)Math.PI)) * 0.5f) : 0f); val.SetPixel(j, i, new Color(1f, 1f, 1f, num5)); } } val.Apply(); _smoothCookie = val; return val; } internal static Texture2D GetCoreCookie() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown //IL_00c3: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_coreCookie != (Object)null) { return _coreCookie; } Texture2D val = new Texture2D(128, 128, (TextureFormat)4, false); ((Texture)val).wrapMode = (TextureWrapMode)1; ((Texture)val).filterMode = (FilterMode)1; ((Object)val).hideFlags = (HideFlags)61; float num = 63.5f; for (int i = 0; i < 128; i++) { for (int j = 0; j < 128; j++) { float num2 = ((float)j - num) / num; float num3 = ((float)i - num) / num; float num4 = Mathf.Sqrt(num2 * num2 + num3 * num3); float num5; if (num4 >= 1f) { num5 = 0f; } else if (num4 <= 0.1f) { num5 = 1f; } else { float t = (num4 - 0.1f) / 0.9f; num5 = 1f - Ss(t); } val.SetPixel(j, i, new Color(1f, 1f, 1f, num5)); } } val.Apply(); _coreCookie = val; return val; } internal static Texture2D GetFalloffCookie() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown //IL_00f9: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_falloffCookie != (Object)null) { return _falloffCookie; } Texture2D val = new Texture2D(128, 128, (TextureFormat)4, false); ((Texture)val).wrapMode = (TextureWrapMode)1; ((Texture)val).filterMode = (FilterMode)1; ((Object)val).hideFlags = (HideFlags)61; float num = 63.5f; for (int i = 0; i < 128; i++) { for (int j = 0; j < 128; j++) { float num2 = ((float)j - num) / num; float num3 = ((float)i - num) / num; float num4 = Mathf.Sqrt(num2 * num2 + num3 * num3); float num5; if (num4 >= 1f) { num5 = 0f; } else if (num4 <= 0.5f) { num5 = 1f; } else if (num4 <= 0.68f) { float t = (num4 - 0.5f) / 0.18f; num5 = 1f - 0.7f * Ss(t); } else { float t2 = (num4 - 0.68f) / 0.32f; num5 = 0.3f - 0.26000002f * Ss(t2); } val.SetPixel(j, i, new Color(1f, 1f, 1f, num5)); } } val.Apply(); _falloffCookie = val; return val; } internal static Texture2D GetMidCookie() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown //IL_00c3: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_midCookie != (Object)null) { return _midCookie; } Texture2D val = new Texture2D(128, 128, (TextureFormat)4, false); ((Texture)val).wrapMode = (TextureWrapMode)1; ((Texture)val).filterMode = (FilterMode)1; ((Object)val).hideFlags = (HideFlags)61; float num = 63.5f; for (int i = 0; i < 128; i++) { for (int j = 0; j < 128; j++) { float num2 = ((float)j - num) / num; float num3 = ((float)i - num) / num; float num4 = Mathf.Sqrt(num2 * num2 + num3 * num3); float num5; if (num4 >= 1f) { num5 = 0f; } else if (num4 <= 0.22f) { num5 = 1f; } else { float t = (num4 - 0.22f) / 0.78f; num5 = 1f - Ss(t); } val.SetPixel(j, i, new Color(1f, 1f, 1f, num5)); } } val.Apply(); _midCookie = val; return val; } private static void BuildDustPS(Transform rfCoreTransform, ItemEquippable owner) { if (!((Object)(object)rfCoreTransform == (Object)null) && !((Object)(object)owner == (Object)null)) { DustEffect.EnsurePool(rfCoreTransform); } } internal static (bool isPickable, bool isMeleeOrTool) ClassifyOwner(Transform t) { try { Transform val = t; ItemEquippable val2 = null; int num = 32; while ((Object)(object)val != (Object)null && (Object)(object)val2 == (Object)null && num-- > 0) { GameObject gameObject = ((Component)val).gameObject; if ((Object)(object)gameObject == (Object)null) { break; } val2 = gameObject.GetComponent(); val = val.parent; } if ((Object)(object)val2 == (Object)null) { return (false, false); } if ((Object)(object)((Il2CppObjectBase)val2).TryCast() != (Object)null) { return (true, false); } if ((Object)(object)((Il2CppObjectBase)val2).TryCast() != (Object)null) { return (false, false); } return (false, true); } catch { return (false, false); } } internal static bool IsOwnerWeapon(Transform t) { try { Transform val = t; int num = 32; while ((Object)(object)val != (Object)null && num-- > 0) { GameObject gameObject = ((Component)val).gameObject; if ((Object)(object)gameObject == (Object)null) { break; } ItemEquippable component = gameObject.GetComponent(); if ((Object)(object)component != (Object)null) { try { return (Object)(object)((Il2CppObjectBase)component).TryCast() != (Object)null; } catch { return false; } } val = val.parent; } } catch { } return false; } internal static bool IsCameraAttached(Transform t) { try { Transform val = t; int num = 32; while ((Object)(object)val != (Object)null && num-- > 0) { GameObject gameObject = ((Component)val).gameObject; if (!((Object)(object)gameObject == (Object)null)) { if ((Object)(object)gameObject.GetComponent() != (Object)null) { return true; } string name = ((Object)gameObject).name; if (name != null && (name.IndexOf("FPSCamera", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("FPSLookCamera", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("FlashlightHolder", StringComparison.OrdinalIgnoreCase) >= 0)) { return true; } val = val.parent; continue; } break; } } catch { } return false; } internal static bool IsRFChild(string name) { return name.StartsWith("RF_"); } internal static bool IsUnmanaged(Transform t, string name) { if (IsRFChild(name)) { return true; } if ((Object)(object)t.Find("RF_Core") != (Object)null) { return false; } Light component = ((Component)t).GetComponent(); if ((Object)(object)component != (Object)null && HelmetEditedIDs.Contains(((Object)component).GetInstanceID())) { return false; } return true; } internal static ItemEquippable? FindItemEquippableOwner(Transform t) { try { Transform val = t; int num = 32; while ((Object)(object)val != (Object)null && num-- > 0) { ItemEquippable component = ((Component)val).gameObject.GetComponent(); if ((Object)(object)component != (Object)null) { return component; } val = val.parent; } } catch { } return null; } internal static bool IsHelmetLight(Transform t) { try { Transform val = t; int num = 32; while ((Object)(object)val != (Object)null && num-- > 0) { string name = ((Object)((Component)val).gameObject).name; if (name != null && name.IndexOf("HelmetLight", StringComparison.OrdinalIgnoreCase) >= 0) { return true; } val = val.parent; } } catch { } return false; } internal static void ApplyHelmetInPlace(Light l) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)l == (Object)null || (int)l.type != 0) { return; } int instanceID = ((Object)l).GetInstanceID(); if (!HelmetEditedIDs.Add(instanceID)) { return; } string[] array = new string[6] { "RF_Core", "RF_L1", "RF_L2", "RF_L3", "RF_L4", "RF_L5" }; foreach (string text in array) { Transform val = ((Component)l).transform.Find(text); if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)((Component)val).gameObject); } } l.cullingMask = -1; l.intensity = Plugin.HelmetIntensity; l.range = Plugin.HelmetRange; l.spotAngle = Mathf.Min(Plugin.HelmetAngle, 179f); l.innerSpotAngle = 0f; l.shadows = (LightShadows)0; try { l.cookie = (Texture)(object)GetSmoothCookie(); } catch { } _managed[instanceID] = ManagedKind.MeleeOrTool; Transform parent = ((Component)l).transform.parent; int num = 0; while (num < 2 && (Object)(object)parent != (Object)null) { Il2CppArrayBase componentsInChildren = ((Component)parent).GetComponentsInChildren(true); if (componentsInChildren != null) { foreach (Light item in componentsInChildren) { if (!((Object)(object)item == (Object)null) && !((Object)(object)item == (Object)(object)l) && !IsRFChild(((Object)((Component)item).gameObject).name) && (int)item.type == 0) { item.cullingMask = 0; } } } num++; parent = parent.parent; } LightUpdater.RegisterFlickerBaseline(l); LightUpdater.RegisterFlickerRef(l); } internal static void ApplySandwich(Light light, ItemEquippable owner) { bool flag = (Object)(object)owner != (Object)null && (Object)(object)((Il2CppObjectBase)owner).TryCast() != (Object)null; bool flag2 = (Object)(object)owner != (Object)null && (Object)(object)((Il2CppObjectBase)owner).TryCast() != (Object)null; bool isMeleeOrTool = (Object)(object)owner != (Object)null && !flag && !flag2; ApplySandwichInternal(light, flag, isMeleeOrTool); if (!flag2 || !((Object)(object)owner != (Object)null)) { return; } try { Il2CppArrayBase componentsInChildren = ((Component)owner).gameObject.GetComponentsInChildren(true); if (componentsInChildren == null) { return; } foreach (Light item in componentsInChildren) { if ((Object)(object)item == (Object)null || (Object)(object)item == (Object)(object)light || IsRFChild(((Object)((Component)item).gameObject).name)) { continue; } string[] array = new string[6] { "RF_Core", "RF_L1", "RF_L2", "RF_L3", "RF_L4", "RF_L5" }; foreach (string text in array) { Transform val = ((Component)item).transform.Find(text); if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)((Component)val).gameObject); } } _managed.Remove(((Object)item).GetInstanceID()); item.intensity = 0f; item.range = 0f; item.spotAngle = 0f; item.cullingMask = 0; } } catch { } } internal static void SuppressRangedSiblings(Light mLt, ItemEquippable owner) { if ((Object)(object)mLt == (Object)null || (Object)(object)owner == (Object)null) { return; } try { if (mLt.cullingMask != 0) { mLt.cullingMask = 0; } if (mLt.spotAngle != 0f) { mLt.spotAngle = 0f; } if (mLt.innerSpotAngle != 0f) { mLt.innerSpotAngle = 0f; } if (mLt.intensity != 0f) { mLt.intensity = 0f; } if (mLt.range != 0f) { mLt.range = 0f; } Il2CppArrayBase componentsInChildren = ((Component)owner).gameObject.GetComponentsInChildren(true); if (componentsInChildren == null) { return; } foreach (Light item in componentsInChildren) { if (!((Object)(object)item == (Object)null) && !((Object)(object)item == (Object)(object)mLt) && !IsRFChild(((Object)((Component)item).gameObject).name)) { if (item.cullingMask != 0) { item.cullingMask = 0; } if (item.intensity != 0f) { item.intensity = 0f; } if (item.range != 0f) { item.range = 0f; } if (item.spotAngle != 0f) { item.spotAngle = 0f; } } } } catch { } } internal static void ApplySandwich(Light light) { var (isPickable, isMeleeOrTool) = ClassifyOwner(((Component)light).transform); ApplySandwichInternal(light, isPickable, isMeleeOrTool); } internal static void EnsurePickableSettings(Light light) { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) Light light2 = light; if ((Object)(object)light2 == (Object)null) { return; } ItemEquippable val = FindItemEquippableOwner(((Component)light2).transform); if ((Object)(object)val == (Object)null) { return; } bool flag; try { flag = (Object)(object)((Il2CppObjectBase)val).TryCast() != (Object)null; } catch { return; } if (!flag) { return; } int instanceID = ((Object)light2).GetInstanceID(); if (_managed.TryGetValue(instanceID, out var value) && value == ManagedKind.Pickable) { return; } Color warm = Plugin.PickColor; float num = Mathf.Min(Plugin.PickAngle, 179f); float num2 = Mathf.Min(num + Plugin.Step1.Value, 179f); float angle2 = Mathf.Min(num2 + Plugin.Step2.Value, 179f); float angle3 = Mathf.Min(num2 + Plugin.Step2.Value * Plugin.MidStepFraction.Value, 179f); float pickIntensity = Plugin.PickIntensity; float pickRange = Plugin.PickRange; light2.intensity = pickIntensity; light2.range = pickRange; light2.spotAngle = num; light2.innerSpotAngle = 0f; light2.color = warm; _managed[instanceID] = ManagedKind.Pickable; UpdateLayer("RF_Core", pickIntensity, pickRange, num2); UpdateLayer("RF_L1", pickIntensity * Plugin.I1.Value, pickRange * Plugin.R1.Value, angle3); UpdateLayer("RF_L2", pickIntensity * Plugin.I2.Value, pickRange * Plugin.R2.Value, angle2); Transform val2 = ((Component)light2).transform.Find("RF_Core"); if ((Object)(object)val2 != (Object)null) { Light component = ((Component)val2).GetComponent(); if ((Object)(object)component != (Object)null) { LightUpdater.RegisterFlickerBaseline(component); } BuildDustPS(val2, val); } void UpdateLayer(string layerName, float intensity, float range, float angle) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) Transform val3 = ((Component)light2).transform.Find(layerName); if (!((Object)(object)val3 == (Object)null)) { Light component2 = ((Component)val3).GetComponent(); if (!((Object)(object)component2 == (Object)null)) { component2.intensity = intensity; component2.range = range; component2.spotAngle = angle; component2.innerSpotAngle = InnerForLayer(layerName, angle); component2.color = warm; } } } } internal static void EnsureRangedSettings(Light light, bool forceResolve = false) { if (!((Object)(object)light == (Object)null)) { EnsureRangedSettings(light, FindItemEquippableOwner(((Component)light).transform), forceResolve); } } internal static void EnsureRangedSettings(Light light, ItemEquippable? owner, bool forceResolve) { Light light2 = light; if ((Object)(object)light2 == (Object)null || (Object)(object)owner == (Object)null) { return; } bool flag; try { flag = (Object)(object)((Il2CppObjectBase)owner).TryCast() != (Object)null; } catch { return; } if (!flag) { return; } int instanceID = ((Object)light2).GetInstanceID(); if (_managed.TryGetValue(instanceID, out var value) && (value == ManagedKind.MeleeOrTool || value == ManagedKind.Pickable)) { try { Plugin.Logger.LogWarning((object)("[RF] EnsureRangedSettings: light id=" + instanceID + " was misclassified as " + value.ToString() + " (owner=" + (((Object)(object)((Component)owner).gameObject != (Object)null) ? ((Object)((Component)owner).gameObject).name : "?") + ") — destroying RF children and rebuilding sandwich")); Transform transform = ((Component)light2).transform; string[] legacyLayers = LegacyLayers; foreach (string text in legacyLayers) { Transform val = transform.Find(text); if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)((Component)val).gameObject); } } _managed.Remove(instanceID); _lightPreset.Remove(instanceID); ApplySandwich(light2, owner); } catch (Exception ex) { Plugin.Logger.LogWarning((object)("[RF] defensive rebuild failed: " + ex.Message)); } } if (forceResolve) { RangedPresets.ClearOwnerCacheEntry(owner); } RangedPresets.Preset? preset2 = RangedPresets.ResolveByOwner(owner); RangedPresets.Preset preset; RangedPresets.Preset value2; if (preset2.HasValue) { preset = preset2.Value; } else if (_lightPreset.TryGetValue(instanceID, out value2)) { preset = value2; } else { preset = RangedPresets.ResolveByLight(light2); } _lightPreset[instanceID] = preset; _managed[instanceID] = ManagedKind.Ranged; UpdateLayer("RF_Core", preset.CoreIntensity, preset.CoreRange, WithLayerOverlap(preset.CoreAngle, 0)); UpdateLayer("RF_L1", preset.HasMid ? preset.MidIntensity : 0f, preset.HasMid ? preset.MidRange : 0f, preset.HasMid ? WithLayerOverlap(preset.MidAngle, 1) : 0f); UpdateLayer("RF_L2", preset.FallIntensity, preset.FallRange, preset.FallAngle); Transform val2 = ((Component)light2).transform.Find("RF_Core"); if ((Object)(object)val2 != (Object)null) { Light component = ((Component)val2).GetComponent(); if ((Object)(object)component != (Object)null) { LightUpdater.RegisterFlickerBaseline(component); } BuildDustPS(val2, owner); } void UpdateLayer(string layerName, float intensity, float range, float angle) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) Transform val3 = ((Component)light2).transform.Find(layerName); if (!((Object)(object)val3 == (Object)null)) { Light component2 = ((Component)val3).GetComponent(); if (!((Object)(object)component2 == (Object)null)) { component2.intensity = intensity; component2.range = range; component2.spotAngle = angle; component2.innerSpotAngle = InnerForLayer(layerName, angle); component2.color = preset.Tint; } } } } private static void ApplySandwichInternal(Light light, bool isPickable, bool isMeleeOrTool) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Invalid comparison between Unknown and I4 //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_045d: Unknown result type (might be due to invalid IL or missing references) //IL_047d: Unknown result type (might be due to invalid IL or missing references) //IL_048c: Unknown result type (might be due to invalid IL or missing references) //IL_0491: Unknown result type (might be due to invalid IL or missing references) //IL_049e: Unknown result type (might be due to invalid IL or missing references) //IL_04a4: Unknown result type (might be due to invalid IL or missing references) //IL_04ae: Unknown result type (might be due to invalid IL or missing references) //IL_051f: Unknown result type (might be due to invalid IL or missing references) //IL_04ff: Unknown result type (might be due to invalid IL or missing references) //IL_0587: Unknown result type (might be due to invalid IL or missing references) //IL_0590: Unknown result type (might be due to invalid IL or missing references) //IL_0596: Invalid comparison between Unknown and I4 Transform transform = ((Component)light).transform; if ((Object)(object)transform.Find("RF_L1") != (Object)null) { return; } if ((int)light.type == 0) { if (isPickable) { light.intensity = Plugin.PickIntensity; light.range = Plugin.PickRange; light.spotAngle = Plugin.PickAngle; light.innerSpotAngle = 0f; light.color = Plugin.PickColor; _managed[((Object)light).GetInstanceID()] = ManagedKind.Pickable; } else if (isMeleeOrTool) { light.spotAngle = Mathf.Min(Plugin.HelmetAngle, 179f); light.intensity = Plugin.HelmetIntensity; light.range = Plugin.HelmetRange; light.innerSpotAngle = 0f; _managed[((Object)light).GetInstanceID()] = ManagedKind.MeleeOrTool; } } float intensity = light.intensity; float range = light.range; bool flag = !isPickable && !isMeleeOrTool && IsOwnerWeapon(((Component)light).transform); RangedPresets.Preset value = RangedPresets.Default; if (flag && (int)light.type == 0) { value = RangedPresets.ResolveByOwner(FindItemEquippableOwner(((Component)light).transform)) ?? RangedPresets.ResolveByLight(light); int instanceID = ((Object)light).GetInstanceID(); _managed[instanceID] = ManagedKind.Ranged; _lightPreset[instanceID] = value; } Color color = (flag ? value.Tint : light.color); bool enabled = ((Behaviour)light).enabled; if ((int)light.type == 2) { float[] array = new float[3] { 0.55f, 0.3f, 0.1f }; float[] array2 = new float[3] { 1.3f, 1.8f, 2.4f }; string[] array3 = new string[3] { "RF_L1", "RF_L2", "RF_L3" }; for (int i = 0; i < array3.Length; i++) { GameObject val = new GameObject(array3[i]); val.transform.SetParent(transform, false); val.transform.localPosition = Vector3.zero; val.layer = ((Component)transform).gameObject.layer; Light obj = val.AddComponent(); obj.type = (LightType)2; obj.intensity = intensity * array[i]; obj.range = range * array2[i]; obj.color = color; ((Behaviour)obj).enabled = enabled; obj.shadows = (LightShadows)0; obj.cullingMask = -1; } return; } float num; float num2; float num3; if (flag && (int)light.type == 0) { num = value.CoreAngle - Plugin.Step1.Value; num2 = value.CoreIntensity; num3 = value.CoreRange; } else { num = light.spotAngle; num2 = intensity; num3 = range; } float[] array4; float[] array5; float[] array6; if (flag && (int)light.type == 0) { array4 = new float[3] { value.CoreAngle, value.HasMid ? value.MidAngle : 0f, value.FallAngle }; array5 = new float[3] { value.CoreIntensity, value.HasMid ? value.MidIntensity : 0f, value.FallIntensity }; array6 = new float[3] { value.CoreRange, value.HasMid ? value.MidRange : 0f, value.FallRange }; } else { float num4 = Mathf.Min(num + Plugin.Step1.Value, 179f); float num5 = Mathf.Min(num4 + Plugin.Step2.Value, 179f); float num6 = Mathf.Min(num4 + Plugin.Step2.Value * Plugin.MidStepFraction.Value, 179f); array4 = new float[3] { num4, num6, num5 }; array5 = new float[3] { num2, num2 * Plugin.I1.Value, num2 * Plugin.I2.Value }; array6 = new float[3] { num3, num3 * Plugin.R1.Value, num3 * Plugin.R2.Value }; if (isPickable) { array5[2] = num2 * Plugin.I2.Value * 2.5f; array4[2] = Mathf.Min(num5 + 50f, 179f); } } for (int j = 0; j < AllLayers.Length; j++) { AddLayer(transform, AllLayers[j], array5[j], array6[j], 0f, WithLayerOverlap(array4[j], j), color, enabled, j == 0); } if ((int)light.type == 0) { GameObject val2 = new GameObject("RF_Spill"); val2.transform.SetParent(transform, false); val2.transform.localPosition = Vector3.zero; val2.layer = ((Component)transform).gameObject.layer; Light obj2 = val2.AddComponent(); obj2.type = (LightType)2; float num7 = (isPickable ? 0.2f : 0.18f); obj2.intensity = array5[2] * num7; obj2.range = (isPickable ? 8f : 7f); obj2.color = color; ((Behaviour)obj2).enabled = enabled; obj2.shadows = (LightShadows)0; obj2.cullingMask = -1; } if (flag && (int)light.type == 0) { light.spotAngle = 0f; } light.cullingMask = 0; Il2CppArrayBase componentsInChildren = ((Component)light).gameObject.GetComponentsInChildren(true); if (componentsInChildren == null) { return; } foreach (Light item in componentsInChildren) { if (!((Object)(object)item == (Object)null) && !((Object)(object)item == (Object)(object)light) && !IsRFChild(((Object)((Component)item).gameObject).name) && ((int)item.type == 0 || (int)item.type == 2)) { item.cullingMask = 0; } } } internal static float InnerForLayer(string layerName, float outerAngle) { if (layerName == "RF_L2") { return Mathf.Max(0f, outerAngle - 3f); } return Mathf.Max(0f, outerAngle - 0.5f); } private static void AddLayer(Transform parent, string name, float intensity, float range, float innerAngle, float outerAngle, Color color, bool enabled, bool isCore = false) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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_0020: 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) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) Light component = ((Component)parent).GetComponent(); GameObject val = new GameObject(name); val.transform.SetParent(parent, false); val.transform.localPosition = Vector3.zero; val.transform.localRotation = Quaternion.identity; val.layer = ((Component)parent).gameObject.layer; Light val2 = val.AddComponent(); val2.type = (LightType)0; val2.intensity = intensity; val2.range = range; val2.spotAngle = outerAngle; val2.innerSpotAngle = InnerForLayer(name, outerAngle); val2.color = color; ((Behaviour)val2).enabled = enabled; val2.shadows = (LightShadows)0; val2.cullingMask = -1; Texture2D cookie = (isCore ? GetCoreCookie() : ((!(name == "RF_L1")) ? GetFalloffCookie() : GetMidCookie())); try { val2.cookie = (Texture)(object)cookie; } catch { } if ((Object)(object)component != (Object)null) { val2.renderMode = component.renderMode; val2.bounceIntensity = component.bounceIntensity; } if (isCore) { LightUpdater.RegisterFlickerBaseline(val2); LightUpdater.RegisterFlickerRef(val2); } } internal static void RebuildAll() { HelmetEditedIDs.Clear(); _lightPreset.Clear(); DustEffect.DestroyPool(); FogBeamEffect.Deallocate(); foreach (Light item in Object.FindObjectsOfType()) { if (!((Object)(object)item == (Object)null) && !IsRFChild(((Object)((Component)item).gameObject).name)) { string[] legacyLayers = LegacyLayers; foreach (string childName in legacyLayers) { DestroyChild(((Component)item).transform, childName); } } } } private static void DestroyChild(Transform parent, string childName) { Transform val = parent.Find(childName); if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)((Component)val).gameObject); } } internal static void ProcessAllSpotLights() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Invalid comparison between Unknown and I4 if (!Plugin.Enabled.Value) { return; } foreach (Light item in Object.FindObjectsOfType()) { if (!((Object)(object)item == (Object)null) && ((int)item.type == 0 || (int)item.type == 2) && !IsRFChild(((Object)((Component)item).gameObject).name)) { if (IsHelmetLight(((Component)item).transform)) { ApplyHelmetInPlace(item); } else if (!ClassifyOwner(((Component)item).transform).isMeleeOrTool) { ApplySandwich(item); } } } } internal static void SyncEnabled(Transform t, bool v) { Light component = ((Component)t).GetComponent(); if ((Object)(object)component != (Object)null && (Object)(object)t.Find("RF_L1") != (Object)null) { component.cullingMask = 0; } if (v) { ItemEquippable val = FindItemEquippableOwner(t); if ((Object)(object)val != (Object)null && (Object)(object)Patch_ItemWield.CurrentWieldedItem != (Object)null && (Object)(object)val != (Object)(object)Patch_ItemWield.CurrentWieldedItem) { v = false; } } string[] allLayers = AllLayers; foreach (string text in allLayers) { Transform val2 = t.Find(text); if ((Object)(object)val2 == (Object)null) { continue; } GameObject gameObject = ((Component)val2).gameObject; if (v) { if (!gameObject.activeSelf) { gameObject.SetActive(true); } Light component2 = ((Component)val2).GetComponent(); if ((Object)(object)component2 != (Object)null) { ((Behaviour)component2).enabled = true; } } else { Light component3 = ((Component)val2).GetComponent(); if ((Object)(object)component3 != (Object)null) { ((Behaviour)component3).enabled = false; } if (gameObject.activeSelf) { gameObject.SetActive(false); } } } Transform val3 = t.Find("RF_Spill"); if (!((Object)(object)val3 != (Object)null)) { return; } GameObject gameObject2 = ((Component)val3).gameObject; if (v) { if (!gameObject2.activeSelf) { gameObject2.SetActive(true); } Light component4 = ((Component)val3).GetComponent(); if ((Object)(object)component4 != (Object)null) { ((Behaviour)component4).enabled = true; } } else { Light component5 = ((Component)val3).GetComponent(); if ((Object)(object)component5 != (Object)null) { ((Behaviour)component5).enabled = false; } if (gameObject2.activeSelf) { gameObject2.SetActive(false); } } } internal static void SyncColor(Transform t, Color v) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) ManagedKind managedKind = GetManagedKind(((Component)t).GetComponent()); if (managedKind == ManagedKind.None || managedKind == ManagedKind.Ranged || managedKind == ManagedKind.Pickable) { return; } string[] allLayers = AllLayers; foreach (string text in allLayers) { Apply(t.Find(text), delegate(Light x) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) x.color = v; }); } } internal static void SyncIntensity(Transform t, float parentIntensity) { switch (GetManagedKind(((Component)t).GetComponent())) { case ManagedKind.MeleeOrTool: parentIntensity = Plugin.HelmetIntensity; break; case ManagedKind.Pickable: parentIntensity = Plugin.PickIntensity; break; case ManagedKind.Ranged: return; default: if (parentIntensity <= 0f) { return; } break; } float[] mults = new float[3] { 1f, Plugin.I1.Value, Plugin.I2.Value }; int i; for (i = 0; i < AllLayers.Length; i++) { Apply(t.Find(AllLayers[i]), delegate(Light x) { x.intensity = parentIntensity * mults[i]; }); } } internal static void SyncRange(Transform t, float parentRange) { switch (GetManagedKind(((Component)t).GetComponent())) { case ManagedKind.MeleeOrTool: parentRange = Plugin.HelmetRange; break; case ManagedKind.Pickable: parentRange = Plugin.PickRange; break; case ManagedKind.Ranged: return; default: if (parentRange <= 0f) { return; } break; } float[] mults = new float[3] { 1f, Plugin.R1.Value, Plugin.R2.Value }; int i; for (i = 0; i < AllLayers.Length; i++) { Apply(t.Find(AllLayers[i]), delegate(Light x) { x.range = parentRange * mults[i]; }); } } internal static void SyncAngle(Transform t, float coreAngle) { switch (GetManagedKind(((Component)t).GetComponent())) { case ManagedKind.MeleeOrTool: coreAngle = Plugin.HelmetAngle; break; case ManagedKind.Pickable: coreAngle = Plugin.PickAngle; break; case ManagedKind.Ranged: return; } float num = Mathf.Min(coreAngle + Plugin.Step1.Value, 179f); float num2 = Mathf.Min(num + Plugin.Step2.Value, 179f); float nominalAngle = Mathf.Min(num + Plugin.Step2.Value * Plugin.MidStepFraction.Value, 179f); float[] array = new float[3] { WithLayerOverlap(num, 0), WithLayerOverlap(nominalAngle, 1), num2 }; for (int i = 0; i < AllLayers.Length; i++) { float outer = array[i]; string layerName = AllLayers[i]; Apply(t.Find(layerName), delegate(Light x) { x.innerSpotAngle = InnerForLayer(layerName, outer); x.spotAngle = outer; }); } } private static void Apply(Transform? child, Action action) { if (!((Object)(object)child == (Object)null)) { Light component = ((Component)child).GetComponent(); if ((Object)(object)component != (Object)null) { action(component); } } } } internal static class DustEffect { private const int TotalCount = 365; private const int CountSoft = 245; private const int CountStar = 88; private const int CountMed = 32; private const float CoreToMidFactor = 1.4f; private const float VelMin = 0.04f; private const float VelMax = 0.18f; private const float ResampleMin = 4f; private const float ResampleMax = 9f; private const float SoftMin = 0.004f; private const float SoftMax = 0.025f; private const float StarMin = 0.006f; private const float StarMax = 0.014f; private const float MedMin = 0.025f; private const float MedMax = 0.075f; private const float SizeExp = 3.5f; private const float SizeExpMed = 2f; private const float ConeTol = 1.1f; internal static int _tickThrowLogBudget = 3; private static GameObject? _root; private static GameObject[]? _motes; private static Renderer?[]? _renderers; private static byte[]? _kind; private static Vector3[]? _vels; private static float[]? _nextResample; private static Vector3[]? _targetVels; private const float VelLerpPerSec = 0.45f; private static Color[]? _baseColors; private static float[]? _spawnTime; private const float SpawnFadeSec = 1.6f; private static Material? _softMat; private static Material? _starMat; private static Material? _milkMat; private static Texture2D? _softTex; private static Texture2D? _starTex; private static MaterialPropertyBlock? _mpb; private static Transform? _anchor; internal static Transform? _coneRoot; internal static Light? _coreLight; private static GameObject? _milkSphere; private const float MilkBaseAlpha = 0.006f; private const float MilkConeFraction = 0.35f; private const float MilkScaleMul = 0.95f; private const float MilkMinDist = 0.45f; private static readonly float[] _milkTier_A = new float[2] { 0.5f, 0.6f }; private static readonly float[] _milkTier_B = new float[2] { 0.6f, 0.75f }; private static readonly float[] _milkTier_C = new float[2] { 0.75f, 0.8f }; private static readonly float[] _milkTier_D = new float[4] { 0.75f, 0.8f, 0.85f, 0.9f }; private static readonly float[] _milkTier_E = new float[3] { 0.85f, 0.9f, 1f }; private const float MilkRollMinSec = 900f; private const float MilkRollMaxSec = 3900f; private const float MilkLerpMinSec = 8f; private const float MilkLerpMaxSec = 25f; internal static float _milkMulCurrent = 1f; private static float _milkMulFrom = 1f; private static float _milkMulTo = 1f; private static float _milkLerpStart = -1f; private static float _milkLerpDur = 12f; private static float _milkNextRoll = -1f; private static float _hazeDepth = 1f; private static float _hazeAlpha01 = 1f; private const float HazeLerpPerSec = 4.5f; private const float NearBiasMaxDepth = 4f; private const float NearBiasRangeThresh = 8f; internal static void SetActiveCone(Transform? coneT, Light? coreL) { if (!((Object)(object)coneT == (Object)null) && !((Object)(object)coreL == (Object)null)) { _coneRoot = coneT; _coreLight = coreL; Transform val = FindCameraAnchor(coneT); if ((Object)(object)val != (Object)null) { _anchor = val; } } } internal static void EnsurePool(Transform rfCoreT) { //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Expected O, but got Unknown //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Expected O, but got Unknown //IL_02a7: Unknown result type (might be due to invalid IL or missing references) //IL_02a8: Unknown result type (might be due to invalid IL or missing references) //IL_02f8: 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_02d4: Unknown result type (might be due to invalid IL or missing references) //IL_02d5: Unknown result type (might be due to invalid IL or missing references) //IL_031c: 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_032b: Unknown result type (might be due to invalid IL or missing references) //IL_033b: 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_036b: Unknown result type (might be due to invalid IL or missing references) //IL_038b: Unknown result type (might be due to invalid IL or missing references) //IL_0458: Unknown result type (might be due to invalid IL or missing references) //IL_0469: Unknown result type (might be due to invalid IL or missing references) //IL_0491: Unknown result type (might be due to invalid IL or missing references) //IL_04a5: Unknown result type (might be due to invalid IL or missing references) //IL_04aa: Unknown result type (might be due to invalid IL or missing references) //IL_04b3: Unknown result type (might be due to invalid IL or missing references) //IL_04b5: Unknown result type (might be due to invalid IL or missing references) //IL_04c1: 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_04e8: Unknown result type (might be due to invalid IL or missing references) //IL_04ea: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.DustEnabled.Value || (Object)(object)rfCoreT == (Object)null) { return; } SetActiveCone(rfCoreT, ((Component)rfCoreT).GetComponent()); if ((Object)(object)_coreLight == (Object)null || (Object)(object)_anchor == (Object)null || ((Object)(object)_root != (Object)null && _motes != null && _vels != null)) { return; } try { if ((Object)(object)_softTex == (Object)null) { _softTex = BuildSoftCircleTex(64); } if ((Object)(object)_starTex == (Object)null) { _starTex = BuildStarTex(64); } if ((Object)(object)_softMat == (Object)null) { _softMat = BuildBillboardMat(_softTex, new Color(0.4f, 0.36f, 0.3f, 0.03f)); } if ((Object)(object)_starMat == (Object)null) { _starMat = BuildBillboardMat(_starTex, new Color(0.55f, 0.5f, 0.42f, 0.05f)); } if ((Object)(object)_milkMat == (Object)null) { _milkMat = BuildBillboardMat(_softTex, new Color(0.45f, 0.42f, 0.38f, 0.006f)); } if ((Object)(object)_softMat == (Object)null || (Object)(object)_starMat == (Object)null || (Object)(object)_milkMat == (Object)null) { return; } if (_mpb == null) { _mpb = new MaterialPropertyBlock(); } _root = new GameObject("RF_DustPool"); Object.DontDestroyOnLoad((Object)(object)_root); _motes = (GameObject[]?)(object)new GameObject[365]; _renderers = (Renderer?[]?)(object)new Renderer[365]; _kind = new byte[365]; _vels = (Vector3[]?)(object)new Vector3[365]; _targetVels = (Vector3[]?)(object)new Vector3[365]; _nextResample = new float[365]; _baseColors = (Color[]?)(object)new Color[365]; _spawnTime = new float[365]; float unscaledTime = Time.unscaledTime; float num = Mathf.Max(0f, Plugin.DustOpacity?.Value ?? 1f); Color val = default(Color); ((Color)(ref val))..ctor(0.4f, 0.36f, 0.3f, 0.022f * num); Color val2 = default(Color); ((Color)(ref val2))..ctor(0.55f, 0.5f, 0.42f, 0.038f * num); Color val3 = default(Color); ((Color)(ref val3))..ctor(0.42f, 0.38f, 0.32f, 0.03f * num); for (int i = 0; i < 365; i++) { byte b; Material sharedMaterial; float num2; float num3; float num4; Color val4; if (i < 245) { b = 0; sharedMaterial = _softMat; num2 = 0.004f; num3 = 0.025f; num4 = 3.5f; val4 = val; } else if (i < 333) { b = 1; sharedMaterial = _starMat; num2 = 0.006f; num3 = 0.014f; num4 = 3.5f; val4 = val2; } else { b = 2; sharedMaterial = _softMat; num2 = 0.025f; num3 = 0.075f; num4 = 2f; val4 = val3; } if (Random.value < 0.45f) { float num5 = Random.Range(0.35f, 0.65f); float num6 = (val4.r + val4.g + val4.b) / 3f; float num7 = Mathf.Lerp(val4.r, num6, 0.6f) * num5; float num8 = Mathf.Lerp(val4.g, num6, 0.6f) * num5; float num9 = Mathf.Lerp(val4.b, num6, 0.6f) * num5; ((Color)(ref val4))..ctor(num7, num8, num9, val4.a); } GameObject val5 = GameObject.CreatePrimitive((PrimitiveType)5); ((Object)val5).name = "RF_DustMote_" + i + b switch { 1 => "_x", 0 => "_s", _ => "_m", }; val5.transform.SetParent(_root.transform, false); Collider component = val5.GetComponent(); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } MeshRenderer component2 = val5.GetComponent(); if ((Object)(object)component2 != (Object)null) { ((Renderer)component2).sharedMaterial = sharedMaterial; ((Renderer)component2).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)component2).receiveShadows = false; } float num10 = Mathf.Pow(Random.value, num4); float num11 = Mathf.Lerp(num2, num3, num10); val5.transform.localScale = new Vector3(num11, num11, num11); val5.transform.position = SampleInCone(); _motes[i] = val5; _renderers[i] = (Renderer?)(object)component2; _kind[i] = b; Vector3 val6 = Random.onUnitSphere * Random.Range(0.04f, 0.18f); _vels[i] = val6; _targetVels[i] = val6; _nextResample[i] = unscaledTime + Random.Range(4f, 9f); _baseColors[i] = val4; _spawnTime[i] = unscaledTime - Random.Range(0f, 1.6f); } _milkSphere = GameObject.CreatePrimitive((PrimitiveType)5); ((Object)_milkSphere).name = "RF_MilkHaze"; _milkSphere.transform.SetParent(_coneRoot, false); Collider component3 = _milkSphere.GetComponent(); if ((Object)(object)component3 != (Object)null) { Object.Destroy((Object)(object)component3); } MeshRenderer component4 = _milkSphere.GetComponent(); if ((Object)(object)component4 != (Object)null) { ((Renderer)component4).sharedMaterial = _milkMat; ((Renderer)component4).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)component4).receiveShadows = false; } Plugin.Logger.LogWarning((object)("[RF] DustEffect: pool built, total=" + 365 + " (soft=" + 245 + " star=" + 88 + " med=" + 32 + ") + Haze (helmet-only quad) anchor=" + ((Object)((Component)_anchor).gameObject).name)); } catch (Exception ex) { Plugin.Logger.LogWarning((object)("[RF] DustEffect.EnsurePool failed: " + ex.GetType().Name + " " + ex.Message)); DestroyPool(); } } internal static void Tick(float dt) { //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: 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_0092: 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_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0312: Unknown result type (might be due to invalid IL or missing references) //IL_031e: 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_032a: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_0430: Unknown result type (might be due to invalid IL or missing references) //IL_0437: Unknown result type (might be due to invalid IL or missing references) //IL_0439: Unknown result type (might be due to invalid IL or missing references) //IL_043b: Unknown result type (might be due to invalid IL or missing references) //IL_0440: 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_0248: Unknown result type (might be due to invalid IL or missing references) //IL_0457: Unknown result type (might be due to invalid IL or missing references) //IL_0459: Unknown result type (might be due to invalid IL or missing references) //IL_02b1: Unknown result type (might be due to invalid IL or missing references) //IL_02c5: Unknown result type (might be due to invalid IL or missing references) //IL_02ca: Unknown result type (might be due to invalid IL or missing references) //IL_03e8: Unknown result type (might be due to invalid IL or missing references) //IL_03ed: Unknown result type (might be due to invalid IL or missing references) //IL_0416: Unknown result type (might be due to invalid IL or missing references) if (_motes == null || _vels == null || _renderers == null || (Object)(object)_anchor == (Object)null || (Object)(object)_coneRoot == (Object)null || (Object)(object)_coreLight == (Object)null) { return; } bool flag = false; try { flag = ((Behaviour)_coreLight).isActiveAndEnabled; } catch { } if ((Object)(object)_root != (Object)null && _root.activeSelf != flag) { try { _root.SetActive(flag); } catch { } } if (!flag) { return; } Vector3 position = _coneRoot.position; Vector3 forward = _coneRoot.forward; Vector3 right = _coneRoot.right; Vector3 up = _coneRoot.up; float range = _coreLight.range; float num = Mathf.Tan(Mathf.Min(_coreLight.spotAngle * 0.5f * ((float)Math.PI / 180f) * 1.4f, 1.5358897f)); Vector3 position2 = _anchor.position; float unscaledTime = Time.unscaledTime; UpdateMilkMultiplier(unscaledTime); for (int i = 0; i < _motes.Length; i++) { GameObject val = _motes[i]; if ((Object)(object)val == (Object)null) { continue; } Vector3 val2 = val.transform.position + _vels[i] * dt; Vector3 val3 = val2 - position; float num2 = Vector3.Dot(val3, forward); bool flag2 = num2 > 0.1f && num2 < range; float num3 = 1f; if (flag2) { float num4 = num2 * num; Vector3 val4 = val3 - forward * num2; num3 = ((Vector3)(ref val4)).magnitude / Mathf.Max(num4, 0.0001f); if (num3 > 1.1f) { flag2 = false; } } Renderer val5 = _renderers[i]; if ((Object)(object)val5 != (Object)null && val5.enabled != flag2) { val5.enabled = flag2; } if (!flag2) { float range2 = ((range > 8f) ? Mathf.Min(range * 0.9f, 4f) : range); val2 = SampleInConeFast(position, forward, right, up, range2, num); Vector3 val6 = Random.onUnitSphere * Random.Range(0.04f, 0.18f); _vels[i] = val6; if (_targetVels != null) { _targetVels[i] = val6; } if (_nextResample != null) { _nextResample[i] = unscaledTime + Random.Range(4f, 9f); } if (_spawnTime != null) { _spawnTime[i] = unscaledTime; } } else { if (_nextResample != null && unscaledTime >= _nextResample[i]) { if (num3 > 0.6f && _targetVels != null) { _targetVels[i] = Random.onUnitSphere * Random.Range(0.04f, 0.18f); } _nextResample[i] = unscaledTime + Random.Range(4f, 9f); } if (_targetVels != null) { float num5 = 1f - Mathf.Exp(-0.45f * dt); _vels[i] = Vector3.Lerp(_vels[i], _targetVels[i], num5); } if (_mpb != null && _baseColors != null && (Object)(object)val5 != (Object)null) { float num6 = Mathf.Clamp01(num3); float num7 = 1f - num6 * num6 * num6 * (num6 * (num6 * 6f - 15f) + 10f); float num8 = Mathf.Clamp01(1f - num2 / range * 0.6f); float num9 = 1f; if (_spawnTime != null) { float num10 = Mathf.Clamp01((unscaledTime - _spawnTime[i]) / 1.6f); num9 = num10 * num10 * num10 * (num10 * (num10 * 6f - 15f) + 10f); } Color val7 = _baseColors[i]; val7.a *= num7 * num8 * num9; _mpb.Clear(); _mpb.SetColor("_Color", val7); val5.SetPropertyBlock(_mpb); } } val.transform.position = val2; Vector3 val8 = val2 - position2; if (((Vector3)(ref val8)).sqrMagnitude > 0.0001f) { val.transform.rotation = Quaternion.LookRotation(val8); } } } internal static void RepositionHaze() { if (!((Object)(object)_milkSphere == (Object)null) && !((Object)(object)_coneRoot == (Object)null) && !((Object)(object)_coreLight == (Object)null) && !((Object)(object)_anchor == (Object)null)) { bool flag = false; try { flag = ((Behaviour)_coreLight).isActiveAndEnabled; } catch { } MeshRenderer component = _milkSphere.GetComponent(); bool value = Plugin.HazeEnabled.Value; bool flag2 = (Object)(object)_coneRoot != (Object)null && ((Object)_coneRoot).name.IndexOf("HelmetSynth", StringComparison.Ordinal) >= 0; if (!flag || value) { } if ((Object)(object)component != (Object)null && ((Renderer)component).enabled) { ((Renderer)component).enabled = false; } } } internal static void DestroyPool() { try { if ((Object)(object)_milkSphere != (Object)null) { Object.Destroy((Object)(object)_milkSphere); } } catch { } try { if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)_root); } } catch { } _milkSphere = null; _root = null; _motes = null; _renderers = null; _kind = null; _vels = null; _nextResample = null; _targetVels = null; _baseColors = null; _spawnTime = null; } private static float UpdateMilkMultiplier(float now) { if (_milkNextRoll < 0f) { int rundownTierIndex = GetRundownTierIndex(); float[] targetsForTier = GetTargetsForTier(rundownTierIndex); _milkMulCurrent = targetsForTier[Random.Range(0, targetsForTier.Length)]; _milkMulFrom = _milkMulCurrent; _milkMulTo = _milkMulCurrent; _milkLerpStart = now; _milkLerpDur = 0.01f; _milkNextRoll = now + Random.Range(900f, 3900f); Plugin.Logger.LogWarning((object)("[RF] Haze init: tier=" + TierLetter(rundownTierIndex) + " mul=" + _milkMulCurrent.ToString("F2") + " (effective alpha=" + (0.006f * _milkMulCurrent).ToString("F4") + ") nextRollIn=" + ((_milkNextRoll - now) / 60f).ToString("F1") + "min")); return _milkMulCurrent; } if (now < _milkLerpStart + _milkLerpDur) { float num = Mathf.Clamp01((now - _milkLerpStart) / _milkLerpDur); float num2 = num * num * num * (num * (num * 6f - 15f) + 10f); _milkMulCurrent = Mathf.Lerp(_milkMulFrom, _milkMulTo, num2); } else { _milkMulCurrent = _milkMulTo; } if (now >= _milkNextRoll) { int rundownTierIndex2 = GetRundownTierIndex(); float[] targetsForTier2 = GetTargetsForTier(rundownTierIndex2); float num3 = _milkMulCurrent; if (targetsForTier2.Length > 1) { for (int i = 0; i < 6; i++) { num3 = targetsForTier2[Random.Range(0, targetsForTier2.Length)]; if (Mathf.Abs(num3 - _milkMulCurrent) > 0.02f) { break; } } } else { num3 = targetsForTier2[0]; } _milkMulFrom = _milkMulCurrent; _milkMulTo = num3; _milkLerpStart = now; _milkLerpDur = Random.Range(8f, 25f); _milkNextRoll = now + Random.Range(900f, 3900f); Plugin.Logger.LogWarning((object)("[RF] Haze re-roll: tier=" + TierLetter(rundownTierIndex2) + " from=" + _milkMulFrom.ToString("F2") + " to=" + _milkMulTo.ToString("F2") + " (alpha " + (0.006f * _milkMulFrom).ToString("F4") + " → " + (0.006f * _milkMulTo).ToString("F4") + ") over=" + _milkLerpDur.ToString("F1") + "s nextRollIn=" + ((_milkNextRoll - now) / 60f).ToString("F1") + "min")); } return _milkMulCurrent; } private static int GetRundownTierIndex() { try { string activeExpeditionUniqueKey = RundownManager.ActiveExpeditionUniqueKey; if (!string.IsNullOrEmpty(activeExpeditionUniqueKey)) { foreach (char c in activeExpeditionUniqueKey) { if (c >= 'A' && c <= 'E') { return c - 65; } } } } catch { } return 4; } private static string TierLetter(int idx) { return idx switch { 0 => "A", 1 => "B", 2 => "C", 3 => "D", _ => "E", }; } private static float[] GetTargetsForTier(int tier) { float num; try { num = tier switch { 0 => Plugin.HazeTierA?.Value ?? 0.25f, 1 => Plugin.HazeTierB?.Value ?? 0.4f, 2 => Plugin.HazeTierC?.Value ?? 0.55f, 3 => Plugin.HazeTierD?.Value ?? 0.68f, _ => Plugin.HazeTierE?.Value ?? 0.78f, }; } catch { num = 0.55f; } num = Mathf.Clamp(num, 0.05f, 2f); return new float[3] { Mathf.Max(0.05f, num * 0.87f), num, Mathf.Min(2f, num * 1.13f) }; } private static Vector3 SampleInCone() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_coneRoot == (Object)null || (Object)(object)_coreLight == (Object)null) { return Vector3.zero; } float range = _coreLight.range; float range2 = ((range > 8f) ? Mathf.Min(range * 0.9f, 4f) : range); return SampleInConeFast(_coneRoot.position, _coneRoot.forward, _coneRoot.right, _coneRoot.up, range2, Mathf.Tan(_coreLight.spotAngle * 0.5f * ((float)Math.PI / 180f))); } private static Vector3 SampleInConeFast(Vector3 origin, Vector3 fwd, Vector3 right, Vector3 up, float range, float tanHA) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) float num = Random.Range(0.5f, range * 0.9f); float num2 = num * tanHA * Mathf.Sqrt(Random.value); float num3 = Random.value * (float)Math.PI * 2f; return origin + fwd * num + right * (num2 * Mathf.Cos(num3)) + up * (num2 * Mathf.Sin(num3)); } private static Transform? FindCameraAnchor(Transform t) { try { Transform val = t; int num = 32; while ((Object)(object)val != (Object)null && num-- > 0) { string name = ((Object)((Component)val).gameObject).name; if (name != null && (name.IndexOf("FPSCameraHolder", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("FPSCamera", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("FPSLookCamera", StringComparison.OrdinalIgnoreCase) >= 0)) { return val; } val = val.parent; } } catch { } return null; } private static Material? BuildBillboardMat(Texture2D? tex, Color tint) { //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown Shader val = Shader.Find("Sprites/Default"); if ((Object)(object)val == (Object)null) { val = Shader.Find("Mobile/Particles/Alpha Blended"); } if ((Object)(object)val == (Object)null) { val = Shader.Find("Particles/Standard Unlit"); } if ((Object)(object)val == (Object)null) { val = Shader.Find("Unlit/Transparent"); } if ((Object)(object)val == (Object)null) { return null; } Material val2 = new Material(val); ((Object)val2).hideFlags = (HideFlags)61; try { if ((Object)(object)tex != (Object)null) { val2.mainTexture = (Texture)(object)tex; } } catch { } try { val2.SetColor("_Color", tint); } catch { } try { val2.SetColor("_TintColor", tint); } catch { } return val2; } private static Texture2D BuildSoftCircleTex(int size) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Expected O, but got Unknown //IL_008e: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(size, size, (TextureFormat)4, false); ((Object)val).hideFlags = (HideFlags)61; ((Texture)val).wrapMode = (TextureWrapMode)1; float num = (float)(size - 1) * 0.5f; for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { float num2 = ((float)j - num) / num; float num3 = ((float)i - num) / num; float num4 = Mathf.Sqrt(num2 * num2 + num3 * num3); float num5 = Mathf.Clamp01(1f - num4); float num6 = num5 * num5 * num5 * (num5 * (num5 * 6f - 15f) + 10f); val.SetPixel(j, i, new Color(1f, 1f, 1f, num6)); } } val.Apply(); return val; } private static Texture2D BuildStarTex(int size) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Expected O, but got Unknown //IL_0102: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(size, size, (TextureFormat)4, false); ((Object)val).hideFlags = (HideFlags)61; ((Texture)val).wrapMode = (TextureWrapMode)1; float num = (float)(size - 1) * 0.5f; for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { float num2 = ((float)j - num) / num; float num3 = ((float)i - num) / num; float num4 = Mathf.Sqrt(num2 * num2 + num3 * num3); float num5 = Mathf.Clamp01(1f - num4 * 2.5f); num5 = num5 * num5 * num5 * (num5 * (num5 * 6f - 15f) + 10f); float num6 = Mathf.Abs(num2); float num7 = Mathf.Abs(num3); float num8 = Mathf.Exp((0f - num6) * 12f) * Mathf.Clamp01(1f - num7) * 0.55f; float num9 = Mathf.Exp((0f - num7) * 12f) * Mathf.Clamp01(1f - num6) * 0.55f; float num10 = Mathf.Clamp01(num5 + num8 + num9); val.SetPixel(j, i, new Color(1f, 1f, 1f, num10)); } } val.Apply(); return val; } } [HarmonyPatch(typeof(GearManager), "LoadOfflineGearDatas")] internal static class Patch_GearManager { [HarmonyPrefix] private static void Prefix() { if (!Plugin.Enabled.Value || Plugin.Mode.Value == FlashLightMode.VANILLA) { return; } FlashlightSettingsDataBlock[] array = Il2CppArrayBase.op_Implicit(GameDataBlockBase.Wrapper.Blocks.ToArray()); RangedPresets.ByPID.Clear(); FlashlightSettingsDataBlock[] array2 = array; foreach (FlashlightSettingsDataBlock val in array2) { if (val == null) { continue; } uint persistentID = ((GameDataBlockBase)(object)val).persistentID; if (persistentID == 1 || persistentID == 4) { val.angle = 0f; val.intensity = 0f; val.range = 0f; continue; } RangedPresets.Preset value = RangedPresets.Classify(((GameDataBlockBase)(object)val).name ?? $"PID_{persistentID}", val.angle, val.range); RangedPresets.ByPID[persistentID] = value; float angle = Mathf.Max(0f, value.CoreAngle - Plugin.Step1.Value); float num = value.CoreIntensity; if (value.Name == RangedPresets.WideRange.Name) { num += 0.01f; } val.angle = angle; val.intensity = num; val.range = value.CoreRange; } } } [HarmonyPatch(typeof(Light), "set_type")] internal static class Patch_LightType { [HarmonyPostfix] private static void Postfix(Light __instance, LightType value) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) if (Plugin.Enabled.Value && (int)value == 0 && !LightSandwich.IsRFChild(((Object)((Component)__instance).gameObject).name)) { if (LightSandwich.IsHelmetLight(((Component)__instance).transform)) { LightSandwich.ApplyHelmetInPlace(__instance); } else if (!LightSandwich.ClassifyOwner(((Component)__instance).transform).isMeleeOrTool) { LightSandwich.ApplySandwich(__instance); } } } } [HarmonyPatch(typeof(ItemEquippable), "SetAttachedFlashlightEnabled")] internal static class Patch_EquippableSetFlashlight { [HarmonyPostfix] private static void Postfix(ItemEquippable __instance, bool mode) { if (!Plugin.Enabled.Value || (Object)(object)__instance == (Object)null || !LightUpdater.IsLocalItem(__instance)) { return; } Light lt = __instance.m_lt; if (!((Object)(object)lt == (Object)null)) { if ((Object)(object)((Component)lt).transform.Find("RF_L1") == (Object)null) { LightSandwich.ApplySandwich(lt, __instance); } if ((Object)(object)((Il2CppObjectBase)__instance).TryCast() != (Object)null) { LightSandwich.SuppressRangedSiblings(lt, __instance); LightSandwich.EnsureRangedSettings(lt, __instance, forceResolve: false); } else if ((Object)(object)((Il2CppObjectBase)__instance).TryCast() != (Object)null) { LightSandwich.EnsurePickableSettings(lt); } lt.innerSpotAngle = 0f; if ((Object)(object)((Component)lt).transform.Find("RF_L1") != (Object)null) { lt.cullingMask = 0; } } } } [HarmonyPatch(typeof(Behaviour), "set_enabled")] internal static class Patch_BehaviourEnabled { [HarmonyPostfix] private static void Postfix(Behaviour __instance, bool value) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Invalid comparison between Unknown and I4 if (!Plugin.Enabled.Value) { return; } Transform transform = ((Component)__instance).transform; if (LightSandwich.IsRFChild(((Object)((Component)__instance).gameObject).name)) { return; } Light val = ((Il2CppObjectBase)__instance).TryCast(); if (!((Object)(object)val == (Object)null) && ((int)val.type == 0 || (int)val.type == 2) && value && (Object)(object)transform.Find("RF_L1") == (Object)null) { if (LightSandwich.IsHelmetLight(transform)) { LightSandwich.ApplyHelmetInPlace(val); } else if (!LightSandwich.ClassifyOwner(transform).isMeleeOrTool) { LightSandwich.ApplySandwich(val); } } } } [HarmonyPatch(typeof(Light), "set_color")] internal static class Patch_LightColor { [HarmonyPostfix] private static void Postfix(Light __instance, Color value) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) Transform transform = ((Component)__instance).transform; if (!LightSandwich.IsUnmanaged(transform, ((Object)((Component)__instance).gameObject).name)) { LightSandwich.SyncColor(transform, value); } } } [HarmonyPatch(typeof(Light), "set_intensity")] internal static class Patch_LightIntensity { [HarmonyPostfix] private static void Postfix(Light __instance, float value) { //IL_003b: 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_0049: Invalid comparison between Unknown and I4 if (!Plugin.Enabled.Value) { return; } Transform transform = ((Component)__instance).transform; if (LightSandwich.IsRFChild(((Object)((Component)__instance).gameObject).name)) { return; } if ((Object)(object)transform.Find("RF_L1") == (Object)null) { if ((int)__instance.type == 0 || (int)__instance.type == 2) { if (LightSandwich.IsHelmetLight(((Component)__instance).transform)) { LightSandwich.ApplyHelmetInPlace(__instance); } else if (!LightSandwich.ClassifyOwner(((Component)__instance).transform).isMeleeOrTool) { LightSandwich.ApplySandwich(__instance); } } } else { LightSandwich.SyncIntensity(transform, value); } } } [HarmonyPatch(typeof(Light), "set_range")] internal static class Patch_LightRange { [HarmonyPostfix] private static void Postfix(Light __instance, float value) { Transform transform = ((Component)__instance).transform; if (!LightSandwich.IsUnmanaged(transform, ((Object)((Component)__instance).gameObject).name)) { LightSandwich.SyncRange(transform, value); } } } [HarmonyPatch(typeof(Light), "set_spotAngle")] internal static class Patch_LightAngle { [HarmonyPostfix] private static void Postfix(Light __instance, float value) { Transform transform = ((Component)__instance).transform; string name = ((Object)((Component)__instance).gameObject).name; if (LightSandwich.IsRFChild(name)) { return; } if ((Object)(object)transform.Find("RF_L1") != (Object)null) { if (__instance.innerSpotAngle != 0f) { __instance.innerSpotAngle = 0f; } if (LightSandwich.GetManagedKind(__instance) == LightSandwich.ManagedKind.Ranged) { if (value != 0f) { __instance.spotAngle = 0f; } return; } } if (!LightSandwich.IsUnmanaged(transform, name)) { LightSandwich.SyncAngle(transform, value); } } } [HarmonyPatch(typeof(Light), "set_innerSpotAngle")] internal static class Patch_LightInnerAngle { [HarmonyPrefix] private static bool Prefix(Light __instance, ref float value) { if (LightSandwich.IsRFChild(((Object)((Component)__instance).gameObject).name)) { return true; } if ((Object)(object)((Component)__instance).transform.Find("RF_L1") == (Object)null) { return true; } value = 0f; return true; } } [HarmonyPatch(typeof(Light), "set_cullingMask")] internal static class Patch_LightCullingMask { [ThreadStatic] private static bool _inPatch; [HarmonyPrefix] private static bool Prefix(Light __instance, ref int value) { //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Invalid comparison between Unknown and I4 if (LightSandwich.IsRFChild(((Object)((Component)__instance).gameObject).name)) { return true; } if ((Object)(object)((Component)__instance).transform.Find("RF_L1") != (Object)null) { value = 0; if (!_inPatch) { _inPatch = true; try { Il2CppArrayBase componentsInChildren = ((Component)__instance).gameObject.GetComponentsInChildren(true); if (componentsInChildren != null) { foreach (Light item in componentsInChildren) { if (!((Object)(object)item == (Object)null) && !((Object)(object)item == (Object)(object)__instance) && !LightSandwich.IsRFChild(((Object)((Component)item).gameObject).name) && ((int)item.type == 0 || (int)item.type == 2) && item.cullingMask != 0) { item.cullingMask = 0; } } } } catch { } finally { _inPatch = false; } } } return true; } } internal static class Patch_ItemWield { internal static ItemEquippable? CurrentWieldedItem; } [HarmonyPatch(typeof(ItemEquippable), "OnWield")] internal static class Patch_OnWield { [HarmonyPrefix] private static void Prefix(ItemEquippable __instance) { if ((Object)(object)__instance == (Object)null || !LightUpdater.IsLocalItem(__instance)) { return; } Patch_ItemWield.CurrentWieldedItem = __instance; LightUpdater._pendingWieldItem = __instance; LightUpdater.OnWieldedChanged(__instance); try { if ((Object)(object)((Il2CppObjectBase)__instance).TryCast() != (Object)null || (Object)(object)((Il2CppObjectBase)__instance).TryCast() != (Object)null) { LightUpdater._lastObservedWasGun = true; } LightUpdater.EndSwap(); } catch { } } } [HarmonyPatch(typeof(ItemEquippable), "OnUnWield")] internal static class Patch_OnUnWield { [HarmonyPostfix] private static void Postfix(ItemEquippable __instance) { if ((Object)(object)__instance == (Object)null || !LightUpdater.IsLocalItem(__instance)) { return; } LightUpdater.RegisterItem(__instance); try { if ((Object)(object)((Il2CppObjectBase)__instance).TryCast() != (Object)null || (Object)(object)((Il2CppObjectBase)__instance).TryCast() != (Object)null) { Light lt = __instance.m_lt; if ((Object)(object)lt != (Object)null && (Object)(object)((Component)lt).transform.Find("RF_L1") != (Object)null) { LightSandwich.SyncEnabled(((Component)lt).transform, v: false); } } LightUpdater.BeginSwap(); } catch { } if ((Object)(object)Patch_ItemWield.CurrentWieldedItem == (Object)(object)__instance) { Patch_ItemWield.CurrentWieldedItem = null; } if ((Object)(object)LightUpdater._pendingWieldItem == (Object)(object)__instance) { LightUpdater._pendingWieldItem = null; } } } [HarmonyPatch(typeof(EnemyAgent), "Setup")] internal static class Patch_EnemyAgentSetup_LayerProbe { [HarmonyPostfix] private static void Postfix(EnemyAgent __instance) { try { FlashlightEnemyDetection.LogEnemyLayer(__instance); } catch { } try { FlashlightEnemyDetection.RegisterAgent(__instance); } catch { } } } [HarmonyPatch(typeof(EnemyAgent), "Disable")] internal static class Patch_EnemyAgentDisable { [HarmonyPostfix] private static void Postfix(EnemyAgent __instance) { try { FlashlightEnemyDetection.UnregisterAgent(__instance); } catch { } } } internal static class Patch_HibernationDetectionUpdate { [HarmonyPostfix] private static void Postfix(EnemyDetection __instance, ref bool __result, ref AgentTarget target) { //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Invalid comparison between Unknown and I4 try { if ((Object)(object)__instance == (Object)null) { return; } EnemyAgent val = null; try { EnemyAI ai = __instance.m_ai; val = ((ai != null) ? ai.m_enemyAgent : null); } catch { } if ((Object)(object)val == (Object)null) { try { val = ((Component)__instance).GetComponentInParent(); } catch { return; } } if ((Object)(object)val == (Object)null) { return; } int instanceID; try { instanceID = ((Object)val).GetInstanceID(); } catch { return; } EnemyLocomotion locomotion = val.Locomotion; ES_Hibernate val2 = ((locomotion != null) ? locomotion.Hibernate : null); if (val2 == null || Plugin._hibSetDetectionCurrent == null) { return; } float num = 1f; if (Plugin._hibGetDetectionTarget != null) { try { num = Plugin._hibGetDetectionTarget(val2); } catch { } } float value; if ((int)((AgentAI)val.AI).Mode == 1) { Plugin._triggeredEnemies.Remove(instanceID); Plugin._headlightTriggeredEnemies.Remove(instanceID); Plugin._customBuildup.Remove(instanceID); Plugin._customDetectionCurrent.Remove(instanceID); } else if (Plugin._triggeredEnemies.Contains(instanceID)) { if (Plugin._headlightTriggeredEnemies.Contains(instanceID)) { Plugin.RetryWakeupPinchIfDue(val, instanceID); return; } try { Plugin._hibSetDetectionCurrent(val2, num * 1.05f); } catch { } if (Plugin._hibSetHeartbeatActive != null) { try { Plugin._hibSetHeartbeatActive(val2, arg2: true); } catch { } } AgentTarget val3 = Plugin.TryBuildFlashlightTarget(val, 1f); if (val3 != null) { target = val3; __instance.m_biggestDetectionTarget = val3; __instance.m_biggestDetectionBuildup = 1f; __result = true; } Plugin.RetryWakeupPinchIfDue(val, instanceID); } else if (Plugin._customDetectionCurrent.TryGetValue(instanceID, out value) && !(value <= 0f)) { try { Plugin._hibSetDetectionCurrent(val2, Mathf.Min(value, num)); } catch { } float num2 = Mathf.Clamp01(value / Mathf.Max(num, 0.001f)); AgentTarget val4 = Plugin.TryBuildFlashlightTarget(val, num2); if (val4 != null) { target = val4; __instance.m_biggestDetectionTarget = val4; __instance.m_biggestDetectionBuildup = num2; } } } catch { } } } internal static class FogBeamEffect { private const int N = 5; private const float RadiusOverlap = 0.5f; private const float NearDensityDefault = 0.0025f; private const float FarDensityDefault = 0.0005f; private static readonly Color RadianceColor = new Color(0.08f, 0.07f, 0.06f); private const float RadianceIntensity = 1f; private const float MaxDensity = 0.0086f; private static readonly FogSphereAllocator?[] _allocs = (FogSphereAllocator?[])(object)new FogSphereAllocator[5]; private static bool _allocated = false; private static bool _loggedTypeError = false; private static bool _loggedAllocWarn = false; internal static void Update(Transform? coneRoot, Light? coreLight, bool lightIsOn) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_007d: 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_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.FogBeamEnabled.Value) { if (_allocated) { Deallocate(); } } else if ((Object)(object)coneRoot != (Object)null && ((Object)coneRoot).name.IndexOf("HelmetSynth", StringComparison.Ordinal) >= 0) { if (_allocated) { ZeroAllDensities(); } } else { if (!_allocated && !TryAllocateAll()) { return; } if (!lightIsOn || (Object)(object)coneRoot == (Object)null || (Object)(object)coreLight == (Object)null) { ZeroAllDensities(); return; } Vector3 position = coneRoot.position; Vector3 forward = coneRoot.forward; float range = coreLight.range; float num = Mathf.Tan(Mathf.Min(coreLight.spotAngle * 0.5f * ((float)Math.PI / 180f), 1.5358897f)); float num2 = Mathf.Max(0f, Plugin.HazeStrength.Value); float milkMulCurrent = DustEffect._milkMulCurrent; for (int i = 0; i < 5; i++) { FogSphereAllocator val = _allocs[i]; if (val != null) { float num3 = ((float)i + 0.5f) / 5f * 0.5f; float num4 = range * num3; float num5 = num4 * num * 0.5f; if (num5 < 0.1f) { num5 = 0.1f; } float num6 = ((!(num3 <= 0.25f)) ? Mathf.Max(0f, 0.35f * (1f - (num3 - 0.25f) / 0.25f)) : 1f); float num7 = num3 / 0.5f; float num8 = Mathf.Max(0f, Plugin.FogBeamNearDensity?.Value ?? 0.0025f); float num9 = Mathf.Max(0f, Plugin.FogBeamFarDensity?.Value ?? 0.0005f); float num10 = Mathf.Lerp(num8, num9, num7) * num2 * milkMulCurrent * num6; if (num10 > 0.0086f) { num10 = 0.0086f; } Vector3 val2 = position + forward * num4; float num11 = val2.y - position.y; if (num11 < 0.1f) { num10 *= Mathf.Clamp01((num11 + 0.4f) / 0.5f); } try { val.SetPositionRange(val2, num5); val.SetDensity(num10); val.SetRadiance(RadianceColor, 1f); } catch { } } } } } internal static void Deallocate() { for (int i = 0; i < 5; i++) { try { FogSphereAllocator? obj = _allocs[i]; if (obj != null) { obj.Deallocate(); } } catch { } _allocs[i] = null; } _allocated = false; _loggedAllocWarn = false; } private static void ZeroAllDensities() { if (!_allocated) { return; } for (int i = 0; i < 5; i++) { try { FogSphereAllocator? obj = _allocs[i]; if (obj != null) { obj.SetDensity(0f); } } catch { } } } private static bool TryAllocateAll() { //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Expected O, but got Unknown try { if ((Object)(object)PreLitVolume.Current == (Object)null) { return false; } } catch (Exception ex) { if (!_loggedTypeError) { _loggedTypeError = true; Plugin.Logger.LogWarning((object)("[RF] FogBeam: PreLitVolume.Current threw — " + ex.GetType().Name + ": " + ex.Message + " → volumetric fog disabled for this session.")); } return false; } int num = 0; for (int i = 0; i < 5; i++) { if (_allocs[i] != null) { num++; continue; } try { FogSphereAllocator val = new FogSphereAllocator(); if (val.TryAllocate()) { val.SetDensity(0f); _allocs[i] = val; num++; } } catch (Exception ex2) { if (!_loggedTypeError) { _loggedTypeError = true; Plugin.Logger.LogWarning((object)("[RF] FogBeam: FogSphereAllocator threw — " + ex2.GetType().Name + ": " + ex2.Message + " → volumetric fog disabled for this session.")); } return false; } } if (num == 5) { _allocated = true; Plugin.Logger.LogInfo((object)("[RF] FogBeam: allocated " + 5 + " FogSpheres (global limit = 32).")); return true; } if (num > 0 && !_loggedAllocWarn) { _loggedAllocWarn = true; Plugin.Logger.LogWarning((object)("[RF] FogBeam: only got " + num + "/" + 5 + " FogSphere slots (global cap hit by FogRepeller/enemies?). Using partial chain.")); _allocated = true; return true; } return false; } } public class LightUpdater : MonoBehaviour { internal static readonly List _knownItems = new List(); private const float ScanIntervalSeconds = 3f; private float _nextScan; internal static LightUpdater? Instance; private static bool _preCullAttached = false; private static GameObject? _helmetSynthGO; private static bool _helmetSynthBuilt = false; private static GameObject? _eyeFillGO; private static bool _eyeFillBuilt = false; private static GameObject? _cameraBeamGO; private static bool _cameraBeamBuilt = false; internal static bool GunFlashlightActive = false; internal static bool LastFlashlightState = false; internal static float LastWieldChangeTime = -1000f; internal static ItemEquippable? _pendingWieldItem; internal static bool _lastObservedWasGun = false; internal static bool _swapInProgress = false; private static float _swapStartedAt = 0f; private const float SwapMaxSeconds = 0.8f; private static float _holdDarkUntil = 0f; private static float _lastWieldedDiagAt = 0f; private static float _lastStateDiagAt = 0f; private static float _lastLoopTraceAt = 0f; private const float MinDarkSeconds = 0.15f; private static ItemEquippable? _iconLastItem; private static bool _iconLastState = false; private static bool _inDriveIcon = false; private static readonly HashSet _boneMissLogged = new HashSet(); private static readonly Dictionary _rfCoreBaselineIntensity = new Dictionary(); private static readonly List _rfCoreRefs = new List(); private float _rfNextBurstTime; private bool _rfBurstActive; private int _rfBlinksLeft; private float _rfNextBlinkTime; private bool _rfBlinkOn = true; private float _horNextBurstTime; private bool _horBurstActive; private int _horBlinksLeft; private float _horNextBlinkTime; private bool _horBlinkOn = true; private int _horLongPauseAt = -1; private float _boNextTriggerTime; private bool _boActive; private float _boStartTime; private float _boDimEnd; private float _boHoldEnd; private float _boRecoverEnd; private float _boDimTarget = 0.4f; private float _stNextTriggerTime; private bool _stActive; private float _stStartTime; private float _stEndTime; private float _stSpeed = 30f; private float _stAmplitude = 0.65f; private float _stSeed; private float _rsNextTriggerTime; private int _rsPhase = -1; private float _rsPhaseEnd; private float _rsRecoverEnd; private float _rsRecoverStart; private float _rsStrikeLevel = 0.4f; public LightUpdater(IntPtr ptr) : base(ptr) { } internal static void RegisterItem(ItemEquippable? it) { if ((Object)(object)it == (Object)null || !IsLocalItem(it)) { return; } for (int num = _knownItems.Count - 1; num >= 0; num--) { try { ItemEquippable val = _knownItems[num]; if ((Object)(object)val == (Object)null) { _knownItems.RemoveAt(num); } else if (!IsLocalItem(val)) { _knownItems.RemoveAt(num); } else if ((Object)(object)val == (Object)(object)it) { return; } } catch { _knownItems.RemoveAt(num); } } _knownItems.Add(it); } internal static void ClearKnownItems() { _knownItems.Clear(); } internal static bool IsLocalItem(ItemEquippable? it) { if ((Object)(object)it == (Object)null) { return false; } try { PlayerAgent owner = ((Item)it).Owner; if ((Object)(object)owner != (Object)null) { return ((Agent)owner).IsLocallyOwned; } } catch { } try { if (it.IsFirstPerson) { return true; } } catch { } return false; } private static ItemEquippable? GetLocalInventoryWieldedItem() { try { if (!PlayerManager.HasLocalPlayerAgent()) { return null; } PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent(); if ((Object)(object)localPlayerAgent == (Object)null) { return null; } try { PlayerInventoryBase inventory = localPlayerAgent.Inventory; if ((Object)(object)inventory != (Object)null && (Object)(object)inventory.WieldedItem != (Object)null) { return inventory.WieldedItem; } } catch { } try { FirstPersonItemHolder fPItemHolder = localPlayerAgent.FPItemHolder; if ((Object)(object)fPItemHolder != (Object)null && (Object)(object)fPItemHolder.WieldedItem != (Object)null) { return fPItemHolder.WieldedItem; } } catch { } } catch { } return null; } private static void SeedLocalWieldedItemFromInventory() { ItemEquippable localInventoryWieldedItem = GetLocalInventoryWieldedItem(); if ((Object)(object)localInventoryWieldedItem == (Object)null || !IsLocalItem(localInventoryWieldedItem)) { return; } RegisterItem(localInventoryWieldedItem); if ((Object)(object)Patch_ItemWield.CurrentWieldedItem == (Object)(object)localInventoryWieldedItem) { return; } Patch_ItemWield.CurrentWieldedItem = localInventoryWieldedItem; _pendingWieldItem = localInventoryWieldedItem; OnWieldedChanged(localInventoryWieldedItem); try { _lastObservedWasGun = (Object)(object)((Il2CppObjectBase)localInventoryWieldedItem).TryCast() != (Object)null || (Object)(object)((Il2CppObjectBase)localInventoryWieldedItem).TryCast() != (Object)null; } catch { } } public void Awake() { Instance = this; } internal static void SetHelmetSynthActive(bool active) { if ((Object)(object)_helmetSynthGO != (Object)null && _helmetSynthGO.activeSelf != active) { _helmetSynthGO.SetActive(active); } } internal static void BeginSwap() { bool swapInProgress = _swapInProgress; _swapInProgress = true; _swapStartedAt = Time.unscaledTime; if (!swapInProgress) { _holdDarkUntil = Time.unscaledTime + 0.15f; } } internal static void EndSwap() { _swapInProgress = false; } internal static void DriveIcon(ItemEquippable? item, bool state) { if (_inDriveIcon || (Object)(object)item == (Object)null || ((Object)(object)item == (Object)(object)_iconLastItem && state == _iconLastState)) { return; } _iconLastItem = item; _iconLastState = state; _inDriveIcon = true; try { item.SetAttachedFlashlightEnabled(state); } catch { } finally { _inDriveIcon = false; } } internal static void ResetIconCache() { _iconLastItem = null; _iconLastState = false; } internal void EnforceRFState() { //IL_0ec9: Unknown result type (might be due to invalid IL or missing references) //IL_0ed0: Unknown result type (might be due to invalid IL or missing references) //IL_08f4: Unknown result type (might be due to invalid IL or missing references) //IL_08f9: Unknown result type (might be due to invalid IL or missing references) //IL_0902: Unknown result type (might be due to invalid IL or missing references) //IL_0907: Unknown result type (might be due to invalid IL or missing references) //IL_0bb7: Unknown result type (might be due to invalid IL or missing references) //IL_0bbc: Unknown result type (might be due to invalid IL or missing references) try { SeedLocalWieldedItemFromInventory(); float unscaledTime = Time.unscaledTime; if (_swapInProgress && unscaledTime - _swapStartedAt > 0.8f) { _swapInProgress = false; } if (_swapInProgress || unscaledTime < _holdDarkUntil) { if (Time.unscaledTime - _lastStateDiagAt > 10f) { _lastStateDiagAt = Time.unscaledTime; Plugin.Logger.LogInfo((object)("[RF] state FORCE_DARK swapInProgress=" + _swapInProgress + " holdUntil-now=" + (_holdDarkUntil - unscaledTime).ToString("F2"))); } if ((Object)(object)_helmetSynthGO != (Object)null && _helmetSynthGO.activeSelf) { _helmetSynthGO.SetActive(false); } foreach (ItemEquippable knownItem in _knownItems) { if ((Object)(object)knownItem == (Object)null || !IsLocalItem(knownItem)) { continue; } Light val = null; try { val = knownItem.m_lt; } catch { } if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).transform.Find("RF_L1") == (Object)null)) { Transform val2 = ((Component)val).transform.Find("RF_Core"); if ((Object)(object)val2 != (Object)null && ((Component)val2).gameObject.activeSelf) { LightSandwich.SyncEnabled(((Component)val).transform, v: false); } } } GunFlashlightActive = false; ResetIconCache(); return; } ItemEquippable val3 = null; bool flag = false; foreach (ItemEquippable knownItem2 in _knownItems) { if ((Object)(object)knownItem2 == (Object)null || !IsLocalItem(knownItem2)) { continue; } bool isWielded; try { isWielded = knownItem2.m_isWielded; } catch { continue; } if (isWielded) { val3 = knownItem2; try { flag = (Object)(object)((Il2CppObjectBase)knownItem2).TryCast() != (Object)null || (Object)(object)((Il2CppObjectBase)knownItem2).TryCast() != (Object)null; } catch { flag = false; } break; } } if ((Object)(object)val3 == (Object)null && (Object)(object)_pendingWieldItem != (Object)null) { val3 = _pendingWieldItem; try { flag = (Object)(object)((Il2CppObjectBase)val3).TryCast() != (Object)null || (Object)(object)((Il2CppObjectBase)val3).TryCast() != (Object)null; } catch { flag = false; } } else if ((Object)(object)val3 != (Object)null && (Object)(object)val3 == (Object)(object)_pendingWieldItem) { _pendingWieldItem = null; } if ((Object)(object)val3 != (Object)null && (Object)(object)Patch_ItemWield.CurrentWieldedItem != (Object)(object)val3) { Patch_ItemWield.CurrentWieldedItem = val3; } if ((Object)(object)val3 != (Object)null) { _lastObservedWasGun = flag; } bool num = (Object)(object)val3 == (Object)null && (Object)(object)_pendingWieldItem == (Object)null && _lastObservedWasGun; GunFlashlightActive = flag && LastFlashlightState; bool flag2 = !num && !flag && LastFlashlightState; if (Time.unscaledTime - _lastStateDiagAt > 10f) { _lastStateDiagAt = Time.unscaledTime; try { StringBuilder stringBuilder = new StringBuilder(256); stringBuilder.Append("[RF] state LFS=").Append(LastFlashlightState).Append(" trueW=") .Append(((Object)(object)val3 != (Object)null && (Object)(object)((Component)val3).gameObject != (Object)null) ? ((Object)((Component)val3).gameObject).name : "null") .Append(" pendW=") .Append(((Object)(object)_pendingWieldItem != (Object)null && (Object)(object)((Component)_pendingWieldItem).gameObject != (Object)null) ? ((Object)((Component)_pendingWieldItem).gameObject).name : "null") .Append(" cw=") .Append(((Object)(object)Patch_ItemWield.CurrentWieldedItem != (Object)null && (Object)(object)((Component)Patch_ItemWield.CurrentWieldedItem).gameObject != (Object)null) ? ((Object)((Component)Patch_ItemWield.CurrentWieldedItem).gameObject).name : "null") .Append(" swapInProgress=") .Append(_swapInProgress) .Append(" known=["); bool flag3 = true; foreach (ItemEquippable knownItem3 in _knownItems) { if (!((Object)(object)knownItem3 == (Object)null)) { if (!flag3) { stringBuilder.Append(','); } flag3 = false; string value = "?"; try { value = (((Object)(object)((Component)knownItem3).gameObject != (Object)null) ? ((Object)((Component)knownItem3).gameObject).name : "?"); } catch { } bool value2 = false; try { value2 = knownItem3.m_isWielded; } catch { } bool value3 = false; try { value3 = (Object)(object)knownItem3.m_lt != (Object)null; } catch { } bool value4 = false; try { value4 = (Object)(object)knownItem3.m_lt != (Object)null && (Object)(object)((Component)knownItem3.m_lt).transform.Find("RF_L1") != (Object)null; } catch { } stringBuilder.Append(value).Append("(w=").Append(value2) .Append(",lt=") .Append(value3) .Append(",L1=") .Append(value4) .Append(")"); } } stringBuilder.Append("]"); Plugin.Logger.LogInfo((object)stringBuilder.ToString()); } catch { } } if ((Object)(object)_helmetSynthGO != (Object)null && _helmetSynthGO.activeSelf != flag2) { _helmetSynthGO.SetActive(flag2); } bool flag4 = Time.unscaledTime - _lastLoopTraceAt > 10f; if (flag4) { _lastLoopTraceAt = Time.unscaledTime; } foreach (ItemEquippable knownItem4 in _knownItems) { if ((Object)(object)knownItem4 == (Object)null) { if (flag4) { Plugin.Logger.LogInfo((object)"[RF] loop: it=null skip"); } continue; } if (!IsLocalItem(knownItem4)) { if (flag4) { Plugin.Logger.LogInfo((object)"[RF] loop: non-local skip"); } continue; } string text = "?"; try { text = (((Object)(object)((Component)knownItem4).gameObject != (Object)null) ? ((Object)((Component)knownItem4).gameObject).name : "?"); } catch { } bool flag5; try { flag5 = (Object)(object)((Il2CppObjectBase)knownItem4).TryCast() != (Object)null || (Object)(object)((Il2CppObjectBase)knownItem4).TryCast() != (Object)null; } catch { if (flag4) { Plugin.Logger.LogInfo((object)("[RF] loop " + text + ": cast threw, skip")); } continue; } if (!flag5) { if (flag4) { Plugin.Logger.LogInfo((object)("[RF] loop " + text + ": !isGunOrPick skip")); } continue; } Light val4 = null; try { val4 = knownItem4.m_lt; } catch { } if ((Object)(object)val4 == (Object)null) { if (flag4) { Plugin.Logger.LogInfo((object)("[RF] loop " + text + ": lt=null skip")); } continue; } bool flag6 = (Object)(object)knownItem4 == (Object)(object)val3; bool flag7 = flag6 && LastFlashlightState; if (!flag6 && (Object)(object)val3 != (Object)null) { Light val5 = null; try { val5 = val3.m_lt; } catch { } if ((Object)(object)val5 != (Object)null && ((Object)val5).GetInstanceID() == ((Object)val4).GetInstanceID()) { if (flag4) { Plugin.Logger.LogInfo((object)("[RF] loop " + text + ": shares m_lt with wielded — skip")); } continue; } } if (flag4) { Plugin.Logger.LogInfo((object)("[RF] loop " + text + ": isWielded=" + flag6 + " shouldBeEnabled=" + flag7 + " hasL1=" + ((Object)(object)((Component)val4).transform.Find("RF_L1") != (Object)null))); } if ((Object)(object)((Component)val4).transform.Find("RF_L1") == (Object)null) { if (!flag6) { continue; } LightSandwich.ApplySandwich(val4, knownItem4); } if (flag6) { if (flag7) { Transform val6 = ((Component)val4).transform; GameObject val7 = null; try { val7 = ((Component)knownItem4).gameObject; } catch { } int num2 = 16; while ((Object)(object)val6 != (Object)null && num2-- > 0) { if (!((Component)val6).gameObject.activeSelf) { ((Component)val6).gameObject.SetActive(true); } if ((Object)(object)val7 != (Object)null && (Object)(object)((Component)val6).gameObject == (Object)(object)val7) { break; } val6 = val6.parent; } } LightSandwich.SyncEnabled(((Component)val4).transform, flag7); if (!flag7 || !(Time.unscaledTime - _lastWieldedDiagAt > 10f)) { continue; } _lastWieldedDiagAt = Time.unscaledTime; int num3 = 0; try { num3 = 1; Transform val8 = ((Component)val4).transform.Find("RF_Core"); num3 = 2; Transform val9 = ((Component)val4).transform.Find("RF_L1"); num3 = 3; Transform val10 = ((Component)val4).transform.Find("RF_L2"); num3 = 4; bool activeInHierarchy = ((Component)val4).gameObject.activeInHierarchy; num3 = 5; bool enabled = ((Behaviour)val4).enabled; num3 = 6; Vector3 position = ((Component)val4).transform.position; Vector3 forward = ((Component)val4).transform.forward; int instanceID = ((Object)val4).GetInstanceID(); string text2 = "[RF] wielded=" + text + " ltID=" + instanceID + " ltGO_actHier=" + activeInHierarchy + " ltEnabled=" + enabled + " ltPos=(" + position.x.ToString("F1") + "," + position.y.ToString("F1") + "," + position.z.ToString("F1") + ") ltFwd=(" + forward.x.ToString("F2") + "," + forward.y.ToString("F2") + "," + forward.z.ToString("F2") + ")"; num3 = 7; string text3 = "?"; if (LightSandwich._lightPreset.TryGetValue(instanceID, out var value5)) { text3 = value5.Name ?? "Unnamed"; } text2 = text2 + " preset=\"" + text3 + "\""; if ((Object)(object)val8 != (Object)null) { Light component = ((Component)val8).GetComponent(); num3 = 8; text2 = text2 + " | RF_Core: enabled=" + (((Object)(object)component != (Object)null) ? ((Behaviour)component).enabled.ToString() : "noL") + " int=" + (((Object)(object)component != (Object)null) ? component.intensity.ToString("F2") : "?") + " rng=" + (((Object)(object)component != (Object)null) ? component.range.ToString("F1") : "?") + " ang=" + (((Object)(object)component != (Object)null) ? component.spotAngle.ToString("F0") : "?") + " cull=" + (((Object)(object)component != (Object)null) ? component.cullingMask.ToString() : "?") + " cookie=" + (((Object)(object)component != (Object)null && (Object)(object)component.cookie != (Object)null) ? "Y" : "N"); if ((Object)(object)component != (Object)null) { Color color = component.color; text2 = text2 + " color=(" + color.r.ToString("F2") + "," + color.g.ToString("F2") + "," + color.b.ToString("F2") + ")"; } num3 = 9; } if ((Object)(object)val9 != (Object)null) { Light component2 = ((Component)val9).GetComponent(); num3 = 10; text2 = text2 + " | L1: actHier=" + ((Component)val9).gameObject.activeInHierarchy + " enabled=" + (((Object)(object)component2 != (Object)null) ? ((Behaviour)component2).enabled.ToString() : "noL") + " int=" + (((Object)(object)component2 != (Object)null) ? component2.intensity.ToString("F2") : "?"); } if ((Object)(object)val10 != (Object)null) { Light component3 = ((Component)val10).GetComponent(); num3 = 11; text2 = text2 + " | L2: actHier=" + ((Component)val10).gameObject.activeInHierarchy + " enabled=" + (((Object)(object)component3 != (Object)null) ? ((Behaviour)component3).enabled.ToString() : "noL") + " int=" + (((Object)(object)component3 != (Object)null) ? component3.intensity.ToString("F2") : "?"); } num3 = 12; Plugin.Logger.LogInfo((object)text2); } catch (Exception ex) { Plugin.Logger.LogWarning((object)("[RF] wielded diag THREW at step=" + num3 + " ex=" + ex.GetType().Name + " msg=" + ex.Message)); } continue; } Transform val11 = ((Component)val4).transform.Find("RF_Core"); if (!((Object)(object)val11 == (Object)null)) { Light component4 = ((Component)val11).GetComponent(); if ((((Component)val11).gameObject.activeSelf && ((Object)(object)component4 == (Object)null || ((Behaviour)component4).enabled)) != flag7) { LightSandwich.SyncEnabled(((Component)val4).transform, flag7); } } } try { if (Plugin.AttachLightToWeaponBone != null && Plugin.AttachLightToWeaponBone.Value && (Object)(object)val3 != (Object)null && flag && (Object)(object)((Il2CppObjectBase)val3).TryCast() != (Object)null) { Light val12 = null; try { val12 = val3.m_lt; } catch { } if ((Object)(object)val12 != (Object)null) { Transform val13 = WeaponBoneTracker.Resolve(val3); if ((Object)(object)val13 != (Object)null) { ((Component)val12).transform.SetPositionAndRotation(val13.position, val13.rotation); } else { LogBoneFollowMiss(val3, "no bone found"); } } else { LogBoneFollowMiss(val3, "m_lt is null"); } } } catch (Exception ex2) { try { Plugin.Logger.LogWarning((object)("[RF] bone-follow threw: " + ex2.GetType().Name + " " + ex2.Message)); } catch { } } if ((Object)(object)val3 != (Object)null) { DriveIcon(val3, LastFlashlightState); } } catch { } } private static void LogBoneFollowMiss(ItemEquippable owner, string reason) { try { long item = ((long)((Object)owner).GetInstanceID() << 4) | (reason.Length & 0xF); if (_boneMissLogged.Add(item)) { string text = (((Object)(object)((Component)owner).gameObject != (Object)null) ? ((Object)((Component)owner).gameObject).name : "?"); Plugin.Logger.LogWarning((object)("[RF] bone-follow miss owner=" + text + " reason=" + reason)); } } catch { } } internal static void OnWieldedChanged(ItemEquippable? newWielded) { LastWieldChangeTime = Time.unscaledTime; if ((Object)(object)newWielded == (Object)null || !IsLocalItem(newWielded)) { return; } RegisterItem(newWielded); try { if ((Object)(object)newWielded.m_lt == (Object)null) { return; } Light lt = newWielded.m_lt; bool num = (Object)(object)((Il2CppObjectBase)newWielded).TryCast() != (Object)null; bool flag = (Object)(object)((Il2CppObjectBase)newWielded).TryCast() != (Object)null; if (num) { if ((Object)(object)((Component)lt).transform.Find("RF_L1") == (Object)null) { LightSandwich.ApplySandwich(lt, newWielded); } LightSandwich.EnsureRangedSettings(lt, newWielded, forceResolve: true); } else if (flag) { if ((Object)(object)((Component)lt).transform.Find("RF_L1") == (Object)null) { LightSandwich.ApplySandwich(lt, newWielded); } LightSandwich.EnsurePickableSettings(lt); } } catch { } } private void TryAttachPreCullEnforcer() { if (_preCullAttached) { return; } try { Camera val = null; Il2CppReferenceArray allCameras = Camera.allCameras; if (allCameras != null) { foreach (Camera item in (Il2CppArrayBase)(object)allCameras) { if (!((Object)(object)item == (Object)null)) { string name = ((Object)item).name; if (!string.IsNullOrEmpty(name) && name.IndexOf("FPSLookCamera", StringComparison.OrdinalIgnoreCase) >= 0) { val = item; break; } } } } if (!((Object)(object)val == (Object)null)) { if ((Object)(object)((Component)val).gameObject.GetComponent() == (Object)null) { ((Component)val).gameObject.AddComponent(); } _preCullAttached = true; } } catch { } } private static void EnsureHelmetSynth() { //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_016d: 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_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_0294: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Expected O, but got Unknown //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) if (_helmetSynthBuilt) { return; } Camera val = null; Il2CppReferenceArray allCameras = Camera.allCameras; if (allCameras != null) { foreach (Camera item in (Il2CppArrayBase)(object)allCameras) { if ((Object)(object)item != (Object)null && ((Object)item).name.IndexOf("FPSLookCamera", StringComparison.OrdinalIgnoreCase) >= 0) { val = item; break; } } } if (!((Object)(object)val == (Object)null)) { _helmetSynthBuilt = true; GameObject val2 = new GameObject("RF_HelmetSynth"); val2.transform.SetParent(((Component)val).transform, false); val2.transform.localPosition = Vector3.zero; val2.transform.localRotation = Quaternion.identity; ((Object)val2).hideFlags = (HideFlags)61; Color color = default(Color); ((Color)(ref color))..ctor(1f, 0.88f, 0.65f); Light val3 = val2.AddComponent(); val3.type = (LightType)0; val3.spotAngle = 96f; val3.innerSpotAngle = 0f; val3.intensity = Plugin.HelmetIntensity * 0.55f; val3.range = Plugin.HelmetRange; val3.shadows = (LightShadows)0; val3.cullingMask = -1; val3.color = color; try { val3.cookie = (Texture)(object)LightSandwich.GetCoreCookie(); } catch { } GameObject val4 = new GameObject("RF_HelmetSynth_Mid"); val4.transform.SetParent(val2.transform, false); val4.transform.localPosition = Vector3.zero; val4.transform.localRotation = Quaternion.identity; ((Object)val4).hideFlags = (HideFlags)61; Light val5 = val4.AddComponent(); val5.type = (LightType)0; val5.spotAngle = 105f; val5.innerSpotAngle = 0f; val5.intensity = Plugin.HelmetIntensity * 0.28f; val5.range = Plugin.HelmetFallRange * 0.55f; val5.shadows = (LightShadows)0; val5.cullingMask = -1; val5.color = color; try { val5.cookie = (Texture)(object)LightSandwich.GetMidCookie(); } catch { } GameObject val6 = new GameObject("RF_HelmetSynth_Fall"); val6.transform.SetParent(val2.transform, false); val6.transform.localPosition = Vector3.zero; val6.transform.localRotation = Quaternion.identity; ((Object)val6).hideFlags = (HideFlags)61; Light val7 = val6.AddComponent(); val7.type = (LightType)0; val7.spotAngle = 130f; val7.innerSpotAngle = 100f; val7.intensity = Plugin.HelmetIntensity * 0.07f; val7.range = Plugin.HelmetFallRange * 0.8f; val7.shadows = (LightShadows)0; val7.cullingMask = -1; val7.color = color; try { val7.cookie = (Texture)(object)LightSandwich.GetFalloffCookie(); } catch { } _helmetSynthGO = val2; RegisterFlickerBaseline(val3); RegisterFlickerRef(val3); val2.SetActive(!GunFlashlightActive && LastFlashlightState); } } private static void EnsureEyeFill() { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Expected O, but got Unknown if (_eyeFillBuilt) { return; } Camera val = null; Il2CppReferenceArray allCameras = Camera.allCameras; if (allCameras != null) { foreach (Camera item in (Il2CppArrayBase)(object)allCameras) { if ((Object)(object)item != (Object)null && ((Object)item).name.IndexOf("FPSLookCamera", StringComparison.OrdinalIgnoreCase) >= 0) { val = item; break; } } } if (!((Object)(object)val == (Object)null)) { _eyeFillBuilt = true; GameObject val2 = new GameObject("RF_EyeFill"); val2.transform.SetParent(((Component)val).transform, false); val2.transform.localPosition = Vector3.zero; val2.transform.localRotation = Quaternion.identity; ((Object)val2).hideFlags = (HideFlags)61; Light obj = val2.AddComponent(); obj.type = (LightType)2; obj.range = 1.6f; obj.intensity = 0.18f; obj.color = new Color(1f, 0.95f, 0.86f); obj.shadows = (LightShadows)0; obj.cullingMask = -1; _eyeFillGO = val2; val2.SetActive(LastFlashlightState); } } internal static void SetEyeFillActive(bool active) { if ((Object)(object)_eyeFillGO != (Object)null && _eyeFillGO.activeSelf != active) { _eyeFillGO.SetActive(active); } } private static void EnsureCameraBeam() { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Expected O, but got Unknown //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) if (_cameraBeamBuilt) { return; } Camera val = null; Il2CppReferenceArray allCameras = Camera.allCameras; if (allCameras != null) { foreach (Camera item in (Il2CppArrayBase)(object)allCameras) { if ((Object)(object)item != (Object)null && ((Object)item).name.IndexOf("FPSLookCamera", StringComparison.OrdinalIgnoreCase) >= 0) { val = item; break; } } } if (!((Object)(object)val == (Object)null)) { _cameraBeamBuilt = true; GameObject val2 = new GameObject("RF_CameraBeam"); val2.transform.SetParent(((Component)val).transform, false); val2.transform.localPosition = Vector3.zero; val2.transform.localRotation = Quaternion.identity; ((Object)val2).hideFlags = (HideFlags)61; Light val3 = val2.AddComponent(); val3.type = (LightType)0; val3.spotAngle = 50f; val3.innerSpotAngle = 0f; val3.intensity = 0f; val3.range = 3.5f; val3.shadows = (LightShadows)0; val3.cullingMask = -1; val3.color = new Color(1f, 0.95f, 0.86f); try { val3.cookie = (Texture)(object)LightSandwich.GetSmoothCookie(); } catch { } _cameraBeamGO = val2; val2.SetActive(false); } } internal static void SetCameraBeamActive(bool active) { if ((Object)(object)_cameraBeamGO != (Object)null && _cameraBeamGO.activeSelf != active) { _cameraBeamGO.SetActive(active); } } internal static void RegisterFlickerBaseline(Light l) { if (!((Object)(object)l == (Object)null)) { _rfCoreBaselineIntensity[((Object)l).GetInstanceID()] = l.intensity; } } internal static void RegisterFlickerRef(Light l) { if (!((Object)(object)l == (Object)null) && !_rfCoreRefs.Contains(l)) { _rfCoreRefs.Add(l); } } private void ApplyFlicker() { if (!Plugin.FlickerEnabled.Value || _rfCoreRefs.Count == 0) { return; } float value = Plugin.FlickerSpeed.Value; float value2 = Plugin.FlickerAmplitude.Value; float num = Time.time * value; for (int num2 = _rfCoreRefs.Count - 1; num2 >= 0; num2--) { try { Light val = _rfCoreRefs[num2]; if ((Object)(object)val == (Object)null) { _rfCoreRefs.RemoveAt(num2); } else { int instanceID = ((Object)val).GetInstanceID(); if (_rfCoreBaselineIntensity.TryGetValue(instanceID, out var value3)) { float num3 = Mathf.PerlinNoise(num, (float)instanceID * 0.0001f) * 2f - 1f; val.intensity = Mathf.Max(0f, value3 * (1f + num3 * value2)); } } } catch { _rfCoreRefs.RemoveAt(num2); } } } private void ApplyRareFlicker() { if (!Plugin.RareFlickerEnabled.Value || _rfCoreRefs.Count == 0) { return; } float unscaledTime = Time.unscaledTime; if (!_rfBurstActive) { if (_rfNextBurstTime == 0f) { _rfNextBurstTime = unscaledTime + Random.Range(Plugin.RareFlickerIntervalMin.Value, Plugin.RareFlickerIntervalMax.Value); } else if (unscaledTime >= _rfNextBurstTime) { _rfBurstActive = true; _rfBlinksLeft = Random.Range(3, 8); _rfNextBlinkTime = unscaledTime + Random.Range(0.05f, 0.1f); _rfBlinkOn = false; ApplyBurstState(); } } else if (unscaledTime >= _rfNextBlinkTime) { _rfBlinkOn = !_rfBlinkOn; _rfBlinksLeft--; if (_rfBlinksLeft <= 0) { _rfBurstActive = false; _rfBlinkOn = true; ApplyBurstState(); _rfNextBurstTime = unscaledTime + Random.Range(Plugin.RareFlickerIntervalMin.Value, Plugin.RareFlickerIntervalMax.Value); } else { _rfNextBlinkTime = unscaledTime + Random.Range(0.05f, 0.1f); ApplyBurstState(); } } } private void ApplyBurstState() { for (int num = _rfCoreRefs.Count - 1; num >= 0; num--) { try { Light val = _rfCoreRefs[num]; if ((Object)(object)val == (Object)null) { _rfCoreRefs.RemoveAt(num); } else { int instanceID = ((Object)val).GetInstanceID(); if (_rfCoreBaselineIntensity.TryGetValue(instanceID, out var value)) { val.intensity = (_rfBlinkOn ? value : 0f); } } } catch { _rfCoreRefs.RemoveAt(num); } } } private void ApplyHorrorFlicker() { if (!Plugin.HorrorFlickerEnabled.Value || _rfCoreRefs.Count == 0) { return; } float unscaledTime = Time.unscaledTime; if (!_horBurstActive) { if (_horNextBurstTime == 0f) { _horNextBurstTime = unscaledTime + Random.Range(Plugin.HorrorFlickerIntervalMin.Value, Plugin.HorrorFlickerIntervalMax.Value); } else if (unscaledTime >= _horNextBurstTime) { _horBurstActive = true; _horBlinksLeft = Random.Range(6, 15); _horBlinkOn = false; _horLongPauseAt = Random.Range(2, _horBlinksLeft - 1); _horNextBlinkTime = unscaledTime + Random.Range(0.04f, 0.12f); ApplyHorrorState(); } } else if (unscaledTime >= _horNextBlinkTime) { _horBlinkOn = !_horBlinkOn; _horBlinksLeft--; if (_horBlinksLeft <= 0) { _horBurstActive = false; _horBlinkOn = true; ApplyHorrorState(); _horNextBurstTime = unscaledTime + Random.Range(Plugin.HorrorFlickerIntervalMin.Value, Plugin.HorrorFlickerIntervalMax.Value); } else { float num = ((!_horBlinkOn && _horBlinksLeft == _horLongPauseAt) ? Random.Range(0.45f, 1.2f) : (_horBlinkOn ? Random.Range(0.06f, 0.22f) : Random.Range(0.04f, 0.15f))); _horNextBlinkTime = unscaledTime + num; ApplyHorrorState(); } } } private void ApplyHorrorState() { for (int num = _rfCoreRefs.Count - 1; num >= 0; num--) { try { Light val = _rfCoreRefs[num]; if ((Object)(object)val == (Object)null) { _rfCoreRefs.RemoveAt(num); } else { int instanceID = ((Object)val).GetInstanceID(); if (_rfCoreBaselineIntensity.TryGetValue(instanceID, out var value)) { val.intensity = (_horBlinkOn ? value : 0f); } } } catch { _rfCoreRefs.RemoveAt(num); } } } private void ApplyIntensityMultiplier(float m) { for (int num = _rfCoreRefs.Count - 1; num >= 0; num--) { try { Light val = _rfCoreRefs[num]; if ((Object)(object)val == (Object)null) { _rfCoreRefs.RemoveAt(num); } else { int instanceID = ((Object)val).GetInstanceID(); if (_rfCoreBaselineIntensity.TryGetValue(instanceID, out var value)) { val.intensity = Mathf.Max(0f, value * m); } } } catch { _rfCoreRefs.RemoveAt(num); } } } private void ApplyBrownoutFlicker() { if (!Plugin.BrownoutEnabled.Value || _rfCoreRefs.Count == 0) { return; } float unscaledTime = Time.unscaledTime; if (!_boActive) { if (_boNextTriggerTime == 0f) { _boNextTriggerTime = unscaledTime + Random.Range(Plugin.BrownoutIntervalMin.Value, Plugin.BrownoutIntervalMax.Value); } else if (unscaledTime >= _boNextTriggerTime) { _boActive = true; _boStartTime = unscaledTime; _boDimEnd = unscaledTime + Random.Range(1.5f, 3f); _boHoldEnd = _boDimEnd + Random.Range(1.5f, 4.5f); _boRecoverEnd = _boHoldEnd + Random.Range(1.5f, 3f); _boDimTarget = Random.Range(0.35f, 0.55f); } return; } float m; if (unscaledTime < _boDimEnd) { float num = (unscaledTime - _boStartTime) / (_boDimEnd - _boStartTime); float num2 = num * num * (3f - 2f * num); m = Mathf.Lerp(1f, _boDimTarget, num2); } else if (unscaledTime < _boHoldEnd) { float num3 = (Mathf.PerlinNoise(unscaledTime * 1.5f, 0.13f) - 0.5f) * 0.06f; m = Mathf.Max(0.05f, _boDimTarget + num3); } else { if (!(unscaledTime < _boRecoverEnd)) { _boActive = false; _boNextTriggerTime = unscaledTime + Random.Range(Plugin.BrownoutIntervalMin.Value, Plugin.BrownoutIntervalMax.Value); return; } float num4 = (unscaledTime - _boHoldEnd) / (_boRecoverEnd - _boHoldEnd); float num5 = num4 * num4 * (3f - 2f * num4); m = Mathf.Lerp(_boDimTarget, 1f, num5); } ApplyIntensityMultiplier(m); } private void ApplyStutterFlicker() { if (!Plugin.StutterEnabled.Value || _rfCoreRefs.Count == 0) { return; } float unscaledTime = Time.unscaledTime; if (!_stActive) { if (_stNextTriggerTime == 0f) { _stNextTriggerTime = unscaledTime + Random.Range(Plugin.StutterIntervalMin.Value, Plugin.StutterIntervalMax.Value); } else if (unscaledTime >= _stNextTriggerTime) { _stActive = true; _stStartTime = unscaledTime; _stEndTime = unscaledTime + Random.Range(0.8f, 2.5f); _stSpeed = Random.Range(25f, 45f); _stAmplitude = Random.Range(0.5f, 0.8f); _stSeed = Random.Range(0f, 1000f); } } else if (unscaledTime >= _stEndTime) { _stActive = false; _stNextTriggerTime = unscaledTime + Random.Range(Plugin.StutterIntervalMin.Value, Plugin.StutterIntervalMax.Value); } else { float num = Mathf.PerlinNoise(unscaledTime * _stSpeed, _stSeed); float num2 = Mathf.Clamp01((unscaledTime - _stStartTime) / 0.1f); float num3 = Mathf.Clamp01((_stEndTime - unscaledTime) / 0.3f); float num4 = Mathf.Min(num2, num3); float m = 1f + (num * 2f - 1f) * _stAmplitude * num4; ApplyIntensityMultiplier(m); } } private void ApplyRestrikeFlicker() { if (!Plugin.RestrikeEnabled.Value || _rfCoreRefs.Count == 0) { return; } float unscaledTime = Time.unscaledTime; if (_rsPhase < 0) { if (_rsNextTriggerTime == 0f) { _rsNextTriggerTime = unscaledTime + Random.Range(Plugin.RestrikeIntervalMin.Value, Plugin.RestrikeIntervalMax.Value); } else if (unscaledTime >= _rsNextTriggerTime) { _rsPhase = 0; _rsPhaseEnd = unscaledTime + Random.Range(0.15f, 0.4f); _rsStrikeLevel = Random.Range(0.35f, 0.5f); ApplyIntensityMultiplier(0f); } } else if (_rsPhase == 0) { ApplyIntensityMultiplier(0f); if (unscaledTime >= _rsPhaseEnd) { _rsPhase = 1; _rsPhaseEnd = unscaledTime + Random.Range(0.05f, 0.1f); } } else if (_rsPhase == 1) { ApplyIntensityMultiplier(_rsStrikeLevel); if (unscaledTime >= _rsPhaseEnd) { _rsPhase = 2; _rsPhaseEnd = unscaledTime + Random.Range(0.1f, 0.25f); } } else if (_rsPhase == 2) { ApplyIntensityMultiplier(0f); if (unscaledTime >= _rsPhaseEnd) { _rsPhase = 3; _rsRecoverStart = unscaledTime; _rsRecoverEnd = unscaledTime + Random.Range(0.35f, 0.65f); } } else if (_rsPhase == 3) { if (unscaledTime >= _rsRecoverEnd) { _rsPhase = -1; _rsNextTriggerTime = unscaledTime + Random.Range(Plugin.RestrikeIntervalMin.Value, Plugin.RestrikeIntervalMax.Value); return; } float num = (unscaledTime - _rsRecoverStart) / (_rsRecoverEnd - _rsRecoverStart); float num2 = (1f - num) * 0.35f; float num3 = Mathf.PerlinNoise(unscaledTime * 28f, 17.3f); float m = Mathf.Max(0.2f, 1f + (num3 * 2f - 1f) * num2); ApplyIntensityMultiplier(m); } } public void LateUpdate() { EnforceRFState(); ItemEquippable currentWieldedItem = Patch_ItemWield.CurrentWieldedItem; if ((Object)(object)currentWieldedItem != (Object)null) { try { if ((Object)(object)((Il2CppObjectBase)currentWieldedItem).TryCast() != (Object)null && (Object)(object)currentWieldedItem.m_lt != (Object)null && (Object)(object)((Component)currentWieldedItem.m_lt).transform.Find("RF_L1") != (Object)null) { LightSandwich.SuppressRangedSiblings(currentWieldedItem.m_lt, currentWieldedItem); } } catch { } } try { DustEffect.RepositionHaze(); } catch (Exception ex) { if (DustEffect._tickThrowLogBudget > 0) { DustEffect._tickThrowLogBudget--; Plugin.Logger.LogWarning((object)("[RF] DustEffect.RepositionHaze threw: " + ex.GetType().Name + " " + ex.Message)); } } try { FogBeamEffect.Update(DustEffect._coneRoot, DustEffect._coreLight, LastFlashlightState && (Object)(object)DustEffect._coneRoot != (Object)null); } catch (Exception ex2) { if (DustEffect._tickThrowLogBudget > 0) { DustEffect._tickThrowLogBudget--; Plugin.Logger.LogWarning((object)("[RF] FogBeamEffect.Update threw: " + ex2.GetType().Name + " " + ex2.Message)); } } } public void Update() { //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_03b8: Unknown result type (might be due to invalid IL or missing references) //IL_034b: Unknown result type (might be due to invalid IL or missing references) //IL_0350: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_0249: 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_0257: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) try { if (Input.GetKeyDown((KeyCode)102)) { LastFlashlightState = !LastFlashlightState; } } catch { } try { bool flag = false; for (int i = 49; i <= 54; i++) { if (Input.GetKeyDown((KeyCode)i)) { flag = true; break; } } if (!flag && Mathf.Abs(Input.mouseScrollDelta.y) > 0.01f) { flag = true; } if (flag) { if ((Object)(object)_helmetSynthGO != (Object)null && _helmetSynthGO.activeSelf) { _helmetSynthGO.SetActive(false); } ItemEquippable currentWieldedItem = Patch_ItemWield.CurrentWieldedItem; if ((Object)(object)currentWieldedItem != (Object)null) { try { Light lt = currentWieldedItem.m_lt; if ((Object)(object)lt != (Object)null && (Object)(object)((Component)lt).transform.Find("RF_L1") != (Object)null) { LightSandwich.SyncEnabled(((Component)lt).transform, v: false); } } catch { } } BeginSwap(); } } catch { } ApplyFlicker(); ApplyRareFlicker(); ApplyHorrorFlicker(); ApplyBrownoutFlicker(); ApplyStutterFlicker(); ApplyRestrikeFlicker(); if ((Object)(object)_helmetSynthGO == (Object)null) { _helmetSynthBuilt = false; } if (!_helmetSynthBuilt) { EnsureHelmetSynth(); } if ((Object)(object)_eyeFillGO == (Object)null) { _eyeFillBuilt = false; } if (!_eyeFillBuilt) { EnsureEyeFill(); } if ((Object)(object)_cameraBeamGO == (Object)null) { _cameraBeamBuilt = false; } if (!_cameraBeamBuilt) { EnsureCameraBeam(); } bool flag2 = false; float num = 0f; Color color = default(Color); ((Color)(ref color))..ctor(1f, 0.95f, 0.86f); if (LastFlashlightState) { ItemEquippable currentWieldedItem2 = Patch_ItemWield.CurrentWieldedItem; if ((Object)(object)currentWieldedItem2 != (Object)null && ((Object)(object)((Il2CppObjectBase)currentWieldedItem2).TryCast() != (Object)null || (Object)(object)((Il2CppObjectBase)currentWieldedItem2).TryCast() != (Object)null) && (Object)(object)_cameraBeamGO != (Object)null) { Vector3 position = _cameraBeamGO.transform.position; Transform transform = _cameraBeamGO.transform; Vector3[] obj4 = new Vector3[5] { transform.forward, default(Vector3), default(Vector3), default(Vector3), default(Vector3) }; Vector3 val = transform.forward + transform.right; obj4[1] = ((Vector3)(ref val)).normalized; val = transform.forward - transform.right; obj4[2] = ((Vector3)(ref val)).normalized; obj4[3] = -transform.up; obj4[4] = transform.right; Vector3[] array = (Vector3[])(object)obj4; float num2 = 1.3f; RaycastHit val2 = default(RaycastHit); for (int j = 0; j < array.Length; j++) { try { if (Physics.Raycast(position, array[j], ref val2, 1.3f, -1, (QueryTriggerInteraction)1) && ((RaycastHit)(ref val2)).distance < num2) { num2 = ((RaycastHit)(ref val2)).distance; } } catch { } } if (num2 < 1.3f) { float num3 = Mathf.Clamp01(1f - (num2 - 0.15f) / 1.15f); float num4 = num3 * num3 * num3 * (num3 * (num3 * 6f - 15f) + 10f); num = 0.18f * num4; flag2 = true; try { Light lt2 = currentWieldedItem2.m_lt; if ((Object)(object)lt2 != (Object)null) { Transform val3 = ((Component)lt2).transform.Find("RF_Core"); if ((Object)(object)val3 != (Object)null) { Light component = ((Component)val3).GetComponent(); if ((Object)(object)component != (Object)null) { color = component.color; } } } } catch { } } } } SetEyeFillActive(active: false); SetCameraBeamActive(flag2); if (flag2 && (Object)(object)_cameraBeamGO != (Object)null) { Light component2 = _cameraBeamGO.GetComponent(); if ((Object)(object)component2 != (Object)null) { float num5 = num * 2.5f; if (Mathf.Abs(component2.intensity - num5) > 0.001f) { component2.intensity = num5; } component2.color = color; float num6 = Mathf.Clamp01(num / 0.18f); float num7 = 50f + 45f * num6; if (Mathf.Abs(component2.spotAngle - num7) > 0.1f) { component2.spotAngle = num7; } } } TryAttachPreCullEnforcer(); try { Transform val4 = null; Light val5 = null; ItemEquippable currentWieldedItem3 = Patch_ItemWield.CurrentWieldedItem; if ((Object)(object)currentWieldedItem3 != (Object)null && LastFlashlightState && ((Object)(object)((Il2CppObjectBase)currentWieldedItem3).TryCast() != (Object)null || (Object)(object)((Il2CppObjectBase)currentWieldedItem3).TryCast() != (Object)null)) { Light val6 = null; try { val6 = currentWieldedItem3.m_lt; } catch { } if ((Object)(object)val6 != (Object)null) { Transform val7 = ((Component)val6).transform.Find("RF_Core"); if ((Object)(object)val7 != (Object)null) { val4 = val7; val5 = ((Component)val7).GetComponent(); } } } if ((Object)(object)val4 == (Object)null && (Object)(object)_helmetSynthGO != (Object)null && _helmetSynthGO.activeSelf) { val4 = _helmetSynthGO.transform; val5 = _helmetSynthGO.GetComponent(); } if ((Object)(object)val4 != (Object)null && (Object)(object)val5 != (Object)null) { DustEffect.EnsurePool(val4); DustEffect.SetActiveCone(val4, val5); if (((Object)val4).name.StartsWith("RF_HelmetSynth", StringComparison.Ordinal)) { FlashlightEnemyDetection.Tick(val4, val5, val5.range, Mathf.Min(val5.spotAngle, 70f), 0.7f, isHeadlight: true); } else { FlashlightEnemyDetection.Tick(val4, val5); } } DustEffect.Tick(Time.deltaTime); } catch (Exception ex) { if (DustEffect._tickThrowLogBudget > 0) { DustEffect._tickThrowLogBudget--; Plugin.Logger.LogWarning((object)("[RF] DustEffect.Tick threw: " + ex.GetType().Name + " " + ex.Message)); } } if (!(Time.unscaledTime < _nextScan)) { _nextScan = Time.unscaledTime + 3f; if (Plugin.Enabled.Value) { DoScan(); } } } private void DoScan() { //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Invalid comparison between Unknown and I4 try { if (_knownItems.Count == 0) { return; } for (int num = _knownItems.Count - 1; num >= 0; num--) { ItemEquippable val; try { val = _knownItems[num]; } catch { _knownItems.RemoveAt(num); continue; } if ((Object)(object)val == (Object)null) { _knownItems.RemoveAt(num); continue; } if (!IsLocalItem(val)) { _knownItems.RemoveAt(num); continue; } GameObject gameObject; try { gameObject = ((Component)val).gameObject; } catch { _knownItems.RemoveAt(num); continue; } if ((Object)(object)gameObject == (Object)null) { _knownItems.RemoveAt(num); continue; } bool flag = (Object)(object)((Il2CppObjectBase)val).TryCast() != (Object)null; bool flag2 = (Object)(object)((Il2CppObjectBase)val).TryCast() != (Object)null; if (!flag && !flag2) { continue; } Light lt = val.m_lt; if (!((Object)(object)lt == (Object)null) && ((int)lt.type == 0 || (int)lt.type == 2)) { if ((Object)(object)((Component)lt).transform.Find("RF_L1") == (Object)null) { LightSandwich.ApplySandwich(lt, val); } else if (flag) { LightSandwich.EnsurePickableSettings(lt); } else if (flag2 && (Object)(object)Patch_ItemWield.CurrentWieldedItem == (Object)(object)val) { LightSandwich.EnsureRangedSettings(lt, val, forceResolve: false); } } } } catch { } } } internal static class WeaponBoneTracker { private static readonly Dictionary _cache = new Dictionary(); private static readonly HashSet _logged = new HashSet(); private static readonly string[] BoneKeywords = new string[5] { "Flashlight", "MuzzleEffect", "Muzzle", "GunMount", "Barrel" }; internal static void ClearAll() { _cache.Clear(); _logged.Clear(); } internal static Transform? Resolve(ItemEquippable? owner) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)owner == (Object)null) { return null; } int instanceID; try { instanceID = ((Object)owner).GetInstanceID(); } catch { return null; } if (_cache.TryGetValue(instanceID, out Transform value)) { if ((Object)(object)value == (Object)null) { return null; } try { _ = value.position; return value; } catch { _cache.Remove(instanceID); } } Transform val = null; string text = "?"; try { if ((Object)(object)((Component)owner).gameObject != (Object)null) { val = ((Component)owner).gameObject.transform; text = ((Object)((Component)owner).gameObject).name; } } catch { } if ((Object)(object)val == (Object)null) { _cache[instanceID] = null; return null; } Transform best = null; int bestPri = int.MaxValue; List list = new List(8); ScanDescendants(val, 0, ref best, ref bestPri, list); if (_logged.Add(instanceID)) { try { string text2 = (((Object)(object)best != (Object)null) ? ((Object)((Component)best).gameObject).name : "(none)"); string text3 = ((list.Count == 0) ? "" : string.Join(",", list.ToArray())); Plugin.Logger.LogInfo((object)("[RF] bone-resolve owner=" + text + " chosen=" + text2 + " candidates=[" + text3 + "]")); } catch { } } _cache[instanceID] = best; return best; } private static void ScanDescendants(Transform t, int depth, ref Transform? best, ref int bestPri, List matches) { if (depth > 8) { return; } int childCount; try { childCount = t.childCount; } catch { return; } for (int i = 0; i < childCount; i++) { Transform child; try { child = t.GetChild(i); } catch { continue; } if ((Object)(object)child == (Object)null) { continue; } string name; try { name = ((Object)((Component)child).gameObject).name; } catch { continue; } if (!string.IsNullOrEmpty(name) && !LightSandwich.IsRFChild(name)) { for (int j = 0; j < BoneKeywords.Length; j++) { if (name.IndexOf(BoneKeywords[j], StringComparison.OrdinalIgnoreCase) >= 0) { matches.Add(name + "[" + BoneKeywords[j] + "]"); if (j < bestPri) { best = child; bestPri = j; } break; } } } ScanDescendants(child, depth + 1, ref best, ref bestPri, matches); } } } public class PreCullEnforcer : MonoBehaviour { public PreCullEnforcer(IntPtr ptr) : base(ptr) { } public void OnPreCull() { try { LightUpdater.Instance?.EnforceRFState(); } catch { } } } [HarmonyPatch(typeof(GameDataInit), "Initialize")] internal static class Patch_GameDataInit_RareFlashlight { [HarmonyPostfix] private static void Postfix() { //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Expected O, but got Unknown if (!Plugin.Enabled.Value) { return; } float value = Plugin.Pick_RareWeight.Value; try { uint num = 0u; List val = GameDataBlockBase.Wrapper?.Blocks; if (val != null) { Enumerator enumerator = val.GetEnumerator(); while (enumerator.MoveNext()) { ItemDataBlock current = enumerator.Current; if (current != null && ((GameDataBlockBase)(object)current).name != null && ((GameDataBlockBase)(object)current).name.IndexOf("FlashlightMedium", StringComparison.OrdinalIgnoreCase) >= 0) { num = ((GameDataBlockBase)(object)current).persistentID; break; } } } if (num == 0) { return; } List val2 = GameDataBlockBase.Wrapper?.Blocks; if (val2 == null) { return; } Enumerator enumerator2 = val2.GetEnumerator(); while (enumerator2.MoveNext()) { ConsumableDistributionDataBlock current2 = enumerator2.Current; if (current2 == null || current2.SpawnData == null) { continue; } for (int i = 0; i < current2.SpawnData.Count; i++) { ConsumableSpawnData val3 = current2.SpawnData[i]; if (val3 != null && val3.ItemID == num) { val3.Weight = value; } } } } catch (Exception ex) { ManualLogSource logger = Plugin.Logger; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val4 = new BepInExWarningLogInterpolatedStringHandler(39, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("[FO] Rare flashlight weight patch err: "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(ex.Message); } logger.LogWarning(val4); } } } internal static class PickableFlashlightTracker { internal const string FlashlightItemName = "FlashlightMedium"; internal const string FallbackItemName = "GlowStick"; private static int _flashlightsSpawned; private static int _nonFlashlightPickups; private static bool _guaranteeFired; internal static int MaxPerLevel => Plugin.Pick_MaxPerLevel.Value; internal static int GuaranteeAfterNPickups => Plugin.Pick_GuaranteeFloor.Value; internal static int FlashlightsSpawned => _flashlightsSpawned; internal static void Reset() { _flashlightsSpawned = 0; _nonFlashlightPickups = 0; _guaranteeFired = false; } internal static bool TryConsume() { if (_flashlightsSpawned < MaxPerLevel) { _flashlightsSpawned++; return true; } return false; } internal static bool ShouldPromoteToFlashlight() { if (_guaranteeFired) { return false; } if (_flashlightsSpawned > 0) { return false; } _nonFlashlightPickups++; if (_nonFlashlightPickups < GuaranteeAfterNPickups) { return false; } _guaranteeFired = true; _flashlightsSpawned++; return true; } } [HarmonyPatch(typeof(LG_PickupItem), "SetupAsConsumable", new Type[] { typeof(int), typeof(uint) })] internal static class Patch_LGPickupSetupAsConsumable { [HarmonyPrefix] private static void Prefix(LG_PickupItem __instance, int randomSeed, ref uint itemIDOverride) { if (!Plugin.Enabled.Value) { return; } ItemDataBlock block = GameDataBlockBase.GetBlock(itemIDOverride); if (block == null) { return; } if (LooksLikeFlashlight(block)) { if (!PickableFlashlightTracker.TryConsume()) { uint num = FindReplacement(block); if (num != 0) { itemIDOverride = num; } } } else if (PickableFlashlightTracker.ShouldPromoteToFlashlight()) { uint num2 = FindFlashlightItemID(block); if (num2 != 0) { itemIDOverride = num2; } } } internal static bool LooksLikeFlashlight(ItemDataBlock b) { if (b == null || ((GameDataBlockBase)(object)b).name == null) { return false; } return ((GameDataBlockBase)(object)b).name.IndexOf("FlashlightMedium", StringComparison.OrdinalIgnoreCase) >= 0; } private static uint FindReplacement(ItemDataBlock original) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) List blocks = GameDataBlockBase.Wrapper.Blocks; if (blocks == null) { return 0u; } Enumerator enumerator = blocks.GetEnumerator(); while (enumerator.MoveNext()) { ItemDataBlock current = enumerator.Current; if (current != null && ((GameDataBlockBase)(object)current).name != null && current.inventorySlot == original.inventorySlot && !LooksLikeFlashlight(current)) { return ((GameDataBlockBase)(object)current).persistentID; } } return 0u; } private static uint FindFlashlightItemID(ItemDataBlock original) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) List blocks = GameDataBlockBase.Wrapper.Blocks; if (blocks == null) { return 0u; } uint num = 0u; uint num2 = 0u; Enumerator enumerator = blocks.GetEnumerator(); while (enumerator.MoveNext()) { ItemDataBlock current = enumerator.Current; if (current != null && ((GameDataBlockBase)(object)current).name != null && LooksLikeFlashlight(current)) { uint persistentID = ((GameDataBlockBase)(object)current).persistentID; if (num2 == 0) { num2 = persistentID; } if (current.inventorySlot == original.inventorySlot) { num = persistentID; break; } } } if (num == 0) { return num2; } return num; } } public enum FlashLightMode { MINIMAL, VANILLA, CASUAL, VERY_CASUAL, ITS_2050_BRUH } internal struct PresetOffset { public float CoreAngle; public float CoreIntensity; public float CoreRange; public float MidAngle; public float MidIntensity; public float MidRange; public float FallAngle; public float FallIntensity; public float FallRange; } internal struct ModeAdjustments { public PresetOffset Ranged; public float HelmetAngleOffset; public float HelmetIntensityOffset; public float HelmetRangeOffset; public float HelmetFallRangeExtra; public float PickRangeOffset; public float PickIntensityOffset; public float PickAngleOffset; public Color? PickColorOverride; } internal static class ModePresets { private static readonly ModeAdjustments _minimal = new ModeAdjustments { Ranged = new PresetOffset { CoreRange = -2f, CoreIntensity = 0.05f }, PickRangeOffset = -5f, PickAngleOffset = -10f, PickIntensityOffset = -0.1f }; private static readonly ModeAdjustments _veryCasual = new ModeAdjustments { Ranged = new PresetOffset { CoreRange = 2f, CoreIntensity = 0.05f, MidAngle = 10f, MidRange = 2f, FallAngle = 3f, FallRange = 1f }, HelmetRangeOffset = 1f, HelmetFallRangeExtra = 3f }; private static readonly ModeAdjustments _its2050 = new ModeAdjustments { Ranged = new PresetOffset { CoreRange = 4f, CoreIntensity = 0.05f, MidAngle = 20f, MidRange = 4f, FallAngle = 6f, FallRange = 3f }, HelmetRangeOffset = 4f, HelmetIntensityOffset = 0.3f, HelmetFallRangeExtra = 5f, PickRangeOffset = 2f, PickColorOverride = new Color(1f, 0.92f, 0.82f) }; internal static ModeAdjustments For(FlashLightMode m) { return m switch { FlashLightMode.MINIMAL => _minimal, FlashLightMode.VERY_CASUAL => _veryCasual, FlashLightMode.ITS_2050_BRUH => _its2050, _ => default(ModeAdjustments), }; } } internal static class PluginInfo { public const string GUID = "FlashlightOverhaul"; public const string Name = "Flashlight Overhaul"; public const string Version = "2.0.0"; } }