You may find examples of monsters already built in /obj/mon.
What must be done in each and every monster!:
To build a monster, you must first inherit "/std/monster";
In the create functions, you must call the following functions IN ORDER!:
set_name("beggar"); // Please use a single noun for set name so that
intelligent objects can use phrases like "a beggar".
This function simply gives the monster a generic
name. (Also see set_proper_name()) //
set("id", ({ "beggar", "poor beggar", "a poor beggar", "a beggar" }) );
// These are the things a player must type to make
reference to the monster, as in look at poor beggar.
You can have any number of id's inside the ({ }),
but make sure you separate them by , and enclose them
in "". For advanced information, this is an example
of an array. //
set_level( 4 ); // This actually does a lot of things besides setting the
monster's level, and that is why you should call it
before you call other things. Besides making the
beggar 4th level, it also sets all other attributes
necessary to keep the beggar MINIMALLY balanced.
To name a few examples, this will set the monster's
skills and stats to a minimum level for a level 4
monster. It will set the monster exp to the level
of a fourth level player, and so on. //
set("short", "a poor beggar" ); // This sets the desc you see when you enter a
room with the monster in it.
set("long", "He is a poor pathetic beggar looking for a few coins." );
// This sets the decription you see when you look at
the monster.
set("race", "human" ); // This makes the monster a member of a certain race.
See /doc/build/races for a list of races. This
list is never complete, and it is meant to be added
to, but any time you want to add a race that is not
on the list, mail APPROVAL so that the race can be
added to the list. //
set_gender( "male" ); // The old version used numbers to indicate gender.
Nowadays gender is set with a string. Acceptable
strings are "male", "female", "neuter". Make sure
you set this, as a neuter knight is a silly thing.
Either :
set_body_type("human"); *or* add_limb("head", "FATAL", 20, 0, 4);
// Let's start from the back up. In the
Nightmare 3.0 limb combat system, you must create
a body for a monster. You do this by adding limbs.
set_body_type() automatically adds the limbs used
by the player race you pass, or by the monster
body type you pass as an arg. Examples:
set_body_type("artrell") set_body_type("quadruped")
If you want ANY odd combination, you must add_limb
from scratch. If you simply want two heads for a
two headed giant, set_body_type("human") and add a
"right head" or something. You cannot have two limbs
with the same name. Now the meaning of the stuff in
add_limb():
add_limb( limb_name, referent_limb, max_dam, dam, ac);
The limb_name is self explanatory, it gives the limb
a name, like "right forepaw".
referent_limb is the name of any limb that must
necessarily be lost if this one is. For example,
if you lose your "right arm" you WILL lose you
"right hand". So in adding the "right arm", you
put "right hand as the referent limb. If no limb
will be lost, put "". If the loss of the limb = death
put "FATAL". Fatal limbs must have AT LEAST half of
the damage taking ability as the monster has hp.
max_dam is the maximum amount of damage the limb can
take before being lost. As I just said, for fatal
limbs, this number should be 1/2 (at least) the
monster's hp.
dam is the amount of damage the monster is starting
with on the limb. In this way you can creatively
make wounded monsters, great for newbie areas.
ac is the ac of the limb. Limbs should have an ac
at least = to the monster's level in low levels and
right at the monster level at high levels.
set_overall_ac( 4 ); // This sets the ac of all limbs to 4, except the torso
which it sets a bit higher than the number.
These are all of the functions minimally necessary to create a monster.
However, just using these functions will not help you get a monster past
QC, as they will be dull monsters set up for hack and slash. Below is a
listing of optional functions you may put in code to individualize your monster.
******************************************************************************
set_wielding_limbs( ({ "right hand", "left hand" }) );
// Sets the limbs in which a monster
is able to wield a weapon.
set_ac("right hand", 7); // Sets the ac of a limb to a certain number.
set_fingers(5); // Gives the monster fingers. Necessary to have the
monster wear rings.
set_moving(1);
*and*
set_speed(60); // Makes the monster a wandering monster. 1 MUST be
the argument to moving, whereas speed is how often
the monster moves in seconds. ALL wandering
monsters on Nightmare MUST be intelligent monsters.
This means they have to respond to external stimuli
beyond kill. Their wandering needs a purpose.
set_max_hp(100); // Sets the maximum number of hit points a monster
may have. You would set this if you want to create
a monster that is wounded and can heal.
set_hp(50); // Sets how many hp the monster has. The function
will not allow you to set it below a certain number
depending on the level of the monster.
set_max_sp(400); // Sets the maximum number of stamina points
set_sp(300); // Sets the starting stamina points
set_exp(1000); // Sets how many experience points the monster has, and
therefore its worth to the player. Thois function
is mostly useless to the immortal, since it will not
allow you to set it above the default setting. But
if you want to make a 20th level monster yielding
no exp, set_exp(0); is the way to do it.
set_skill("melee", 20) // Sets a given skill to a certain number. This will
not allow you to set the stat below its default
setting. This is useful for creating monsters that
pick pockets, steal, or (in the future, I hope)
caste mage, monk, or cleric spells.
YOU MUST USE THIS IF YOU WISH THE MONSTER TO WIELD
A WEAPON EFFECTIVELY. Otherwise Balance will have
you shot :)
set_stats("strength", 15) // Sets a monster stat value.
set_class("cleric"); // Makes the monster a member of a certain class. I
hope to make this important later, by allowing the
monsters with set_class to do class-like things.
set("aggressive", 10) *or* set("aggressive", "special_func");
// If you pass a number, then it will have the monster
automatically attack anyone with a charisma lower than that
number. If you pass a string, then it will look for a
function by the name of the string passed to call (you write
the function and specify what you want to happen when the
monster encounters a player). This is useful for making
monsters which only attack rogues or artrells or whatever.
set_wimpy(20); // Makes the monster wimp out at 20% of its max_hp
set_wimpydir("out"); // Makes "out" the preferred direction of wimping out.
Keep in mind that if you set out and there is no out,
it will search for a direction that is there.
set_spell_chance(30); // Sets the percent chance the monster has during an
and attack for each round for casting a spell.
set_spells( ({ "missile", "shock", "fireball" }) );
// Sets up a list of possible commands the monster
can execute during combat. Note that game defined
attack spells need no argument during combat. But
other spells, like heal spells, stealing, and
immortal defined spells need any appropriate arguments
Remember that the monster needs the right amount of
magic points in order to cast a spell. Also, some
spells require the monster to be a member of a certain
class. And if you want the monster to cast the spell
effectively, remember to set that skill.
set_languages( ({ "farsi", "borgish" }) );
Makes the monster be able to speak each of these
languages fluently. A monster needs to be able
to speak a language fluently in order ALWAYS to
understand the utterances of another fluent speaker
in the same language (for insteance, when you use
set_speech() or define catch_tell())
set_lang_prof("nibelungen", 7);
Useful for making a monster partially adept
at a given language. (fluency range: 1-10)
set_emotes(20, ({"The beggar grovels a bit.","The beggar whines."}), 0);
This sends emotes and other messages to the room.
Every heart beat, this beggar will have a 20% chance
(the first arg) of sending out randomly one of these
messages. The third argument is either 1 or 0.
1 means the message is for combat, 0 is for peace.
set_speech(20, "farsi", ({"I have nothing to sell.", "My brain hurts."}),0);
Much like set_emotes(), except this sets up text
which the monster will randomly try to speak using
the speak command. Of course, the monster must
already have had set_lang_prof() or set_languages()
set for the language (in this case "farsi") being
spoken.
set_achats(20, ({ "The beggar bleeds on you.\n", "The beggar spits on you.\n" }) ); \\ This is the same as set_chats(), except that these chats
are given while the monster is engaged in combat.
*******************************************************************************
Functions outside of create() that you define:
void catch_tell(string str) { }
Whenever anything is done in a room, like you give bozo a flower, the function
tell_object is used to tell:
you: You give Bozo a flower.
Bozo: Descartes gives you a flower.
anyone else in the room: Descartes gives Bozo a flower.
The string given by tell_object() to a monster will go to the function
catch_tell if it exists in the monster, so that, if Bozo is a monster, then
str in our catch tell: str = "Descartes gives you a flower."
inside catch_tell, you can do whatever you want with this string, the most
common user is to use a function called sscanf() to search for keywords in
the monster. I am adding a function to monster.c called interact
usage: interact(str1, str2);
If str1 is in str2, the the function will return 1, if not 0;
So we could test to see if Bozo is getting a sword by the following:
if(interact("gives", str)) {
if(interact("you", str)) {
if(interact("sword", str)) {
if(present("sword")) tell_room(environment(this_object(), "Bozo says: Thank you!\n");
}
}
}
You need to check in the case of gives that it was actually a giving, and no
emote was used. Make sure you do not have the monster respond by teling
a phrase that would in turn cause it to respond again. You can always
exempt the monster from being told what you are telling the room with the
following syntax:
tell_room(environment(this_object()), string_to_be_told, ({ this_object() }) );
Please note that I put a syntax error in my tell room in the Bozo example.
there is a missing ). But the tell_room example I just gave is correct.
Please see /doc/efun/tell_room, /doc/lfun/catch_tell, /doc/lfun/interact,
/doc/efun/tell_object
-Descartes of Borg 920928
modified 930822