Combatintermediate11 min readupdated 19 Sept 2026

Controlling drive-by shooting on a FiveM server

The short answer

SetPlayerCanDoDriveBy(PlayerId(), false) turns off aiming and shooting from vehicles for the local player; it is a toggle, not a per-frame call. For driver-only rules, check GetPedInVehicleSeat(vehicle, -1) and flip the toggle when the player changes seat. Finer rules, such as weapon allow lists or speed limits, disable the vehicle aim and attack controls (68, 69, 70, 91, 92) per frame. Mounted guns are separate: use DisableVehicleWeapon. Back it up on the server with a weaponDamageEvent check.

Drive-bys are the fastest way to turn a roleplay chase into a one-sided shooting gallery. A driver who can steer at full speed while emptying an SMG out of the window has no reason to ever stop the car, and police chases stop being about driving. Most servers do not want drive-bys gone entirely, they want them fair: passengers can shoot, drivers drive.

Controlling drive-by shooting on a FiveM server — illustrated with a FiveM-compatible minimap render

#What counts as a drive-by

In GTA terms a drive-by is any aiming or shooting a ped does while seated in a vehicle: leaning out of a car window with a pistol, firing an SMG from a motorbike, or shooting from a boat. The native reference for SetPlayerCanDoDriveBy notes that it also covers the middle-finger taunt, since that uses the same in-vehicle aiming system.

Two things look similar but are not drive-bys:

  • Vehicle weapons, such as the mounted guns on armed vans, jeeps and helicopters, or the cannon on a tank. These belong to the vehicle and are handled with vehicle weapon natives.
  • Shooting while standing on a vehicle, for example from the back of a truck bed while not seated. That is normal on-foot shooting.

Decide which you want before writing code. "No drive-bys" on a roleplay server almost always means "drivers may not shoot"; on a PvP server it might mean the opposite.

#Turning drive-bys off completely

The simplest rule is one call. The native is a toggle for the player, so run it once when the player spawns rather than in a per-frame loop.

client.lua
AddEventHandler('playerSpawned', function()
    SetPlayerCanDoDriveBy(PlayerId(), false)
end)

CreateThread(function()
    SetPlayerCanDoDriveBy(PlayerId(), false)
end)

The second block covers the resource being restarted while players are already in the game. Frameworks with their own spawn events (esx:playerLoaded, QBCore:Client:OnPlayerLoaded) work just as well; the point is to set it once per session and after anything that might reset the player.

#Blocking drivers, allowing passengers

The common roleplay rule checks the seat. The driver's seat index is -1; passengers are 0 and up. Poll a few times a second and flip the toggle only when the answer changes.

client.lua
local allowed = true

local function setDriveBy(state)
    if state ~= allowed then
        allowed = state
        SetPlayerCanDoDriveBy(PlayerId(), state)
    end
end

CreateThread(function()
    while true do
        local ped = PlayerPedId()
        local vehicle = GetVehiclePedIsIn(ped, false)

        if vehicle ~= 0 and GetPedInVehicleSeat(vehicle, -1) == ped then
            setDriveBy(false)
        else
            setDriveBy(true)
        end
        Wait(250)
    end
end)

A quarter of a second is fast enough that nobody can shuffle into the driver's seat and fire before the rule catches up, and slow enough to cost nothing. If you also block seat shuffling, that window disappears entirely.

#Weapon allow lists and speed limits

The toggle is all or nothing. For finer rules, leave drive-bys enabled and disable the in-vehicle aim and fire controls on frames where the rule says no.

IndexControlDefault key
68INPUT_VEH_AIMRight mouse
69INPUT_VEH_ATTACKLeft mouse
70INPUT_VEH_ATTACK2Right mouse
91INPUT_VEH_PASSENGER_AIMRight mouse
92INPUT_VEH_PASSENGER_ATTACKLeft mouse

Vehicle combat controls

This example lets passengers shoot only pistols and SMGs, and blocks everyone above 80 km/h:

client.lua
local ALLOWED_GROUPS = {
    [`GROUP_PISTOL`] = true,
    [`GROUP_SMG`] = true,
}
local MAX_SPEED = 80.0 / 3.6 -- km/h to m/s

local function blockVehicleCombat()
    DisableControlAction(0, 68, true)
    DisableControlAction(0, 69, true)
    DisableControlAction(0, 70, true)
    DisableControlAction(0, 91, true)
    DisableControlAction(0, 92, true)
end

CreateThread(function()
    while true do
        local ped = PlayerPedId()
        local vehicle = GetVehiclePedIsIn(ped, false)

        if vehicle == 0 then
            Wait(500)
        else
            local weapon = GetSelectedPedWeapon(ped)
            local group = GetWeapontypeGroup(weapon)
            local tooFast = GetEntitySpeed(vehicle) > MAX_SPEED

            if not ALLOWED_GROUPS[group] or tooFast then
                blockVehicleCombat()
            end
            Wait(0)
        end
    end
end)

The loop only runs every frame while the player is inside a vehicle and sleeps otherwise. Weapon groups come from the Group field in weapons.meta, so an add-on SMG with GROUP_SMG is allowed automatically. Note that the machine guns in vanilla GTA are in GROUP_MG, not GROUP_SMG, so they stay blocked here.

Combining this with the driver-only rule from the previous section is straightforward: turn the toggle off for drivers and run the control loop for passengers.

#Disabling mounted vehicle weapons

Armed vehicles have their own weapons, named VEHICLE_WEAPON_..., for example VEHICLE_WEAPON_TANK, VEHICLE_WEAPON_TURRET_INSURGENT and VEHICLE_WEAPON_PLAYER_BUZZARD. SetPlayerCanDoDriveBy is about hand-held weapons, so handle mounted guns separately. DisableVehicleWeapon(disabled, weaponHash, vehicle, owner) turns a specific one off for a specific ped.

client.lua
local BLOCKED = {
    `VEHICLE_WEAPON_TANK`,
    `VEHICLE_WEAPON_PLAYER_BUZZARD`,
    `VEHICLE_WEAPON_TURRET_INSURGENT`,
    `VEHICLE_WEAPON_TURRET_TECHNICAL`,
}

CreateThread(function()
    local lastVehicle = 0
    while true do
        local ped = PlayerPedId()
        local vehicle = GetVehiclePedIsIn(ped, false)
        if vehicle ~= 0 and vehicle ~= lastVehicle and DoesVehicleHaveWeapons(vehicle) then
            for i = 1, #BLOCKED do
                DisableVehicleWeapon(true, BLOCKED[i], vehicle, ped)
            end
        end
        lastVehicle = vehicle
        Wait(500)
    end
end)

Most roleplay servers simply do not allow armed vehicles to be spawned or bought, which is the more robust fix. The native is useful when a vehicle is needed for its looks, a police Insurgent for example, without its turret.

#Middle-finger taunts and unarmed drive-bys

Because the same system drives the in-vehicle taunt, disabling drive-bys also stops players flipping each other off from a car. If you want the taunt but not the guns, use the control-based approach and only block while a weapon is selected (GetSelectedPedWeapon(ped) ~= WEAPON_UNARMED). The ped config flag reference also lists flag 123 as DisableUnarmedDrivebys, which targets the unarmed side on its own.

#Backing it up on the server

Everything above runs on the client, so a modified client can ignore it. With OneSync the server can see who is in which seat, and weaponDamageEvent fires before damage is applied, which is enough to reject hits from drivers.

server.lua
AddEventHandler('weaponDamageEvent', function(sender, data)
    local ped = GetPlayerPed(sender)
    if ped == 0 then return end

    local vehicle = GetVehiclePedIsIn(ped, false)
    if vehicle ~= 0 and GetPedInVehicleSeat(vehicle, -1) == ped then
        CancelEvent()
        print(('[driveby] blocked damage from driver %s (%s)'):format(GetPlayerName(sender), sender))
    end
end)

Log before you punish. Ramming, explosions and a few edge cases involving vehicle weapons can produce damage events from drivers that are not drive-bys, so watch the log for a week before turning it into an automatic kick. The wider pattern is in server-side weapon validation.

#Testing each rule

Drive-by rules are easy to get subtly wrong, because the same player moves between seats, vehicles and weapons constantly. Walk through these with a second player:

  1. Driver, pistol drawn. Aim with right mouse. Nothing should happen, and no shots should fire with left mouse.
  2. Passenger, same pistol. Aiming and shooting should work. Swap seats with the driver and confirm the rules follow the seat, not the person.
  3. Passenger, blocked weapon. Select a rifle or machine gun and confirm it cannot fire from the car.
  4. Speed limit. Accelerate past the limit as a passenger and confirm shooting stops, then slows back under it.
  5. Motorbike. Ride alone and with a pillion to see what your bike rule does.
  6. Armed vehicle. Enter a vehicle with a mounted gun and confirm the turret is disabled for the seats you blocked.
  7. Server log. Check the server console for [driveby] lines from the test, which proves the server-side check sees drivers correctly.

If step 1 fails but the others pass, another resource is probably calling SetPlayerCanDoDriveBy(PlayerId(), true) after yours. Search your resources for the native; old framework scripts and HUDs sometimes set it on spawn.

#Roleplay rules that work alongside the script

  • Write it in the rules. Players accept a script that enforces a written rule far better than one that silently blocks them.
  • Give passengers a reason to exist. Drive-by rules make a second person in the car valuable, which is good for group roleplay.
  • Think about police. Some servers let police passengers return fire but not civilians; that is a job check around the same code.
  • Pair it with aiming rules. First-person-only aiming in vehicles is a popular companion setting, covered in forcing first-person aiming.
Share this guideXRedditFacebook

Questions

How do I disable drive-by in FiveM?
Call SetPlayerCanDoDriveBy(PlayerId(), false) on the client once per session. It is a toggle, so it does not need to run every frame.
How do I let passengers shoot but not drivers?
Check whether GetPedInVehicleSeat(vehicle, -1) is the player's ped and toggle SetPlayerCanDoDriveBy off for drivers and on for everyone else.
Which controls are used for shooting from a vehicle?
68 (vehicle aim), 69 (vehicle attack), 70 (vehicle attack 2) for the driver and 91 and 92 for passenger aim and attack.
How do I disable the guns on armed vehicles?
Use DisableVehicleWeapon(true, weaponHash, vehicle, ped) with the vehicle weapon's hash, such as VEHICLE_WEAPON_TANK, or do not allow armed vehicles to be spawned.
Can a cheater bypass a drive-by script?
The client part, yes. Add a server check in weaponDamageEvent that cancels damage coming from a player sitting in the driver's seat.

Ready to pick a map?

Twelve themes on three base map styles, $8 each, instant download.

Relevant to what you just read

Look it up while you work

The reference tables this guide leans on, free and without an account.