Item script structure
Each usable item has a Lua file in scripts/items/ named by the item’s in-game name (e.g., acorn_cookie.lua). An item script returns a table with up to two handler functions.
Handler signatures
target is the player using the item. user is the character who used the item (usually the same as target for self-use items).
Item utility functions
scripts/globals/item_utils.lua provides xi.itemUtils with shared validation helpers.
Food check
Inventory box check
Skill book check
Status effect removal list
xi.itemUtils.removableEffects is an ordered array of status effect constants that items like remedies can remove (paralysis, poison, blindness, silence, etc.).
Trade handling
Trade validation is done with npcUtil.tradeHas and npcUtil.tradeHasExactly. Both are available globally.
All tradeHas* functions automatically call trade:confirmItem() on matched items when returning true.
Trade container API
The trade object passed to onTrade handlers is a CLuaTradeContainer (bound in src/map/lua/lua_trade_container.cpp).
Item IDs
Item IDs are defined as constants under xi.item.*. The full enum is in scripts/enum/item.lua.
Use xi.item.* in scripts rather than raw integers to keep code readable and maintainable.
Giving items from NPC scripts
Always use npcUtil.giveItem() rather than calling player:addItem() directly, because giveItem handles the inventory check and displays the correct obtained message automatically:
Returns false if the player lacks inventory space, true otherwise.