Combatbeginner10 min readupdated 19 Sept 2026

Stopping NPC weapon drops and vehicle weapon rewards

The 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.

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.

Stopping NPC weapon drops and vehicle weapon rewards — illustrated with a FiveM-compatible minimap render

#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.

#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
CreateThread(function()
    local playerId = PlayerId()
    while true do
        DisablePlayerVehicleRewards(playerId)
        Wait(0)
    end
end)

#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
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
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
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.

#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
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
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.

#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.

Share this guideXRedditFacebook

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.

Ready to pick a map?

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

Relevant to what you just read

The tool for this

Twenty theme pairs for ox_lib and ox_inventory From $15, built in the browser, exported as a drop-in resource.

Look it up while you work

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