Files
BoneSync/BoneSync/Sync/Components/SyncablePhysics.cs
2025-03-07 16:42:45 +02:00

173 lines
5.6 KiB
C#

using BoneSync.Data;
using BoneSync.Networking;
using BoneSync.Networking.Messages;
using BoneSync.Patching;
using Facepunch.Steamworks;
using MelonLoader;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.Events;
namespace BoneSync.Sync.Components
{
public partial class Syncable : MonoBehaviour
{
private bool pullDevicePatched = false;
void DeviceOnPull()
{
MelonLogger.Msg("OnPull");
if (!isOwner) { return; }
_SendSimpleEvent(SimpleEventType.OnDevicePull);
}
void DeviceOnRelease()
{
MelonLogger.Msg("OnRelease");
if (!isOwner) { return; }
_SendSimpleEvent(SimpleEventType.OnDeviceRelease);
}
private void _TryPatchPullDevice()
{
if (pullDevicePatched) return;
if (!pullDevice) return;
pullDevice.OnHandlePull.AddListener((UnityAction)DeviceOnPull);
pullDevice.OnHandleReturn.AddListener((UnityAction)DeviceOnRelease);
pullDevicePatched = true;
}
public bool AllRigidbodiesSleeping()
{
if (rigidbodies.Length == 0) return false;
foreach (Rigidbody rb in rigidbodies)
{
try
{
if (!rb.IsSleeping()) return false;
}
catch { } // ignore null rigidbodies
}
return true;
}
private void _SetKinematic(bool kinematic)
{
if (rigidbodies.Length == 0) return;
foreach (Rigidbody rb in rigidbodies)
{
try
{
rb.isKinematic = kinematic;
}
catch { } // ignore null rigidbodies
}
}
private void SetKinematic(bool kinematic)
{
if (!this) return;
try
{
_SetKinematic(kinematic);
}
catch {
MelonLogger.Warning("Failed to set kinematic");
}
}
public ObjectSyncTransform[] GetObjectSyncTransforms()
{
ObjectSyncTransform[] objectSyncTransforms = new ObjectSyncTransform[rigidbodies.Length];
for (int i = 0; i < _transforms.Length; i++)
{
objectSyncTransforms[i] = new ObjectSyncTransform()
{
transform = new SimpleSyncTransform(_transforms[i]),
velocity = Vector3.zero
};
}
return objectSyncTransforms;
}
public void ApplyObjectSyncTransforms(ObjectSyncTransform[] objectSyncTransforms)
{
if (IsPlugged()) { return; }
if (objectSyncTransforms.Length != rigidbodies.Length)
{
MelonLogger.Warning("ObjectSyncTransforms length mismatch: " + objectSyncTransforms.Length + " != " + _transforms.Length);
return;
}
for (int i = 0; i < objectSyncTransforms.Length; i++)
{
ObjectSyncTransform objectSyncTransform = objectSyncTransforms[i];
rigidbodies[i].angularVelocity = objectSyncTransform.angularVelocity;
rigidbodies[i].velocity = objectSyncTransform.velocity;
rigidbodies[i].position = objectSyncTransform.transform.position;
rigidbodies[i].rotation = objectSyncTransform.transform.rotation;
_transforms[i].localScale = objectSyncTransform.transform.scale;
//_transforms[i].ApplySimpleTransform(objectSyncTransform.transform);
}
}
private Syncable GetRigidbodySyncable(Rigidbody rigidbody)
{
if (rigidbody == null) return null;
return rigidbody.GetComponentInParent<Syncable>();
}
private bool RigidbodyBelongsToSyncable(Rigidbody rigidbody)
{
return GetRigidbodySyncable(rigidbody) == this;
}
private Rigidbody[] GetRigidbodies()
{
if (interactableManager)
{
return interactableManager.hosts.Select(host => host.rb).ToArray();
}
if (interactableHost)
{
return new Rigidbody[] { interactableHost.rb };
}
if (poolee)
{
return new Rigidbody[] { poolee.GetComponentInChildren<Rigidbody>(true) };
}
return new Rigidbody[0];
}
private void UpdateTransformList()
{
// get non-null rigidbodies
Rigidbody[] rbs = GetRigidbodies().Where(rb => rb != null).ToArray();
rigidbodies = rbs;
_transforms = rbs.Select(rb => rb.transform).ToArray();
}
private void UpdateKinematic()
{
//SetKinematic(false);
SetKinematic(_ownerId != BoneSync.lobby.GetLocalId() && Registered && !IsPlugged());
}
internal void OnSimpleSyncableEvent(SimpleSyncableEvent eventData)
{
MelonLogger.Msg("OnSimpleSyncableEvent: " + eventData.eventType);
SimpleEventType eType = eventData.eventType;
switch (eType) {
case SimpleEventType.OnDevicePull:
pullDevice?.OnHandlePull?.Invoke();
break;
case SimpleEventType.OnDeviceRelease:
pullDevice?.OnHandleReturn?.Invoke();
break;
}
}
// on collision
}
}