Template: MERCH - ThePix/QuestJS GitHub Wiki

The MERCH template allows the author to create items to use as merchandise in a shop. I am going to go somewhat outside the template to discuss all the options for creating a shop. For how to have the shop only open at certain times of the day, go here.

The MERCH template requires two parameters, the cost of the item and either the name of the shop or an array of shops where it is available. Here is an example:

createItem("carrot", TAKEABLE(), MERCH(2, ["shop"]), {
  examine:"It's a carrot!",
});

Here "shop" is the name of a location. In this example, it is part of a list (though a list of one), and you can have as many as you want in the list. Using a list creates an item that will be cloned when purchased, allowing the player to buy as many as she wants.

For a unique item, you do not want it to be cloned when purchased, so use just a single name, rather than a list - a unique item can only be in one place.

createItem("trophy",  TAKEABLE(), MERCH(15, "shop"), {
  examine:"It is a unique trophy!",
});

In both instances we have an item that is only available at the location "shop", but the first was given in a list, so Quest will clone it, the second was not in a list, so will not be cloned.

For a simple shop, that is all you need to do. The player can now go to the shop, type BUY CARROT. A carrot object will be cloned in the player's inventory, and 2 will be deducted from the player's "money" attribute. Or she can type BUY TROPHY, and the single trophy object will be moved to her inventory, and 15 deducted from her money.

The player can also just type BUY or PURCHASE, and a table will appear listing all the items for sale in this location; if the player can afford the item, they will be a "Buy" link that she can click too.

Selling

To create a shop where the player can sell things, you need to go to that room, and modify that. It needs a "willBuy" function that returns a Boolean. This simple example will have the shop buy anything (that uses the MERCH template).

createRoom("shop", {
  desc:"A funny little shop.",
  east:new Exit("garden"),
  willBuy:function(obj) { return true; }
});

Items that are clones will disappear from the world, other items will be moved to the shop's inventory. You can modify "willBuy" to have the shop only buy specific items.

createRoom("shop", {
  desc:"A funny little shop.",
  east:new Exit("garden"),
  willBuy:function(obj) {
    return (obj === w.trophy);
  }
});

Discounts and mark-ups

By default, a shop will sell goods for the price you give them, and will buy them for half that. You can modify that on a shop-by-shop basis. Give the shop a "sellingDiscount" to have it sells goods at a discount, as a percentage. A value of 20 will cause the shop to sell good with 20% off. You can use negative numbers to inflate prices; a value of -50 will add 50% to the price.

Give a shop a "buyingValue" attribute to have it buy goods at a certain percentage of the given price. A value of 75 will have the shop buy goods at 75% of their price, rather than the default 50%.

For even more control, you can change the "getSellingPrice" and "getBuyingPrice" functions on an object. Both take the character buying or selling as a parameter, so potentially you could have different discounts for different characters.

Services

You can also offer a service at a shop in the same way - create an item that represents that service. Just over-ride the "purchaseScript" function to do the service. This example allows the player to get his hair dyed orange.

createItem("hair_dyed_orange", MERCH(2000, ["hairstylist"]), {
  purchaseScript:function(isMultiple, char, cost) {
    msg("'I'd like my hair dyed orange,' you say.");
    msg("'Of course.' You sit in the chair, and let the guy do his stuff. Soon your hair is bright orange!")
    game.player.haircolor = "orange"
    game.player.money -= cost
  },
});