mirror of
https://github.com/NotAKidoS/NAK_CVR_Mods.git
synced 2025-09-02 14:29:25 +00:00
more
This commit is contained in:
parent
21f8893095
commit
a92e478eb9
22 changed files with 2 additions and 80 deletions
2
.DepricatedMods/EzGrab/EzGrab.csproj
Normal file
2
.DepricatedMods/EzGrab/EzGrab.csproj
Normal file
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk"/>
|
58
.DepricatedMods/EzGrab/Main.cs
Normal file
58
.DepricatedMods/EzGrab/Main.cs
Normal file
|
@ -0,0 +1,58 @@
|
|||
using MelonLoader;
|
||||
using System.Reflection;
|
||||
using ABI_RC.Systems.InputManagement.InputModules;
|
||||
using ABI_RC.Systems.InputManagement.XR;
|
||||
|
||||
namespace NAK.EzGrab;
|
||||
|
||||
public class EzGrab : MelonMod
|
||||
{
|
||||
private const string SettingsCategory = nameof(EzGrab);
|
||||
|
||||
private static readonly MelonPreferences_Category Category =
|
||||
MelonPreferences.CreateCategory(SettingsCategory);
|
||||
|
||||
private static readonly MelonPreferences_Entry<bool> EntryEnabled =
|
||||
Category.CreateEntry("Enabled", true,
|
||||
description: "Should EzGrab be enabled?");
|
||||
|
||||
private static readonly MelonPreferences_Entry<float> EntryReleaseWeight =
|
||||
Category.CreateEntry("Release Weight", 0.1f,
|
||||
description: "The release weight for grip up to fire.");
|
||||
|
||||
public override void OnInitializeMelon()
|
||||
{
|
||||
HarmonyInstance.Patch(
|
||||
typeof(CVRInputModule_XR).GetMethod(nameof(CVRInputModule_XR.Update_Grip)),
|
||||
prefix: new HarmonyLib.HarmonyMethod(typeof(EzGrab).GetMethod(nameof(OnCVRInputModule_XR_Prefix), BindingFlags.NonPublic))
|
||||
);
|
||||
}
|
||||
|
||||
private static void OnCVRInputModule_XR_Prefix(CVRXRModule module, ref CVRInputModule_XR __instance)
|
||||
{
|
||||
if (module.Type != EXRControllerType.Index || !EntryEnabled.Value) return;
|
||||
|
||||
float gripValue = module.Grip;
|
||||
float gripThreshold = __instance._indexGripThreshold;
|
||||
float releaseThreshold = EntryReleaseWeight.Value;
|
||||
|
||||
if (module.IsLeftHand)
|
||||
{
|
||||
float lastGripLeft = __instance._lastGripLeft;
|
||||
if ((gripValue < gripThreshold && lastGripLeft >= gripThreshold) &&
|
||||
!(gripValue < releaseThreshold && lastGripLeft >= releaseThreshold))
|
||||
{
|
||||
__instance._lastGripLeft = 0f;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float lastGripRight = __instance._lastGripRight;
|
||||
if ((gripValue < gripThreshold && lastGripRight >= gripThreshold) &&
|
||||
!(gripValue < releaseThreshold && lastGripRight >= releaseThreshold))
|
||||
{
|
||||
__instance._lastGripRight = 0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
29
.DepricatedMods/EzGrab/Properties/AssemblyInfo.cs
Normal file
29
.DepricatedMods/EzGrab/Properties/AssemblyInfo.cs
Normal file
|
@ -0,0 +1,29 @@
|
|||
using MelonLoader;
|
||||
using NAK.EzGrab.Properties;
|
||||
using System.Reflection;
|
||||
|
||||
[assembly: AssemblyVersion(AssemblyInfoParams.Version)]
|
||||
[assembly: AssemblyFileVersion(AssemblyInfoParams.Version)]
|
||||
[assembly: AssemblyInformationalVersion(AssemblyInfoParams.Version)]
|
||||
[assembly: AssemblyTitle(nameof(NAK.EzGrab))]
|
||||
[assembly: AssemblyCompany(AssemblyInfoParams.Author)]
|
||||
[assembly: AssemblyProduct(nameof(NAK.EzGrab))]
|
||||
|
||||
[assembly: MelonInfo(
|
||||
typeof(NAK.EzGrab.EzGrab),
|
||||
nameof(NAK.EzGrab),
|
||||
AssemblyInfoParams.Version,
|
||||
AssemblyInfoParams.Author,
|
||||
downloadLink: "https://github.com/NotAKidOnSteam/NAK_CVR_Mods/tree/main/EzGrab"
|
||||
)]
|
||||
|
||||
[assembly: MelonGame("Alpha Blend Interactive", "ChilloutVR")]
|
||||
[assembly: MelonPlatform(MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
|
||||
[assembly: MelonPlatformDomain(MelonPlatformDomainAttribute.CompatibleDomains.MONO)]
|
||||
|
||||
namespace NAK.EzGrab.Properties;
|
||||
internal static class AssemblyInfoParams
|
||||
{
|
||||
public const string Version = "1.0.0";
|
||||
public const string Author = "NotAKidoS";
|
||||
}
|
23
.DepricatedMods/EzGrab/format.json
Normal file
23
.DepricatedMods/EzGrab/format.json
Normal file
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"_id": -1,
|
||||
"name": "EzCurls",
|
||||
"modversion": "1.0.0",
|
||||
"gameversion": "2022r170p1",
|
||||
"loaderversion": "0.6.1",
|
||||
"modtype": "Mod",
|
||||
"author": "NotAKidoS",
|
||||
"description": "A mod that should hopefully make finger curls more predictable.",
|
||||
"searchtags": [
|
||||
"aas",
|
||||
"sync",
|
||||
"naked",
|
||||
"buffer"
|
||||
],
|
||||
"requirements": [
|
||||
"UIExpansionKit"
|
||||
],
|
||||
"downloadlink": "https://github.com/NotAKidOnSteam/NAK_CVR_Mods/releases/download/r13/EzCurls.dll",
|
||||
"sourcelink": "https://github.com/NotAKidOnSteam/NAK_CVR_Mods/tree/main/EzCurls/",
|
||||
"changelog": "- Initial CVRMG release",
|
||||
"embedcolor": "7d7d7d"
|
||||
}
|
320
.DepricatedMods/IKFixes/HarmonyPatches.cs
Normal file
320
.DepricatedMods/IKFixes/HarmonyPatches.cs
Normal file
|
@ -0,0 +1,320 @@
|
|||
using ABI_RC.Core.InteractionSystem;
|
||||
using ABI.CCK.Components;
|
||||
using ABI_RC.Core.Player;
|
||||
using ABI_RC.Systems.IK;
|
||||
using ABI_RC.Systems.IK.SubSystems;
|
||||
using ABI_RC.Systems.InputManagement;
|
||||
using ABI_RC.Systems.MovementSystem;
|
||||
using HarmonyLib;
|
||||
using RootMotion.FinalIK;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NAK.IKFixes.HarmonyPatches;
|
||||
|
||||
internal static class BodySystemPatches
|
||||
{
|
||||
private static float _ikSimulatedRootAngle;
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(BodySystem), nameof(BodySystem.SetupOffsets))]
|
||||
private static void Postfix_BodySystem_SetupOffsets(List<TrackingPoint> trackingPoints)
|
||||
{
|
||||
foreach (TrackingPoint trackingPoint in trackingPoints)
|
||||
{
|
||||
Transform parent = null;
|
||||
float offsetDistance = 0f;
|
||||
|
||||
switch (trackingPoint.assignedRole)
|
||||
{
|
||||
case TrackingPoint.TrackingRole.LeftKnee:
|
||||
parent = IKSystem.vrik.references.leftCalf;
|
||||
offsetDistance = 0.15f;
|
||||
break;
|
||||
case TrackingPoint.TrackingRole.RightKnee:
|
||||
parent = IKSystem.vrik.references.rightCalf;
|
||||
offsetDistance = 0.15f;
|
||||
break;
|
||||
case TrackingPoint.TrackingRole.Chest:
|
||||
parent = IKSystem.vrik.references.chest;
|
||||
offsetDistance = 0.5f;
|
||||
break;
|
||||
case TrackingPoint.TrackingRole.LeftElbow:
|
||||
parent = IKSystem.vrik.references.leftForearm;
|
||||
offsetDistance = -0.15f;
|
||||
break;
|
||||
case TrackingPoint.TrackingRole.RightElbow:
|
||||
parent = IKSystem.vrik.references.rightForearm;
|
||||
offsetDistance = -0.15f;
|
||||
break;
|
||||
}
|
||||
|
||||
if (parent == null)
|
||||
continue;
|
||||
|
||||
// Set the offset transform's parent and reset its local position and rotation
|
||||
trackingPoint.offsetTransform.parent = parent;
|
||||
trackingPoint.offsetTransform.localPosition = Vector3.zero;
|
||||
trackingPoint.offsetTransform.localRotation = Quaternion.identity;
|
||||
trackingPoint.offsetTransform.parent = trackingPoint.referenceTransform;
|
||||
|
||||
// Apply additional offset based on the assigned role
|
||||
Vector3 additionalOffset = IKSystem.vrik.references.root.forward * offsetDistance;
|
||||
trackingPoint.offsetTransform.position += additionalOffset;
|
||||
|
||||
// Game originally sets them to about half a meter out, which fucks with slime tracker users and
|
||||
// makes the bendGoals less responsive/less accurate.
|
||||
|
||||
//Funny thing is that IKTweaks specifically made this an option, which should be added to both CVR & Standable for the same reason.
|
||||
/// Elbow / knee / chest bend goal offset - controls how far bend goal targets will be away from the actual joint.
|
||||
/// Lower values should produce better precision with bent joint, higher values - better stability with straight joint.
|
||||
/// Sensible range of values is between 0 and 1.
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetArmWeight(IKSolverVR.Arm arm, float weight)
|
||||
{
|
||||
arm.positionWeight = weight;
|
||||
arm.rotationWeight = weight;
|
||||
arm.shoulderRotationWeight = weight;
|
||||
arm.shoulderTwistWeight = weight;
|
||||
// assumed fix of bend goal weight if arms disabled with elbows (havent tested)
|
||||
arm.bendGoalWeight = arm.bendGoal != null ? weight : 0f;
|
||||
}
|
||||
|
||||
private static void SetLegWeight(IKSolverVR.Leg leg, float weight)
|
||||
{
|
||||
leg.positionWeight = weight;
|
||||
leg.rotationWeight = weight;
|
||||
// fixes knees bending to tracker if feet disabled (running anim)
|
||||
leg.bendGoalWeight = leg.usingKneeTracker ? weight : 0f;
|
||||
}
|
||||
|
||||
private static void SetPelvisWeight(IKSolverVR.Spine spine, float weight)
|
||||
{
|
||||
// looks better when hips are disabled while running
|
||||
spine.pelvisPositionWeight = weight;
|
||||
spine.pelvisRotationWeight = weight;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(BodySystem), nameof(BodySystem.Update))]
|
||||
private static bool Prefix_BodySystem_Update(ref BodySystem __instance)
|
||||
{
|
||||
if (IKSystem.vrik != null)
|
||||
{
|
||||
IKSolverVR solver = IKSystem.vrik.solver;
|
||||
|
||||
if (BodySystem.TrackingEnabled)
|
||||
{
|
||||
IKSystem.vrik.enabled = true;
|
||||
solver.IKPositionWeight = BodySystem.TrackingPositionWeight;
|
||||
solver.locomotion.weight = BodySystem.TrackingLocomotionEnabled ? 1f : 0f;
|
||||
|
||||
// fixes arm weights not being set if leftArm & rightArm targets are null
|
||||
// game handles TrackingLegs in PlayerSetup, but not for knee goals
|
||||
SetArmWeight(solver.leftArm, BodySystem.TrackingLeftArmEnabled && solver.leftArm.target != null ? 1f : 0f);
|
||||
SetArmWeight(solver.rightArm, BodySystem.TrackingRightArmEnabled && solver.rightArm.target != null ? 1f : 0f);
|
||||
SetLegWeight(solver.leftLeg, BodySystem.TrackingLeftLegEnabled && solver.leftLeg.target != null ? 1f : 0f);
|
||||
SetLegWeight(solver.rightLeg, BodySystem.TrackingRightLegEnabled && solver.leftLeg.target != null ? 1f : 0f);
|
||||
SetPelvisWeight(solver.spine, solver.spine.pelvisTarget != null ? 1f : 0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
IKSystem.vrik.enabled = false;
|
||||
solver.IKPositionWeight = 0f;
|
||||
solver.locomotion.weight = 0f;
|
||||
|
||||
SetArmWeight(solver.leftArm, 0f);
|
||||
SetArmWeight(solver.rightArm, 0f);
|
||||
SetLegWeight(solver.leftLeg, 0f);
|
||||
SetLegWeight(solver.rightLeg, 0f);
|
||||
SetPelvisWeight(solver.spine, 0f);
|
||||
}
|
||||
|
||||
float maxRootAngle = 25f;
|
||||
float rootHeadingOffset = 0f;
|
||||
|
||||
if (BodySystem.isCalibratedAsFullBody
|
||||
|| IKFixes.EntryUseFakeRootAngle.Value
|
||||
|| CVRInputManager.Instance.movementVector.sqrMagnitude > 0f)
|
||||
maxRootAngle = 0f;
|
||||
|
||||
// fixes body being wrong direction while playing emotes (root rotation)
|
||||
if (PlayerSetup.Instance._emotePlaying)
|
||||
maxRootAngle = 180f;
|
||||
|
||||
// fixes feet always pointing toward head direction
|
||||
if (IKFixes.EntryUseFakeRootAngle.Value && !BodySystem.isCalibratedAsFullBody)
|
||||
{
|
||||
float weightedAngleLimit = IKFixes.EntryFakeRootAngleLimit.Value * solver.locomotion.weight;
|
||||
float playerDirection = MovementSystem.Instance.rotationPivot.eulerAngles.y;
|
||||
|
||||
float deltaAngleRoot = Mathf.DeltaAngle(playerDirection, _ikSimulatedRootAngle);
|
||||
float angleOverLimit = Mathf.Abs(deltaAngleRoot) - weightedAngleLimit;
|
||||
|
||||
if (angleOverLimit > 0)
|
||||
{
|
||||
deltaAngleRoot = Mathf.Sign(deltaAngleRoot) * weightedAngleLimit;
|
||||
_ikSimulatedRootAngle = Mathf.MoveTowardsAngle(_ikSimulatedRootAngle, playerDirection, angleOverLimit);
|
||||
}
|
||||
|
||||
rootHeadingOffset = deltaAngleRoot;
|
||||
}
|
||||
|
||||
solver.spine.maxRootAngle = maxRootAngle;
|
||||
solver.spine.rootHeadingOffset = rootHeadingOffset;
|
||||
|
||||
// custom IK settings
|
||||
solver.spine.neckStiffness = IKFixes.EntryNeckStiffness.Value;
|
||||
solver.spine.bodyRotStiffness = IKFixes.EntryBodyRotStiffness.Value;
|
||||
solver.spine.rotateChestByHands = IKFixes.EntryRotateChestByHands.Value;
|
||||
|
||||
if (!IKSystem.vrik.solver.leftLeg.usingKneeTracker)
|
||||
IKSystem.vrik.solver.leftLeg.bendToTargetWeight = IKFixes.EntryBendToTargetWeight.Value;
|
||||
if (!IKSystem.vrik.solver.rightLeg.usingKneeTracker)
|
||||
IKSystem.vrik.solver.rightLeg.bendToTargetWeight = IKFixes.EntryBendToTargetWeight.Value;
|
||||
}
|
||||
|
||||
int count = IKSystem.Instance.AllTrackingPoints.FindAll(m => m.isActive && m.isValid && m.suggestedRole > TrackingPoint.TrackingRole.Invalid).Count;
|
||||
|
||||
// solid body count block
|
||||
int num = 0;
|
||||
if (BodySystem.enableLeftFootTracking) num++;
|
||||
if (BodySystem.enableRightFootTracking) num++;
|
||||
if (BodySystem.enableHipTracking) num++;
|
||||
if (BodySystem.enableLeftKneeTracking) num++;
|
||||
if (BodySystem.enableRightKneeTracking) num++;
|
||||
if (BodySystem.enableChestTracking) num++;
|
||||
if (BodySystem.enableLeftElbowTracking) num++;
|
||||
if (BodySystem.enableRightElbowTracking) num++;
|
||||
|
||||
// fixes having all tracking points disabled forcing calibration
|
||||
if (num == 0 || count == 0)
|
||||
{
|
||||
CVR_MenuManager.Instance.coreData.core.fullBodyActive = __instance._fbtAvailable = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
CVR_MenuManager.Instance.coreData.core.fullBodyActive = __instance._fbtAvailable = (count >= num);
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(BodySystem), nameof(BodySystem.AssignRemainingTrackers))]
|
||||
private static bool Prefix_BodySystem_AssignRemainingTrackers()
|
||||
{
|
||||
return IKFixes.EntryAssignRemainingTrackers.Value;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(BodySystem), nameof(BodySystem.MuscleUpdate))]
|
||||
private static void Prefix_BodySystem_MuscleUpdate()
|
||||
{
|
||||
if (BodySystem.isCalibrating)
|
||||
{
|
||||
IKSystem.Instance.humanPose.bodyRotation = Quaternion.identity;
|
||||
//IKSystem.vrik.solver.spine.maxRootAngle = 0f; // idk, testing
|
||||
}
|
||||
|
||||
if (BodySystem.isCalibratedAsFullBody && BodySystem.TrackingPositionWeight > 0f)
|
||||
{
|
||||
bool isRunning = MovementSystem.Instance.movementVector.sqrMagnitude > 0f;
|
||||
bool isGrounded = MovementSystem.Instance._isGrounded;
|
||||
bool isFlying = MovementSystem.Instance.flying;
|
||||
bool playRunningAnimation = BodySystem.PlayRunningAnimationInFullBody;
|
||||
|
||||
if ((playRunningAnimation && (isRunning || !isGrounded && !isFlying)))
|
||||
{
|
||||
SetPelvisWeight(IKSystem.vrik.solver.spine, 0f);
|
||||
IKSystem.Instance.applyOriginalHipPosition = true;
|
||||
IKSystem.Instance.applyOriginalHipRotation = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
IKSystem.Instance.applyOriginalHipPosition = true;
|
||||
IKSystem.Instance.applyOriginalHipRotation = false;
|
||||
IKSystem.Instance.humanPose.bodyRotation = Quaternion.identity;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Rewrite to exclude setting T-pose to limbs that are not tracked
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(BodySystem), nameof(BodySystem.Calibrate))]
|
||||
private static void Postfix_BodySystem_Calibrate()
|
||||
{
|
||||
IKSystem.Instance.applyOriginalHipPosition = false;
|
||||
IKSystem.Instance.applyOriginalHipRotation = false;
|
||||
if (IKSystem.vrik.solver.leftLeg.usingKneeTracker)
|
||||
{
|
||||
IKSystem.vrik.solver.leftLeg.bendToTargetWeight = 0f;
|
||||
IKSystem.vrik.solver.leftLeg.bendGoalWeight = 1f;
|
||||
}
|
||||
if (IKSystem.vrik.solver.rightLeg.usingKneeTracker)
|
||||
{
|
||||
IKSystem.vrik.solver.rightLeg.bendToTargetWeight = 0f;
|
||||
IKSystem.vrik.solver.rightLeg.bendGoalWeight = 1f;
|
||||
}
|
||||
}
|
||||
|
||||
internal static void OffsetSimulatedRootAngle(float deltaRotation)
|
||||
{
|
||||
_ikSimulatedRootAngle = Mathf.Repeat(_ikSimulatedRootAngle + deltaRotation, 360f);
|
||||
}
|
||||
}
|
||||
|
||||
internal static class IKSystemPatches
|
||||
{
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(IKSystem), nameof(IKSystem.InitializeAvatar))]
|
||||
private static void Prefix_IKSystem_InitializeAvatar(ref IKSystem __instance)
|
||||
{
|
||||
__instance.applyOriginalHipPosition = true;
|
||||
__instance.applyOriginalHipRotation = true;
|
||||
}
|
||||
}
|
||||
|
||||
internal static class PlayerSetupPatches
|
||||
{
|
||||
// Last Movement Parent Info
|
||||
private static CVRMovementParent lastMovementParent;
|
||||
private static Vector3 lastMovementPosition;
|
||||
private static Quaternion lastMovementRotation;
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(PlayerSetup), nameof(PlayerSetup.ResetIk))]
|
||||
private static bool Prefix_PlayerSetup_ResetIk()
|
||||
{
|
||||
if (IKSystem.vrik == null)
|
||||
return false;
|
||||
|
||||
CVRMovementParent currentParent = MovementSystem.Instance._currentParent;
|
||||
if (currentParent == null || currentParent._referencePoint == null)
|
||||
return true;
|
||||
|
||||
// Get current position, VR pivots around VR camera
|
||||
Vector3 currentPosition = MovementSystem.Instance.rotationPivot.transform.position;
|
||||
currentPosition.y = IKSystem.vrik.transform.position.y; // set pivot to floor
|
||||
Quaternion currentRotation = Quaternion.Euler(0f, currentParent.transform.rotation.eulerAngles.y, 0f);
|
||||
|
||||
// Prevent targeting previous movement parent
|
||||
if (lastMovementParent != null && lastMovementParent == currentParent)
|
||||
{
|
||||
Vector3 deltaPosition = currentPosition - lastMovementPosition;
|
||||
Quaternion deltaRotation = Quaternion.identity;
|
||||
|
||||
if (currentParent.orientationMode == CVRMovementParent.OrientationMode.RotateWithParent)
|
||||
deltaRotation = Quaternion.Inverse(lastMovementRotation) * currentRotation;
|
||||
|
||||
IKSystem.vrik.solver.AddPlatformMotion(deltaPosition, deltaRotation, currentPosition);
|
||||
BodySystemPatches.OffsetSimulatedRootAngle(deltaRotation.eulerAngles.y);
|
||||
}
|
||||
|
||||
lastMovementParent = currentParent;
|
||||
lastMovementPosition = currentPosition;
|
||||
lastMovementRotation = currentRotation;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
11
.DepricatedMods/IKFixes/IKFixes.csproj
Normal file
11
.DepricatedMods/IKFixes/IKFixes.csproj
Normal file
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="UIExpansionKit">
|
||||
<HintPath>$(MsBuildThisFileDirectory)\..\.ManagedLibs\UIExpansionKit.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
21
.DepricatedMods/IKFixes/Integrations/UIExKitAddon.cs
Normal file
21
.DepricatedMods/IKFixes/Integrations/UIExKitAddon.cs
Normal file
|
@ -0,0 +1,21 @@
|
|||
using System.Runtime.CompilerServices;
|
||||
using MelonLoader;
|
||||
using UIExpansionKit.API;
|
||||
|
||||
namespace NAK.IKFixes.Integrations;
|
||||
|
||||
public static class UIExKitAddon
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public static void Initialize()
|
||||
{
|
||||
var settings = ExpansionKitApi.GetSettingsCategory(IKFixes.SettingsCategory);
|
||||
settings.AddSimpleButton("Reset Settings (Only visually updates bool values, UIExpansionKit bug!)", ResetSettings);
|
||||
}
|
||||
|
||||
private static void ResetSettings()
|
||||
{
|
||||
foreach (MelonPreferences_Entry setting in IKFixes.Category.Entries)
|
||||
setting.ResetToDefault();
|
||||
}
|
||||
}
|
62
.DepricatedMods/IKFixes/Main.cs
Normal file
62
.DepricatedMods/IKFixes/Main.cs
Normal file
|
@ -0,0 +1,62 @@
|
|||
using MelonLoader;
|
||||
|
||||
namespace NAK.IKFixes;
|
||||
|
||||
public class IKFixes : MelonMod
|
||||
{
|
||||
internal const string SettingsCategory = nameof(IKFixes);
|
||||
|
||||
public static readonly MelonPreferences_Category Category =
|
||||
MelonPreferences.CreateCategory(SettingsCategory);
|
||||
|
||||
public static readonly MelonPreferences_Entry<bool> EntryUseFakeRootAngle =
|
||||
Category.CreateEntry("use_fake_root_angle", true, display_name: "Use Fake Root Angle", description: "Emulates maxRootAngle. This fixes feet pointing in direction of head when looking around.");
|
||||
|
||||
public static readonly MelonPreferences_Entry<float> EntryFakeRootAngleLimit =
|
||||
Category.CreateEntry("fake_root_angle_limit", 25f, display_name: "Fake Root Angle Limit (25f)", description: "Specifies the maximum angle the lower body can have relative to the head when rotating.");
|
||||
|
||||
public static readonly MelonPreferences_Entry<float> EntryNeckStiffness =
|
||||
Category.CreateEntry("neck_stiffness", 0.2f, display_name: "Neck Stiffness (0.2f)", description: "Neck stiffness.");
|
||||
|
||||
public static readonly MelonPreferences_Entry<float> EntryBodyRotStiffness =
|
||||
Category.CreateEntry("body_rot_stiffness", 0.1f, display_name: "Body Rot Stiffness (0.1f)", description: "Body rotation stiffness.");
|
||||
|
||||
public static readonly MelonPreferences_Entry<float> EntryRotateChestByHands =
|
||||
Category.CreateEntry("rot_chest_by_hands", 1f, display_name: "Rot Chest By Hands (1f)", description: "Rotate chest by hands.");
|
||||
|
||||
public static readonly MelonPreferences_Entry<float> EntryBendToTargetWeight =
|
||||
Category.CreateEntry("leg_bend_to_target", 1f, display_name: "Leg Bend To Target (1f)", description: "Leg bend to target weight");
|
||||
|
||||
public static readonly MelonPreferences_Entry<bool> EntryAssignRemainingTrackers =
|
||||
Category.CreateEntry("assign_remaining_trackers", true, display_name: "Assign Remaining Trackers (true)", description: "Should the game calibrate any additional trackers as secondary trackers for already-tracked points?");
|
||||
|
||||
public override void OnInitializeMelon()
|
||||
{
|
||||
ApplyPatches(typeof(HarmonyPatches.BodySystemPatches));
|
||||
ApplyPatches(typeof(HarmonyPatches.PlayerSetupPatches));
|
||||
ApplyPatches(typeof(HarmonyPatches.IKSystemPatches));
|
||||
InitializeIntegration("UI Expansion Kit", Integrations.UIExKitAddon.Initialize);
|
||||
}
|
||||
|
||||
private void InitializeIntegration(string modName, Action integrationAction)
|
||||
{
|
||||
if (RegisteredMelons.All(it => it.Info.Name != modName))
|
||||
return;
|
||||
|
||||
LoggerInstance.Msg($"Initializing {modName} integration.");
|
||||
integrationAction.Invoke();
|
||||
}
|
||||
|
||||
private void ApplyPatches(Type type)
|
||||
{
|
||||
try
|
||||
{
|
||||
HarmonyInstance.PatchAll(type);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LoggerInstance.Msg($"Failed while patching {type.Name}!");
|
||||
LoggerInstance.Error(e);
|
||||
}
|
||||
}
|
||||
}
|
30
.DepricatedMods/IKFixes/Properties/AssemblyInfo.cs
Normal file
30
.DepricatedMods/IKFixes/Properties/AssemblyInfo.cs
Normal file
|
@ -0,0 +1,30 @@
|
|||
using MelonLoader;
|
||||
using NAK.IKFixes.Properties;
|
||||
using System.Reflection;
|
||||
|
||||
[assembly: AssemblyVersion(AssemblyInfoParams.Version)]
|
||||
[assembly: AssemblyFileVersion(AssemblyInfoParams.Version)]
|
||||
[assembly: AssemblyInformationalVersion(AssemblyInfoParams.Version)]
|
||||
[assembly: AssemblyTitle(nameof(NAK.IKFixes))]
|
||||
[assembly: AssemblyCompany(AssemblyInfoParams.Author)]
|
||||
[assembly: AssemblyProduct(nameof(NAK.IKFixes))]
|
||||
|
||||
[assembly: MelonInfo(
|
||||
typeof(NAK.IKFixes.IKFixes),
|
||||
nameof(NAK.IKFixes),
|
||||
AssemblyInfoParams.Version,
|
||||
AssemblyInfoParams.Author,
|
||||
downloadLink: "https://github.com/NotAKidOnSteam/NAK_CVR_Mods/tree/main/IKFixes"
|
||||
)]
|
||||
|
||||
[assembly: MelonGame("Alpha Blend Interactive", "ChilloutVR")]
|
||||
[assembly: MelonPlatform(MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
|
||||
[assembly: MelonPlatformDomain(MelonPlatformDomainAttribute.CompatibleDomains.MONO)]
|
||||
[assembly: HarmonyDontPatchAll]
|
||||
|
||||
namespace NAK.IKFixes.Properties;
|
||||
internal static class AssemblyInfoParams
|
||||
{
|
||||
public const string Version = "1.1.0";
|
||||
public const string Author = "NotAKidoS";
|
||||
}
|
52
.DepricatedMods/IKFixes/README.md
Normal file
52
.DepricatedMods/IKFixes/README.md
Normal file
|
@ -0,0 +1,52 @@
|
|||
# IKFixes
|
||||
Adds a few small fixes and configuration options to IK.
|
||||
|
||||
**FBT Fixes** -
|
||||
* Knee tracking.
|
||||
* Running animations..
|
||||
* Emotes playing in wrong direction.
|
||||
* Forced to calibrate if all IK Tracking Settings are disabled.
|
||||
* Root animation bleeding into IK.
|
||||
|
||||
**Halfbody Fixes** -
|
||||
* Locomotion footsteps while on Movement Parents.
|
||||
* Root Angle Offset while looking around. Fixes feet only pointing in direction of head.
|
||||
* Halfbody feet pointing upward.
|
||||
|
||||
**Configurations** -
|
||||
* Neck Stiffness
|
||||
* Body Rot Stiffness
|
||||
* Rot Chest By Hands
|
||||
* Assign Remaining Trackers
|
||||
* Network IK Pass
|
||||
|
||||
**NOTE**
|
||||
The mod works, but is done in a very janky way with patches everywhere.
|
||||
|
||||
I could spend some time to properly clean it up and make the fixes more "stable", but there isn't much reason to as the IKSystem is still in active development. This mod is just mostly a collection of quick fixes to a bunch of things that bothered me, and that I knew or could guess how to fix after working on DesktopVRIK for however long.
|
||||
|
||||
## Relevant Feedback Posts:
|
||||
https://feedback.abinteractive.net/p/ik-knee-tracking
|
||||
|
||||
https://feedback.abinteractive.net/p/2022r170-ex3-knee-ik-weirdness-when-using-knee-trackers
|
||||
|
||||
https://feedback.abinteractive.net/p/disabling-all-tracked-points-makes-game-assume-fbt
|
||||
|
||||
https://feedback.abinteractive.net/p/about-ik-behaviour
|
||||
|
||||
https://feedback.abinteractive.net/p/vrik-addplatformmotion-for-movement-parents
|
||||
|
||||
https://feedback.abinteractive.net/p/halfbodyik-feet-will-only-point-in-direction-of-head
|
||||
|
||||
https://feedback.abinteractive.net/p/halfbodyik-heels-are-low-as-of-iksystem-update
|
||||
|
||||
---
|
||||
|
||||
Here is the block of text where I tell you this mod is not affiliated or endorsed by ABI.
|
||||
https://documentation.abinteractive.net/official/legal/tos/#7-modding-our-games
|
||||
|
||||
> This mod is an independent creation and is not affiliated with, supported by or approved by Alpha Blend Interactive.
|
||||
|
||||
> Use of this mod is done so at the user's own risk and the creator cannot be held responsible for any issues arising from its use.
|
||||
|
||||
> To the best of my knowledge, I have adhered to the Modding Guidelines established by Alpha Blend Interactive.
|
24
.DepricatedMods/IKFixes/format.json
Normal file
24
.DepricatedMods/IKFixes/format.json
Normal file
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"_id": 142,
|
||||
"name": "IKFixes",
|
||||
"modversion": "1.0.9",
|
||||
"gameversion": "2023r172",
|
||||
"loaderversion": "0.6.1",
|
||||
"modtype": "Mod",
|
||||
"author": "NotAKidoS",
|
||||
"description": "A few small fixes and configuration options to IK. Major ones are listed below:\n\n**FBT** - Fixes root rotation animation bleeding, chest tracking, locomotion animations, chair seated direction, and bend goal offsets.\n\n**Halfbody** - Fixes footsteps while on a Movement Parent & feet always pointing in head direction.",
|
||||
"searchtags": [
|
||||
"knee",
|
||||
"ik",
|
||||
"tracking",
|
||||
"fix",
|
||||
"chest"
|
||||
],
|
||||
"requirements": [
|
||||
"None"
|
||||
],
|
||||
"downloadlink": "https://github.com/NotAKidOnSteam/NAK_CVR_Mods/releases/download/r21/IKFixes.dll",
|
||||
"sourcelink": "https://github.com/NotAKidOnSteam/NAK_CVR_Mods/tree/main/IKFixes/",
|
||||
"changelog": "- Fix Seated Play button not returning once disconnecting all trackers from SteamVR.",
|
||||
"embedcolor": "f46e49"
|
||||
}
|
203
.DepricatedMods/MenuScalePatch/HarmonyPatches.cs
Normal file
203
.DepricatedMods/MenuScalePatch/HarmonyPatches.cs
Normal file
|
@ -0,0 +1,203 @@
|
|||
using ABI.CCK.Components;
|
||||
using ABI_RC.Core;
|
||||
using ABI_RC.Core.InteractionSystem;
|
||||
using ABI_RC.Core.Player;
|
||||
using ABI_RC.Core.Savior;
|
||||
using HarmonyLib;
|
||||
using NAK.MenuScalePatch.Helpers;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NAK.MenuScalePatch.HarmonyPatches;
|
||||
|
||||
/**
|
||||
ViewManager.SetScale runs once a second when it should only run when aspect ratio changes- CVR bug
|
||||
assuming its caused by cast from int to float getting the screen size, something floating point bleh
|
||||
**/
|
||||
|
||||
[HarmonyPatch]
|
||||
internal class HarmonyPatches
|
||||
{
|
||||
//stuff needed on start
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(PlayerSetup), "Start")]
|
||||
private static void Postfix_PlayerSetup_Start()
|
||||
{
|
||||
MSP_MenuInfo.CameraTransform = PlayerSetup.Instance.GetActiveCamera().transform;
|
||||
MenuScalePatch.UpdateSettings();
|
||||
QuickMenuHelper.Instance.CreateWorldAnchors();
|
||||
MainMenuHelper.Instance.CreateWorldAnchors();
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(CVR_MenuManager), "SetScale")]
|
||||
private static bool Prefix_CVR_MenuManager_SetScale(float avatarHeight, ref float ____scaleFactor)
|
||||
{
|
||||
____scaleFactor = avatarHeight / 1.8f;
|
||||
if (MetaPort.Instance.isUsingVr) ____scaleFactor *= 0.5f;
|
||||
MSP_MenuInfo.ScaleFactor = ____scaleFactor;
|
||||
if (!MSP_MenuInfo.PlayerAnchorMenus)
|
||||
{
|
||||
QuickMenuHelper.Instance.NeedsPositionUpdate = true;
|
||||
MainMenuHelper.Instance.NeedsPositionUpdate = true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(ViewManager), "SetScale")]
|
||||
private static bool Prefix_ViewManager_SetScale()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//nuke UpdateMenuPosition methods
|
||||
//there are 2 Jobs calling this each second, which is fucking my shit
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(CVR_MenuManager), "UpdateMenuPosition")]
|
||||
private static bool Prefix_CVR_MenuManager_UpdateMenuPosition()
|
||||
{
|
||||
if (QuickMenuHelper.Instance == null) return true;
|
||||
return !QuickMenuHelper.Instance.MenuIsOpen;
|
||||
}
|
||||
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(ViewManager), "UpdateMenuPosition")]
|
||||
private static bool Prefix_ViewManager_UpdateMenuPosition(ref float ___cachedScreenAspectRatio)
|
||||
{
|
||||
if (MainMenuHelper.Instance == null) return true;
|
||||
//this is called once a second, so ill fix their dumb aspect ratio shit
|
||||
float ratio = (float)Screen.width / (float)Screen.height;
|
||||
float clamp = Mathf.Clamp(ratio, 0f, 1.8f);
|
||||
MSP_MenuInfo.AspectRatio = 1.7777779f / clamp;
|
||||
return !MainMenuHelper.Instance.MenuIsOpen;
|
||||
}
|
||||
|
||||
//Set QM stuff
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(CVR_MenuManager), "Start")]
|
||||
private static void Postfix_CVR_MenuManager_Start(ref CVR_MenuManager __instance, ref GameObject ____leftVrAnchor)
|
||||
{
|
||||
QuickMenuHelper helper = __instance.quickMenu.gameObject.AddComponent<QuickMenuHelper>();
|
||||
helper.handAnchor = ____leftVrAnchor.transform;
|
||||
}
|
||||
|
||||
//Set MM stuff
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(ViewManager), "Start")]
|
||||
private static void Postfix_ViewManager_Start(ref ViewManager __instance)
|
||||
{
|
||||
__instance.gameObject.AddComponent<MainMenuHelper>();
|
||||
}
|
||||
|
||||
//hook quickmenu open/close
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(CVR_MenuManager), "ToggleQuickMenu", new Type[] { typeof(bool) })]
|
||||
private static bool Prefix_CVR_MenuManager_ToggleQuickMenu(bool show, ref CVR_MenuManager __instance, ref bool ____quickMenuOpen)
|
||||
{
|
||||
if (QuickMenuHelper.Instance == null) return true;
|
||||
if (show != ____quickMenuOpen)
|
||||
{
|
||||
____quickMenuOpen = show;
|
||||
__instance.quickMenu.enabled = true;
|
||||
__instance.quickMenuAnimator.SetBool("Open", show);
|
||||
QuickMenuHelper.Instance.MenuIsOpen = show;
|
||||
QuickMenuHelper.Instance.UpdateWorldAnchors(show);
|
||||
//shouldnt run if switching menus on desktop
|
||||
if (!MetaPort.Instance.isUsingVr)
|
||||
{
|
||||
if (!show && MainMenuHelper.Instance.MenuIsOpen)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
ViewManager.Instance.UiStateToggle(false);
|
||||
}
|
||||
MSP_MenuInfo.ToggleDesktopInputMethod(show);
|
||||
CVRPlayerManager.Instance.ReloadAllNameplates();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//hook menu open/close
|
||||
[HarmonyPrefix]
|
||||
[HarmonyPatch(typeof(ViewManager), "UiStateToggle", new Type[] { typeof(bool) })]
|
||||
private static bool Prefix_ViewManager_UiStateToggle(bool show, ref ViewManager __instance, ref bool ____gameMenuOpen)
|
||||
{
|
||||
if (MainMenuHelper.Instance == null) return true;
|
||||
if (show != ____gameMenuOpen)
|
||||
{
|
||||
____gameMenuOpen = show;
|
||||
__instance.gameMenuView.enabled = true;
|
||||
__instance.uiMenuAnimator.SetBool("Open", show);
|
||||
MainMenuHelper.Instance.MenuIsOpen = show;
|
||||
MainMenuHelper.Instance.UpdateWorldAnchors(show);
|
||||
//shouldnt run if switching menus on desktop
|
||||
if (!MetaPort.Instance.isUsingVr)
|
||||
{
|
||||
if (!show && QuickMenuHelper.Instance.MenuIsOpen)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
CVR_MenuManager.Instance.ToggleQuickMenu(false);
|
||||
}
|
||||
MSP_MenuInfo.ToggleDesktopInputMethod(show);
|
||||
CVRPlayerManager.Instance.ReloadAllNameplates();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//add independent head movement to important input
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(InputModuleMouseKeyboard), "UpdateImportantInput")]
|
||||
private static void Postfix_InputModuleMouseKeyboard_UpdateImportantInput(ref CVRInputManager ____inputManager)
|
||||
{
|
||||
____inputManager.independentHeadTurn |= Input.GetKey(KeyCode.LeftAlt);
|
||||
}
|
||||
|
||||
//Support for changing VRMode during runtime.
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(CVRTools), "ConfigureHudAffinity")]
|
||||
private static void Postfix_CVRTools_ConfigureHudAffinity()
|
||||
{
|
||||
MSP_MenuInfo.CameraTransform = PlayerSetup.Instance.GetActiveCamera().transform;
|
||||
}
|
||||
|
||||
// prevents CVRWorld from closing menus when world transitioning, cause cool
|
||||
[HarmonyTranspiler]
|
||||
[HarmonyPatch(typeof(CVRWorld), nameof(CVRWorld.Start), MethodType.Enumerator)]
|
||||
private static IEnumerable<CodeInstruction> Transpiler_CVRWorld_Start(IEnumerable<CodeInstruction> instructions, ILGenerator il)
|
||||
{
|
||||
var patchedInstructions = new CodeMatcher(instructions).MatchForward(false,
|
||||
new CodeMatch(OpCodes.Ldsfld),
|
||||
new CodeMatch(OpCodes.Ldc_I4_0),
|
||||
new CodeMatch(i => i.opcode == OpCodes.Callvirt && i.operand is MethodInfo { Name: "ForceUiStatus" }))
|
||||
.RemoveInstructions(3)
|
||||
.InstructionEnumeration();
|
||||
|
||||
patchedInstructions = new CodeMatcher(patchedInstructions).MatchForward(false,
|
||||
new CodeMatch(OpCodes.Ldsfld),
|
||||
new CodeMatch(OpCodes.Ldc_I4_0),
|
||||
new CodeMatch(i => i.opcode == OpCodes.Callvirt && i.operand is MethodInfo { Name: "ToggleQuickMenu" }))
|
||||
.RemoveInstructions(3)
|
||||
.InstructionEnumeration();
|
||||
|
||||
return patchedInstructions;
|
||||
}
|
||||
|
||||
[HarmonyPostfix]
|
||||
[HarmonyPatch(typeof(CVR_DesktopCameraController), nameof(CVR_DesktopCameraController.UpdateFov))]
|
||||
private static void Postfix_CVR_DesktopCameraController_UpdateFov()
|
||||
{
|
||||
if (!MenuScalePatch.EntryUseFOVAdjustment.Value)
|
||||
{
|
||||
MSP_MenuInfo.FOVAdjustment = 1f;
|
||||
return;
|
||||
}
|
||||
|
||||
const float minFovValue = 60f;
|
||||
const float maxFovValue = 120f;
|
||||
MSP_MenuInfo.FOVAdjustment =
|
||||
1f + (2f * Mathf.Clamp01((CVR_DesktopCameraController.defaultFov - minFovValue) / (maxFovValue - minFovValue)));
|
||||
}
|
||||
}
|
112
.DepricatedMods/MenuScalePatch/Helpers/MainMenuHelper.cs
Normal file
112
.DepricatedMods/MenuScalePatch/Helpers/MainMenuHelper.cs
Normal file
|
@ -0,0 +1,112 @@
|
|||
using ABI_RC.Core.Player;
|
||||
using ABI_RC.Core.Savior;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace NAK.MenuScalePatch.Helpers;
|
||||
|
||||
//TODO: Implement desktop ratio scaling back to MM
|
||||
|
||||
/**
|
||||
|
||||
This helper is assigned to the MainMenu object.
|
||||
The DefaultExecutionOrder attribute saves me from needing
|
||||
to use OnPreRender() callback... yay.
|
||||
|
||||
**/
|
||||
|
||||
[DefaultExecutionOrder(20000)]
|
||||
public class MainMenuHelper : MonoBehaviour
|
||||
{
|
||||
public static MainMenuHelper Instance;
|
||||
public Transform worldAnchor;
|
||||
public bool NeedsPositionUpdate;
|
||||
public bool MenuIsOpen;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
Instance = this;
|
||||
}
|
||||
|
||||
private void LateUpdate()
|
||||
{
|
||||
if (!MenuIsOpen) return;
|
||||
|
||||
if (MSP_MenuInfo.PlayerAnchorMenus || NeedsPositionUpdate)
|
||||
{
|
||||
UpdateMenuPosition();
|
||||
}
|
||||
|
||||
if (MSP_MenuInfo.UseIndependentHeadTurn)
|
||||
{
|
||||
MSP_MenuInfo.HandleIndependentHeadTurnInput();
|
||||
}
|
||||
}
|
||||
|
||||
public void CreateWorldAnchors()
|
||||
{
|
||||
//VR specific anchor
|
||||
GameObject vrAnchor = new GameObject("MSP_MMVR_Anchor");
|
||||
vrAnchor.transform.parent = PlayerSetup.Instance.vrCameraRig.transform;
|
||||
vrAnchor.transform.localPosition = Vector3.zero;
|
||||
worldAnchor = vrAnchor.transform;
|
||||
}
|
||||
|
||||
public void UpdateWorldAnchors(bool updateMenuPos = false)
|
||||
{
|
||||
if (worldAnchor == null || MSP_MenuInfo.CameraTransform == null) return;
|
||||
|
||||
if (MetaPort.Instance.isUsingVr)
|
||||
{
|
||||
float zRotation = Mathf.Abs(MSP_MenuInfo.CameraTransform.localRotation.eulerAngles.z);
|
||||
float minTilt = MetaPort.Instance.settings.GetSettingsFloat("GeneralMinimumMenuTilt", 0f);
|
||||
if (zRotation <= minTilt || zRotation >= 360f - minTilt)
|
||||
{
|
||||
worldAnchor.rotation = Quaternion.LookRotation(MSP_MenuInfo.CameraTransform.forward, Vector3.up);
|
||||
}
|
||||
else
|
||||
{
|
||||
worldAnchor.rotation = MSP_MenuInfo.CameraTransform.rotation;
|
||||
}
|
||||
worldAnchor.position = MSP_MenuInfo.CameraTransform.position + MSP_MenuInfo.CameraTransform.forward * 2f * MSP_MenuInfo.ScaleFactor;
|
||||
}
|
||||
else
|
||||
{
|
||||
worldAnchor.rotation = MSP_MenuInfo.CameraTransform.rotation;
|
||||
worldAnchor.position = MSP_MenuInfo.CameraTransform.position;
|
||||
}
|
||||
if (updateMenuPos) UpdateMenuPosition();
|
||||
}
|
||||
|
||||
public void UpdateMenuPosition()
|
||||
{
|
||||
NeedsPositionUpdate = false;
|
||||
if (MetaPort.Instance.isUsingVr)
|
||||
{
|
||||
HandleVRPosition();
|
||||
return;
|
||||
}
|
||||
HandleDesktopPosition();
|
||||
}
|
||||
|
||||
//Desktop Main Menu
|
||||
public void HandleDesktopPosition()
|
||||
{
|
||||
if (MSP_MenuInfo.CameraTransform == null || MSP_MenuInfo.DisableMMHelper) return;
|
||||
|
||||
Transform activeAnchor = MSP_MenuInfo.isIndependentHeadTurn ? worldAnchor : MSP_MenuInfo.CameraTransform;
|
||||
transform.localScale = new Vector3(1.6f * MSP_MenuInfo.ScaleFactor * MSP_MenuInfo.FOVAdjustment, 0.9f * MSP_MenuInfo.ScaleFactor * MSP_MenuInfo.FOVAdjustment, 1f);
|
||||
transform.position = activeAnchor.position + activeAnchor.forward * 1f * MSP_MenuInfo.ScaleFactor * MSP_MenuInfo.AspectRatio;
|
||||
transform.rotation = activeAnchor.rotation;
|
||||
}
|
||||
|
||||
//VR Main Menu
|
||||
public void HandleVRPosition()
|
||||
{
|
||||
if (worldAnchor == null || MSP_MenuInfo.DisableMMHelper_VR) return;
|
||||
|
||||
transform.localScale = new Vector3(1.6f * MSP_MenuInfo.ScaleFactor * 1.8f, 0.9f * MSP_MenuInfo.ScaleFactor * 1.8f, 1f);
|
||||
transform.position = worldAnchor.position;
|
||||
transform.rotation = worldAnchor.rotation;
|
||||
}
|
||||
}
|
100
.DepricatedMods/MenuScalePatch/Helpers/QuickMenuHelper.cs
Normal file
100
.DepricatedMods/MenuScalePatch/Helpers/QuickMenuHelper.cs
Normal file
|
@ -0,0 +1,100 @@
|
|||
using ABI_RC.Core.Player;
|
||||
using ABI_RC.Core.Savior;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NAK.MenuScalePatch.Helpers;
|
||||
|
||||
/**
|
||||
|
||||
This helper is assigned to the QuickMenu object.
|
||||
The DefaultExecutionOrder attribute saves me from needing
|
||||
to use OnPreRender() callback... yay.
|
||||
|
||||
**/
|
||||
|
||||
[DefaultExecutionOrder(20000)]
|
||||
public class QuickMenuHelper : MonoBehaviour
|
||||
{
|
||||
public static QuickMenuHelper Instance;
|
||||
public Transform worldAnchor;
|
||||
public Transform handAnchor;
|
||||
public bool NeedsPositionUpdate;
|
||||
public bool MenuIsOpen;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
Instance = this;
|
||||
}
|
||||
|
||||
private void LateUpdate()
|
||||
{
|
||||
if (!MenuIsOpen) return;
|
||||
|
||||
if (MSP_MenuInfo.PlayerAnchorMenus || NeedsPositionUpdate || MetaPort.Instance.isUsingVr)
|
||||
{
|
||||
UpdateMenuPosition();
|
||||
}
|
||||
|
||||
if (MSP_MenuInfo.UseIndependentHeadTurn)
|
||||
{
|
||||
MSP_MenuInfo.HandleIndependentHeadTurnInput();
|
||||
}
|
||||
}
|
||||
|
||||
public void CreateWorldAnchors()
|
||||
{
|
||||
//VR specific anchor
|
||||
GameObject vrAnchor = new GameObject("MSP_QMVR_Anchor");
|
||||
vrAnchor.transform.parent = PlayerSetup.Instance.vrCameraRig.transform;
|
||||
vrAnchor.transform.localPosition = Vector3.zero;
|
||||
worldAnchor = vrAnchor.transform;
|
||||
}
|
||||
|
||||
public void UpdateWorldAnchors(bool updateMenuPos = false)
|
||||
{
|
||||
if (worldAnchor == null || MSP_MenuInfo.CameraTransform == null) return;
|
||||
|
||||
worldAnchor.rotation = MSP_MenuInfo.CameraTransform.rotation;
|
||||
worldAnchor.position = MSP_MenuInfo.CameraTransform.position;
|
||||
if (updateMenuPos) UpdateMenuPosition();
|
||||
}
|
||||
|
||||
public void UpdateMenuPosition()
|
||||
{
|
||||
NeedsPositionUpdate = false;
|
||||
if (MetaPort.Instance.isUsingVr)
|
||||
{
|
||||
HandleVRPosition();
|
||||
return;
|
||||
}
|
||||
HandleDesktopPosition();
|
||||
}
|
||||
|
||||
//Desktop Quick Menu
|
||||
public void HandleDesktopPosition()
|
||||
{
|
||||
if (MSP_MenuInfo.CameraTransform == null || MSP_MenuInfo.DisableQMHelper) return;
|
||||
|
||||
Transform activeAnchor = MSP_MenuInfo.isIndependentHeadTurn ? worldAnchor : MSP_MenuInfo.CameraTransform;
|
||||
transform.localScale = new Vector3(1f * MSP_MenuInfo.ScaleFactor * MSP_MenuInfo.FOVAdjustment, 1f * MSP_MenuInfo.ScaleFactor * MSP_MenuInfo.FOVAdjustment, 1f);
|
||||
transform.rotation = activeAnchor.rotation;
|
||||
transform.position = activeAnchor.position + activeAnchor.transform.forward * 1f * MSP_MenuInfo.ScaleFactor;
|
||||
}
|
||||
|
||||
//VR Quick Menu
|
||||
public void HandleVRPosition()
|
||||
{
|
||||
if (handAnchor == null || MSP_MenuInfo.DisableQMHelper_VR) return;
|
||||
|
||||
if (MSP_MenuInfo.WorldAnchorQM)
|
||||
{
|
||||
transform.localScale = new Vector3(1f * MSP_MenuInfo.ScaleFactor, 1f * MSP_MenuInfo.ScaleFactor, 1f);
|
||||
transform.position = worldAnchor.position + worldAnchor.transform.forward * 1f * MSP_MenuInfo.ScaleFactor;
|
||||
transform.rotation = worldAnchor.rotation;
|
||||
return;
|
||||
}
|
||||
transform.localScale = new Vector3(1f * MSP_MenuInfo.ScaleFactor, 1f * MSP_MenuInfo.ScaleFactor, 1f);
|
||||
transform.position = handAnchor.position;
|
||||
transform.rotation = handAnchor.rotation;
|
||||
}
|
||||
}
|
67
.DepricatedMods/MenuScalePatch/MSP_Menus.cs
Normal file
67
.DepricatedMods/MenuScalePatch/MSP_Menus.cs
Normal file
|
@ -0,0 +1,67 @@
|
|||
using ABI_RC.Core;
|
||||
using ABI_RC.Core.InteractionSystem;
|
||||
using ABI_RC.Core.Savior;
|
||||
using ABI_RC.Systems.MovementSystem;
|
||||
using UnityEngine;
|
||||
|
||||
namespace NAK.MenuScalePatch.Helpers;
|
||||
|
||||
public class MSP_MenuInfo
|
||||
{
|
||||
//Shared Info
|
||||
internal static float ScaleFactor = 1f;
|
||||
internal static float AspectRatio = 1f;
|
||||
internal static float FOVAdjustment = 1f;
|
||||
internal static Transform CameraTransform;
|
||||
|
||||
//Settings...?
|
||||
internal static bool WorldAnchorQM = false;
|
||||
internal static bool UseIndependentHeadTurn = true;
|
||||
internal static bool PlayerAnchorMenus = true;
|
||||
|
||||
//Debug/Integration
|
||||
public static bool DisableQMHelper;
|
||||
public static bool DisableQMHelper_VR;
|
||||
public static bool DisableMMHelper;
|
||||
public static bool DisableMMHelper_VR;
|
||||
|
||||
internal static bool isIndependentHeadTurn = false;
|
||||
|
||||
internal static void ToggleDesktopInputMethod(bool flag)
|
||||
{
|
||||
if (MetaPort.Instance.isUsingVr) return;
|
||||
|
||||
ViewManager.Instance._desktopMouseMode = flag;
|
||||
CVR_MenuManager.Instance._desktopMouseMode = flag;
|
||||
|
||||
RootLogic.Instance.ToggleMouse(flag);
|
||||
CVRInputManager.Instance.inputEnabled = !flag;
|
||||
CVR_MenuManager.Instance.desktopControllerRay.enabled = !flag;
|
||||
}
|
||||
|
||||
internal static void HandleIndependentHeadTurnInput()
|
||||
{
|
||||
//angle of independent look axis
|
||||
bool isPressed = CVRInputManager.Instance.independentHeadTurn || CVRInputManager.Instance.independentHeadToggle;
|
||||
if (isPressed && !isIndependentHeadTurn)
|
||||
{
|
||||
isIndependentHeadTurn = true;
|
||||
MSP_MenuInfo.ToggleDesktopInputMethod(false);
|
||||
QuickMenuHelper.Instance.UpdateWorldAnchors();
|
||||
MainMenuHelper.Instance.UpdateWorldAnchors();
|
||||
}
|
||||
else if (!isPressed && isIndependentHeadTurn)
|
||||
{
|
||||
float angleX = MovementSystem.Instance._followAngleX;
|
||||
float angleY = MovementSystem.Instance._followAngleY;
|
||||
float manualAngleX = MovementSystem.Instance._manualAngleX;
|
||||
if (angleY == 0f && angleX == manualAngleX)
|
||||
{
|
||||
isIndependentHeadTurn = false;
|
||||
MSP_MenuInfo.ToggleDesktopInputMethod(true);
|
||||
QuickMenuHelper.Instance.NeedsPositionUpdate = true;
|
||||
MainMenuHelper.Instance.NeedsPositionUpdate = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
33
.DepricatedMods/MenuScalePatch/Main.cs
Normal file
33
.DepricatedMods/MenuScalePatch/Main.cs
Normal file
|
@ -0,0 +1,33 @@
|
|||
using MelonLoader;
|
||||
|
||||
namespace NAK.MenuScalePatch;
|
||||
|
||||
public class MenuScalePatch : MelonMod
|
||||
{
|
||||
public static MelonPreferences_Category Category =
|
||||
MelonPreferences.CreateCategory(nameof(MenuScalePatch));
|
||||
|
||||
public static MelonPreferences_Entry<bool> EntryUseIndependentHeadTurn =
|
||||
Category.CreateEntry<bool>("Use Independent Head Turn", true, description: "Should you be able to use independent head turn in a menu while in Desktop?");
|
||||
|
||||
public static MelonPreferences_Entry<bool> EntryPlayerAnchorMenus =
|
||||
Category.CreateEntry<bool>("Player Anchor Menus", true, description: "Should the menus be anchored to & constantly follow the player?");
|
||||
|
||||
public static MelonPreferences_Entry<bool> EntryUseFOVAdjustment =
|
||||
Category.CreateEntry<bool>("Use FOV Adjustment", true, description: "Should the menus adjust to your changed FOV?");
|
||||
|
||||
public override void OnInitializeMelon()
|
||||
{
|
||||
foreach (var setting in Category.Entries)
|
||||
{
|
||||
setting.OnEntryValueChangedUntyped.Subscribe(OnUpdateSettings);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void UpdateSettings()
|
||||
{
|
||||
Helpers.MSP_MenuInfo.UseIndependentHeadTurn = EntryUseIndependentHeadTurn.Value;
|
||||
Helpers.MSP_MenuInfo.PlayerAnchorMenus = EntryPlayerAnchorMenus.Value;
|
||||
}
|
||||
private static void OnUpdateSettings(object arg1, object arg2) => UpdateSettings();
|
||||
}
|
2
.DepricatedMods/MenuScalePatch/MenuScalePatch.csproj
Normal file
2
.DepricatedMods/MenuScalePatch/MenuScalePatch.csproj
Normal file
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Sdk="Microsoft.NET.Sdk"/>
|
29
.DepricatedMods/MenuScalePatch/Properties/AssemblyInfo.cs
Normal file
29
.DepricatedMods/MenuScalePatch/Properties/AssemblyInfo.cs
Normal file
|
@ -0,0 +1,29 @@
|
|||
using MelonLoader;
|
||||
using NAK.MenuScalePatch.Properties;
|
||||
using System.Reflection;
|
||||
|
||||
[assembly: AssemblyVersion(AssemblyInfoParams.Version)]
|
||||
[assembly: AssemblyFileVersion(AssemblyInfoParams.Version)]
|
||||
[assembly: AssemblyInformationalVersion(AssemblyInfoParams.Version)]
|
||||
[assembly: AssemblyTitle(nameof(NAK.MenuScalePatch))]
|
||||
[assembly: AssemblyCompany(AssemblyInfoParams.Author)]
|
||||
[assembly: AssemblyProduct(nameof(NAK.MenuScalePatch))]
|
||||
|
||||
[assembly: MelonInfo(
|
||||
typeof(NAK.MenuScalePatch.MenuScalePatch),
|
||||
nameof(NAK.MenuScalePatch),
|
||||
AssemblyInfoParams.Version,
|
||||
AssemblyInfoParams.Author,
|
||||
downloadLink: "https://github.com/NotAKidOnSteam/NAK_CVR_Mods/tree/main/MenuScalePatch"
|
||||
)]
|
||||
|
||||
[assembly: MelonGame("Alpha Blend Interactive", "ChilloutVR")]
|
||||
[assembly: MelonPlatform(MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
|
||||
[assembly: MelonPlatformDomain(MelonPlatformDomainAttribute.CompatibleDomains.MONO)]
|
||||
|
||||
namespace NAK.MenuScalePatch.Properties;
|
||||
internal static class AssemblyInfoParams
|
||||
{
|
||||
public const string Version = "4.2.8";
|
||||
public const string Author = "NotAKidoS";
|
||||
}
|
33
.DepricatedMods/MenuScalePatch/README.md
Normal file
33
.DepricatedMods/MenuScalePatch/README.md
Normal file
|
@ -0,0 +1,33 @@
|
|||
# MenuScalePatch
|
||||
|
||||
Originally forced menu position to update while scaling. Now changes ChilloutVR menu behavior to feel less clunky.
|
||||
|
||||
## Features:
|
||||
* Menu position properly updates at end of update cycle.
|
||||
* This makes sure menu is always correctly positioned while moving and scaling.
|
||||
* This also allows for menus to be used while moving. (this is iffy though)
|
||||
|
||||
* Adds independent head moving support while on Desktop. (makes selecting users easier)
|
||||
* Hold ALT while on Desktop. Native feature that now works while in a menu.
|
||||
|
||||
* Implemented world anchors for menus. They can now be placed in the world, but still attached to you.
|
||||
* This is used for independent head movement internally, as well as a toggle for VR QM.
|
||||
|
||||
* Main Menu in VR is now attached to player rig.
|
||||
* Menu will now follow you while moving in world space, but not while moving in play space.
|
||||
|
||||
* Menus are no longer forced closed on world start.
|
||||
|
||||
https://user-images.githubusercontent.com/37721153/189479474-41e93dff-a695-42f2-9d20-6a895a723039.mp4
|
||||
|
||||
---
|
||||
|
||||
Here is the block of text where I tell you this mod is not affiliated or endorsed by ABI.
|
||||
https://documentation.abinteractive.net/official/legal/tos/#7-modding-our-games
|
||||
|
||||
> This mod is an independent creation and is not affiliated with, supported by or approved by Alpha Blend Interactive.
|
||||
|
||||
> Use of this mod is done so at the user's own risk and the creator cannot be held responsible for any issues arising from its use.
|
||||
|
||||
> To the best of my knowledge, I have adhered to the Modding Guidelines established by Alpha Blend Interactive.
|
||||
|
23
.DepricatedMods/MenuScalePatch/format.json
Normal file
23
.DepricatedMods/MenuScalePatch/format.json
Normal file
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"_id": 95,
|
||||
"name": "MenuScalePatch",
|
||||
"modversion": "4.2.8",
|
||||
"gameversion": "2022r170p1",
|
||||
"loaderversion": "0.6.1",
|
||||
"modtype": "Mod",
|
||||
"author": "NotAKidoS",
|
||||
"description": "Corrects MM and QM position when avatar is being scaled.\n\nOptional setting to enable Independent Head Turn while in menus.\nOptional setting to force menus to always follow player.\nOptional setting to adjust with FOV changes.",
|
||||
"searchtags": [
|
||||
"menu",
|
||||
"scale",
|
||||
"avatarscale",
|
||||
"slider"
|
||||
],
|
||||
"requirements": [
|
||||
"None"
|
||||
],
|
||||
"downloadlink": "https://github.com/NotAKidOnSteam/NAK_CVR_Mods/releases/download/r13/MenuScalePatch.dll",
|
||||
"sourcelink": "https://github.com/NotAKidOnSteam/NAK_CVR_Mods/tree/main/MenuScalePatch/",
|
||||
"changelog": "- Added FOV handling to menu scaling. The menu will scale with changes to your FOV.",
|
||||
"embedcolor": "363020"
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue