Violet

Shop

On this page

Read and interact with the NPC shop dialog while it's open: list the items the NPC sells, buy and sell, and close the dialog.

Shop must be open

Every function here requires an NPC shop dialog to be open. When no shop is open, is_open() returns false, get_items() returns nil, and the action functions return false. Talk to a shop NPC first (see NPC).

Shop Item Structure

get_items() returns an array of objects describing the goods the NPC offers for sale (i.e. what you can buy):

PropertyTypeDescription
idnumberItem template ID
positionnumberThe item's slot in the shop list — pass this as index to buy()
countnumberStock quantity for the entry
pricenumberUnit price in mesos
unit_pricenumberPer-charge unit price for rechargeables, else 0
max_per_slotnumberMaximum quantity per slot
namestringReadable item name

Functions

core.shop.is_open() -> boolean

Returns true if an NPC shop dialog is currently open.


core.shop.get_items() -> table<shop_item> | nil

Returns every item the open NPC shop sells, across all of its tabs — i.e. everything you can buy. Returns nil if no shop is open. Each entry's position is the index used by buy().

lua
if core.shop.is_open() then
    for _, item in ipairs(core.shop.get_items()) do
        core.log(string.format("[%d] %s x%d - %d mesos",
            item.position, item.name, item.count, item.price))
    end
end

core.shop.buy(item: shop_item, count: number, price?: number) -> boolean

Buys count of item — pass an entry straight from get_items() and its position/id are read for you. price is the per-unit price; when omitted it's resolved from the matching shop entry. Returns true if the request was sent, or false (plus an error string) if no shop is open, or the item is no longer at that slot in the open tab and no explicit price was given.

You can also call the explicit form buy(index, item_id, count [, price]) with raw numbers (index = get_items().position). For multi-tab shops buy() acts on the currently open tab; index is the slot within it. (Most NPC shops have a single tab, so this rarely matters.)

ParameterTypeDescription
itemshop_itemA get_items() entry (or pass index, item_id as numbers)
countnumberQuantity to buy
pricenumberOptional. Per-unit price; auto-resolved from the shop entry when omitted.
lua
-- Buy 100 of the item at slot 4
for _, item in ipairs(core.shop.get_items()) do
    if item.position == 4 then
        core.shop.buy(item, 100)
        break
    end
end

core.shop.sell(position: number, item_id: number, count: number) -> boolean

Sells count of the inventory item at slot position. Returns true if the request was sent, or false if no shop is open or a previous sell is still awaiting the server's acknowledgement.

ParameterTypeDescription
positionnumberInventory slot position of the item to sell
item_idnumberItem template ID
countnumberQuantity to sell
Quest / untradeable items

The server rejects (and may disconnect on) attempts to sell quest, not-for-sale, or cash items. Only sell items you know are sellable.


core.shop.close() -> boolean

Closes the open shop dialog. Returns true if a shop was open and the close was issued, false otherwise.

Example

lua
-- Restock mana potions, then sell off junk etc items
if not core.shop.is_open() then
    core.log_warning("No shop open")
    return
end

-- Buy 1000 mana potions if the shop carries them
local MANA_POTION = 2000059
for _, item in ipairs(core.shop.get_items()) do
    if item.id == MANA_POTION then
        core.shop.buy(item, 1000)
        core.log("Bought 1000x " .. item.name)
        break
    end
end

-- Sell every etc item (tab_id 4) in the bag
for _, item in ipairs(core.inventory.get_etc_items()) do
    core.shop.sell(item.position, item.id, item.count)
end

core.shop.close()