mirror of
https://github.com/hanetzer/sdraw_mods_cvr.git
synced 2025-09-03 18:39:23 +00:00
Moved PlayerRagdollMod and DesktopHeadTracking to archived
Fixed for r173 game build
This commit is contained in:
parent
a232c2ce13
commit
9886bdc154
43 changed files with 3490 additions and 3600 deletions
|
@ -1,43 +0,0 @@
|
|||
using ABI_RC.Core;
|
||||
using System.Text.RegularExpressions;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ml_prm
|
||||
{
|
||||
class AvatarBoolParameter
|
||||
{
|
||||
public readonly string m_name;
|
||||
public readonly int m_hash = 0;
|
||||
public readonly bool m_sync;
|
||||
readonly CVRAnimatorManager m_manager = null;
|
||||
|
||||
public AvatarBoolParameter(string p_name, CVRAnimatorManager p_manager)
|
||||
{
|
||||
m_name = p_name;
|
||||
m_manager = p_manager;
|
||||
|
||||
Regex l_regex = new Regex("^#?" + p_name + '$');
|
||||
foreach(var l_param in m_manager.animator.parameters)
|
||||
{
|
||||
if(l_regex.IsMatch(l_param.name) && (l_param.type == AnimatorControllerParameterType.Bool))
|
||||
{
|
||||
m_name = l_param.name;
|
||||
m_hash = l_param.nameHash;
|
||||
m_sync = (l_param.name[0] != '#');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetValue(bool p_value)
|
||||
{
|
||||
if(m_hash != 0)
|
||||
{
|
||||
if(m_sync)
|
||||
m_manager.SetAnimatorParameterBool(m_name, p_value);
|
||||
else
|
||||
m_manager.animator.SetBool(m_hash, p_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
216
ml_prm/Main.cs
216
ml_prm/Main.cs
|
@ -1,216 +0,0 @@
|
|||
using ABI.CCK.Components;
|
||||
using ABI_RC.Core;
|
||||
using ABI_RC.Core.InteractionSystem;
|
||||
using ABI_RC.Core.Player;
|
||||
using ABI_RC.Core.Util.AssetFiltering;
|
||||
using ABI_RC.Systems.IK.SubSystems;
|
||||
using ABI_RC.Systems.MovementSystem;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace ml_prm
|
||||
{
|
||||
public class PlayerRagdollMod : MelonLoader.MelonMod
|
||||
{
|
||||
static PlayerRagdollMod ms_instance = null;
|
||||
|
||||
RagdollController m_localController = null;
|
||||
|
||||
public override void OnInitializeMelon()
|
||||
{
|
||||
if(ms_instance == null)
|
||||
ms_instance = this;
|
||||
|
||||
Settings.Init();
|
||||
ModUi.Init();
|
||||
|
||||
HarmonyInstance.Patch(
|
||||
typeof(PlayerSetup).GetMethod(nameof(PlayerSetup.ClearAvatar)),
|
||||
null,
|
||||
new HarmonyLib.HarmonyMethod(typeof(PlayerRagdollMod).GetMethod(nameof(OnAvatarClear_Postfix), BindingFlags.NonPublic | BindingFlags.Static))
|
||||
);
|
||||
HarmonyInstance.Patch(
|
||||
typeof(PlayerSetup).GetMethod(nameof(PlayerSetup.SetupAvatar)),
|
||||
null,
|
||||
new HarmonyLib.HarmonyMethod(typeof(PlayerRagdollMod).GetMethod(nameof(OnSetupAvatar_Postfix), BindingFlags.Static | BindingFlags.NonPublic))
|
||||
);
|
||||
HarmonyInstance.Patch(
|
||||
typeof(PlayerSetup).GetMethod("SetupIKScaling", BindingFlags.NonPublic | BindingFlags.Instance),
|
||||
null,
|
||||
new HarmonyLib.HarmonyMethod(typeof(PlayerRagdollMod).GetMethod(nameof(OnSetupIKScaling_Postfix), BindingFlags.Static | BindingFlags.NonPublic))
|
||||
);
|
||||
HarmonyInstance.Patch(
|
||||
typeof(CVRSeat).GetMethod(nameof(CVRSeat.SitDown)),
|
||||
new HarmonyLib.HarmonyMethod(typeof(PlayerRagdollMod).GetMethod(nameof(OnCVRSeatSitDown_Prefix), BindingFlags.Static | BindingFlags.NonPublic)),
|
||||
null
|
||||
);
|
||||
HarmonyInstance.Patch(
|
||||
typeof(BodySystem).GetMethod(nameof(BodySystem.StartCalibration)),
|
||||
new HarmonyLib.HarmonyMethod(typeof(PlayerRagdollMod).GetMethod(nameof(OnStartCalibration_Prefix), BindingFlags.Static | BindingFlags.NonPublic)),
|
||||
null
|
||||
);
|
||||
HarmonyInstance.Patch(
|
||||
typeof(RootLogic).GetMethod(nameof(RootLogic.SpawnOnWorldInstance)),
|
||||
new HarmonyLib.HarmonyMethod(typeof(PlayerRagdollMod).GetMethod(nameof(OnWorldSpawn_Prefix), BindingFlags.Static | BindingFlags.NonPublic)),
|
||||
null
|
||||
);
|
||||
HarmonyInstance.Patch(
|
||||
typeof(CombatSystem).GetMethods().First(m => (!m.IsGenericMethod && m.Name == nameof(CombatSystem.Down))),
|
||||
new HarmonyLib.HarmonyMethod(typeof(PlayerRagdollMod).GetMethod(nameof(OnCombatDown_Prefix), BindingFlags.Static | BindingFlags.NonPublic)),
|
||||
null
|
||||
);
|
||||
HarmonyInstance.Patch(
|
||||
typeof(MovementSystem).GetMethod(nameof(MovementSystem.ChangeFlight)),
|
||||
null,
|
||||
new HarmonyLib.HarmonyMethod(typeof(PlayerRagdollMod).GetMethod(nameof(OnChangeFlight_Postfix), BindingFlags.Static | BindingFlags.NonPublic))
|
||||
);
|
||||
|
||||
// Whitelist the toggle script
|
||||
(typeof(SharedFilter).GetField("_localComponentWhitelist", BindingFlags.NonPublic | BindingFlags.Static)?.GetValue(null) as HashSet<Type>)?.Add(typeof(RagdollToggle));
|
||||
|
||||
MelonLoader.MelonCoroutines.Start(WaitForLocalPlayer());
|
||||
}
|
||||
|
||||
public override void OnDeinitializeMelon()
|
||||
{
|
||||
if(ms_instance == this)
|
||||
ms_instance = null;
|
||||
|
||||
m_localController = null;
|
||||
}
|
||||
|
||||
System.Collections.IEnumerator WaitForLocalPlayer()
|
||||
{
|
||||
while(PlayerSetup.Instance == null)
|
||||
yield return null;
|
||||
|
||||
m_localController = PlayerSetup.Instance.gameObject.AddComponent<RagdollController>();
|
||||
ModUi.SwitchChange += this.OnSwitchActivation;
|
||||
}
|
||||
|
||||
void OnSwitchActivation()
|
||||
{
|
||||
if(m_localController != null)
|
||||
m_localController.SwitchRagdoll();
|
||||
}
|
||||
|
||||
// Patches
|
||||
static void OnAvatarClear_Postfix() => ms_instance?.OnAvatarClear();
|
||||
void OnAvatarClear()
|
||||
{
|
||||
try
|
||||
{
|
||||
if(m_localController != null)
|
||||
m_localController.OnAvatarClear();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
MelonLoader.MelonLogger.Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
static void OnSetupAvatar_Postfix() => ms_instance?.OnSetupAvatar();
|
||||
void OnSetupAvatar()
|
||||
{
|
||||
try
|
||||
{
|
||||
if(m_localController != null)
|
||||
m_localController.OnAvatarSetup();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
MelonLoader.MelonLogger.Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
static void OnSetupIKScaling_Postfix(ref UnityEngine.Vector3 ___scaleDifference) => ms_instance?.OnSetupIKScaling(___scaleDifference.y);
|
||||
void OnSetupIKScaling(float p_scaleDifference)
|
||||
{
|
||||
try
|
||||
{
|
||||
if(m_localController != null)
|
||||
m_localController.OnAvatarScaling(1f + p_scaleDifference);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
MelonLoader.MelonLogger.Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
static void OnCVRSeatSitDown_Prefix(ref CVRSeat __instance) => ms_instance?.OnCVRSeatSitDown(__instance);
|
||||
void OnCVRSeatSitDown(CVRSeat p_seat)
|
||||
{
|
||||
try
|
||||
{
|
||||
if(m_localController != null)
|
||||
m_localController.OnSeatSitDown(p_seat);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
MelonLoader.MelonLogger.Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
static void OnStartCalibration_Prefix() => ms_instance?.OnStartCalibration();
|
||||
void OnStartCalibration()
|
||||
{
|
||||
try
|
||||
{
|
||||
if(m_localController != null)
|
||||
m_localController.OnStartCalibration();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
MelonLoader.MelonLogger.Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
static void OnWorldSpawn_Prefix() => ms_instance?.OnWorldSpawn();
|
||||
void OnWorldSpawn()
|
||||
{
|
||||
try
|
||||
{
|
||||
if(m_localController != null)
|
||||
m_localController.OnWorldSpawn();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
MelonLoader.MelonLogger.Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
static void OnCombatDown_Prefix(ref CombatSystem __instance)
|
||||
{
|
||||
if((__instance == CombatSystem.Instance) && !__instance.isDown)
|
||||
ms_instance?.OnCombatDown();
|
||||
}
|
||||
void OnCombatDown()
|
||||
{
|
||||
try
|
||||
{
|
||||
if(m_localController != null)
|
||||
m_localController.OnCombatDown();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
MelonLoader.MelonLogger.Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
static void OnChangeFlight_Postfix() => ms_instance?.OnChangeFlight();
|
||||
void OnChangeFlight()
|
||||
{
|
||||
try
|
||||
{
|
||||
if(m_localController != null)
|
||||
m_localController.OnChangeFlight();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
MelonLoader.MelonLogger.Error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
198
ml_prm/ModUi.cs
198
ml_prm/ModUi.cs
|
@ -1,198 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace ml_prm
|
||||
{
|
||||
static class ModUi
|
||||
{
|
||||
enum UiIndex
|
||||
{
|
||||
Hotkey = 0,
|
||||
Gravity,
|
||||
PointersReaction,
|
||||
IgnoreLocal,
|
||||
CombatReaction,
|
||||
AutoRecover,
|
||||
Slipperiness,
|
||||
Bounciness,
|
||||
ViewVelocity,
|
||||
JumpRecover,
|
||||
VelocityMultiplier,
|
||||
MovementDrag,
|
||||
AngularDrag,
|
||||
RecoverDelay
|
||||
}
|
||||
|
||||
static public event Action SwitchChange;
|
||||
|
||||
static List<object> ms_uiElements = null;
|
||||
|
||||
internal static void Init()
|
||||
{
|
||||
ms_uiElements = new List<object>();
|
||||
|
||||
if(MelonLoader.MelonMod.RegisteredMelons.FirstOrDefault(m => m.Info.Name == "BTKUILib") != null)
|
||||
CreateUi();
|
||||
}
|
||||
|
||||
// Separated method, otherwise exception is thrown, funny CSharp and optional references, smh
|
||||
static void CreateUi()
|
||||
{
|
||||
BTKUILib.QuickMenuAPI.PrepareIcon("PlayerRagdollMod", "PRM-Person", GetIconStream("person.png"));
|
||||
|
||||
var l_modRoot = new BTKUILib.UIObjects.Page("PlayerRagdollMod", "MainPage", true, "PRM-Person");
|
||||
l_modRoot.MenuTitle = "Player Ragdoll Mod";
|
||||
l_modRoot.MenuSubtitle = "Become a ragdoll and change various settings for people amusement";
|
||||
|
||||
var l_modCategory = l_modRoot.AddCategory("Settings");
|
||||
|
||||
l_modCategory.AddButton("Switch ragdoll", "PRM-Person", "Switch between normal and ragdoll state").OnPress += () => SwitchChange?.Invoke();
|
||||
|
||||
ms_uiElements.Add(l_modCategory.AddToggle("Use hotkey", "Switch ragdoll mode with 'R' key", Settings.Hotkey));
|
||||
(ms_uiElements[(int)UiIndex.Hotkey] as BTKUILib.UIObjects.Components.ToggleButton).OnValueUpdated += (state) => OnToggleUpdate(UiIndex.Hotkey, state);
|
||||
|
||||
ms_uiElements.Add(l_modCategory.AddToggle("Use gravity", "Apply gravity to ragdoll", Settings.Gravity));
|
||||
(ms_uiElements[(int)UiIndex.Gravity] as BTKUILib.UIObjects.Components.ToggleButton).OnValueUpdated += (state) => OnToggleUpdate(UiIndex.Gravity, state);
|
||||
|
||||
ms_uiElements.Add(l_modCategory.AddToggle("Pointers reaction", "React to trigger colliders with CVRPointer component of 'ragdoll' type", Settings.PointersReaction));
|
||||
(ms_uiElements[(int)UiIndex.PointersReaction] as BTKUILib.UIObjects.Components.ToggleButton).OnValueUpdated += (state) => OnToggleUpdate(UiIndex.PointersReaction, state);
|
||||
|
||||
ms_uiElements.Add(l_modCategory.AddToggle("Ignore local pointers", "Ignore local avatar's CVRPointer components of 'ragdoll' type", Settings.IgnoreLocal));
|
||||
(ms_uiElements[(int)UiIndex.IgnoreLocal] as BTKUILib.UIObjects.Components.ToggleButton).OnValueUpdated += (state) => OnToggleUpdate(UiIndex.IgnoreLocal, state);
|
||||
|
||||
ms_uiElements.Add(l_modCategory.AddToggle("Combat reaction", "Ragdoll upon combat system death", Settings.CombatReaction));
|
||||
(ms_uiElements[(int)UiIndex.CombatReaction] as BTKUILib.UIObjects.Components.ToggleButton).OnValueUpdated += (state) => OnToggleUpdate(UiIndex.CombatReaction, state);
|
||||
|
||||
ms_uiElements.Add(l_modCategory.AddToggle("Auto recover", "Automatically unragdoll after set recover delay", Settings.AutoRecover));
|
||||
(ms_uiElements[(int)UiIndex.AutoRecover] as BTKUILib.UIObjects.Components.ToggleButton).OnValueUpdated += (state) => OnToggleUpdate(UiIndex.AutoRecover, state);
|
||||
|
||||
ms_uiElements.Add(l_modCategory.AddToggle("Slipperiness", "Enables/disables friction of ragdoll", Settings.Slipperiness));
|
||||
(ms_uiElements[(int)UiIndex.Slipperiness] as BTKUILib.UIObjects.Components.ToggleButton).OnValueUpdated += (state) => OnToggleUpdate(UiIndex.Slipperiness, state);
|
||||
|
||||
ms_uiElements.Add(l_modCategory.AddToggle("Bounciness", "Enables/disables bounciness of ragdoll", Settings.Bounciness));
|
||||
(ms_uiElements[(int)UiIndex.Bounciness] as BTKUILib.UIObjects.Components.ToggleButton).OnValueUpdated += (state) => OnToggleUpdate(UiIndex.Bounciness, state);
|
||||
|
||||
ms_uiElements.Add(l_modCategory.AddToggle("View direction velocity", "Apply velocity to camera view direction", Settings.ViewVelocity));
|
||||
(ms_uiElements[(int)UiIndex.ViewVelocity] as BTKUILib.UIObjects.Components.ToggleButton).OnValueUpdated += (state) => OnToggleUpdate(UiIndex.ViewVelocity, state);
|
||||
|
||||
ms_uiElements.Add(l_modCategory.AddToggle("Jump recover", "Recover from ragdoll state by jumping", Settings.JumpRecover));
|
||||
(ms_uiElements[(int)UiIndex.JumpRecover] as BTKUILib.UIObjects.Components.ToggleButton).OnValueUpdated += (state) => OnToggleUpdate(UiIndex.JumpRecover, state);
|
||||
|
||||
ms_uiElements.Add(l_modRoot.AddSlider("Velocity multiplier", "Velocity multiplier upon entering ragdoll state", Settings.VelocityMultiplier, 1f, 50f));
|
||||
(ms_uiElements[(int)UiIndex.VelocityMultiplier] as BTKUILib.UIObjects.Components.SliderFloat).OnValueUpdated += (value) => OnSliderUpdate(UiIndex.VelocityMultiplier, value);
|
||||
|
||||
ms_uiElements.Add(l_modRoot.AddSlider("Movement drag", "Movement resistance", Settings.MovementDrag, 0f, 50f));
|
||||
(ms_uiElements[(int)UiIndex.MovementDrag] as BTKUILib.UIObjects.Components.SliderFloat).OnValueUpdated += (value) => OnSliderUpdate(UiIndex.MovementDrag, value);
|
||||
|
||||
ms_uiElements.Add(l_modRoot.AddSlider("Angular movement drag", "Rotation movement resistance", Settings.AngularDrag, 0f, 50f));
|
||||
(ms_uiElements[(int)UiIndex.AngularDrag] as BTKUILib.UIObjects.Components.SliderFloat).OnValueUpdated += (value) => OnSliderUpdate(UiIndex.AngularDrag, value);
|
||||
|
||||
ms_uiElements.Add(l_modRoot.AddSlider("Recover delay (seconds)", "Recover delay for automatic recover", Settings.RecoverDelay, 1f, 10f));
|
||||
(ms_uiElements[(int)UiIndex.RecoverDelay] as BTKUILib.UIObjects.Components.SliderFloat).OnValueUpdated += (value) => OnSliderUpdate(UiIndex.RecoverDelay, value);
|
||||
|
||||
l_modCategory.AddButton("Reset settings", "", "Reset mod settings to default").OnPress += Reset;
|
||||
}
|
||||
|
||||
static void OnToggleUpdate(UiIndex p_index, bool p_state, bool p_force = false)
|
||||
{
|
||||
switch(p_index)
|
||||
{
|
||||
case UiIndex.Hotkey:
|
||||
Settings.SetSetting(Settings.ModSetting.Hotkey, p_state);
|
||||
break;
|
||||
|
||||
case UiIndex.Gravity:
|
||||
Settings.SetSetting(Settings.ModSetting.Gravity, p_state);
|
||||
break;
|
||||
|
||||
case UiIndex.PointersReaction:
|
||||
Settings.SetSetting(Settings.ModSetting.PointersReaction, p_state);
|
||||
break;
|
||||
|
||||
case UiIndex.IgnoreLocal:
|
||||
Settings.SetSetting(Settings.ModSetting.IgnoreLocal, p_state);
|
||||
break;
|
||||
|
||||
case UiIndex.CombatReaction:
|
||||
Settings.SetSetting(Settings.ModSetting.CombatReaction, p_state);
|
||||
break;
|
||||
|
||||
case UiIndex.AutoRecover:
|
||||
Settings.SetSetting(Settings.ModSetting.AutoRecover, p_state);
|
||||
break;
|
||||
|
||||
case UiIndex.Slipperiness:
|
||||
Settings.SetSetting(Settings.ModSetting.Slipperiness, p_state);
|
||||
break;
|
||||
|
||||
case UiIndex.Bounciness:
|
||||
Settings.SetSetting(Settings.ModSetting.Bounciness, p_state);
|
||||
break;
|
||||
|
||||
case UiIndex.ViewVelocity:
|
||||
Settings.SetSetting(Settings.ModSetting.ViewVelocity, p_state);
|
||||
break;
|
||||
|
||||
case UiIndex.JumpRecover:
|
||||
Settings.SetSetting(Settings.ModSetting.JumpRecover, p_state);
|
||||
break;
|
||||
}
|
||||
|
||||
if(p_force)
|
||||
(ms_uiElements[(int)p_index] as BTKUILib.UIObjects.Components.ToggleButton).ToggleValue = p_state;
|
||||
}
|
||||
|
||||
static void OnSliderUpdate(UiIndex p_index, float p_value, bool p_force = false)
|
||||
{
|
||||
switch(p_index)
|
||||
{
|
||||
case UiIndex.VelocityMultiplier:
|
||||
Settings.SetSetting(Settings.ModSetting.VelocityMultiplier, p_value);
|
||||
break;
|
||||
|
||||
case UiIndex.MovementDrag:
|
||||
Settings.SetSetting(Settings.ModSetting.MovementDrag, p_value);
|
||||
break;
|
||||
|
||||
case UiIndex.AngularDrag:
|
||||
Settings.SetSetting(Settings.ModSetting.AngularDrag, p_value);
|
||||
break;
|
||||
|
||||
case UiIndex.RecoverDelay:
|
||||
Settings.SetSetting(Settings.ModSetting.RecoverDelay, p_value);
|
||||
break;
|
||||
}
|
||||
|
||||
if(p_force)
|
||||
(ms_uiElements[(int)p_index] as BTKUILib.UIObjects.Components.SliderFloat).SetSliderValue(p_value);
|
||||
}
|
||||
|
||||
static void Reset()
|
||||
{
|
||||
OnToggleUpdate(UiIndex.Hotkey, true, true);
|
||||
OnToggleUpdate(UiIndex.Gravity, true, true);
|
||||
OnToggleUpdate(UiIndex.PointersReaction, true, true);
|
||||
OnToggleUpdate(UiIndex.IgnoreLocal, true, true);
|
||||
OnToggleUpdate(UiIndex.CombatReaction, true, true);
|
||||
OnToggleUpdate(UiIndex.AutoRecover, false, true);
|
||||
OnToggleUpdate(UiIndex.Slipperiness, false, true);
|
||||
OnToggleUpdate(UiIndex.Bounciness, false, true);
|
||||
OnToggleUpdate(UiIndex.ViewVelocity, false, true);
|
||||
OnToggleUpdate(UiIndex.JumpRecover, false, true);
|
||||
OnSliderUpdate(UiIndex.VelocityMultiplier, 2f, true);
|
||||
OnSliderUpdate(UiIndex.MovementDrag, 2f, true);
|
||||
OnSliderUpdate(UiIndex.AngularDrag, 2f, true);
|
||||
OnSliderUpdate(UiIndex.RecoverDelay, 3f, true);
|
||||
}
|
||||
|
||||
static Stream GetIconStream(string p_name)
|
||||
{
|
||||
Assembly l_assembly = Assembly.GetExecutingAssembly();
|
||||
string l_assemblyName = l_assembly.GetName().Name;
|
||||
return l_assembly.GetManifestResourceStream(l_assemblyName + ".resources." + p_name);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
[assembly: MelonLoader.MelonInfo(typeof(ml_prm.PlayerRagdollMod), "PlayerRagdollMod", "1.0.11", "SDraw", "https://github.com/SDraw/ml_mods_cvr")]
|
||||
[assembly: MelonLoader.MelonGame(null, "ChilloutVR")]
|
||||
[assembly: MelonLoader.MelonPriority(2)]
|
||||
[assembly: MelonLoader.MelonOptionalDependencies("BTKUILib")]
|
||||
[assembly: MelonLoader.MelonPlatform(MelonLoader.MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
|
||||
[assembly: MelonLoader.MelonPlatformDomain(MelonLoader.MelonPlatformDomainAttribute.CompatibleDomains.MONO)]
|
||||
[assembly: MelonLoader.MelonAdditionalCredits("kafeijao, NotAKidOnSteam")]
|
|
@ -1,68 +0,0 @@
|
|||
# Player Ragdoll Mod
|
||||
This mod turns player's avatar into ragdoll puppet.
|
||||
|
||||
# Installation
|
||||
* Install [latest MelonLoader](https://github.com/LavaGang/MelonLoader)
|
||||
* Get [latest release DLL](../../../releases/latest):
|
||||
* Put `ml_prm.dll` in `Mods` folder of game
|
||||
|
||||
# Usage
|
||||
* Press `R` to turn into ragdoll and back.
|
||||
|
||||
Optional mod's settings page with [BTKUILib](https://github.com/BTK-Development/BTKUILib):
|
||||
* **Switch ragdoll:** turns into ragdoll state and back, made for VR usage primarily.
|
||||
* **Use hotkey:** enables/disables ragdoll state switch with `R` key; `true` by default.
|
||||
* **Use gravity:** enables/disables gravity for ragdoll; `true` by default.
|
||||
* Note: Forcibly enabled in worlds that don't allow flight.
|
||||
* **Pointers reaction:** enables ragdoll state when player collides with trigger colliders and particle systems with CVRPointer component of `ragdoll` type (avatars, props and world included); `true` by default.
|
||||
* **Ignore local pointers:** enables/disables ignoring of CVRPointer components of `ragdoll` type on local player's avatar; `true` by default.
|
||||
* **Combat reaction:** enables ragdoll state upon death in worlds with combat system; `true` by default.
|
||||
* **Auto recover:** enables automatic recovering after specific time delay; `false` by default.
|
||||
* **Slipperiness:** enables/disable low friction of ragdoll; `false` by default.
|
||||
* Note: Forcibly disabled in worlds that don't allow flight.
|
||||
* **Bounciness:** enables/disable bounce force of ragdoll; `false` by default.
|
||||
* Note: Forcibly disabled in worlds that don't allow flight.
|
||||
* **View direction velocity:** apply velocity to camera view direction instead of player movement direction; `false` by default.
|
||||
* Note: Forcibly disabled in worlds that don't allow flight.
|
||||
* **Jump recover:** enables recovering from ragdoll state by jumping; `false` by default.
|
||||
* **Velocity multiplier:** velocity force multiplier based on player's movement direction; `2.0` by default.
|
||||
* Note: Limited according to world's fly multiplier.
|
||||
* Note: Forcibly set to `1.0` in worlds that don't allow flight.
|
||||
* **Movement drag:** movement resistance; `2.0` by default.
|
||||
* Note: Forcibly set to `1.0` in worlds that don't allow flight.
|
||||
* **Angular movement drag:** angular movement resistance; `2.0` by default.
|
||||
* **Recover delay:** time delay for enabled `Auto recover` in seconds; `3.0` by default.
|
||||
* **Reset settings:** resets mod settings to default.
|
||||
|
||||
Optional mod's settings in [UIExpansionKit](https://github.com/ddakebono/ChilloutMods):
|
||||
* **Hotkey:** system key that is used to switch ragdoll state; `R` by default.
|
||||
|
||||
Available additional parameters for AAS animator:
|
||||
* **`Ragdolled`:** defines current ragdoll state; boolean.
|
||||
* Note: Can be set as local-only (not synced) if starts with `#` character.
|
||||
|
||||
# Unity Editor Script
|
||||
You can also trigger the ragdoll via animations on your avatar. To do this you need:
|
||||
* Download and import the `ml_prm_editor_script.unitypackage` into your unity project
|
||||
* Add the component `Ragdoll Toggle` anywhere inside of your avatar's hierarchy.
|
||||
|
||||
Now you can animate both parameters available:
|
||||
- **Should Override:** whether the animation should override the toggled state of the ragdoll.
|
||||
- **Is On:** whether the ragdoll state is On or Off (only works if `Should Override` is also On).
|
||||
|
||||

|
||||
Note: In order to work the game object needs to be active and the component enabled.
|
||||
|
||||
# Mods Integration
|
||||
You can use this mod's functions within your mod. To do this you need:
|
||||
* Add mod's dll as reference in your project
|
||||
* Access ragdoll controller with `ml_prm.RagdollController.Instance`
|
||||
|
||||
Available methods:
|
||||
* ```bool IsRagdolled()```
|
||||
* ```void SwitchRagdoll()```
|
||||
|
||||
# Notes
|
||||
* If ragdoll state is enabled during emote, remote players see whole emote playing while local player sees ragdolling. It's tied to how game handles remote players, currently can be prevented with (choose one):
|
||||
* Renaming avatar emote animations to not have default name or containing `Emote` substring.
|
||||
* Holding any movement key right after activating ragdoll state.
|
|
@ -1,570 +0,0 @@
|
|||
using ABI.CCK.Components;
|
||||
using ABI_RC.Core.InteractionSystem;
|
||||
using ABI_RC.Core.Player;
|
||||
using ABI_RC.Core.Savior;
|
||||
using ABI_RC.Systems.IK.SubSystems;
|
||||
using ABI_RC.Systems.InputManagement;
|
||||
using ABI_RC.Systems.MovementSystem;
|
||||
using RootMotion.Dynamics;
|
||||
using RootMotion.FinalIK;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ml_prm
|
||||
{
|
||||
[DisallowMultipleComponent]
|
||||
public class RagdollController : MonoBehaviour
|
||||
{
|
||||
const float c_defaultFriction = 0.6f;
|
||||
|
||||
public static RagdollController Instance { get; private set; } = null;
|
||||
|
||||
VRIK m_vrIK = null;
|
||||
float m_vrIkWeight = 1f;
|
||||
bool m_inVr = false;
|
||||
|
||||
bool m_enabled = false;
|
||||
|
||||
readonly List<Rigidbody> m_rigidBodies = null;
|
||||
readonly List<Collider> m_colliders = null;
|
||||
Transform m_puppetRoot = null;
|
||||
Transform m_puppet = null;
|
||||
BipedRagdollReferences m_puppetReferences;
|
||||
readonly List<System.Tuple<Transform, Transform>> m_boneLinks = null;
|
||||
readonly List<System.Tuple<CharacterJoint, Vector3>> m_jointAnchors = null;
|
||||
|
||||
bool m_avatarReady = false;
|
||||
Vector3 m_lastPosition = Vector3.zero;
|
||||
Vector3 m_velocity = Vector3.zero;
|
||||
Vector3 m_ragdollLastPos = Vector3.zero;
|
||||
|
||||
RagdollToggle m_avatarRagdollToggle = null;
|
||||
RagdollTrigger m_customTrigger = null;
|
||||
AvatarBoolParameter m_ragdolledParameter = null;
|
||||
readonly PhysicMaterial m_physicsMaterial = null;
|
||||
|
||||
bool m_reachedGround = true;
|
||||
float m_groundedTime = 0f;
|
||||
float m_downTime = float.MinValue;
|
||||
|
||||
internal RagdollController()
|
||||
{
|
||||
if(Instance == null)
|
||||
Instance = this;
|
||||
|
||||
m_rigidBodies = new List<Rigidbody>();
|
||||
m_colliders = new List<Collider>();
|
||||
m_boneLinks = new List<System.Tuple<Transform, Transform>>();
|
||||
m_jointAnchors = new List<System.Tuple<CharacterJoint, Vector3>>();
|
||||
|
||||
m_physicsMaterial = new PhysicMaterial("Ragdoll");
|
||||
m_physicsMaterial.dynamicFriction = c_defaultFriction;
|
||||
m_physicsMaterial.staticFriction = c_defaultFriction;
|
||||
m_physicsMaterial.frictionCombine = PhysicMaterialCombine.Average;
|
||||
m_physicsMaterial.bounciness = 0f;
|
||||
m_physicsMaterial.bounceCombine = PhysicMaterialCombine.Average;
|
||||
}
|
||||
~RagdollController()
|
||||
{
|
||||
if(Instance == this)
|
||||
Instance = null;
|
||||
}
|
||||
|
||||
// Unity events
|
||||
void Start()
|
||||
{
|
||||
m_inVr = Utils.IsInVR();
|
||||
|
||||
m_puppetRoot = new GameObject("[PlayerAvatarPuppet]").transform;
|
||||
m_puppetRoot.parent = PlayerSetup.Instance.transform;
|
||||
m_puppetRoot.localPosition = Vector3.zero;
|
||||
m_puppetRoot.localRotation = Quaternion.identity;
|
||||
|
||||
m_customTrigger = MovementSystem.Instance.proxyCollider.gameObject.AddComponent<RagdollTrigger>();
|
||||
|
||||
Settings.MovementDragChange += this.OnMovementDragChange;
|
||||
Settings.AngularDragChange += this.OnAngularDragChange;
|
||||
Settings.GravityChange += this.OnGravityChange;
|
||||
Settings.SlipperinessChange += this.OnPhysicsMaterialChange;
|
||||
Settings.BouncinessChange += this.OnPhysicsMaterialChange;
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
if(m_customTrigger != null)
|
||||
{
|
||||
Object.Destroy(m_customTrigger);
|
||||
m_customTrigger = null;
|
||||
}
|
||||
|
||||
Settings.MovementDragChange -= this.OnMovementDragChange;
|
||||
Settings.AngularDragChange -= this.OnAngularDragChange;
|
||||
Settings.GravityChange -= this.OnGravityChange;
|
||||
Settings.SlipperinessChange -= this.OnPhysicsMaterialChange;
|
||||
Settings.BouncinessChange -= this.OnPhysicsMaterialChange;
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
if(m_avatarReady && m_enabled)
|
||||
{
|
||||
Vector3 l_dif = m_puppetReferences.hips.position - m_ragdollLastPos;
|
||||
PlayerSetup.Instance.transform.position += l_dif;
|
||||
m_puppetReferences.hips.position -= l_dif;
|
||||
m_ragdollLastPos = m_puppetReferences.hips.position;
|
||||
}
|
||||
|
||||
if(m_avatarReady && !m_enabled)
|
||||
{
|
||||
Vector3 l_pos = PlayerSetup.Instance.transform.position;
|
||||
m_velocity = (m_velocity + (l_pos - m_lastPosition) / Time.deltaTime) * 0.5f;
|
||||
m_lastPosition = l_pos;
|
||||
|
||||
if(!m_reachedGround && MovementSystem.Instance.IsGrounded())
|
||||
{
|
||||
m_groundedTime += Time.deltaTime;
|
||||
if(m_groundedTime >= 0.25f)
|
||||
m_reachedGround = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(m_avatarReady && m_enabled && !BodySystem.isCalibrating)
|
||||
BodySystem.TrackingPositionWeight = 0f;
|
||||
|
||||
if(m_avatarReady && m_enabled && Settings.AutoRecover)
|
||||
{
|
||||
m_downTime += Time.deltaTime;
|
||||
if(m_downTime >= Settings.RecoverDelay)
|
||||
{
|
||||
SwitchRagdoll();
|
||||
m_downTime = float.MinValue; // One attepmt to recover
|
||||
}
|
||||
}
|
||||
|
||||
if((m_avatarRagdollToggle != null) && m_avatarRagdollToggle.isActiveAndEnabled && m_avatarRagdollToggle.shouldOverride && (m_enabled != m_avatarRagdollToggle.isOn))
|
||||
SwitchRagdoll();
|
||||
|
||||
if((m_customTrigger != null) && m_customTrigger.GetStateWithReset() && m_avatarReady && !m_enabled && Settings.PointersReaction)
|
||||
SwitchRagdoll();
|
||||
|
||||
if(Settings.Hotkey && Input.GetKeyDown(Settings.HotkeyKey) && !ViewManager.Instance.isGameMenuOpen())
|
||||
SwitchRagdoll();
|
||||
|
||||
if(m_avatarReady && m_enabled && CVRInputManager.Instance.jump && Settings.JumpRecover)
|
||||
SwitchRagdoll();
|
||||
}
|
||||
|
||||
void LateUpdate()
|
||||
{
|
||||
if(m_avatarReady)
|
||||
{
|
||||
if(m_enabled)
|
||||
{
|
||||
if(!BodySystem.isCalibrating)
|
||||
{
|
||||
BodySystem.TrackingPositionWeight = 0f;
|
||||
|
||||
foreach(var l_link in m_boneLinks)
|
||||
l_link.Item1.CopyGlobal(l_link.Item2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach(var l_link in m_boneLinks)
|
||||
l_link.Item2.CopyGlobal(l_link.Item1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Game events
|
||||
internal void OnAvatarClear()
|
||||
{
|
||||
if(m_enabled && (MovementSystem.Instance != null))
|
||||
MovementSystem.Instance.SetImmobilized(false);
|
||||
|
||||
if(m_puppet != null)
|
||||
Object.Destroy(m_puppet.gameObject);
|
||||
m_puppet = null;
|
||||
|
||||
m_vrIK = null;
|
||||
m_enabled = false;
|
||||
m_avatarReady = false;
|
||||
m_avatarRagdollToggle = null;
|
||||
m_ragdolledParameter = null;
|
||||
m_rigidBodies.Clear();
|
||||
m_colliders.Clear();
|
||||
m_puppetReferences = new BipedRagdollReferences();
|
||||
m_boneLinks.Clear();
|
||||
m_jointAnchors.Clear();
|
||||
m_reachedGround = true;
|
||||
m_groundedTime = 0f;
|
||||
m_downTime = float.MinValue;
|
||||
m_puppetRoot.localScale = Vector3.one;
|
||||
}
|
||||
|
||||
internal void OnAvatarSetup()
|
||||
{
|
||||
m_inVr = Utils.IsInVR();
|
||||
|
||||
if(PlayerSetup.Instance._animator.isHuman)
|
||||
{
|
||||
BipedRagdollReferences l_avatarReferences = BipedRagdollReferences.FromAvatar(PlayerSetup.Instance._animator);
|
||||
|
||||
m_puppet = new GameObject("Root").transform;
|
||||
m_puppet.parent = m_puppetRoot;
|
||||
m_puppet.localPosition = Vector3.zero;
|
||||
m_puppet.localRotation = Quaternion.identity;
|
||||
|
||||
m_puppetReferences.root = m_puppet;
|
||||
m_puppetReferences.hips = CloneTransform(l_avatarReferences.hips, m_puppetReferences.root, "Hips");
|
||||
m_puppetReferences.spine = CloneTransform(l_avatarReferences.spine, m_puppetReferences.hips, "Spine");
|
||||
|
||||
if(l_avatarReferences.chest != null)
|
||||
m_puppetReferences.chest = CloneTransform(l_avatarReferences.chest, m_puppetReferences.spine, "Chest");
|
||||
|
||||
m_puppetReferences.head = CloneTransform(l_avatarReferences.head, (m_puppetReferences.chest != null) ? m_puppetReferences.chest : m_puppetReferences.spine, "Head");
|
||||
|
||||
m_puppetReferences.leftUpperArm = CloneTransform(l_avatarReferences.leftUpperArm, (m_puppetReferences.chest != null) ? m_puppetReferences.chest : m_puppetReferences.spine, "LeftUpperArm");
|
||||
m_puppetReferences.leftLowerArm = CloneTransform(l_avatarReferences.leftLowerArm, m_puppetReferences.leftUpperArm, "LeftLowerArm");
|
||||
m_puppetReferences.leftHand = CloneTransform(l_avatarReferences.leftHand, m_puppetReferences.leftLowerArm, "LeftHand");
|
||||
|
||||
m_puppetReferences.rightUpperArm = CloneTransform(l_avatarReferences.rightUpperArm, (m_puppetReferences.chest != null) ? m_puppetReferences.chest : m_puppetReferences.spine, "RightUpperArm");
|
||||
m_puppetReferences.rightLowerArm = CloneTransform(l_avatarReferences.rightLowerArm, m_puppetReferences.rightUpperArm, "RightLowerArm");
|
||||
m_puppetReferences.rightHand = CloneTransform(l_avatarReferences.rightHand, m_puppetReferences.rightLowerArm, "RightHand");
|
||||
|
||||
m_puppetReferences.leftUpperLeg = CloneTransform(l_avatarReferences.leftUpperLeg, m_puppetReferences.hips, "LeftUpperLeg");
|
||||
m_puppetReferences.leftLowerLeg = CloneTransform(l_avatarReferences.leftLowerLeg, m_puppetReferences.leftUpperLeg, "LeftLowerLeg");
|
||||
m_puppetReferences.leftFoot = CloneTransform(l_avatarReferences.leftFoot, m_puppetReferences.leftLowerLeg, "LeftFoot");
|
||||
|
||||
m_puppetReferences.rightUpperLeg = CloneTransform(l_avatarReferences.rightUpperLeg, m_puppetReferences.hips, "RightUpperLeg");
|
||||
m_puppetReferences.rightLowerLeg = CloneTransform(l_avatarReferences.rightLowerLeg, m_puppetReferences.rightUpperLeg, "RightLowerLeg");
|
||||
m_puppetReferences.rightFoot = CloneTransform(l_avatarReferences.rightFoot, m_puppetReferences.rightLowerLeg, "RightFoot");
|
||||
|
||||
// Move to world origin to overcome possible issues, maybe?
|
||||
m_puppetRoot.position = Vector3.zero;
|
||||
m_puppetRoot.rotation = Quaternion.identity;
|
||||
|
||||
BipedRagdollCreator.Options l_options = BipedRagdollCreator.AutodetectOptions(m_puppetReferences);
|
||||
l_options.joints = RagdollCreator.JointType.Character;
|
||||
BipedRagdollCreator.Create(m_puppetReferences, l_options);
|
||||
|
||||
Transform[] l_puppetTransforms = m_puppetReferences.GetRagdollTransforms();
|
||||
Transform[] l_avatarTransforms = l_avatarReferences.GetRagdollTransforms();
|
||||
for(int i = 0; i < l_puppetTransforms.Length; i++)
|
||||
{
|
||||
if(l_puppetTransforms[i] != null)
|
||||
{
|
||||
Rigidbody l_body = l_puppetTransforms[i].GetComponent<Rigidbody>();
|
||||
if(l_body != null)
|
||||
{
|
||||
m_rigidBodies.Add(l_body);
|
||||
l_body.isKinematic = true;
|
||||
l_body.angularDrag = Settings.AngularDrag;
|
||||
l_body.drag = (Utils.IsWorldSafe() ? Settings.MovementDrag : 1f);
|
||||
l_body.useGravity = (!Utils.IsWorldSafe() || Settings.Gravity);
|
||||
l_body.collisionDetectionMode = CollisionDetectionMode.ContinuousDynamic;
|
||||
l_body.gameObject.layer = LayerMask.NameToLayer("PlayerLocal");
|
||||
}
|
||||
|
||||
CharacterJoint l_joint = l_puppetTransforms[i].GetComponent<CharacterJoint>();
|
||||
if(l_joint != null)
|
||||
{
|
||||
l_joint.enablePreprocessing = false;
|
||||
l_joint.enableProjection = true;
|
||||
m_jointAnchors.Add(System.Tuple.Create(l_joint, l_joint.connectedAnchor));
|
||||
}
|
||||
|
||||
Collider l_collider = l_puppetTransforms[i].GetComponent<Collider>();
|
||||
if(l_collider != null)
|
||||
{
|
||||
Physics.IgnoreCollision(l_collider, MovementSystem.Instance.proxyCollider, true);
|
||||
Physics.IgnoreCollision(l_collider, MovementSystem.Instance.controller, true);
|
||||
Physics.IgnoreCollision(l_collider, MovementSystem.Instance.forceCollider, true);
|
||||
l_collider.enabled = false;
|
||||
l_collider.sharedMaterial = m_physicsMaterial;
|
||||
l_collider.material = m_physicsMaterial;
|
||||
m_colliders.Add(l_collider);
|
||||
}
|
||||
|
||||
if(l_avatarTransforms[i] != null)
|
||||
m_boneLinks.Add(System.Tuple.Create(l_puppetTransforms[i], l_avatarTransforms[i]));
|
||||
}
|
||||
}
|
||||
|
||||
// And return back
|
||||
m_puppetRoot.localPosition = Vector3.zero;
|
||||
m_puppetRoot.localRotation = Quaternion.identity;
|
||||
m_puppetRoot.gameObject.SetActive(false);
|
||||
|
||||
m_vrIK = PlayerSetup.Instance._avatar.GetComponent<VRIK>();
|
||||
if(m_vrIK != null)
|
||||
{
|
||||
m_vrIK.onPreSolverUpdate.AddListener(this.OnIKPreUpdate);
|
||||
m_vrIK.onPostSolverUpdate.AddListener(this.OnIKPostUpdate);
|
||||
}
|
||||
|
||||
m_avatarRagdollToggle = PlayerSetup.Instance._avatar.GetComponentInChildren<RagdollToggle>(true);
|
||||
m_ragdolledParameter = new AvatarBoolParameter("Ragdolled", PlayerSetup.Instance.animatorManager);
|
||||
|
||||
m_avatarReady = true;
|
||||
}
|
||||
}
|
||||
|
||||
internal void OnAvatarScaling(float p_scaleDifference)
|
||||
{
|
||||
if(m_avatarReady)
|
||||
{
|
||||
m_puppetRoot.localScale = Vector3.one * p_scaleDifference;
|
||||
foreach(var l_pair in m_jointAnchors)
|
||||
l_pair.Item1.connectedAnchor = l_pair.Item2 * p_scaleDifference;
|
||||
}
|
||||
}
|
||||
|
||||
internal void OnSeatSitDown(CVRSeat p_seat)
|
||||
{
|
||||
if(m_avatarReady && m_enabled && !p_seat.occupied)
|
||||
SwitchRagdoll();
|
||||
}
|
||||
|
||||
internal void OnStartCalibration()
|
||||
{
|
||||
if(m_avatarReady && m_enabled)
|
||||
SwitchRagdoll();
|
||||
}
|
||||
|
||||
internal void OnWorldSpawn()
|
||||
{
|
||||
if(m_avatarReady && m_enabled)
|
||||
SwitchRagdoll();
|
||||
|
||||
OnGravityChange(Settings.Gravity);
|
||||
OnPhysicsMaterialChange(true);
|
||||
OnMovementDragChange(Settings.MovementDrag);
|
||||
}
|
||||
|
||||
internal void OnCombatDown()
|
||||
{
|
||||
if(m_avatarReady && !m_enabled && Settings.CombatReaction)
|
||||
{
|
||||
m_reachedGround = true;
|
||||
SwitchRagdoll();
|
||||
}
|
||||
}
|
||||
|
||||
internal void OnChangeFlight()
|
||||
{
|
||||
if(m_avatarReady && m_enabled && MovementSystem.Instance.flying)
|
||||
SwitchRagdoll();
|
||||
}
|
||||
|
||||
// IK updates
|
||||
void OnIKPreUpdate()
|
||||
{
|
||||
if(m_enabled)
|
||||
{
|
||||
m_vrIkWeight = m_vrIK.solver.IKPositionWeight;
|
||||
m_vrIK.solver.IKPositionWeight = 0f;
|
||||
}
|
||||
}
|
||||
void OnIKPostUpdate()
|
||||
{
|
||||
if(m_enabled)
|
||||
m_vrIK.solver.IKPositionWeight = m_vrIkWeight;
|
||||
else
|
||||
{
|
||||
foreach(var l_link in m_boneLinks)
|
||||
l_link.Item2.CopyGlobal(l_link.Item1);
|
||||
}
|
||||
}
|
||||
|
||||
// Settings
|
||||
void OnMovementDragChange(float p_value)
|
||||
{
|
||||
if(m_avatarReady)
|
||||
{
|
||||
float l_drag = (Utils.IsWorldSafe() ? p_value : 1f);
|
||||
foreach(Rigidbody l_body in m_rigidBodies)
|
||||
{
|
||||
l_body.drag = l_drag;
|
||||
if(m_enabled)
|
||||
l_body.WakeUp();
|
||||
}
|
||||
}
|
||||
}
|
||||
void OnAngularDragChange(float p_value)
|
||||
{
|
||||
if(m_avatarReady)
|
||||
{
|
||||
foreach(Rigidbody l_body in m_rigidBodies)
|
||||
{
|
||||
l_body.angularDrag = p_value;
|
||||
if(m_enabled)
|
||||
l_body.WakeUp();
|
||||
}
|
||||
}
|
||||
}
|
||||
void OnGravityChange(bool p_state)
|
||||
{
|
||||
if(m_avatarReady)
|
||||
{
|
||||
bool l_gravity = (!Utils.IsWorldSafe() || p_state);
|
||||
foreach(Rigidbody l_body in m_rigidBodies)
|
||||
l_body.useGravity = l_gravity;
|
||||
}
|
||||
}
|
||||
void OnPhysicsMaterialChange(bool p_state)
|
||||
{
|
||||
if(m_physicsMaterial != null)
|
||||
{
|
||||
bool l_slipperiness = (Settings.Slipperiness && Utils.IsWorldSafe());
|
||||
bool l_bounciness = (Settings.Bounciness && Utils.IsWorldSafe());
|
||||
m_physicsMaterial.dynamicFriction = (l_slipperiness ? 0f : c_defaultFriction);
|
||||
m_physicsMaterial.staticFriction = (l_slipperiness ? 0f : c_defaultFriction);
|
||||
m_physicsMaterial.frictionCombine = (l_slipperiness ? PhysicMaterialCombine.Minimum : PhysicMaterialCombine.Average);
|
||||
m_physicsMaterial.bounciness = (l_bounciness ? 1f : 0f);
|
||||
m_physicsMaterial.bounceCombine = (l_bounciness ? PhysicMaterialCombine.Maximum : PhysicMaterialCombine.Average);
|
||||
}
|
||||
}
|
||||
|
||||
// Arbitrary
|
||||
public void SwitchRagdoll()
|
||||
{
|
||||
if(m_avatarReady)
|
||||
{
|
||||
if(!m_enabled)
|
||||
{
|
||||
if(IsSafeToRagdoll() && m_reachedGround)
|
||||
{
|
||||
// Eject player from seat
|
||||
if(MovementSystem.Instance.lastSeat != null)
|
||||
{
|
||||
Vector3 l_pos = PlayerSetup.Instance.transform.position;
|
||||
Quaternion l_rot = PlayerSetup.Instance.transform.rotation;
|
||||
|
||||
if(MetaPort.Instance.isUsingVr)
|
||||
{
|
||||
MetaPort.Instance.isUsingVr = false;
|
||||
MovementSystem.Instance.lastSeat.ExitSeat();
|
||||
MetaPort.Instance.isUsingVr = true;
|
||||
}
|
||||
else
|
||||
MovementSystem.Instance.lastSeat.ExitSeat();
|
||||
|
||||
PlayerSetup.Instance.transform.position = l_pos;
|
||||
PlayerSetup.Instance.transform.rotation = Quaternion.Euler(0f, l_rot.eulerAngles.y, 0f);
|
||||
}
|
||||
|
||||
if(MovementSystem.Instance.flying)
|
||||
MovementSystem.Instance.ChangeFlight(false);
|
||||
|
||||
bool l_crouch = MovementSystem.Instance.crouching;
|
||||
bool l_prone = MovementSystem.Instance.prone;
|
||||
MovementSystem.Instance.SetImmobilized(true);
|
||||
MovementSystem.Instance.ChangeCrouch(l_crouch);
|
||||
MovementSystem.Instance.ChangeProne(l_prone);
|
||||
|
||||
PlayerSetup.Instance.animatorManager.SetAnimatorParameterTrigger("CancelEmote");
|
||||
m_ragdolledParameter.SetValue(true);
|
||||
if(!BodySystem.isCalibrating)
|
||||
BodySystem.TrackingPositionWeight = 0f;
|
||||
|
||||
if(!Utils.IsWorldSafe())
|
||||
{
|
||||
m_reachedGround = false; // Force player to unragdoll and reach ground first
|
||||
m_groundedTime = 0f;
|
||||
}
|
||||
|
||||
m_puppetRoot.gameObject.SetActive(true);
|
||||
|
||||
foreach(Rigidbody l_body in m_rigidBodies)
|
||||
l_body.isKinematic = false;
|
||||
|
||||
Vector3 l_velocity = Vector3.ClampMagnitude(m_velocity * (Utils.IsWorldSafe() ? Settings.VelocityMultiplier : 1f), Utils.GetWorldMovementLimit());
|
||||
if(Settings.ViewVelocity && Utils.IsWorldSafe())
|
||||
{
|
||||
float l_mag = l_velocity.magnitude;
|
||||
l_velocity = PlayerSetup.Instance.GetActiveCamera().transform.forward * l_mag;
|
||||
}
|
||||
|
||||
foreach(Rigidbody l_body in m_rigidBodies)
|
||||
{
|
||||
l_body.velocity = l_velocity;
|
||||
l_body.angularVelocity = Vector3.zero;
|
||||
}
|
||||
|
||||
foreach(Collider l_collider in m_colliders)
|
||||
l_collider.enabled = true;
|
||||
|
||||
m_ragdollLastPos = m_puppetReferences.hips.position;
|
||||
m_downTime = 0f;
|
||||
|
||||
m_enabled = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(IsSafeToUnragdoll())
|
||||
{
|
||||
MovementSystem.Instance.SetImmobilized(false);
|
||||
if(!Utils.IsWorldSafe())
|
||||
{
|
||||
Vector3 l_vec = MovementSystem.Instance.GetAppliedGravity();
|
||||
l_vec.y = Mathf.Clamp(l_vec.y, float.MinValue, 0f);
|
||||
MovementSystem.Instance.SetAppliedGravity(l_vec);
|
||||
}
|
||||
|
||||
m_ragdolledParameter.SetValue(false);
|
||||
if(!BodySystem.isCalibrating)
|
||||
BodySystem.TrackingPositionWeight = 1f;
|
||||
|
||||
m_puppetRoot.gameObject.SetActive(false);
|
||||
|
||||
foreach(Rigidbody l_body in m_rigidBodies)
|
||||
l_body.isKinematic = true;
|
||||
|
||||
PlayerSetup.Instance.transform.position = m_puppetReferences.hips.position;
|
||||
if(m_inVr)
|
||||
PlayerSetup.Instance.transform.position -= (PlayerSetup.Instance.transform.rotation * PlayerSetup.Instance._avatar.transform.localPosition);
|
||||
|
||||
foreach(Collider l_collider in m_colliders)
|
||||
l_collider.enabled = false;
|
||||
|
||||
if(m_vrIK != null)
|
||||
m_vrIK.solver.Reset();
|
||||
|
||||
m_lastPosition = PlayerSetup.Instance.transform.position;
|
||||
m_velocity = Vector3.zero;
|
||||
m_downTime = float.MinValue;
|
||||
|
||||
m_enabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsRagdolled() => (m_avatarReady && m_enabled);
|
||||
|
||||
static Transform CloneTransform(Transform p_source, Transform p_parent, string p_name)
|
||||
{
|
||||
Transform l_target = new GameObject(p_name).transform;
|
||||
l_target.parent = p_parent;
|
||||
p_source.CopyGlobal(l_target);
|
||||
return l_target;
|
||||
}
|
||||
|
||||
static bool IsSafeToRagdoll()
|
||||
{
|
||||
bool l_result = true;
|
||||
l_result &= !BodySystem.isCalibrating; // Not calibrating
|
||||
l_result &= ((CombatSystem.Instance == null) || !CombatSystem.Instance.isDown); // Non-combat world or not dead
|
||||
return l_result;
|
||||
}
|
||||
|
||||
static bool IsSafeToUnragdoll()
|
||||
{
|
||||
bool l_result = true;
|
||||
l_result &= ((CombatSystem.Instance == null) || !CombatSystem.Instance.isDown); // Non-combat world or not dead
|
||||
return l_result;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
using UnityEngine;
|
||||
|
||||
namespace ml_prm
|
||||
{
|
||||
public class RagdollToggle : MonoBehaviour
|
||||
{
|
||||
[Tooltip("Whether or not is should use the isOn property to override the current Ragdoll State of the Avatar.")]
|
||||
[SerializeField] public bool shouldOverride;
|
||||
[Tooltip("Whether Ragdoll State is active or not on the Avatar. Requires shouldOverride to be true to work.")]
|
||||
[SerializeField] public bool isOn;
|
||||
}
|
||||
}
|
|
@ -1,103 +0,0 @@
|
|||
using ABI.CCK.Components;
|
||||
using ABI_RC.Core.Player;
|
||||
using ABI_RC.Core.Savior;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ml_prm
|
||||
{
|
||||
[DisallowMultipleComponent]
|
||||
class RagdollTrigger : MonoBehaviour
|
||||
{
|
||||
const string c_ragdollPointerType = "ragdoll";
|
||||
|
||||
Collider m_collider = null;
|
||||
Collider m_lastColliderTrigger = null;
|
||||
ParticleSystem m_lastParticleSystemTrigger = null;
|
||||
bool m_triggered = false;
|
||||
|
||||
void Start()
|
||||
{
|
||||
m_collider = this.GetComponent<Collider>();
|
||||
|
||||
CVRParticlePointerManager.volumes.Add(new RagdollTriggerVolume(m_collider, this));
|
||||
CVRParticlePointerManager.UpdateParticleSystems();
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
CVRParticlePointerManager.RemoveTrigger(m_collider);
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
if(!ReferenceEquals(m_lastColliderTrigger, null))
|
||||
{
|
||||
if(m_lastColliderTrigger != null)
|
||||
{
|
||||
if(!m_collider.bounds.Intersects(m_lastColliderTrigger.bounds))
|
||||
m_lastColliderTrigger = null;
|
||||
}
|
||||
else
|
||||
m_lastColliderTrigger = null;
|
||||
}
|
||||
if(!ReferenceEquals(m_lastParticleSystemTrigger, null))
|
||||
{
|
||||
if(m_lastParticleSystemTrigger != null)
|
||||
{
|
||||
if(m_lastParticleSystemTrigger.particleCount == 0)
|
||||
m_lastParticleSystemTrigger = null;
|
||||
}
|
||||
else
|
||||
m_lastParticleSystemTrigger = null;
|
||||
}
|
||||
}
|
||||
|
||||
void OnTriggerEnter(Collider p_other)
|
||||
{
|
||||
CVRPointer l_pointer = p_other.GetComponent<CVRPointer>();
|
||||
if((l_pointer != null) && (l_pointer.type == c_ragdollPointerType) && !IsIgnored(l_pointer.transform) && (m_lastColliderTrigger != p_other))
|
||||
{
|
||||
m_lastColliderTrigger = p_other;
|
||||
m_triggered = true;
|
||||
}
|
||||
}
|
||||
|
||||
void OnTriggerExit(Collider p_other)
|
||||
{
|
||||
if(m_lastColliderTrigger == p_other)
|
||||
m_lastColliderTrigger = null;
|
||||
}
|
||||
|
||||
public void OnPointerParticleEnter(CVRPointer p_pointer)
|
||||
{
|
||||
if(!this.gameObject.activeInHierarchy)
|
||||
return;
|
||||
|
||||
if((p_pointer.type == c_ragdollPointerType) && !IsIgnored(p_pointer.transform) && (m_lastParticleSystemTrigger != p_pointer.particleSystem))
|
||||
{
|
||||
m_lastParticleSystemTrigger = p_pointer.particleSystem;
|
||||
m_triggered = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnPointerParticleExit(CVRPointer p_pointer)
|
||||
{
|
||||
// This seems to be very unreliable, and it's causing weird behavior
|
||||
// if (!gameObject.activeInHierarchy) return;
|
||||
// if(m_lastParticleSystemTrigger == p_pointer.particleSystem)
|
||||
// m_lastParticleSystemTrigger = null;
|
||||
}
|
||||
|
||||
public bool GetStateWithReset()
|
||||
{
|
||||
bool l_state = m_triggered;
|
||||
m_triggered = false;
|
||||
return l_state;
|
||||
}
|
||||
|
||||
static bool IsIgnored(Transform p_transform)
|
||||
{
|
||||
return (Settings.IgnoreLocal && (p_transform.root == PlayerSetup.Instance.transform));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
using ABI_RC.Core.Savior;
|
||||
using ABI.CCK.Components;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ml_prm
|
||||
{
|
||||
class RagdollTriggerVolume : CVRTriggerVolume
|
||||
{
|
||||
readonly RagdollTrigger m_trigger = null;
|
||||
|
||||
public Collider collider { get; set; }
|
||||
|
||||
internal RagdollTriggerVolume(Collider p_collider, RagdollTrigger p_trigger)
|
||||
{
|
||||
collider = p_collider;
|
||||
m_trigger = p_trigger;
|
||||
}
|
||||
|
||||
public void TriggerEnter(CVRPointer pointer) => m_trigger.OnPointerParticleEnter(pointer);
|
||||
public void TriggerExit(CVRPointer pointer) => m_trigger.OnPointerParticleExit(pointer);
|
||||
}
|
||||
}
|
|
@ -1,223 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ml_prm
|
||||
{
|
||||
static class Settings
|
||||
{
|
||||
public enum ModSetting
|
||||
{
|
||||
Hotkey = 0,
|
||||
HotkeyKey,
|
||||
VelocityMultiplier,
|
||||
MovementDrag,
|
||||
AngularDrag,
|
||||
Gravity,
|
||||
PointersReaction,
|
||||
IgnoreLocal,
|
||||
CombatReaction,
|
||||
AutoRecover,
|
||||
RecoverDelay,
|
||||
Slipperiness,
|
||||
Bounciness,
|
||||
ViewVelocity,
|
||||
JumpRecover
|
||||
}
|
||||
|
||||
public static bool Hotkey { get; private set; } = true;
|
||||
public static KeyCode HotkeyKey { get; private set; } = KeyCode.R;
|
||||
public static float VelocityMultiplier { get; private set; } = 2f;
|
||||
public static float MovementDrag { get; private set; } = 2f;
|
||||
public static float AngularDrag { get; private set; } = 2f;
|
||||
public static bool Gravity { get; private set; } = true;
|
||||
public static bool PointersReaction { get; private set; } = true;
|
||||
public static bool IgnoreLocal { get; private set; } = true;
|
||||
public static bool CombatReaction { get; private set; } = true;
|
||||
public static bool AutoRecover { get; private set; } = false;
|
||||
public static float RecoverDelay { get; private set; } = 3f;
|
||||
public static bool Slipperiness { get; private set; } = false;
|
||||
public static bool Bounciness { get; private set; } = false;
|
||||
public static bool ViewVelocity { get; private set; } = false;
|
||||
public static bool JumpRecover { get; private set; } = false;
|
||||
|
||||
static public event Action<bool> HotkeyChange;
|
||||
static public event Action<KeyCode> HotkeyKeyChange;
|
||||
static public event Action<float> VelocityMultiplierChange;
|
||||
static public event Action<float> MovementDragChange;
|
||||
static public event Action<float> AngularDragChange;
|
||||
static public event Action<bool> GravityChange;
|
||||
static public event Action<bool> PointersReactionChange;
|
||||
static public event Action<bool> IgnoreLocalChange;
|
||||
static public event Action<bool> CombatReactionChange;
|
||||
static public event Action<bool> AutoRecoverChange;
|
||||
static public event Action<float> RecoverDelayChange;
|
||||
static public event Action<bool> SlipperinessChange;
|
||||
static public event Action<bool> BouncinessChange;
|
||||
static public event Action<bool> ViewVelocityChange;
|
||||
static public event Action<bool> JumpRecoverChange;
|
||||
|
||||
static MelonLoader.MelonPreferences_Category ms_category = null;
|
||||
static List<MelonLoader.MelonPreferences_Entry> ms_entries = null;
|
||||
|
||||
internal static void Init()
|
||||
{
|
||||
ms_category = MelonLoader.MelonPreferences.CreateCategory("PRM", "Player Ragdoll Mod");
|
||||
|
||||
ms_entries = new List<MelonLoader.MelonPreferences_Entry>()
|
||||
{
|
||||
ms_category.CreateEntry(ModSetting.Hotkey.ToString(), Hotkey, null, null, true),
|
||||
ms_category.CreateEntry(ModSetting.HotkeyKey.ToString(), HotkeyKey, "Hotkey"),
|
||||
ms_category.CreateEntry(ModSetting.VelocityMultiplier.ToString(), VelocityMultiplier, null, null, true),
|
||||
ms_category.CreateEntry(ModSetting.MovementDrag.ToString(), MovementDrag, null, null, true),
|
||||
ms_category.CreateEntry(ModSetting.AngularDrag.ToString(), AngularDrag, null, null, true),
|
||||
ms_category.CreateEntry(ModSetting.Gravity.ToString(), Gravity, null, null, true),
|
||||
ms_category.CreateEntry(ModSetting.PointersReaction.ToString(), PointersReaction, null, null, true),
|
||||
ms_category.CreateEntry(ModSetting.IgnoreLocal.ToString(), IgnoreLocal, null, null, true),
|
||||
ms_category.CreateEntry(ModSetting.CombatReaction.ToString(), CombatReaction, null, null, true),
|
||||
ms_category.CreateEntry(ModSetting.AutoRecover.ToString(), AutoRecover, null, null, true),
|
||||
ms_category.CreateEntry(ModSetting.RecoverDelay.ToString(), RecoverDelay, null, null, true),
|
||||
ms_category.CreateEntry(ModSetting.Slipperiness.ToString(), Slipperiness, null, null, true),
|
||||
ms_category.CreateEntry(ModSetting.Bounciness.ToString(), Bounciness, null, null, true),
|
||||
ms_category.CreateEntry(ModSetting.ViewVelocity.ToString(), ViewVelocity, null, null, true),
|
||||
ms_category.CreateEntry(ModSetting.JumpRecover.ToString(), JumpRecover, null, null, true)
|
||||
};
|
||||
|
||||
ms_entries[(int)ModSetting.HotkeyKey].OnEntryValueChangedUntyped.Subscribe(OnMelonSettingSave_HotkeyKey);
|
||||
|
||||
Hotkey = (bool)ms_entries[(int)ModSetting.Hotkey].BoxedValue;
|
||||
HotkeyKey = (KeyCode)ms_entries[(int)ModSetting.HotkeyKey].BoxedValue;
|
||||
VelocityMultiplier = Mathf.Clamp((float)ms_entries[(int)ModSetting.VelocityMultiplier].BoxedValue, 1f, 50f);
|
||||
MovementDrag = Mathf.Clamp((float)ms_entries[(int)ModSetting.MovementDrag].BoxedValue, 0f, 50f);
|
||||
AngularDrag = Mathf.Clamp((float)ms_entries[(int)ModSetting.AngularDrag].BoxedValue, 0f, 50f);
|
||||
Gravity = (bool)ms_entries[(int)ModSetting.Gravity].BoxedValue;
|
||||
PointersReaction = (bool)ms_entries[(int)ModSetting.PointersReaction].BoxedValue;
|
||||
IgnoreLocal = (bool)ms_entries[(int)ModSetting.IgnoreLocal].BoxedValue;
|
||||
CombatReaction = (bool)ms_entries[(int)ModSetting.CombatReaction].BoxedValue;
|
||||
AutoRecover = (bool)ms_entries[(int)ModSetting.AutoRecover].BoxedValue;
|
||||
RecoverDelay = Mathf.Clamp((float)ms_entries[(int)ModSetting.RecoverDelay].BoxedValue, 1f, 10f);
|
||||
Slipperiness = (bool)ms_entries[(int)ModSetting.Slipperiness].BoxedValue;
|
||||
Bounciness = (bool)ms_entries[(int)ModSetting.Bounciness].BoxedValue;
|
||||
ViewVelocity = (bool)ms_entries[(int)ModSetting.ViewVelocity].BoxedValue;
|
||||
JumpRecover = (bool)ms_entries[(int)ModSetting.JumpRecover].BoxedValue;
|
||||
}
|
||||
|
||||
static void OnMelonSettingSave_HotkeyKey(object p_oldValue, object p_newValue)
|
||||
{
|
||||
if(p_newValue is KeyCode)
|
||||
{
|
||||
HotkeyKey = (KeyCode)p_newValue;
|
||||
HotkeyKeyChange?.Invoke(HotkeyKey);
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetSetting(ModSetting p_settings, object p_value)
|
||||
{
|
||||
switch(p_settings)
|
||||
{
|
||||
// Booleans
|
||||
case ModSetting.Hotkey:
|
||||
{
|
||||
Hotkey = (bool)p_value;
|
||||
HotkeyChange?.Invoke((bool)p_value);
|
||||
}
|
||||
break;
|
||||
|
||||
case ModSetting.Gravity:
|
||||
{
|
||||
Gravity = (bool)p_value;
|
||||
GravityChange?.Invoke((bool)p_value);
|
||||
}
|
||||
break;
|
||||
|
||||
case ModSetting.PointersReaction:
|
||||
{
|
||||
PointersReaction = (bool)p_value;
|
||||
PointersReactionChange?.Invoke((bool)p_value);
|
||||
}
|
||||
break;
|
||||
|
||||
case ModSetting.IgnoreLocal:
|
||||
{
|
||||
IgnoreLocal = (bool)p_value;
|
||||
IgnoreLocalChange?.Invoke((bool)p_value);
|
||||
}
|
||||
break;
|
||||
|
||||
case ModSetting.CombatReaction:
|
||||
{
|
||||
CombatReaction = (bool)p_value;
|
||||
CombatReactionChange?.Invoke((bool)p_value);
|
||||
}
|
||||
break;
|
||||
|
||||
case ModSetting.AutoRecover:
|
||||
{
|
||||
AutoRecover = (bool)p_value;
|
||||
AutoRecoverChange?.Invoke((bool)p_value);
|
||||
}
|
||||
break;
|
||||
|
||||
case ModSetting.Slipperiness:
|
||||
{
|
||||
Slipperiness = (bool)p_value;
|
||||
SlipperinessChange?.Invoke((bool)p_value);
|
||||
}
|
||||
break;
|
||||
|
||||
case ModSetting.Bounciness:
|
||||
{
|
||||
Bounciness = (bool)p_value;
|
||||
BouncinessChange?.Invoke((bool)p_value);
|
||||
}
|
||||
break;
|
||||
|
||||
case ModSetting.ViewVelocity:
|
||||
{
|
||||
ViewVelocity = (bool)p_value;
|
||||
ViewVelocityChange?.Invoke((bool)p_value);
|
||||
}
|
||||
break;
|
||||
|
||||
case ModSetting.JumpRecover:
|
||||
{
|
||||
JumpRecover = (bool)p_value;
|
||||
JumpRecoverChange?.Invoke((bool)p_value);
|
||||
}
|
||||
break;
|
||||
|
||||
// Floats
|
||||
case ModSetting.VelocityMultiplier:
|
||||
{
|
||||
VelocityMultiplier = (float)p_value;
|
||||
VelocityMultiplierChange?.Invoke((float)p_value);
|
||||
}
|
||||
break;
|
||||
|
||||
case ModSetting.MovementDrag:
|
||||
{
|
||||
MovementDrag = (float)p_value;
|
||||
MovementDragChange?.Invoke((float)p_value);
|
||||
}
|
||||
break;
|
||||
|
||||
case ModSetting.AngularDrag:
|
||||
{
|
||||
AngularDrag = (float)p_value;
|
||||
AngularDragChange?.Invoke((float)p_value);
|
||||
}
|
||||
break;
|
||||
|
||||
case ModSetting.RecoverDelay:
|
||||
{
|
||||
RecoverDelay = (float)p_value;
|
||||
RecoverDelayChange?.Invoke((float)p_value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if(ms_entries != null)
|
||||
ms_entries[(int)p_settings].BoxedValue = p_value;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
using ABI.CCK.Components;
|
||||
using ABI_RC.Core.Savior;
|
||||
using ABI_RC.Systems.MovementSystem;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ml_prm
|
||||
{
|
||||
static class Utils
|
||||
{
|
||||
static readonly FieldInfo ms_groundedRaw = typeof(MovementSystem).GetField("_isGroundedRaw", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
static readonly FieldInfo ms_appliedGravity = typeof(MovementSystem).GetField("_appliedGravity", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
|
||||
public static bool IsInVR() => ((CheckVR.Instance != null) && CheckVR.Instance.hasVrDeviceLoaded);
|
||||
public static bool IsWorldSafe() => ((CVRWorld.Instance != null) && CVRWorld.Instance.allowFlying);
|
||||
public static float GetWorldMovementLimit()
|
||||
{
|
||||
float l_result = 1f;
|
||||
if(CVRWorld.Instance != null)
|
||||
{
|
||||
l_result = CVRWorld.Instance.baseMovementSpeed;
|
||||
l_result *= CVRWorld.Instance.sprintMultiplier;
|
||||
l_result *= CVRWorld.Instance.inAirMovementMultiplier;
|
||||
l_result *= CVRWorld.Instance.flyMultiplier;
|
||||
}
|
||||
return l_result;
|
||||
}
|
||||
|
||||
public static bool IsGrounded(this MovementSystem p_instance) => (bool)ms_groundedRaw.GetValue(p_instance);
|
||||
public static Vector3 GetAppliedGravity(this MovementSystem p_instance) => (Vector3)ms_appliedGravity.GetValue(p_instance);
|
||||
public static void SetAppliedGravity(this MovementSystem p_instance, Vector3 p_vec) => ms_appliedGravity.SetValue(p_instance, p_vec);
|
||||
|
||||
public static void CopyGlobal(this Transform p_source, Transform p_target)
|
||||
{
|
||||
p_target.position = p_source.position;
|
||||
p_target.rotation = p_source.rotation;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,78 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<Platforms>x64</Platforms>
|
||||
<PackageId>PlayerRagdollMod</PackageId>
|
||||
<Version>1.0.11</Version>
|
||||
<Authors>SDraw</Authors>
|
||||
<Company>None</Company>
|
||||
<Product>PlayerRagdollMod</Product>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="PlayerRagdollMod.json" />
|
||||
<None Remove="resources\person.png" />
|
||||
<None Remove="vendor\RootMotion\info.txt" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="resources\person.png" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="0Harmony">
|
||||
<HintPath>D:\games\Steam\steamapps\common\ChilloutVR\MelonLoader\net35\0Harmony.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
<Reference Include="Assembly-CSharp">
|
||||
<HintPath>D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Assembly-CSharp.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
<Reference Include="Assembly-CSharp-firstpass">
|
||||
<HintPath>D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\Assembly-CSharp-firstpass.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
<Reference Include="BTKUILib">
|
||||
<HintPath>D:\games\Steam\steamapps\common\ChilloutVR\Mods\BTKUILib.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
<Reference Include="MelonLoader">
|
||||
<HintPath>D:\games\Steam\steamapps\common\ChilloutVR\MelonLoader\net35\MelonLoader.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine">
|
||||
<HintPath>D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.AnimationModule">
|
||||
<HintPath>D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.AnimationModule.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ClothModule">
|
||||
<HintPath>D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.ClothModule.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.CoreModule">
|
||||
<HintPath>D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.CoreModule.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.InputLegacyModule">
|
||||
<HintPath>D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.InputLegacyModule.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.PhysicsModule">
|
||||
<HintPath>D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.PhysicsModule.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
<Reference Include="UnityEngine.ParticleSystemModule">
|
||||
<HintPath>D:\games\Steam\steamapps\common\ChilloutVR\ChilloutVR_Data\Managed\UnityEngine.ParticleSystemModule.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
||||
<Exec Command="copy /y "$(TargetPath)" "D:\Games\Steam\steamapps\common\ChilloutVR\Mods\"" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
Binary file not shown.
Before Width: | Height: | Size: 4.9 KiB |
1
ml_prm/vendor/RootMotion/ReadMe.md
vendored
1
ml_prm/vendor/RootMotion/ReadMe.md
vendored
|
@ -1 +0,0 @@
|
|||
Put `PuppetMaster` and `RagdollMaster` folders from [PuppetMaster asset](https://assetstore.unity.com/packages/tools/physics/puppetmaster-48977) here.
|
1
ml_prm/vendor/RootMotion/info.txt
vendored
1
ml_prm/vendor/RootMotion/info.txt
vendored
|
@ -1 +0,0 @@
|
|||
https://assetstore.unity.com/packages/tools/physics/puppetmaster-48977
|
Loading…
Add table
Add a link
Reference in a new issue