quantum-space-buddies/QSB/MeteorSync/Events/FragmentResyncEvent.cs

121 lines
4.1 KiB
C#
Raw Normal View History

2021-11-14 03:29:58 -08:00
using System;
2021-11-15 00:29:36 -08:00
using OWML.Common;
2021-11-14 03:29:58 -08:00
using QSB.Events;
2021-11-13 20:41:46 -08:00
using QSB.MeteorSync.WorldObjects;
2021-11-14 03:29:58 -08:00
using QSB.Utility;
2021-11-13 20:41:46 -08:00
using QSB.WorldSync;
2021-11-14 03:29:58 -08:00
using UnityEngine;
using EventType = QSB.Events.EventType;
2021-11-13 20:41:46 -08:00
namespace QSB.MeteorSync.Events
{
/// called when we request a resync on client join
2021-11-14 03:29:58 -08:00
/// pain
2021-11-13 20:41:46 -08:00
public class FragmentResyncEvent : QSBEvent<FragmentResyncMessage>
{
public override EventType Type => EventType.FragmentResync;
public override void SetupListener()
=> GlobalMessenger<QSBFragment>.AddListener(EventNames.QSBFragmentResync, Handler);
public override void CloseListener()
=> GlobalMessenger<QSBFragment>.RemoveListener(EventNames.QSBFragmentResync, Handler);
private void Handler(QSBFragment qsbFragment) => SendEvent(CreateMessage(qsbFragment));
private FragmentResyncMessage CreateMessage(QSBFragment qsbFragment)
{
var msg = new FragmentResyncMessage
{
ObjectId = qsbFragment.ObjectId,
Integrity = qsbFragment.AttachedObject._integrity,
2021-11-15 18:05:34 -08:00
OrigIntegrity = qsbFragment.AttachedObject._origIntegrity,
LeashLength = qsbFragment.LeashLength
2021-11-13 20:41:46 -08:00
};
2021-11-14 03:29:58 -08:00
if (msg.Integrity <= 0)
{
2021-11-15 00:29:36 -08:00
msg.IsThruWhiteHole = qsbFragment.IsThruWhiteHole;
2021-11-14 03:29:58 -08:00
var refBody = qsbFragment.RefBody;
var body = qsbFragment.Body;
2021-11-14 03:29:58 -08:00
msg.Pos = refBody.transform.InverseTransformPoint(body.transform.position);
msg.Rot = refBody.transform.InverseTransformRotation(body.transform.rotation);
msg.Vel = GetRelativeVelocity(body, refBody);
msg.AngVel = body.GetRelativeAngularVelocity(refBody);
}
2021-11-13 20:41:46 -08:00
return msg;
}
public override void OnReceiveRemote(bool isHost, FragmentResyncMessage msg)
{
if (!MeteorManager.Ready)
2021-11-13 20:41:46 -08:00
{
return;
}
var qsbFragment = QSBWorldSync.GetWorldFromId<QSBFragment>(msg.ObjectId);
qsbFragment.AttachedObject._integrity = msg.Integrity;
qsbFragment.AttachedObject._origIntegrity = msg.OrigIntegrity;
2021-11-15 18:05:34 -08:00
qsbFragment.LeashLength = msg.LeashLength;
qsbFragment.AttachedObject.CallOnTakeDamage();
2021-11-14 03:29:58 -08:00
if (msg.Integrity <= 0)
{
// the detach is delayed, so wait even more until that happens lol
2021-11-14 03:29:58 -08:00
QSBCore.UnityEvents.FireInNUpdates(() =>
{
2021-11-15 00:29:36 -08:00
if (msg.IsThruWhiteHole && !qsbFragment.IsThruWhiteHole)
2021-11-14 03:29:58 -08:00
{
2021-11-15 00:29:36 -08:00
qsbFragment.DetachableFragment.ChangeFragmentSector(MeteorManager.WhiteHoleVolume._whiteHoleSector,
2021-11-14 03:29:58 -08:00
MeteorManager.WhiteHoleVolume._whiteHoleProxyShadowSuperGroup);
qsbFragment.DetachableFragment.EndWarpScaling();
qsbFragment.Body.gameObject.AddComponent<DebrisLeash>()
.Init(MeteorManager.WhiteHoleVolume._whiteHoleBody, qsbFragment.LeashLength);
2021-11-15 00:29:36 -08:00
}
else if (!msg.IsThruWhiteHole && qsbFragment.IsThruWhiteHole)
{
// should only happen if client is way too far ahead and they try to connect. we fail here.
DebugLog.ToConsole($"{qsbFragment.LogName} is thru white hole, but msg is not. goodbye", MessageType.Quit);
Application.Quit();
}
2021-11-14 03:29:58 -08:00
var refBody = qsbFragment.RefBody;
2021-11-15 02:39:06 -08:00
var body = qsbFragment.Body;
2021-11-14 03:29:58 -08:00
var targetPos = refBody.transform.TransformPoint(msg.Pos);
var targetRot = refBody.transform.TransformRotation(msg.Rot);
var targetVel = refBody.GetPointVelocity(targetPos) + msg.Vel;
var targetAngVel = refBody.GetAngularVelocity() + msg.AngVel;
body.MoveToPosition(targetPos);
body.MoveToRotation(targetRot);
SetVelocity(body, targetVel);
body.SetAngularVelocity(targetAngVel);
}, 20);
}
2021-11-13 20:41:46 -08:00
}
2021-11-14 03:29:58 -08:00
// code yoink from transform sync lol
private static void SetVelocity(OWRigidbody rigidbody, Vector3 relativeVelocity)
{
var currentVelocity = rigidbody._currentVelocity;
2021-11-15 00:29:36 -08:00
if (rigidbody.RunningKinematicSimulation())
2021-11-14 03:29:58 -08:00
{
rigidbody._kinematicRigidbody.velocity = relativeVelocity + Locator.GetCenterOfTheUniverse().GetStaticFrameVelocity_Internal();
}
else
{
rigidbody._rigidbody.velocity = relativeVelocity + Locator.GetCenterOfTheUniverse().GetStaticFrameVelocity_Internal();
}
rigidbody._lastVelocity = currentVelocity;
rigidbody._currentVelocity = relativeVelocity;
}
private static Vector3 GetRelativeVelocity(OWRigidbody body, OWRigidbody refBody)
=> body.GetVelocity() - refBody.GetPointVelocity(body.transform.position);
2021-11-13 20:41:46 -08:00
}
}