mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2024-12-22 21:43:35 +00:00
Fix vehicle serialization during races (#1122)
* Fix vehicle serialization during races - Add missing frame stats reading - correct the inversion of rotation - correct serialization order - use proper dirty flags Tested that racers are no longer sideways on certain vertical slopes and stay in sync throughout the whole race. * Update ClientPackets.cpp * Update ClientPackets.cpp * Update VehiclePhysicsComponent.h
This commit is contained in:
parent
2d31b7e4bb
commit
132d31d3ab
@ -19,34 +19,47 @@ VehiclePhysicsComponent::~VehiclePhysicsComponent() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void VehiclePhysicsComponent::SetPosition(const NiPoint3& pos) {
|
void VehiclePhysicsComponent::SetPosition(const NiPoint3& pos) {
|
||||||
|
if (pos == m_Position) return;
|
||||||
|
m_DirtyPosition = true;
|
||||||
m_Position = pos;
|
m_Position = pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VehiclePhysicsComponent::SetRotation(const NiQuaternion& rot) {
|
void VehiclePhysicsComponent::SetRotation(const NiQuaternion& rot) {
|
||||||
|
if (rot == m_Rotation) return;
|
||||||
m_DirtyPosition = true;
|
m_DirtyPosition = true;
|
||||||
m_Rotation = rot;
|
m_Rotation = rot;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VehiclePhysicsComponent::SetVelocity(const NiPoint3& vel) {
|
void VehiclePhysicsComponent::SetVelocity(const NiPoint3& vel) {
|
||||||
|
if (vel == m_Velocity) return;
|
||||||
m_DirtyPosition = true;
|
m_DirtyPosition = true;
|
||||||
m_Velocity = vel;
|
m_Velocity = vel;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VehiclePhysicsComponent::SetAngularVelocity(const NiPoint3& vel) {
|
void VehiclePhysicsComponent::SetAngularVelocity(const NiPoint3& vel) {
|
||||||
|
if (vel == m_AngularVelocity) return;
|
||||||
m_DirtyPosition = true;
|
m_DirtyPosition = true;
|
||||||
m_AngularVelocity = vel;
|
m_AngularVelocity = vel;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VehiclePhysicsComponent::SetIsOnGround(bool val) {
|
void VehiclePhysicsComponent::SetIsOnGround(bool val) {
|
||||||
|
if (val == m_IsOnGround) return;
|
||||||
m_DirtyPosition = true;
|
m_DirtyPosition = true;
|
||||||
m_IsOnGround = val;
|
m_IsOnGround = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VehiclePhysicsComponent::SetIsOnRail(bool val) {
|
void VehiclePhysicsComponent::SetIsOnRail(bool val) {
|
||||||
|
if (val == m_IsOnRail) return;
|
||||||
m_DirtyPosition = true;
|
m_DirtyPosition = true;
|
||||||
m_IsOnRail = val;
|
m_IsOnRail = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VehiclePhysicsComponent::SetRemoteInputInfo(const RemoteInputInfo& remoteInputInfo) {
|
||||||
|
if (m_RemoteInputInfo == remoteInputInfo) return;
|
||||||
|
this->m_RemoteInputInfo = remoteInputInfo;
|
||||||
|
m_DirtyRemoteInput = true;
|
||||||
|
}
|
||||||
|
|
||||||
void VehiclePhysicsComponent::SetDirtyPosition(bool val) {
|
void VehiclePhysicsComponent::SetDirtyPosition(bool val) {
|
||||||
m_DirtyPosition = val;
|
m_DirtyPosition = val;
|
||||||
}
|
}
|
||||||
@ -63,9 +76,15 @@ void VehiclePhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bI
|
|||||||
outBitStream->Write(bIsInitialUpdate || m_DirtyPosition);
|
outBitStream->Write(bIsInitialUpdate || m_DirtyPosition);
|
||||||
|
|
||||||
if (bIsInitialUpdate || m_DirtyPosition) {
|
if (bIsInitialUpdate || m_DirtyPosition) {
|
||||||
outBitStream->Write(m_Position);
|
m_DirtyPosition = false;
|
||||||
|
outBitStream->Write(m_Position.x);
|
||||||
|
outBitStream->Write(m_Position.y);
|
||||||
|
outBitStream->Write(m_Position.z);
|
||||||
|
|
||||||
outBitStream->Write(m_Rotation);
|
outBitStream->Write(m_Rotation.x);
|
||||||
|
outBitStream->Write(m_Rotation.y);
|
||||||
|
outBitStream->Write(m_Rotation.z);
|
||||||
|
outBitStream->Write(m_Rotation.w);
|
||||||
|
|
||||||
outBitStream->Write(m_IsOnGround);
|
outBitStream->Write(m_IsOnGround);
|
||||||
outBitStream->Write(m_IsOnRail);
|
outBitStream->Write(m_IsOnRail);
|
||||||
@ -73,20 +92,33 @@ void VehiclePhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bI
|
|||||||
outBitStream->Write(bIsInitialUpdate || m_DirtyVelocity);
|
outBitStream->Write(bIsInitialUpdate || m_DirtyVelocity);
|
||||||
|
|
||||||
if (bIsInitialUpdate || m_DirtyVelocity) {
|
if (bIsInitialUpdate || m_DirtyVelocity) {
|
||||||
outBitStream->Write(m_Velocity);
|
outBitStream->Write(m_Velocity.x);
|
||||||
|
outBitStream->Write(m_Velocity.y);
|
||||||
|
outBitStream->Write(m_Velocity.z);
|
||||||
|
m_DirtyVelocity = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
outBitStream->Write(bIsInitialUpdate || m_DirtyAngularVelocity);
|
outBitStream->Write(bIsInitialUpdate || m_DirtyAngularVelocity);
|
||||||
|
|
||||||
if (bIsInitialUpdate || m_DirtyAngularVelocity) {
|
if (bIsInitialUpdate || m_DirtyAngularVelocity) {
|
||||||
outBitStream->Write(m_AngularVelocity);
|
outBitStream->Write(m_AngularVelocity.x);
|
||||||
|
outBitStream->Write(m_AngularVelocity.y);
|
||||||
|
outBitStream->Write(m_AngularVelocity.z);
|
||||||
|
m_DirtyAngularVelocity = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
outBitStream->Write0();
|
outBitStream->Write0(); // local_space_info. TODO: Implement this
|
||||||
|
|
||||||
outBitStream->Write0();
|
outBitStream->Write(m_DirtyRemoteInput || bIsInitialUpdate); // remote_input_info
|
||||||
|
if (m_DirtyRemoteInput || bIsInitialUpdate) {
|
||||||
|
outBitStream->Write(m_RemoteInputInfo.m_RemoteInputX);
|
||||||
|
outBitStream->Write(m_RemoteInputInfo.m_RemoteInputY);
|
||||||
|
outBitStream->Write(m_RemoteInputInfo.m_IsPowersliding);
|
||||||
|
outBitStream->Write(m_RemoteInputInfo.m_IsModified);
|
||||||
|
m_DirtyRemoteInput = false;
|
||||||
|
}
|
||||||
|
|
||||||
outBitStream->Write(0.0f);
|
outBitStream->Write(125.0f); // remote_input_ping TODO: Figure out how this should be calculated as it seems to be constant through the whole race.
|
||||||
|
|
||||||
if (!bIsInitialUpdate) {
|
if (!bIsInitialUpdate) {
|
||||||
outBitStream->Write0();
|
outBitStream->Write0();
|
||||||
@ -95,7 +127,7 @@ void VehiclePhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bI
|
|||||||
|
|
||||||
if (bIsInitialUpdate) {
|
if (bIsInitialUpdate) {
|
||||||
outBitStream->Write<uint8_t>(m_EndBehavior);
|
outBitStream->Write<uint8_t>(m_EndBehavior);
|
||||||
outBitStream->Write1();
|
outBitStream->Write1(); // is input locked?
|
||||||
}
|
}
|
||||||
|
|
||||||
outBitStream->Write0();
|
outBitStream->Write0();
|
||||||
@ -104,7 +136,6 @@ void VehiclePhysicsComponent::Serialize(RakNet::BitStream* outBitStream, bool bI
|
|||||||
void VehiclePhysicsComponent::Update(float deltaTime) {
|
void VehiclePhysicsComponent::Update(float deltaTime) {
|
||||||
if (m_SoftUpdate > 5) {
|
if (m_SoftUpdate > 5) {
|
||||||
EntityManager::Instance()->SerializeEntity(m_Parent);
|
EntityManager::Instance()->SerializeEntity(m_Parent);
|
||||||
|
|
||||||
m_SoftUpdate = 0;
|
m_SoftUpdate = 0;
|
||||||
} else {
|
} else {
|
||||||
m_SoftUpdate += deltaTime;
|
m_SoftUpdate += deltaTime;
|
||||||
|
@ -5,6 +5,24 @@
|
|||||||
#include "Component.h"
|
#include "Component.h"
|
||||||
#include "eReplicaComponentType.h"
|
#include "eReplicaComponentType.h"
|
||||||
|
|
||||||
|
struct RemoteInputInfo {
|
||||||
|
void operator=(const RemoteInputInfo& other) {
|
||||||
|
m_RemoteInputX = other.m_RemoteInputX;
|
||||||
|
m_RemoteInputY = other.m_RemoteInputY;
|
||||||
|
m_IsPowersliding = other.m_IsPowersliding;
|
||||||
|
m_IsModified = other.m_IsModified;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const RemoteInputInfo& other) {
|
||||||
|
return m_RemoteInputX == other.m_RemoteInputX && m_RemoteInputY == other.m_RemoteInputY && m_IsPowersliding == other.m_IsPowersliding && m_IsModified == other.m_IsModified;
|
||||||
|
}
|
||||||
|
|
||||||
|
float m_RemoteInputX;
|
||||||
|
float m_RemoteInputY;
|
||||||
|
bool m_IsPowersliding;
|
||||||
|
bool m_IsModified;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Physics component for vehicles.
|
* Physics component for vehicles.
|
||||||
*/
|
*/
|
||||||
@ -94,6 +112,7 @@ public:
|
|||||||
void SetDirtyPosition(bool val);
|
void SetDirtyPosition(bool val);
|
||||||
void SetDirtyVelocity(bool val);
|
void SetDirtyVelocity(bool val);
|
||||||
void SetDirtyAngularVelocity(bool val);
|
void SetDirtyAngularVelocity(bool val);
|
||||||
|
void SetRemoteInputInfo(const RemoteInputInfo&);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_DirtyPosition;
|
bool m_DirtyPosition;
|
||||||
@ -110,4 +129,6 @@ private:
|
|||||||
|
|
||||||
float m_SoftUpdate = 0;
|
float m_SoftUpdate = 0;
|
||||||
uint32_t m_EndBehavior;
|
uint32_t m_EndBehavior;
|
||||||
|
RemoteInputInfo m_RemoteInputInfo;
|
||||||
|
bool m_DirtyRemoteInput;
|
||||||
};
|
};
|
||||||
|
@ -136,6 +136,33 @@ void ClientPackets::HandleClientPositionUpdate(const SystemAddress& sysAddr, Pac
|
|||||||
inStream.Read(angVelocity.z);
|
inStream.Read(angVelocity.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO figure out how to use these. Ignoring for now, but reading in if they exist.
|
||||||
|
bool hasLocalSpaceInfo{};
|
||||||
|
LWOOBJID objectId{};
|
||||||
|
NiPoint3 localSpacePosition{};
|
||||||
|
bool hasLinearVelocity{};
|
||||||
|
NiPoint3 linearVelocity{};
|
||||||
|
if (inStream.Read(hasLocalSpaceInfo) && hasLocalSpaceInfo) {
|
||||||
|
inStream.Read(objectId);
|
||||||
|
inStream.Read(localSpacePosition.x);
|
||||||
|
inStream.Read(localSpacePosition.y);
|
||||||
|
inStream.Read(localSpacePosition.z);
|
||||||
|
if (inStream.Read(hasLinearVelocity) && hasLinearVelocity) {
|
||||||
|
inStream.Read(linearVelocity.x);
|
||||||
|
inStream.Read(linearVelocity.y);
|
||||||
|
inStream.Read(linearVelocity.z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool hasRemoteInputInfo{};
|
||||||
|
RemoteInputInfo remoteInput{};
|
||||||
|
|
||||||
|
if (inStream.Read(hasRemoteInputInfo) && hasRemoteInputInfo) {
|
||||||
|
inStream.Read(remoteInput.m_RemoteInputX);
|
||||||
|
inStream.Read(remoteInput.m_RemoteInputY);
|
||||||
|
inStream.Read(remoteInput.m_IsPowersliding);
|
||||||
|
inStream.Read(remoteInput.m_IsModified);
|
||||||
|
}
|
||||||
|
|
||||||
bool updateChar = true;
|
bool updateChar = true;
|
||||||
|
|
||||||
if (possessorComponent != nullptr) {
|
if (possessorComponent != nullptr) {
|
||||||
@ -150,9 +177,6 @@ void ClientPackets::HandleClientPositionUpdate(const SystemAddress& sysAddr, Pac
|
|||||||
|
|
||||||
auto* vehiclePhysicsComponent = possassableEntity->GetComponent<VehiclePhysicsComponent>();
|
auto* vehiclePhysicsComponent = possassableEntity->GetComponent<VehiclePhysicsComponent>();
|
||||||
if (vehiclePhysicsComponent != nullptr) {
|
if (vehiclePhysicsComponent != nullptr) {
|
||||||
// This is flipped for whatever reason
|
|
||||||
rotation = NiQuaternion(rotation.z, rotation.y, rotation.x, rotation.w);
|
|
||||||
|
|
||||||
vehiclePhysicsComponent->SetPosition(position);
|
vehiclePhysicsComponent->SetPosition(position);
|
||||||
vehiclePhysicsComponent->SetRotation(rotation);
|
vehiclePhysicsComponent->SetRotation(rotation);
|
||||||
vehiclePhysicsComponent->SetIsOnGround(onGround);
|
vehiclePhysicsComponent->SetIsOnGround(onGround);
|
||||||
@ -161,6 +185,7 @@ void ClientPackets::HandleClientPositionUpdate(const SystemAddress& sysAddr, Pac
|
|||||||
vehiclePhysicsComponent->SetDirtyVelocity(velocityFlag);
|
vehiclePhysicsComponent->SetDirtyVelocity(velocityFlag);
|
||||||
vehiclePhysicsComponent->SetAngularVelocity(angVelocity);
|
vehiclePhysicsComponent->SetAngularVelocity(angVelocity);
|
||||||
vehiclePhysicsComponent->SetDirtyAngularVelocity(angVelocityFlag);
|
vehiclePhysicsComponent->SetDirtyAngularVelocity(angVelocityFlag);
|
||||||
|
vehiclePhysicsComponent->SetRemoteInputInfo(remoteInput);
|
||||||
} else {
|
} else {
|
||||||
// Need to get the mount's controllable physics
|
// Need to get the mount's controllable physics
|
||||||
auto* controllablePhysicsComponent = possassableEntity->GetComponent<ControllablePhysicsComponent>();
|
auto* controllablePhysicsComponent = possassableEntity->GetComponent<ControllablePhysicsComponent>();
|
||||||
|
Loading…
Reference in New Issue
Block a user