@@ -6530,25 +6530,19 @@ void CClientPed::UpdateStreamPosition(const CVector& vecInPosition)
65306530// Asks server for permission to start entering vehicle
65316531//
65326532// ////////////////////////////////////////////////////////////////
6533- bool CClientPed::EnterVehicle (CClientVehicle* pVehicle, bool bPassenger)
6533+ bool CClientPed::EnterVehicle (CClientVehicle* pVehicle, bool bPassenger, std::optional< unsigned int > optSeat )
65346534{
65356535 // Are we local player or ped we are syncing
65366536 if (!IsSyncing () && !IsLocalPlayer () && !IsLocalEntity ())
6537- {
65386537 return false ;
6539- }
65406538
65416539 // Are we already inside a vehicle
65426540 if (GetOccupiedVehicle ())
6543- {
65446541 return false ;
6545- }
65466542
65476543 // We dead or in water?
65486544 if (IsDead ())
6549- {
65506545 return false ;
6551- }
65526546
65536547 // Are we already sending an in/out request or not allowed to create a new in/out?
65546548 if (m_bNoNewVehicleTask // Are we permitted to even enter a vehicle?
@@ -6567,9 +6561,7 @@ bool CClientPed::EnterVehicle(CClientVehicle* pVehicle, bool bPassenger)
65676561
65686562 // Streamed?
65696563 if (!m_pPlayerPed)
6570- {
65716564 return false ;
6572- }
65736565
65746566 unsigned int uiDoor = 0 ;
65756567 // Do we want to enter a specific vehicle?
@@ -6594,43 +6586,31 @@ bool CClientPed::EnterVehicle(CClientVehicle* pVehicle, bool bPassenger)
65946586
65956587 // Dead vehicle?
65966588 if (pVehicle->GetHealth () <= 0 .0f )
6597- {
65986589 return false ;
6599- }
66006590
6591+ // Stop if the vehicle is not enterable
66016592 if (!pVehicle->IsEnterable (IsLocalEntity ()))
6602- {
6603- // Stop if the vehicle is not enterable
66046593 return false ;
6605- }
66066594
66076595 // Stop if the ped is swimming and the vehicle model cannot be entered from water (fixes #1990)
66086596 auto vehicleModel = static_cast <VehicleType>(pVehicle->GetModel ());
66096597
66106598 if (IsInWater () && !(vehicleModel == VehicleType::VT_SKIMMER || vehicleModel == VehicleType::VT_SEASPAR || vehicleModel == VehicleType::VT_LEVIATHN || vehicleModel == VehicleType::VT_VORTEX))
6611- {
66126599 return false ;
6613- }
66146600
66156601 // If the Jump task is playing and we are in water - I know right
66166602 // Kill the task.
66176603 CTask* pTask = GetCurrentPrimaryTask ();
66186604 if (pTask && pTask->GetTaskType () == TASK_COMPLEX_JUMP) // Kill jump task - breaks warp in entry and doesn't really matter
66196605 {
6620- if (pVehicle->IsInWater () ||
6621- IsInWater ()) // Make sure we are about to warp in (this bug only happens when someone jumps into water with a vehicle)
6622- {
6606+ if (pVehicle->IsInWater () || IsInWater ()) // Make sure we are about to warp in (this bug only happens when someone jumps into water with a vehicle)
66236607 KillTask (3 , true ); // Kill jump task if we are about to warp in
6624- }
66256608 }
66266609
66276610 // Make sure we don't have any other primary tasks running, otherwise our 'enter-vehicle'
66286611 // task will replace it and fuck it up!
66296612 if (GetCurrentPrimaryTask ())
6630- {
6631- // We already have a primary task, so stop.
66326613 return false ;
6633- }
66346614
66356615 if (IsClimbing () // Make sure we're not currently climbing
66366616 || HasJetPack () // Make sure we don't have a jetpack
@@ -6641,17 +6621,36 @@ bool CClientPed::EnterVehicle(CClientVehicle* pVehicle, bool bPassenger)
66416621 return false ;
66426622 }
66436623
6644- unsigned int uiSeat = uiDoor;
6645- if (bPassenger && uiDoor == 0 )
6624+ // Determine seat - either explicitly specified or auto-determined from door/passenger flag
6625+ unsigned int uiSeat;
6626+
6627+ if (optSeat.has_value ())
66466628 {
6647- // We're trying to enter as a passenger, yet our closest door
6648- // is the driver's door. Force an enter for the passenger seat.
6649- uiSeat = 1 ;
6629+ // Explicit seat specified - validate it (reuse validation logic from warpPedIntoVehicle)
6630+ uiSeat = optSeat.value ();
6631+ const unsigned char ucMaxPassengers = CClientVehicleManager::GetMaxPassengerCount (pVehicle->GetModel ());
6632+
6633+ if (uiSeat > ucMaxPassengers)
6634+ return false ;
6635+
6636+ if (uiSeat > 0 && ucMaxPassengers == 255 )
6637+ return false ;
66506638 }
6651- else if (!bPassenger)
6639+ else
66526640 {
6653- // We want to drive. Force our seat to the driver's seat.
6654- uiSeat = 0 ;
6641+ // Legacy behavior - auto-determine seat from door/passenger flag
6642+ uiSeat = uiDoor;
6643+ if (bPassenger && uiDoor == 0 )
6644+ {
6645+ // We're trying to enter as a passenger, yet our closest door
6646+ // is the driver's door. Force an enter for the passenger seat.
6647+ uiSeat = 1 ;
6648+ }
6649+ else if (!bPassenger)
6650+ {
6651+ // We want to drive. Force our seat to the driver's seat.
6652+ uiSeat = 0 ;
6653+ }
66556654 }
66566655
66576656 // If the vehicle's a boat, make sure we're standing on it (we need a dif task to enter boats properly)
0 commit comments