Table of Contents

Configuring an NPC guard

Summary

This creates a simple NPC guard, in this example every character has an Allegiance. There is an “Allegiance Hall” which is guarded by this NPC, it allows entry to members of its allegiance, but must be defeated by anyone else. It can be healed by members of its own faction if it is not at full health.

Note this example is easily exploitable, in that any defender can reset the guard endlessly, it's more intended as a base for building a setup with rules, e.g. if you want guards against stealing when other players may not be around.

Take the example with a pinch of salt.

Note this implementation is tedious to interact with ; you click the guard over and over until you die or it lets you in, this is a very dull and spammy activity. Try be more creative :)

Deployment

The Health, Scripting and Teleportation modules must be enabled.

Create two landmarks, “Inside” and “Ejected” (move to the location in world and run “/1teleportation.createlandmark Inside” for example)

You must create a character (/1characters.create Name, surround Name in “” if it contains spaces) and then set it to be an NPC (/1characters.makeNPC <name>).

Rez an object in world, give it a reasonable name (not used), and insert the “GPHUD Object Driver” script (obtainable from the region server with /1objects.getdriver)

In the web interface, under configuration, scripting, create a script called “Guard”, or similar, and paste the script below. Save source.

Under configuration, objects, create a new Object Type called “Guard”, or similar, set it to be of type NPC, bind the character and script we just configured.

Back on Configuration, Objects, find the newly connected guard object and set its object type to “Guard”, then reboot it.

Example interactions

As a friend:

[15:52:45] test tends the wounds of Guard
[15:52:48] Guard salutes as test passes into the building</pre>

As an enemy:

<pre>[15:55:11] Guard challenges test2 as they attempt to force their was past into the building!
Guard is hit by test2 and now has 2 health
[15:55:12] Guard challenges test2 as they attempt to force their was past into the building!
Guard strikes successfully at test2 who now has 6 health
[15:55:14] Guard challenges test2 as they attempt to force their was past into the building!
Guard is hit by test2 and now has 1 health
[15:55:15] Guard challenges test2 as they attempt to force their was past into the building!
Guard is hit by test2 and now has 0 health
Guard is defeated and will no longer impede entry to the building
[15:55:23] Guard is incapacitated and unable to act as test2 enters the building

Sample code

//
// A sample GUARD for a (sealed) building.
// IF you are of the same "Allegiance" then you either heal the guard
// or teleport into the "safe building".
// Otherwise, if the unit has health you'll engage it in combat
// once it dies, you can enter the sealed building too.
// if it defeats you, you'll be removed from the area
//
// As an NPC, CALLER is the NPC, and TARGET is the interactor
//
// Version 1.0 =)

Integer discard=0;

String ourallegiance=gsGetGroupByType(CALLER,"Allegiance");
String theirallegiance=gsGetGroupByType(TARGET,"Allegiance");
Integer ourhealth=gsGetKV(CALLER,"Health.Health");
Integer maxhealth=gsGetKV(CALLER,"Health.InitialHealth");
if (ourallegiance==theirallegiance) {
  // SAME ALLEGIANCE
  if (ourhealth<maxhealth) {
    // heal the NPC
    discard=gsSayAsChar(TARGET,"/me tends the wounds of "+CALLER);
    discard=gsAPIX(CALLER,"Health.ResetHealth",[]);
  } else {
    // enter the building
    discard=gsSayAsChar(CALLER,"/me salutes as "+TARGET+" passes into the building");
    discard=gsTeleport(TARGET,"Inside");
  }
} else {
  // DIFFERENT ALLEGIANCE
  if (ourhealth==0) {
    // if the guard has zero health then we just let people pass
    discard=gsSayAsChar(CALLER,"/me is incapacitated and unable to act as "+TARGET+" enters the building");
    discard=gsTeleport(TARGET,"Inside");
  } else {
    // Guard will engage in combat
    discard=gsSayAsChar(CALLER,"/me challenges "+TARGET+" as they attempt to force their was past into the building!");
    // implement combat here.  as this is a demo script we do something dull
    Integer guardroll=gsRand(1,6);
    Integer attackerroll=gsRand(1,6);
    if (guardroll==attackerroll) { 
      // draw, no effect
      discard=gsSayAsChar(CALLER,CALLER+" and "+TARGET+" clash weapons ineffectually");
    }
    if (guardroll>attackerroll) {
      // score damage
      Integer theirhealth=gsGetKV(TARGET,"Health.health");
      theirhealth=theirhealth-1;
      if (theirhealth<0) { theirhealth=0; }
      discard=gsAPIX(TARGET,"health.set",[""+theirhealth]);
      discard=gsSayAsChar(CALLER,CALLER+" strikes successfully at "+TARGET+" who now has "+theirhealth+" health");
      if (theirhealth==0) {
        discard=gsSayAsChar(CALLER,CALLER+" defeated "+TARGET+"!");
        discard=gsTeleport(TARGET,"Ejected");
      }
    }
    if (guardroll<attackerroll) {
      ourhealth=ourhealth-1;
      discard=gsSayAsChar(CALLER,CALLER+" is hit by "+TARGET+" and now has "+ourhealth+" health");
      discard=gsAPIX(CALLER,"Health.Set",[""+ourhealth]);
      if (ourhealth==0) {
        discard=gsSayAsChar(CALLER,CALLER+" is defeated and will no longer impede entry to the building");
      }
    }
  }
}

Script