From 2540a4fca2111fac3e302dc1e6d5eb5776d9e74c Mon Sep 17 00:00:00 2001 From: SDraw Date: Sun, 16 Apr 2023 22:17:10 +0300 Subject: [PATCH] Slipperiness and bounciness options --- README.md | 2 +- ml_prm/Properties/AssemblyInfo.cs | 6 ++--- ml_prm/README.md | 4 +++ ml_prm/RagdollController.cs | 30 +++++++++++++++++++++- ml_prm/Settings.cs | 42 +++++++++++++++++++++++++++++-- 5 files changed, 77 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 1a5c4f8..894a20f 100644 --- a/README.md +++ b/README.md @@ -11,5 +11,5 @@ Merged set of MelonLoader mods for ChilloutVR. | Four Point Tracking | ml_fpt | 1.0.9 | Retired | Deprecated | In-game feature since 2022r170 update | Leap Motion Extension | ml_lme | 1.3.4 | Yes, update review | Working | | Pickup Arm Movement | ml_pam | 1.0.3 | Yes, update review| Working | -| Player Ragdoll Mod | ml_prm | 1.0.0 | Yes | Working | +| Player Ragdoll Mod | ml_prm | 1.0.1 | Yes, update review | Working | | Server Connection Info | ml_sci | 1.0.2 | Retired | Retired | Superseded by `Extended Game Notifications` diff --git a/ml_prm/Properties/AssemblyInfo.cs b/ml_prm/Properties/AssemblyInfo.cs index 9e478a5..dca7ef0 100644 --- a/ml_prm/Properties/AssemblyInfo.cs +++ b/ml_prm/Properties/AssemblyInfo.cs @@ -1,10 +1,10 @@ using System.Reflection; [assembly: AssemblyTitle("PlayerRagdollMod")] -[assembly: AssemblyVersion("1.0.0")] -[assembly: AssemblyFileVersion("1.0.0")] +[assembly: AssemblyVersion("1.0.1")] +[assembly: AssemblyFileVersion("1.0.1")] -[assembly: MelonLoader.MelonInfo(typeof(ml_prm.PlayerRagdollMod), "PlayerRagdollMod", "1.0.0", "SDraw", "https://github.com/SDraw/ml_mods_cvr")] +[assembly: MelonLoader.MelonInfo(typeof(ml_prm.PlayerRagdollMod), "PlayerRagdollMod", "1.0.1", "SDraw", "https://github.com/SDraw/ml_mods_cvr")] [assembly: MelonLoader.MelonGame(null, "ChilloutVR")] [assembly: MelonLoader.MelonPriority(2)] [assembly: MelonLoader.MelonOptionalDependencies("BTKUILib")] diff --git a/ml_prm/README.md b/ml_prm/README.md index 4596181..ccd275c 100644 --- a/ml_prm/README.md +++ b/ml_prm/README.md @@ -19,6 +19,10 @@ Optional mod's settings with [BTKUILib](https://github.com/BTK-Development/BTKUI * **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. * **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. diff --git a/ml_prm/RagdollController.cs b/ml_prm/RagdollController.cs index 14251ed..c626c12 100644 --- a/ml_prm/RagdollController.cs +++ b/ml_prm/RagdollController.cs @@ -5,7 +5,6 @@ using ABI_RC.Systems.IK.SubSystems; using ABI_RC.Systems.MovementSystem; using RootMotion.Dynamics; using RootMotion.FinalIK; -using System.Collections; using System.Collections.Generic; using UnityEngine; @@ -35,6 +34,7 @@ namespace ml_prm RagdollToggle m_avatarRagdollToggle = null; RagdollTrigger m_customTrigger = null; AvatarBoolParameter m_ragdolledParameter = null; + readonly PhysicMaterial m_physicsMaterial = null; bool m_reachedGround = true; float m_downTime = float.MinValue; @@ -47,6 +47,13 @@ namespace ml_prm m_rigidBodies = new List(); m_colliders = new List(); m_boneLinks = new List>(); + + m_physicsMaterial = new PhysicMaterial("Ragdoll"); + m_physicsMaterial.dynamicFriction = 0.5f; + m_physicsMaterial.staticFriction = 0.5f; + m_physicsMaterial.frictionCombine = PhysicMaterialCombine.Average; + m_physicsMaterial.bounciness = 0f; + m_physicsMaterial.bounceCombine = PhysicMaterialCombine.Average; } ~RagdollController() { @@ -68,6 +75,8 @@ namespace ml_prm Settings.MovementDragChange += this.OnMovementDragChange; Settings.AngularDragChange += this.OnAngularDragChange; Settings.GravityChange += this.OnGravityChange; + Settings.SlipperinessChange += this.OnPhysicsMaterialChange; + Settings.BouncinessChange += this.OnPhysicsMaterialChange; } void OnDestroy() @@ -82,6 +91,8 @@ namespace ml_prm Settings.MovementDragChange -= this.OnMovementDragChange; Settings.AngularDragChange -= this.OnAngularDragChange; Settings.GravityChange -= this.OnGravityChange; + Settings.SlipperinessChange -= this.OnPhysicsMaterialChange; + Settings.BouncinessChange -= this.OnPhysicsMaterialChange; } void Update() @@ -230,6 +241,8 @@ namespace ml_prm 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); } @@ -274,6 +287,8 @@ namespace ml_prm foreach(Rigidbody l_body in m_rigidBodies) l_body.useGravity = (!Utils.IsWorldSafe() || Settings.Gravity); } + + OnPhysicsMaterialChange(true); } internal void OnCombatDown() @@ -330,6 +345,19 @@ namespace ml_prm l_body.useGravity = (!Utils.IsWorldSafe() || p_state); } } + 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 : 0.5f); + m_physicsMaterial.staticFriction = (l_slipperiness ? 0f : 0.5f); + 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() diff --git a/ml_prm/Settings.cs b/ml_prm/Settings.cs index 591c3f6..8dc8577 100644 --- a/ml_prm/Settings.cs +++ b/ml_prm/Settings.cs @@ -19,7 +19,9 @@ namespace ml_prm IgnoreLocal, CombatReaction, AutoRecover, - RecoverDelay + RecoverDelay, + Slipperiness, + Bounciness } enum UiElementIndex @@ -31,6 +33,8 @@ namespace ml_prm IgnoreLocal, CombatReaction, AutoRecover, + Slipperiness, + Bounciness, VelocityMultiplier, MovementDrag, AngularDrag, @@ -48,6 +52,8 @@ namespace ml_prm 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; static public event Action SwitchChange; static public event Action HotkeyChange; @@ -61,6 +67,8 @@ namespace ml_prm static public event Action CombatReactionChange; static public event Action AutoRecoverChange; static public event Action RecoverDelayChange; + static public event Action SlipperinessChange; + static public event Action BouncinessChange; static MelonLoader.MelonPreferences_Category ms_category = null; static List ms_entries = null; @@ -82,7 +90,9 @@ namespace ml_prm ms_category.CreateEntry(ModSetting.IgnoreLocal.ToString(), IgnoreLocal), ms_category.CreateEntry(ModSetting.CombatReaction.ToString(), CombatReaction), ms_category.CreateEntry(ModSetting.AutoRecover.ToString(), AutoRecover), - ms_category.CreateEntry(ModSetting.RecoverDelay.ToString(), RecoverDelay) + ms_category.CreateEntry(ModSetting.RecoverDelay.ToString(), RecoverDelay), + ms_category.CreateEntry(ModSetting.Slipperiness.ToString(), Slipperiness), + ms_category.CreateEntry(ModSetting.Bounciness.ToString(), Bounciness) }; Hotkey = (bool)ms_entries[(int)ModSetting.Hotkey].BoxedValue; @@ -96,6 +106,8 @@ namespace ml_prm 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; if(MelonLoader.MelonMod.RegisteredMelons.FirstOrDefault(m => m.Info.Name == "BTKUILib") != null) { @@ -171,6 +183,22 @@ namespace ml_prm AutoRecoverChange?.Invoke(state); }; + ms_uiElements.Add(l_categoryMod.AddToggle("Slipperiness", "Enables/disables friction of ragdoll", Slipperiness)); + (ms_uiElements[(int)UiElementIndex.Slipperiness] as BTKUILib.UIObjects.Components.ToggleButton).OnValueUpdated += (state) => + { + Slipperiness = state; + ms_entries[(int)ModSetting.Slipperiness].BoxedValue = state; + SlipperinessChange?.Invoke(state); + }; + + ms_uiElements.Add(l_categoryMod.AddToggle("Bounciness", "Enables/disables bounciness of ragdoll", Bounciness)); + (ms_uiElements[(int)UiElementIndex.Bounciness] as BTKUILib.UIObjects.Components.ToggleButton).OnValueUpdated += (state) => + { + Bounciness = state; + ms_entries[(int)ModSetting.Bounciness].BoxedValue = state; + BouncinessChange?.Invoke(state); + }; + ms_uiElements.Add(l_page.AddSlider("Velocity multiplier", "Velocity multiplier upon entering ragdoll state", VelocityMultiplier, 1f, 50f)); (ms_uiElements[(int)UiElementIndex.VelocityMultiplier] as BTKUILib.UIObjects.Components.SliderFloat).OnValueUpdated += (value) => { @@ -240,6 +268,16 @@ namespace ml_prm (ms_uiElements[(int)UiElementIndex.AutoRecover] as BTKUILib.UIObjects.Components.ToggleButton).ToggleValue = false; AutoRecoverChange?.Invoke(false); + Slipperiness = false; + ms_entries[(int)ModSetting.Slipperiness].BoxedValue = false; + (ms_uiElements[(int)UiElementIndex.Slipperiness] as BTKUILib.UIObjects.Components.ToggleButton).ToggleValue = false; + SlipperinessChange?.Invoke(false); + + Bounciness = false; + ms_entries[(int)ModSetting.Bounciness].BoxedValue = false; + (ms_uiElements[(int)UiElementIndex.Bounciness] as BTKUILib.UIObjects.Components.ToggleButton).ToggleValue = false; + BouncinessChange?.Invoke(false); + VelocityMultiplier = 2f; ms_entries[(int)ModSetting.VelocityMultiplier].BoxedValue = 2f; (ms_uiElements[(int)UiElementIndex.VelocityMultiplier] as BTKUILib.UIObjects.Components.SliderFloat).SetSliderValue(2f);