Unarchived and fixed PlayerRagdollMod

This commit is contained in:
SDraw 2023-11-12 21:30:15 +03:00
parent dacde8975b
commit 7d087bd8fe
No known key found for this signature in database
GPG key ID: BB95B4DAB2BB8BB5
16 changed files with 307 additions and 155 deletions

View file

@ -3,10 +3,11 @@ Merged set of MelonLoader mods for ChilloutVR.
**Table for game build 2023r173:** **Table for game build 2023r173:**
| Full name | Short name | Latest version | Available in [CVRMA](https://github.com/knah/CVRMelonAssistant) | | 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<br>: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<br>: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 |
| [Pickup Arm Movement](/ml_pam/README.md)| ml_pam | 1.0.8 [:arrow_down:](../../releases/latest/download/ml_pam.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 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<br>: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 | | [Vive Extended Input](/ml_vei/README.md) | ml_vei | 1.0.0 [:arrow_down:](../../releases/latest/download/ml_vei.dll)| ✔ Yes |
**Archived mods:** **Archived mods:**
@ -18,5 +19,4 @@ Merged set of MelonLoader mods for ChilloutVR.
| Extended Game Notifications | ml_egn | In-game feature sine 2023r172 update | | Extended Game Notifications | ml_egn | In-game feature sine 2023r172 update |
| Four Point Tracking | ml_fpt | In-game feature since 2022r170 update | | Four Point Tracking | ml_fpt | In-game feature since 2022r170 update |
| Game Main Fixes | ml_gmf | In-game feature sine 2023r172 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` | Server Connection Info | ml_sci | Superseded by `Extended Game Notifications`

View file

@ -1,56 +1,54 @@
 
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16 # Visual Studio Version 16
VisualStudioVersion = 16.0.33214.272 VisualStudioVersion = 16.0.33214.272
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ml_amt", "ml_amt\ml_amt.csproj", "{714806A3-E6FC-46F6-9D1D-89C77FEBAF06}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ml_amt", "ml_amt\ml_amt.csproj", "{714806A3-E6FC-46F6-9D1D-89C77FEBAF06}"
ProjectSection(ProjectDependencies) = postProject EndProject
{D27B6D36-884F-4A49-9A25-B9C121E7B65F} = {D27B6D36-884F-4A49-9A25-B9C121E7B65F} Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ml_lme", "ml_lme\ml_lme.csproj", "{77EA76B1-3709-4FC5-BDBD-8F77160E6DA3}"
{118675AA-9AC7-4B0C-BFB1-FA1691619502} = {118675AA-9AC7-4B0C-BFB1-FA1691619502} ProjectSection(ProjectDependencies) = postProject
EndProjectSection {118675AA-9AC7-4B0C-BFB1-FA1691619502} = {118675AA-9AC7-4B0C-BFB1-FA1691619502}
EndProject EndProjectSection
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ml_dht", "ml_dht\ml_dht.csproj", "{D805BA67-067E-4B79-87FC-6B08973F13EE}" EndProject
EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ml_pam", "ml_pam\ml_pam.csproj", "{5B614459-234A-443D-B06D-34FF81ADA67E}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ml_lme", "ml_lme\ml_lme.csproj", "{77EA76B1-3709-4FC5-BDBD-8F77160E6DA3}" EndProject
ProjectSection(ProjectDependencies) = postProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ml_pmc", "ml_pmc\ml_pmc.csproj", "{118675AA-9AC7-4B0C-BFB1-FA1691619502}"
{118675AA-9AC7-4B0C-BFB1-FA1691619502} = {118675AA-9AC7-4B0C-BFB1-FA1691619502} EndProject
EndProjectSection Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ml_vei", "ml_vei\ml_vei.csproj", "{608CDBD6-8E29-43B7-BCBF-7E3967430A24}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ml_pam", "ml_pam\ml_pam.csproj", "{5B614459-234A-443D-B06D-34FF81ADA67E}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ml_prm", "ml_prm\ml_prm.csproj", "{C4C3F080-379F-49DB-ADC6-6328BE884AE3}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ml_prm", "ml_prm\ml_prm.csproj", "{D27B6D36-884F-4A49-9A25-B9C121E7B65F}" Global
EndProject GlobalSection(SolutionConfigurationPlatforms) = preSolution
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ml_pmc", "ml_pmc\ml_pmc.csproj", "{118675AA-9AC7-4B0C-BFB1-FA1691619502}" Debug|x64 = Debug|x64
EndProject Release|x64 = Release|x64
Global EndGlobalSection
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
Debug|x64 = Debug|x64 {714806A3-E6FC-46F6-9D1D-89C77FEBAF06}.Debug|x64.ActiveCfg = Debug|x64
Release|x64 = Release|x64 {714806A3-E6FC-46F6-9D1D-89C77FEBAF06}.Release|x64.ActiveCfg = Release|x64
EndGlobalSection {714806A3-E6FC-46F6-9D1D-89C77FEBAF06}.Release|x64.Build.0 = Release|x64
GlobalSection(ProjectConfigurationPlatforms) = postSolution {77EA76B1-3709-4FC5-BDBD-8F77160E6DA3}.Debug|x64.ActiveCfg = Debug|x64
{714806A3-E6FC-46F6-9D1D-89C77FEBAF06}.Debug|x64.ActiveCfg = Debug|x64 {77EA76B1-3709-4FC5-BDBD-8F77160E6DA3}.Release|x64.ActiveCfg = Release|x64
{714806A3-E6FC-46F6-9D1D-89C77FEBAF06}.Release|x64.ActiveCfg = Release|x64 {77EA76B1-3709-4FC5-BDBD-8F77160E6DA3}.Release|x64.Build.0 = Release|x64
{714806A3-E6FC-46F6-9D1D-89C77FEBAF06}.Release|x64.Build.0 = Release|x64 {5B614459-234A-443D-B06D-34FF81ADA67E}.Debug|x64.ActiveCfg = Debug|x64
{D805BA67-067E-4B79-87FC-6B08973F13EE}.Debug|x64.ActiveCfg = Debug|x64 {5B614459-234A-443D-B06D-34FF81ADA67E}.Release|x64.ActiveCfg = Release|x64
{D805BA67-067E-4B79-87FC-6B08973F13EE}.Release|x64.ActiveCfg = Release|x64 {5B614459-234A-443D-B06D-34FF81ADA67E}.Release|x64.Build.0 = Release|x64
{D805BA67-067E-4B79-87FC-6B08973F13EE}.Release|x64.Build.0 = Release|x64 {118675AA-9AC7-4B0C-BFB1-FA1691619502}.Debug|x64.ActiveCfg = Debug|x64
{77EA76B1-3709-4FC5-BDBD-8F77160E6DA3}.Debug|x64.ActiveCfg = Debug|x64 {118675AA-9AC7-4B0C-BFB1-FA1691619502}.Release|x64.ActiveCfg = Release|x64
{77EA76B1-3709-4FC5-BDBD-8F77160E6DA3}.Release|x64.ActiveCfg = Release|x64 {118675AA-9AC7-4B0C-BFB1-FA1691619502}.Release|x64.Build.0 = Release|x64
{77EA76B1-3709-4FC5-BDBD-8F77160E6DA3}.Release|x64.Build.0 = Release|x64 {608CDBD6-8E29-43B7-BCBF-7E3967430A24}.Debug|x64.ActiveCfg = Debug|x64
{5B614459-234A-443D-B06D-34FF81ADA67E}.Debug|x64.ActiveCfg = Debug|x64 {608CDBD6-8E29-43B7-BCBF-7E3967430A24}.Debug|x64.Build.0 = Debug|x64
{5B614459-234A-443D-B06D-34FF81ADA67E}.Release|x64.ActiveCfg = Release|x64 {608CDBD6-8E29-43B7-BCBF-7E3967430A24}.Release|x64.ActiveCfg = Release|x64
{5B614459-234A-443D-B06D-34FF81ADA67E}.Release|x64.Build.0 = Release|x64 {608CDBD6-8E29-43B7-BCBF-7E3967430A24}.Release|x64.Build.0 = Release|x64
{D27B6D36-884F-4A49-9A25-B9C121E7B65F}.Debug|x64.ActiveCfg = Debug|x64 {C4C3F080-379F-49DB-ADC6-6328BE884AE3}.Debug|x64.ActiveCfg = Debug|x64
{D27B6D36-884F-4A49-9A25-B9C121E7B65F}.Release|x64.ActiveCfg = Release|x64 {C4C3F080-379F-49DB-ADC6-6328BE884AE3}.Debug|x64.Build.0 = Debug|x64
{D27B6D36-884F-4A49-9A25-B9C121E7B65F}.Release|x64.Build.0 = Release|x64 {C4C3F080-379F-49DB-ADC6-6328BE884AE3}.Release|x64.ActiveCfg = Release|x64
{118675AA-9AC7-4B0C-BFB1-FA1691619502}.Debug|x64.ActiveCfg = Debug|x64 {C4C3F080-379F-49DB-ADC6-6328BE884AE3}.Release|x64.Build.0 = Release|x64
{118675AA-9AC7-4B0C-BFB1-FA1691619502}.Release|x64.ActiveCfg = Release|x64 EndGlobalSection
{118675AA-9AC7-4B0C-BFB1-FA1691619502}.Release|x64.Build.0 = Release|x64 GlobalSection(SolutionProperties) = preSolution
EndGlobalSection HideSolutionNode = FALSE
GlobalSection(SolutionProperties) = preSolution EndGlobalSection
HideSolutionNode = FALSE GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection SolutionGuid = {C7C6398E-220C-40C3-AE95-5690C9B2B3C3}
GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection
SolutionGuid = {C7C6398E-220C-40C3-AE95-5690C9B2B3C3} EndGlobal
EndGlobalSection
EndGlobal

View file

@ -22,8 +22,8 @@ namespace ml_prm
if(l_regex.IsMatch(l_param.name) && (l_param.type == AnimatorControllerParameterType.Bool)) if(l_regex.IsMatch(l_param.name) && (l_param.type == AnimatorControllerParameterType.Bool))
{ {
m_name = l_param.name; m_name = l_param.name;
m_sync = l_param.name.StartsWith('#');
m_hash = l_param.nameHash; m_hash = l_param.nameHash;
m_sync = (l_param.name[0] != '#');
break; break;
} }
} }

View file

@ -3,6 +3,7 @@ using ABI_RC.Core;
using ABI_RC.Core.InteractionSystem; using ABI_RC.Core.InteractionSystem;
using ABI_RC.Core.Player; using ABI_RC.Core.Player;
using ABI_RC.Core.Util.AssetFiltering; using ABI_RC.Core.Util.AssetFiltering;
using ABI_RC.Systems.Camera.VisualMods;
using ABI_RC.Systems.IK.SubSystems; using ABI_RC.Systems.IK.SubSystems;
using ABI_RC.Systems.MovementSystem; using ABI_RC.Systems.MovementSystem;
using System; using System;
@ -66,6 +67,16 @@ namespace ml_prm
null, null,
new HarmonyLib.HarmonyMethod(typeof(PlayerRagdollMod).GetMethod(nameof(OnChangeFlight_Postfix), BindingFlags.Static | BindingFlags.NonPublic)) 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 // Whitelist the toggle script
(typeof(SharedFilter).GetField("_localComponentWhitelist", BindingFlags.NonPublic | BindingFlags.Static)?.GetValue(null) as HashSet<Type>)?.Add(typeof(RagdollToggle)); (typeof(SharedFilter).GetField("_localComponentWhitelist", BindingFlags.NonPublic | BindingFlags.Static)?.GetValue(null) as HashSet<Type>)?.Add(typeof(RagdollToggle));
@ -212,5 +223,33 @@ namespace ml_prm
MelonLoader.MelonLogger.Error(e); 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);
}
}
} }
} }

View file

@ -20,6 +20,7 @@ namespace ml_prm
Bounciness, Bounciness,
ViewVelocity, ViewVelocity,
JumpRecover, JumpRecover,
Buoyancy,
VelocityMultiplier, VelocityMultiplier,
MovementDrag, MovementDrag,
AngularDrag, AngularDrag,
@ -49,7 +50,7 @@ namespace ml_prm
var l_modCategory = l_modRoot.AddCategory("Settings"); 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.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[(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.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[(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.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[(int)UiIndex.VelocityMultiplier] as BTKUILib.UIObjects.Components.SliderFloat).OnValueUpdated += (value) => OnSliderUpdate(UiIndex.VelocityMultiplier, value);
@ -139,6 +143,10 @@ namespace ml_prm
case UiIndex.JumpRecover: case UiIndex.JumpRecover:
Settings.SetSetting(Settings.ModSetting.JumpRecover, p_state); Settings.SetSetting(Settings.ModSetting.JumpRecover, p_state);
break; break;
case UiIndex.Buoyancy:
Settings.SetSetting(Settings.ModSetting.Buoyancy, p_state);
break;
} }
if(p_force) if(p_force)
@ -182,9 +190,10 @@ namespace ml_prm
OnToggleUpdate(UiIndex.Bounciness, false, true); OnToggleUpdate(UiIndex.Bounciness, false, true);
OnToggleUpdate(UiIndex.ViewVelocity, false, true); OnToggleUpdate(UiIndex.ViewVelocity, false, true);
OnToggleUpdate(UiIndex.JumpRecover, false, true); OnToggleUpdate(UiIndex.JumpRecover, false, true);
OnToggleUpdate(UiIndex.Buoyancy, true, true);
OnSliderUpdate(UiIndex.VelocityMultiplier, 2f, true); OnSliderUpdate(UiIndex.VelocityMultiplier, 2f, true);
OnSliderUpdate(UiIndex.MovementDrag, 2f, true); OnSliderUpdate(UiIndex.MovementDrag, 1f, true);
OnSliderUpdate(UiIndex.AngularDrag, 2f, true); OnSliderUpdate(UiIndex.AngularDrag, 1f, true);
OnSliderUpdate(UiIndex.RecoverDelay, 3f, true); OnSliderUpdate(UiIndex.RecoverDelay, 3f, true);
} }

View file

@ -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.MelonGame(null, "ChilloutVR")]
[assembly: MelonLoader.MelonPriority(2)] [assembly: MelonLoader.MelonPriority(2)]
[assembly: MelonLoader.MelonOptionalDependencies("BTKUILib")] [assembly: MelonLoader.MelonOptionalDependencies("BTKUILib")]

View file

@ -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): 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. * **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 hotkey:** enables/disables ragdoll state switch with `R` key; `true` by default.
* **Use gravity:** enables/disables gravity for ragdoll; `true` by default. * **Use gravity:** enables/disables gravity for ragdoll; `true` by default.
* Note: Forcibly enabled in worlds that don't allow flight. * 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. * **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. * Note: Forcibly disabled in worlds that don't allow flight.
* **Jump recover:** enables recovering from ragdoll state by jumping; `false` by default. * **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. * **Velocity multiplier:** velocity force multiplier based on player's movement direction; `2.0` by default.
* Note: Limited according to world's fly multiplier. * Note: Limited according to world's fly multiplier.
* Note: Forcibly set to `1.0` in worlds that don't allow flight. * Note: Forcibly set to `1.0` in worlds that don't allow flight.

View file

@ -2,11 +2,14 @@
using ABI_RC.Core.InteractionSystem; using ABI_RC.Core.InteractionSystem;
using ABI_RC.Core.Player; using ABI_RC.Core.Player;
using ABI_RC.Core.Savior; 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.IK.SubSystems;
using ABI_RC.Systems.InputManagement; using ABI_RC.Systems.InputManagement;
using ABI_RC.Systems.MovementSystem; using ABI_RC.Systems.MovementSystem;
using RootMotion.Dynamics; using RootMotion.Dynamics;
using RootMotion.FinalIK; using RootMotion.FinalIK;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
@ -19,11 +22,12 @@ namespace ml_prm
public static RagdollController Instance { get; private set; } = null; public static RagdollController Instance { get; private set; } = null;
VRIK m_vrIK = null;
float m_vrIkWeight = 1f;
bool m_inVr = false; bool m_inVr = false;
VRIK m_vrIK = null;
bool m_applyHipsPosition = false;
bool m_enabled = false; bool m_enabled = false;
bool m_forcedSwitch = false;
readonly List<Rigidbody> m_rigidBodies = null; readonly List<Rigidbody> m_rigidBodies = null;
readonly List<Collider> m_colliders = null; readonly List<Collider> m_colliders = null;
@ -32,8 +36,10 @@ namespace ml_prm
BipedRagdollReferences m_puppetReferences; BipedRagdollReferences m_puppetReferences;
readonly List<System.Tuple<Transform, Transform>> m_boneLinks = null; readonly List<System.Tuple<Transform, Transform>> m_boneLinks = null;
readonly List<System.Tuple<CharacterJoint, Vector3>> m_jointAnchors = null; readonly List<System.Tuple<CharacterJoint, Vector3>> m_jointAnchors = null;
readonly List<PhysicsInfluencer> m_physicsInfluencers = null;
bool m_avatarReady = false; bool m_avatarReady = false;
Coroutine m_initCoroutine = null;
Vector3 m_lastPosition = Vector3.zero; Vector3 m_lastPosition = Vector3.zero;
Vector3 m_velocity = Vector3.zero; Vector3 m_velocity = Vector3.zero;
Vector3 m_ragdollLastPos = Vector3.zero; Vector3 m_ragdollLastPos = Vector3.zero;
@ -56,6 +62,7 @@ namespace ml_prm
m_colliders = new List<Collider>(); m_colliders = new List<Collider>();
m_boneLinks = new List<System.Tuple<Transform, Transform>>(); m_boneLinks = new List<System.Tuple<Transform, Transform>>();
m_jointAnchors = new List<System.Tuple<CharacterJoint, Vector3>>(); m_jointAnchors = new List<System.Tuple<CharacterJoint, Vector3>>();
m_physicsInfluencers = new List<PhysicsInfluencer>();
m_physicsMaterial = new PhysicMaterial("Ragdoll"); m_physicsMaterial = new PhysicMaterial("Ragdoll");
m_physicsMaterial.dynamicFriction = c_defaultFriction; m_physicsMaterial.dynamicFriction = c_defaultFriction;
@ -81,12 +88,14 @@ namespace ml_prm
m_puppetRoot.localRotation = Quaternion.identity; m_puppetRoot.localRotation = Quaternion.identity;
m_customTrigger = MovementSystem.Instance.proxyCollider.gameObject.AddComponent<RagdollTrigger>(); m_customTrigger = MovementSystem.Instance.proxyCollider.gameObject.AddComponent<RagdollTrigger>();
m_customTrigger.enabled = false;
Settings.MovementDragChange += this.OnMovementDragChange; Settings.MovementDragChange += this.OnMovementDragChange;
Settings.AngularDragChange += this.OnAngularDragChange; Settings.AngularDragChange += this.OnAngularDragChange;
Settings.GravityChange += this.OnGravityChange; Settings.GravityChange += this.OnGravityChange;
Settings.SlipperinessChange += this.OnPhysicsMaterialChange; Settings.SlipperinessChange += this.OnPhysicsMaterialChange;
Settings.BouncinessChange += this.OnPhysicsMaterialChange; Settings.BouncinessChange += this.OnPhysicsMaterialChange;
Settings.BuoyancyChange += this.OnBuoyancyChange;
} }
void OnDestroy() void OnDestroy()
@ -112,6 +121,8 @@ namespace ml_prm
PlayerSetup.Instance.transform.position += l_dif; PlayerSetup.Instance.transform.position += l_dif;
m_puppetReferences.hips.position -= l_dif; m_puppetReferences.hips.position -= l_dif;
m_ragdollLastPos = m_puppetReferences.hips.position; m_ragdollLastPos = m_puppetReferences.hips.position;
BodySystem.TrackingPositionWeight = 0f;
} }
if(m_avatarReady && !m_enabled) 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) if(m_avatarReady && m_enabled && Settings.AutoRecover)
{ {
m_downTime += Time.deltaTime; m_downTime += Time.deltaTime;
@ -160,13 +168,8 @@ namespace ml_prm
{ {
if(m_enabled) if(m_enabled)
{ {
if(!BodySystem.isCalibrating) foreach(var l_link in m_boneLinks)
{ l_link.Item1.CopyGlobal(l_link.Item2);
BodySystem.TrackingPositionWeight = 0f;
foreach(var l_link in m_boneLinks)
l_link.Item1.CopyGlobal(l_link.Item2);
}
} }
else else
{ {
@ -179,14 +182,30 @@ namespace ml_prm
// Game events // Game events
internal void OnAvatarClear() internal void OnAvatarClear()
{ {
if(m_enabled && (MovementSystem.Instance != null)) if(m_initCoroutine != null)
MovementSystem.Instance.SetImmobilized(false); {
StopCoroutine(m_initCoroutine);
m_initCoroutine = null;
}
if(m_enabled)
{
TryRestoreMovement();
BodySystem.TrackingPositionWeight = 1f;
}
if(m_puppet != null) if(m_puppet != null)
Object.Destroy(m_puppet.gameObject); Object.Destroy(m_puppet.gameObject);
m_puppet = null; m_puppet = null;
if(m_customTrigger != null)
{
m_customTrigger.GetStateWithReset();
m_customTrigger.enabled = false;
}
m_vrIK = null; m_vrIK = null;
m_applyHipsPosition = false;
m_enabled = false; m_enabled = false;
m_avatarReady = false; m_avatarReady = false;
m_avatarRagdollToggle = null; m_avatarRagdollToggle = null;
@ -196,6 +215,7 @@ namespace ml_prm
m_puppetReferences = new BipedRagdollReferences(); m_puppetReferences = new BipedRagdollReferences();
m_boneLinks.Clear(); m_boneLinks.Clear();
m_jointAnchors.Clear(); m_jointAnchors.Clear();
m_physicsInfluencers.Clear();
m_reachedGround = true; m_reachedGround = true;
m_groundedTime = 0f; m_groundedTime = 0f;
m_downTime = float.MinValue; m_downTime = float.MinValue;
@ -277,15 +297,32 @@ namespace ml_prm
Collider l_collider = l_puppetTransforms[i].GetComponent<Collider>(); Collider l_collider = l_puppetTransforms[i].GetComponent<Collider>();
if(l_collider != null) 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.controller, true);
Physics.IgnoreCollision(l_collider, MovementSystem.Instance.proxyCollider, true);
Physics.IgnoreCollision(l_collider, MovementSystem.Instance.forceCollider, true); Physics.IgnoreCollision(l_collider, MovementSystem.Instance.forceCollider, true);
l_collider.enabled = false;
l_collider.sharedMaterial = m_physicsMaterial; l_collider.sharedMaterial = m_physicsMaterial;
l_collider.material = m_physicsMaterial; l_collider.material = m_physicsMaterial;
m_colliders.Add(l_collider); 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<PhysicsInfluencer>();
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) if(l_avatarTransforms[i] != null)
m_boneLinks.Add(System.Tuple.Create(l_puppetTransforms[i], l_avatarTransforms[i])); m_boneLinks.Add(System.Tuple.Create(l_puppetTransforms[i], l_avatarTransforms[i]));
} }
@ -294,22 +331,36 @@ namespace ml_prm
// And return back // And return back
m_puppetRoot.localPosition = Vector3.zero; m_puppetRoot.localPosition = Vector3.zero;
m_puppetRoot.localRotation = Quaternion.identity; m_puppetRoot.localRotation = Quaternion.identity;
m_puppetRoot.gameObject.SetActive(false); m_puppetRoot.gameObject.SetActive(true);
m_vrIK = PlayerSetup.Instance._avatar.GetComponent<VRIK>(); m_vrIK = PlayerSetup.Instance._avatar.GetComponent<VRIK>();
if(m_vrIK != null) if(m_vrIK != null)
{
m_vrIK.onPreSolverUpdate.AddListener(this.OnIKPreUpdate);
m_vrIK.onPostSolverUpdate.AddListener(this.OnIKPostUpdate); m_vrIK.onPostSolverUpdate.AddListener(this.OnIKPostUpdate);
}
m_avatarRagdollToggle = PlayerSetup.Instance._avatar.GetComponentInChildren<RagdollToggle>(true); m_avatarRagdollToggle = PlayerSetup.Instance._avatar.GetComponentInChildren<RagdollToggle>(true);
m_ragdolledParameter = new AvatarBoolParameter("Ragdolled", PlayerSetup.Instance.animatorManager); 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) internal void OnAvatarScaling(float p_scaleDifference)
{ {
if(m_avatarReady) if(m_avatarReady)
@ -323,13 +374,21 @@ namespace ml_prm
internal void OnSeatSitDown(CVRSeat p_seat) internal void OnSeatSitDown(CVRSeat p_seat)
{ {
if(m_avatarReady && m_enabled && !p_seat.occupied) if(m_avatarReady && m_enabled && !p_seat.occupied)
{
m_forcedSwitch = true;
SwitchRagdoll(); SwitchRagdoll();
m_forcedSwitch = false;
}
} }
internal void OnStartCalibration() internal void OnStartCalibration()
{ {
if(m_avatarReady && m_enabled) if(m_avatarReady && m_enabled)
{
m_forcedSwitch = true;
SwitchRagdoll(); SwitchRagdoll();
m_forcedSwitch = false;
}
} }
internal void OnWorldSpawn() internal void OnWorldSpawn()
@ -340,6 +399,7 @@ namespace ml_prm
OnGravityChange(Settings.Gravity); OnGravityChange(Settings.Gravity);
OnPhysicsMaterialChange(true); OnPhysicsMaterialChange(true);
OnMovementDragChange(Settings.MovementDrag); OnMovementDragChange(Settings.MovementDrag);
OnBuoyancyChange(Settings.Buoyancy);
} }
internal void OnCombatDown() internal void OnCombatDown()
@ -347,30 +407,38 @@ namespace ml_prm
if(m_avatarReady && !m_enabled && Settings.CombatReaction) if(m_avatarReady && !m_enabled && Settings.CombatReaction)
{ {
m_reachedGround = true; m_reachedGround = true;
m_forcedSwitch = true;
SwitchRagdoll(); SwitchRagdoll();
m_forcedSwitch = false;
} }
} }
internal void OnChangeFlight() internal void OnChangeFlight()
{ {
if(m_avatarReady && m_enabled && MovementSystem.Instance.flying) if(m_avatarReady && m_enabled && MovementSystem.Instance.flying)
{
m_forcedSwitch = true;
SwitchRagdoll(); 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 // IK updates
void OnIKPreUpdate()
{
if(m_enabled)
{
m_vrIkWeight = m_vrIK.solver.IKPositionWeight;
m_vrIK.solver.IKPositionWeight = 0f;
}
}
void OnIKPostUpdate() void OnIKPostUpdate()
{ {
if(m_enabled) if(!m_enabled)
m_vrIK.solver.IKPositionWeight = m_vrIkWeight;
else
{ {
foreach(var l_link in m_boneLinks) foreach(var l_link in m_boneLinks)
l_link.Item2.CopyGlobal(l_link.Item1); l_link.Item2.CopyGlobal(l_link.Item1);
@ -389,6 +457,8 @@ namespace ml_prm
if(m_enabled) if(m_enabled)
l_body.WakeUp(); l_body.WakeUp();
} }
foreach(PhysicsInfluencer l_influencer in m_physicsInfluencers)
l_influencer.airDrag = l_drag;
} }
} }
void OnAngularDragChange(float p_value) void OnAngularDragChange(float p_value)
@ -401,6 +471,8 @@ namespace ml_prm
if(m_enabled) if(m_enabled)
l_body.WakeUp(); l_body.WakeUp();
} }
foreach(PhysicsInfluencer l_influencer in m_physicsInfluencers)
l_influencer.airAngularDrag = p_value;
} }
} }
void OnGravityChange(bool p_state) void OnGravityChange(bool p_state)
@ -410,6 +482,14 @@ namespace ml_prm
bool l_gravity = (!Utils.IsWorldSafe() || p_state); bool l_gravity = (!Utils.IsWorldSafe() || p_state);
foreach(Rigidbody l_body in m_rigidBodies) foreach(Rigidbody l_body in m_rigidBodies)
l_body.useGravity = l_gravity; 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) void OnPhysicsMaterialChange(bool p_state)
@ -425,6 +505,21 @@ namespace ml_prm
m_physicsMaterial.bounceCombine = (l_bounciness ? PhysicMaterialCombine.Maximum : PhysicMaterialCombine.Average); 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 // Arbitrary
public void SwitchRagdoll() public void SwitchRagdoll()
@ -433,40 +528,17 @@ namespace ml_prm
{ {
if(!m_enabled) 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) if(MovementSystem.Instance.flying)
MovementSystem.Instance.ChangeFlight(false); MovementSystem.Instance.ChangeFlight(false);
bool l_crouch = MovementSystem.Instance.crouching;
bool l_prone = MovementSystem.Instance.prone;
MovementSystem.Instance.SetImmobilized(true); MovementSystem.Instance.SetImmobilized(true);
MovementSystem.Instance.ChangeCrouch(l_crouch); BodySystem.TrackingPositionWeight = 0f;
MovementSystem.Instance.ChangeProne(l_prone); m_applyHipsPosition = IKSystem.Instance.applyOriginalHipPosition;
IKSystem.Instance.applyOriginalHipPosition = true;
PlayerSetup.Instance.animatorManager.SetAnimatorParameterTrigger("CancelEmote"); PlayerSetup.Instance.animatorManager.SetAnimatorParameterTrigger("CancelEmote");
m_ragdolledParameter.SetValue(true); m_ragdolledParameter.SetValue(true);
if(!BodySystem.isCalibrating)
BodySystem.TrackingPositionWeight = 0f;
if(!Utils.IsWorldSafe()) if(!Utils.IsWorldSafe())
{ {
@ -492,9 +564,6 @@ namespace ml_prm
l_body.angularVelocity = Vector3.zero; l_body.angularVelocity = Vector3.zero;
} }
foreach(Collider l_collider in m_colliders)
l_collider.enabled = true;
m_ragdollLastPos = m_puppetReferences.hips.position; m_ragdollLastPos = m_puppetReferences.hips.position;
m_downTime = 0f; m_downTime = 0f;
@ -503,39 +572,39 @@ namespace ml_prm
} }
else 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()) if(!Utils.IsWorldSafe())
{ {
Vector3 l_vec = MovementSystem.Instance.GetAppliedGravity(); Vector3 l_vec = MovementSystem.Instance.GetAppliedGravity();
l_vec.y = Mathf.Clamp(l_vec.y, float.MinValue, 0f); l_vec.y = Mathf.Clamp(l_vec.y, float.MinValue, 0f);
MovementSystem.Instance.SetAppliedGravity(l_vec); MovementSystem.Instance.SetAppliedGravity(l_vec);
} }
BodySystem.TrackingPositionWeight = 1f;
m_ragdolledParameter.SetValue(false); IKSystem.Instance.applyOriginalHipPosition = m_applyHipsPosition;
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) if(m_vrIK != null)
m_vrIK.solver.Reset(); 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_lastPosition = PlayerSetup.Instance.transform.position;
m_velocity = Vector3.zero; m_velocity = Vector3.zero;
m_downTime = float.MinValue; m_downTime = float.MinValue;
// Restore rigidbody properties that could be affected by buoyancy
OnMovementDragChange(Settings.MovementDrag);
OnAngularDragChange(Settings.AngularDrag);
m_enabled = false; m_enabled = false;
} }
} }
@ -552,19 +621,34 @@ namespace ml_prm
return l_target; return l_target;
} }
static bool IsSafeToRagdoll() bool CanRagdoll()
{ {
bool l_result = true; bool l_result = m_reachedGround;
l_result &= !BodySystem.isCalibrating; // Not calibrating l_result &= !BodySystem.isCalibrating;
l_result &= ((CombatSystem.Instance == null) || !CombatSystem.Instance.isDown); // Non-combat world or not dead l_result &= (MovementSystem.Instance.lastSeat == null);
return l_result; l_result &= ((CombatSystem.Instance == null) || !CombatSystem.Instance.isDown);
return (l_result || m_forcedSwitch);
} }
static bool IsSafeToUnragdoll() bool CanUnragdoll()
{ {
bool l_result = true; bool l_result = true;
l_result &= ((CombatSystem.Instance == null) || !CombatSystem.Instance.isDown); // Non-combat world or not dead l_result &= ((CombatSystem.Instance == null) || !CombatSystem.Instance.isDown);
return l_result; 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;
}
} }
} }
} }

View file

@ -22,7 +22,8 @@ namespace ml_prm
Slipperiness, Slipperiness,
Bounciness, Bounciness,
ViewVelocity, ViewVelocity,
JumpRecover JumpRecover,
Buoyancy
} }
public static bool Hotkey { get; private set; } = true; 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 Bounciness { get; private set; } = false;
public static bool ViewVelocity { get; private set; } = false; public static bool ViewVelocity { get; private set; } = false;
public static bool JumpRecover { get; private set; } = false; public static bool JumpRecover { get; private set; } = false;
public static bool Buoyancy { get; private set; } = true;
static public event Action<bool> HotkeyChange; static public event Action<bool> HotkeyChange;
static public event Action<KeyCode> HotkeyKeyChange; static public event Action<KeyCode> HotkeyKeyChange;
@ -56,6 +58,7 @@ namespace ml_prm
static public event Action<bool> BouncinessChange; static public event Action<bool> BouncinessChange;
static public event Action<bool> ViewVelocityChange; static public event Action<bool> ViewVelocityChange;
static public event Action<bool> JumpRecoverChange; static public event Action<bool> JumpRecoverChange;
static public event Action<bool> BuoyancyChange;
static MelonLoader.MelonPreferences_Category ms_category = null; static MelonLoader.MelonPreferences_Category ms_category = null;
static List<MelonLoader.MelonPreferences_Entry> ms_entries = null; static List<MelonLoader.MelonPreferences_Entry> ms_entries = null;
@ -80,7 +83,8 @@ namespace ml_prm
ms_category.CreateEntry(ModSetting.Slipperiness.ToString(), Slipperiness, 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.Bounciness.ToString(), Bounciness, null, null, true),
ms_category.CreateEntry(ModSetting.ViewVelocity.ToString(), ViewVelocity, 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); ms_entries[(int)ModSetting.HotkeyKey].OnEntryValueChangedUntyped.Subscribe(OnMelonSettingSave_HotkeyKey);
@ -100,6 +104,7 @@ namespace ml_prm
Bounciness = (bool)ms_entries[(int)ModSetting.Bounciness].BoxedValue; Bounciness = (bool)ms_entries[(int)ModSetting.Bounciness].BoxedValue;
ViewVelocity = (bool)ms_entries[(int)ModSetting.ViewVelocity].BoxedValue; ViewVelocity = (bool)ms_entries[(int)ModSetting.ViewVelocity].BoxedValue;
JumpRecover = (bool)ms_entries[(int)ModSetting.JumpRecover].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) static void OnMelonSettingSave_HotkeyKey(object p_oldValue, object p_newValue)
@ -186,6 +191,13 @@ namespace ml_prm
} }
break; break;
case ModSetting.Buoyancy:
{
Buoyancy = (bool)p_value;
BuoyancyChange?.Invoke((bool)p_value);
}
break;
// Floats // Floats
case ModSetting.VelocityMultiplier: case ModSetting.VelocityMultiplier:
{ {

View file

@ -1,6 +1,7 @@
using ABI.CCK.Components; using ABI.CCK.Components;
using ABI_RC.Core.Savior; using ABI_RC.Core.Savior;
using ABI_RC.Systems.MovementSystem; using ABI_RC.Systems.MovementSystem;
using System.Collections.Generic;
using System.Reflection; using System.Reflection;
using UnityEngine; 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_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_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 IsInVR() => ((CheckVR.Instance != null) && CheckVR.Instance.hasVrDeviceLoaded);
public static bool IsWorldSafe() => ((CVRWorld.Instance != null) && CVRWorld.Instance.allowFlying); 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.position = p_source.position;
p_target.rotation = p_source.rotation; p_target.rotation = p_source.rotation;
} }
public static bool IsReady(this PhysicsInfluencer p_instance)
{
return ((ms_referencePoints.GetValue(p_instance) as List<Vector3>).Count > 0);
}
} }
} }

View file

@ -4,7 +4,7 @@
<TargetFramework>netstandard2.1</TargetFramework> <TargetFramework>netstandard2.1</TargetFramework>
<Platforms>x64</Platforms> <Platforms>x64</Platforms>
<PackageId>PlayerRagdollMod</PackageId> <PackageId>PlayerRagdollMod</PackageId>
<Version>1.0.11</Version> <Version>1.1.0</Version>
<Authors>SDraw</Authors> <Authors>SDraw</Authors>
<Company>None</Company> <Company>None</Company>
<Product>PlayerRagdollMod</Product> <Product>PlayerRagdollMod</Product>

View file

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Before After
Before After