RPG Library: NPC Behaviour - ThePix/QuestJS GitHub Wiki

Attack

To have the NPC attack the player, call "performAttack".

w.orc.performAttack(player)

That will just trigger one attack. To have the NPC continue to attack, call "antagonise".

w.orc.antagonise(player)

You can also do this as part of an agenda. Use "antagoniseNow" to have it become aggressive and attack in the same round.

w.orc.agenda = [
  "walkTo:player:'Prepare to die!', says the orc with a cruel grin.",
  'antagonise:player',
]

The Chase

By default an NPC will stop attacking once the player moves to another room (but will attack again if the player returns). You can set the NPC to give chase by setting its "pursueToAttack" attribute. This can be set to any function, but the easiest way is to use the built-in one, which will give chase as long as there is an exit the NPC can take to the player's current location.

createItem("orc", RPG_NPC(false), {
  loc:"practice_room",
  ex:"A large green humanoid; hairless and dressed in leather.",
  pursueToAttack:rpg.pursueToAttack,
  // etc.

You can set this on the NPC at character creation too.

Guards!

A common scenario in an RPG is to have an NPC guarding an item or location.

Setting A Guard On An Exit

Use the "setGuard" function of an NPC to have it guard an exit from a location. It takes two arguments - the direction and an optional string or function that describes the NPC reacting to the player trying to use the exit. The NPC will guard the given exit on the room it is currently in.

w.orc.setGuard("east", "The orc looks at {nm:char:the} suspiciously.")

w.orc.setGuard("east", function(char, exit) {
  msg("It chucks a rock at {nm:char:the}.", {char:char})
})

The player will be unable to use the exit while the NPC is in place; instead the message will be displayed or function run. If the NPC moves to another location or is dead, the player will be able to use it. Note that there is nothing to stop the player coming the other way, as that uses a different exit.

Use "unsetGuard" to stop the NPC guarding the exit.

w.orc.unsetGuard()

Note that both the room and the NPC must exist before you call "setGuard". I suggest creating the room first, then the guards, then calling this function.

Setting A Guard On A Room

Use the "setGuard" function, as before, but set the direction to false.

  w.orc.setGuard(false, 'The orc eyes you suspiciously.')

In this example, the orc will not actually stop the player, but you could give it a function that initiates an attack.

Setting A Guard On An Item

To have the NPC guard an item, a rather different approach works best. In this case, you are better giving the NPC an agenda.

w.orc.agenda = ['guardItemNow:tapestry:The orc draws his sword.']

This relies on the item being flagged as scenery. The guard will attack when the item in question no longer has the scenery tag - that is to say, when it gets picked up.

This version will have the orc react a bit more slowly; after the tapestry is taken, the orc will draw its sword. It will attack after the player takes a further turn.

w.orc.agenda = ['guardItem:tapestry:The orc draws his sword.']

Setting A Guard In General

You can use the "waitUntil" or waitUntilNow" agenda items to gave any attribute change trigger the guard. This example does the same as the previous, but illustrates the technique.

w.orc.agenda = ['waitUntilNow:tapestry:scenery:false:The orc draws his sword.', 'antagoniseNow']

Kill

To just kill an NPC call the "terminate" function, passing the fatal attack as a parameter, if applicable. If it is already dead, nothing will happened. If it is alive, it will become dead, triggering its afterDeath function and printing its "msgDeath". Its "dead" attribute will be set to true.

w.orc.terminate()