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