Merge remote-tracking branch 'PickupPushPull/main'

Merge PickupPushPull
This commit is contained in:
NotAKidoS 2023-04-16 06:57:05 -05:00
commit 31d5ad9554
9 changed files with 507 additions and 0 deletions

View file

@ -0,0 +1,34 @@
using ABI.CCK.Components;
using ABI_RC.Core.Player;
using ABI_RC.Core.Savior;
using HarmonyLib;
using UnityEngine;
using NAK.Melons.PickupPushPull.InputModules;
namespace NAK.Melons.PickupPushPull.HarmonyPatches;
[HarmonyPatch]
internal class HarmonyPatches
{
//uses code from https://github.com/ljoonal/CVR-Plugins/tree/main/RotateIt
//GPL-3.0 license - Thank you ljoonal for being smart brain :plead:
[HarmonyPostfix]
[HarmonyPatch(typeof(CVRPickupObject), "Update")]
public static void GrabbedObjectPatch(ref CVRPickupObject __instance)
{
// Need to only run when the object is grabbed by the local player
if (__instance._controllerRay == null) return;
//and only if its a prop we support
if (__instance.gripType == CVRPickupObject.GripType.Origin) return;
Quaternion originalRotation = __instance.transform.rotation;
Transform referenceTransform = __instance._controllerRay.transform;
__instance.transform.RotateAround(__instance.transform.position, referenceTransform.right, PickupPushPull_Module.Instance.objectRotation.y * Time.deltaTime);
__instance.transform.RotateAround(__instance.transform.position, referenceTransform.up, PickupPushPull_Module.Instance.objectRotation.x * Time.deltaTime);
// Add the new difference between the og rotation and our newly added rotation the the stored offset.
__instance.initialRotationalOffset *= Quaternion.Inverse(__instance.transform.rotation) * originalRotation;
}
}

View file

@ -0,0 +1,33 @@
using ABI_RC.Core.Savior;
using System.Reflection;
namespace NAK.Melons.PickupPushPull.InputModules.Info;
// Stolen from my scrapped Enhanced Input mod
internal class EI_SteamVR_Info
{
//General Inputs
internal static readonly FieldInfo im_vrMovementAction = typeof(InputModuleSteamVR).GetField("vrMovementAction", BindingFlags.NonPublic | BindingFlags.Instance);
internal static readonly FieldInfo im_vrJumpAction = typeof(InputModuleSteamVR).GetField("vrJumpAction", BindingFlags.NonPublic | BindingFlags.Instance);
internal static readonly FieldInfo im_vrLookAction = typeof(InputModuleSteamVR).GetField("vrLookAction", BindingFlags.NonPublic | BindingFlags.Instance);
internal static readonly FieldInfo im_vrMuteAction = typeof(InputModuleSteamVR).GetField("vrMuteAction", BindingFlags.NonPublic | BindingFlags.Instance);
internal static readonly FieldInfo im_vrMenuButton = typeof(InputModuleSteamVR).GetField("vrMenuButton", BindingFlags.NonPublic | BindingFlags.Instance);
internal static readonly FieldInfo im_vrTriggerValue = typeof(InputModuleSteamVR).GetField("vrTriggerValue", BindingFlags.NonPublic | BindingFlags.Instance);
internal static readonly FieldInfo im_vrGripValue = typeof(InputModuleSteamVR).GetField("vrGripValue", BindingFlags.NonPublic | BindingFlags.Instance);
//Vive Controllers
internal static readonly FieldInfo im_vrTouchPadValue = typeof(InputModuleSteamVR).GetField("vrTouchPadValue", BindingFlags.NonPublic | BindingFlags.Instance);
internal static readonly FieldInfo im_vrTouchPadClick = typeof(InputModuleSteamVR).GetField("vrTouchPadClick", BindingFlags.NonPublic | BindingFlags.Instance);
internal static readonly FieldInfo im_vrTouchPadTouch = typeof(InputModuleSteamVR).GetField("vrTouchPadTouch", BindingFlags.NonPublic | BindingFlags.Instance);
//Knuckles Controllers
internal static readonly FieldInfo im_steamVrIndexSkeletonLeft = typeof(InputModuleSteamVR).GetField("steamVrIndexSkeletonLeft", BindingFlags.NonPublic | BindingFlags.Instance);
internal static readonly FieldInfo im_steamVrIndexSkeletonRight = typeof(InputModuleSteamVR).GetField("steamVrIndexSkeletonRight", BindingFlags.NonPublic | BindingFlags.Instance);
internal static readonly FieldInfo im_steamVrIndexGestureToggle = typeof(InputModuleSteamVR).GetField("steamVrIndexGestureToggle", BindingFlags.NonPublic | BindingFlags.Instance);
//Touch Controllers
internal static readonly FieldInfo im_steamVrTriggerTouch = typeof(InputModuleSteamVR).GetField("steamVrTriggerTouch", BindingFlags.Public | BindingFlags.Instance);
internal static readonly FieldInfo im_steamVrGripTouch = typeof(InputModuleSteamVR).GetField("steamVrGripTouch", BindingFlags.Public | BindingFlags.Instance);
internal static readonly FieldInfo im_steamVrStickTouch = typeof(InputModuleSteamVR).GetField("steamVrStickTouch", BindingFlags.Public | BindingFlags.Instance);
internal static readonly FieldInfo im_steamVrButtonATouch = typeof(InputModuleSteamVR).GetField("steamVrButtonATouch", BindingFlags.Public | BindingFlags.Instance);
internal static readonly FieldInfo im_steamVrButtonBTouch = typeof(InputModuleSteamVR).GetField("steamVrButtonBTouch", BindingFlags.Public | BindingFlags.Instance);
//SteamVR Specific
//internal static readonly FieldInfo im_steamVrVibration = typeof(InputModuleSteamVR).GetField("steamVrVibration", BindingFlags.NonPublic | BindingFlags.Instance);
}

View file

@ -0,0 +1,201 @@
using ABI.CCK.Components;
using ABI_RC.Core;
using ABI_RC.Core.InteractionSystem;
using ABI_RC.Core.Player;
using ABI_RC.Core.Savior;
using NAK.Melons.PickupPushPull.InputModules.Info;
using System.Reflection;
using UnityEngine;
using UnityEngine.Events;
using Valve.VR;
namespace NAK.Melons.PickupPushPull.InputModules;
public class PickupPushPull_Module : CVRInputModule
{
//Reflection shit
private static readonly FieldInfo _grabbedObject = typeof(ControllerRay).GetField("grabbedObject", BindingFlags.NonPublic | BindingFlags.Instance);
//Global stuff
public static PickupPushPull_Module Instance;
public Vector2 objectRotation = Vector2.zero;
//Global settings
public float Setting_PushPullSpeed = 100f;
public float Setting_RotationSpeed = 200f;
public bool Setting_EnableRotation = false;
//Desktop settings
public bool Desktop_UseZoomForRotate = true;
//VR settings
public BindingOptionsVR.BindHand VR_RotateHand = BindingOptionsVR.BindHand.LeftHand;
public BindingOptionsVR.BindingOptions VR_RotateBind = BindingOptionsVR.BindingOptions.ButtonATouch;
private SteamVR_Action_Boolean VR_RotateBind_Boolean;
//Local stuff
private CVRInputManager _inputManager;
private ControllerRay desktopControllerRay;
private float deadzoneRightValue;
private bool controlGamepadEnabled;
//SteamVR Input
private SteamVR_Action_Vector2 vrLookAction;
private SteamVR_Action_Boolean steamVrTriggerTouch;
private SteamVR_Action_Boolean steamVrGripTouch;
private SteamVR_Action_Boolean steamVrStickTouch;
private SteamVR_Action_Boolean steamVrButtonATouch;
private SteamVR_Action_Boolean steamVrButtonBTouch;
public new void Start()
{
_inputManager = CVRInputManager.Instance;
Instance = this;
base.Start();
//Get desktop controller ray
desktopControllerRay = PlayerSetup.Instance.desktopCamera.GetComponent<ControllerRay>();
//Touch Controllers
InputModuleSteamVR inputModuleSteamVR = GetComponent<InputModuleSteamVR>();
vrLookAction = (SteamVR_Action_Vector2)EI_SteamVR_Info.im_vrLookAction.GetValue(inputModuleSteamVR);
steamVrTriggerTouch = (SteamVR_Action_Boolean)EI_SteamVR_Info.im_steamVrTriggerTouch.GetValue(inputModuleSteamVR);
steamVrGripTouch = (SteamVR_Action_Boolean)EI_SteamVR_Info.im_steamVrGripTouch.GetValue(inputModuleSteamVR);
steamVrStickTouch = (SteamVR_Action_Boolean)EI_SteamVR_Info.im_steamVrStickTouch.GetValue(inputModuleSteamVR);
steamVrButtonATouch = (SteamVR_Action_Boolean)EI_SteamVR_Info.im_steamVrButtonATouch.GetValue(inputModuleSteamVR);
steamVrButtonBTouch = (SteamVR_Action_Boolean)EI_SteamVR_Info.im_steamVrButtonBTouch.GetValue(inputModuleSteamVR);
controlGamepadEnabled = (bool)MetaPort.Instance.settings.GetSettingsBool("ControlEnableGamepad", false);
MetaPort.Instance.settings.settingBoolChanged.AddListener(new UnityAction<string, bool>(SettingsBoolChanged));
deadzoneRightValue = (float)MetaPort.Instance.settings.GetSettingInt("ControlDeadZoneRight", 0) / 100f;
MetaPort.Instance.settings.settingIntChanged.AddListener(new UnityAction<string, int>(SettingsIntChanged));
UpdateVRBinding();
}
private void SettingsBoolChanged(string name, bool value)
{
if (name == "ControlEnableGamepad")
controlGamepadEnabled = value;
}
private void SettingsIntChanged(string name, int value)
{
if (name == "ControlDeadZoneRight")
deadzoneRightValue = (float)value / 100f;
}
public void UpdateVRBinding()
{
switch (VR_RotateBind)
{
case BindingOptionsVR.BindingOptions.ButtonATouch:
VR_RotateBind_Boolean = steamVrButtonATouch;
break;
case BindingOptionsVR.BindingOptions.ButtonBTouch:
VR_RotateBind_Boolean = steamVrButtonBTouch;
break;
case BindingOptionsVR.BindingOptions.StickTouch:
VR_RotateBind_Boolean = steamVrStickTouch;
break;
case BindingOptionsVR.BindingOptions.TriggerTouch:
VR_RotateBind_Boolean = steamVrTriggerTouch;
break;
case BindingOptionsVR.BindingOptions.GripTouch:
VR_RotateBind_Boolean = steamVrGripTouch;
break;
default:
break;
}
}
//this will run while menu is being hovered
public override void UpdateImportantInput()
{
objectRotation = Vector2.zero;
}
//this will only run outside of menus
public override void UpdateInput()
{
objectRotation = Vector2.zero;
CVRPickupObject desktopObject = (CVRPickupObject)_grabbedObject.GetValue(desktopControllerRay);
if (desktopObject != null && desktopObject.gripType == CVRPickupObject.GripType.Free)
{
//Desktop Input
DoDesktopInput();
//Gamepad Input
DoGamepadInput();
}
//VR Input
if (!MetaPort.Instance.isUsingVr) return;
DoSteamVRInput();
}
private void DoDesktopInput()
{
if (!Desktop_UseZoomForRotate) return;
//mouse rotation when zoomed
if (Setting_EnableRotation && _inputManager.zoom)
{
objectRotation.x += Setting_RotationSpeed * _inputManager.rawLookVector.x;
objectRotation.y += Setting_RotationSpeed * _inputManager.rawLookVector.y * -1;
_inputManager.lookVector = Vector2.zero;
_inputManager.zoom = false;
return;
}
}
private void DoGamepadInput()
{
if (!controlGamepadEnabled) return;
//not sure how to make settings for this
bool button1 = Input.GetButton("Controller Left Button");
bool button2 = Input.GetButton("Controller Right Button");
if (button1 || button2)
{
//Rotation
if (Setting_EnableRotation && button2)
{
objectRotation.x += Setting_RotationSpeed * _inputManager.rawLookVector.x;
objectRotation.y += Setting_RotationSpeed * _inputManager.rawLookVector.y * -1;
_inputManager.lookVector = Vector2.zero;
return;
}
_inputManager.objectPushPull += _inputManager.rawLookVector.y * Setting_PushPullSpeed * Time.deltaTime;
_inputManager.lookVector = Vector2.zero;
}
}
private void DoSteamVRInput()
{
CVRPickupObject leftObject = (CVRPickupObject)_grabbedObject.GetValue(PlayerSetup.Instance.leftRay);
CVRPickupObject rightObject = (CVRPickupObject)_grabbedObject.GetValue(PlayerSetup.Instance.rightRay);
if (leftObject == null && rightObject == null) return;
bool canRotate = (leftObject != null && leftObject.gripType == CVRPickupObject.GripType.Free) ||
(rightObject != null && rightObject.gripType == CVRPickupObject.GripType.Free);
if (Setting_EnableRotation && canRotate && VR_RotateBind_Boolean.GetState((SteamVR_Input_Sources)VR_RotateHand))
{
Vector2 rawLookVector = new Vector2(CVRTools.AxisDeadZone(vrLookAction.GetAxis(SteamVR_Input_Sources.Any).x, deadzoneRightValue, true),
CVRTools.AxisDeadZone(vrLookAction.GetAxis(SteamVR_Input_Sources.Any).y, deadzoneRightValue, true));
objectRotation.x += Setting_RotationSpeed * rawLookVector.x;
objectRotation.y += Setting_RotationSpeed * rawLookVector.y * -1;
_inputManager.lookVector = Vector2.zero;
return;
}
CVRInputManager.Instance.objectPushPull += CVRInputManager.Instance.floatDirection * Setting_PushPullSpeed * Time.deltaTime;
}
}

108
PickupPushPull/Main.cs Normal file
View file

@ -0,0 +1,108 @@
using ABI.CCK.Components;
using ABI_RC.Core.Player;
using ABI_RC.Core.Savior;
using HarmonyLib;
using MelonLoader;
using UnityEngine;
using Valve.VR;
using NAK.Melons.PickupPushPull.InputModules;
namespace NAK.Melons.PickupPushPull;
public class PickupPushPull : MelonMod
{
private static MelonPreferences_Category Category_PickupPushPull;
private static MelonPreferences_Entry<float> Setting_PushPullSpeed, Setting_RotateSpeed;
private static MelonPreferences_Entry<bool> Setting_EnableRotation, Setting_Desktop_UseZoomForRotate;
private static MelonPreferences_Entry<BindingOptionsVR.BindHand> Setting_VR_RotateHand;
private static MelonPreferences_Entry<BindingOptionsVR.BindingOptions> Setting_VR_RotateBind;
public override void OnInitializeMelon()
{
Category_PickupPushPull = MelonPreferences.CreateCategory(nameof(PickupPushPull));
//Global settings
Setting_PushPullSpeed = Category_PickupPushPull.CreateEntry("Push Pull Speed", 2f, description: "Up/down on right joystick for VR. Left buSettingr + Up/down on right joystick for Gamepad.");
Setting_RotateSpeed = Category_PickupPushPull.CreateEntry<float>("Rotate Speed", 6f);
Setting_EnableRotation = Category_PickupPushPull.CreateEntry<bool>("Enable Rotation", false, description: "Hold left trigger in VR or right buSettingr on Gamepad.");
//Desktop settings
Setting_Desktop_UseZoomForRotate = Category_PickupPushPull.CreateEntry<bool>("Desktop Use Zoom For Rotate", true, description: "Use zoom bind for rotation while a prop is held.");
//VR settings
Setting_VR_RotateHand = Category_PickupPushPull.CreateEntry("VR Hand", BindingOptionsVR.BindHand.LeftHand);
//bruh
foreach (var setting in Category_PickupPushPull.Entries)
{
setting.OnEntryValueChangedUntyped.Subscribe(OnUpdateSettings);
}
//special setting
Setting_VR_RotateBind = Category_PickupPushPull.CreateEntry("VR Binding", BindingOptionsVR.BindingOptions.ButtonATouch);
Setting_VR_RotateBind.OnEntryValueChangedUntyped.Subscribe(OnUpdateVRBinding);
MelonLoader.MelonCoroutines.Start(WaitForLocalPlayer());
}
System.Collections.IEnumerator WaitForLocalPlayer()
{
while (PlayerSetup.Instance == null)
yield return null;
CVRInputManager.Instance.gameObject.AddComponent<PickupPushPull_Module>();
//update BlackoutController settings after it initializes
while (PickupPushPull_Module.Instance == null)
yield return null;
UpdateVRBinding();
UpdateAllSettings();
}
private void OnUpdateSettings(object arg1, object arg2) => UpdateAllSettings();
private void OnUpdateVRBinding(object arg1, object arg2) => UpdateVRBinding();
private void UpdateAllSettings()
{
if (!PickupPushPull_Module.Instance) return;
//Global settings
PickupPushPull_Module.Instance.Setting_PushPullSpeed = Setting_PushPullSpeed.Value * 50;
PickupPushPull_Module.Instance.Setting_RotationSpeed = Setting_RotateSpeed.Value * 50;
PickupPushPull_Module.Instance.Setting_EnableRotation = Setting_EnableRotation.Value;
//Desktop settings
PickupPushPull_Module.Instance.Desktop_UseZoomForRotate = Setting_Desktop_UseZoomForRotate.Value;
//VR settings
PickupPushPull_Module.Instance.VR_RotateHand = Setting_VR_RotateHand.Value;
}
private void UpdateVRBinding()
{
//VR special settings
PickupPushPull_Module.Instance.VR_RotateBind = Setting_VR_RotateBind.Value;
PickupPushPull_Module.Instance.UpdateVRBinding();
}
}
public class BindingOptionsVR
{
public enum BindHand
{
Any,
LeftHand,
RightHand
}
public enum BindingOptions
{
//Only oculus bindings have by default
ButtonATouch,
ButtonBTouch,
TriggerTouch,
//doesnt work?
StickTouch,
//Index only
GripTouch
}
}

View file

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net472</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<LangVersion>latest</LangVersion>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>
<ItemGroup>
<Reference Include="0Harmony">
<HintPath>C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\MelonLoader\0Harmony.dll</HintPath>
</Reference>
<Reference Include="Assembly-CSharp">
<HintPath>C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Assembly-CSharp.dll</HintPath>
</Reference>
<Reference Include="MelonLoader">
<HintPath>C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\MelonLoader\MelonLoader.dll</HintPath>
</Reference>
<Reference Include="SteamVR">
<HintPath>C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\SteamVR.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.CoreModule">
<HintPath>C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.CoreModule.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.InputLegacyModule">
<HintPath>C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.InputLegacyModule.dll</HintPath>
</Reference>
</ItemGroup>
<Target Name="Deploy" AfterTargets="Build">
<Copy SourceFiles="$(TargetPath)" DestinationFolder="C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\Mods\" />
<Message Text="Copied $(TargetPath) to C:\Program Files (x86)\Steam\steamapps\common\ChilloutVR\Mods\" Importance="high" />
</Target>
</Project>

View file

@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.2.32630.192
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PickupPushPull", "PickupPushPull.csproj", "{817132E7-2DE5-412F-A34C-A325C368F42B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{817132E7-2DE5-412F-A34C-A325C368F42B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{817132E7-2DE5-412F-A34C-A325C368F42B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{817132E7-2DE5-412F-A34C-A325C368F42B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{817132E7-2DE5-412F-A34C-A325C368F42B}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {D636F9FB-C0CF-40CE-8105-E5238CDE0902}
EndGlobalSection
EndGlobal

View file

@ -0,0 +1,30 @@
using NAK.Melons.PickupPushPull.Properties;
using MelonLoader;
using System.Reflection;
[assembly: AssemblyVersion(AssemblyInfoParams.Version)]
[assembly: AssemblyFileVersion(AssemblyInfoParams.Version)]
[assembly: AssemblyInformationalVersion(AssemblyInfoParams.Version)]
[assembly: AssemblyTitle(nameof(NAK.Melons.PickupPushPull))]
[assembly: AssemblyCompany(AssemblyInfoParams.Author)]
[assembly: AssemblyProduct(nameof(NAK.Melons.PickupPushPull))]
[assembly: MelonInfo(
typeof(NAK.Melons.PickupPushPull.PickupPushPull),
nameof(NAK.Melons.PickupPushPull),
AssemblyInfoParams.Version,
AssemblyInfoParams.Author,
downloadLink: "https://github.com/NotAKidOnSteam/PickupPushPull"
)]
[assembly: MelonGame("Alpha Blend Interactive", "ChilloutVR")]
[assembly: MelonPlatform(MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
[assembly: MelonPlatformDomain(MelonPlatformDomainAttribute.CompatibleDomains.MONO)]
namespace NAK.Melons.PickupPushPull.Properties;
internal static class AssemblyInfoParams
{
public const string Version = "3.0.2";
public const string Author = "NotAKidoS";
}

View file

@ -0,0 +1,23 @@
{
"_id": 91,
"name": "PickupPushPull",
"modversion": "3.0.2",
"gameversion": "2022r170",
"loaderversion": "0.5.7",
"modtype": "Mod",
"author": "NotAKidoS",
"description": "Allows you to push & pull pickups with Mouse, Gamepad, & VR.\nCan also optionally rotate props via keybind.\n\nIndex users will need to manually bind the missing SteamVR binds.",
"searchtags": [
"pull",
"push",
"pickup",
"prop"
],
"requirements": [
"None"
],
"downloadlink": "https://github.com/NotAKidOnSteam/PickupPushPull/releases/download/v3.0.2/PickupPushPull.dll",
"sourcelink": "https://github.com/NotAKidOnSteam/PickupPushPull/",
"changelog": "- Fixed issue where ControlEnableGamepad setting was improperly checked on startup.",
"embedcolor": "804221"
}

View file

@ -220,6 +220,22 @@ https://user-images.githubusercontent.com/37721153/189479474-41e93dff-a695-42f2-
Disables the CVRPathCameraController by default while keeping the flight binding.
Using UIExpansionKit or similar you can toggle both while in game.
# PickupPushPull
Allows you to push & pull props with Gamepad and VR.
Simply maps Gamepad & VR joystick input to objectPushPull.
Hold left bumper on Gamepad to use objectPushPull.
You can also rotate props while holding down the selected bind in VR, or right bumper on Gamepad.
Desktop can use the zoom bind while holding props without pickup origin to rotate with mouse.
As you can tell, i have no fucking clue how to use GitHub.
https://user-images.githubusercontent.com/37721153/188521473-9d180795-785a-4ba0-b97f-1e9163d1ba14.mp4
---