Skip to content

ThrowShield

ThrowShield adds a deployable ballistic shield weapon for FiveM. Players can throw the shield into position, let it unfold into a deployed shield object, then remove it later through target interaction.

The resource also supports manual placement while the shield weapon is equipped, plus a tactical shield drone item for remote shield deployment.

  • ox_lib v3.30.0 or newer.
  • ox_target v1.17.0 or newer.
  • One supported inventory adapter set in Config.inventory:
    • ox_inventory
    • codem-inventory
    • qb-inventory
    • qs-inventory
    • origen_inventory
    • tgiann-inventory
    • standalone
  1. Download the latest granted asset from the Cfx.re Portal.

  2. Install and start ox_lib, ox_target, and your selected inventory resource.

  3. Place both folders in your server resources directory:

    • kf-throw-shield
    • kf-throw-shield-assets
  4. Start dependencies before ThrowShield. Start the asset resource before the script resource so the custom weapon and shield models are registered first.

    server.cfg
    ensure ox_lib
    ensure ox_target
    # Start your inventory.
    ensure ox_inventory
    ensure kf-throw-shield-assets
    ensure kf-throw-shield
  5. Open config.lua and set the inventory, target, and notification adapters for your server.

    config.lua
    Config.inventory = 'ox_inventory'
    Config.target = 'ox_target'
    Config.notifications = true
    Config.notify = 'ox_lib'

    Config.inventory = 'auto' can be used when exactly one supported inventory resource is started. If multiple supported inventory resources are running, set the inventory explicitly.

  6. Add the shield weapon and, if used, the tactical drone shield and tactical drone tablet items to your inventory system.

    For ox_inventory, add the shield weapon to the weapons config file.

    Default location:

    resources/[ox]/ox_inventory/data/weapons.lua
    weapons.lua
    ['WEAPON_KFTHROWSHIELD'] = {
    label = 'Throw Shield',
    weight = 8000,
    throwable = true,
    },
  7. Add the images to the inventory images folder

    Section titled “Add the images to the inventory images folder”

    Add all the image files from kf-throw-shield/inventory-images/ingame OR kf-throw-shield/inventory-images/stylized into the ox_inventory images folder.

    Default location:

    resources/[ox]/ox_inventory/web/images
  8. Add WEAPON_KFTHROWSHIELD and, if used, kf_tactical_drone_shield and kf_tactical_drone_tablet to your armoury, shop, loot table, DutyKit, or other item dispenser method.

The default item name is:

config.lua
Config.shieldItem = 'WEAPON_KFTHROWSHIELD'

The default shield skin is controlled by Config.shieldVariation.

config.lua
Config.shieldVariation = 'Police'

Use the same values for Config.shieldVariation and item metadata type:

  • Regular
  • Regular MK2
  • Police
  • Police MK2
  • FIB
  • FIB MK2
  • Sheriff
  • Sheriff MK2
  • EMS
  • EMS MK2
/giveitem 1 WEAPON_KFTHROWSHIELD 1 "Sheriff MK2"

When adding shield variations to item dispensers, set item metadata type to the variation label.

Example ox_inventory shop item:

ox_inventory/data/shops.lua
PoliceArmoury = {
name = 'Police Armoury',
groups = shared.police,
blip = {
id = 110, colour = 84, scale = 0.8
},
inventory = {
{ name = 'ammo-9', price = 5 },
{ name = 'WEAPON_FLASHLIGHT', price = 200 },
{ name = 'WEAPON_NIGHTSTICK', price = 100 },
{ name = 'WEAPON_KFTHROWSHIELD', price = 500, metadata = { type = 'Police' } },
{ name = 'WEAPON_KFTHROWSHIELD', price = 750, metadata = { type = 'FIB MK2' }, grade = 3 },
},
locations = {
vec3(451.51, -979.44, 30.68)
},
targets = {
{ loc = vec3(453.21, -980.03, 30.68), length = 0.5, width = 3.0, heading = 270.0, minZ = 30.5, maxZ = 32.0, distance = 6 }
}
},

Example DutyKit loadout item:

loadouts/ld_police_shields.lua
items = {
{
itemName = 'bandage',
max = 1,
quick = false,
},
{
itemName = 'WEAPON_KFTHROWSHIELD',
max = 10,
metadata = {
type = 'FIB MK2',
},
quick = false,
},
}

Players equip the WEAPON_KFTHROWSHIELD weapon and throw it like a throwable. After the projectile settles, ThrowShield replaces it with a synced deployed shield object and adds an ox_target option to remove it.

If Config.enableShieldPlacement is enabled, players can also use the global Place shield target option while the shield weapon is equipped. Manual placement shows a preview with rotate, raise/lower, ground snap, cancel, and confirm controls before deploying the shield.

The server selects the shield variation from item metadata when available, tracks active shields, validates placement distance, enforces per-player and global limits, and returns the shield item when a deployed shield is removed.

Thrown deployment expects the inventory system to consume the throwable item. Manual placement consumes the item through ThrowShield before deployment begins.

config.lua
Config = {
debug = true,
notifications = true,
-- 'ox_lib' | 'esx_notify' | 'qb-core' | 'qbx_core' | 'okokNotify' | 'wasabi_notify',
notify = 'ox_lib',
target = 'ox_target',
targetRadius = 2.0,
-- 'auto' | 'standalone' | 'ox_inventory' | 'codem-inventory' | 'qb-inventory' | 'qs-inventory' | 'origen_inventory' | 'tgiann-inventory'
inventory = 'auto',
shieldItem = 'WEAPON_KFTHROWSHIELD',
tacticalDroneItem = 'kf_tactical_drone_shield',
tacticalDroneTabletItem = 'kf_tactical_drone_tablet',
-- Command used to equip/unequip the shield when inventory is set to 'standalone'.
standaloneShieldCommand = 'throwshield',
standaloneTacticalDroneCommand = 'throwdrone',
standaloneTacticalDroneTabletCommand = 'throwdrone_tablet',
-- 'Regular' | 'Regular MK2' | 'Police' | 'Police MK2' | 'FIB' | 'FIB MK2' | 'Sheriff' | 'Sheriff MK2' | 'EMS' | 'EMS MK2'
shieldVariation = 'Police',
-- 'Regular' | 'FIB' | 'Sheriff'
tacticalDroneVariation = 'Regular',
-- Enables the manual 'Place shield' target option while the shield weapon is equipped.
enableShieldPlacement = true,
-- Snaps thrown shield deployment visuals to the ground before the final deployed object is created.
snapDeployingShieldToGround = true,
-- Maximum distance from the player where a shield may be placed.
placeShieldMaxDistance = 10.0,
-- Tactical drone shield remote-control raw keys.
tacticalDroneDeployKey = 'E',
tacticalDroneCancelKey = 'X',
tacticalDroneMaxDistance = 60.0,
tacticalDroneTabletRange = 20.0,
tacticalDroneBatterySeconds = 3600,
tacticalDroneShieldGunShots = 4,
tacticalDroneUseVehicleServerSetter = false,
-- Uses a scripted camera attached to the front of the tactical drone vehicle.
tacticalDroneFrontCamera = true,
tacticalDroneFrontCameraOffset = vector3(0.0, 0.58188, 0.101411),
tacticalDroneFirstPerson = true,
-- Shows the web camera overlay while controlling the tactical drone.
tacticalDroneCameraOverlay = true,
tacticalDroneNightVisionToggleEnabled = true,
tacticalDroneThermalVisionToggleEnabled = true,
-- Distance used by the client placement raycast. Must be at least placeShieldMaxDistance.
placeShieldRaycastDistance = 10.0,
-- Prevents confirming placement when the preview shield overlaps nearby entities or geometry.
placeShieldCollisionCheck = true,
-- Extra clearance around the shield model used by the placement collision check.
placeShieldCollisionPadding = 0.05,
-- Maximum active shields each player can have.
-- Deployed shields are network objects.
-- When a player reaches this limit, their oldest shield is removed so they can deploy another.
maxDeployedShieldsPerPlayer = 3,
-- Maximum active tactical drone shields each player can have.
-- When a player reaches this limit, their oldest tactical drone shield is removed so they can deploy another.
maxActiveTacticalDronesPerPlayer = 1,
-- Maximum active shields across the whole server.
-- This is also a network object budget; avoid high values.
maxTotalDeployedShields = 30,
-- Removes all active shields owned by a player when they disconnect.
clearShieldsOnPlayerDrop = true,
-- ACE permission that can remove any player's shield. Set false to allow only shield owners.
-- Example: add_ace group.admin kf-throw-shield.remove allow
removeShieldAce = false,
}

By default, players can remove only their own shields. To allow a staff or command group to remove any deployed shield, set an ACE permission in config.lua:

config.lua
Config.removeShieldAce = 'kf-throw-shield.remove'

Then grant it in server.cfg:

server.cfg
add_ace group.admin kf-throw-shield.remove allow

The following files are escrow-ignored so you can adapt ThrowShield to custom server stacks without editing locked code:

  • config.lua
  • client/interface/*.lua
  • client/target/*.lua
  • server/inventory/*.lua

Inventory adapters must provide:

ServerFramework.addInventoryItem(player, itemName, amount, metadata)
ServerFramework.removeInventoryItem(player, itemName, amount, metadata, slot)
ServerFramework.getInventoryItem(player, itemName, preferredVariation)

Notification adapters are expected to provide:

ClientFramework.notify(data)