mirror of
https://github.com/hanetzer/sdraw_mods_cvr.git
synced 2025-09-03 18:39:23 +00:00
Too many changes
This commit is contained in:
parent
45557943c4
commit
a22e5992d0
72 changed files with 1064 additions and 927 deletions
|
@ -248,6 +248,5 @@ namespace ml_prm
|
|||
}
|
||||
return !ms_result.m_result;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,14 +42,9 @@ namespace ml_prm
|
|||
System.Collections.IEnumerator WaitForWhitelist()
|
||||
{
|
||||
// Whitelist the toggle script
|
||||
FieldInfo l_field = typeof(SharedFilter).GetField("_localComponentWhitelist", BindingFlags.NonPublic | BindingFlags.Static);
|
||||
HashSet<Type> l_hashSet = l_field?.GetValue(null) as HashSet<Type>;
|
||||
while(l_hashSet == null)
|
||||
{
|
||||
l_hashSet = l_field?.GetValue(null) as HashSet<Type>;
|
||||
while(SharedFilter.LocalComponentWhitelist == null)
|
||||
yield return null;
|
||||
}
|
||||
l_hashSet.Add(typeof(RagdollToggle));
|
||||
SharedFilter.LocalComponentWhitelist.Add(typeof(RagdollToggle));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@ namespace ml_prm
|
|||
const string c_ragdollKeyTooltip = "Switch ragdoll mode with '{0}' key";
|
||||
const string c_fallLimitTooltip = "Fall limit based on impact velocity<p>Current value corresponds to drop from {0} units with default gravity</p>";
|
||||
|
||||
readonly static string ms_namespace = typeof(ModUi).Namespace;
|
||||
internal static readonly UiEvent OnSwitchChanged = new UiEvent();
|
||||
|
||||
static Page ms_page = null;
|
||||
|
@ -345,7 +346,7 @@ namespace ml_prm
|
|||
{
|
||||
Assembly l_assembly = Assembly.GetExecutingAssembly();
|
||||
string l_assemblyName = l_assembly.GetName().Name;
|
||||
return l_assembly.GetManifestResourceStream(l_assemblyName + ".resources." + p_name);
|
||||
return l_assembly.GetManifestResourceStream(ms_namespace + ".resources." + p_name);
|
||||
}
|
||||
|
||||
static float GetDropHeight(float p_speed, float p_gravity = 9.8f)
|
||||
|
|
|
@ -65,7 +65,7 @@ Now you can animate both parameters available:
|
|||

|
||||
Note: In order to work the game object needs to be active and the component enabled.
|
||||
|
||||
# Mods Integration
|
||||
# Mods integration
|
||||
You can use this mod's functions within your mod. To do this you need:
|
||||
* Add mod's dll as reference in your project
|
||||
* Access ragdoll controller with `ml_prm.RagdollController.Instance`
|
||||
|
@ -75,9 +75,3 @@ Available methods:
|
|||
* ```void SwitchRagdoll()```
|
||||
* ```void Ragdoll()```
|
||||
* ```void Unragdoll()```
|
||||
|
||||
# Notes
|
||||
* If ragdoll state is enabled during emote, remote players see whole emote playing while local player sees ragdolling. It's tied to how game handles remote players, currently can be prevented with (choose one):
|
||||
* Renaming avatar emote animations to not have default name or containing `Emote` substring.
|
||||
* Holding any movement key right after activating ragdoll state.
|
||||
* Add transition from `Any state` to state with A-pose/T-pose animation and condition with `Ragdolled` parameter on main avatar's animator layer.
|
||||
|
|
|
@ -26,8 +26,10 @@ namespace ml_prm
|
|||
bool m_applyHipsPosition = false;
|
||||
bool m_applyHipsRotation = false;
|
||||
|
||||
bool m_avatarReady = false;
|
||||
bool m_ragdolled = false;
|
||||
bool m_forcedSwitch = false;
|
||||
Coroutine m_initTask = null;
|
||||
|
||||
Transform m_puppet = null;
|
||||
Transform m_puppetRoot = null;
|
||||
|
@ -36,10 +38,6 @@ namespace ml_prm
|
|||
readonly List<System.Tuple<Transform, Transform>> m_boneLinks = null;
|
||||
readonly List<System.Tuple<CharacterJoint, Vector3>> m_jointAnchors = null;
|
||||
|
||||
bool m_avatarReady = false;
|
||||
Coroutine m_initCoroutine = null;
|
||||
Vector3 m_ragdollLastPos = Vector3.zero;
|
||||
|
||||
RagdollToggle m_avatarRagdollToggle = null; // Custom component available for editor
|
||||
AvatarBoolParameter m_ragdolledParameter = null;
|
||||
PhysicMaterial m_physicsMaterial = null;
|
||||
|
@ -49,6 +47,11 @@ namespace ml_prm
|
|||
float m_groundedTime = 0f;
|
||||
float m_downTime = float.MinValue;
|
||||
|
||||
Vector3 m_lastRagdollPosition;
|
||||
Vector3 m_lastSeatPositon;
|
||||
Vector3 m_seatVelocity;
|
||||
Plane m_playerPlane;
|
||||
|
||||
internal RagdollController()
|
||||
{
|
||||
m_ragdollBodyHandlers = new List<RagdollBodypartHandler>();
|
||||
|
@ -59,10 +62,14 @@ namespace ml_prm
|
|||
// Unity events
|
||||
void Awake()
|
||||
{
|
||||
if((Instance != null) && (Instance != this))
|
||||
Object.Destroy(this);
|
||||
else
|
||||
Instance = this;
|
||||
if(Instance != null)
|
||||
{
|
||||
DestroyImmediate(this);
|
||||
return;
|
||||
}
|
||||
|
||||
Instance = this;
|
||||
DontDestroyOnLoad(this);
|
||||
}
|
||||
|
||||
void Start()
|
||||
|
@ -112,9 +119,9 @@ namespace ml_prm
|
|||
if(Instance == this)
|
||||
Instance = null;
|
||||
|
||||
if(m_initCoroutine != null)
|
||||
StopCoroutine(m_initCoroutine);
|
||||
m_initCoroutine = null;
|
||||
if(m_initTask != null)
|
||||
StopCoroutine(m_initTask);
|
||||
m_initTask = null;
|
||||
|
||||
if(m_puppet != null)
|
||||
Object.Destroy(m_puppet);
|
||||
|
@ -160,7 +167,7 @@ namespace ml_prm
|
|||
{
|
||||
if(m_avatarReady)
|
||||
{
|
||||
if(!m_ragdolled && Settings.FallDamage && !BetterBetterCharacterController.Instance.IsFlying())
|
||||
if(!m_ragdolled && Settings.FallDamage && !BetterBetterCharacterController.Instance.IsFlying() && !BetterBetterCharacterController.Instance.IsSitting())
|
||||
{
|
||||
bool l_grounded = BetterBetterCharacterController.Instance.IsGrounded();
|
||||
bool l_inWater = BetterBetterCharacterController.Instance.IsInWater();
|
||||
|
@ -170,6 +177,17 @@ namespace ml_prm
|
|||
m_inAir = !(l_grounded || l_inWater);
|
||||
}
|
||||
|
||||
if(!m_ragdolled && BetterBetterCharacterController.Instance.IsSitting()) // Those seats without velocity, smh
|
||||
{
|
||||
CVRSeat l_seat = BetterBetterCharacterController.Instance.GetCurrentSeat();
|
||||
if(l_seat != null)
|
||||
{
|
||||
Vector3 l_pos = l_seat.transform.position;
|
||||
m_seatVelocity = (l_pos - m_lastSeatPositon) / Time.deltaTime;
|
||||
m_lastSeatPositon = l_pos;
|
||||
}
|
||||
}
|
||||
|
||||
if(m_ragdolled)
|
||||
{
|
||||
BodySystem.TrackingPositionWeight = 0f;
|
||||
|
@ -178,7 +196,7 @@ namespace ml_prm
|
|||
PlayerSetup.Instance.animatorManager.CancelEmote = true;
|
||||
}
|
||||
|
||||
if(!m_ragdolled && !m_reachedGround && (BetterBetterCharacterController.Instance.IsOnGround() || BetterBetterCharacterController.Instance.IsInWater()))
|
||||
if(!m_ragdolled && !m_reachedGround && (BetterBetterCharacterController.Instance.IsOnGround() || BetterBetterCharacterController.Instance.IsInWater() || BetterBetterCharacterController.Instance.IsSitting()))
|
||||
{
|
||||
m_groundedTime += Time.unscaledDeltaTime;
|
||||
if(m_groundedTime >= 0.25f)
|
||||
|
@ -210,9 +228,18 @@ namespace ml_prm
|
|||
{
|
||||
if(m_avatarReady && m_ragdolled)
|
||||
{
|
||||
Vector3 l_currentPos = m_puppetReferences.hips.position;
|
||||
PlayerSetup.Instance.transform.position += (l_currentPos - m_ragdollLastPos);
|
||||
m_ragdollLastPos = l_currentPos;
|
||||
Vector3 l_diff = m_puppetReferences.hips.position - m_lastRagdollPosition;
|
||||
m_playerPlane.SetNormalAndPosition(PlayerSetup.Instance.transform.rotation * Vector3.up, PlayerSetup.Instance.transform.position);
|
||||
|
||||
PlayerSetup.Instance.transform.position += l_diff;
|
||||
m_lastRagdollPosition = m_puppetReferences.hips.position;
|
||||
|
||||
// Project on plane and fix our position if we under previous plane
|
||||
if(m_playerPlane.GetDistanceToPoint(m_lastRagdollPosition) < 0f)
|
||||
m_playerPlane.Flip();
|
||||
float l_distance = m_playerPlane.GetDistanceToPoint(PlayerSetup.Instance.transform.position);
|
||||
if(l_distance < 0f)
|
||||
PlayerSetup.Instance.transform.position = m_playerPlane.ClosestPointOnPlane(PlayerSetup.Instance.transform.position);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -242,10 +269,10 @@ namespace ml_prm
|
|||
// Game events
|
||||
void OnAvatarClear()
|
||||
{
|
||||
if(m_initCoroutine != null)
|
||||
if(m_initTask != null)
|
||||
{
|
||||
StopCoroutine(m_initCoroutine);
|
||||
m_initCoroutine = null;
|
||||
StopCoroutine(m_initTask);
|
||||
m_initTask = null;
|
||||
}
|
||||
|
||||
if(m_ragdolled)
|
||||
|
@ -365,7 +392,7 @@ namespace ml_prm
|
|||
m_avatarRagdollToggle = PlayerSetup.Instance._avatar.GetComponentInChildren<RagdollToggle>(true);
|
||||
m_ragdolledParameter = new AvatarBoolParameter("Ragdolled", PlayerSetup.Instance.animatorManager);
|
||||
|
||||
m_initCoroutine = StartCoroutine(WaitForBodyHandlers());
|
||||
m_initTask = StartCoroutine(WaitForBodyHandlers());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -381,7 +408,7 @@ namespace ml_prm
|
|||
}
|
||||
|
||||
m_avatarReady = true;
|
||||
m_initCoroutine = null;
|
||||
m_initTask = null;
|
||||
|
||||
OnMovementDragChanged(Settings.MovementDrag);
|
||||
OnAngularDragChanged(Settings.AngularDrag);
|
||||
|
@ -414,6 +441,8 @@ namespace ml_prm
|
|||
|
||||
void OnSeatPreSit(CVRSeat p_seat)
|
||||
{
|
||||
m_lastSeatPositon = p_seat.transform.position;
|
||||
|
||||
if(!p_seat.occupied)
|
||||
{
|
||||
m_forcedSwitch = true;
|
||||
|
@ -473,9 +502,8 @@ namespace ml_prm
|
|||
|
||||
if(m_avatarReady && m_ragdolled)
|
||||
{
|
||||
Vector3 l_pos = m_hips.position;
|
||||
m_puppetReferences.hips.position = l_pos;
|
||||
m_ragdollLastPos = l_pos;
|
||||
m_puppetReferences.hips.position = m_hips.position;
|
||||
m_lastRagdollPosition = m_puppetReferences.hips.position;
|
||||
}
|
||||
}
|
||||
catch(System.Exception e)
|
||||
|
@ -600,7 +628,7 @@ namespace ml_prm
|
|||
|
||||
void OnGestureGrabChanged(bool p_state)
|
||||
{
|
||||
if(m_avatarReady && m_ragdolled & !p_state)
|
||||
if(m_avatarReady && m_ragdolled && !p_state)
|
||||
{
|
||||
foreach(var l_hanlder in m_ragdollBodyHandlers)
|
||||
l_hanlder.Detach();
|
||||
|
@ -622,13 +650,24 @@ namespace ml_prm
|
|||
{
|
||||
if(m_avatarReady && !m_ragdolled && CanRagdoll())
|
||||
{
|
||||
Vector3 l_velocity = Vector3.ClampMagnitude(BetterBetterCharacterController.Instance.velocity * (WorldManager.IsSafeWorld() ? Settings.VelocityMultiplier : 1f), WorldManager.GetMovementLimit());
|
||||
Vector3 l_velocity = (BetterBetterCharacterController.Instance.IsSitting() ? m_seatVelocity : BetterBetterCharacterController.Instance.velocity);
|
||||
l_velocity *= (WorldManager.IsSafeWorld() ? Settings.VelocityMultiplier : 1f);
|
||||
l_velocity = Vector3.ClampMagnitude(l_velocity, WorldManager.GetMovementLimit());
|
||||
if(Settings.ViewVelocity && WorldManager.IsSafeWorld())
|
||||
{
|
||||
float l_mag = l_velocity.magnitude;
|
||||
l_velocity = PlayerSetup.Instance.GetActiveCamera().transform.forward * l_mag;
|
||||
}
|
||||
|
||||
Vector3 l_playerPos = PlayerSetup.Instance.transform.position;
|
||||
Quaternion l_playerRot = PlayerSetup.Instance.transform.rotation;
|
||||
bool l_wasSitting = BetterBetterCharacterController.Instance.IsSitting();
|
||||
if(BetterBetterCharacterController.Instance.IsSitting())
|
||||
{
|
||||
BetterBetterCharacterController.Instance.SetSitting(false);
|
||||
l_wasSitting = true;
|
||||
}
|
||||
|
||||
if(BetterBetterCharacterController.Instance.IsFlying())
|
||||
BetterBetterCharacterController.Instance.ChangeFlight(false, true);
|
||||
BetterBetterCharacterController.Instance.SetImmobilized(true);
|
||||
|
@ -662,7 +701,12 @@ namespace ml_prm
|
|||
l_handler.SetAngularVelocity(Vector3.zero);
|
||||
}
|
||||
|
||||
m_ragdollLastPos = m_puppetReferences.hips.position;
|
||||
if(l_wasSitting)
|
||||
{
|
||||
PlayerSetup.Instance.transform.position = l_playerPos;
|
||||
PlayerSetup.Instance.transform.rotation = l_playerRot;
|
||||
}
|
||||
m_lastRagdollPosition = m_puppetReferences.hips.position;
|
||||
m_downTime = 0f;
|
||||
|
||||
m_ragdolled = true;
|
||||
|
@ -675,12 +719,6 @@ namespace ml_prm
|
|||
{
|
||||
BetterBetterCharacterController.Instance.TeleportPlayerTo(m_puppetReferences.hips.position, PlayerSetup.Instance.GetPlayerRotation().eulerAngles, false, false);
|
||||
TryRestoreMovement();
|
||||
if(!WorldManager.IsSafeWorld())
|
||||
{
|
||||
Vector3 l_vec = BetterBetterCharacterController.Instance.GetVelocity();
|
||||
l_vec.y = Mathf.Clamp(l_vec.y, float.MinValue, 0f);
|
||||
BetterBetterCharacterController.Instance.SetVelocity(l_vec);
|
||||
}
|
||||
BodySystem.TrackingPositionWeight = 1f;
|
||||
IKSystem.Instance.applyOriginalHipPosition = m_applyHipsPosition;
|
||||
IKSystem.Instance.applyOriginalHipRotation = m_applyHipsRotation;
|
||||
|
@ -725,7 +763,6 @@ namespace ml_prm
|
|||
|
||||
bool l_result = m_reachedGround;
|
||||
l_result &= !BodySystem.isCalibrating;
|
||||
l_result &= !BetterBetterCharacterController.Instance.IsSitting();
|
||||
l_result &= ((CombatSystem.Instance == null) || !CombatSystem.Instance.isDown);
|
||||
return (l_result || m_forcedSwitch);
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ namespace ml_prm
|
|||
public void RemoveListener(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, GestureHand, bool> OnGestureState = new GestureEvent<PuppetMaster, GestureHand, bool>();
|
||||
|
||||
class PlayerEntry
|
||||
|
@ -32,6 +33,8 @@ namespace ml_prm
|
|||
public bool m_stateRight = false;
|
||||
}
|
||||
|
||||
static RemoteGesturesManager ms_instance = null;
|
||||
|
||||
readonly List<PlayerEntry> m_entries = null;
|
||||
|
||||
internal RemoteGesturesManager()
|
||||
|
@ -39,10 +42,20 @@ namespace ml_prm
|
|||
m_entries = new List<PlayerEntry>();
|
||||
}
|
||||
|
||||
void Awake()
|
||||
{
|
||||
if(ms_instance != null)
|
||||
{
|
||||
DestroyImmediate(this);
|
||||
return;
|
||||
}
|
||||
|
||||
ms_instance = this;
|
||||
DontDestroyOnLoad(this);
|
||||
}
|
||||
|
||||
void Start()
|
||||
{
|
||||
DontDestroyOnLoad(this);
|
||||
|
||||
CVRGameEventSystem.Player.OnJoinEntity.AddListener(OnRemotePlayerCreated);
|
||||
CVRGameEventSystem.Player.OnLeaveEntity.AddListener(OnRemotePlayerDestroyed);
|
||||
Settings.OnGestureGrabChanged.AddListener(OnGestureGrabChanged);
|
||||
|
@ -50,6 +63,9 @@ namespace ml_prm
|
|||
|
||||
void OnDestroy()
|
||||
{
|
||||
if(ms_instance == this)
|
||||
ms_instance = null;
|
||||
|
||||
m_entries.Clear();
|
||||
|
||||
CVRGameEventSystem.Player.OnJoinEntity.RemoveListener(OnRemotePlayerCreated);
|
||||
|
|
|
@ -8,6 +8,7 @@ using System.Reflection;
|
|||
using UnityEngine;
|
||||
using System.Linq;
|
||||
using ABI_RC.Systems.IK.SubSystems;
|
||||
using ABI_RC.Core.InteractionSystem;
|
||||
|
||||
namespace ml_prm
|
||||
{
|
||||
|
@ -17,6 +18,7 @@ namespace ml_prm
|
|||
static readonly FieldInfo ms_referencePoints = typeof(PhysicsInfluencer).GetField("_referencePoints", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
static readonly FieldInfo ms_influencerTouchingVolumes = typeof(PhysicsInfluencer).GetField("_touchingVolumes", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
static readonly FieldInfo ms_influencerSubmergedColliders = typeof(PhysicsInfluencer).GetField("_submergedColliders", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
static readonly FieldInfo ms_lastCVRSeat = typeof(BetterBetterCharacterController).GetField("_lastCvrSeat", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
|
||||
public static void ClearFluidVolumes(this BetterBetterCharacterController p_instance) => (ms_touchingVolumes.GetValue(p_instance) as List<FluidVolume>)?.Clear();
|
||||
|
||||
|
@ -58,5 +60,9 @@ namespace ml_prm
|
|||
l_result |= ((FingerSystem.GetCurlNormalized(p_source._playerAvatarMovementDataCurrent.RightMiddle1Stretched) >= 0.5f) && (FingerSystem.GetCurlNormalized(p_source._playerAvatarMovementDataCurrent.RightMiddle2Stretched) >= 0.5f) && (FingerSystem.GetCurlNormalized(p_source._playerAvatarMovementDataCurrent.RightMiddle3Stretched) >= 0.5f));
|
||||
return l_result;
|
||||
}
|
||||
|
||||
public static CVRSeat GetCurrentSeat(this BetterBetterCharacterController p_instance) => (ms_lastCVRSeat?.GetValue(p_instance) as CVRSeat);
|
||||
|
||||
public static bool IsInRange(float p_value, float p_min, float p_max) => ((p_min <= p_value) && (p_value <= p_max));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using ABI.CCK.Components;
|
||||
using ABI_RC.Systems.GameEventSystem;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ml_prm
|
||||
|
@ -22,18 +23,25 @@ namespace ml_prm
|
|||
|
||||
static void OnWorldLoad(string p_id)
|
||||
{
|
||||
ms_safeWorld = ((CVRWorld.Instance != null) && CVRWorld.Instance.allowFlying);
|
||||
ms_movementLimit = 1f;
|
||||
|
||||
GameObject l_restrictObj = GameObject.Find("[RagdollRestriction]");
|
||||
ms_restrictedWorld = ((l_restrictObj == null) ? false : (l_restrictObj.scene.name != "DontDestroyOnLoad"));
|
||||
|
||||
if(CVRWorld.Instance != null)
|
||||
try
|
||||
{
|
||||
ms_movementLimit = CVRWorld.Instance.baseMovementSpeed;
|
||||
ms_movementLimit *= CVRWorld.Instance.sprintMultiplier;
|
||||
ms_movementLimit *= CVRWorld.Instance.inAirMovementMultiplier;
|
||||
ms_movementLimit *= CVRWorld.Instance.flyMultiplier;
|
||||
ms_safeWorld = ((CVRWorld.Instance != null) && CVRWorld.Instance.allowFlying);
|
||||
ms_movementLimit = 1f;
|
||||
|
||||
GameObject l_restrictObj = GameObject.Find("[RagdollRestriction]");
|
||||
ms_restrictedWorld = ((l_restrictObj == null) ? false : (l_restrictObj.scene.name != "DontDestroyOnLoad"));
|
||||
|
||||
if(CVRWorld.Instance != null)
|
||||
{
|
||||
ms_movementLimit = CVRWorld.Instance.baseMovementSpeed;
|
||||
ms_movementLimit *= CVRWorld.Instance.sprintMultiplier;
|
||||
ms_movementLimit *= CVRWorld.Instance.inAirMovementMultiplier;
|
||||
ms_movementLimit *= CVRWorld.Instance.flyMultiplier;
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
MelonLoader.MelonLogger.Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue