Template: WEARABLE - ThePix/QuestJS GitHub Wiki

This template allows you to add clothing, jewelry, backpacks, etc. to your game.

Note that using the WEARABLE template automatically includes the TAKEABLE template for your object.

Garments can be assigned to layers and slots. Slots are where the item is worn. Each slot is a string, for example “head”. At this point, we need to make a design decision - how are we going to divide the body up? This is up to you. For simplicity, you might say: feet, lower, upper and head. Trousers cover the lower body, so in the wear slots section, add “lower”. However, it is up to you - you just need to be consistent!

As well as slots, clothing has layers. Trousers might go in layer 2, whilst underwear obviously worn underneath might go in layer 1. The player will be unable to put underpants on if he is already wearing trousers, but could take the trousers off, then put the underwear on, then put the trousers back on.

createItem("underwear", WEARABLE(1, ["lower"]), { 
  loc:"bedroom",
  pronouns:lang.pronouns.massnoun,
  examine:"Clean!",
});

createItem("jeans",  WEARABLE(2, ["lower"]),  {
  loc:"bedroom",
  pronouns:lang.pronouns.plural,
  examine:"Just some old jeans",
});

Garments can occupy more than one slot, so overalls could be set to have both "lower" and "upper", but only one layer.

createItem("jumpsuit", WEARABLE(2, ["upper", "lower"]), {
  loc:"bedroom",
  examine:"Bright orange",
});

And any garment with no slots can be worn without restrictions. And you may choose to do this for all the garments in your game, and not worry about what what is worn where!

createItem("helmet", WEARABLE(), {
  loc:"tower_of_power",
  examine:"This steel helm is clearly magical. Or cursed.",
});

Layer zero is special; it is effectively all layers. Say you have a pair of shorts that cannot be worn under trousers or over underpants, you can set its layer to 0.

Restrictions and reactions

You can add "testWear" and "testRemove" functions to an object; these will run before a garment is worn or removed; if they return false the action is aborted. They should print a message saying why in that case.

This example is for a spacesuit. If the room is has air, it can be taken off. Otherwise, a message is printed and false returned.

  testRemove:function(options) {
    if (isRoomPressured(w[optionschar.loc])) return true
    msg("{nv:char:start:true} to unseal {pa:char} spacesuit... There is a hissing sound, and suddenly {nv:char:be} struggling for breath. Quickly, {nv:char:seal:true} it up again. Perhaps taking a spacesuit off in a vacuum is not such a good idea?", options)
    return false
  }

You can add "afterWear" and "afterRemove" functions to an object; these trigger after the object is put on or taken off, and take the character involved as an attribute.

  afterWear:function(options) {
    if (options.char === w.Patch && !this.patchFlag) {
      msg("Mandy looks at Patch in his new hat. 'You look cool!'")
      this.patchFlag = true
    }
    if (options.char === player && !this.playerFlag) {
      msg("Mandy decides she likes the hat; it makes her feel very... Bohemian she decides. It is a shame there is no mirror here.")
      this.playerFlag = true
    }
  },   

Other Attributes

Some attributes have getters too; by default they just return the attribute. It is occasionally useful to override the getter to make the item dynamic - perhaps the slots change after a shirt gets ripped.

Attribute Getter Comment
wearable Always true
worn getWorn() true if worn, obviously
slots getSlots() See above
wear_layer See above
armour getArmour() Defaults to zero
testWear(char) See above
testRemove(char) See above
msgWear Optional
msgRemove Optional

Other Useful functions

You can call getWearing on an NPC to get a list of garments.