Shop
On this page
Read and interact with the NPC shop dialog (CShopDlg) while it's open: list the
items the NPC sells, buy and sell, and close the dialog.
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):
| Property | Type | Description |
|---|---|---|
id | number | Item template ID |
position | number | Commodity index — pass this as index to buy() |
count | number | Stock quantity for the entry (nStock) |
price | number | Unit price in mesos (nPrice) |
unit_price | number | Per-charge unit price for rechargeables (dUnitPrice), else 0 |
max_per_slot | number | Maximum quantity per slot (nMaxPerSlot) |
name | string | Readable 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 the items the open NPC shop sells (CShopDlg::m_aSellItem). Returns nil
if no shop is open. Each entry's position is the index used by buy().
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
endcore.shop.buy(index: number, item_id: number, count: number, price?: number) -> boolean
Buys count of the commodity at index. index and item_id come from
get_items() (position and id). 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 index
couldn't be matched and no explicit price was given.
| Parameter | Type | Description |
|---|---|---|
index | number | Commodity index (get_items().position) |
item_id | number | Item template ID (get_items().id) |
count | number | Quantity to buy |
price | number | Optional. Per-unit price; auto-resolved from the shop entry when omitted. |
-- Buy 100 of whatever sits at commodity index 4
local items = core.shop.get_items()
for _, item in ipairs(items) do
if item.position == 4 then
core.shop.buy(item.position, item.id, 100)
break
end
endcore.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.
| Parameter | Type | Description |
|---|---|---|
position | number | Inventory slot position of the item to sell |
item_id | number | Item template ID |
count | number | Quantity to sell |
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
-- 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.position, item.id, 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()