Skip to content

Commit d035b35

Browse files
committed
enter and exit vehicle
1 parent bbe006d commit d035b35

File tree

5 files changed

+160
-21
lines changed

5 files changed

+160
-21
lines changed

SDK

Server/Components/NPCs/NPC/npc.cpp

Lines changed: 100 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,7 @@
1212
#include <math.h>
1313
#include "../npcs_impl.hpp"
1414
#include "../utils.hpp"
15-
16-
namespace utils
17-
{
18-
float getAngleOfLine(float x, float y)
19-
{
20-
float angle = atan2(y, x) * (180.0f / M_PI) + 270.0f;
21-
if (angle >= 360.0f)
22-
{
23-
angle -= 360.0f;
24-
}
25-
else if (angle < 0.0f)
26-
{
27-
angle += 360.0f;
28-
}
29-
return angle;
30-
}
31-
}
15+
#include <Server/Components/Vehicles/vehicle_seats.hpp>
3216

3317
NPC::NPC(NPCComponent* component, IPlayer* playerPtr)
3418
: skin_(0)
@@ -65,6 +49,10 @@ NPC::NPC(NPCComponent* component, IPlayer* playerPtr)
6549
, hitType_(PlayerBulletHitType_None)
6650
, lastDamager_(nullptr)
6751
, lastDamagerWeapon_(PlayerWeapon_End)
52+
, vehicleToEnter_(nullptr)
53+
, vehicleSeatToEnter_(SEAT_NONE)
54+
, enteringVehicle_(false)
55+
, jackingVehicle_(false)
6856
{
6957
// Fill weapon accuracy with 1.0f, let server devs change it with the desired values
7058
weaponAccuracy.fill(1.0f);
@@ -243,7 +231,7 @@ bool NPC::move(Vector3 pos, NPCMoveType moveType, float moveSpeed)
243231
}
244232

245233
auto rotation = getRotation().ToEuler();
246-
rotation.z = utils::getAngleOfLine(front.x, front.y);
234+
rotation.z = getAngleOfLine(front.x, front.y);
247235
footSync_.Rotation = rotation; // Do this directly, if you use NPC::setRotation it's going to cause recursion
248236

249237
// Calculate velocity to use on tick
@@ -259,7 +247,6 @@ bool NPC::move(Vector3 pos, NPCMoveType moveType, float moveSpeed)
259247
}
260248

261249
// Set internal variables
262-
moveSpeed_ = moveSpeed_;
263250
targetPosition_ = pos;
264251
moving_ = true;
265252
moveType_ = moveType;
@@ -872,6 +859,100 @@ float NPC::getWeaponAccuracy(uint8_t weapon) const
872859
return ret;
873860
}
874861

862+
void NPC::enterVehicle(IVehicle& vehicle, uint8_t seatId, NPCMoveType moveType)
863+
{
864+
if (player_->getState() != PlayerState_OnFoot)
865+
{
866+
return;
867+
}
868+
869+
if (int(moveType) > int(NPCMoveType_Sprint) || int(moveType) < int(NPCMoveType_Walk))
870+
{
871+
moveType = NPCMoveType_Jog;
872+
}
873+
874+
int passengerSeats = Impl::getVehiclePassengerSeats(vehicle.getModel());
875+
if (passengerSeats == 0xFF || seatId < 1 || seatId > passengerSeats)
876+
{
877+
return;
878+
}
879+
880+
auto destination = getVehicleSeatPos(vehicle, seatId);
881+
float distance = glm::distance(getPosition(), destination);
882+
if (distance > MAX_DISTANCE_TO_ENTER_VEHICLE)
883+
{
884+
return;
885+
}
886+
887+
// Save the entering stats
888+
vehicleToEnter_ = &vehicle;
889+
vehicleSeatToEnter_ = seatId;
890+
891+
// Check distance
892+
if (distance < MIN_VEHICLE_GO_TO_DISTANCE)
893+
{
894+
// Wait until the entry animation is finished
895+
vehicleEnterExitUpdateTime_ = lastUpdate_;
896+
enteringVehicle_ = true;
897+
898+
// Check whether the player is jacking the vehicle or not
899+
if (seatId == 0)
900+
{
901+
IPlayer* driver = vehicle.getDriver();
902+
if (driver && driver->getID() != player_->getID())
903+
{
904+
jackingVehicle_ = true;
905+
}
906+
}
907+
else
908+
{
909+
const FlatHashSet<IPlayer*>& passengers = vehicle.getPassengers();
910+
for (auto passenger : passengers)
911+
{
912+
if (passenger && passenger->getID() != player_->getID())
913+
{
914+
IPlayerVehicleData* data = queryExtension<IPlayerVehicleData>(passenger);
915+
if (data && data->getSeat() == seatId)
916+
{
917+
jackingVehicle_ = true;
918+
}
919+
}
920+
}
921+
}
922+
923+
// Call the SAMP enter vehicle function
924+
NetworkBitStream bs;
925+
bs.writeUINT16(vehicle.getID());
926+
bs.writeUINT8(vehicleSeatToEnter_);
927+
npcComponent_->emulateRPCIn(*player_, NetCode::RPC::OnPlayerEnterVehicle::PacketID, bs);
928+
}
929+
else
930+
{
931+
// Go to the vehicle
932+
move(destination, moveType);
933+
}
934+
}
935+
936+
void NPC::exitVehicle()
937+
{
938+
if (player_->getState() != PlayerState_Driver && player_->getState() != PlayerState_Passenger)
939+
{
940+
return;
941+
}
942+
943+
IPlayerVehicleData* vehicleData = queryExtension<IPlayerVehicleData>(player_);
944+
if (!vehicleData || vehicleData->getVehicle() == nullptr)
945+
{
946+
return;
947+
}
948+
949+
NetworkBitStream bs;
950+
bs.writeUINT16(vehicleData->getVehicle()->getID());
951+
npcComponent_->emulateRPCIn(*player_, NetCode::RPC::OnPlayerExitVehicle::PacketID, bs);
952+
953+
vehicleEnterExitUpdateTime_ = lastUpdate_;
954+
}
955+
875956
void NPC::setWeaponState(PlayerWeaponState state)
876957
{
877958
if (state == PlayerWeaponState_Unknown)

Server/Components/NPCs/NPC/npc.hpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,10 @@ class NPC : public INPC, public PoolIDProvider, public NoCopy
121121

122122
float getWeaponAccuracy(uint8_t weapon) const override;
123123

124+
void enterVehicle(IVehicle& vehicle, uint8_t seatId, NPCMoveType moveType) override;
125+
126+
void exitVehicle() override;
127+
124128
void setWeaponState(PlayerWeaponState state);
125129

126130
void updateWeaponState();
@@ -229,6 +233,13 @@ class NPC : public INPC, public PoolIDProvider, public NoCopy
229233
IPlayer* lastDamager_;
230234
uint8_t lastDamagerWeapon_;
231235

236+
// Vehicle data
237+
IVehicle* vehicleToEnter_;
238+
int vehicleSeatToEnter_;
239+
bool enteringVehicle_;
240+
bool jackingVehicle_;
241+
TimePoint vehicleEnterExitUpdateTime_;
242+
232243
// Packets
233244
NetCode::Packet::PlayerFootSync footSync_;
234245
NetCode::Packet::PlayerVehicleSync driverSync_;

Server/Components/NPCs/utils.hpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#pragma once
22
#include <sdk.hpp>
33
#include "npcs_impl.hpp"
4+
#include <Server/Components/Vehicles/vehicle_models.hpp>
45

56
#define MAX_HIT_RADIUS 0.4f
67
#define MAX_HIT_RADIUS_VEHICLE 1.0f
@@ -589,3 +590,50 @@ inline bool isEqualFloat(float a, float b)
589590
{
590591
return glm::epsilonEqual(a, b, glm::epsilon<float>());
591592
}
593+
594+
inline float getAngleOfLine(float x, float y)
595+
{
596+
float angle = atan2(y, x) * (180.0f / M_PI) + 270.0f;
597+
if (angle >= 360.0f)
598+
{
599+
angle -= 360.0f;
600+
}
601+
else if (angle < 0.0f)
602+
{
603+
angle += 360.0f;
604+
}
605+
return angle;
606+
}
607+
608+
inline Vector3 getVehicleSeatPos(IVehicle& vehicle, int seatId)
609+
{
610+
// Get the seat position
611+
Vector3 seatPosFromModelInfo;
612+
613+
if (seatId == 0 || seatId == 1)
614+
{
615+
Impl::getVehicleModelInfo(vehicle.getModel(), VehicleModelInfo_FrontSeat, seatPosFromModelInfo);
616+
}
617+
else
618+
{
619+
Impl::getVehicleModelInfo(vehicle.getModel(), VehicleModelInfo_RearSeat, seatPosFromModelInfo);
620+
}
621+
622+
// Adjust the seat vector
623+
Vector3 seatPosNoAngle(seatPosFromModelInfo.x + 1.3f, seatPosFromModelInfo.y - 0.6f, seatPosFromModelInfo.z);
624+
625+
if (seatId == 0 || seatId == 2)
626+
{
627+
seatPosNoAngle.x = -seatPosNoAngle.x;
628+
}
629+
630+
// Get vehicle angle
631+
float angle = vehicle.getZAngle();
632+
float _angle = angle * 0.01570796326794897f;
633+
634+
Vector3 seatPos(seatPosNoAngle.x * cos(_angle) - seatPosNoAngle.y * sin(_angle),
635+
seatPosNoAngle.x * sin(_angle) + seatPosNoAngle.y * cos(_angle),
636+
seatPosNoAngle.z);
637+
638+
return seatPos + vehicle.getPosition();
639+
}

Shared/NetCode/vehicle.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,6 @@ namespace RPC
214214
bool read(NetworkBitStream& bs)
215215
{
216216
return bs.readUINT16(VehicleID);
217-
;
218217
}
219218

220219
void write(NetworkBitStream& bs) const

0 commit comments

Comments
 (0)