Template: BUTTON and SWITCHABLE - ThePix/QuestJS GitHub Wiki

BUTTON

A button is very simple, though by default it does not do anything.

createItem("charger_button", BUTTON(), {
  examine:"A big red button.",
})

The player can press it, but nothing happens. You can make it do somthing by adding a custom "push" attribute, as in this example:

createItem("charger_button", COMPONENT("charger"), BUTTON(), {
  examine:"A big red button.",
  alias:"button",
  push:function(options) {
    const contents = w.charger_compartment.getContents(world.ALL)[0]
    if (!w.charger_compartment.closed || !contents) return falsemsg("{pv:char:push:true} the button, but nothing happens.", options)
    if (!contents.chargeResponse) return falsemsg("{pv:char:push:true} the button. There is a brief hum of power, but nothing happens.", options)
    return contents.chargeResponse(options)
  }
})

Events

If you use the default "push" function, the "afterPress(options)" event will fire when the button is pressed. This offers an alternative approach to replacing the "push" function. The big difference is if you do it this way you always get the default message.

createItem("charger_button", COMPONENT("charger"), BUTTON(), {
  examine:"A big red button.",
  alias:"button",
  afterPress:function(options) {
    const contents = w.charger_compartment.getContents(world.ALL)[0]
    if (!w.charger_compartment.closed || !contents) return falsemsg("Nothing happens.", options)
    if (!contents.chargeResponse) return falsemsg("There is a brief hum of power, but nothing happens.", options)
    return contents.chargeResponse(options)
  }
})

SWITCHABLE

A switchable item can be turned on and off. It is very easy to set up, the template takes a Boolean indicating if it is already turned on, and optionally a phrase to add to the name when it is on.

Here are two examples, the first includes the optional phrase. If the player picks up the torch and turns it on, in her inventory is will have "a torch (providing light)". The second has no phrase, as it operates a light hanging from the ceiling.

createItem("torch", TAKEABLE(), SWITCHABLE(false, 'providing light'), {
  loc:"shed",
  examine:"A reliable torch.",
});

createItem("light_switch", SWITCHABLE(false), {
  loc:"basement",
  examine:"A switch, presumably for the light.",
});

You can test the "switchedon" attribute to determine its state. This is different to Quest 5, where you would have the switch make changes in your game world when it changes state. In Quest 6, only the switch changes, but other objects can refer to that.

So we want to connect the switch above to the room, and have the room only lit when the switch is on. By default all rooms are light sources, but we can make that conditional on the switch (the exit has been set up so it can still be used if the room is in darkness):

createRoom("basement", {
  desc:"A dank room, with piles of crates everywhere.",
  darkDesc:"It is dark, but you can just see the outline of the trapdoor above you.",
  up:new Exit('kitchen', {isHidden:function() { return false; } }),
  lightSource:function() {
    return w.light_switch.switchedon ? LIGHT_FULL : LIGHT_NONE;
  },
});

You can control whether the switch can be turned on with the "testSwitchOn" function. It should either return true, or give a message saying why it fails and return false. You can use "testSwitchOff" too.

createItem("light_switch", SWITCHABLE(false), {
  loc:"basement", 
  examine:"A switch, presumably for the light.", 
  alias:"light switch",
  testSwitchOn:function() {
    if (!w.crates.moved) {
      msg("You cannot reach the light switch, without first moving the crates.");
      return false;
    }
    else {
      return true;
    }
  }
})

The SWITCH ON and SWITCH OFF commands call doSwitchon() and doSwitchoff() respectively to do the work (but not print anything to screen). As well as setting switchedon they ensure the game world lighting is updated. If your switch changes state other than via a player command, you should do it with doSwitchon() and doSwitchoff() too.

You can use afterSwitchOn and afterSwitchOff to react to it happening - details here.

Set "suppressMsgs" to prevent the default switch on/off messages; you can then add your own to these events.