Propper game events

Ragdoll body parts grab
This commit is contained in:
SDraw 2024-08-10 15:29:40 +03:00
parent 8bead6a764
commit 84c255660e
No known key found for this signature in database
GPG key ID: BB95B4DAB2BB8BB5
12 changed files with 279 additions and 20 deletions

View file

@ -24,8 +24,8 @@ namespace ml_pin
{
m_soundManager = null;
CVRGameEventSystem.Player.OnJoin.RemoveListener(OnPlayerJoin);
CVRGameEventSystem.Player.OnLeave.RemoveListener(OnPlayerLeave);
CVRGameEventSystem.Player.OnJoinEntity.RemoveListener(OnPlayerJoin);
CVRGameEventSystem.Player.OnLeaveEntity.RemoveListener(OnPlayerLeave);
}
IEnumerator WaitForInstances()
@ -36,17 +36,17 @@ namespace ml_pin
m_soundManager = new SoundManager();
m_soundManager.LoadSounds();
CVRGameEventSystem.Player.OnJoin.AddListener(OnPlayerJoin);
CVRGameEventSystem.Player.OnLeave.AddListener(OnPlayerLeave);
CVRGameEventSystem.Player.OnJoinEntity.AddListener(OnPlayerJoin);
CVRGameEventSystem.Player.OnLeaveEntity.AddListener(OnPlayerLeave);
}
void OnPlayerJoin(PlayerDescriptor p_player)
void OnPlayerJoin(CVRPlayerEntity p_player)
{
try
{
if(p_player != null) // This happens sometimes, no idea why
if((p_player != null) && (p_player.PlayerDescriptor != null)) // This happens sometimes, no idea why
{
bool l_isFriend = Friends.FriendsWith(p_player.ownerId);
bool l_isFriend = Friends.FriendsWith(p_player.PlayerDescriptor.ownerId);
bool l_notify = false;
switch(Settings.NotifyType)
@ -72,13 +72,13 @@ namespace ml_pin
MelonLoader.MelonLogger.Warning(e);
}
}
void OnPlayerLeave(PlayerDescriptor p_player)
void OnPlayerLeave(CVRPlayerEntity p_player)
{
try
{
if(p_player != null) // This happens sometimes, no idea why
if((p_player != null) && (p_player.PlayerDescriptor != null)) // This happens sometimes, no idea why
{
bool l_isFriend = Friends.FriendsWith(p_player.ownerId);
bool l_isFriend = Friends.FriendsWith(p_player.PlayerDescriptor.ownerId);
bool l_notify = false;
switch(Settings.NotifyType)

View file

@ -1,4 +1,4 @@
[assembly: MelonLoader.MelonInfo(typeof(ml_pin.PlayersInstanceNotifier), "PlayersInstanceNotifier", "1.0.7", "SDraw", "https://github.com/SDraw/ml_mods_cvr")]
[assembly: MelonLoader.MelonInfo(typeof(ml_pin.PlayersInstanceNotifier), "PlayersInstanceNotifier", "1.0.8", "SDraw", "https://github.com/SDraw/ml_mods_cvr")]
[assembly: MelonLoader.MelonGame(null, "ChilloutVR")]
[assembly: MelonLoader.MelonPlatform(MelonLoader.MelonPlatformAttribute.CompatiblePlatforms.WINDOWS_X64)]
[assembly: MelonLoader.MelonPlatformDomain(MelonLoader.MelonPlatformDomainAttribute.CompatibleDomains.MONO)]

View file

@ -7,7 +7,7 @@
<Authors>SDraw</Authors>
<Company>None</Company>
<Product>PlayersInstanceNotifier</Product>
<Version>1.0.7</Version>
<Version>1.0.8</Version>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">

View file

@ -1,5 +1,6 @@
using ABI_RC.Core.Player;
using ABI_RC.Core.Util.AssetFiltering;
using ABI_RC.Systems.GameEventSystem;
using System;
using System.Collections.Generic;
using System.Reflection;
@ -17,6 +18,8 @@ namespace ml_prm
GameEvents.Init(HarmonyInstance);
WorldHandler.Init();
CVRGameEventSystem.Player.OnJoinEntity.AddListener(this.OnRemotePlayerCreated);
MelonLoader.MelonCoroutines.Start(WaitForLocalPlayer());
MelonLoader.MelonCoroutines.Start(WaitForWhitelist());
}
@ -28,6 +31,8 @@ namespace ml_prm
if(m_localController != null)
UnityEngine.Object.Destroy(m_localController);
m_localController = null;
CVRGameEventSystem.Player.OnJoinEntity.RemoveListener(this.OnRemotePlayerCreated);
}
System.Collections.IEnumerator WaitForLocalPlayer()
@ -50,5 +55,11 @@ namespace ml_prm
}
l_hashSet.Add(typeof(RagdollToggle));
}
void OnRemotePlayerCreated(CVRPlayerEntity p_player)
{
if((p_player != null) && (p_player.PuppetMaster != null))
p_player.PuppetMaster.gameObject.AddComponent<RemoteGestureHandler>();
}
}
}

View file

@ -34,7 +34,10 @@ namespace ml_prm
MovementDrag,
AngularDrag,
RecoverDelay,
FallLimit
FallLimit,
GestureGrab,
FriendsGrab,
GrabDistance
}
const string c_ragdollKeyTooltip = "Switch ragdoll mode with '{0}' key";
@ -58,11 +61,14 @@ namespace ml_prm
static ToggleButton ms_jumpRecoverToggle = null;
static ToggleButton ms_buoyancyToggle = null;
static ToggleButton ms_fallDamageToggle = null;
static ToggleButton ms_gestureGrabToggle = null;
static ToggleButton ms_friendsGrabToggle = null;
static SliderFloat ms_velocityMultiplierSlider = null;
static SliderFloat ms_movementDragSlider = null;
static SliderFloat ms_angularMovementDragSlider = null;
static SliderFloat ms_recoverDelaySlider = null;
static SliderFloat ms_fallLimitSlider = null;
static SliderFloat ms_grabDistanceSlider = null;
static Button ms_resetButton = null;
internal static void Init()
@ -116,6 +122,12 @@ namespace ml_prm
ms_fallDamageToggle = ms_category.AddToggle("Fall damage", "Enable ragdoll when falling from height", Settings.FallDamage);
ms_fallDamageToggle.OnValueUpdated += (state) => OnToggleUpdate(UiIndex.FallDamage, state);
ms_gestureGrabToggle = ms_category.AddToggle("Gesture grab", "Enable grabbing of ragdolled body parts by remote players with trigger gesture<p>Warning: can lead to unpredictable physics behaviour in some cases", Settings.GestureGrab);
ms_gestureGrabToggle.OnValueUpdated += (state) => OnToggleUpdate(UiIndex.GestureGrab, state);
ms_friendsGrabToggle = ms_category.AddToggle("Friends grab only", " ", Settings.FriendsGrab);
ms_friendsGrabToggle.OnValueUpdated += (state) => OnToggleUpdate(UiIndex.FriendsGrab, state);
ms_velocityMultiplierSlider = ms_category.AddSlider("Velocity multiplier", "Velocity multiplier upon entering ragdoll state", Settings.VelocityMultiplier, 1f, 50f);
ms_velocityMultiplierSlider.OnValueUpdated += (value) => OnSliderUpdate(UiIndex.VelocityMultiplier, value);
@ -132,6 +144,9 @@ namespace ml_prm
ms_fallLimitSlider.SliderTooltip = string.Format(c_fallLimitTooltip, GetDropHeight(Settings.FallLimit));
ms_fallLimitSlider.OnValueUpdated += (value) => OnSliderUpdate(UiIndex.FallLimit, value);
ms_grabDistanceSlider = ms_category.AddSlider("Grab distance", "Minimal distance for successful grab", Settings.GrabDistance, 0f, 1f);
ms_grabDistanceSlider.OnValueUpdated += (value) => OnSliderUpdate(UiIndex.GrabDistance, value);
ms_resetButton = ms_category.AddButton("Reset settings", "", "Reset mod settings to default");
ms_resetButton.OnPress += Reset;
}
@ -201,6 +216,14 @@ namespace ml_prm
case UiIndex.FallDamage:
Settings.SetSetting(Settings.ModSetting.FallDamage, p_state);
break;
case UiIndex.GestureGrab:
Settings.SetSetting(Settings.ModSetting.GestureGrab, p_state);
break;
case UiIndex.FriendsGrab:
Settings.SetSetting(Settings.ModSetting.FriendsGrab, p_state);
break;
}
}
catch(Exception e)
@ -237,6 +260,10 @@ namespace ml_prm
ms_fallLimitSlider.SliderTooltip = string.Format(c_fallLimitTooltip, GetDropHeight(p_value));
}
break;
case UiIndex.GrabDistance:
Settings.SetSetting(Settings.ModSetting.GrabDistance, p_value);
break;
}
}
catch(Exception e)
@ -283,6 +310,12 @@ namespace ml_prm
OnToggleUpdate(UiIndex.FallDamage, true);
ms_fallDamageToggle.ToggleValue = true;
OnToggleUpdate(UiIndex.GestureGrab, false);
ms_gestureGrabToggle.ToggleValue = false;
OnToggleUpdate(UiIndex.FriendsGrab, true);
ms_friendsGrabToggle.ToggleValue = true;
OnSliderUpdate(UiIndex.VelocityMultiplier, 2f);
ms_velocityMultiplierSlider.SetSliderValue(2f);
@ -297,6 +330,9 @@ namespace ml_prm
OnSliderUpdate(UiIndex.FallLimit, 9.899494f);
ms_fallLimitSlider.SetSliderValue(9.899494f);
OnSliderUpdate(UiIndex.GrabDistance, 0.1f);
ms_grabDistanceSlider.SetSliderValue(0.1f);
}
static void OnHotkeyKeyChanged(UnityEngine.KeyCode p_keyCode)

View file

@ -1,4 +1,4 @@
[assembly: MelonLoader.MelonInfo(typeof(ml_prm.PlayerRagdollMod), "PlayerRagdollMod", "1.1.8", "SDraw", "https://github.com/SDraw/ml_mods_cvr")]
[assembly: MelonLoader.MelonInfo(typeof(ml_prm.PlayerRagdollMod), "PlayerRagdollMod", "1.1.9", "SDraw", "https://github.com/SDraw/ml_mods_cvr")]
[assembly: MelonLoader.MelonGame(null, "ChilloutVR")]
[assembly: MelonLoader.MelonPriority(2)]
[assembly: MelonLoader.MelonAdditionalDependencies("BTKUILib")]

View file

@ -29,6 +29,9 @@ Optional mod's settings page with [BTKUILib](https://github.com/BTK-Development/
* **Buoyancy:** enables floating in fluid volumes; `true` by default.
* Note: Forcibly enabled in worlds that don't allow flight.
* **Fall damage:** enables ragdoll when falling from specific height; `true` by default.
* **Gesture grab:** enables grabbing of ragdolled body parts by remote players with trigger gesture; `false` by default.
* Note: Can lead to unpredictable physics behaviour in some cases.
* **Friends grab only:** Allow only friends to be able to grab your radgolled body parts; `true` by default.
* **Velocity multiplier:** velocity force multiplier based on player's movement direction; `2.0` by default.
* Note: Limited according to world's fly multiplier.
* Note: Forcibly set to `1.0` in worlds that don't allow flight.
@ -37,6 +40,7 @@ Optional mod's settings page with [BTKUILib](https://github.com/BTK-Development/
* **Angular movement drag:** angular movement resistance; `2.0` by default.
* **Recover delay:** time delay for enabled `Auto recover` in seconds; `3.0` by default.
* **Fall limit:** height limit for fall damage; `5.0` by default.
* **Grab distance:** minimal distance for successful grab; `0.1` by default.
* **Reset settings:** resets mod settings to default.
Optional mod's settings in [UIExpansionKit](https://github.com/ddakebono/ChilloutMods):

View file

@ -18,6 +18,11 @@ namespace ml_prm
bool m_shouldHaveInfluencer = false;
bool m_activeGravity = true;
bool m_attached = false;
Transform m_attachedHand = null;
Transform m_attachTransform = null;
FixedJoint m_attachJoint = null;
// Unity events
void Awake()
{
@ -72,6 +77,8 @@ namespace ml_prm
{
if(collider != null)
CVRParticlePointerManager.RemoveTrigger(collider);
Detach();
}
void FixedUpdate()
@ -80,11 +87,26 @@ namespace ml_prm
{
m_rigidBody.useGravity = false;
if(m_activeGravity && ((m_physicsInfluencer == null) || !m_physicsInfluencer.enableInfluence || !m_physicsInfluencer.GetSubmerged()))
if(!m_attached && m_activeGravity && ((m_physicsInfluencer == null) || !m_physicsInfluencer.enableInfluence || !m_physicsInfluencer.GetSubmerged()))
m_rigidBody.AddForce(BetterBetterCharacterController.Instance.GravityResult.AppliedGravity * m_rigidBody.mass);
}
}
void Update()
{
if(m_attached && !ReferenceEquals(m_attachTransform, null) && (m_attachTransform == null))
{
m_attachTransform = null;
if(m_attachJoint != null)
Object.Destroy(m_attachJoint);
m_attachJoint = null;
m_attachedHand = null;
m_attached = false;
}
}
void OnTriggerEnter(Collider p_col)
{
if(Settings.PointersReaction && (RagdollController.Instance != null))
@ -178,6 +200,54 @@ namespace ml_prm
return (Settings.IgnoreLocal && (p_transform.root == PlayerSetup.Instance.transform));
}
public bool Attach(Transform p_hand, Vector3 p_pos)
{
bool l_result = false;
if(!m_attached && (collider != null))
{
if(Vector3.Distance(p_pos, collider.ClosestPoint(p_pos)) <= Settings.GrabDistance)
{
GameObject l_attachPoint = new GameObject("[AttachPoint]");
m_attachTransform = l_attachPoint.transform;
m_attachTransform.parent = p_hand;
m_attachTransform.position = p_pos;
Rigidbody l_body = l_attachPoint.AddComponent<Rigidbody>();
l_body.isKinematic = true;
l_body.detectCollisions = false;
m_attachJoint = this.gameObject.AddComponent<FixedJoint>();
m_attachJoint.connectedBody = l_body;
m_attachJoint.breakForce = Mathf.Infinity;
m_attachJoint.breakTorque = Mathf.Infinity;
m_attached = true;
m_attachedHand = p_hand;
l_result = true;
}
}
return l_result;
}
public void Detach() => Detach(m_attachedHand);
public void Detach(Transform p_hand)
{
if(m_attached && ReferenceEquals(m_attachedHand, p_hand))
{
if(m_attachTransform != null)
Object.Destroy(m_attachTransform.gameObject);
m_attachTransform = null;
if(m_attachJoint != null)
Object.Destroy(m_attachJoint);
m_attachJoint = null;
m_attachedHand = null;
m_attached = false;
}
}
// CVRTriggerVolume
public void TriggerEnter(CVRPointer pointer)
{
@ -187,6 +257,8 @@ namespace ml_prm
RagdollController.Instance.SwitchRagdoll();
}
}
public void TriggerExit(CVRPointer pointer) { }
public void TriggerExit(CVRPointer pointer)
{
}
}
}

View file

@ -88,6 +88,7 @@ namespace ml_prm
Settings.OnBouncinessChanged.AddHandler(this.OnPhysicsMaterialChanged);
Settings.OnBuoyancyChanged.AddHandler(this.OnBuoyancyChanged);
Settings.OnFallDamageChanged.AddHandler(this.OnFallDamageChanged);
Settings.OnGestureGrabChanged.AddHandler(this.OnGestureGrabChanged);
GameEvents.OnAvatarClear.AddHandler(this.OnAvatarClear);
GameEvents.OnAvatarSetup.AddHandler(this.OnAvatarSetup);
@ -103,6 +104,7 @@ namespace ml_prm
BetterBetterCharacterController.OnTeleport.AddListener(this.OnPlayerTeleport);
ModUi.OnSwitchChanged.AddHandler(this.SwitchRagdoll);
RemoteGestureHandler.OnGestureState.AddHandler(this.OnRemotePlayerGestureStateChanged);
}
void OnDestroy()
@ -135,6 +137,7 @@ namespace ml_prm
Settings.OnBouncinessChanged.RemoveHandler(this.OnPhysicsMaterialChanged);
Settings.OnBuoyancyChanged.RemoveHandler(this.OnBuoyancyChanged);
Settings.OnFallDamageChanged.RemoveHandler(this.OnFallDamageChanged);
Settings.OnGestureGrabChanged.RemoveHandler(this.OnGestureGrabChanged);
GameEvents.OnAvatarClear.RemoveHandler(this.OnAvatarClear);
GameEvents.OnAvatarSetup.RemoveHandler(this.OnAvatarSetup);
@ -150,6 +153,7 @@ namespace ml_prm
BetterBetterCharacterController.OnTeleport.RemoveListener(this.OnPlayerTeleport);
ModUi.OnSwitchChanged.RemoveHandler(this.SwitchRagdoll);
RemoteGestureHandler.OnGestureState.RemoveHandler(this.OnRemotePlayerGestureStateChanged);
}
void Update()
@ -485,6 +489,37 @@ namespace ml_prm
p_result.m_result |= (m_enabled && (m_vrIK != null));
}
// Custom game events
void OnRemotePlayerGestureStateChanged(ABI_RC.Core.Player.PuppetMaster p_master, bool p_left, bool p_state)
{
if(m_avatarReady && m_enabled && Settings.GestureGrab && (p_master.animatorManager.Animator != null))
{
Transform l_hand = p_master.animatorManager.Animator.GetBoneTransform(p_left ? HumanBodyBones.LeftHand : HumanBodyBones.RightHand);
Transform l_finger = p_master.animatorManager.Animator.GetBoneTransform(p_left ? HumanBodyBones.LeftMiddleProximal : HumanBodyBones.RightMiddleProximal);
if(l_hand != null)
{
Vector3 l_pos = l_hand.position;
if(l_finger != null)
{
l_pos += l_finger.position;
l_pos *= 0.5f;
}
foreach(var l_bodyHandler in m_ragdollBodyHandlers)
{
if(p_state)
{
if(l_bodyHandler.Attach(l_hand, l_pos))
break;
}
else
l_bodyHandler.Detach(l_hand);
}
}
}
}
// VRIK updates
void OnIKPostSolverUpdate()
{
@ -505,6 +540,7 @@ namespace ml_prm
l_handler.SetDrag(l_drag);
}
}
void OnAngularDragChanged(float p_value)
{
if(m_avatarReady)
@ -513,6 +549,7 @@ namespace ml_prm
l_handler.SetAngularDrag(p_value);
}
}
void OnGravityChanged(bool p_state)
{
if(m_avatarReady)
@ -528,6 +565,7 @@ namespace ml_prm
}
}
}
void OnPhysicsMaterialChanged(bool p_state)
{
if(m_physicsMaterial != null)
@ -541,6 +579,7 @@ namespace ml_prm
m_physicsMaterial.bounceCombine = (l_bounciness ? PhysicMaterialCombine.Maximum : PhysicMaterialCombine.Average);
}
}
void OnBuoyancyChanged(bool p_state)
{
if(m_avatarReady)
@ -556,11 +595,21 @@ namespace ml_prm
}
}
}
void OnFallDamageChanged(bool p_state)
{
m_inAir = false;
}
void OnGestureGrabChanged(bool p_state)
{
if(m_avatarReady && m_enabled & !p_state)
{
foreach(var l_hanlder in m_ragdollBodyHandlers)
l_hanlder.Detach();
}
}
// Arbitrary
public void SwitchRagdoll()
{
@ -644,8 +693,9 @@ namespace ml_prm
foreach(RagdollBodypartHandler l_handler in m_ragdollBodyHandlers)
{
l_handler.SetAsKinematic(true);
l_handler.Detach();
l_handler.ClearFluidVolumes();
l_handler.SetAsKinematic(true);
}
m_lastPosition = PlayerSetup.Instance.transform.position;

View file

@ -0,0 +1,50 @@
using ABI_RC.Core.Networking.IO.Social;
using ABI_RC.Core.Player;
using System;
using System.Collections.Generic;
using System.Text;
using UnityEngine;
namespace ml_prm
{
class RemoteGestureHandler : MonoBehaviour
{
internal class GestureEvent<T1, T2, T3>
{
event Action<T1, T2, T3> m_action;
public void AddHandler(Action<T1, T2, T3> p_listener) => m_action += p_listener;
public void RemoveHandler(Action<T1, T2, T3> p_listener) => m_action -= p_listener;
public void Invoke(T1 p_objA, T2 p_objB, T3 p_objC) => m_action?.Invoke(p_objA, p_objB, p_objC);
}
public static readonly GestureEvent<PuppetMaster, bool, bool> OnGestureState = new GestureEvent<PuppetMaster, bool, bool>();
PuppetMaster m_puppetMaster = null;
bool m_stateLeft = false;
bool m_stateRight = false;
void Start()
{
m_puppetMaster = this.GetComponent<PuppetMaster>();
}
void Update()
{
bool l_state = Mathf.Approximately(m_puppetMaster.PlayerAvatarMovementDataInput.AnimatorGestureLeft, 1f);
if(m_stateLeft != l_state)
{
m_stateLeft = l_state;
if(!Settings.FriendsGrab || Friends.FriendsWith(m_puppetMaster.CVRPlayerEntity.PlayerDescriptor.ownerId))
OnGestureState.Invoke(m_puppetMaster, true, m_stateLeft);
}
l_state = Mathf.Approximately(m_puppetMaster.PlayerAvatarMovementDataInput.AnimatorGestureRight, 1f);
if(m_stateRight != l_state)
{
m_stateRight = l_state;
if(!Settings.FriendsGrab || Friends.FriendsWith(m_puppetMaster.CVRPlayerEntity.PlayerDescriptor.ownerId))
OnGestureState.Invoke(m_puppetMaster, false, m_stateRight);
}
}
}
}

View file

@ -33,7 +33,10 @@ namespace ml_prm
JumpRecover,
Buoyancy,
FallDamage,
FallLimit
FallLimit,
GestureGrab,
FriendsGrab,
GrabDistance
}
public static bool Hotkey { get; private set; } = true;
@ -54,6 +57,9 @@ namespace ml_prm
public static bool Buoyancy { get; private set; } = true;
public static bool FallDamage { get; private set; } = true;
public static float FallLimit { get; private set; } = 9.899494f;
public static bool GestureGrab { get; private set; } = false;
public static bool FriendsGrab { get; private set; } = true;
public static float GrabDistance { get; private set; } = 0.1f;
public static readonly SettingEvent<bool> OnHotkeyChanged = new SettingEvent<bool>();
public static readonly SettingEvent<KeyCode> OnHotkeyKeyChanged = new SettingEvent<KeyCode>();
@ -73,6 +79,9 @@ namespace ml_prm
public static readonly SettingEvent<bool> OnBuoyancyChanged = new SettingEvent<bool>();
public static readonly SettingEvent<bool> OnFallDamageChanged = new SettingEvent<bool>();
public static readonly SettingEvent<float> OnFallLimitChanged = new SettingEvent<float>();
public static readonly SettingEvent<bool> OnGestureGrabChanged = new SettingEvent<bool>();
public static readonly SettingEvent<bool> OnFriendsGrabChanged = new SettingEvent<bool>();
public static readonly SettingEvent<float> OnGrabDistanceChanged = new SettingEvent<float>();
static MelonLoader.MelonPreferences_Category ms_category = null;
static List<MelonLoader.MelonPreferences_Entry> ms_entries = null;
@ -101,6 +110,9 @@ namespace ml_prm
ms_category.CreateEntry(ModSetting.Buoyancy.ToString(), Buoyancy, null, null, true),
ms_category.CreateEntry(ModSetting.FallDamage.ToString(), FallDamage, null, null, true),
ms_category.CreateEntry(ModSetting.FallLimit.ToString(), FallLimit, null, null, true),
ms_category.CreateEntry(ModSetting.GestureGrab.ToString(), GestureGrab, null, null, true),
ms_category.CreateEntry(ModSetting.FriendsGrab.ToString(), FriendsGrab, null, null, true),
ms_category.CreateEntry(ModSetting.GrabDistance.ToString(), GrabDistance, null, null, true),
};
ms_entries[(int)ModSetting.HotkeyKey].OnEntryValueChangedUntyped.Subscribe(OnMelonSettingSave_HotkeyKey);
@ -123,6 +135,9 @@ namespace ml_prm
Buoyancy = (bool)ms_entries[(int)ModSetting.Buoyancy].BoxedValue;
FallDamage = (bool)ms_entries[(int)ModSetting.FallDamage].BoxedValue;
FallLimit = Mathf.Clamp((float)ms_entries[(int)ModSetting.FallLimit].BoxedValue, 4.5f, 44.5f);
GestureGrab = (bool)ms_entries[(int)ModSetting.GestureGrab].BoxedValue;
FriendsGrab = (bool)ms_entries[(int)ModSetting.FriendsGrab].BoxedValue;
GrabDistance = Mathf.Clamp01((float)ms_entries[(int)ModSetting.GrabDistance].BoxedValue);
}
static void OnMelonSettingSave_HotkeyKey(object p_oldValue, object p_newValue)
@ -232,6 +247,20 @@ namespace ml_prm
}
break;
case ModSetting.GestureGrab:
{
GestureGrab = (bool)p_value;
OnGestureGrabChanged.Invoke(GestureGrab);
}
break;
case ModSetting.FriendsGrab:
{
FriendsGrab = (bool)p_value;
OnFriendsGrabChanged.Invoke(FriendsGrab);
}
break;
// Floats
case ModSetting.VelocityMultiplier:
{
@ -267,6 +296,13 @@ namespace ml_prm
OnFallLimitChanged.Invoke(FallLimit);
}
break;
case ModSetting.GrabDistance:
{
GrabDistance = (float)p_value;
OnGrabDistanceChanged.Invoke(GrabDistance);
}
break;
}
if(ms_entries != null)

View file

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