From df59c59f2ce829f8bc8969fbf7d3f1863838ab5f Mon Sep 17 00:00:00 2001 From: Youssef Maged Date: Sat, 12 Sep 2026 06:28:16 +0300 Subject: [PATCH] Remember vehicle/seat when ped/player dies --- Server/mods/deathmatch/logic/CGame.cpp | 12 +++++++++-- Server/mods/deathmatch/logic/CPed.cpp | 20 +++++++++++++++++++ Server/mods/deathmatch/logic/CPed.h | 7 +++++++ .../logic/CStaticFunctionDefinitions.cpp | 18 +++++++++++++++-- 4 files changed, 53 insertions(+), 4 deletions(-) diff --git a/Server/mods/deathmatch/logic/CGame.cpp b/Server/mods/deathmatch/logic/CGame.cpp index a34a50f2cec..542d58a8103 100644 --- a/Server/mods/deathmatch/logic/CGame.cpp +++ b/Server/mods/deathmatch/logic/CGame.cpp @@ -2151,10 +2151,14 @@ void CGame::Packet_PedWasted(CPedWastedPacket& Packet) pPed->SetVehicleAction(CPed::VEHICLEACTION_NONE); // Remove him from any occupied vehicle + // The client keeps the player paired with the vehicle until he respawns, + // so remember it and let the occupied-vehicle getters report it while dead if (pVehicle) { - pVehicle->SetOccupant(NULL, pPed->GetOccupiedVehicleSeat()); + const unsigned int uiOccupiedSeat = pPed->GetOccupiedVehicleSeat(); + pVehicle->SetOccupant(NULL, uiOccupiedSeat); pPed->SetOccupiedVehicle(NULL, 0); + pPed->SetVehicleOccupiedOnDeath(pVehicle, uiOccupiedSeat); } CElement* pKiller = (Packet.m_Killer != INVALID_ELEMENT_ID) ? CElementIDs::GetElement(Packet.m_Killer) : NULL; @@ -2210,11 +2214,15 @@ void CGame::Packet_PlayerWasted(CPlayerWastedPacket& Packet) pPlayer->SetVehicleAction(CPed::VEHICLEACTION_NONE); // Remove him from any occupied vehicle + // The client keeps the player paired with the vehicle until he respawns, + // so remember it and let the occupied-vehicle getters report it while dead CVehicle* pVehicle = pPlayer->GetOccupiedVehicle(); if (pVehicle) { - pVehicle->SetOccupant(NULL, pPlayer->GetOccupiedVehicleSeat()); + const unsigned int uiOccupiedSeat = pPlayer->GetOccupiedVehicleSeat(); + pVehicle->SetOccupant(NULL, uiOccupiedSeat); pPlayer->SetOccupiedVehicle(NULL, 0); + pPlayer->SetVehicleOccupiedOnDeath(pVehicle, uiOccupiedSeat); } CElement* pKiller = (Packet.m_Killer != INVALID_ELEMENT_ID) ? CElementIDs::GetElement(Packet.m_Killer) : NULL; diff --git a/Server/mods/deathmatch/logic/CPed.cpp b/Server/mods/deathmatch/logic/CPed.cpp index e1caa98a6f0..447bfdc5eb0 100644 --- a/Server/mods/deathmatch/logic/CPed.cpp +++ b/Server/mods/deathmatch/logic/CPed.cpp @@ -12,6 +12,7 @@ #include "StdInc.h" #include "CPed.h" #include "CPedManager.h" +#include "CElementRefManager.h" #include "CLogger.h" #include "Utils.h" #include "CStaticFunctionDefinitions.h" @@ -73,6 +74,11 @@ CPed::CPed(CPedManager* pPedManager, CElement* pParent, unsigned short usModel) m_uiVehicleSeat = INVALID_VEHICLE_SEAT; m_uiVehicleAction = CPed::VEHICLEACTION_NONE; + m_pVehicleOnDeath = NULL; + m_uiVehicleSeatOnDeath = INVALID_VEHICLE_SEAT; + + CElementRefManager::AddElementRefs(ELEMENT_REF_DEBUG(this, "CPed"), &m_pVehicleOnDeath, NULL); + m_vecVelocity.fX = m_vecVelocity.fY = m_vecVelocity.fZ = 0.0f; m_pSyncer = NULL; @@ -114,6 +120,8 @@ CPed::~CPed() m_pVehicle->SetOccupant(NULL, m_uiVehicleSeat); } + CElementRefManager::RemoveElementRefs(ELEMENT_REF_DEBUG(this, "CPed"), &m_pVehicleOnDeath, NULL); + SetSyncer(NULL); delete m_pClothes; @@ -409,6 +417,9 @@ void CPed::SetContactElement(CElement* pElement) void CPed::SetIsDead(bool bDead) { m_bIsDead = bDead; + + if (!bDead) + SetVehicleOccupiedOnDeath(NULL, INVALID_VEHICLE_SEAT); } CVehicle* CPed::SetOccupiedVehicle(CVehicle* pVehicle, unsigned int uiSeat) @@ -420,6 +431,9 @@ CVehicle* CPed::SetOccupiedVehicle(CVehicle* pVehicle, unsigned int uiSeat) m_pVehicle = pVehicle; m_uiVehicleSeat = uiSeat; + if (pVehicle) + SetVehicleOccupiedOnDeath(NULL, INVALID_VEHICLE_SEAT); + // Make sure the vehicle knows if (m_pVehicle) { @@ -432,6 +446,12 @@ CVehicle* CPed::SetOccupiedVehicle(CVehicle* pVehicle, unsigned int uiSeat) return m_pVehicle; } +void CPed::SetVehicleOccupiedOnDeath(CVehicle* pVehicle, unsigned int uiSeat) +{ + m_pVehicleOnDeath = pVehicle; + m_uiVehicleSeatOnDeath = pVehicle ? uiSeat : INVALID_VEHICLE_SEAT; +} + void CPed::SetVehicleAction(unsigned int uiAction) { m_uiVehicleAction = uiAction; diff --git a/Server/mods/deathmatch/logic/CPed.h b/Server/mods/deathmatch/logic/CPed.h index 11da52a6422..919097413e1 100644 --- a/Server/mods/deathmatch/logic/CPed.h +++ b/Server/mods/deathmatch/logic/CPed.h @@ -259,6 +259,10 @@ class CPed : public CElement unsigned int GetOccupiedVehicleSeat() { return m_uiVehicleSeat; }; CVehicle* SetOccupiedVehicle(CVehicle* pVehicle, unsigned int uiSeat); + CVehicle* GetVehicleOccupiedOnDeath() { return m_pVehicleOnDeath; }; + unsigned int GetVehicleOccupiedSeatOnDeath() { return m_uiVehicleSeatOnDeath; }; + void SetVehicleOccupiedOnDeath(CVehicle* pVehicle, unsigned int uiSeat); + unsigned int GetVehicleAction() { return m_uiVehicleAction; }; void SetVehicleAction(unsigned int uiAction); @@ -359,6 +363,9 @@ class CPed : public CElement unsigned int m_uiVehicleSeat; unsigned int m_uiVehicleAction; + CVehicle* m_pVehicleOnDeath; + unsigned int m_uiVehicleSeatOnDeath; + bool m_bSyncable; bool m_bCollisionsEnabled; diff --git a/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp b/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp index 2bfc7345024..0c3026584ba 100644 --- a/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp +++ b/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp @@ -2461,7 +2461,10 @@ CVehicle* CStaticFunctionDefinitions::GetPedOccupiedVehicle(CPed* pPed) { assert(pPed); - return pPed->GetOccupiedVehicle(); + if (CVehicle* pVehicle = pPed->GetOccupiedVehicle()) + return pVehicle; + + return pPed->IsDead() ? pPed->GetVehicleOccupiedOnDeath() : NULL; } bool CStaticFunctionDefinitions::GetPedOccupiedVehicleSeat(CPed* pPed, unsigned int& uiSeat) @@ -2473,6 +2476,13 @@ bool CStaticFunctionDefinitions::GetPedOccupiedVehicleSeat(CPed* pPed, unsigned uiSeat = pPed->GetOccupiedVehicleSeat(); return true; } + + if (pPed->IsDead() && pPed->GetVehicleOccupiedOnDeath()) + { + uiSeat = pPed->GetVehicleOccupiedSeatOnDeath(); + return true; + } + return false; } @@ -3961,11 +3971,15 @@ bool CStaticFunctionDefinitions::KillPed(CElement* pElement, CElement* pKiller, pPed->SetVehicleAction(CPed::VEHICLEACTION_NONE); // Remove him from any occupied vehicle + // The client keeps the ped paired with the vehicle until it respawns, + // so remember it and let the occupied-vehicle getters report it while dead CVehicle* pVehicle = pPed->GetOccupiedVehicle(); if (pVehicle) { - pVehicle->SetOccupant(NULL, pPed->GetOccupiedVehicleSeat()); + const unsigned int uiOccupiedSeat = pPed->GetOccupiedVehicleSeat(); + pVehicle->SetOccupant(NULL, uiOccupiedSeat); pPed->SetOccupiedVehicle(NULL, 0); + pPed->SetVehicleOccupiedOnDeath(pVehicle, uiOccupiedSeat); } // Update the ped