CityRP Documentation Repository

Item Actions

Last updated

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