diff --git a/README.md b/README.md
index 9e0e1b0..ab4e439 100644
--- a/README.md
+++ b/README.md
@@ -3,10 +3,11 @@ Merged set of MelonLoader mods for ChilloutVR.
**Table for game build 2023r173:**
| Full name | Short name | Latest version | Available in [CVRMA](https://github.com/knah/CVRMelonAssistant) |
|:---------:|:----------:|:--------------:| :----------------------------------------------------------------|
-| [Avatar Motion Tweaker](/ml_amt/README.md) | ml_amt | 1.3.4 [:arrow_down:](../../releases/latest/download/ml_amt.dll)| ✔ Yes
:hourglass_flowing_sand: Update review |
-| [Leap Motion Extension](/ml_lme/README.md)| ml_lme | 1.4.4 [:arrow_down:](../../releases/latest/download/ml_lme.dll)| ✔ Yes
:hourglass_flowing_sand: Update review |
+| [Avatar Motion Tweaker](/ml_amt/README.md) | ml_amt | 1.3.4 [:arrow_down:](../../releases/latest/download/ml_amt.dll)| ✔ Yes |
+| [Leap Motion Extension](/ml_lme/README.md)| ml_lme | 1.4.4 [:arrow_down:](../../releases/latest/download/ml_lme.dll)| ✔ Yes |
| [Pickup Arm Movement](/ml_pam/README.md)| ml_pam | 1.0.8 [:arrow_down:](../../releases/latest/download/ml_pam.dll)| ✔ Yes |
| [Player Movement Copycat](/ml_pmc/README.md)| ml_pmc | 1.0.3 [:arrow_down:](../../releases/latest/download/ml_pmc.dll)| ✔ Yes |
+| [Player Ragdoll Mod](/ml_prm/README.md) | ml_prm | 1.1.0 | ✔ Yes
:hourglass_flowing_sand: Update review |
| [Vive Extended Input](/ml_vei/README.md) | ml_vei | 1.0.0 [:arrow_down:](../../releases/latest/download/ml_vei.dll)| ✔ Yes |
**Archived mods:**
@@ -18,5 +19,4 @@ Merged set of MelonLoader mods for ChilloutVR.
| Extended Game Notifications | ml_egn | In-game feature sine 2023r172 update |
| Four Point Tracking | ml_fpt | In-game feature since 2022r170 update |
| Game Main Fixes | ml_gmf | In-game feature sine 2023r172 update |
-| Player Ragdoll Mod | ml_prm | Unable to fix offset problems |
| Server Connection Info | ml_sci | Superseded by `Extended Game Notifications`
diff --git a/ml_mods_cvr.sln b/ml_mods_cvr.sln
index 1100165..8a8dfbb 100644
--- a/ml_mods_cvr.sln
+++ b/ml_mods_cvr.sln
@@ -1,56 +1,54 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 16
-VisualStudioVersion = 16.0.33214.272
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ml_amt", "ml_amt\ml_amt.csproj", "{714806A3-E6FC-46F6-9D1D-89C77FEBAF06}"
- ProjectSection(ProjectDependencies) = postProject
- {D27B6D36-884F-4A49-9A25-B9C121E7B65F} = {D27B6D36-884F-4A49-9A25-B9C121E7B65F}
- {118675AA-9AC7-4B0C-BFB1-FA1691619502} = {118675AA-9AC7-4B0C-BFB1-FA1691619502}
- EndProjectSection
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ml_dht", "ml_dht\ml_dht.csproj", "{D805BA67-067E-4B79-87FC-6B08973F13EE}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ml_lme", "ml_lme\ml_lme.csproj", "{77EA76B1-3709-4FC5-BDBD-8F77160E6DA3}"
- ProjectSection(ProjectDependencies) = postProject
- {118675AA-9AC7-4B0C-BFB1-FA1691619502} = {118675AA-9AC7-4B0C-BFB1-FA1691619502}
- EndProjectSection
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ml_pam", "ml_pam\ml_pam.csproj", "{5B614459-234A-443D-B06D-34FF81ADA67E}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ml_prm", "ml_prm\ml_prm.csproj", "{D27B6D36-884F-4A49-9A25-B9C121E7B65F}"
-EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ml_pmc", "ml_pmc\ml_pmc.csproj", "{118675AA-9AC7-4B0C-BFB1-FA1691619502}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|x64 = Debug|x64
- Release|x64 = Release|x64
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {714806A3-E6FC-46F6-9D1D-89C77FEBAF06}.Debug|x64.ActiveCfg = Debug|x64
- {714806A3-E6FC-46F6-9D1D-89C77FEBAF06}.Release|x64.ActiveCfg = Release|x64
- {714806A3-E6FC-46F6-9D1D-89C77FEBAF06}.Release|x64.Build.0 = Release|x64
- {D805BA67-067E-4B79-87FC-6B08973F13EE}.Debug|x64.ActiveCfg = Debug|x64
- {D805BA67-067E-4B79-87FC-6B08973F13EE}.Release|x64.ActiveCfg = Release|x64
- {D805BA67-067E-4B79-87FC-6B08973F13EE}.Release|x64.Build.0 = Release|x64
- {77EA76B1-3709-4FC5-BDBD-8F77160E6DA3}.Debug|x64.ActiveCfg = Debug|x64
- {77EA76B1-3709-4FC5-BDBD-8F77160E6DA3}.Release|x64.ActiveCfg = Release|x64
- {77EA76B1-3709-4FC5-BDBD-8F77160E6DA3}.Release|x64.Build.0 = Release|x64
- {5B614459-234A-443D-B06D-34FF81ADA67E}.Debug|x64.ActiveCfg = Debug|x64
- {5B614459-234A-443D-B06D-34FF81ADA67E}.Release|x64.ActiveCfg = Release|x64
- {5B614459-234A-443D-B06D-34FF81ADA67E}.Release|x64.Build.0 = Release|x64
- {D27B6D36-884F-4A49-9A25-B9C121E7B65F}.Debug|x64.ActiveCfg = Debug|x64
- {D27B6D36-884F-4A49-9A25-B9C121E7B65F}.Release|x64.ActiveCfg = Release|x64
- {D27B6D36-884F-4A49-9A25-B9C121E7B65F}.Release|x64.Build.0 = Release|x64
- {118675AA-9AC7-4B0C-BFB1-FA1691619502}.Debug|x64.ActiveCfg = Debug|x64
- {118675AA-9AC7-4B0C-BFB1-FA1691619502}.Release|x64.ActiveCfg = Release|x64
- {118675AA-9AC7-4B0C-BFB1-FA1691619502}.Release|x64.Build.0 = Release|x64
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
- GlobalSection(ExtensibilityGlobals) = postSolution
- SolutionGuid = {C7C6398E-220C-40C3-AE95-5690C9B2B3C3}
- EndGlobalSection
-EndGlobal
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.33214.272
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ml_amt", "ml_amt\ml_amt.csproj", "{714806A3-E6FC-46F6-9D1D-89C77FEBAF06}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ml_lme", "ml_lme\ml_lme.csproj", "{77EA76B1-3709-4FC5-BDBD-8F77160E6DA3}"
+ ProjectSection(ProjectDependencies) = postProject
+ {118675AA-9AC7-4B0C-BFB1-FA1691619502} = {118675AA-9AC7-4B0C-BFB1-FA1691619502}
+ EndProjectSection
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ml_pam", "ml_pam\ml_pam.csproj", "{5B614459-234A-443D-B06D-34FF81ADA67E}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ml_pmc", "ml_pmc\ml_pmc.csproj", "{118675AA-9AC7-4B0C-BFB1-FA1691619502}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ml_vei", "ml_vei\ml_vei.csproj", "{608CDBD6-8E29-43B7-BCBF-7E3967430A24}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ml_prm", "ml_prm\ml_prm.csproj", "{C4C3F080-379F-49DB-ADC6-6328BE884AE3}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x64 = Debug|x64
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {714806A3-E6FC-46F6-9D1D-89C77FEBAF06}.Debug|x64.ActiveCfg = Debug|x64
+ {714806A3-E6FC-46F6-9D1D-89C77FEBAF06}.Release|x64.ActiveCfg = Release|x64
+ {714806A3-E6FC-46F6-9D1D-89C77FEBAF06}.Release|x64.Build.0 = Release|x64
+ {77EA76B1-3709-4FC5-BDBD-8F77160E6DA3}.Debug|x64.ActiveCfg = Debug|x64
+ {77EA76B1-3709-4FC5-BDBD-8F77160E6DA3}.Release|x64.ActiveCfg = Release|x64
+ {77EA76B1-3709-4FC5-BDBD-8F77160E6DA3}.Release|x64.Build.0 = Release|x64
+ {5B614459-234A-443D-B06D-34FF81ADA67E}.Debug|x64.ActiveCfg = Debug|x64
+ {5B614459-234A-443D-B06D-34FF81ADA67E}.Release|x64.ActiveCfg = Release|x64
+ {5B614459-234A-443D-B06D-34FF81ADA67E}.Release|x64.Build.0 = Release|x64
+ {118675AA-9AC7-4B0C-BFB1-FA1691619502}.Debug|x64.ActiveCfg = Debug|x64
+ {118675AA-9AC7-4B0C-BFB1-FA1691619502}.Release|x64.ActiveCfg = Release|x64
+ {118675AA-9AC7-4B0C-BFB1-FA1691619502}.Release|x64.Build.0 = Release|x64
+ {608CDBD6-8E29-43B7-BCBF-7E3967430A24}.Debug|x64.ActiveCfg = Debug|x64
+ {608CDBD6-8E29-43B7-BCBF-7E3967430A24}.Debug|x64.Build.0 = Debug|x64
+ {608CDBD6-8E29-43B7-BCBF-7E3967430A24}.Release|x64.ActiveCfg = Release|x64
+ {608CDBD6-8E29-43B7-BCBF-7E3967430A24}.Release|x64.Build.0 = Release|x64
+ {C4C3F080-379F-49DB-ADC6-6328BE884AE3}.Debug|x64.ActiveCfg = Debug|x64
+ {C4C3F080-379F-49DB-ADC6-6328BE884AE3}.Debug|x64.Build.0 = Debug|x64
+ {C4C3F080-379F-49DB-ADC6-6328BE884AE3}.Release|x64.ActiveCfg = Release|x64
+ {C4C3F080-379F-49DB-ADC6-6328BE884AE3}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {C7C6398E-220C-40C3-AE95-5690C9B2B3C3}
+ EndGlobalSection
+EndGlobal
diff --git a/archived/ml_prm/AvatarBoolParameter.cs b/ml_prm/AvatarBoolParameter.cs
similarity index 92%
rename from archived/ml_prm/AvatarBoolParameter.cs
rename to ml_prm/AvatarBoolParameter.cs
index cfc8fdb..fc8729a 100644
--- a/archived/ml_prm/AvatarBoolParameter.cs
+++ b/ml_prm/AvatarBoolParameter.cs
@@ -22,8 +22,8 @@ namespace ml_prm
if(l_regex.IsMatch(l_param.name) && (l_param.type == AnimatorControllerParameterType.Bool))
{
m_name = l_param.name;
+ m_sync = l_param.name.StartsWith('#');
m_hash = l_param.nameHash;
- m_sync = (l_param.name[0] != '#');
break;
}
}
diff --git a/archived/ml_prm/Main.cs b/ml_prm/Main.cs
similarity index 81%
rename from archived/ml_prm/Main.cs
rename to ml_prm/Main.cs
index d043e0b..26303da 100644
--- a/archived/ml_prm/Main.cs
+++ b/ml_prm/Main.cs
@@ -3,6 +3,7 @@ using ABI_RC.Core;
using ABI_RC.Core.InteractionSystem;
using ABI_RC.Core.Player;
using ABI_RC.Core.Util.AssetFiltering;
+using ABI_RC.Systems.Camera.VisualMods;
using ABI_RC.Systems.IK.SubSystems;
using ABI_RC.Systems.MovementSystem;
using System;
@@ -66,6 +67,16 @@ namespace ml_prm
null,
new HarmonyLib.HarmonyMethod(typeof(PlayerRagdollMod).GetMethod(nameof(OnChangeFlight_Postfix), BindingFlags.Static | BindingFlags.NonPublic))
);
+ HarmonyInstance.Patch(
+ typeof(MovementSystem).GetMethod(nameof(MovementSystem.TeleportToPosRot)),
+ null,
+ new HarmonyLib.HarmonyMethod(typeof(PlayerRagdollMod).GetMethod(nameof(OnPlayerTeleport_Postfix), BindingFlags.Static | BindingFlags.NonPublic))
+ );
+ HarmonyInstance.Patch(
+ typeof(DroneMode).GetMethod(nameof(DroneMode.Disable)),
+ null,
+ new HarmonyLib.HarmonyMethod(typeof(PlayerRagdollMod).GetMethod(nameof(OnDroneModeDisable_Postfix), BindingFlags.Static | BindingFlags.NonPublic))
+ );
// Whitelist the toggle script
(typeof(SharedFilter).GetField("_localComponentWhitelist", BindingFlags.NonPublic | BindingFlags.Static)?.GetValue(null) as HashSet)?.Add(typeof(RagdollToggle));
@@ -212,5 +223,33 @@ namespace ml_prm
MelonLoader.MelonLogger.Error(e);
}
}
+
+ static void OnPlayerTeleport_Postfix() => ms_instance?.OnPlayerTeleport();
+ void OnPlayerTeleport()
+ {
+ try
+ {
+ if(m_localController != null)
+ m_localController.OnPlayerTeleport();
+ }
+ catch(Exception e)
+ {
+ MelonLoader.MelonLogger.Error(e);
+ }
+ }
+
+ static void OnDroneModeDisable_Postfix() => ms_instance?.OnDroneModeDisable();
+ void OnDroneModeDisable()
+ {
+ try
+ {
+ if(m_localController != null)
+ m_localController.OnDroneModeDisable();
+ }
+ catch(Exception e)
+ {
+ MelonLoader.MelonLogger.Error(e);
+ }
+ }
}
}
diff --git a/archived/ml_prm/ModUi.cs b/ml_prm/ModUi.cs
similarity index 90%
rename from archived/ml_prm/ModUi.cs
rename to ml_prm/ModUi.cs
index cca7f58..179adea 100644
--- a/archived/ml_prm/ModUi.cs
+++ b/ml_prm/ModUi.cs
@@ -20,6 +20,7 @@ namespace ml_prm
Bounciness,
ViewVelocity,
JumpRecover,
+ Buoyancy,
VelocityMultiplier,
MovementDrag,
AngularDrag,
@@ -49,7 +50,7 @@ namespace ml_prm
var l_modCategory = l_modRoot.AddCategory("Settings");
- l_modCategory.AddButton("Switch ragdoll", "PRM-Person", "Switch between normal and ragdoll state").OnPress += () => SwitchChange?.Invoke();
+ 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);
@@ -81,6 +82,9 @@ namespace ml_prm
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_modCategory.AddToggle("Buoyancy", "Enable buoyancy in fluid volumes. Warning: constantly changes movement and air drag of hips, spine and chest.", Settings.Buoyancy));
+ (ms_uiElements[(int)UiIndex.Buoyancy] as BTKUILib.UIObjects.Components.ToggleButton).OnValueUpdated += (state) => OnToggleUpdate(UiIndex.Buoyancy, 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);
@@ -139,6 +143,10 @@ namespace ml_prm
case UiIndex.JumpRecover:
Settings.SetSetting(Settings.ModSetting.JumpRecover, p_state);
break;
+
+ case UiIndex.Buoyancy:
+ Settings.SetSetting(Settings.ModSetting.Buoyancy, p_state);
+ break;
}
if(p_force)
@@ -182,9 +190,10 @@ namespace ml_prm
OnToggleUpdate(UiIndex.Bounciness, false, true);
OnToggleUpdate(UiIndex.ViewVelocity, false, true);
OnToggleUpdate(UiIndex.JumpRecover, false, true);
+ OnToggleUpdate(UiIndex.Buoyancy, true, true);
OnSliderUpdate(UiIndex.VelocityMultiplier, 2f, true);
- OnSliderUpdate(UiIndex.MovementDrag, 2f, true);
- OnSliderUpdate(UiIndex.AngularDrag, 2f, true);
+ OnSliderUpdate(UiIndex.MovementDrag, 1f, true);
+ OnSliderUpdate(UiIndex.AngularDrag, 1f, true);
OnSliderUpdate(UiIndex.RecoverDelay, 3f, true);
}
diff --git a/archived/ml_prm/Properties/AssemblyInfo.cs b/ml_prm/Properties/AssemblyInfo.cs
similarity index 84%
rename from archived/ml_prm/Properties/AssemblyInfo.cs
rename to ml_prm/Properties/AssemblyInfo.cs
index aae800c..169c7cd 100644
--- a/archived/ml_prm/Properties/AssemblyInfo.cs
+++ b/ml_prm/Properties/AssemblyInfo.cs
@@ -1,4 +1,4 @@
-[assembly: MelonLoader.MelonInfo(typeof(ml_prm.PlayerRagdollMod), "PlayerRagdollMod", "1.0.11", "SDraw", "https://github.com/SDraw/ml_mods_cvr")]
+[assembly: MelonLoader.MelonInfo(typeof(ml_prm.PlayerRagdollMod), "PlayerRagdollMod", "1.1.0", "SDraw", "https://github.com/SDraw/ml_mods_cvr")]
[assembly: MelonLoader.MelonGame(null, "ChilloutVR")]
[assembly: MelonLoader.MelonPriority(2)]
[assembly: MelonLoader.MelonOptionalDependencies("BTKUILib")]
diff --git a/archived/ml_prm/README.md b/ml_prm/README.md
similarity index 94%
rename from archived/ml_prm/README.md
rename to ml_prm/README.md
index e45baa6..a38a10b 100644
--- a/archived/ml_prm/README.md
+++ b/ml_prm/README.md
@@ -11,6 +11,7 @@ This mod turns player's avatar into ragdoll puppet.
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.
+ * Note: You can't ragdoll in chairs.
* **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.
@@ -25,6 +26,8 @@ Optional mod's settings page with [BTKUILib](https://github.com/BTK-Development/
* **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.
+* **Buoyancy:** enabled floating in fluid volumes; `true` by default.
+ * Note: Forcibly enabled 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/archived/ml_prm/RagdollController.cs b/ml_prm/RagdollController.cs
similarity index 73%
rename from archived/ml_prm/RagdollController.cs
rename to ml_prm/RagdollController.cs
index 194a0ad..d3b20f3 100644
--- a/archived/ml_prm/RagdollController.cs
+++ b/ml_prm/RagdollController.cs
@@ -2,11 +2,14 @@
using ABI_RC.Core.InteractionSystem;
using ABI_RC.Core.Player;
using ABI_RC.Core.Savior;
+using ABI_RC.Systems.Camera;
+using ABI_RC.Systems.IK;
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;
using System.Collections.Generic;
using UnityEngine;
@@ -19,11 +22,12 @@ namespace ml_prm
public static RagdollController Instance { get; private set; } = null;
- VRIK m_vrIK = null;
- float m_vrIkWeight = 1f;
bool m_inVr = false;
+ VRIK m_vrIK = null;
+ bool m_applyHipsPosition = false;
bool m_enabled = false;
+ bool m_forcedSwitch = false;
readonly List m_rigidBodies = null;
readonly List m_colliders = null;
@@ -32,8 +36,10 @@ namespace ml_prm
BipedRagdollReferences m_puppetReferences;
readonly List> m_boneLinks = null;
readonly List> m_jointAnchors = null;
+ readonly List m_physicsInfluencers = null;
bool m_avatarReady = false;
+ Coroutine m_initCoroutine = null;
Vector3 m_lastPosition = Vector3.zero;
Vector3 m_velocity = Vector3.zero;
Vector3 m_ragdollLastPos = Vector3.zero;
@@ -56,6 +62,7 @@ namespace ml_prm
m_colliders = new List();
m_boneLinks = new List>();
m_jointAnchors = new List>();
+ m_physicsInfluencers = new List();
m_physicsMaterial = new PhysicMaterial("Ragdoll");
m_physicsMaterial.dynamicFriction = c_defaultFriction;
@@ -81,12 +88,14 @@ namespace ml_prm
m_puppetRoot.localRotation = Quaternion.identity;
m_customTrigger = MovementSystem.Instance.proxyCollider.gameObject.AddComponent();
+ m_customTrigger.enabled = false;
Settings.MovementDragChange += this.OnMovementDragChange;
Settings.AngularDragChange += this.OnAngularDragChange;
Settings.GravityChange += this.OnGravityChange;
Settings.SlipperinessChange += this.OnPhysicsMaterialChange;
Settings.BouncinessChange += this.OnPhysicsMaterialChange;
+ Settings.BuoyancyChange += this.OnBuoyancyChange;
}
void OnDestroy()
@@ -112,6 +121,8 @@ namespace ml_prm
PlayerSetup.Instance.transform.position += l_dif;
m_puppetReferences.hips.position -= l_dif;
m_ragdollLastPos = m_puppetReferences.hips.position;
+
+ BodySystem.TrackingPositionWeight = 0f;
}
if(m_avatarReady && !m_enabled)
@@ -128,9 +139,6 @@ namespace ml_prm
}
}
- if(m_avatarReady && m_enabled && !BodySystem.isCalibrating)
- BodySystem.TrackingPositionWeight = 0f;
-
if(m_avatarReady && m_enabled && Settings.AutoRecover)
{
m_downTime += Time.deltaTime;
@@ -160,13 +168,8 @@ namespace ml_prm
{
if(m_enabled)
{
- if(!BodySystem.isCalibrating)
- {
- BodySystem.TrackingPositionWeight = 0f;
-
- foreach(var l_link in m_boneLinks)
- l_link.Item1.CopyGlobal(l_link.Item2);
- }
+ foreach(var l_link in m_boneLinks)
+ l_link.Item1.CopyGlobal(l_link.Item2);
}
else
{
@@ -179,14 +182,30 @@ namespace ml_prm
// Game events
internal void OnAvatarClear()
{
- if(m_enabled && (MovementSystem.Instance != null))
- MovementSystem.Instance.SetImmobilized(false);
+ if(m_initCoroutine != null)
+ {
+ StopCoroutine(m_initCoroutine);
+ m_initCoroutine = null;
+ }
+
+ if(m_enabled)
+ {
+ TryRestoreMovement();
+ BodySystem.TrackingPositionWeight = 1f;
+ }
if(m_puppet != null)
Object.Destroy(m_puppet.gameObject);
m_puppet = null;
+ if(m_customTrigger != null)
+ {
+ m_customTrigger.GetStateWithReset();
+ m_customTrigger.enabled = false;
+ }
+
m_vrIK = null;
+ m_applyHipsPosition = false;
m_enabled = false;
m_avatarReady = false;
m_avatarRagdollToggle = null;
@@ -196,6 +215,7 @@ namespace ml_prm
m_puppetReferences = new BipedRagdollReferences();
m_boneLinks.Clear();
m_jointAnchors.Clear();
+ m_physicsInfluencers.Clear();
m_reachedGround = true;
m_groundedTime = 0f;
m_downTime = float.MinValue;
@@ -277,15 +297,32 @@ namespace ml_prm
Collider l_collider = l_puppetTransforms[i].GetComponent();
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.proxyCollider, 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_body != null) && (l_collider != null) && (l_puppetTransforms[i] == m_puppetReferences.hips || l_puppetTransforms[i] == m_puppetReferences.spine || l_puppetTransforms[i] == m_puppetReferences.chest))
+ {
+ PhysicsInfluencer l_physicsInfluencer = l_puppetTransforms[i].gameObject.AddComponent();
+ l_physicsInfluencer.airDrag = (Utils.IsWorldSafe() ? Settings.MovementDrag : 1f);
+ l_physicsInfluencer.airAngularDrag = Settings.AngularDrag;
+ l_physicsInfluencer.fluidDrag = 3f;
+ l_physicsInfluencer.fluidAngularDrag = 1f;
+ l_physicsInfluencer.enableBuoyancy = true;
+ l_physicsInfluencer.enableInfluence = false;
+ float mass = l_body.mass;
+ l_physicsInfluencer.UpdateDensity();
+ l_body.mass = mass;
+ l_physicsInfluencer.volume = mass * 0.005f;
+ l_physicsInfluencer.enableLocalGravity = true;
+
+ m_physicsInfluencers.Add(l_physicsInfluencer);
+ }
+
if(l_avatarTransforms[i] != null)
m_boneLinks.Add(System.Tuple.Create(l_puppetTransforms[i], l_avatarTransforms[i]));
}
@@ -294,22 +331,36 @@ namespace ml_prm
// And return back
m_puppetRoot.localPosition = Vector3.zero;
m_puppetRoot.localRotation = Quaternion.identity;
- m_puppetRoot.gameObject.SetActive(false);
+ m_puppetRoot.gameObject.SetActive(true);
m_vrIK = PlayerSetup.Instance._avatar.GetComponent();
if(m_vrIK != null)
- {
- m_vrIK.onPreSolverUpdate.AddListener(this.OnIKPreUpdate);
m_vrIK.onPostSolverUpdate.AddListener(this.OnIKPostUpdate);
- }
m_avatarRagdollToggle = PlayerSetup.Instance._avatar.GetComponentInChildren(true);
m_ragdolledParameter = new AvatarBoolParameter("Ragdolled", PlayerSetup.Instance.animatorManager);
- m_avatarReady = true;
+ m_initCoroutine = StartCoroutine(WaitForPhysicsInfluencers());
}
}
+ IEnumerator WaitForPhysicsInfluencers()
+ {
+ while(!m_physicsInfluencers.TrueForAll(p => p.IsReady()))
+ yield return null;
+
+ m_puppetRoot.gameObject.SetActive(false);
+
+ m_customTrigger.enabled = true;
+ m_avatarReady = true;
+ m_initCoroutine = null;
+
+ OnGravityChange(Settings.Gravity);
+ OnBuoyancyChange(Settings.Buoyancy);
+ OnMovementDragChange(Settings.MovementDrag);
+ OnAngularDragChange(Settings.AngularDrag);
+ }
+
internal void OnAvatarScaling(float p_scaleDifference)
{
if(m_avatarReady)
@@ -323,13 +374,21 @@ namespace ml_prm
internal void OnSeatSitDown(CVRSeat p_seat)
{
if(m_avatarReady && m_enabled && !p_seat.occupied)
+ {
+ m_forcedSwitch = true;
SwitchRagdoll();
+ m_forcedSwitch = false;
+ }
}
internal void OnStartCalibration()
{
if(m_avatarReady && m_enabled)
+ {
+ m_forcedSwitch = true;
SwitchRagdoll();
+ m_forcedSwitch = false;
+ }
}
internal void OnWorldSpawn()
@@ -340,6 +399,7 @@ namespace ml_prm
OnGravityChange(Settings.Gravity);
OnPhysicsMaterialChange(true);
OnMovementDragChange(Settings.MovementDrag);
+ OnBuoyancyChange(Settings.Buoyancy);
}
internal void OnCombatDown()
@@ -347,30 +407,38 @@ namespace ml_prm
if(m_avatarReady && !m_enabled && Settings.CombatReaction)
{
m_reachedGround = true;
+ m_forcedSwitch = true;
SwitchRagdoll();
+ m_forcedSwitch = false;
}
}
internal void OnChangeFlight()
{
if(m_avatarReady && m_enabled && MovementSystem.Instance.flying)
+ {
+ m_forcedSwitch = true;
SwitchRagdoll();
+ m_forcedSwitch = false;
+ }
+ }
+
+ internal void OnPlayerTeleport()
+ {
+ if(m_avatarReady && m_enabled)
+ m_ragdollLastPos = m_puppetReferences.hips.position;
+ }
+
+ internal void OnDroneModeDisable()
+ {
+ if(m_avatarReady && m_enabled)
+ MovementSystem.Instance.canRot = false;
}
// 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
+ if(!m_enabled)
{
foreach(var l_link in m_boneLinks)
l_link.Item2.CopyGlobal(l_link.Item1);
@@ -389,6 +457,8 @@ namespace ml_prm
if(m_enabled)
l_body.WakeUp();
}
+ foreach(PhysicsInfluencer l_influencer in m_physicsInfluencers)
+ l_influencer.airDrag = l_drag;
}
}
void OnAngularDragChange(float p_value)
@@ -401,6 +471,8 @@ namespace ml_prm
if(m_enabled)
l_body.WakeUp();
}
+ foreach(PhysicsInfluencer l_influencer in m_physicsInfluencers)
+ l_influencer.airAngularDrag = p_value;
}
}
void OnGravityChange(bool p_state)
@@ -410,6 +482,14 @@ namespace ml_prm
bool l_gravity = (!Utils.IsWorldSafe() || p_state);
foreach(Rigidbody l_body in m_rigidBodies)
l_body.useGravity = l_gravity;
+ foreach(PhysicsInfluencer l_influencer in m_physicsInfluencers)
+ l_influencer.enabled = l_gravity;
+
+ if(!l_gravity)
+ {
+ OnMovementDragChange(Settings.MovementDrag);
+ OnAngularDragChange(Settings.AngularDrag);
+ }
}
}
void OnPhysicsMaterialChange(bool p_state)
@@ -425,6 +505,21 @@ namespace ml_prm
m_physicsMaterial.bounceCombine = (l_bounciness ? PhysicMaterialCombine.Maximum : PhysicMaterialCombine.Average);
}
}
+ void OnBuoyancyChange(bool p_state)
+ {
+ if(m_avatarReady)
+ {
+ bool l_buoyancy = (!Utils.IsWorldSafe() || p_state);
+ foreach(PhysicsInfluencer l_influencer in m_physicsInfluencers)
+ l_influencer.enableInfluence = l_buoyancy;
+
+ if(!l_buoyancy)
+ {
+ OnMovementDragChange(Settings.MovementDrag);
+ OnAngularDragChange(Settings.AngularDrag);
+ }
+ }
+ }
// Arbitrary
public void SwitchRagdoll()
@@ -433,40 +528,17 @@ namespace ml_prm
{
if(!m_enabled)
{
- if(IsSafeToRagdoll() && m_reachedGround)
+ if(CanRagdoll())
{
- // 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);
+ BodySystem.TrackingPositionWeight = 0f;
+ m_applyHipsPosition = IKSystem.Instance.applyOriginalHipPosition;
+ IKSystem.Instance.applyOriginalHipPosition = true;
PlayerSetup.Instance.animatorManager.SetAnimatorParameterTrigger("CancelEmote");
m_ragdolledParameter.SetValue(true);
- if(!BodySystem.isCalibrating)
- BodySystem.TrackingPositionWeight = 0f;
if(!Utils.IsWorldSafe())
{
@@ -492,9 +564,6 @@ namespace ml_prm
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;
@@ -503,39 +572,39 @@ namespace ml_prm
}
else
{
- if(IsSafeToUnragdoll())
+ if(CanUnragdoll())
{
- MovementSystem.Instance.SetImmobilized(false);
+ MovementSystem.Instance.TeleportTo(m_puppetReferences.hips.position, new Vector3(0f, PlayerSetup.Instance.GetActiveCamera().transform.rotation.eulerAngles.y, 0f));
+ TryRestoreMovement();
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;
+ BodySystem.TrackingPositionWeight = 1f;
+ IKSystem.Instance.applyOriginalHipPosition = m_applyHipsPosition;
if(m_vrIK != null)
m_vrIK.solver.Reset();
+ m_ragdolledParameter.SetValue(false);
+
+ m_puppetRoot.gameObject.SetActive(false);
+ m_puppetRoot.localPosition = Vector3.zero;
+ m_puppetRoot.localRotation = Quaternion.identity;
+
+ foreach(Rigidbody l_body in m_rigidBodies)
+ l_body.isKinematic = true;
+
m_lastPosition = PlayerSetup.Instance.transform.position;
m_velocity = Vector3.zero;
m_downTime = float.MinValue;
+ // Restore rigidbody properties that could be affected by buoyancy
+ OnMovementDragChange(Settings.MovementDrag);
+ OnAngularDragChange(Settings.AngularDrag);
+
m_enabled = false;
}
}
@@ -552,19 +621,34 @@ namespace ml_prm
return l_target;
}
- static bool IsSafeToRagdoll()
+ bool CanRagdoll()
{
- 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;
+ bool l_result = m_reachedGround;
+ l_result &= !BodySystem.isCalibrating;
+ l_result &= (MovementSystem.Instance.lastSeat == null);
+ l_result &= ((CombatSystem.Instance == null) || !CombatSystem.Instance.isDown);
+ return (l_result || m_forcedSwitch);
}
- static bool IsSafeToUnragdoll()
+ bool CanUnragdoll()
{
bool l_result = true;
- l_result &= ((CombatSystem.Instance == null) || !CombatSystem.Instance.isDown); // Non-combat world or not dead
- return l_result;
+ l_result &= ((CombatSystem.Instance == null) || !CombatSystem.Instance.isDown);
+ return (l_result || m_forcedSwitch);
+ }
+
+ static void TryRestoreMovement()
+ {
+ bool l_state = true;
+ l_state &= ((CombatSystem.Instance == null) || !CombatSystem.Instance.isDown);
+ l_state &= (MovementSystem.Instance.lastSeat == null);
+
+ if(l_state)
+ {
+ MovementSystem.Instance.SetImmobilized(false);
+ if(PortableCamera.Instance.CheckModActive(typeof(ABI_RC.Systems.Camera.VisualMods.DroneMode)))
+ MovementSystem.Instance.canRot = false;
+ }
}
}
}
diff --git a/archived/ml_prm/RagdollToggle.cs b/ml_prm/RagdollToggle.cs
similarity index 100%
rename from archived/ml_prm/RagdollToggle.cs
rename to ml_prm/RagdollToggle.cs
diff --git a/archived/ml_prm/RagdollTrigger.cs b/ml_prm/RagdollTrigger.cs
similarity index 100%
rename from archived/ml_prm/RagdollTrigger.cs
rename to ml_prm/RagdollTrigger.cs
diff --git a/archived/ml_prm/RagdollTriggerVolume.cs b/ml_prm/RagdollTriggerVolume.cs
similarity index 100%
rename from archived/ml_prm/RagdollTriggerVolume.cs
rename to ml_prm/RagdollTriggerVolume.cs
diff --git a/archived/ml_prm/Settings.cs b/ml_prm/Settings.cs
similarity index 92%
rename from archived/ml_prm/Settings.cs
rename to ml_prm/Settings.cs
index 71db949..1685450 100644
--- a/archived/ml_prm/Settings.cs
+++ b/ml_prm/Settings.cs
@@ -22,7 +22,8 @@ namespace ml_prm
Slipperiness,
Bounciness,
ViewVelocity,
- JumpRecover
+ JumpRecover,
+ Buoyancy
}
public static bool Hotkey { get; private set; } = true;
@@ -40,6 +41,7 @@ namespace ml_prm
public static bool Bounciness { get; private set; } = false;
public static bool ViewVelocity { get; private set; } = false;
public static bool JumpRecover { get; private set; } = false;
+ public static bool Buoyancy { get; private set; } = true;
static public event Action HotkeyChange;
static public event Action HotkeyKeyChange;
@@ -56,6 +58,7 @@ namespace ml_prm
static public event Action BouncinessChange;
static public event Action ViewVelocityChange;
static public event Action JumpRecoverChange;
+ static public event Action BuoyancyChange;
static MelonLoader.MelonPreferences_Category ms_category = null;
static List ms_entries = null;
@@ -80,7 +83,8 @@ namespace ml_prm
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_category.CreateEntry(ModSetting.JumpRecover.ToString(), JumpRecover, null, null, true),
+ ms_category.CreateEntry(ModSetting.Buoyancy.ToString(), Buoyancy, null, null, true),
};
ms_entries[(int)ModSetting.HotkeyKey].OnEntryValueChangedUntyped.Subscribe(OnMelonSettingSave_HotkeyKey);
@@ -100,6 +104,7 @@ namespace ml_prm
Bounciness = (bool)ms_entries[(int)ModSetting.Bounciness].BoxedValue;
ViewVelocity = (bool)ms_entries[(int)ModSetting.ViewVelocity].BoxedValue;
JumpRecover = (bool)ms_entries[(int)ModSetting.JumpRecover].BoxedValue;
+ Buoyancy = (bool)ms_entries[(int)ModSetting.Buoyancy].BoxedValue;
}
static void OnMelonSettingSave_HotkeyKey(object p_oldValue, object p_newValue)
@@ -186,6 +191,13 @@ namespace ml_prm
}
break;
+ case ModSetting.Buoyancy:
+ {
+ Buoyancy = (bool)p_value;
+ BuoyancyChange?.Invoke((bool)p_value);
+ }
+ break;
+
// Floats
case ModSetting.VelocityMultiplier:
{
diff --git a/archived/ml_prm/Utils.cs b/ml_prm/Utils.cs
similarity index 80%
rename from archived/ml_prm/Utils.cs
rename to ml_prm/Utils.cs
index 8d16014..5843122 100644
--- a/archived/ml_prm/Utils.cs
+++ b/ml_prm/Utils.cs
@@ -1,6 +1,7 @@
using ABI.CCK.Components;
using ABI_RC.Core.Savior;
using ABI_RC.Systems.MovementSystem;
+using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
@@ -10,6 +11,7 @@ namespace ml_prm
{
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);
+ static readonly FieldInfo ms_referencePoints = typeof(PhysicsInfluencer).GetField("_referencePoints", BindingFlags.NonPublic | BindingFlags.Instance);
public static bool IsInVR() => ((CheckVR.Instance != null) && CheckVR.Instance.hasVrDeviceLoaded);
public static bool IsWorldSafe() => ((CVRWorld.Instance != null) && CVRWorld.Instance.allowFlying);
@@ -35,5 +37,10 @@ namespace ml_prm
p_target.position = p_source.position;
p_target.rotation = p_source.rotation;
}
+
+ public static bool IsReady(this PhysicsInfluencer p_instance)
+ {
+ return ((ms_referencePoints.GetValue(p_instance) as List).Count > 0);
+ }
}
}
diff --git a/archived/ml_prm/ml_prm.csproj b/ml_prm/ml_prm.csproj
similarity index 99%
rename from archived/ml_prm/ml_prm.csproj
rename to ml_prm/ml_prm.csproj
index a0d9d36..b276fe1 100644
--- a/archived/ml_prm/ml_prm.csproj
+++ b/ml_prm/ml_prm.csproj
@@ -4,7 +4,7 @@
netstandard2.1
x64
PlayerRagdollMod
- 1.0.11
+ 1.1.0
SDraw
None
PlayerRagdollMod
diff --git a/archived/ml_prm/resources/person.png b/ml_prm/resources/person.png
similarity index 100%
rename from archived/ml_prm/resources/person.png
rename to ml_prm/resources/person.png
diff --git a/archived/ml_prm/vendor/RootMotion/README.md b/ml_prm/vendor/RootMotion/README.md
similarity index 100%
rename from archived/ml_prm/vendor/RootMotion/README.md
rename to ml_prm/vendor/RootMotion/README.md