Features in detail — lumo-inventory
Physical item drops
Right-click a player item and choose Hold / throw. While holding it:
- Hold RMB for GTA's native throwable aim camera and stance.
- Press LMB while aiming for the native throw animation and release.
- Press G to enter precise placement mode.
Items can also be sent straight into placement mode with Place object in the inventory menu. Aim at a nearby surface to move the translucent preview, use the mouse wheel to rotate it, hold Shift for fine rotation, use Page Up / Page Down to adjust height, press E to confirm, or Backspace to cancel. Confirmation uses a proper put-down animation.
Throwing works from vehicles and inherits part of the vehicle's velocity. The stock throwable controller supplies the seated/window release animation while the configured inventory prop replaces the hidden dummy projectile.
Ground objects can be opened, held/thrown again, or picked up directly through your target resource (ox_target, qb-target or qtarget), or with the key prompts ([E] and the keys shown) when the server runs no target resource. Exact item metadata is retained, including weapon condition, durability, serials, ammo, tint and attachments.
Configure models and tuning in Config.DropSystem in config/config.lua. 321 items and 110 weapons have their own model: bottles, cans, food plates, phones, cards, tools, drugs, cash, jewellery, clothing, vehicle parts and weapon attachments. They are stock GTA V, except farm produce (farm_apple, farm_tomato, etc.), which uses lumo-farming's streamed crop models when that resource runs (otherwise the bag below). The same model is used on the ground, in the hand while holding or throwing, and in a give. A model is chosen by exact name in Items, then Weapons, then the first Patterns rule that matches the name (so, for example, every weapontint_* item is a spray can). Anything still unmatched uses the stock prop_paper_bag_small, so custom/add-on items remain visible and fully usable without needing a model entry. amounts swaps the model with stack size: one banknote, a pile, a wrapped brick, then a case.
Each item has a size (Sizes), which decides how it is handled:
- small: one hand, native aim, full throw. This is the default.
- heavy: one hand, native aim, a shorter, flatter throw. Toolboxes, jerry cans, drills, gold bars and heavy weapons are heavy, and so is any stack whose total weight reaches
throwing.heavyWeight. - bulky: carried in both arms with the box-carry pose. There's no sprinting, jumping, weapons or getting into vehicles, and LMB is a short two-handed toss in the direction you face. Crates, delivery boxes, engines, wheels and car panels are bulky.
Thrown items tumble end over end (spin). Dropping from the inventory plays a put-down with the item in your hand rather than spawning it on the floor.
If the game build lacks a configured model, the first client to log in reports it. The server console lists it and that item uses the bag, instead of an invisible drop. To fit a grip in game, set gripTuning = true, hold the item and use /dropgrip x y z rx ry rz [bone]. It re-attaches the prop live and prints a ready-made Items line to F8. Set throwing.impactDamage = 0 if throws should be physical/visual only.
Weapons
On QBCore with qb-weapons running, qb-weapons equips weapons, loads ammo and fits attachments, exactly as with qb-inventory. Everywhere else (Qbox, ESX, standalone, or Config.ItemUse.weaponResource = 'builtin') the built-in handler does it:
- Use a weapon item (hotbar or Use) to draw it; use it again to put it away.
- Ammo is saved per weapon on its item (
info.ammo). The server owns it: shots fired are reported and saved, ammo only goes up through ammo items. - Ammo items (
pistol_ammo,smg_ammo,rifle_ammo,shotgun_ammo,mg_ammo,snp_ammo,emp_ammo) load the weapon in your hands if it takes that ammo type:Config.Weapons.Ammosets the rounds per item,MaxAmmothe cap. - Wear: every shot takes
Config.Weapons.WearPerShotoff the weapon's quality; at 0 it cannot be drawn. - Throwables (grenades, molotovs, …) are used up when thrown.
- Attachments and tint stored on the item are fitted when the weapon is drawn.
- Moving, dropping, giving or selling the weapon in your hands puts it away.
Interface and full bags
The UI retains the original transparent panel layout, lime palette and textured body scan with colored injury overlays, plus a compact action grid for use, give, throw, place, drop, lock and split. It retains the HUD's reduced-motion setting. Common food, drink and medical items also have physical prop mappings.
Crafted output, level item rewards and the admin give command now use AddItemOrDrop. When the whole incoming stack cannot fit by weight or slots, it is delivered as a physical drop at the player's feet, with a notification. Existing carried items stay in the bag. The drop retains item metadata and uses the existing ground-drop cleanup lifetime; it is not persistent across restarts. Config.Overflow enables this behavior and caps outstanding overflow drops at 12 per citizen. Failed creation or a reached cap returns failure to the caller.
Other acquisition resources can adopt the server export:
lua
local delivered, slot, dropId = exports['lumo-inventory']:AddItemOrDrop(
source, 'water_bottle', 1, nil, {}, 'job reward'
)
-- delivered: item reached inventory OR ground; grant/charge only once.
-- slot: inventory destination, or nil when delivered to the ground.
-- dropId: ground destination, or nil when delivered to inventory.AddItem remains strict for compatibility with shops, transfers, pickups and rollback logic. Existing third-party jobs must use AddItemOrDrop for ground overflow; their existing CanAddItem early returns also need to defer to that export. Cash and explicit-slot requests do not overflow. This avoids silently changing transaction semantics throughout the server.
Drop discovery returns nearby IDs instead of full item tables. OneSync state bags attach targets as objects stream in. Drop creation and the updated open/carry/pickup/give paths respect routing buckets. Physical NUI actions are serialized and use the returned server inventory instead of subtracting twice when inventory pushes race an action response.
Choosing a Give recipient
Give now closes the inventory and marks nearby visible players with overhead small arrows, without player labels. Your text UI (ox_lib, qb-core or ESX) shows the controls at the bottom center. Use Left/Right or the mouse wheel to select a player; the selected arrow is lime green. Press E to give, or Escape/Backspace to cancel. Selection expires after 30 seconds. Reopening inventory or unloading the character also cancels. A departing target is never silently replaced. No items are removed until confirmation passes server validation. Weapon serials are checked again to avoid handing over a replacement weapon from the same slot.
Config.GiveSelection controls the shared distance (3 metres by default), timeout and candidate refresh interval. Candidates are scanned every 250 ms only during selection; arrows are immediate-mode markers, with no spawned entities. The server checks its own range, routing bucket, item/slot/amount, locks and capacity.
A confirmed give plays a hand-off. Both players turn to face each other and play mp_common give/take, and the item's own prop moves from the giver's right hand to the receiver's, then is put away. Bystanders within Config.GiveAnimation.broadcastDistance see it too. The prop is a local object on each client, so entity lockdown does not affect it. Bulky items hand over without a prop. Timings are in Config.GiveAnimation.