Item Actions
Last updated
May be stale
This page was last updated ago, on 25 August 2026. Check what it says against the code before relying on it.
Every item action (Use, Give, Remove, Drop, Destroy, Pickup, Sell, Place — the same set the inventory panel uses to generate its buttons) follows the same two-hook pattern: a canX check that decides whether the action is allowed at all, and an onX handler that performs the action's effect and can veto the library's default follow-up behaviour.
canX — is this allowed?
canX(ply, ...) is checked before the action runs. It returns a boolean, and optionally a reason string to show the player if it returns false.
function ITEM:canDrop(ply, pos, amt)
return false, "You cannot drop this car."
end
If canX returns false, the action is stopped immediately — onX is never called, and no server-side state (inventory, money) changes.
onX — do the thing, optionally overriding the default effect
onX(ply, ...) is called once canX has passed. Most actions have a default effect that runs immediately afterwards — deducting the item from the player's inventory, giving money, spawning an entity, and so on. onX can suppress that default effect by explicitly returning false (optionally with a message string, shown to the player the same way canX's does). Any other return value — including no return at all — lets the default effect proceed.
| Action | Default effect if onX doesn't return false |
|---|---|
onUse |
Item removed from inventory |
onGive |
Item transferred to the recipient, money/logs recorded |
onDrop |
Item removed from inventory, entity spawned in the world |
onPlace |
Item removed from inventory, entity spawned in the world |
onDestroy |
Item removed from inventory |
onSell |
Item removed from inventory, money given to the player |
onPickup |
The owned vehicle entity is removed |
onRemove |
None — onRemove is the effect (e.g. unequipping a worn item); there's nothing further to suppress |
This mirrors the way DOM event handlers work: canX is like checking whether an event is cancellable in advance, and returning false from onX is like calling preventDefault() — the handler still ran, it just declined the library's default follow-up.
Worked example
The bmwm3gtr46 vehicle item is untradeable and undroppable. It uses canGive/canDrop to refuse the action outright with a player-facing reason, and — as defence in depth, in case a caller ever bypasses the can gate — also has onGive/onDrop return false with the same message:
function ITEM:canDrop(ply, pos) return false, "You cannot drop this car." end
function ITEM:canGive(ply, to, amt) return false, "You cannot trade this car." end
function ITEM:onGive(ply, amt, to) return false, "You cannot trade this car." end
function ITEM:onDrop(ply, pos) return false, "You cannot drop this car." end
In practice, canX alone is enough to block a normal action — use it when you simply want to disallow something. Reach for the onX override when the handler needs to run custom logic first and only conditionally allow the default effect afterwards (for example, consuming an item only if using it succeeded).