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 DoorLootFix v1.0.1
BepInEx/plugins/DoorLootFix.dll
Decompiled 20 hours agousing System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using TMPro; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("DoorLootFix")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("DoorLootFix")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("18ba3e78-ed87-48b3-9e3b-3e9246e42e4a")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.0.0")] namespace DoorLootFixMod; [HarmonyPatch(typeof(PlayerControllerB), "BeginGrabObject")] internal static class DoorLootFixBeginGrabPatch { private static readonly FieldInfo InteractableMask = AccessTools.Field(typeof(PlayerControllerB), "interactableObjectsMask"); private static readonly FieldInfo HoverTrig = AccessTools.Field(typeof(PlayerControllerB), "hoveringOverTrigger"); [HarmonyPrefix] private static void Prefix(PlayerControllerB __instance) { if (!IsLocal(__instance) || !DoorLootFixRuntime.TryGet(__instance, out var state) || (Object)(object)state?.Blocker == (Object)null) { return; } if (InteractableMask != null && !state.MaskSaved) { state.OriginalMask = (int)InteractableMask.GetValue(__instance); int layer = ((Component)state.Blocker).gameObject.layer; if (layer >= 0 && layer < 32) { int num = state.OriginalMask & ~(1 << layer); InteractableMask.SetValue(__instance, num); } state.MaskSaved = true; } HoverTrig?.SetValue(__instance, null); } [HarmonyPostfix] private static void Postfix(PlayerControllerB __instance) { Restore(__instance); } private static void Restore(PlayerControllerB p) { if (!((Object)(object)p == (Object)null) && !(InteractableMask == null) && DoorLootFixRuntime.TryGet(p, out var state) && state.MaskSaved) { InteractableMask.SetValue(p, state.OriginalMask); state.MaskSaved = false; } } private static bool IsLocal(PlayerControllerB p) { return (Object)(object)p != (Object)null && (Object)(object)GameNetworkManager.Instance != (Object)null && (Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)(object)p; } } [HarmonyPatch(typeof(PlayerControllerB), "SetHoverTipAndCurrentInteractTrigger")] internal static class DoorLootFixHoverPatch { private static readonly FieldInfo CursorTipField = AccessTools.Field(typeof(PlayerControllerB), "cursorTip"); private static readonly FieldInfo IsGrabbableField = AccessTools.Field(typeof(GrabbableObject), "isGrabbable"); private static readonly RaycastHit[] RaycastBuffer = (RaycastHit[])(object)new RaycastHit[20]; [HarmonyPostfix] private static void Postfix(PlayerControllerB __instance) { if (!IsLocal(__instance)) { return; } InteractTrigger hoveringOverTrigger = __instance.hoveringOverTrigger; DoorLootFixRuntime.State state = DoorLootFixRuntime.Get(__instance); if (!IsBlocking(hoveringOverTrigger)) { ResetState(state); return; } GrabbableObject val = FindLootBehindBlocker(__instance, hoveringOverTrigger); if ((Object)(object)val == (Object)null) { ResetState(state); return; } state.Loot = val; state.Blocker = hoveringOverTrigger; int instanceID = ((Object)val).GetInstanceID(); if (state.LastAnnouncedLootId != instanceID) { state.LastAnnouncedLootId = instanceID; SetTip(__instance, "Grab : [E]"); } } private static void ResetState(DoorLootFixRuntime.State state) { if (state != null) { state.Loot = null; state.Blocker = null; state.LastAnnouncedLootId = -1; } } private static bool IsLocal(PlayerControllerB p) { return (Object)(object)p != (Object)null && (Object)(object)GameNetworkManager.Instance != (Object)null && (Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)(object)p; } private static bool IsBlocking(InteractTrigger t) { if ((Object)(object)t == (Object)null) { return false; } if (HasParentComponentByName(((Component)t).transform, "EntranceTeleport")) { return true; } string text = ((Object)t).name.ToLowerInvariant(); return text.Contains("door") || text.Contains("entrance") || text.Contains("exit") || text.Contains("gate") || text.Contains("hatch") || text.Contains("lever") || text.Contains("button") || text.Contains("switch") || text.Contains("terminal") || text.Contains("panel") || text.Contains("teleport"); } private static bool HasParentComponentByName(Transform tr, string typeName) { if ((Object)(object)tr == (Object)null || string.IsNullOrEmpty(typeName)) { return false; } MonoBehaviour[] componentsInParent = ((Component)tr).GetComponentsInParent<MonoBehaviour>(true); for (int i = 0; i < componentsInParent.Length; i++) { if ((Object)(object)componentsInParent[i] != (Object)null && ((object)componentsInParent[i]).GetType().Name == typeName) { return true; } } return false; } private static GrabbableObject FindLootBehindBlocker(PlayerControllerB p, InteractTrigger blocker) { //IL_003d: 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_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0134: 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_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)p == (Object)null || (Object)(object)blocker == (Object)null || (Object)(object)p.gameplayCamera == (Object)null) { return null; } Transform transform = ((Component)p.gameplayCamera).transform; int num = Physics.RaycastNonAlloc(transform.position, transform.forward, RaycastBuffer, p.grabDistance, -1, (QueryTriggerInteraction)2); if (num == 0) { return null; } for (int i = 0; i < num - 1; i++) { for (int j = 0; j < num - i - 1; j++) { if (((RaycastHit)(ref RaycastBuffer[j])).distance > ((RaycastHit)(ref RaycastBuffer[j + 1])).distance) { RaycastHit val = RaycastBuffer[j]; RaycastBuffer[j] = RaycastBuffer[j + 1]; RaycastBuffer[j + 1] = val; } } } float num2 = float.MaxValue; float num3 = float.MaxValue; GrabbableObject val2 = null; for (int k = 0; k < num; k++) { RaycastHit val3 = RaycastBuffer[k]; Collider collider = ((RaycastHit)(ref val3)).collider; if ((Object)(object)collider == (Object)null) { continue; } InteractTrigger componentInParent = ((Component)collider).GetComponentInParent<InteractTrigger>(true); if ((Object)(object)componentInParent != (Object)null && IsBlocking(componentInParent)) { if (((RaycastHit)(ref val3)).distance < num2) { num2 = ((RaycastHit)(ref val3)).distance; } continue; } GrabbableObject componentInParent2 = ((Component)collider).GetComponentInParent<GrabbableObject>(true); if ((Object)(object)componentInParent2 != (Object)null && (Object)(object)componentInParent2.itemProperties != (Object)null && !componentInParent2.isHeld && !componentInParent2.isPocketed && (IsGrabbableField == null || (bool)IsGrabbableField.GetValue(componentInParent2)) && ((RaycastHit)(ref val3)).distance < num3) { num3 = ((RaycastHit)(ref val3)).distance; val2 = componentInParent2; } } if ((Object)(object)val2 == (Object)null || num3 > num2 + 0.18f) { return null; } return val2; } private static void SetTip(PlayerControllerB p, string text) { if (CursorTipField == null || (Object)(object)p == (Object)null) { return; } object value = CursorTipField.GetValue(p); if (value == null) { return; } TextMeshProUGUI val = (TextMeshProUGUI)((value is TextMeshProUGUI) ? value : null); if (val != null) { ((TMP_Text)val).text = text; return; } Text val2 = (Text)((value is Text) ? value : null); if (val2 != null) { val2.text = text; } else { value.GetType().GetProperty("text")?.SetValue(value, text, null); } } } [HarmonyPatch(typeof(PlayerControllerB), "LateUpdate")] internal static class DoorLootFixLateUpdatePatch { private static readonly FieldInfo CursorTipField = AccessTools.Field(typeof(PlayerControllerB), "cursorTip"); [HarmonyPostfix] private static void Postfix(PlayerControllerB __instance) { if (!((Object)(object)__instance == (Object)null) && !((Object)(object)GameNetworkManager.Instance == (Object)null) && !((Object)(object)GameNetworkManager.Instance.localPlayerController != (Object)(object)__instance) && DoorLootFixRuntime.TryGet(__instance, out var state) && (Object)(object)state?.Loot != (Object)null && (Object)(object)state?.Blocker != (Object)null) { SetTip(__instance, "Grab : [E]"); } } private static void SetTip(PlayerControllerB p, string text) { if (CursorTipField == null || (Object)(object)p == (Object)null) { return; } object value = CursorTipField.GetValue(p); if (value == null) { return; } TextMeshProUGUI val = (TextMeshProUGUI)((value is TextMeshProUGUI) ? value : null); if (val != null) { ((TMP_Text)val).text = text; return; } Text val2 = (Text)((value is Text) ? value : null); if (val2 != null) { val2.text = text; } else { value.GetType().GetProperty("text")?.SetValue(value, text, null); } } } internal static class DoorLootFixRuntime { internal sealed class State { public GrabbableObject Loot; public InteractTrigger Blocker; public int OriginalMask; public bool MaskSaved; public int LastAnnouncedLootId = -1; } private static readonly Dictionary<int, State> States = new Dictionary<int, State>(8); internal static State Get(PlayerControllerB p) { if ((Object)(object)p == (Object)null) { return null; } int instanceID = ((Object)p).GetInstanceID(); if (!States.TryGetValue(instanceID, out var value) || value == null) { value = new State(); States[instanceID] = value; } return value; } internal static bool TryGet(PlayerControllerB p, out State state) { state = null; if ((Object)(object)p == (Object)null) { return false; } return States.TryGetValue(((Object)p).GetInstanceID(), out state) && state != null; } internal static void Clear(PlayerControllerB p) { if ((Object)(object)p != (Object)null) { States.Remove(((Object)p).GetInstanceID()); } } } [BepInPlugin("maxteam.doorlootfix", "DoorLootFix", "1.0.1")] public sealed class Plugin : BaseUnityPlugin { public const string Guid = "maxteam.doorlootfix"; public const string Name = "DoorLootFix"; public const string Version = "1.0.1"; internal static ManualLogSource Log; private Harmony _harmony; private void Awake() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; _harmony = new Harmony("maxteam.doorlootfix"); _harmony.PatchAll(); Log.LogInfo((object)"DoorLootFix v1.0.1 successfully loaded."); } }