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 EpicLootVRFix v1.0.17
EpicLootVRFix.dll
Decompiled 5 days agousing System; using System.Collections; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("EpicLootVRFix")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("EpicLootVRFix")] [assembly: AssemblyTitle("EpicLootVRFix")] [assembly: AssemblyVersion("1.0.0.0")] public static class EpicLootVRControls { private static Coroutine _inputCoroutine; private static Type _vrControlsType; private static PropertyInfo _instanceProperty; private static MethodInfo _getButtonDownMethod; private static Type _epicLootUiType; private static MethodInfo _isVisibleMethod; private static MethodInfo _hideMethod; private static PropertyInfo _epicLootInstanceProperty; private static FieldInfo _epicLootInstanceField; private static bool _reflectionCached = false; private static int _lastCloseFrame = -1; private static readonly object[] _menuArg = new object[1] { "JoyMenu" }; private static readonly object[] _inventoryArg = new object[1] { "Inventory" }; public static void Initialize(Canvas canvas) { Cleanup(); if (!((Object)(object)canvas == (Object)null) && ((Component)canvas).gameObject.activeInHierarchy) { CacheReflection(); _inputCoroutine = ((MonoBehaviour)UIVRPatch.Instance).StartCoroutine(WaitForVRInput(canvas)); UIVRPatch.LogInfo("EpicLoot VR controls initialized"); } } public static void Stop() { Cleanup(); } private static void CacheReflection() { if (_reflectionCached) { return; } try { _vrControlsType = AccessTools.TypeByName("ValheimVRMod.VRCore.UI.VRControls"); if (_vrControlsType != null) { _instanceProperty = AccessTools.Property(_vrControlsType, "instance"); _getButtonDownMethod = AccessTools.Method(_vrControlsType, "GetButtonDown", (Type[])null, (Type[])null); } _epicLootUiType = AccessTools.TypeByName("EpicLoot_UnityLib.EnchantingTableUI"); if (_epicLootUiType != null) { _isVisibleMethod = AccessTools.Method(_epicLootUiType, "IsVisible", (Type[])null, (Type[])null); _hideMethod = AccessTools.Method(_epicLootUiType, "Hide", (Type[])null, (Type[])null); _epicLootInstanceProperty = AccessTools.Property(_epicLootUiType, "instance"); _epicLootInstanceField = AccessTools.Field(_epicLootUiType, "instance"); } _reflectionCached = true; } catch (Exception arg) { UIVRPatch.LogError($"Error caching reflection: {arg}"); } } private static IEnumerator WaitForVRInput(Canvas canvas) { while (true) { yield return null; if (!IsEpicLootUIVisible()) { break; } try { if (IsVRMenuButtonPressed()) { CloseEpicLootUI(); yield break; } } catch (Exception arg) { UIVRPatch.LogError($"Error in VR input check: {arg}"); } } Cleanup(); } private static bool IsVRMenuButtonPressed() { if (!_reflectionCached || _vrControlsType == null) { return false; } try { object obj = _instanceProperty?.GetValue(null); if (obj != null) { bool num = (bool)_getButtonDownMethod.Invoke(obj, _menuArg); bool flag = (bool)_getButtonDownMethod.Invoke(obj, _inventoryArg); return num || flag; } } catch (Exception arg) { UIVRPatch.LogError($"VR input error: {arg}"); } return false; } public static bool IsEpicLootUIVisible() { try { CacheReflection(); object obj = _isVisibleMethod?.Invoke(null, null); if (obj is bool) { return (bool)obj; } } catch (Exception arg) { UIVRPatch.LogError($"Error checking EpicLoot UI visibility: {arg}"); } return false; } public static void PollGlobalCloseInput() { try { if (UIVRPatch.EnableVRFix.Value && IsEpicLootUIVisible() && IsVRMenuButtonPressed()) { CloseEpicLootUI(); } } catch (Exception arg) { UIVRPatch.LogError($"Error polling EpicLoot global close input: {arg}"); } } private static void CloseEpicLootUI() { if (_lastCloseFrame == Time.frameCount) { return; } _lastCloseFrame = Time.frameCount; try { CacheReflection(); _ = _epicLootUiType; MethodInfo hideMethod = _hideMethod; if (hideMethod == null) { UIVRPatch.LogWarning("EpicLoot EnchantingTableUI.Hide() was not found"); Cleanup(); return; } object obj = null; if (!hideMethod.IsStatic) { obj = EpicLootVRUI.GetActiveEnchantingUI() ?? _epicLootInstanceField?.GetValue(null) ?? _epicLootInstanceProperty?.GetValue(null, null); if (obj == null) { UIVRPatch.LogWarning("EpicLoot EnchantingTableUI.Hide() is instance-based, but no active instance was available"); Cleanup(); return; } } hideMethod.Invoke(obj, null); } catch (Exception arg) { UIVRPatch.LogError($"Error closing EpicLoot UI: {arg}"); } Cleanup(); } private static void Cleanup() { if (_inputCoroutine != null) { ((MonoBehaviour)UIVRPatch.Instance).StopCoroutine(_inputCoroutine); _inputCoroutine = null; } } } public static class EpicLootVRUI { private static Type _uiType; private static Type _vrguiType; private static FieldInfo _guiCameraField; private static FieldInfo _guiCanvasesField; private static bool _cached; private static object _activeEnchantingUI; private static Coroutine _reopenCoroutine; private static void CacheReflection() { if (_cached) { return; } try { _uiType = AccessTools.TypeByName("EpicLoot_UnityLib.EnchantingTableUI"); _vrguiType = AccessTools.TypeByName("ValheimVRMod.VRCore.UI.VRGUI"); if (_vrguiType != null) { _guiCameraField = AccessTools.Field(_vrguiType, "_guiCamera"); _guiCanvasesField = AccessTools.Field(_vrguiType, "_guiCanvases"); } _cached = true; UIVRPatch.LogInfo("EpicLootVRUI reflection cached"); } catch (Exception arg) { UIVRPatch.LogError($"Reflection cache failed: {arg}"); } } public static bool IsEpicLootLoaded() { try { if (!_cached) { CacheReflection(); } return _uiType != null; } catch { return false; } } public static void PatchEpicLootUI(Harmony harmony) { try { CacheReflection(); if (!(_uiType == null)) { PatchLifecycleMethod(harmony, "Awake", "OnUIOpened", "creation"); PatchLifecycleMethod(harmony, "Show", "OnUIOpened", "show"); PatchLifecycleMethod(harmony, "Hide", "OnUIClosed", "hide"); } } catch (Exception arg) { UIVRPatch.LogError($"Error patching EpicLoot: {arg}"); } } private static void PatchLifecycleMethod(Harmony harmony, string methodName, string postfixName, string reason) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown MethodInfo method = _uiType.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (method == null) { UIVRPatch.LogWarning("EpicLoot UI has no " + methodName + "() method to patch for VR " + reason); return; } string text = ((method.IsStatic && postfixName == "OnUIOpened") ? "OnUIOpenedStatic" : postfixName); harmony.Patch((MethodBase)method, (HarmonyMethod)null, new HarmonyMethod(typeof(EpicLootVRUI), text, (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); UIVRPatch.LogInfo("Patched EpicLoot UI " + methodName + "() for VR " + reason); } public static void OnUIOpenedStatic() { try { OnUIOpened(AccessTools.PropertyGetter(_uiType, "instance")?.Invoke(null, null) ?? AccessTools.Field(_uiType, "instance")?.GetValue(null)); } catch (Exception arg) { UIVRPatch.LogError($"OnUIOpenedStatic error: {arg}"); } } public static void OnUIOpened(object __instance) { try { if (__instance != null) { _activeEnchantingUI = __instance; Component val = (Component)((__instance is Component) ? __instance : null); if (!((Object)(object)val == (Object)null)) { ScheduleProcessWhenVisible(val); } } } catch (Exception arg) { UIVRPatch.LogError($"OnUIOpened error: {arg}"); } } public static void OnUIClosed(object __instance) { try { if (_reopenCoroutine != null && (Object)(object)UIVRPatch.Instance != (Object)null) { ((MonoBehaviour)UIVRPatch.Instance).StopCoroutine(_reopenCoroutine); _reopenCoroutine = null; } EpicLootVRControls.Stop(); } catch (Exception arg) { UIVRPatch.LogError($"OnUIClosed error: {arg}"); } } public static object GetActiveEnchantingUI() { return _activeEnchantingUI; } private static void ScheduleProcessWhenVisible(Component component) { if (!((Object)(object)component == (Object)null) && !((Object)(object)UIVRPatch.Instance == (Object)null)) { if (_reopenCoroutine != null) { ((MonoBehaviour)UIVRPatch.Instance).StopCoroutine(_reopenCoroutine); _reopenCoroutine = null; } _reopenCoroutine = ((MonoBehaviour)UIVRPatch.Instance).StartCoroutine(ProcessWhenVisible(component)); } } private static IEnumerator ProcessWhenVisible(Component component) { for (int attempt = 0; attempt < 45; attempt++) { if ((Object)(object)component == (Object)null) { break; } Canvas componentInChildren = component.GetComponentInChildren<Canvas>(true); if ((Object)(object)componentInChildren != (Object)null) { ProcessCanvas(componentInChildren); if (((Component)componentInChildren).gameObject.activeInHierarchy) { _reopenCoroutine = null; yield break; } } yield return null; } UIVRPatch.LogWarning("EpicLoot enchanting UI canvas was not active after reopen retry window"); _reopenCoroutine = null; } private static void ProcessCanvas(Canvas canvas) { try { object vHVRVRGUI = GetVHVRVRGUI(); if (vHVRVRGUI != null) { AddCanvasToVHVR(canvas, vHVRVRGUI); SetupCanvas(canvas, vHVRVRGUI); EpicLootVRControls.Initialize(canvas); UIVRPatch.LogInfo("EpicLoot UI processed (event-driven)"); } } catch (Exception arg) { UIVRPatch.LogError($"ProcessCanvas error: {arg}"); } } private static object GetVHVRVRGUI() { try { if (_vrguiType == null) { return null; } Object[] array = Object.FindObjectsByType(_vrguiType, (FindObjectsSortMode)0); return (array.Length != 0) ? array[0] : null; } catch (Exception arg) { UIVRPatch.LogError($"Error getting VRGUI: {arg}"); return null; } } private static void AddCanvasToVHVR(Canvas canvas, object vrguiInstance) { try { if (!(_guiCanvasesField == null) && _guiCanvasesField.GetValue(vrguiInstance) is IList list && !list.Contains(canvas)) { list.Add(canvas); } } catch (Exception arg) { UIVRPatch.LogWarning($"Error adding canvas: {arg}"); } } private static void SetupCanvas(Canvas canvas, object vrguiInstance) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) try { if (_guiCameraField == null) { return; } object? value = _guiCameraField.GetValue(vrguiInstance); Camera val = (Camera)((value is Camera) ? value : null); if (!((Object)(object)val == (Object)null)) { canvas.renderMode = (RenderMode)2; canvas.worldCamera = val; RectTransform component = ((Component)canvas).GetComponent<RectTransform>(); if ((Object)(object)component != (Object)null) { ((Transform)component).localScale = Vector3.one; } } } catch (Exception arg) { UIVRPatch.LogError($"SetupCanvas error: {arg}"); } } } [BepInPlugin("EpicLootVRFix", "Epic Loot VR Fix", "1.0.17")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class UIVRPatch : BaseUnityPlugin { public static ConfigEntry<bool> EnableVRFix; public static ConfigEntry<bool> DebugMode; public static UIVRPatch Instance; private Harmony _harmony; private bool _patched; public ManualLogSource Logger => ((BaseUnityPlugin)this).Logger; private void Awake() { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown Instance = this; EnableVRFix = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enable VR Fix", true, "Enable VR UI fixes"); DebugMode = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Debug Mode", false, "Enable debug logging (for testing only)"); if (EnableVRFix.Value) { _harmony = new Harmony("EpicLootVRFix"); _harmony.PatchAll(); ((MonoBehaviour)this).StartCoroutine(WaitForEpicLootAndPatch()); } } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } private void Update() { ConfigEntry<bool> enableVRFix = EnableVRFix; if (enableVRFix != null && enableVRFix.Value) { EpicLootVRControls.PollGlobalCloseInput(); } } private IEnumerator WaitForEpicLootAndPatch() { while (!EpicLootVRUI.IsEpicLootLoaded()) { yield return (object)new WaitForSeconds(2f); } if (!_patched) { _patched = true; LogInfo("EpicLoot detected! Applying VR fixes..."); EpicLootVRUI.PatchEpicLootUI(_harmony); } } public static void LogInfo(string message) { if (DebugMode.Value) { Instance.Logger.LogInfo((object)message); } } public static void LogWarning(string message) { if (DebugMode.Value) { Instance.Logger.LogWarning((object)message); } } public static void LogError(string message) { Instance.Logger.LogError((object)message); } } namespace EpicLootVRFix; [HarmonyPatch] public static class EpicLootVRTooltipFix { private static readonly int UILayer = LayerMask.NameToLayer("UI"); private static MethodBase TargetMethod() { return AccessTools.Method("EpicLoot.PatchOnHoverFix:AddScrollbar", (Type[])null, (Type[])null); } private static void Postfix(GameObject tooltipObject) { try { if (!UIVRPatch.EnableVRFix.Value || (Object)(object)tooltipObject == (Object)null) { return; } Transform val = tooltipObject.transform.Find("Canvas"); if ((Object)(object)val == (Object)null) { return; } Transform val2 = val.Find("Scroll View"); if (!((Object)(object)val2 == (Object)null)) { ScrollRect component = ((Component)val2).GetComponent<ScrollRect>(); if ((Object)(object)component != (Object)null) { EpicLootVRTooltipScrollState.RegisterTooltipScrollRect(component); } val2.SetParent(tooltipObject.transform, true); SetLayerRecursive(((Component)val2).gameObject, UILayer); if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)((Component)val).gameObject); } } } catch (Exception ex) { UIVRPatch.LogError("EpicLootVRTooltipFix error: " + ex); } } private static void SetLayerRecursive(GameObject obj, int layer) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) obj.layer = layer; foreach (Transform item in obj.transform) { SetLayerRecursive(((Component)item).gameObject, layer); } } } internal static class EpicLootVRTooltipScrollState { private const float Deadzone = 0.18f; private const float ScrollSpeed = 3.8f; private const float DigitalScrollHoldSeconds = 0.28f; private const float SyntheticWheelStep = 0.22f; private static ScrollRect _cachedScrollRect; private static ScrollRect _registeredScrollRect; private static GameObject _cachedTooltip; private static int _lastScrollFrame = -1; private static float _lastAxis; private static float _setControlsAxis; private static float _setControlsAxisUntil; private static FieldInfo _uiTooltipField; private static bool _steamVrCached; private static FieldInfo _toggleCrouchField; private static FieldInfo _toggleRunField; private static FieldInfo _holdRunField; private static PropertyInfo _stateProperty; private static MethodInfo _getStateMethod; private static Type _inputSourcesType; private static MethodInfo _vrControlsInstanceGetter; private static MethodInfo _getDirectRightYAxisMethod; public static void RegisterTooltipScrollRect(ScrollRect scrollRect) { if (!((Object)(object)scrollRect == (Object)null)) { _registeredScrollRect = scrollRect; _cachedScrollRect = scrollRect; UIVRPatch.LogInfo("Registered EpicLoot tooltip ScrollRect for VR right-stick scrolling"); } } public static bool ShouldConsumeRightStickY() { if (UIVRPatch.EnableVRFix.Value) { return IsInventoryOpen(); } return false; } public static bool HasActiveScrollTarget() { if (ShouldConsumeRightStickY()) { return (Object)(object)GetActiveScrollableTooltip() != (Object)null; } return false; } public static float GetSyntheticMouseWheelAxis() { if (!HasActiveScrollTarget()) { return 0f; } if (Mathf.Abs(_lastAxis) > 0.18f) { return Mathf.Sign(_lastAxis) * 0.22f; } CacheSteamVrReflection(); if (GetSteamVrActionState(_toggleCrouchField)) { return -0.22f; } if (GetSteamVrActionState(_toggleRunField) || GetSteamVrActionState(_holdRunField)) { return 0.22f; } return 0f; } public static void TryScroll(float axis) { float num = 0f - axis; _lastAxis = ((Mathf.Abs(num) > 0.18f) ? num : 0f); if (Mathf.Abs(num) > 0.18f) { _setControlsAxis = num; _setControlsAxisUntil = Time.unscaledTime + 0.28f; } TryScrollInternal(num); } public static float GetCurrentVrScrollAxis() { if (!ShouldConsumeRightStickY()) { return 0f; } float directRightStickYAxis = GetDirectRightStickYAxis(); if (Mathf.Abs(directRightStickYAxis) > 0.18f) { return directRightStickYAxis; } if (Mathf.Abs(_lastAxis) > 0.18f) { return _lastAxis; } if (Mathf.Abs(_setControlsAxis) > 0.18f && Time.unscaledTime <= _setControlsAxisUntil) { return _setControlsAxis; } if (Time.unscaledTime > _setControlsAxisUntil) { _setControlsAxis = 0f; } CacheSteamVrReflection(); if (GetSteamVrActionState(_toggleCrouchField)) { return -1f; } if (GetSteamVrActionState(_toggleRunField) || GetSteamVrActionState(_holdRunField)) { return 1f; } return 0f; } public static void ScrollRectByAxis(ScrollRect scrollRect, float axis) { if (!((Object)(object)scrollRect == (Object)null) && !(Mathf.Abs(axis) <= 0.18f)) { Canvas.ForceUpdateCanvases(); float num = axis * 3.8f * Time.unscaledDeltaTime; scrollRect.verticalNormalizedPosition = Mathf.Clamp01(scrollRect.verticalNormalizedPosition + num); Canvas.ForceUpdateCanvases(); } } public static void TryScrollLastAxis() { TryScrollInternal(_lastAxis); } public static void TryScrollFromSetControls(bool run, bool crouch) { if (ShouldConsumeRightStickY()) { float num = 0f; if (crouch) { num = -1f; } else if (run) { num = 1f; } if (Mathf.Abs(num) > 0.18f) { _setControlsAxis = num; _setControlsAxisUntil = Time.unscaledTime + 0.28f; } else if (Time.unscaledTime > _setControlsAxisUntil) { _setControlsAxis = 0f; } TryScrollInternal(num); } } private static void TryScrollInternal(float axis) { if (ShouldConsumeRightStickY() && !(Mathf.Abs(axis) <= 0.18f) && _lastScrollFrame != Time.frameCount) { ScrollRect activeScrollableTooltip = GetActiveScrollableTooltip(); if (!((Object)(object)activeScrollableTooltip == (Object)null)) { float num = axis * 3.8f * Time.unscaledDeltaTime; Canvas.ForceUpdateCanvases(); activeScrollableTooltip.verticalNormalizedPosition = Mathf.Clamp01(activeScrollableTooltip.verticalNormalizedPosition + num); Canvas.ForceUpdateCanvases(); _lastScrollFrame = Time.frameCount; } } } private static bool IsInventoryOpen() { try { return InventoryGui.IsVisible(); } catch { return false; } } private static float GetDirectRightStickYAxis() { CacheSteamVrReflection(); try { object obj = _vrControlsInstanceGetter?.Invoke(null, null); if (obj == null || _getDirectRightYAxisMethod == null) { return 0f; } if (_getDirectRightYAxisMethod.Invoke(obj, null) is int num) { return Mathf.Clamp(num, -1, 1); } } catch { return 0f; } return 0f; } private static bool GetSteamVrActionState(FieldInfo actionField) { CacheSteamVrReflection(); try { object obj = actionField?.GetValue(null); if (obj == null) { return false; } if (_stateProperty != null && _stateProperty.GetValue(obj, null) is bool result) { return result; } if (_getStateMethod != null && _inputSourcesType != null) { object obj2 = Enum.ToObject(_inputSourcesType, 0); if (_getStateMethod.Invoke(obj, new object[1] { obj2 }) is bool result2) { return result2; } } } catch { return false; } return false; } private static void CacheSteamVrReflection() { if (!_steamVrCached) { _steamVrCached = true; _uiTooltipField = AccessTools.Field(typeof(UITooltip), "m_tooltip"); Type type = AccessTools.TypeByName("SteamVR_Actions"); _toggleCrouchField = AccessTools.Field(type, "valheim_ToggleCrouch"); _toggleRunField = AccessTools.Field(type, "valheim_ToggleRun"); _holdRunField = AccessTools.Field(type, "valheim_HoldRun"); Type type2 = AccessTools.TypeByName("ValheimVRMod.VRCore.UI.VRControls"); _vrControlsInstanceGetter = AccessTools.PropertyGetter(type2, "instance"); _getDirectRightYAxisMethod = AccessTools.Method(type2, "getDirectRightYAxis", (Type[])null, (Type[])null); Type type3 = AccessTools.TypeByName("Valve.VR.SteamVR_Action_Boolean"); _inputSourcesType = AccessTools.TypeByName("Valve.VR.SteamVR_Input_Sources"); _stateProperty = AccessTools.Property(type3, "state"); _getStateMethod = AccessTools.Method(type3, "GetState", new Type[1] { _inputSourcesType }, (Type[])null); } } private static ScrollRect GetActiveScrollableTooltip() { if (IsUsableRegisteredScrollRect(_registeredScrollRect)) { return _registeredScrollRect; } _registeredScrollRect = null; GameObject currentTooltipObject = GetCurrentTooltipObject(); if ((Object)(object)currentTooltipObject != (Object)null && currentTooltipObject.activeInHierarchy) { if ((Object)(object)_cachedTooltip != (Object)(object)currentTooltipObject || (Object)(object)_cachedScrollRect == (Object)null) { _cachedTooltip = currentTooltipObject; _cachedScrollRect = FindScrollableInTooltip(currentTooltipObject); } if (IsScrollable(_cachedScrollRect)) { return _cachedScrollRect; } } _cachedTooltip = null; _cachedScrollRect = FindAnyActiveTooltipScrollRect(); return _cachedScrollRect; } private static GameObject GetCurrentTooltipObject() { try { CacheSteamVrReflection(); object? obj = _uiTooltipField?.GetValue(null); return (GameObject)((obj is GameObject) ? obj : null); } catch { return null; } } private static ScrollRect FindScrollableInTooltip(GameObject tooltip) { ScrollRect[] componentsInChildren = tooltip.GetComponentsInChildren<ScrollRect>(true); foreach (ScrollRect val in componentsInChildren) { if (IsScrollable(val)) { return val; } } return null; } private static ScrollRect FindAnyActiveTooltipScrollRect() { ScrollRect[] array = Resources.FindObjectsOfTypeAll<ScrollRect>(); foreach (ScrollRect val in array) { if (IsScrollable(val)) { string name = ((Object)((Component)val).gameObject).name; Transform parent = ((Component)val).transform.parent; string text = (((Object)(object)parent != (Object)null) ? ((Object)parent).name : string.Empty); if (name.Contains("Scroll") || text.Contains("Tooltip") || text.Contains("ItemTooltip")) { return val; } } } return null; } private static bool IsUsableRegisteredScrollRect(ScrollRect scrollRect) { if ((Object)(object)scrollRect != (Object)null && ((Component)scrollRect).gameObject.activeInHierarchy && scrollRect.vertical) { return (Object)(object)scrollRect.content != (Object)null; } return false; } private static bool IsScrollable(ScrollRect scrollRect) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: 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_005a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)scrollRect == (Object)null || !((Component)scrollRect).gameObject.activeInHierarchy || !scrollRect.vertical) { return false; } if ((Object)(object)scrollRect.content != (Object)null && (Object)(object)scrollRect.viewport != (Object)null) { Rect rect = scrollRect.content.rect; float height = ((Rect)(ref rect)).height; rect = scrollRect.viewport.rect; float height2 = ((Rect)(ref rect)).height; if (height > height2 + 1f) { return true; } } if ((Object)(object)scrollRect.verticalScrollbar != (Object)null) { return scrollRect.verticalScrollbar.size < 0.999f; } return false; } } [HarmonyPatch] public static class EpicLootVRScrollWheelHandlerUpdatePatch { private static MethodBase TargetMethod() { return AccessTools.Method("EpicLoot.ScrollWheelHandler:Update", (Type[])null, (Type[])null) ?? AccessTools.Method("ScrollWheelHandler:Update", (Type[])null, (Type[])null); } [HarmonyPriority(0)] private static void Postfix(Component __instance) { try { float currentVrScrollAxis = EpicLootVRTooltipScrollState.GetCurrentVrScrollAxis(); if (!(Mathf.Abs(currentVrScrollAxis) <= 0f)) { EpicLootVRTooltipScrollState.ScrollRectByAxis(__instance.GetComponent<ScrollRect>(), currentVrScrollAxis); } } catch (Exception ex) { UIVRPatch.LogError("EpicLootVRScrollWheelHandlerUpdatePatch error: " + ex); } } } [HarmonyPatch(typeof(Input), "GetAxis", new Type[] { typeof(string) })] public static class EpicLootVRMouseScrollWheelAxisPatch { [HarmonyPriority(0)] private static void Postfix(string axisName, ref float __result) { try { if (!(axisName != "Mouse ScrollWheel")) { float syntheticMouseWheelAxis = EpicLootVRTooltipScrollState.GetSyntheticMouseWheelAxis(); if (Mathf.Abs(syntheticMouseWheelAxis) > 0f) { __result = syntheticMouseWheelAxis; } } } catch (Exception ex) { UIVRPatch.LogError("EpicLootVRMouseScrollWheelAxisPatch error: " + ex); } } } [HarmonyPatch] public static class EpicLootVRControlsRightStickYPatch { private static MethodBase TargetMethod() { return AccessTools.Method("ValheimVRMod.VRCore.UI.VRControls:GetJoyRightStickY", (Type[])null, (Type[])null); } [HarmonyPriority(0)] private static void Postfix(ref float __result) { try { if (EpicLootVRTooltipScrollState.ShouldConsumeRightStickY()) { EpicLootVRTooltipScrollState.TryScroll(__result); } } catch (Exception ex) { UIVRPatch.LogError("EpicLootVRControlsRightStickYPatch error: " + ex); } } } [HarmonyPatch] public static class EpicLootVRZInputRightStickYPatch { private static MethodBase TargetMethod() { return AccessTools.Method("ZInput:GetJoyRightStickY", (Type[])null, (Type[])null); } [HarmonyPriority(0)] private static void Postfix(ref float __result) { try { if (EpicLootVRTooltipScrollState.ShouldConsumeRightStickY()) { EpicLootVRTooltipScrollState.TryScroll(__result); __result = 0f; } } catch (Exception ex) { UIVRPatch.LogError("EpicLootVRZInputRightStickYPatch error: " + ex); } } } [HarmonyPatch] public static class EpicLootVRPlayerSetControlsPatch { private static MethodBase TargetMethod() { return AccessTools.Method("Player:SetControls", (Type[])null, (Type[])null); } [HarmonyPriority(0)] private static void Prefix(object __instance, ref bool run, ref bool crouch) { try { if (EpicLootVRTooltipScrollState.ShouldConsumeRightStickY()) { EpicLootVRTooltipScrollState.TryScrollFromSetControls(run, crouch); EpicLootVRTooltipScrollState.TryScrollLastAxis(); run = false; crouch = false; } } catch (Exception ex) { UIVRPatch.LogError("EpicLootVRPlayerSetControlsPatch error: " + ex); } } }