Display Verbs - ThePix/QuestJS GitHub Wiki

Display verbs are the options that appear for an item when you click on it in the side pane. Ideally these should be context sensitive, so for example a hat has "Take" as an option when it is on the ground, "Drop" and "Wear" when held, and "Remove" when worn.

All items have "Examine", and if it has a "use" attribute, it will also have "Use". Templates add further verbs. You can add your own too. There are three techniques, of increasing complexity.

Static

The first is as an array, using the "heldVerbs", "hereVerbs" and wornVerbs" attributes.

This example will add "Read", but only when the item is held.

createItem("book", TAKEABLE(), { 
  loc:"lounge",
  examine:"A leather-bound book.",
  heldVerbs:["Read"], 
}

This is simple, and will often be all you need. However, the lists are statics. If the book is held, the option to read it is always presented. What if it is dark or the player is blindfolded? You could handle that in the command, allowing the player to select the "Read" option, but then report that it is too dark to see, but a slicker way is with dynamics verbs...

Dynamic

For better control, you might want to look at the "verbFunction". This takes a list as its only parameter. You can add to this list any extra verbs. The advantage of this technique is that the verbs you add can be determined by the state of the game. It also allows you to remove verbs you do not want.

Let us suppose we have an NPC, and we are tracking his state with the "state" attribute. At some point, the NPC is injured, and his state become 4. Thereafter it makes no sense to offer a TALK TO verb, so if the state is over 3 we remove the last entry in the list, using pop. However, the player may want to try first aid, so instead we add an ASSIST verb.

  verbFunction:function(list) {
    if (this.state > 3) list.pop()
    if (this.state === 4) list.push("Assist")
  },

This does offer some scope to hide what an item can do, if you are building a puzzle. If there is no text input, it also offers scope for getting the player in an impossible situation - if an item is not showing a vital verb, the player will be stuck, so test carefully!

Remember that you may want the verbs to depend on whether the item is held or not, so use the "isAtLoc" function.

Do not reset the list attribute. This example will fail because behind the scenes the function is passed a reference to the list, rather than the list itself. The code sets list to reference a different, new list, but the original list will not be affected.

  verbFunction:function(list) {
    // DOES NOT WORK!!!
    list = ["Look at", "Assist"]
  },

Using a dictionary instead of a string

In the above examples, we just added a simple string, but for more control you can add a dictionary, with three entries, "name", "action" and, optionally, "style". The name is what will be used, while action is what will be used for the command.

You can use % as a placeholder for the item in the action, otherwise it will get appended to the end. So, for example, if you have a hat item, with "get" the command will be GET HAT; with "put % on", the command will be PUT HAT ON. In English, PUT ON HAT would work, but the option is there, and may be more useful in other languages.

The "style" entry adds an extra style to the text, which you would hen need to define in a CSS file. This would allow you have have verbs in different colours, or whatever.

Dynamic for templates

If you are creating a custom template, you have an extra problem, in that the author may want to add his own custom "verbFunction" attribute, which would override yours, and meanwhile other templates on an item might have their own ideas too.

We therefore need to add our function to "verbFunctions" which is an array of functions. And the problem there is that the array only exists when the object is created, which is after the copy of the template is created. So we have to use a special attribute of the template, "afterCreation", that, instead of getting added to the object, will get run after the object is created. This then can be used to add our custom function to the "verbFunctions" array.

This example is from TAKEABLE. Note that you cannot use this, so the function is passed the object too.

  afterCreation:function(o) {
    o.verbFunctions.push(function(o, list) {
      list.push(o.isAtLoc(game.player.name) ? "Drop" : "Take")
    })
  },

Note that removing verbs from the list requires care. In an earlier example, we assumed "Talk to" was the last one - you cannot do that here as other templates might have done stuff. The easiest way is to use `array.remove'.