> For the complete documentation index, see [llms.txt](https://nodemods.gitbook.io/nodemods-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://nodemods.gitbook.io/nodemods-docs/throwable-items/integration.md).

# Integration Guide

## Integration Philosophy

You should integrate Throwable Items by editing only:

* `cl_funcs.lua`
* `sv_funcs.lua`

Those files are intentionally structured with editable public hooks at the top and framework examples below.

## Client Hooks (`cl_funcs.lua`)

### `CanThrowItem(item)`

Called before throw start and while holding throw state.

Use this to block throw attempts when needed:

* player dead or downed
* handcuffed or in restricted state
* custom cooldown active

### `NearGroundItem(distance, coords, data, index)`

Called each frame for the closest eligible ground item within configured distance.

Return values:

* `true`: pickup requested
* `false`: no pickup action

Typical usage:

* draw 3D text prompt
* check pickup key press
* block pickup for invalid states

### `GetCurrentItem()`

Must return a valid `ThrowableItem` or `nil`.

Required fields:

* `id`
* `itemCode`
* `name`

At least one of these must also be present:

* `model`
* `hash`

If both `model` and `hash` are missing, throw is rejected.

### `RemoveCurrentItem(item)`

Called after successful throw creation.

Use this to remove the thrown item from active hand/inventory state on the client side when needed.

### `CancelActiveEmote()`

Called before throw animation where relevant.

Use this to stop emotes or other animation systems that conflict with throw behavior.

## Server Hooks (`sv_funcs.lua`)

### `OnItemThrown(source, item, decorId, netObj, visualNetObj)`

Called when server receives a new thrown item.

Use this to remove item(s) from your inventory framework on throw.

### `OnItemPickedUp(source, item)`

Called when pickup is validated and throwable entity is removed.

Use this to add item(s) back to inventory.

## Exports

### Client Exports

```lua
exports["nm-throwable-items"]:CancelThrow()
exports["nm-throwable-items"]:ThrowItem(item, speed, doAnim)
```

* `CancelThrow()`: Force-cancel an active throw state.
* `ThrowItem(item, speed, doAnim)`: Programmatic throw trigger.

### Server Exports

```lua
exports["nm-throwable-items"]:RemoveThrowable(decorId)
exports["nm-throwable-items"]:ClearAllThrownItems()
exports["nm-throwable-items"]:ClearPlayersThrownItems(source)
```

* `RemoveThrowable`: Remove one throwable by decor ID.
* `ClearAllThrownItems`: Remove all tracked throwables.
* `ClearPlayersThrownItems`: Remove throwables belonging to one player.

## ThrowableItem Schema

```lua
---@class ThrowableItem
---@field id string
---@field itemCode string
---@field name string
---@field model? string|number
---@field hash? number
---@field ammo? number
---@field metadata? table
---@field slot? number
---@field amount? number
```

`slot` and `amount` are optional but commonly used by inventory integrations.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://nodemods.gitbook.io/nodemods-docs/throwable-items/integration.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
