Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Headlamp v0.1.0
Headlamp.dll
Decompiled 27 minutes agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security.Cryptography; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using LethalCompanyInputUtils.Api; using LethalLib.Modules; using Microsoft.CodeAnalysis; using ReservedItemSlotCore; using ReservedItemSlotCore.Data; using Unity.Collections; using Unity.Netcode; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.Rendering; using UnityEngine.Rendering.HighDefinition; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Headlamp")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: AssemblyInformationalVersion("0.1.0+ed132eba366f8c892a2260cdc4910a6a62bd6030")] [assembly: AssemblyProduct("Headlamp")] [assembly: AssemblyTitle("Headlamp")] [assembly: AssemblyVersion("0.1.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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 Headlamp { public class HeadlampItem : GrabbableObject { internal static readonly List<HeadlampItem> All = new List<HeadlampItem>(); private static readonly Color Warm = new Color(1f, 0.86f, 0.64f); private const float LensGlow = 12f; private const float FlickerBelow = 0.1f; public Light beam; public Light glow; public Transform lensPoint; public Renderer lensRenderer; public int lensMaterialIndex = -1; public AudioClip[] clickClips; public AudioClip deadClip; public AudioSource audioSource; private HDAdditionalLightData _beamHd; private float _beamIntensity; private Material _lensMat; private Vector3 _beamLocalPos; private Quaternion _beamLocalRot; internal bool IsWorn { get { if ((Object)(object)base.playerHeldBy == (Object)null) { return false; } if (!ReservedPlayerData.allPlayerData.TryGetValue(base.playerHeldBy, out var value)) { return false; } if (value.IsItemInReservedItemSlot((GrabbableObject)(object)this)) { return (Object)(object)value.currentlySelectedItem != (Object)(object)this; } return false; } } internal void Setup(FlashlightItem template, GameObject model) { //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: 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_01bc: 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_023f: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Unknown result type (might be due to invalid IL or missing references) audioSource = ((Component)this).GetComponent<AudioSource>(); clickClips = template.flashlightClips; deadClip = template.outOfBatteriesClip; lensPoint = model.transform.Find("LensPoint") ?? model.transform; MeshRenderer componentInChildren = model.GetComponentInChildren<MeshRenderer>(); Material[] sharedMaterials = ((Renderer)componentInChildren).sharedMaterials; for (int i = 0; i < sharedMaterials.Length; i++) { if ((Object)(object)sharedMaterials[i] != (Object)null && ((Object)sharedMaterials[i]).name.StartsWith("M_HL_Lens")) { lensRenderer = (Renderer)(object)componentInChildren; lensMaterialIndex = i; } } beam = Object.Instantiate<GameObject>(((Component)template.flashlightBulb).gameObject, lensPoint, false).GetComponent<Light>(); ((Object)beam).name = "Beam"; ((Component)beam).transform.localPosition = new Vector3(0f, 0f, 0.05f); ((Component)beam).transform.localRotation = Quaternion.identity; ((Behaviour)beam).enabled = false; HDAdditionalLightData component = ((Component)beam).GetComponent<HDAdditionalLightData>(); if ((Object)(object)component != (Object)null) { component.intensity *= Plugin.Brightness.Value; component.range *= Plugin.Range.Value; component.SetSpotAngle(Plugin.BeamAngle.Value, 0f); component.color = Warm; } else { Light obj = beam; obj.intensity *= Plugin.Brightness.Value; Light obj2 = beam; obj2.range *= Plugin.Range.Value; beam.spotAngle = Plugin.BeamAngle.Value; } beam.color = Warm; if ((Object)(object)template.flashlightBulbGlow != (Object)null) { glow = Object.Instantiate<GameObject>(((Component)template.flashlightBulbGlow).gameObject, lensPoint, false).GetComponent<Light>(); ((Object)glow).name = "LensGlow"; ((Component)glow).transform.localPosition = new Vector3(0f, 0f, 0.03f); ((Behaviour)glow).enabled = false; glow.color = Warm; HDAdditionalLightData component2 = ((Component)glow).GetComponent<HDAdditionalLightData>(); if ((Object)(object)component2 != (Object)null) { component2.color = Warm; } } Transform[] componentsInChildren = ((Component)beam).GetComponentsInChildren<Transform>(true); for (int j = 0; j < componentsInChildren.Length; j++) { ((Component)componentsInChildren[j]).gameObject.layer = ((Component)this).gameObject.layer; } } public override void Start() { //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Expected O, but got Unknown //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: 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) ((GrabbableObject)this).Start(); All.Add(this); if ((Object)(object)beam != (Object)null) { _beamHd = ((Component)beam).GetComponent<HDAdditionalLightData>(); _beamIntensity = (((Object)(object)_beamHd != (Object)null) ? _beamHd.intensity : beam.intensity); _beamLocalPos = ((Component)beam).transform.localPosition; _beamLocalRot = ((Component)beam).transform.localRotation; } if ((Object)(object)lensRenderer != (Object)null && lensMaterialIndex >= 0) { Material[] materials = lensRenderer.materials; _lensMat = materials[lensMaterialIndex]; } if (base.insertedBattery == null) { base.insertedBattery = new Battery(false, 1f); } SetLit(base.isBeingUsed, sound: false); } public override void OnDestroy() { All.Remove(this); ((GrabbableObject)this).OnDestroy(); } public override void ItemActivate(bool used, bool buttonDown = true) { SetLit(used, sound: true); } public override void UseUpBatteries() { ((GrabbableObject)this).UseUpBatteries(); SetLit(on: false, sound: false); if ((Object)(object)audioSource != (Object)null && (Object)(object)deadClip != (Object)null) { audioSource.PlayOneShot(deadClip, 1f); } } internal void PlayDead() { if ((Object)(object)audioSource != (Object)null && (Object)(object)deadClip != (Object)null) { audioSource.PlayOneShot(deadClip, 0.8f); } } internal void SetLit(bool on, bool sound) { //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_0050: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)beam != (Object)null) { ((Behaviour)beam).enabled = on; } if ((Object)(object)glow != (Object)null) { ((Behaviour)glow).enabled = on; } if ((Object)(object)_lensMat != (Object)null) { _lensMat.SetColor("_EmissiveColor", on ? (Warm * 12f) : Color.black); } if (sound && (Object)(object)audioSource != (Object)null && clickClips != null && clickClips.Length != 0) { audioSource.pitch = 1.15f; audioSource.PlayOneShot(clickClips[Random.Range(0, clickClips.Length)]); if ((Object)(object)RoundManager.Instance != (Object)null) { RoundManager.Instance.PlayAudibleNoise(((Component)this).transform.position, 7f, 0.4f, 0, base.isInElevator && (Object)(object)StartOfRound.Instance != (Object)null && StartOfRound.Instance.hangarDoorsClosed, 0); } } } public override void LateUpdate() { //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009b: 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_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: 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_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: 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) ((GrabbableObject)this).LateUpdate(); if (!((Object)(object)beam == (Object)null) && ((Behaviour)beam).enabled) { PlayerControllerB val = (((Object)(object)StartOfRound.Instance != (Object)null) ? StartOfRound.Instance.localPlayerController : null); if ((Object)(object)val != (Object)null && (Object)(object)base.playerHeldBy == (Object)(object)val && IsWorn && (Object)(object)val.gameplayCamera != (Object)null) { Transform transform = ((Component)val.gameplayCamera).transform; ((Component)beam).transform.SetPositionAndRotation(transform.position + transform.forward * 0.25f + transform.up * 0.06f, transform.rotation * Quaternion.Euler(Plugin.FirstPersonTilt.Value, 0f, 0f)); } else { ((Component)beam).transform.localPosition = _beamLocalPos; ((Component)beam).transform.localRotation = _beamLocalRot; } float num = 1f; if (base.insertedBattery != null && base.insertedBattery.charge < 0.1f) { num = ((Mathf.PerlinNoise(Time.time * 9f, (float)((Object)this).GetInstanceID() * 0.01f) < 0.35f) ? 0.15f : 0.85f); } if ((Object)(object)_beamHd != (Object)null) { _beamHd.intensity = _beamIntensity * num; } else { beam.intensity = _beamIntensity * num; } } } internal static HeadlampItem FindOn(PlayerControllerB p) { ReservedItemSlotData val = default(ReservedItemSlotData); if (ReservedPlayerData.allPlayerData.TryGetValue(p, out var value) && Slot.Data != null && SessionManager.TryGetUnlockedItemSlotData(Slot.Data.slotName, ref val) && value.GetReservedItem(val) is HeadlampItem result) { return result; } if (p.currentlyHeldObjectServer is HeadlampItem result2) { return result2; } GrabbableObject[] itemSlots = p.ItemSlots; for (int i = 0; i < itemSlots.Length; i++) { if (itemSlots[i] is HeadlampItem result3) { return result3; } } return null; } } internal static class Keys { private static InputAction _toggle; internal static void Init() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown if (Plugin.InputUtilsLoaded) { _toggle = FromInputUtils(); } if (_toggle == null) { _toggle = InputActionSetupExtensions.AddAction(new InputActionMap("Headlamp"), "Headlamp.Toggle", (InputActionType)1, Plugin.ToggleKey.Value, (string)null, (string)null, (string)null, (string)null); } _toggle.performed += delegate { Toggle(); }; } [MethodImpl(MethodImplOptions.NoInlining)] private static InputAction FromInputUtils() { return HeadlampInputs.Instance.Toggle; } internal static void Enable(bool on) { if (_toggle != null) { if (on) { _toggle.Enable(); } else { _toggle.Disable(); } } } private static void Toggle() { PlayerControllerB val = (((Object)(object)StartOfRound.Instance != (Object)null) ? StartOfRound.Instance.localPlayerController : null); if ((Object)(object)val == (Object)null || !val.isPlayerControlled || val.isPlayerDead || val.isTypingChat || val.inTerminalMenu || ((Object)(object)val.quickMenuManager != (Object)null && val.quickMenuManager.isMenuOpen) || val.isGrabbingObjectAnimation || ((Object)(object)ShipBuildModeManager.Instance != (Object)null && ShipBuildModeManager.Instance.InBuildMode)) { return; } HeadlampItem headlampItem = HeadlampItem.FindOn(val); if (!((Object)(object)headlampItem == (Object)null)) { if (!((GrabbableObject)headlampItem).isBeingUsed && (((GrabbableObject)headlampItem).insertedBattery == null || ((GrabbableObject)headlampItem).insertedBattery.empty)) { headlampItem.PlayDead(); } else { ((GrabbableObject)headlampItem).UseItemOnClient(true); } } } } internal class HeadlampInputs : LcInputActions { internal static readonly HeadlampInputs Instance = new HeadlampInputs(); [InputAction("<Keyboard>/h", Name = "Toggle headlamp")] public InputAction Toggle { get; set; } } [HarmonyPatch] internal static class KeyPatches { [HarmonyPatch(typeof(StartOfRound), "OnEnable")] [HarmonyPostfix] private static void On() { Keys.Enable(on: true); } [HarmonyPatch(typeof(StartOfRound), "OnDisable")] [HarmonyPostfix] private static void Off() { Keys.Enable(on: false); } } internal static class Net { [CompilerGenerated] private static class <>O { public static HandleNamedMessageDelegate <0>__OnConfig; } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static HandleNamedMessageDelegate <>9__6_0; internal void <Register>b__6_0(ulong sender, FastBufferReader r) { SendConfig(sender); } } private const string MsgConfigRequest = "daniel.headlamp.cfgreq"; private const string MsgConfig = "daniel.headlamp.cfg"; private static readonly string[] All = new string[2] { "daniel.headlamp.cfgreq", "daniel.headlamp.cfg" }; private static bool _registered; public static bool IsHost { get { if ((Object)(object)NetworkManager.Singleton != (Object)null) { return NetworkManager.Singleton.IsServer; } return false; } } public static void Register() { //IL_0070: 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_007b: Expected O, but got Unknown //IL_0048: 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_0053: Expected O, but got Unknown NetworkManager singleton = NetworkManager.Singleton; if (_registered || (Object)(object)singleton == (Object)null || singleton.CustomMessagingManager == null) { return; } CustomMessagingManager customMessagingManager = singleton.CustomMessagingManager; if (singleton.IsServer) { object obj = <>c.<>9__6_0; if (obj == null) { HandleNamedMessageDelegate val = delegate(ulong sender, FastBufferReader r) { SendConfig(sender); }; <>c.<>9__6_0 = val; obj = (object)val; } customMessagingManager.RegisterNamedMessageHandler("daniel.headlamp.cfgreq", (HandleNamedMessageDelegate)obj); } else { object obj2 = <>O.<0>__OnConfig; if (obj2 == null) { HandleNamedMessageDelegate val2 = OnConfig; <>O.<0>__OnConfig = val2; obj2 = (object)val2; } customMessagingManager.RegisterNamedMessageHandler("daniel.headlamp.cfg", (HandleNamedMessageDelegate)obj2); Send("daniel.headlamp.cfgreq", 0uL, null); } _registered = true; } public static void Unregister() { CustomMessagingManager val = (((Object)(object)NetworkManager.Singleton != (Object)null) ? NetworkManager.Singleton.CustomMessagingManager : null); if (val != null) { string[] all = All; foreach (string text in all) { try { val.UnregisterNamedMessageHandler(text); } catch (Exception) { } } } _registered = false; } private static void SendConfig(ulong client) { List<ulong> lit = new List<ulong>(); foreach (HeadlampItem item in HeadlampItem.All) { if ((Object)(object)item != (Object)null && ((GrabbableObject)item).isBeingUsed && ((NetworkBehaviour)item).IsSpawned) { lit.Add(((NetworkBehaviour)item).NetworkObjectId); } } Send("daniel.headlamp.cfg", client, delegate(FastBufferWriter w) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: 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_0052: 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_007b: Unknown result type (might be due to invalid IL or missing references) int value = Plugin.Price.Value; ((FastBufferWriter)(ref w)).WriteValueSafe<int>(ref value, default(ForPrimitives)); float value2 = Plugin.BatteryMinutes.Value; ((FastBufferWriter)(ref w)).WriteValueSafe<float>(ref value2, default(ForPrimitives)); value = lit.Count; ((FastBufferWriter)(ref w)).WriteValueSafe<int>(ref value, default(ForPrimitives)); foreach (ulong item2 in lit) { ulong current2 = item2; ((FastBufferWriter)(ref w)).WriteValueSafe<ulong>(ref current2, default(ForPrimitives)); } }); } private static void OnConfig(ulong sender, FastBufferReader r) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //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) //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) int num = default(int); ((FastBufferReader)(ref r)).ReadValueSafe<int>(ref num, default(ForPrimitives)); float num2 = default(float); ((FastBufferReader)(ref r)).ReadValueSafe<float>(ref num2, default(ForPrimitives)); int num3 = default(int); ((FastBufferReader)(ref r)).ReadValueSafe<int>(ref num3, default(ForPrimitives)); Registry.ApplyHostSettings(num, num2); NetworkManager singleton = NetworkManager.Singleton; ulong key = default(ulong); for (int i = 0; i < num3; i++) { ((FastBufferReader)(ref r)).ReadValueSafe<ulong>(ref key, default(ForPrimitives)); if ((Object)(object)singleton != (Object)null && singleton.SpawnManager.SpawnedObjects.TryGetValue(key, out var value)) { HeadlampItem component = ((Component)value).GetComponent<HeadlampItem>(); if ((Object)(object)component != (Object)null) { ((GrabbableObject)component).isBeingUsed = true; component.SetLit(on: true, sound: false); } } } Plugin.Log.LogInfo((object)$"Headlamp: host settings: price {num}, {num2:F1} min battery; {num3} lit."); } private static void Send(string name, ulong to, Action<FastBufferWriter> write) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton == (Object)null || singleton.CustomMessagingManager == null) { return; } FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(256, (Allocator)2, 8192); try { write?.Invoke(val); singleton.CustomMessagingManager.SendNamedMessage(name, to, val, (NetworkDelivery)3); } finally { ((FastBufferWriter)(ref val)).Dispose(); } } } [HarmonyPatch] internal static class NetPatches { [HarmonyPatch(typeof(StartOfRound), "Start")] [HarmonyPostfix] private static void StartOfRoundStart() { Net.Register(); if (Net.IsHost) { Registry.ApplyHostSettings(Plugin.Price.Value, Plugin.BatteryMinutes.Value); } } [HarmonyPatch(typeof(StartOfRound), "OnDestroy")] [HarmonyPrefix] private static void StartOfRoundDestroy() { Net.Unregister(); } } public static class PluginInfo { public const string Guid = "daniel.lethalcompany.headlamp"; public const string Name = "Headlamp"; public const string Version = "0.1.0"; } [BepInPlugin("daniel.lethalcompany.headlamp", "Headlamp", "0.1.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { internal static ManualLogSource Log; internal static ConfigEntry<int> Price; internal static ConfigEntry<float> BatteryMinutes; internal static ConfigEntry<int> SlotPriority; internal static ConfigEntry<string> ToggleKey; internal static ConfigEntry<float> Brightness; internal static ConfigEntry<float> Range; internal static ConfigEntry<float> BeamAngle; internal static ConfigEntry<float> FirstPersonTilt; internal static ConfigEntry<Vector3> HolsterPosition; internal static ConfigEntry<Vector3> HolsterRotation; internal static ConfigEntry<bool> DebugKeys; internal static bool InputUtilsLoaded; private readonly Harmony _harmony = new Harmony("daniel.lethalcompany.headlamp"); private void Awake() { //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Expected O, but got Unknown //IL_01b6: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; Price = ((BaseUnityPlugin)this).Config.Bind<int>("Store (host)", "Price", 35, "Store price in credits (Daniel, q_f0a8a4bfa5cb480d)."); BatteryMinutes = ((BaseUnityPlugin)this).Config.Bind<float>("Store (host)", "Battery minutes", 10f, "Minutes of light per full charge. Recharge it on the ship's charger."); SlotPriority = ((BaseUnityPlugin)this).Config.Bind<int>("Slot", "Slot priority", -20, "ReservedItemSlotCore slot priority. Negative = alone on the left of the screen; positive stacks it with the other reserved slots on the right. Must match on every player."); ToggleKey = ((BaseUnityPlugin)this).Config.Bind<string>("Local", "Toggle key", "<Keyboard>/h", "Turns the headlamp on and off from any slot. Used when LethalCompany InputUtils isn't installed (with it, rebind in the game's keybind menu)."); Brightness = ((BaseUnityPlugin)this).Config.Bind<float>("Local", "Brightness", 1.4f, "Beam brightness compared with the Pro-flashlight."); Range = ((BaseUnityPlugin)this).Config.Bind<float>("Local", "Range", 1f, "Beam range compared with the Pro-flashlight."); BeamAngle = ((BaseUnityPlugin)this).Config.Bind<float>("Local", "Beam angle", 70f, "Spot cone angle in degrees (the Pro-flashlight's is narrower)."); FirstPersonTilt = ((BaseUnityPlugin)this).Config.Bind<float>("Local", "First-person tilt", 6f, "Degrees your own beam points below where you look."); HolsterPosition = ((BaseUnityPlugin)this).Config.Bind<Vector3>("Fit", "Holster position", HolsterFit.Position, "Offset from the head bone (spine.004), in its axes, metres."); HolsterRotation = ((BaseUnityPlugin)this).Config.Bind<Vector3>("Fit", "Holster rotation", HolsterFit.Rotation, "Rotation from the head bone (spine.004), Euler degrees."); DebugKeys = ((BaseUnityPlugin)this).Config.Bind<bool>("Testing", "Debug keys", false, "Host only, not while typing. F11: spawn a charged headlamp in front of you."); InputUtilsLoaded = Chainloader.PluginInfos.ContainsKey("com.rune580.LethalCompanyInputUtils"); Keys.Init(); GameObject val = new GameObject("Headlamp.Runner"); Object.DontDestroyOnLoad((Object)val); ((Object)val).hideFlags = (HideFlags)61; val.AddComponent<Runner>(); _harmony.PatchAll(typeof(Plugin).Assembly); Registry.Load(); Slot.Register(); Log.LogInfo((object)("Headlamp 0.1.0 loaded (InputUtils " + (InputUtilsLoaded ? "found" : "not found") + ").")); } } internal static class Registry { internal const string ItemName = "Headlamp"; private static readonly string[] Templates = new string[2] { "Pro-flashlight", "Flashlight" }; private static GameObject _container; internal static Sprite Icon; private static bool _shopRegistered; internal static GameObject ModelAsset { get; private set; } public static GameObject Prefab { get; private set; } public static Item Item { get; private set; } public static void Load() { //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) try { using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Headlamp.headlamp")) { AssetBundle val = ((stream != null) ? AssetBundle.LoadFromStream(stream) : null); if ((Object)(object)val == (Object)null) { Plugin.Log.LogError((object)"Headlamp: the embedded bundle is missing."); return; } ModelAsset = val.LoadAsset<GameObject>("HeadlampModel"); } using (Stream stream2 = Assembly.GetExecutingAssembly().GetManifestResourceStream("Headlamp.icon_item.png")) { if (stream2 != null) { MemoryStream memoryStream = new MemoryStream(); stream2.CopyTo(memoryStream); Texture2D val2 = new Texture2D(2, 2, (TextureFormat)4, false) { name = "HeadlampIcon" }; if (ImageConversion.LoadImage(val2, memoryStream.ToArray())) { Icon = Sprite.Create(val2, new Rect(0f, 0f, (float)((Texture)val2).width, (float)((Texture)val2).height), new Vector2(0.5f, 0.5f)); } } } Plugin.Log.LogInfo((object)$"Headlamp: model loaded ({(Object)(object)ModelAsset != (Object)null}, icon {(Object)(object)Icon != (Object)null})."); } catch (Exception arg) { Plugin.Log.LogError((object)$"Headlamp: assets failed to load: {arg}"); } } internal static void BuildPrefab() { //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Expected O, but got Unknown //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Expected O, but got Unknown //IL_0213: 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_025d: Invalid comparison between Unknown and I4 //IL_02fd: Unknown result type (might be due to invalid IL or missing references) //IL_0302: Unknown result type (might be due to invalid IL or missing references) //IL_030a: Unknown result type (might be due to invalid IL or missing references) //IL_0316: Unknown result type (might be due to invalid IL or missing references) //IL_031b: Unknown result type (might be due to invalid IL or missing references) //IL_0320: Unknown result type (might be due to invalid IL or missing references) //IL_0328: Unknown result type (might be due to invalid IL or missing references) //IL_032d: Unknown result type (might be due to invalid IL or missing references) //IL_0332: Unknown result type (might be due to invalid IL or missing references) //IL_03cb: Unknown result type (might be due to invalid IL or missing references) //IL_03d9: 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_03f2: Unknown result type (might be due to invalid IL or missing references) //IL_035b: Unknown result type (might be due to invalid IL or missing references) //IL_034d: Unknown result type (might be due to invalid IL or missing references) //IL_037b: Unknown result type (might be due to invalid IL or missing references) //IL_036d: Unknown result type (might be due to invalid IL or missing references) //IL_0452: Unknown result type (might be due to invalid IL or missing references) //IL_0612: Unknown result type (might be due to invalid IL or missing references) //IL_0617: Unknown result type (might be due to invalid IL or missing references) //IL_0623: Unknown result type (might be due to invalid IL or missing references) //IL_062f: Unknown result type (might be due to invalid IL or missing references) //IL_0653: Unknown result type (might be due to invalid IL or missing references) //IL_0658: Unknown result type (might be due to invalid IL or missing references) //IL_0664: Unknown result type (might be due to invalid IL or missing references) //IL_0669: Unknown result type (might be due to invalid IL or missing references) //IL_06aa: Unknown result type (might be due to invalid IL or missing references) //IL_06b4: Expected O, but got Unknown //IL_0709: Unknown result type (might be due to invalid IL or missing references) //IL_0715: Unknown result type (might be due to invalid IL or missing references) //IL_039b: Unknown result type (might be due to invalid IL or missing references) //IL_038d: Unknown result type (might be due to invalid IL or missing references) //IL_03a5: Unknown result type (might be due to invalid IL or missing references) //IL_03aa: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Prefab != (Object)null) { return; } if ((Object)(object)ModelAsset == (Object)null) { Plugin.Log.LogError((object)"Headlamp: no model, so no item."); return; } NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton == (Object)null) { Plugin.Log.LogError((object)"Headlamp: no NetworkManager at GameNetworkManager.Start."); return; } List<FlashlightItem> candidates = (from p in singleton.NetworkConfig.Prefabs.Prefabs select (!((Object)(object)p.Prefab != (Object)null)) ? null : p.Prefab.GetComponent<FlashlightItem>() into g where (Object)(object)g != (Object)null && (Object)(object)((GrabbableObject)g).itemProperties != (Object)null select g).ToList(); FlashlightItem val = Templates.Select((string n) => ((IEnumerable<FlashlightItem>)candidates).FirstOrDefault((Func<FlashlightItem, bool>)((FlashlightItem g) => ((GrabbableObject)g).itemProperties.itemName == n))).FirstOrDefault<FlashlightItem>((Func<FlashlightItem, bool>)((FlashlightItem g) => (Object)(object)g != (Object)null)) ?? candidates.FirstOrDefault(); if ((Object)(object)val == (Object)null) { Plugin.Log.LogError((object)"Headlamp: no vanilla flashlight to base the headlamp on."); return; } _container = new GameObject("Headlamp.Prefabs"); _container.SetActive(false); ((Object)_container).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)_container); GameObject val2 = new GameObject("Headlamp"); val2.transform.SetParent(_container.transform, false); val2.layer = ((Component)val).gameObject.layer; val2.tag = ((Component)val).gameObject.tag; NetworkObject obj = val2.AddComponent<NetworkObject>(); AccessTools.Field(typeof(NetworkObject), "GlobalObjectIdHash").SetValue(obj, StableHash("daniel.lethalcompany.headlamp.Headlamp")); AudioSource val3 = (((Object)(object)val.flashlightAudio != (Object)null) ? val.flashlightAudio : ((Component)val).GetComponent<AudioSource>()); AudioSource val4 = val2.AddComponent<AudioSource>(); val4.playOnAwake = false; if ((Object)(object)val3 != (Object)null) { val4.outputAudioMixerGroup = val3.outputAudioMixerGroup; val4.spatialBlend = val3.spatialBlend; val4.rolloffMode = val3.rolloffMode; val4.minDistance = val3.minDistance; val4.maxDistance = val3.maxDistance; val4.dopplerLevel = val3.dopplerLevel; val4.volume = val3.volume; if ((int)val3.rolloffMode == 2) { val4.SetCustomCurve((AudioSourceCurveType)0, val3.GetCustomCurve((AudioSourceCurveType)0)); } } GameObject val5 = Object.Instantiate<GameObject>(ModelAsset, val2.transform, false); ((Object)val5).name = "Model"; Transform[] componentsInChildren = val5.GetComponentsInChildren<Transform>(true); for (int num = 0; num < componentsInChildren.Length; num++) { ((Component)componentsInChildren[num]).gameObject.layer = val2.layer; } MeshRenderer componentInChildren = val5.GetComponentInChildren<MeshRenderer>(); Renderer[] componentsInChildren2 = val5.GetComponentsInChildren<Renderer>(true); for (int num = 0; num < componentsInChildren2.Length; num++) { componentsInChildren2[num].shadowCastingMode = (ShadowCastingMode)0; } Bounds bounds = val5.GetComponentInChildren<MeshFilter>().sharedMesh.bounds; Matrix4x4 val6 = val2.transform.worldToLocalMatrix * ((Component)componentInChildren).transform.localToWorldMatrix; Bounds val7 = default(Bounds); ((Bounds)(ref val7))..ctor(((Matrix4x4)(ref val6)).MultiplyPoint3x4(((Bounds)(ref bounds)).min), Vector3.zero); for (int num2 = 0; num2 < 8; num2++) { ((Bounds)(ref val7)).Encapsulate(((Matrix4x4)(ref val6)).MultiplyPoint3x4(new Vector3(((num2 & 1) == 0) ? ((Bounds)(ref bounds)).min.x : ((Bounds)(ref bounds)).max.x, ((num2 & 2) == 0) ? ((Bounds)(ref bounds)).min.y : ((Bounds)(ref bounds)).max.y, ((num2 & 4) == 0) ? ((Bounds)(ref bounds)).min.z : ((Bounds)(ref bounds)).max.z))); } BoxCollider val8 = val2.AddComponent<BoxCollider>(); val8.center = ((Bounds)(ref val7)).center; val8.size = ((Bounds)(ref val7)).size + new Vector3(0.04f, 0.04f, 0.04f); ((Collider)val8).isTrigger = (Object)(object)((Component)val).GetComponent<Collider>() != (Object)null && ((Component)val).GetComponent<Collider>().isTrigger; ScanNodeProperties componentInChildren2 = ((Component)val).GetComponentInChildren<ScanNodeProperties>(true); if ((Object)(object)componentInChildren2 != (Object)null) { ScanNodeProperties component = Object.Instantiate<GameObject>(((Component)componentInChildren2).gameObject, val2.transform, false).GetComponent<ScanNodeProperties>(); ((Component)component).transform.localPosition = val8.center; component.headerText = "Headlamp"; component.subText = "Wear it. [H] to switch on."; component.scrapValue = 0; component.nodeType = 0; } Item itemProperties = ((GrabbableObject)val).itemProperties; Item = Object.Instantiate<Item>(itemProperties); ((Object)Item).name = "HeadlampItem"; Item.itemName = "Headlamp"; Item.spawnPrefab = val2; if ((Object)(object)Icon != (Object)null) { Item.itemIcon = Icon; } Item.isScrap = false; Item.minValue = (Item.maxValue = 0); Item.creditsWorth = Plugin.Price.Value; Item.highestSalePercentage = 80; Item.twoHanded = false; Item.requiresBattery = true; Item.batteryUsage = Mathf.Max(0.5f, Plugin.BatteryMinutes.Value) * 60f; Item.automaticallySetUsingPower = true; Item.syncUseFunction = true; Item.holdButtonUse = false; Item.itemIsTrigger = false; Item.isConductiveMetal = false; Item.isDefensiveWeapon = false; Item.canBeGrabbedBeforeGameStart = true; Item.saveItemVariable = false; Item.meshVariants = (Mesh[])(object)new Mesh[0]; Item.materialVariants = (Material[])(object)new Material[0]; Item.spawnPositionTypes = new List<ItemGroup>(); Item.toolTips = new string[2] { "Switch on/off : [LMB]", "Toggle from any slot : [H]" }; Item.weight = 1f; Item.restingRotation = Vector3.zero; Item.verticalOffset = 0f - (val8.center.y - val8.size.y / 2f) + 0.01f; Item.positionOffset = itemProperties.positionOffset; Item.rotationOffset = itemProperties.rotationOffset; HeadlampItem headlampItem = val2.AddComponent<HeadlampItem>(); ((GrabbableObject)headlampItem).itemProperties = Item; ((GrabbableObject)headlampItem).grabbable = true; ((GrabbableObject)headlampItem).grabbableToEnemies = true; ((GrabbableObject)headlampItem).isInFactory = false; ((GrabbableObject)headlampItem).scrapValue = 0; ((GrabbableObject)headlampItem).mainObjectRenderer = componentInChildren; ((GrabbableObject)headlampItem).insertedBattery = new Battery(false, 1f); headlampItem.Setup(val, val5); Prefab = val2; singleton.AddNetworkPrefab(val2); RegisterWithLethalLib(); Plugin.Log.LogInfo((object)($"Headlamp: item built from \"{itemProperties.itemName}\" (weight {Item.weight:F2}, battery {Item.batteryUsage:F0} s, " + $"collider {val8.center} {val8.size}, floor offset {Item.verticalOffset:F3}).")); } private static void RegisterWithLethalLib() { if (!_shopRegistered) { TerminalNode val = ScriptableObject.CreateInstance<TerminalNode>(); ((Object)val).name = "HeadlampInfo"; val.clearPreviousText = true; val.displayText = "HEADLAMP\n\nAn elastic headlamp that you wear on your helmet, so both hands stay free. It goes in its own small slot (on the left of the screen), not in your pockets. Press [H] to switch it on or off from anywhere.\n\nAbout 10 minutes of light per charge: select its slot and use the ship's charger to top it up.\n\n"; Items.RegisterShopItem(Item, (TerminalNode)null, (TerminalNode)null, val, Plugin.Price.Value); _shopRegistered = true; } } internal static void ApplyHostSettings(int price, float minutes) { if ((Object)(object)Item == (Object)null) { return; } if (minutes > 0f) { Item.batteryUsage = Mathf.Max(0.5f, minutes) * 60f; } if (price <= 0) { return; } Item.creditsWorth = price; Terminal val = Object.FindObjectOfType<Terminal>(); if (val?.buyableItemsList == null) { return; } Item[] buyableItemsList = val.buyableItemsList; foreach (Item val2 in buyableItemsList) { if ((Object)(object)val2 != (Object)null && val2.itemName == Item.itemName) { val2.creditsWorth = price; } } } private static uint StableHash(string s) { using MD5 mD = MD5.Create(); return BitConverter.ToUInt32(mD.ComputeHash(Encoding.UTF8.GetBytes(s)), 0); } } [HarmonyPatch] internal static class RegistryPatches { [HarmonyPatch(typeof(GameNetworkManager), "Start")] [HarmonyPostfix] private static void GameNetworkManagerStart() { Build("GameNetworkManager.Start"); } [HarmonyPatch(typeof(MenuManager), "Start")] [HarmonyPostfix] private static void MenuManagerStart() { Build("MenuManager.Start"); } private static void Build(string from) { if ((Object)(object)Registry.Prefab != (Object)null) { return; } Plugin.Log.LogInfo((object)("Headlamp: building the item (" + from + ").")); try { Registry.BuildPrefab(); } catch (Exception arg) { Plugin.Log.LogError((object)$"Headlamp: building the item failed: {arg}"); } } } internal class Runner : MonoBehaviour { private void Update() { //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: 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_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: 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_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0146: 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) if (!Plugin.DebugKeys.Value) { return; } Keyboard current = Keyboard.current; if (current == null || !((ButtonControl)current.f11Key).wasPressedThisFrame) { return; } PlayerControllerB val = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null); if (!((Object)(object)val == (Object)null) && !val.isPlayerDead && !val.isTypingChat && !val.inTerminalMenu) { if (!Net.IsHost) { Plugin.Log.LogWarning((object)"Headlamp F11: only the host can use the debug keys."); return; } if ((Object)(object)Registry.Prefab == (Object)null) { Plugin.Log.LogWarning((object)"Headlamp F11: the item isn't built."); return; } Vector3 val2 = ((Component)val).transform.position + ((Component)val).transform.forward * 1.5f + Vector3.up * 0.5f; RoundManager instance = RoundManager.Instance; Transform val3 = (((Object)(object)instance != (Object)null && (Object)(object)instance.spawnedScrapContainer != (Object)null && !StartOfRound.Instance.inShipPhase) ? instance.spawnedScrapContainer : StartOfRound.Instance.elevatorTransform); GameObject obj = Object.Instantiate<GameObject>(Registry.Prefab, val2, Quaternion.identity, val3); obj.SetActive(true); GrabbableObject component = obj.GetComponent<GrabbableObject>(); component.fallTime = 0f; Bounds bounds = StartOfRound.Instance.shipBounds.bounds; component.isInShipRoom = ((Bounds)(ref bounds)).Contains(val2); component.isInElevator = component.isInShipRoom; obj.GetComponent<NetworkObject>().Spawn(false); Plugin.Log.LogInfo((object)"Headlamp F11: spawned a headlamp."); } } } [HarmonyPatch] internal static class HudPatches { [HarmonyPatch(typeof(PlayerControllerB), "LateUpdate")] [HarmonyPostfix] private static void BatteryMeter(PlayerControllerB __instance) { if (!((NetworkBehaviour)__instance).IsOwner || !__instance.isPlayerControlled || (Object)(object)__instance != (Object)(object)StartOfRound.Instance?.localPlayerController) { return; } HUDManager instance = HUDManager.Instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.batteryMeter == (Object)null || ((Component)instance.batteryMeter).gameObject.activeSelf) { return; } HeadlampItem headlampItem = HeadlampItem.FindOn(__instance); if (!((Object)(object)headlampItem == (Object)null) && ((GrabbableObject)headlampItem).isBeingUsed && ((GrabbableObject)headlampItem).insertedBattery != null) { float num = ((GrabbableObject)headlampItem).insertedBattery.charge / 1.3f; instance.batteryMeter.fillAmount = num; ((Component)instance.batteryMeter).gameObject.SetActive(true); ((Behaviour)instance.batteryIcon).enabled = true; if ((Object)(object)instance.batteryBlinkUI != (Object)null) { instance.batteryBlinkUI.SetBool("blink", num < 0.2f && num > 0f); } } } } internal static class Slot { internal const string SlotName = "headlamp"; internal static ReservedItemSlotData Data; internal static void Register() { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0034: 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_0043: Expected O, but got Unknown Data = ReservedItemSlotData.CreateReservedItemSlotData("headlamp", Plugin.SlotPriority.Value, 0); Data.AddItemToReservedItemSlot(new ReservedItemData("Headlamp", (PlayerBone)6, Plugin.HolsterPosition.Value, Plugin.HolsterRotation.Value)); Plugin.Log.LogInfo((object)$"Headlamp: slot \"{Data.slotName}\" registered (priority {Data.slotPriority})."); } } internal static class HolsterFit { internal static readonly Vector3 Position = new Vector3(-0.00832f, 0.18688f, 0.01179f); internal static readonly Vector3 Rotation = new Vector3(358.006f, 0f, 0f); } }