# Stopping NPC weapon drops and vehicle weapon rewards

> Stop free guns on your FiveM server: disable NPC weapon drops on death, police car shotgun rewards and weapon pickups, and see what ox_inventory handles.

Source: https://fam-tools.com/guides/fivem-disable-npc-weapon-drops · FAM Tools · published 2026-09-19 · updated 2026-09-19 · about 10 min

**Short answer.** Ambient peds drop their weapon as a pickup when they die; stop it with `SetPedDropsWeaponsWhenDead(ped, false)` applied to every non-player ped, which you can find with `GetGamePool('CPed')`. Entering some vehicles gives a weapon reward; call `DisablePlayerVehicleRewards(PlayerId())` every frame. Clean up any pickups that still spawn with `RemoveAllPickupsOfType` and the `PICKUP_WEAPON_` hashes. ox_inventory already disables vehicle rewards and disarms weapons it did not equip.

## Key points

- NPC drops and vehicle rewards are separate systems with separate fixes.
- `SetPedDropsWeaponsWhenDead` is per ped, so it has to be applied to peds as they spawn.
- `DisablePlayerVehicleRewards` only lasts one frame; call it in a per-frame loop.
- Pickup hashes follow the weapons.meta `PickupHash` field, such as `PICKUP_WEAPON_PISTOL`.
- ox_inventory handles vehicle rewards and unissued weapons for you; standalone and ESX loadout servers need this script.

Every weapon economy on a FiveM server has the same leak on day one. Punch a gang member in Grove Street and his pistol falls to the pavement. Steal a police cruiser and you drive away with a shotgun. Neither weapon went through your shop, your crafting bench or your inventory, and on an inventory server they cause a second problem: a gun the inventory never issued.

## Why free weapons are a problem

A weapon economy only works if every gun enters the world through a door you control: a shop, a crafting recipe, a heist reward, an armory. Two vanilla GTA systems ignore those doors.

- **Death drops.** When an armed ambient ped dies, the game spawns a pickup of their weapon. On a busy city server with gang peds, that is a steady supply of pistols and SMGs.
- **Vehicle rewards.** Getting into certain vehicles, police cars being the famous example, hands the player a weapon.

On an ESX loadout server both drops go straight into the player's loadout on the next save. On an inventory server the weapon exists on the ped without an item, which confuses the inventory and can trip anticheat checks that compare held weapons with issued ones. See [server-side weapon validation](https://fam-tools.com/guides/fivem-weapon-anticheat-validation).

## Vehicle weapon rewards

`DisablePlayerVehicleRewards(player)` disables vehicle rewards for the current frame only, so it must run every frame. It is cheap: a single native call per tick.

*client.lua*

```lua
CreateThread(function()
    local playerId = PlayerId()
    while true do
        DisablePlayerVehicleRewards(playerId)
        Wait(0)
    end
end)
```

> **Already done on ox_inventory** — ox_inventory calls `DisablePlayerVehicleRewards` in its own client tick, so on an ox server you do not need this loop. Add it on ESX loadout, QBCore without ox and standalone servers.

## NPC death drops

`SetPedDropsWeaponsWhenDead(ped, toggle)` controls whether a ped leaves its weapon behind when it dies. It is a property of each ped, not a global setting, so ambient peds that spawn after you set it are unaffected. The practical approach is a slow loop over the ped pool that flags every non-player ped.

*client.lua*

```lua
local flagged = {}

CreateThread(function()
    while true do
        for _, ped in ipairs(GetGamePool('CPed')) do
            if not flagged[ped] and not IsPedAPlayer(ped) then
                SetPedDropsWeaponsWhenDead(ped, false)
                flagged[ped] = true
            end
        end
        Wait(1000)
    end
end)

CreateThread(function()
    while true do
        Wait(60000)
        for ped in pairs(flagged) do
            if not DoesEntityExist(ped) then flagged[ped] = nil end
        end
    end
end)
```

`GetGamePool('CPed')` returns every ped handle this client knows about. The cache stops the loop calling the native thousands of times a minute for the same peds, and the second thread prunes handles that no longer exist so the table does not grow forever.

A ped that spawns and dies within the same second can still drop a weapon. That is rare with a one-second loop, and the pickup cleanup below catches it.

## Removing weapon pickups

When a pickup does appear, `RemoveAllPickupsOfType(pickupHash)` deletes every pickup of that type near the client. Pickup names come from the `PickupHash` field in weapons.meta and follow the `PICKUP_WEAPON_` pattern: the pistol's is `PICKUP_WEAPON_PISTOL`, the carbine's `PICKUP_WEAPON_CARBINERIFLE`, the pump shotgun's `PICKUP_WEAPON_PUMPSHOTGUN`.

*client.lua*

```lua
local PICKUPS = {
    `PICKUP_WEAPON_PISTOL`,
    `PICKUP_WEAPON_COMBATPISTOL`,
    `PICKUP_WEAPON_APPISTOL`,
    `PICKUP_WEAPON_MICROSMG`,
    `PICKUP_WEAPON_SMG`,
    `PICKUP_WEAPON_CARBINERIFLE`,
    `PICKUP_WEAPON_PUMPSHOTGUN`,
    `PICKUP_WEAPON_SNIPERRIFLE`,
    `PICKUP_WEAPON_MG`,
}

CreateThread(function()
    while true do
        for i = 1, #PICKUPS do
            RemoveAllPickupsOfType(PICKUPS[i])
        end
        Wait(500)
    end
end)
```

Extend the list with the weapons your ambient population actually carries. Gang peds usually hold pistols and SMGs; police and military NPCs carry pistols, carbines and pump shotguns. The native reference links a community list of pickup hashes if you need more.

There is also `ToggleUsePickupsForPlayer(player, pickupHash, toggle)`, which stops the local player collecting a given pickup type. It is a useful belt-and-braces addition for high-value weapons.

## What ox_inventory already covers

ox_inventory is strict about weapons by design:

- It calls `DisablePlayerVehicleRewards` every tick.
- With the `inventory:weaponmismatch` convar enabled, which is the default, it disarms any weapon in the player's hands that it did not equip itself. A pistol picked up from a dead NPC is removed as soon as the player selects it.
- Weapons that should be allowed anyway, such as a scripted tool weapon, go in `inventory:ignoreweapons` as a JSON array.

*server.cfg*

```cfg
setr inventory:weaponmismatch true
setr inventory:ignoreweapons ["WEAPON_FIREEXTINGUISHER"]
```

Even on ox, stopping death drops is still worth doing. A pickup lying on the street invites players to try, and the "you picked up a weapon, it vanished" cycle looks like a bug to them.

## ESX loadout, QBCore and standalone

- **ESX with the built-in loadout.** This is the most exposed setup: the loadout is synced from the ped, so a picked-up pistol becomes a saved weapon. Run all three pieces: vehicle rewards, death drops and pickup cleanup.
- **QBCore with qb-inventory.** Weapons are items, but the vanilla pickups still put guns on the ped. Run the scripts and consider a server-side check that compares `GetSelectedPedWeapon` with the player's items.
- **Standalone and PvP servers.** Deathmatch modes sometimes want drops. Leave them on in arenas and switch them off elsewhere with the zone logic from [redzone and PvP setup](https://fam-tools.com/guides/fivem-redzone-pvp-weapon-setup).

## A single drop-in resource

Put the three loops into one small resource and start it after your framework. The combined cost is one native per frame plus two light loops, which is negligible even on low-end clients.

*fxmanifest.lua*

```lua
fx_version 'cerulean'
game 'gta5'

client_script 'client.lua'
```

1. Create a folder such as `no_free_guns` in your resources directory.
2. Add the manifest above and a `client.lua` holding the vehicle reward loop, the ped flag loop and the pickup cleanup loop.
3. Add `ensure no_free_guns` to server.cfg after your framework and inventory.
4. Test by killing an armed gang ped and entering a police car. No pickup should appear and no weapon should be given.

## Going further: an unarmed ambient population

Some serious roleplay servers go one step beyond stopping drops and take the guns off ambient peds altogether. Nobody random pulls a pistol in a traffic dispute, gang turf only feels dangerous where you have placed armed guards on purpose, and there is nothing left to drop in the first place.

The same pool loop does it. Instead of only flagging the ped, remove its weapons the first time you see it.

*client.lua*

```lua
local seen = {}

CreateThread(function()
    while true do
        for _, ped in ipairs(GetGamePool('CPed')) do
            if not seen[ped] and not IsPedAPlayer(ped) and not IsEntityAMissionEntity(ped) then
                SetPedDropsWeaponsWhenDead(ped, false)
                RemoveAllPedWeapons(ped, true)
                seen[ped] = true
            end
        end
        Wait(1000)
    end
end)
```

The mission entity check matters. Peds spawned by your own scripts, such as bank guards, gang lookouts or a heist crew, are mission entities, and you do not want the city-wide loop to disarm the guards you just armed. Ambient population peds are not mission entities, so they are the only ones affected.

Two side effects to expect. Armed police NPCs are part of the ambient population, so if you still use GTA's wanted system, officers arrive without guns; most roleplay servers disable NPC police anyway. And peds that were already fleeing or fighting when they lost their weapon may switch to fists, which is usually what you want.

> **Do it on every client** — Ped handles and the ped pool are local to each client, and every client only sees peds near it. The loop has to run on all clients, which is why it lives in a client script, not on the server.

## Testing the fix

Test each leak separately so you know which part works:

1. **Vehicle rewards.** Spawn a police cruiser and get in. Your weapon wheel or inventory should be unchanged.
2. **Death drops.** Give a nearby ambient ped a pistol with `GiveWeaponToPed`, kill it and watch the ground. Nothing should appear. If something does, the flag loop missed it and the pickup cleanup should delete it within half a second.
3. **Pickup collection.** If a pickup does survive, try to collect it. With `ToggleUsePickupsForPlayer` set for that type, nothing should happen.
4. **Your own peds.** Walk up to a scripted guard and confirm it is still armed, which proves the mission entity check works.

Test with two clients where possible. A pickup that only one client removed can still be collected by the other.

## What this does not cover

Player deaths are a different topic. Whether a dead player's weapons drop for others to loot is an inventory decision, handled in [dropping weapons on death](https://fam-tools.com/guides/fivem-drop-weapons-on-death). NPC behaviour, such as how accurately gang peds shoot back, is covered in [NPC accuracy and combat AI](https://fam-tools.com/guides/fivem-npc-accuracy-combat-ai).

## Questions

### How do I stop NPCs dropping weapons in FiveM?

Loop over `GetGamePool('CPed')` on the client and call `SetPedDropsWeaponsWhenDead(ped, false)` for every ped that is not a player. Clean up leftover pickups with `RemoveAllPickupsOfType`.

### How do I stop players getting a shotgun from police cars?

Call `DisablePlayerVehicleRewards(PlayerId())` every frame. ox_inventory already does this.

### Why does the weapon I picked up disappear on ox_inventory?

ox_inventory disarms weapons it did not equip when `inventory:weaponmismatch` is enabled, which it is by default. That is intended; disable the drops so players are not offered the weapon in the first place.

### What are the pickup hash names for weapons?

They come from the `PickupHash` field in weapons.meta and look like `PICKUP_WEAPON_PISTOL` or `PICKUP_WEAPON_CARBINERIFLE`.

### Is SetPedDropsWeaponsWhenDead global?

No. It is set per ped, which is why it has to be applied to new peds as they appear.

## Related

- https://fam-tools.com/guides/fivem-drop-weapons-on-death
- https://fam-tools.com/guides/fivem-npc-accuracy-combat-ai
- https://fam-tools.com/guides/fivem-weapon-balance-roleplay
- https://fam-tools.com/guides/fivem-weapon-anticheat-validation
- https://fam-tools.com/guides/fivem-inventory-systems-compared
