Solarus quests  1.6
Quest maker's reference
Shop treasure

A shop treasure is a treasure that can be purchased by the hero for money.

This type of map entity can be declared in the map data file. It can also be created dynamically with map:create_shop_treasure().

Overview

A shop treasure entity shows the sprite of the treasure and its price. Its size is always 32x32 pixels and other entities cannot traverse it.

The hero can interact with this a shop treasure to buy it. A dialog is then automatically shown and the player can choose to buy the item or not. If he buys the treasure, he obtains it and brandishes it (just like when opening a chest). If the treasure is saved, it disappears from the map, otherwise it stays and can be bought again.

Shop treasures allow to make shops very easily from the quest editor. They provide a built-in process that handles entirely the dialogs, the price and the treasure. This API does not provide much control on this process. If you need to implement more customized interactions, you can use a generalized NPC.

Dialogs of shop treasures

Dialogs of shop treasures need special care because everything is built-in with shop treasures, but dialogs are entirely customizable. You can skip this section if you are not making your own dialog box system.

Dialogs that are displayed when interacting with a shop treasure are quite elaborate because they have both a parameter (the price: a number) and a result (the decision of the player: a boolean). If you implement your own dialog box in Lua, which is recommended, you need to respect the mechanism described in this section for the particular dialog of shop treasures.

First, when the hero interacts with a shop treasure, a dialog shows the description of the treasure. There is nothing special about this dialog.

Then, a second dialog shows the price of the treasure and asks if the player wants to buy it. The player can accept or refuse. This second dialog has the id "_shop.question".

Since the price of the treasure is only known at runtime (dialogs.dat cannot know it), you should put a special sequence in the text of the dialog instead (like "$v"), and replace this special sequence by the actual price at runtime. At runtime, the price is the info argument of the game:on_dialog_started() event, so you can perform the substitution there.

Furthermore, when the dialog finishes, you have to tell the engine the decision of the player. This value to return can be true to buy the treasure, or anything else to refuse and do nothing. Use the status parameter of game:stop_dialog(status) to indicate it.

Remarks
Recall that when the game:on_dialog_started() event is not defined, the engine uses by default a built-in dialog box with minimal features. This built-in dialog box works correctly with shop items, providing that the text of the "_shop.question" dialog has the expected format. It should have three lines. The "$v" sequence (if any) is subsituted by the actual price like suggested above, and the user can select one of the last two lines: the first one is yes and the second one is no.

Methods inherited from map entity

Shop treasures are particular map entities. Therefore, they inherit all methods from the type map entity.

See Methods of all entity types to know these methods.

Methods of the type shop treasure

None.

Events inherited from map entity

Events are callback methods automatically called by the engine if you define them.

Shop treasures are particular map entities. Therefore, they inherit all events from the type map entity.

See Events of all entity types to know these events.

Events of the type shop treasure

The following events are specific to shop treasures.

shop_treasure:on_buying()

Called when the player is about to buy this treasure.

He already accepted to buy it and validated the dialog. At this point, you may cancel the deal for some reason by returning false (for example if you realize that the player has no bottle and therefore cannot buy the potion he wanted).

  • Return value (boolean): true if the player is allowed to buy the treasure.

shop_treasure:on_bought()

Called when the player has just bought this treasure.

  • Return value (boolean): true if the player is allowed to buy the treasure.
Remarks
This event is called right after the more general events item:on_obtaining() and map:on_obtaining_treasure(). Those two events are called no matter how the treasure is being obtained: from a chest, from a pickable treasure, from a shop treasure or explicitly with hero:start_treasure().