Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
150 changes: 74 additions & 76 deletions Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4338,93 +4338,91 @@ bool CStaticFunctionDefinitions::WarpPedIntoVehicle(CPed* pPed, CVehicle* pVehic
if (pVehicle->GetModel() == VT_CAMPER && uiSeat > 2)
return false;

// Valid seat id for that vehicle?
// Temp fix: Disable driver seat for train carriages since the whole vehicle sync logic is based on the the player on the first seat being the vehicle
// syncer (Todo)
if (pVehicle->GetVehicleType() != VEHICLE_TRAIN || !pVehicle->GetTowedByVehicle())
// Disallow driver seat on towed carriages to preserve lead locomotive sync
if (pVehicle->GetVehicleType() == VEHICLE_TRAIN && pVehicle->GetTowedByVehicle() && uiSeat == 0)
return false;

if (!pPed->IsDead())
{
if (!pPed->IsDead())
if (pVehicle->GetHealth() > 0.0f)
{
if (pVehicle->GetHealth() > 0.0f)
CPed* pPreviousOccupant = pVehicle->GetOccupant(uiSeat);
// Make sure no one is entering or he will get stuck in the entry packet handshaking and network trouble
if (pPreviousOccupant == NULL || (pPreviousOccupant && pPreviousOccupant->GetVehicleAction() == CPed::VEHICLEACTION_NONE))
{
CPed* pPreviousOccupant = pVehicle->GetOccupant(uiSeat);
// Make sure no one is entering or he will get stuck in the entry packet handshaking and network trouble
if (pPreviousOccupant == NULL || (pPreviousOccupant && pPreviousOccupant->GetVehicleAction() == CPed::VEHICLEACTION_NONE))
// Toss the previous player out of it if necessary
if (pPreviousOccupant)
{
// Toss the previous player out of it if necessary
if (pPreviousOccupant)
{
// Remove him from the vehicle
RemovePedFromVehicle(pPreviousOccupant);
}
// Remove him from the vehicle
RemovePedFromVehicle(pPreviousOccupant);
}

// Jax: ::RemovePedFromVehicle caused a short delay between removing and entering,
// which creates a buggy effect if we're just warping into a different seat
// Jax: ::RemovePedFromVehicle caused a short delay between removing and entering,
// which creates a buggy effect if we're just warping into a different seat

// Is he already in a vehicle? Remove him from it
CVehicle* pPreviousVehicle = pPed->GetOccupiedVehicle();
if (pPreviousVehicle)
{
// Remove him from the vehicle
pPreviousVehicle->SetOccupant(NULL, pPed->GetOccupiedVehicleSeat());
}
// Is he already in a vehicle? Remove him from it
CVehicle* pPreviousVehicle = pPed->GetOccupiedVehicle();
if (pPreviousVehicle)
{
// Remove him from the vehicle
pPreviousVehicle->SetOccupant(NULL, pPed->GetOccupiedVehicleSeat());
}

// Put him in the new vehicle
pPed->SetOccupiedVehicle(pVehicle, uiSeat);
pPed->SetVehicleAction(CPed::VEHICLEACTION_NONE);
// Put him in the new vehicle
pPed->SetOccupiedVehicle(pVehicle, uiSeat);
pPed->SetVehicleAction(CPed::VEHICLEACTION_NONE);

// If he's the driver, switch on the engine
if (uiSeat == 0 && g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::VEHICLE_ENGINE_AUTOSTART))
pVehicle->SetEngineOn(true);
// If he's the driver, switch on the engine
if (uiSeat == 0 && g_pGame->IsWorldSpecialPropertyEnabled(WorldSpecialProperty::VEHICLE_ENGINE_AUTOSTART))
pVehicle->SetEngineOn(true);

// Tell all the players. If the calling resource's elements haven't reached the clients yet
// (e.g. called from onResourceStart on a vehicle created in the same event), hold off until
// they have instead of just dropping it - the vehicle itself isn't synced to clients yet
// either, and an RPC referencing an unknown element there would leave the server and clients
// permanently disagreeing about whether this ped is in a vehicle.
auto sendWarpRpc = [pPed, pVehicle, uiSeat]()
{
CBitStream BitStream;
BitStream.pBitStream->Write(pVehicle->GetID());
BitStream.pBitStream->Write(static_cast<unsigned char>(uiSeat));
BitStream.pBitStream->Write(pPed->GenerateSyncTimeContext());
m_pPlayerManager->BroadcastOnlyJoined(CElementRPCPacket(pPed, WARP_PED_INTO_VEHICLE, *BitStream.pBitStream));
};

if (pCallingResource)
pCallingResource->RunOrDeferUntilClientSynced(sendWarpRpc);
else
sendWarpRpc();

// Call the player->vehicle event
CLuaArguments PlayerVehicleArguments;
PlayerVehicleArguments.PushElement(pVehicle); // vehicle
PlayerVehicleArguments.PushNumber(uiSeat); // seat
if (pPreviousOccupant) // jacked
PlayerVehicleArguments.PushElement(pPreviousOccupant);
else
PlayerVehicleArguments.PushBoolean(false);
// Leave onPlayerVehicleEnter for backwards compatibility
if (IS_PLAYER(pPed))
pPed->CallEvent("onPlayerVehicleEnter", PlayerVehicleArguments);
else
pPed->CallEvent("onPedVehicleEnter", PlayerVehicleArguments);

// Call the vehicle->player event
CLuaArguments VehiclePlayerArguments;
VehiclePlayerArguments.PushElement(pPed); // player
VehiclePlayerArguments.PushNumber(uiSeat); // seat
if (pPreviousOccupant) // jacked
VehiclePlayerArguments.PushElement(pPreviousOccupant);
else
VehiclePlayerArguments.PushBoolean(false);
pVehicle->CallEvent("onVehicleEnter", VehiclePlayerArguments);
// Tell all the players. If the calling resource's elements haven't reached the clients yet
// (e.g. called from onResourceStart on a vehicle created in the same event), hold off until
// they have instead of just dropping it - the vehicle itself isn't synced to clients yet
// either, and an RPC referencing an unknown element there would leave the server and clients
// permanently disagreeing about whether this ped is in a vehicle.
auto sendWarpRpc = [pPed, pVehicle, uiSeat]()
{
CBitStream BitStream;
BitStream.pBitStream->Write(pVehicle->GetID());
BitStream.pBitStream->Write(static_cast<unsigned char>(uiSeat));
BitStream.pBitStream->Write(pPed->GenerateSyncTimeContext());
m_pPlayerManager->BroadcastOnlyJoined(CElementRPCPacket(pPed, WARP_PED_INTO_VEHICLE, *BitStream.pBitStream));
};

if (pCallingResource)
pCallingResource->RunOrDeferUntilClientSynced(sendWarpRpc);
else
sendWarpRpc();

// Call the player->vehicle event
CLuaArguments PlayerVehicleArguments;
PlayerVehicleArguments.PushElement(pVehicle); // vehicle
PlayerVehicleArguments.PushNumber(uiSeat); // seat
if (pPreviousOccupant) // jacked
PlayerVehicleArguments.PushElement(pPreviousOccupant);
else
PlayerVehicleArguments.PushBoolean(false);
// Leave onPlayerVehicleEnter for backwards compatibility
if (IS_PLAYER(pPed))
pPed->CallEvent("onPlayerVehicleEnter", PlayerVehicleArguments);
else
pPed->CallEvent("onPedVehicleEnter", PlayerVehicleArguments);

// Call the vehicle->player event
CLuaArguments VehiclePlayerArguments;
VehiclePlayerArguments.PushElement(pPed); // player
VehiclePlayerArguments.PushNumber(uiSeat); // seat
if (pPreviousOccupant) // jacked
VehiclePlayerArguments.PushElement(pPreviousOccupant);
else
VehiclePlayerArguments.PushBoolean(false);
pVehicle->CallEvent("onVehicleEnter", VehiclePlayerArguments);

// Used to check if f.e. lua changed the player's vehicle (fix for #7570)
pVehicle->m_bOccupantChanged = true;
// Used to check if f.e. lua changed the player's vehicle (fix for #7570)
pVehicle->m_bOccupantChanged = true;

return true;
}
return true;
}
}
}
Expand Down
Loading