Skip to content

Commit e5026e7

Browse files
authored
Improve player sync when exiting vehicle (#2084)
1 parent 076c7fe commit e5026e7

File tree

8 files changed

+79
-55
lines changed

8 files changed

+79
-55
lines changed

Client/mods/deathmatch/logic/CClientPed.cpp

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -537,21 +537,17 @@ void CClientPed::SetPosition(const CVector& vecPosition, bool bResetInterpolatio
537537
// Don't set the actual position if we're in a vehicle
538538
if (!GetRealOccupiedVehicle())
539539
{
540-
// Set it only if we're not in a vehicle or not working on getting in/out
541-
if (!m_pOccupiedVehicle || GetVehicleInOutState() != VEHICLE_INOUT_GETTING_OUT)
540+
// Is this the local player?
541+
if (m_bIsLocalPlayer)
542542
{
543-
// Is this the local player?
544-
if (m_bIsLocalPlayer)
545-
{
546-
// If move is big enough, do ground checks
547-
float DistanceMoved = (m_Matrix.vPos - vecPosition).Length();
548-
if (DistanceMoved > 50 && !IsFrozen() && bAllowGroundLoadFreeze)
549-
SetFrozenWaitingForGroundToLoad(true);
550-
}
551-
552-
// Set the real position
553-
m_pPlayerPed->SetPosition(const_cast<CVector*>(&vecPosition));
543+
// If move is big enough, do ground checks
544+
float DistanceMoved = (m_Matrix.vPos - vecPosition).Length();
545+
if (DistanceMoved > 50 && !IsFrozen() && bAllowGroundLoadFreeze)
546+
SetFrozenWaitingForGroundToLoad(true);
554547
}
548+
549+
// Set the real position
550+
m_pPlayerPed->SetPosition(const_cast<CVector*>(&vecPosition));
555551
}
556552
}
557553

Client/mods/deathmatch/logic/CClientVehicle.cpp

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -376,9 +376,11 @@ void CClientVehicle::SetPosition(const CVector& vecPosition, bool bResetInterpol
376376
}
377377

378378
// If we have any occupants, update their positions
379+
// Make sure we dont update their position if they are getting out and have physically left the car
379380
for (int i = 0; i <= NUMELMS(m_pPassengers); i++)
380381
if (CClientPed* pOccupant = GetOccupant(i))
381-
pOccupant->SetPosition(vecPosition);
382+
if (pOccupant->GetVehicleInOutState() != VEHICLE_INOUT_GETTING_OUT || pOccupant->GetRealOccupiedVehicle())
383+
pOccupant->SetPosition(vecPosition);
382384

383385
// Reset interpolation
384386
if (bResetInterpolation)
@@ -529,15 +531,11 @@ bool CClientVehicle::SetMatrix(const CMatrix& Matrix)
529531
m_MatrixPure = Matrix;
530532

531533
// If we have any occupants, update their positions
532-
if (m_pDriver)
533-
m_pDriver->SetPosition(m_Matrix.vPos);
534-
for (int i = 0; i < (sizeof(m_pPassengers) / sizeof(CClientPed*)); i++)
535-
{
536-
if (m_pPassengers[i])
537-
{
538-
m_pPassengers[i]->SetPosition(m_Matrix.vPos);
539-
}
540-
}
534+
// Make sure we dont update their position if they are getting out and have physically left the car
535+
for (int i = 0; i <= NUMELMS(m_pPassengers); i++)
536+
if (CClientPed* pOccupant = GetOccupant(i))
537+
if (pOccupant->GetVehicleInOutState() != VEHICLE_INOUT_GETTING_OUT || pOccupant->GetRealOccupiedVehicle())
538+
pOccupant->SetPosition(m_Matrix.vPos);
541539

542540
return true;
543541
}

Client/mods/deathmatch/logic/CNetAPI.cpp

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -318,16 +318,30 @@ void CNetAPI::DoPulse()
318318
// Are in a vehicle?
319319
if (pVehicle)
320320
{
321-
// Send a puresync packet
322-
NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream();
323-
if (pBitStream)
321+
// Are we getting out and physically left the car
322+
if (pPlayer->GetVehicleInOutState() == VEHICLE_INOUT_GETTING_OUT && !pPlayer->GetRealOccupiedVehicle())
324323
{
325-
// Write our data
326-
WriteVehiclePuresync(pPlayer, pVehicle, *pBitStream);
324+
// Send a player puresync packet
325+
NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream();
326+
if (pBitStream)
327+
{
328+
WritePlayerPuresync(pPlayer, *pBitStream);
327329

328-
// Send the packet and destroy it
329-
g_pNet->SendPacket(PACKET_ID_PLAYER_VEHICLE_PURESYNC, pBitStream, PACKET_PRIORITY_MEDIUM, PACKET_RELIABILITY_UNRELIABLE_SEQUENCED);
330-
g_pNet->DeallocateNetBitStream(pBitStream);
330+
g_pNet->SendPacket(PACKET_ID_PLAYER_PURESYNC, pBitStream, PACKET_PRIORITY_MEDIUM, PACKET_RELIABILITY_UNRELIABLE_SEQUENCED);
331+
g_pNet->DeallocateNetBitStream(pBitStream);
332+
}
333+
}
334+
else
335+
{
336+
// Send a vehicle puresync packet
337+
NetBitStreamInterface* pBitStream = g_pNet->AllocateNetBitStream();
338+
if (pBitStream)
339+
{
340+
WriteVehiclePuresync(pPlayer, pVehicle, *pBitStream);
341+
342+
g_pNet->SendPacket(PACKET_ID_PLAYER_VEHICLE_PURESYNC, pBitStream, PACKET_PRIORITY_MEDIUM, PACKET_RELIABILITY_UNRELIABLE_SEQUENCED);
343+
g_pNet->DeallocateNetBitStream(pBitStream);
344+
}
331345
}
332346

333347
// Sync its damage model too
@@ -962,13 +976,9 @@ void CNetAPI::ReadPlayerPuresync(CClientPlayer* pPlayer, NetBitStreamInterface&
962976
position.data.vecPosition -= vecTempPos;
963977
}
964978

965-
// If the player is working on leaving a vehicle, don't set any target position
966-
if (pPlayer->GetVehicleInOutState() == VEHICLE_INOUT_NONE || pPlayer->GetVehicleInOutState() == VEHICLE_INOUT_GETTING_IN ||
967-
pPlayer->GetVehicleInOutState() == VEHICLE_INOUT_JACKING)
968-
{
969-
pPlayer->SetTargetPosition(position.data.vecPosition, TICK_RATE, pContactEntity);
970-
pPlayer->SetTargetRotation(rotation.data.fRotation);
971-
}
979+
// Set position and rotation
980+
pPlayer->SetTargetPosition(position.data.vecPosition, TICK_RATE, pContactEntity);
981+
pPlayer->SetTargetRotation(rotation.data.fRotation);
972982

973983
// Set move speed, controller state and camera rotation + duck state
974984
pPlayer->SetControllerState(ControllerState);

Client/mods/deathmatch/logic/CUnoccupiedVehicleSync.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,16 @@ void CUnoccupiedVehicleSync::UpdateDamageModels()
228228

229229
void CUnoccupiedVehicleSync::UpdateStates()
230230
{
231+
CClientPlayer* pPlayer = g_pClientGame->GetLocalPlayer();
232+
CDeathmatchVehicle* pVehicle = nullptr;
233+
// Are we leaving a vehicle as driver and physically out of it
234+
if (pPlayer && pPlayer->GetVehicleInOutState() == VEHICLE_INOUT_GETTING_OUT && pPlayer->GetOccupiedVehicle() && pPlayer->GetOccupiedVehicleSeat() == 0 && !pPlayer->GetRealOccupiedVehicle())
235+
{
236+
// Make sure it's valid and add it to our list temporarily
237+
if (auto* pVehicle = dynamic_cast<CDeathmatchVehicle*>(pPlayer->GetOccupiedVehicle()))
238+
m_List.push_front(pVehicle);
239+
}
240+
231241
// Got any items?
232242
if (m_List.size() > 0)
233243
{
@@ -250,6 +260,10 @@ void CUnoccupiedVehicleSync::UpdateStates()
250260
g_pNet->DeallocateNetBitStream(pBitStream);
251261
}
252262
}
263+
264+
// Remove our vehicle again
265+
if (pVehicle)
266+
m_List.remove(pVehicle);
253267
}
254268

255269
bool CUnoccupiedVehicleSync::WriteVehicleInformation(NetBitStreamInterface* pBitStream, CDeathmatchVehicle* pVehicle)

Server/mods/deathmatch/logic/CGame.cpp

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2265,23 +2265,27 @@ void CGame::Packet_PlayerPuresync(CPlayerPuresyncPacket& Packet)
22652265
pPlayer->IncrementPuresync();
22662266

22672267
// Ignore this packet if he should be in a vehicle
2268-
if (!pPlayer->GetOccupiedVehicle())
2268+
if (pPlayer->GetOccupiedVehicle())
22692269
{
2270-
// Send a returnsync packet to the player that sent it
2271-
// Only every 4 packets.
2272-
if ((pPlayer->GetPuresyncCount() % 4) == 0)
2273-
pPlayer->Send(CReturnSyncPacket(pPlayer));
2270+
// Allow it if he's exiting
2271+
if (pPlayer->GetVehicleAction() != CPed::VEHICLEACTION_EXITING)
2272+
return;
2273+
}
22742274

2275-
CLOCK("PlayerPuresync", "RelayPlayerPuresync");
2276-
// Relay to other players
2277-
RelayPlayerPuresync(Packet);
2278-
UNCLOCK("PlayerPuresync", "RelayPlayerPuresync");
2275+
// Send a returnsync packet to the player that sent it
2276+
// Only every 4 packets.
2277+
if ((pPlayer->GetPuresyncCount() % 4) == 0)
2278+
pPlayer->Send(CReturnSyncPacket(pPlayer));
22792279

2280-
CLOCK("PlayerPuresync", "DoHitDetection");
2281-
// Run colpoint checks
2282-
m_pColManager->DoHitDetection(pPlayer->GetPosition(), pPlayer);
2283-
UNCLOCK("PlayerPuresync", "DoHitDetection");
2284-
}
2280+
CLOCK("PlayerPuresync", "RelayPlayerPuresync");
2281+
// Relay to other players
2282+
RelayPlayerPuresync(Packet);
2283+
UNCLOCK("PlayerPuresync", "RelayPlayerPuresync");
2284+
2285+
CLOCK("PlayerPuresync", "DoHitDetection");
2286+
// Run colpoint checks
2287+
m_pColManager->DoHitDetection(pPlayer->GetPosition(), pPlayer);
2288+
UNCLOCK("PlayerPuresync", "DoHitDetection");
22852289
}
22862290
}
22872291

Server/mods/deathmatch/logic/CUnoccupiedVehicleSync.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -271,9 +271,9 @@ void CUnoccupiedVehicleSync::Packet_UnoccupiedVehicleSync(CUnoccupiedVehicleSync
271271
// this packet if the time context matches.
272272
if (pVehicle->GetSyncer() == pPlayer && pVehicle->CanUpdateSync(vehicle.data.ucTimeContext))
273273
{
274-
// Is there no player driver?
274+
// Is there no player driver, or is he exiting?
275275
CPed* pOccupant = pVehicle->GetOccupant(0);
276-
if (!pOccupant || !IS_PLAYER(pOccupant))
276+
if (!pOccupant || !IS_PLAYER(pOccupant) || pOccupant->GetVehicleAction() == CPed::VEHICLEACTION_EXITING)
277277
{
278278
// Apply the data to the vehicle
279279
if (vehicle.data.bSyncPosition)

Server/mods/deathmatch/logic/net/CSimPlayer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ class CSimPlayer
4242
std::multimap<ushort, CSimPlayer*> m_PuresyncSendListGrouped; // Send list grouped by bitstream version
4343
bool m_bSendListChanged;
4444
bool m_bHasOccupiedVehicle;
45+
bool m_bIsExitingVehicle;
4546
CControllerState m_sharedControllerState; // Updated by CSim*Packet code
4647

4748
// Used in CSimPlayerPuresyncPacket and CSimVehiclePuresyncPacket

Server/mods/deathmatch/logic/net/CSimPlayerManager.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ void CSimPlayerManager::UpdateSimPlayer(CPlayer* pPlayer)
130130
pSim->m_bIsJoined = pPlayer->IsJoined();
131131
pSim->m_usBitStreamVersion = pPlayer->GetBitStreamVersion();
132132
pSim->m_bHasOccupiedVehicle = pVehicle != NULL;
133+
pSim->m_bIsExitingVehicle = pPlayer->GetVehicleAction() == CPed::VEHICLEACTION_EXITING;
133134
pSim->m_PlayerID = pPlayer->GetID();
134135
pSim->m_usLatency = static_cast<unsigned short>(pPlayer->GetPing());
135136
pSim->m_ucWeaponType = pPlayer->GetWeaponType();
@@ -233,7 +234,7 @@ bool CSimPlayerManager::HandlePlayerPureSync(const NetServerPlayerID& Socket, Ne
233234
CSimPlayer* pSourceSimPlayer = Get(Socket);
234235

235236
// Check is good for player pure sync
236-
if (pSourceSimPlayer && pSourceSimPlayer->IsJoined() && !pSourceSimPlayer->m_bHasOccupiedVehicle)
237+
if (pSourceSimPlayer && pSourceSimPlayer->IsJoined() && (!pSourceSimPlayer->m_bHasOccupiedVehicle || pSourceSimPlayer->m_bIsExitingVehicle))
237238
{
238239
// Read the incoming packet data
239240
CSimPlayerPuresyncPacket* pPacket =

0 commit comments

Comments
 (0)