Chapter 4

Adding Special Functions for Non-Player Characters

Adding special procedures for Non-Player Characters (NPC's) is in fact somewhat simpler than adding them for players. Once the NPC definition and placements have been added to the world files, there are only three things which need to be done: write a handler function, assign the handler to the character type, and update the mob file. Note also that special procedures are totally independent of whether the character is a type S (standard) or type E (extended) mobile; this distinction is only made in the mob file and the only difference is that the builders have more fine control over the attributes of the type E. Also, the procedure for adding special functions to objects is very similar to that for adding them to NPC's, so while this example will add a special function to a non-player character, it can also be used as a guide to adding special functions for objects as well.

If your game is actively running, the SPEC flag in the action bitvector in the NPC's mob file entry should not be set until the changes are made and recompiled, and you are about to restart the game. This is the first bitvector of the NPC definition, at the beginning of the first line after the tilde (~) which ends the long description. If this flag is set, a letter-based bitvector will start with an "a", and a number-based bitvector will be odd. See Jeremy Elson's "building.doc" for more information on this. If your game is not actively running, of course, you can set this bitvector flag now.

Of course, if you haven't even added the NPC's to the .mob and .zon files, the first step is to do so. The characters we are going to add here are called the "Rangers of Don", and we will create both male and female versions for the sake of fairness. For now, we will place them in zone 60, which is the forest region to the west of Midgaard. You are welcome to add them to other zones as well.

Open "60.mob" from the world files in the game file library. Go down to the end of the file. The last entry should be for mobile number 6019, the duck. Right below that entry, above the dollar sign that ends the file, insert the following:

#6020
ranger don~
the Ranger of Don~
A Ranger of Don is here, observing nature.
~
The Ranger of Don is a young man, just barely in his twenties.  He is on
the tall side, handsome, with a peaceful yet righteous air about him.  He
is a member of the Rangers' Guild, and carries their signature Archer Bow. 
~
abeglopt d 1000 S
13 12 2 1d12+123 1d8+5
500 10000
8 8 1
#6021
ranger don~
the Ranger of Don~
A Ranger of Don is here, observing nature.
~
The Ranger of Don is a young woman, just barely in her twenties.  She is
on the tall side, handsome, with a peaceful yet righteous air about her. 
She is a member of the Rangers' Guild, and carries their signature Archer
Bow. 
~
abeglopt d 1000 S
13 12 2 1d12+123 1d8+5
500 10000
8 8 2


These characters will both be immune to the entanglement spell, through the addition of the "t" to the action bitvector. They are also marked for special procedures, per the "a" in the same bitvector.

Close "60.mob" and open "spec_procs.c" from the source code. The section marked for "General Special Procedures For Mobiles" starts at about line 327. After the last function already there, which should be SPECIAL(magic_user), insert the following function above the start of the next section, "Special procedures for mobiles", at about line 460:

SPECIAL(RangerOfDon)
{
  int percent, prob;
  struct char_data *vict;

  if (cmd)
    return FALSE;

  if (GET_POS(ch) != POS_FIGHTING)
    return FALSE;

  vict = FIGHTING(ch);

  if (vict && (vict->in_room == ch->in_room) &&
      (number(0, 40 - GET_LEVEL(ch)) <(GET_LEVEL(ch) >> 1) )) {
    percent = ((10 - (GET_AC(vict) / 10)) << 1) + number (1, 101); prob = number(45, 90); if (MOB_FLAGGED(vict, MOB_NOBEARHUG)) { percent = 101; } if (percent > prob) {
      damage(ch, vict, 0, SKILL_BEARHUG);
    } else
      damage(ch, vict, GET_LEVEL(ch) << 1, SKILL_BEARHUG); return TRUE; } return FALSE; } 

This function was actually derived from the snake function further up, with a section of our do_bearhug function from the previous chapter substituted for a call in snake to the magic procedures for the poison spell. It is a relatively basic NPC function, which determines first if the character is fighting. If the character is not fighting, it exits. Otherwise, it determines whether or not to bearhug the character it is fighting. If so, it determines whether or not the bearhug succeeds, and makes the appropriate call to the damage function.
Now close "spec_procs.c" and open "spec_assign.c". The assignment of special procedures to mobiles is accomplished, as in chapter 2, by the assign_mobiles function, located around line 66. First the function being assigned to the mobile must be made visible. The function starts with a number of lines which do this for the existing NPC special functions:
  SPECIAL(postmaster);
  SPECIAL(cityguard);
  SPECIAL(receptionist);
  SPECIAL(cryogenicist);
  SPECIAL(guild_guard);
  SPECIAL(guild);
  SPECIAL(puff);
  SPECIAL(fido);
  SPECIAL(janitor);
  SPECIAL(mayor);
  SPECIAL(snake);
  SPECIAL(thief);
  SPECIAL(magic_user);
  void assign_kings_castle(void);

Somewhere in or right below this section, insert the following line to make the RangerOfDon function available:
  SPECIAL(RangerOfDon);

Now, go down into the section labeled "forest", which starts at about line 191:
  /* FOREST */
  ASSIGNMOB(6112, magic_user);
  ASSIGNMOB(6113, snake);
  ASSIGNMOB(6114, magic_user);
  ASSIGNMOB(6115, magic_user);
  ASSIGNMOB(6116, magic_user); /* should be a cleric */
  ASSIGNMOB(6117, magic_user);

Insert the following two lines in that section:
  ASSIGNMOB(6020, RangerOfDon);
  ASSIGNMOB(6021, RangerOfDon);

This will allow NPC's of both Ranger of Don types to use the special function which gives them the bearhug ability. All that remains is to add some Rangers of Don to the scenery.
Close "spec_assign.c" and open "60.zon" from the world files of the game data library. For the sake of having a place to put these characters, I have chosen six rooms in zone 60, all of which have no other non-player characters present, to place them in. While this is not the ideal way to decide placement of NPC's, it will do for the purposes of this walkthrough.
Go down to the end of the file. The last two lines contain the letter S and a dollar sign, respectively. Insert the following lines above these last two lines of the file:
* Rangers of Don
M 0 6020 5 6000         Ranger of Don (M)
E 1 3026 999 16                 Archer Bow
M 0 6021 5 6000         Ranger of Don (F)
E 1 3026 999 16                 Archer Bow
M 0 6021 5 6020         Ranger of Don (F)
E 1 3026 999 16                 Archer Bow
M 0 6020 5 6031         Ranger of Don (M)
E 1 3026 999 16                 Archer Bow
M 0 6020 5 6068         Ranger of Don (M)
E 1 3026 999 16                 Archer Bow
M 0 6021 5 6075         Ranger of Don (F)
E 1 3026 999 16                 Archer Bow
M 0 6020 5 6076         Ranger of Don (M)
E 1 3026 999 16                 Archer Bow

Close "60.zon", delete any compiler object files you might have in your "src" directory from previous compiles, and make or re-make the program. If everything is in order, there should be seven Rangers of Don throughout the forest section immediately west of the West Gate of Midgaard, and they should have the ability to bearhug during a fight.