RPG Library: Communicating NPCs - ThePix/QuestJS GitHub Wiki

If the player attacks one goblin, we would expect the others in the location to join the battle. To make this happen, QuestJS has a broadcast feature.

Go here for the introduction to RPG.

It looks like this:

rpg.broadcast('guards', 'attack', 'guard1')

This sends an "attack" message to all NPCs in the "guards" group, from "guard1". You can also use "broadcastAll":

rpg.broadcastAll('attack', 'guard1')

This will send the message to all the NPCs that share a group with guard1.

Here is how you would use it for an NPC. The important attributes are "signalGroups" and "afterAttack". The former is a list of groups this NPC belongs to; he will receive signals sent to any of these groups. The latter attribute, "afterAttack", is a function that will fire when he is attacked; if that happens he will broadcast an "attack" message to everyone in the "guards" group.

createItem("goblin", RPG_NPC(false), {
  loc:"practice_room",
  damage:"d8",
  health:40,
  signalGroups:['guards'],
  afterAttack:function() { rpg.broadcast('guards', 'attack', this.name) },
  examine:"An example of a simple monster.",
})

There are four built-in messages, "test", "alert" (sets "alert" to true), "wake" (sets "asleep" to false) and "attack" (sets "attitude" to rpg.BELLIGERENT_HOSTILE). These are universal. You can add your own messages by adding them to rpg, and prepending "signalResponses_" to the name

  rpg.signalResponse_explode = function() {
    msg("It explodes.")
    rpg.destroy(this)
  }

You can also set responses on a local basis, specific to an NPC.

createItem("goblin", RPG_NPC(false), {
  loc:"practice_room",
  damage:"d8",
  health:40,
  signalGroups:['guards'],
  afterAttack:function() { rpg.broadcast('guards', 'attack', this.name) },
  signalResponse_wake:function() {
      msg("He rolls over and goes back to sleep.")
    },
  },  
  examine:"An example of a simple monster.",
})

You can set an exit to alert guards if the player tries to use it. This example tests the room is guarded and that the orc is still alive - if so, the player is not moved and any NPC in the "guards" signal attack will attack.

  east:new Exit('passage', {
    simpleUse:function(char) {
      if (w.practice_room.guarded && !w.orc.dead) {
        rpg.broadcast('guards', 'attack', 'practice room exit')
        return falsemsg("You try to head east, but the orc bars your way. Looks like he is going to attack!")
      }
      return util.defaultSimpleExitUse(char, this)
    }    
  }),

This also provides a way to have a spell affect every zombie in the world, for example. Put all the zombies in their own group, add a "destroy" message, and broadcast that message to the group in the spell.

new SpellSelf("Dispel", {
  icon:'annul',
  description:"Destroys all zombies across the entire world!",
  targetEffect:function(attack) {
    rpg.broadcast('zombies', 'destroy', 'player')
    return true
  },
})

rpg.signalResponses.destroy = function() {
  this.msg("{nv:item:be:true} destroyed.", {item:this})
  rpg.destroy(this)
}