It begins.

This commit is contained in:
JohnCorby 2021-11-13 03:40:02 -08:00
parent 53bf6097fe
commit 8e7ff076bf
3 changed files with 213 additions and 21 deletions

View File

@ -1,6 +1,9 @@
using QSB.Events;
using System.Linq;
using QSB.Events;
using QSB.MeteorSync.WorldObjects;
using QSB.Utility;
using QSB.WorldSync;
using UnityEngine;
using EventType = QSB.Events.EventType;
namespace QSB.MeteorSync.Events
@ -11,32 +14,135 @@ namespace QSB.MeteorSync.Events
public override EventType Type => EventType.MeteorResync;
public override void SetupListener()
=> GlobalMessenger<QSBMeteor>.AddListener(EventNames.QSBMeteorResync, Handler);
=> GlobalMessenger.AddListener(EventNames.QSBMeteorResync, Handler);
public override void CloseListener()
=> GlobalMessenger<QSBMeteor>.RemoveListener(EventNames.QSBMeteorResync, Handler);
=> GlobalMessenger.RemoveListener(EventNames.QSBMeteorResync, Handler);
private void Handler(QSBMeteor qsbMeteor) => SendEvent(CreateMessage(qsbMeteor));
private void Handler() => SendEvent(CreateMessage());
private MeteorResyncMessage CreateMessage(QSBMeteor qsbMeteor) => new MeteorResyncMessage
private MeteorResyncMessage CreateMessage()
{
ObjectId = qsbMeteor.ObjectId
// todo pos/rot/vel/angvel
// todo is suspended/launched
// todo fragment states
};
var qsbMeteors = QSBWorldSync.GetWorldObjects<QSBMeteor>().ToArray();
var fragments = QSBWorldSync.GetUnityObjects<FragmentIntegrity>().ToArray();
public override void OnReceiveRemote(bool isHost, MeteorResyncMessage message)
var msg = new MeteorResyncMessage
{
Suspended = new bool[qsbMeteors.Length],
Damage = new float[qsbMeteors.Length],
MeteorTransforms = new MeteorResyncMessage.TransformMessage[qsbMeteors.Length],
Integrity = new float[fragments.Length],
FragmentTransforms = new MeteorResyncMessage.TransformMessage[fragments.Length]
};
var refBody = Locator._brittleHollow.GetOWRigidbody();
for (var i = 0; i < qsbMeteors.Length; i++)
{
msg.Suspended[i] = qsbMeteors[i].AttachedObject.isSuspended;
msg.Damage[i] = qsbMeteors[i].Damage;
var body = qsbMeteors[i].AttachedObject.owRigidbody;
msg.MeteorTransforms[i] = new MeteorResyncMessage.TransformMessage
{
pos = refBody.transform.InverseTransformPoint(body.transform.position),
rot = refBody.transform.InverseTransformRotation(body.transform.rotation),
vel = GetRelativeVelocity(body, refBody),
angVel = body.GetRelativeAngularVelocity(refBody)
};
}
for (var i = 0; i < fragments.Length; i++)
{
msg.Integrity[i] = fragments[i].GetIntegrity();
var body = fragments[i].GetAttachedOWRigidbody();
msg.FragmentTransforms[i] = new MeteorResyncMessage.TransformMessage
{
pos = refBody.transform.InverseTransformPoint(body.transform.position),
rot = refBody.transform.InverseTransformRotation(body.transform.rotation),
vel = GetRelativeVelocity(body, refBody),
angVel = body.GetRelativeAngularVelocity(refBody)
};
}
return msg;
}
public override void OnReceiveRemote(bool isHost, MeteorResyncMessage msg)
{
if (!MeteorManager.MeteorsReady)
{
return;
}
var qsbMeteor = QSBWorldSync.GetWorldFromId<QSBMeteor>(message.ObjectId);
// todo
var qsbMeteors = QSBWorldSync.GetWorldObjects<QSBMeteor>().ToArray();
var fragments = QSBWorldSync.GetUnityObjects<FragmentIntegrity>().ToArray();
// DebugLog.DebugWrite($"{qsbMeteor.LogName} - resync requested");
var refBody = Locator._brittleHollow.GetOWRigidbody();
for (var i = 0; i < qsbMeteors.Length; i++)
{
if (!msg.Suspended[i] && qsbMeteors[i].AttachedObject.isSuspended)
{
// todo
DebugLog.DebugWrite($"{qsbMeteors[i].LogName} - TODO unsuspend");
}
else if (msg.Suspended[i] && !qsbMeteors[i].AttachedObject.isSuspended)
{
// todo
DebugLog.DebugWrite($"{qsbMeteors[i].LogName} - TODO suspend");
}
qsbMeteors[i].Damage = msg.Damage[i];
var body = qsbMeteors[i].AttachedObject.owRigidbody;
var targetPos = refBody.transform.TransformPoint(msg.MeteorTransforms[i].pos);
var targetRot = refBody.transform.TransformRotation(msg.MeteorTransforms[i].rot);
var targetVel = refBody.GetPointVelocity(targetPos) + msg.MeteorTransforms[i].vel;
var targetAngVel = refBody.GetAngularVelocity() + msg.MeteorTransforms[i].angVel;
body.MoveToPosition(targetPos);
body.MoveToRotation(targetRot);
SetVelocity(body, targetVel);
body.SetAngularVelocity(targetAngVel);
}
for (var i = 0; i < fragments.Length; i++)
{
fragments[i]._integrity = 0;
fragments[i].AddDamage(fragments[i]._origIntegrity - msg.Integrity[i]);
var body = fragments[i].GetAttachedOWRigidbody();
var targetPos = refBody.transform.TransformPoint(msg.FragmentTransforms[i].pos);
var targetRot = refBody.transform.TransformRotation(msg.FragmentTransforms[i].rot);
var targetVel = refBody.GetPointVelocity(targetPos) + msg.FragmentTransforms[i].vel;
var targetAngVel = refBody.GetAngularVelocity() + msg.FragmentTransforms[i].angVel;
body.MoveToPosition(targetPos);
body.MoveToRotation(targetRot);
SetVelocity(body, targetVel);
body.SetAngularVelocity(targetAngVel);
}
DebugLog.DebugWrite($"METEOR RESYNC REQUESTED - synced {qsbMeteors.Length} meteors and {fragments.Length} fragments");
}
// code yoink from transform sync lol
private static void SetVelocity(OWRigidbody rigidbody, Vector3 relativeVelocity)
{
var isRunningKinematic = rigidbody.RunningKinematicSimulation();
var currentVelocity = rigidbody._currentVelocity;
if (isRunningKinematic)
{
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);
}
}

View File

@ -1,22 +1,109 @@
using QSB.WorldSync.Events;
using QSB.Messaging;
using QuantumUNET.Messages;
using QuantumUNET.Transport;
using UnityEngine;
namespace QSB.MeteorSync.Events
{
public class MeteorResyncMessage : WorldObjectMessage
/// this will be the best and worst thing you've seen outta me :D
public class MeteorResyncMessage : PlayerMessage
{
public float Damage;
public bool[] Suspended;
public float[] Damage;
public TransformMessage[] MeteorTransforms;
public float[] Integrity;
public TransformMessage[] FragmentTransforms;
public override void Deserialize(QNetworkReader reader)
{
base.Deserialize(reader);
Damage = reader.ReadSingle();
Suspended = new bool[reader.ReadInt32()];
for (var i = 0; i < Suspended.Length; i++)
{
Suspended[i] = reader.ReadBoolean();
}
Damage = new float[reader.ReadInt32()];
for (var i = 0; i < Damage.Length; i++)
{
Damage[i] = reader.ReadSingle();
}
MeteorTransforms = new TransformMessage[reader.ReadInt32()];
for (var i = 0; i < MeteorTransforms.Length; i++)
{
MeteorTransforms[i] = reader.ReadMessage<TransformMessage>();
}
Integrity = new float[reader.ReadInt32()];
for (var i = 0; i < Integrity.Length; i++)
{
Integrity[i] = reader.ReadSingle();
}
FragmentTransforms = new TransformMessage[reader.ReadInt32()];
for (var i = 0; i < FragmentTransforms.Length; i++)
{
FragmentTransforms[i] = reader.ReadMessage<TransformMessage>();
}
}
public override void Serialize(QNetworkWriter writer)
{
base.Serialize(writer);
writer.Write(Damage);
writer.Write(Suspended.Length);
foreach (var x in Suspended)
{
writer.Write(x);
}
writer.Write(Damage.Length);
foreach (var x in Damage)
{
writer.Write(x);
}
writer.Write(MeteorTransforms.Length);
foreach (var x in MeteorTransforms)
{
writer.Write(x);
}
writer.Write(Integrity.Length);
foreach (var x in Integrity)
{
writer.Write(x);
}
writer.Write(FragmentTransforms.Length);
foreach (var x in FragmentTransforms)
{
writer.Write(x);
}
}
public class TransformMessage : QMessageBase
{
public Vector3 pos;
public Quaternion rot;
public Vector3 vel;
public Vector3 angVel;
public override void Deserialize(QNetworkReader reader)
{
base.Deserialize(reader);
pos = reader.ReadVector3();
rot = reader.ReadQuaternion();
vel = reader.ReadVector3();
angVel = reader.ReadVector3();
}
public override void Serialize(QNetworkWriter writer)
{
base.Serialize(writer);
writer.Write(pos);
writer.Write(rot);
writer.Write(vel);
writer.Write(angVel);
}
}
}
}

View File

@ -81,8 +81,7 @@ namespace QSB.Player.Events
QSBWorldSync.GetWorldObjects<QSBCampfire>().ForEach(campfire
=> QSBEventManager.FireEvent(EventNames.QSBCampfireState, campfire.ObjectId, campfire.GetState()));
QSBWorldSync.GetWorldObjects<QSBMeteor>().ForEach(meteor
=> QSBEventManager.FireEvent(EventNames.QSBMeteorResync, meteor));
QSBEventManager.FireEvent(EventNames.QSBMeteorResync);
}
}
}