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; }
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);
SPECIAL(RangerOfDon);
/* 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);
* 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