using 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(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(); 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 EnableVRFix; public static ConfigEntry 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("General", "Enable VR Fix", true, "Enable VR UI fixes"); DebugMode = ((BaseUnityPlugin)this).Config.Bind("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 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(); 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(true); foreach (ScrollRect val in componentsInChildren) { if (IsScrollable(val)) { return val; } } return null; } private static ScrollRect FindAnyActiveTooltipScrollRect() { ScrollRect[] array = Resources.FindObjectsOfTypeAll(); 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(), 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); } } }