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