Installation
Welcome to the Bablo Throw Items installation guide! This guide will walk you through the complete installation process for our asset. By following each step carefully, you’ll ensure a smooth and hassle-free setup, provided that all instructions are followed thoroughly.
Download asset
To find the asset, you must have made the purchase using your own cfx account. Otherwise, you can use the transfer system to move the asset to a different cfx account.
After purchasing from our official website, the asset will be delivered directly to your CFX Portal. From your panel, you can download the asset and proceed with the installation using the provided documentation.
Setup CFG
To ensure everything functions correctly when you’re utilizing either the ESX, QBCORE or QBX framework instead of the standalone version, it’s essential to adhere to the following steps carefully. Following these guidelines will help you achieve a seamless integration and maintain optimal performance across your systems.
When setting up your server environment, it is crucial to ensure that your core scripts are initialized before any additional resources. Specifically, the core resources such as es_extended, qb-core or qbx_core should be started first before you introduce other elements like the bablo-throwitems resource. This order is essential for maintaining a stable and functional environment.
-- First we will start the cores, never below
ensure es_extended or qb-core or qbx_core
ensure ox_lib
-- Start your inventory
ensure ox_inventory or qb-inventory
-- Start your target (optional, only if using target mode)
ensure ox_target or qb-target
-- Run bablo-throwitems here
ensure bablo-throwitemsBasic Configuration
Basic Framework Configuration
The asset will function automatically if your framework is named es_extended, qb-core or qbx_core, as it will detect either one when started. If your framework has been renamed, you can update its name in the config.lua file. Additionally, the asset supports standalone mode for users not utilizing a framework.
Inventory Configuration
The inventory is auto-detected. If you need to force a specific inventory, set Config.Inventory in config.lua to either ox_inventory or qb-inventory.
Target / Interaction Configuration
Ground item pickup interaction mode is set via Config.Interact in config.lua:
'dui'(default) — DUI prompt with E key when nearby'target'— Uses your target system (ox_target, qb-target, etc.)
The target system is auto-detected. Set Config.Target manually if needed.
Inventory Setup
Follow the section that matches your inventory system below. ox_inventory is simple — you just add buttons to your items. qb-inventory is more involved and requires editing a few files.
ox_inventory Setup
With ox_inventory, adding throw and place functionality is straightforward. You simply add buttons to any item definition in your ox_inventory/data/items.lua file.
Adding Throw & Place Buttons
For every item you want to be throwable/placeable, add the buttons field to its entry in ox_inventory/data/items.lua:
['burger'] = {
label = 'Burger',
weight = 220,
client = {
status = { hunger = 200000 },
anim = 'eating',
prop = 'burger',
usetime = 2500,
notification = 'You ate a delicious burger'
},
buttons = {
{
label = 'Throw Item',
action = function(slot)
exports['bablo-throwitems']:throwItem(slot)
end
},
{
label = 'Place',
action = function(slot)
exports['bablo-throwitems']:placeItem(slot)
end
}
},
},What the buttons do
- Throw Item — Calls
exports['bablo-throwitems']:throwItem(slot)which enters throw mode. The player aims with RMB, throws with LMB, and can cancel with X. On landing, the item is removed from inventory and spawned as a ground item. - Place — Calls
exports['bablo-throwitems']:placeItem(slot)which lets the player position the item on the ground in front of them with distance and rotation controls.
You can add these buttons to any item. Simply copy the buttons block into the item definition. No other files need to be modified — ox_inventory handles the custom buttons natively.
Full example (data/items.lua)
Here is an example showing the buttons added to a testburger item:
['testburger'] = {
label = 'Test Burger',
weight = 220,
degrade = 60,
client = {
image = 'burger_chicken.png',
status = { hunger = 200000 },
anim = 'eating',
prop = 'burger',
usetime = 2500,
export = 'ox_inventory_examples.testburger'
},
server = {
export = 'ox_inventory_examples.testburger',
test = 'what an amazingly delicious burger, amirite?'
},
buttons = {
{
label = 'Throw Item',
action = function(slot)
exports['bablo-throwitems']:throwItem(slot)
end
},
{
label = 'Place',
action = function(slot)
exports['bablo-throwitems']:placeItem(slot)
end
}
},
consume = 0.3
},That’s it for ox_inventory! No other files need to be changed.
qb-inventory Setup
The qb-inventory setup requires editing 3 files inside your qb-inventory resource and 1 file inside your qb-weapons resource. We provide the fully edited files — you can either drag and drop the provided files, or manually apply the changes below.
The provided qb-inventory and qb-weapons folders in the resource contain the pre-edited files. You can drag and drop them to replace your existing files, or follow the manual steps below.
Overview of Changes
| File | What to add |
|---|---|
qb-inventory/html/index.html | ”Throw” and “Place” buttons in the right-click context menu |
qb-inventory/html/app.js | throwItem() and placeItem() methods in the Vue app |
qb-inventory/client/main.lua | RegisterNUICallback handlers for ThrowItem and PlaceItem |
qb-weapons/client/weapdraw.lua | LocalPlayer.state.intThrowState checks to prevent weapon draw conflicts |
Step 1: Edit html/index.html
Find the context menu <ul> block (around the Give/Drop section) and add the Throw and Place buttons:
<!-- Add these two lines after the Drop </li> and before the Split <li> -->
<li @click="throwItem(contextMenuItem)">Throw</li>
<li @click="placeItem(contextMenuItem)">Place</li>The full context menu should look like this:
<ul v-if="showContextMenu" class="context-menu"
:style="{ top: contextMenuPosition.top, left: contextMenuPosition.left }">
<li v-if="contextMenuItem.useable" @click="useItem(contextMenuItem)">Use</li>
<li @mouseover="showSubmenu = true" @mouseleave="showSubmenu = false">
Give
<ul v-if="showSubmenu" class="submenu">
<li @click="giveItem(contextMenuItem, 1)">Single</li>
<li @click="giveItem(contextMenuItem, 'half')">Half</li>
<li @click="giveItem(contextMenuItem, 'all')">All</li>
</ul>
</li>
<li @mouseover="showSubmenu = true" @mouseleave="showSubmenu = false">
Drop
<ul v-if="showSubmenu" class="submenu">
<li @click="dropItem(contextMenuItem, 1)">Single</li>
<li @click="dropItem(contextMenuItem, 'half')">Half</li>
<li @click="dropItem(contextMenuItem, 'all')">All</li>
</ul>
</li>
<li @click="throwItem(contextMenuItem)">Throw</li>
<li @click="placeItem(contextMenuItem)">Place</li>
<li @click="splitAndPlaceItem(contextMenuItem, 'player')">Split</li>
<li v-if="contextMenuItem.name.includes('weapon_')"
@click="copySerial(contextMenuItem)">Copy Serial</li>
<li v-if="contextMenuItem.name.includes('weapon_')"
@click="openWeaponAttachments(contextMenuItem)">Attachments</li>
</ul>Step 2: Edit html/app.js
Add the throwItem() and placeItem() methods inside the methods: { ... } block of the Vue app. Place them alongside the other item action methods (e.g., near useItem, giveItem, dropItem):
async throwItem(item) {
if (item && item.name) {
this.showContextMenu = false;
await this.closeInventory();
try {
await axios.post("https://qb-inventory/ThrowItem", item);
} catch (error) {
console.error("Error throwing item:", error);
}
}
},
async placeItem(item) {
if (item && item.name) {
this.showContextMenu = false;
await this.closeInventory();
try {
await axios.post("https://qb-inventory/PlaceItem", item);
} catch (error) {
console.error("Error placing item:", error);
}
}
},How it works:
- Hides the context menu
- Closes the inventory UI fully (resets Vue state, releases NUI focus)
- Sends the item data to the Lua client via NUI callback
- The Lua side calls the bablo-throwitems export which handles everything from there
Step 3: Edit client/main.lua
Add the following NUI callback handlers in client/main.lua, alongside the other RegisterNUICallback blocks (near UseItem, GiveItem, etc.):
RegisterNUICallback('ThrowItem', function(data, cb)
exports['bablo-throwitems']:throwItem(data)
cb('ok')
end)
RegisterNUICallback('PlaceItem', function(data, cb)
exports['bablo-throwitems']:placeItem(data)
cb('ok')
end)How it works:
- When the UI sends a
ThrowItemorPlaceItemNUI message, these callbacks receive it and call thebablo-throwitemsexport - The inventory is already closed by the JS side, so no
SetNuiFocusis needed here bablo-throwitemshandles everything: throw animation, aiming, physics, item removal, ground item creation, and syncing
Step 4: Edit qb-weapons/client/weapdraw.lua
This step is required if you use qb-weapons. Without it, the weapon draw animation system will conflict with the throw system, causing broken animations or preventing throws from working correctly.
You need to add LocalPlayer.state.intThrowState checks to the qb-weapons:client:DrawWeapon event handler. This state bag is set by bablo-throwitems when the player enters throw mode, and tells qb-weapons to back off and not run its weapon draw/holster logic.
Open qb-weapons/client/weapdraw.lua and find the DrawWeapon event handler:
RegisterNetEvent('qb-weapons:client:DrawWeapon', function()
if GetResourceState('qb-inventory') == 'missing' then return end
local sleepAdd an early return check for intThrowState right after the inventory check, and a loop break inside the while true loop:
RegisterNetEvent('qb-weapons:client:DrawWeapon', function()
if GetResourceState('qb-inventory') == 'missing' then return end
if LocalPlayer.state.intThrowState then return end -- Add this line
local sleep
local weaponCheck = 0
while true do
local ped = PlayerPedId()
sleep = 250
if LocalPlayer.state.intThrowState then break end -- Add this line
if DoesEntityExist(ped) and not IsEntityDead(ped) ...What this does:
- The first check (
return) prevents the weapon draw handler from running at all while the player is in throw mode - The second check (
break) exits the draw loop if the player enters throw mode while the loop is already running bablo-throwitemsmanages theintThrowStatestate bag automatically — it is set totruewhen entering throw mode andfalsewhen done
Using the pre-edited files
For convenience, we provide ready-to-use edited versions of all required files included with the resource. You can simply drag and drop these files to replace your existing ones:
qb-inventory/html/index.htmlqb-inventory/html/app.jsqb-inventory/client/main.luaqb-weapons/client/weapdraw.lua
Make sure to back up your originals first if you have custom modifications.

