From f685a0bcd94f5268157e5b44a339cdcad6788154 Mon Sep 17 00:00:00 2001 From: ricardoofnl Date: Fri, 4 Sep 2026 23:02:03 +0700 Subject: [PATCH] [saco] Implement/match `ScrPutPlayerInVehicle`, `ScrUnk9F` and `ScrUnk50`; repeating `GetVehiclePool()` instead of caching it in a local is what keeps the second slot-state test --- saco/net/scriptrpc.cpp | 65 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 3 deletions(-) diff --git a/saco/net/scriptrpc.cpp b/saco/net/scriptrpc.cpp index 2a449ca..54f0668 100644 --- a/saco/net/scriptrpc.cpp +++ b/saco/net/scriptrpc.cpp @@ -96,7 +96,24 @@ void ScrUnk4F(RPCParameters *rpcParams) ScriptCommand(&script_command_0948, fX, fY, fZ, iUnk, fUnk); } -void ScrUnk50(RPCParameters *rpcParams) {} +void ScrUnk50(RPCParameters *rpcParams) +{ + PCHAR Data = reinterpret_cast(rpcParams->input); + int iBitLength = rpcParams->numberOfBitsOfData; + PlayerID sender = rpcParams->sender; + + PLAYERID playerId; + BYTE byteUnk; + + RakNet::BitStream bsData(Data,(iBitLength/8)+1,false); + + bsData.Read(playerId); + bsData.Read(byteUnk); + + if(pNetGame->GetPlayerPool()->GetSlotState(playerId)) { + pNetGame->GetPlayerPool()->GetAt(playerId)->field_4 = (byteUnk != 0); + } +} void ScrUnk63(RPCParameters *rpcParams) {} void ScrUnk7A(RPCParameters *rpcParams) {} void ScrUnk7B(RPCParameters *rpcParams) {} @@ -531,7 +548,27 @@ void ScrUnk0D(RPCParameters *rpcParams) pLocalPlayer->sub_10003710(0, 0); pLocalPlayer->GetPlayerPed()->TeleportTo(vecPos.X, vecPos.Y, vecPos.Z); } -void ScrPutPlayerInVehicle(RPCParameters *rpcParams) {} +void ScrPutPlayerInVehicle(RPCParameters *rpcParams) +{ + PCHAR Data = reinterpret_cast(rpcParams->input); + int iBitLength = rpcParams->numberOfBitsOfData; + PlayerID sender = rpcParams->sender; + + VEHICLEID vehicleId; + BYTE byteSeatId; + + RakNet::BitStream bsData(Data,(iBitLength/8)+1,false); + + bsData.Read(vehicleId); + bsData.Read(byteSeatId); + + int iGtaVehicleId = pNetGame->GetVehiclePool()->FindGtaIDFromID(vehicleId); + int iVehicle = pNetGame->GetVehiclePool()->GetAt(vehicleId); + + if(iGtaVehicleId && iVehicle) { + pGame->FindPlayerPed()->FUNC_100AC290(iGtaVehicleId, byteSeatId); + } +} void ScrRemovePlayerFromVehicle(RPCParameters *rpcParams) { PCHAR Data = reinterpret_cast(rpcParams->input); @@ -578,7 +615,29 @@ void ScrSetInterior(RPCParameters *rpcParams) pGame->FindPlayerPed()->SetInterior(byteInterior, TRUE); } -void ScrUnk9F(RPCParameters *rpcParams) {} +void ScrUnk9F(RPCParameters *rpcParams) +{ + PCHAR Data = reinterpret_cast(rpcParams->input); + int iBitLength = rpcParams->numberOfBitsOfData; + PlayerID sender = rpcParams->sender; + + VEHICLEID vehicleId; + float fX, fY, fZ; + + RakNet::BitStream bsData(Data,(iBitLength/8)+1,false); + + bsData.Read(vehicleId); + bsData.Read(fX); + bsData.Read(fY); + bsData.Read(fZ); + + if(!pNetGame) return; + if(!pNetGame->GetVehiclePool()) return; + + if(pNetGame->GetVehiclePool()->GetSlotState(vehicleId)) { + ((CEntity *)pNetGame->GetVehiclePool()->GetAt(vehicleId))->TeleportTo(fX, fY, fZ); + } +} void ScrUnkA0(RPCParameters *rpcParams) {} void ScrUnkA1(RPCParameters *rpcParams) {} void ScrUnk0F(RPCParameters *rpcParams)