doc/004277500000240000044000000000000556520756200113035ustar00mudmud00000420000006doc/build/004677500000240000044000000000000555501453300123775ustar00mudmud00000420000006doc/build/feelings010066400003740000036000000035540546771740400153460ustar00hubbelysator00000420000006Normally you shouldn't make objects that contains 'feelings' because they should be handled by /obj/soul. If you however feel that your feelings doesn't belong in the standard soul it is now possible to patch them into the standard soul with the use of the following functions in the soul. =========================================================================== NAME add_verb(mapping m) DESCRIPTION This function adds verbs to the soul. They will stay there until removed or until soul is destructed. (ie. when player log off) The argument m is a mapping of the same format as the one in the beginning of /obj/soul as the format is quite complex I will not go into details here but advice you to learn from the numerous examples in /obj/soul. =========================================================================== NAME remove_verb(string *v) DESCRIPTION Remove_verbs removes verbs previously added to the soul, not that the standard verbs present from the beginning in the soul cannot be changed nor removed. =========================================================================== NAME add_adverb(string *v) DESCRIPTION With this function you can add adverbs to the soul. It's as simple as that. In all other resepects it works just as add_verbs. =========================================================================== NAME remove_adverb(string *v) DESCRIPTION With this function you can remove adverbs previously added. Note that you can not remove adverbs that are there by default. =========================================================================== Note that that if you patch in feelings in the soul they will not stay there permanently. Therefore you will normally have to patch the players soul every time he log on. Easiest way to do that is to use an autoloading object. If your feelings belong to a guild, the guildobject should be used. doc/build/RULES012077700003050000036000000000000553641112500154402../RULESustar00matcalysator00000420000006doc/build/ed0010066400000240000044000000007050475505112400127610ustar00mudmud00000420000006When in 'ed', the prompt is ':'. Ed has two modes, command mode and insert mode. The insert mode has no prompt. You exit the insert mode by typing a single '.' on a line. All commands have the following syntax: X,Ycmd or Xcmd For example: 1,10p Will print line 1 to 10. 1,5d Will delete line 1 to 5. 8p Will print line 8. A '.' is the "current line". The current line is the last line referenced. If you want to print last line + 10 more: .,.+10p doc/build/ed1010066400000240000044000000014230475505112500127610ustar00mudmud00000420000006Commands that use a line range: If no line is given, then curent line is printed. p Print line. d Delete line. l Print line with control characters. r file Read in a file after the line specified. s Substitute patterns. See special documentation. z Print 10 lines. a Start insert mode after specified line. Exit with '.'. i Start insert mode before specified line. Exit with '.'. Commands used without line specification: q Quit. Won't work if file is changed. Q Quit and discard all changes if not saved. w Write the file out. w file Write the file out with name 'file'. e file Edit a file. !cmd Give a game command. For example "say Wait, I am busy". As line numbers '.' is current line, and '$' is last line of file. Thus '1,$p' will always print all of the file. doc/build/ed2010066400000240000044000000007660475505112500127730ustar00mudmud00000420000006Substitutions are very advanced. First a simple example: s/apa/bepa/ This will substitue the 'apa' in current line to 'bepa'. If an 'p' is appended, you will also immediately see the result. 1,$s/apa/bepa/ Same, but all lines in file. Only first occurence on every line. Any character can used instead of '/': s!apa!bepa!g The 'g' specifies that all occurences of apa on this line are changed to bepa. The pattern that are supposed to be replaced, can be a regular expression. See ed3 about that. doc/build/ed3010066400000240000044000000007450475505112500127710ustar00mudmud00000420000006Searching is done with: /hello/ Find first line in of after current line. Just // will repeat the search. Theere are special characters that can be used in the pattern: . Match any character. x* Match any numbers of x (0 or more). [abc] Match 'a', 'b' or 'c'. [0-9] Match any digit 0 - 9. [a-z] Match any lowercase letter. \x Match 'x' where 'x' can be any character except '(' and ')'. Example: s/ab.d/ABCD/ Substitute any string 'abXd' against 'ABCD' where X can be any character. doc/build/ed4010066400000240000044000000003110475505112600127600ustar00mudmud00000420000006How to copy from a standard file. Enter ed. Then do 'r /room/vill_green.c'. Now you have something in the buffer. Change it into what you want it to be. Then 'w /players/peter/hall.c'. Or 'w hall.c'. doc/build/castle010066400000240000044000000021160500570006000135470ustar00mudmud00000420000006The castle you have is just a 'facade'. If you look at the source, you will find that it defines an 'enter' command, but won't move the player anywhere. You have to make a hall way or something like that first. Do this by copying one of the standard files (se ed4). Now change the line in your castle.c that says write("This is a close..."); into this_player()->move_player("into castle#players/peter/hall"); The function "move_player" in the player object will move the player to your hall, tell other players around that he goes into the castle. The function 'call_other' is very special. The object 'this_player' could be seen as a package or module with a lot of functions. One of these functions is 'move_player' which is called with the argument "into castle#players/peter/hall" If you wish to change the way to enter you castle into, say, east then you will have to change the add_action("enter","enter") into add_action("enter","east") and the argument to move_player into "east#players/peter/hall" See doc about 'load' and 'update'. See rooms for documentation on how to make rooms. doc/build/armour.list010066400003050000036000000065310555030412200157770ustar00matcalysator00000420000006 A R M O U R S ============================================================================= A list of generic names, types, classes, weights and values. +----------------------------------------------------------------------------+ | IMPORTANT: These armour classes refer to values set with "set_class". | | "set_ac" is obsolete, but it still works - implemented roughly like this: | | void set_ac(int old_ac) { set_class(3*old_ac); } | +----------------------------------------------------------------------------+ | | | Name Generic names. | | type Those are mandatory. Note especially the spelling! | | class This is the absolute upper value used with set_class(). | | weight This is the minimum weight to go with the corresponding class. | | value This is the MAX value for the items. The value might be down | | to 20% lower, but not less. | | | | An armour without a type are not allowed to have class. An armour with a | | type other than armour can max have a class of 3. Type armour can at most | | have a class of 15, and that max is VERY, VERY rare. | +----------------------------------------------------------------------------+ | | | NOTE: If your item doesnt conform strictly to this, be sure to get it | | approved and that the approval is noted in /permissions! If it's | | not, don't be surprised if its suddenly changed next time you look | | at it. | +----------------------------------------------------------------------------+ Name type class weight value --------------- -------- ----- ------ ----- shirt armour 2 1 20 jacket armour 4 1 40 leather jacket armour 6 2 50 chainmail armour 9 5 500 platemail armour 12 9 1000 plates armour 15 12 4000 light shield shield 1 1 50 medium shield shield 2 2 100 large shield shield 3 4 300 cap helmet 1 1 20 leather helmet helmet 2 2 50 metal helmet helmet 3 3 200 cloth gloves glove 1 1 20 leather gloves glove 2 1 50 metal gloves glove 3 2 200 shoes boot 1 1 20 leather boots boot 2 2 50 warboots boot 3 3 200 mantle cloak 1 1 20 cloak cloak 2 2 50 heavy cloak cloak 3 3 200 jewelry ring 1 1 50 arm greaves ring 2 2 100 ring of prot. ring 3 1 300 jewlery amulet 1 1 50 neckband amulet 2 2 100 magic amulet amulet 3 2 300 doc/build/monster.list010066400000240000044000000025640555164260200147610ustar00mudmud00000420000006 Recommended minimum values for monsters. level HP WC AC ----- ---- ---- ---- 20 400 25 10 19 350 20 9 18 300 19 8 17 250 18 8 16 225 16 7 15 200 15 6 14 180 13 5 13 170 12 5 12 160 11 4 11 150 10 4 10 140 9 4 9 130 8 3 8 120 7 3 7 110 6 3 6 100 5 2 5 90 4 2 4 80 4 1 3 70 3 1 2 60 3 0 1 50 3 0 Remember that players over level 5 has spells, give your highlevel monsters the same opportunity. Small monsters could use wimpy more often. If the monsters are given a spell the WC above could be reduced with the amount of spell_dam*chance/100 if desired. Don't have items/coins for more than approx HP*WC*AC/20 of value in your monsters. You should never have more that 1000 coins on any monster, unless it's a _very_ thought one. The alignment should lie between -1000 and +1000. Monster Alignment ------ --------- Demon -1000 Dragon -500 Troll -100 Orc -50 Rat -20 Human 0 Bird 20 Hobbit 50 Unicorn 500 Angel 1000 Any major differing from these figures might be subject to archwizard inquieries. doc/build/error010066400000240000044000000007670475505113000134470ustar00mudmud00000420000006If there are any errors when loading a new file, the object will not be loaded at all, and you will be thrown out to the void. To look at the error message, cat or edit the file /log/name, where 'name' is your name. Check this file regularly, and trim it if big (use rm). The line number specified by the error can be several lines wrong sometimes. Sorry for this. There can also be a run time error, for example if the room tries to move you to a room that does not exist. Again, look at lpmud.log. doc/build/rooms010066600012670000065000000026310553064461700153760ustar00ppannionstacken00000420000006This is the file that explains how to make your rooms. The easiest way to make new rooms is to use the roommaker, clone /obj/roommaker and then help room maker to get info on it. For the little more advanced programmer it is recommended that you inherit "/room/room". See the below example (taken from /room/vill_green.c). Also read the file /room/room.c for some more information on what the different variables stands for. inherit "/room/room"; /* Always set the constant variables (yes, it sounds silly...) * in reset(), after the if(arg) return statement. */ reset(arg) { if (arg) { set_light(1); short_desc = "Village green"; no_castle_flag = 1; long_desc = "You are at an open green place south of the village church.\n" + "You can see a road further to the east.\n"; dest_dir = ({"room/church", "north", "room/hump", "west", "room/vill_track", "east"}); items = ({"church","It looks ancient", "road","It seems to lead into the village"}); } /* Here you do things that you want to do every reset, monsters etc. */ } query_inorout() { return 2; } If you have any troubles making rooms then first ask a fellow wizard and if he cannot answear your questions then ask an archwiz/high wiz. If you want to add a monster then read the monster file and the monster.list file to see how it's done. ables stands for. inherit "/room/room"; /* Always set the constant variables (yes, it sounds silly..doc/build/genders010066400000240000044000000030320475505113200137330ustar00mudmud00000420000006Genders ------- Living objects that inherit /obj/living can now have a gender: they can be male, female or neuter. There is a variable, gender, which can have the values 0, 1 or 2, #defined in /obj/living.h as NEUTER_GENDER (0), MALE_GENDER (1) and FEMALE_GENDER (2). These functions have been defined in /obj/living.c: query_gender() -- returns the value of the gender variable query_neuter() -- returns true if gender is neuter (0) query_male() -- returns true if gender is male (1) query_female() -- returns true if gender is female (2) set_gender(g) -- sets the gender variable to g (after checking) set_neuter() -- sets gender to neuter (0) set_male() -- sets gender to male (1) set_female() -- sets gender to female (2) query_gender_string() -- returns "neuter", "male" or "female" query_pronoun() -- returns "it", "he" or "she" query_possessive() -- returns "its", "his" or "her" query_objective() -- returns "it", "him" or "her" The function show_stats(), used by the wizard command stat, has been modified so it also displays the gender of the monster or player. /obj/player.c has been modified to ask for a gender when a player logs in for the first time, and to print "He is in good shape." etc. I also changed the soul to print "Sabrina twiddles her thumbs." etc. Monsters are neuter by default. Old players will be asked at their next login. Padrone (Email: padrone@lysator.liu.se) Oct 22, 1990 doc/build/GUILDS010066400005540000036000000111540554406632300145440ustar00karinlysator00000420000006*** General information *** Before you start writing a guild you should write down all the powers that you think you will have and all the drawbacks. There should also be an explanation of how they fit in the guild. It is also good if you add some information about the general feeling of the guild. Then you give this document to the guild coordinatior. He/She will then tell you if it is ok to start coding or if something has to be changed. This is because you shouldnt have to code things that the guild coordinator not will approve later. Then you write your guild. (See instructions below.) When you are finished you have to add information to your document about exactly how the powers/drawbacks works. After that the guild has to be finally approven by the guild coordinator. The document is then put in /open/GUILDS/GUILD_your-guild-name. **************************** If you are a wizard and want to make a guild of your own, then you should do this: Copy the file /room/adv_guild.c, and make your own titles. It is important that your new guild has the same costs for advancement. This is done by the call "room/adv_guild"->query_cost_for_level(l, e), where 'l' is the current level of the player, and 'e' is the current experience of the player. This function should return the cost in gold to advance for that player. Put this function call in cost_for_level(). Why this extra call ? Because the file room/tune.h might get changed, and the adv_guild.c reloaded with new costs. The cost to advance must be the same in all guilds, as it should not be used for competition. Don't forget to remove the lines for cloning of bboard, orc_slayer-quest and the book in extra_reset(). Next step is to make an autoload object, that players will carry that shows that they are a member of your guild. The object does not have to be visible to the player, but it must have an id == "guild_mark". You must also check that the player is not member of another guild, by the call: present("guild_mark",this_player()). It can happen that a player can lose his autoload object. It is a requirement that all guilds must document all their features in /open/GUILD_xxx, so that all wizards can see what they do. Not how the features are implemented, but what features are implemented. A normal thing with guilds are that they give some nice feature to the player, like special "emotes", extra spells, and other fancy things. It must be possible to leave the guild. Players in your guild must also solve enough quests before becomming wizard. Things that are allowed: Basically are all abilities that aren't too powerful allowed. Limits: Basically all guildpowers must cost sp or hp. (Exceptions from this can be made if the power has other great limitations.) There has to be a logical connection between the guild and the abilities. Teleporting to the guild from many different places in the game have to cost at least 30 sp. Healing may not be better then heal one hp per sp cost (in average). The total abilities (including disadvantages) in a guild may not make the guild more powerful then mageguild. The powers should be in proportion to the players level. That can be made by not allowing abilities until a certain level or make them work less powerful for low-level players. Disadvantages (examples): The guild members may not use party object. The guild members may not use armours. The guild members may not have magobj. Examples of things NOT counted as disadvantages: Playerkilling/Non playerkilling (That is only an attitude.) Hard to join the guild. Long or hard way to the guild. Certain alignment to advance level/stats. Guildline/clubline: =================== All guilds may have a guildline. It doesn't have to cost anything to chat over a guildline, however there is a minimum cost for clublines of 15 sp/chat. The following 4 files in the /open/line library should be used when making a line: 1. /open/line/line.c All functions needed for handling the line. 2. /open/line/send_player.c A statue of the player that automatically will be placed in the send_room. 3. send_room.c The room for keeping statues for the line. (Just make a copy of /open/line/send_room.c) 4. send.h All constants needed for specifying your own line. (Make a copy of /open/line/send.h and make your own adjustments) Here is an example of how to write in your guild-object: (OBS Do NOT change the order of these includefiles.) #include "/players/your-name/send.h" #include "/open/line/line.c" init(arg) { init_line(); } doc/build/general010066400000240000044000000007160533543417000137310ustar00mudmud00000420000006The best way to start building things are to read through the /doc/build/rooms and look at some files in /room and /obj. Some of this files may be very old and thus does not serve as very good examples but /room/vill_green.c is up to date with the new technique used to make rooms. Also check the /doc/examples directory for further examples on how to build things in this mud. These files are kept up to date and should be considered as good style of coding. doc/build/weapon010066400012670000065000000077130553064452400155310ustar00ppannionstacken00000420000006There is a generic weapon avaliable. To set up do : object wobj; wobj = clone_object("obj/weapon"); For customization the following routines are available : You should call these functions: set_name(n) string n. Sets the name and short description to n. Sets long description to "You see nothing special.\n" set_class(c) int c. Sets how much damaged it will do. Refer to weapon.list to get the suggested value. set_weight(w) int w. Sets the weight. set_value(v) int v. Sets the value. These are the optional functions: set_alt_name(n) string n. Adds an alternate name to weapon. set_alias(n) string n. Adds another alternate name to weapon. set_short(sh) string sh. Short description is set to sh. Long to capitalize(short)+"\n" set_long(long) string long. Long description is set to long. set_read(str) string str. str will be returned if it's read. set_info(n) { info = n; } string n sets the info to n info is an extrastring that some guilds/objects uses to see special messages from the creator of the object. ie. good use for this in magic- or quest items. set_hit_func(ob) object ob. Sets up a call to function 'weapon_hit' in object 'ob'. 'weapon_hit' is called every time the weapon strikes someone. The argument given to 'weapon_hit' is the target of the attack. The return value of 'weapon_hit' adds to the weapons wc for this hit. Returning the string "miss" will cause the weapon to miss. set_wield_func(ob) object ob. Sets up a call to function 'wield' in object 'ob'. 'wield' is called every time the weapon is wielded. A return value of 0 from 'wield' means that the weapon will not be wielded. 1 that it's okey to wield it. set_magic() calling this function will set the magicflag in the weapon. Set_wield_func and set_hit_func will set the magicflag automatically. Set this if you don't want your weapon to be modified by weaponsharpers etc. set_hit_lines_object(ob) object ob. Sets up a call to the function 'hit_lines' in object 'ob'. 'hit_lines' is called every time you hit something and is wielding the weapon. The arguments given to 'hit_lines' is how much damage the attack does, the target of the attack, and who the attacker is (the one that wields the weapon). 'hit_lines' should return an array containing of 3 strings: ({ "Message to the target", "Message to the wielder", "Message to the rest of the people in the room" }); If an correct array isn't returned then the regular message will be used. NOTE! All weapons that change the hit message must be approved by 23++. EXAMPLE /* * This is a magic sword is has a wc of 9 as base * and a wc of 19 if it's attacking an orc. */ orc_slayer = clone_object("/obj/weapon"); orc_slayer -> set_name("short sword"); orc_slayer -> set_alias("sword"); orc_slayer -> set_short("a short sword"); orc_slayer -> set_alt_name("orc slayer"); orc_slayer -> set_long("This is a very fine blade.\n"+ "It's covered with ancient runes.\n" + "Engraved on it is a picture of the sword slicing an orc.\n"); orc_slayer -> set_read("The only thing you can read is the word 'orc'.\n"); orc_slayer -> set_class(9); orc_slayer -> set_weight(2); orc_slayer -> set_value(200); orc_slayer -> set_hit_func(this_object()); orc_slayer -> set_hit_lines_object(this_object()); . . . weapon_hit(attacker) { if(attacker -> id("orc")){ write("Ziiing\n"); return 10; } return 0; } hit_lines(dam,target,hitter) { string tarname, hitname; tarname = target->query_name(); hitname = hitter->query_name(); if (!dam) return ({ hitname+" tries to hit you, but you evade it beautifully\n", tarname+" evades your attack.\n", tarname+" evades "+hitname+"'s attack.\n" }); if (dam < 15) return 0; return ({ hitname+" hits you black and blue.\n", "You hit "+tarname+" black and blue.\n", hitname+" hits "+tarname+" black and blue.\n"}); } doc/build/monster010066400000240000044000000150300523716634700140070ustar00mudmud00000420000006There is a generic monster avaliable. To set up do : object mobj; mobj = clone_object("/obj/monster"); (For more advanced monsters, I suggest that you use /obj/smartmonster instead. Look at the file /doc/build/smartmonster!) For customization the folling routines are available : You must call this functions. set_name(n) string n. Sets the name and short description to n. Sets long description to "You see nothing special.\n" set_level(l) int l. The monster gets the level l. Hit points and ep is set as the same as player of level l. Armour class to 0 and weapon class to that of hands. For suggestions on the hp,wc and ac for a monster look in the file named monster.list. If you follow the suggestions can be almost sure of that no archwizard will be mispleased with you. You should call these functions: set_hp(hp) int hp. Sets hit points to hp. set_wc(wc) int wc. Sets the weapon class, how much the damage it will do, to wc. The damage inflicted is in the range 0..wc-1 . set_ac(ac) int ac. Armour class is set to ac. This are the optional functions. set_ep(ep) int ep. Sets ep to ep. set_al(al) int al. Sets the alignment to al, negativ is evil, pos good. set_alias(n) string n. Adds and alternate name for the monster. set_alt_name(n) string n. Adds another alternate name for the monster. set_race(r) string r. Adds an alternate generic name for the monster. set_short(sh) string sh. Sort description is set to sh. Long to capitalize(short)+".\n" set_long(long) string long. Long description is set to long. set_aggressive(a) int a. 0 means peaceful until attacked. 1 that it will attack everyone it sees. set_move_at_reset() If this routine is called the monster will do a random move at every reset. set_frog() If anyone kisses the monster he will turn into a frog. set_whimpy() When monster get low on hp it will flee. init_command(string cmd) Force the monster to do a command. The force_us() function isn't always good, because it checks the level of the caller, and this function can be called by a room. set_real_dead_ob(ob) object ob. The function 'monster_died' in 'ob' will be called just before the monster dies. The argument to 'monster_died' will be the nearly dead monster object. The return value from 'monster_died' determins the fate of the monster. A 1 means that the monster will survive 0 that it will die. set_dead_ob(ob) This was the old way to do the same thing, and it is kept for compatibility. The difference from "set_real_ded_ob" is that when 'monster_died' is called, the stupid monster is already dead! set_init_ob(ob) object ob. The function 'monster_init' in 'ob' will be called from init in the monster. The argument to 'monster_init' will be the the monster object. The return value from 'monster_init' determins if the monster will attack, if it's aggressive. A 1 means that the monster will not attack, 0 that it will function as usually. These are the spell functions: set_spell_mess1(m) string m. This is the message that the other players in the room get when the monster cast's a spell. set_spell_mess2(m) string m. This is the message that the victim of the monster's spell get. set_chance(c) int c. This is the percent chance of casting a spell. set_spell_dam(d) int d. How much damage the spell will do if it hits. The damage will be randomly 0 .. d-1 . You should try to use these functions often in highlevel monsters, after all, the players have spell so why shouldn't the monsters have some too? These are the chat functions: The chat options enables the monster to say something every heart beat. load_chat(c,str) int c. string str. Load the chat strings. c is the percent chance of saying something. str must be an array of strings. The monster will then pick one of them to say. load_a_chat(c,str) Same as above but is used when to monster is under attack. Here are the catch talk functions. Catch talk gives the the monster the possibility to act upon what it hears and sees. All messages streams that are sent to the monster are compared to a set of loadable strings. If a match occurs a function in a given object is called with the matching string as an argument. You can have one function per sentence or multiple senetence per function. set_match(ob,func,type,match) object ob. Tells which object 'ob' that holds the functions. This object becomes the default object. string func. This is the function name that shall be called when a match occour. string type. This is the second word of sentence to match. If you want do catch the sentence 'Humhum gives flower to lady' you should set type to 'gives'. string match. This is rest of the string to match. If you want do catch the sentence 'Humhum gives flower to lady' you should set match to 'flower to lady'. func,type and match must be arrays of strings and the size of the arrays must be equal. EXAMPLE string function, type, match; function=allocate(3); type = allocate(3); match = allocate(3); /* * This cathes 'name gives flower to Lady.' and * 'name gives flower to Ann.' and binds it to * the function 'handle_give' in the current object. */ function[0] = "handle_give"; type[0] = "gives"; match[0] = "flower to Lady."; match[1] = "flower to Ann."; /* * This cathes 'name say: daisy' and binds it to * the function ''handle_say' in the current object. */ function[2] = "handle_say"; type[2] = "says:"; match[2] = "daisy"; dam = clone_object("/obj/monster"); dam -> set_name("mary"); dam -> set_alias("lady"); dam -> set_short("an old lady"); dam -> set_ac(0); dam -> set_level(5); dam -> set_al(200); dam -> set_hp(30); dam -> set_wc(7); dam -> set_aggressive(0); /* Load the catch arrays */ dam -> set_match(this_object(),functions,type,match); . . handle_give(str) { object giver; if(dam && living(dam)) { string who, rest; sscanf(str, "%s %s\n", who, rest); giver = present(lower_case(who),environment(this_player())); alig = giver -> query_alignment(); if(alig > 0 ) { say("Ann says: Oh thank you " + who + ".\n"); say("Ann says: You look like a fine young man.\n"); } else { say("Ann says: Oh thank you " + who + ".\n"); } } } handle_say(str) { if(dam && living(dam)) { string who, rest; sscanf(str, "%s %s\n", who, rest); say("Ann says: Sheeit " + who + ", ah' really likes daisys.\n"); } } ac. Armour class is set to ac. This are the optional functions. set_ep(ep) int ep. Sets ep to ep. set_al(al) int al. Sets the alignment to al, negativ is evil, pos good. set_alias(n) string n. Adds and alternate name for the monster. set_alt_name(n) string n. Adds another alternate name for the monster. set_race(r) string r. Adds an alternate generic name for the monster. set_short(sh) string sh. Sort description is set to sh. Long to capitalize(sdoc/build/door010066400000240000044000000073450475505114100132620ustar00mudmud00000420000006There is a generic door available. To set up do: #include "../../obj/door.h" object obj_1, obj_2; MAKE_DOORS( loc_1, dir_1, loc_2, dir_2, lock_type, lock_code, door_long, is_closed, is_locked, can_lock) The arguments expected are: string loc_1, loc_2: Locations for the two sides of the door. string dir_1, dir_2: The directions in the room where the door is e.g "west". string lock_type: The type the lock is made of e.g "metal" string lock_code: The key type which will lock/unlock the door. string door_long: Message printed when looking at any side of the door int is_closed: 0 if door opened, int is_locked: 0 if door unlocked. int can_lock: 0 if door can't be locked. The call to MAKE_DOORS has to be on ONE line, due to the C-interpreter. The door consists of two objects (obj_1, obj_2). These objects are placed in their rooms when the call to MAKE_DOORS is done. Be sure to make the call to MAKE_DOORS in the room where it should be encountered first. Otherwise there will not be a door when the player arrives. For customization the following routines are available: set_door_long(desc) string desc. Sets the long description for the door to desc. Used for changing the description on one side of the door. If any of these routines are called at an object one must also call set_both_status() which will make the two doors have the same status: set_is_closed(value) int value. Variable is_closed is set to value. set_locked(value) int value. Variable is_locked is set to value. set_can_lock(value) int value. Variable can_lock is set to value. If you want the door to make any kind of noise, such as knocking etc, you should call one of these routines: door_sound(message) string message. This call causes the door to say "'message' is heard from the door.". The noise is only heard on the side of the door that is called with this function. both_door_sound(message) string message. This call causes the door to say "'message' is heard from the door.". The noise is heard on both sides of the door. Commands available to players defined by doors: + go [direction] door or direction if the door is opened the player is move to the other side of the door. + open/close [direction] door works if door is unlocked. + unlock/lock [direction] door with [type] key works if door is set up to have a working lock. If the door is set up to have a working lock i.e can_lock != 0, you should make keys matching the lock. This is how it's done: object key_obj; MAKE_KEY( key_obj, key_type, key_code) The arguments expected are: object key_obj: This will be the key. string key_type: Description of key e.g 'golden'. string key_code: The type of lock key should fit in. EXAMPLE: We make a door between two rooms called "players/hebol/door_factory", and "players/fatty/food_supply". The door is green and has a note on Fatty's side. It has a sophisticated lock. It is initially closed, and unlocked. Along with it we make a silver key that fits the lock. After that a sound will be heard in Hebols room. #include "../../obj/door.h" object obj_1, obj_2, key_obj; /* * Set up the door. */ MAKE_DOORS("players/hebol/door_factory", "north", "players/fatty/food_supply", "south", "sophisticated", "ymca", "This is a green door.\n", 1, 0, 1) call_other( obj_2, "set_door_long", "This is a green door.\n" + "It has a note saying: Here lives Hebol.\n"); /* * Set up the key. Put it in Hebols room. */ MAKE_KEY( key_obj, "silver", "ymca") move_object(key_obj, environment(obj_1)); /* * Now make some noise. */ call_other( obj_1, "both_door_sound", "A chewing sound"); doc/build/armour010066400012670000065000000027660553064440600155470ustar00ppannionstacken00000420000006To get an armour do: object aobj; aobj = clone_object("/obj/armour"); For customization the following routines are available : You must call these functions (use call_other()): set_name(n) string n. Sets the name and short description to n. Sets long description to short + ".\n" These are the optional functions: set_short(s) string s. Sets the short description to s and the long to capitalize(short) + ".\n" set_long(l) string l. Sets the long description to l. set_value(v) int v. Sets the selling value to v. set_weight(w) int w. Sets the weight to w. set_class(a) int a. Sets the armour class to a. A random value up to 'a'/3 is subtracted from the hit. Refer to armour.list to get the suggested value. set_alias(a) { alias = a; } string a. Sets an alias name if armour. set_type(t) { type = t }; string t. Sets the type of armour to t. Only one of every type can be worn. These are the types you can use: helmet, amulet, armour, shield, ring, glove, cloak and boot. You can set an arbitrary name but we strongly suggest that you only use these. Default is armour. The armour class of every worn armour is added together. set_arm_light(l) int l. Makes the armour shine like a lamp of strenght l. set_info(n) { info = n; } string n sets the info to n info is an extrastring that some guilds/objects uses to see special messages from the creator of the object. ie. good use for this in magic- or quest items. doc/build/weapon.list010066400000240000044000000176700555456324700146010ustar00mudmud00000420000006 W E A P O N S A list of classes, values and weights. +----------------------------------------------------------------------------+ | This file contains a summary of allowed classes, values and weights for | | weapons in NannyMUD. Any transgressions of those might draw the attention | | of the administration to your area, and can very well result in a total | | revision... | +----------------------------------------------------------------------------+ | Any weapon that do not conform to the rules below MUST be approved. This | | also applies to weapons with special hit_lines. The approval MUST be noted | | in your file under /permissions; it must contain: | | | | 1/ Who approved it. | | 2/ Date of approval. | | 3/ What was approved, i.e. the stats of the weapon, hit_function, | | spell effects, other effects, special commands etc. | | | | The 23++ can approve things; there is a list of who they are written to | | you when you log in. | | | | Weapons with class > 16 should be hard to get. This means, with the level | | of inflation in this MUD that there should be FEW such weapons in every | | wizards area. ANY monster can be killed very fast by a party of high-level | | players. | | | | NOTE: Use your fantasy when naming weapons; how many Stormbringer and | | Excalibur could be found in this MUD 940331 ? (Answer last in this file.) | | | +----------------------------------------------------------------------------+ | name The name of the weapon. This should be used as the basic name, | | i.e. 'A flamebladed dagger' has the generic name 'Curved knife'. | | class This is the maximum class (used in set_class()) for the weapon | | of this generic type. | | value Here is the MAXIMUM value of the weapon. It's a guideline for | | the minimum too; min value shall be no less than 80% of the | | max. | | weight This is the absolute minimum weight for a weapon with this class. | | Of course, you can make it heavier. | +----------------------------------------------------------------------------+ | Name class value weight comment | | knife 5 8 1 No approval needed. | | club & sticks 7 10 1 - " - | | dagger 7 15 1 - " - | | hand axe 9 25 2 - " - | | twohanded staff 14 400 3 - " - | | Ex: bo-staff, jo-staff ... | | | | shortsword 15 700 3 - " - | | metal clubs: 15 700 3 - " - | | Ex: morningstar, mace, warhammer ... | | | | huge clubs 16 800 4 - " - | | spear 16 800 3 - " - | | sword 18 1000 3 Must be scarse. | | Ex: longsword, broadsword, rapier, sabre, scimitar ... | | | | bastard sword 19 1000 4 Must be very scarse. | | twohanded weapon 20 2000 4 Wc 20 must be approved. | | Ex: TH axe, TH sword, halberd ... | | | | common item | | Ex: shovel, hatpin, chair ... | | Class: Max 7. | | Weight varies, as per item. | | Value varies, as per item. A jewelled hatpin might have a value of | | 100, but then you must also be able to wear it. | | | | Classes, prices and weights not mentioned above: | | class value weight | | 1 1 1 | | 2 2 1 | | 3 4 1 | | 4 6 1 | | 6 9 1 | | 8 20 1 | | 10 100 2 | | 11 175 2 | | 12 250 2 | | 13 325 2 | | 17 900 3 Must be scarse. | | | | (For more info see /doc/build/weapon). | | | +----------------------------------------------------------------------------+ | Special weapons | | It is possible to make special weapons with dramatic effects, heavy damage | | etc. Be sure to get approval before introducing them to the game. Every | | weapon with wc > 20 MUST have drawbacks! Here is a list of examples of | | such weapons: | | | | wc = 21 This sword has a weight of 7. | | wc = 23 Only players with alignment higher than 500 can use it. | | wc = 25 Constantly refuses to fight evil monsters. Talks alot. | | wc = 27 Selfdestruct after 5 minutes. | | wc = 29 High wc only in a certain wizards realm. Otherwise wc=15. | | | | For weapons like M16, M60 machineguns, shotguns etc. that do not fit the | | medieval atmosphere in NannyMUD ( :-) ), talk to your local friendly | | neighbourhood highwizard. The highwizard is your friend, and happiness is | | mandatory... | +----------------------------------------------------------------------------+ This file is the result of the cooperation of Brom, Slater and Mats. ============================================================================== Answer to Stormbringer/Excalibur question: 14/9 ...doc/build/QUESTS010066400005710000044000000215330553236435600136630ustar00henkemud00000420000006 QUESTS ------ Each wizard can build one or more quests. Quests are problems that the mortal players have to solve before they can become wizards. When a wizard has made a quest, he (or she, or it) must arrange for it to be test-played by at least one real, mortal player. The wizard should then write some documentation about the quest, and ask a highwizard or arch wizard to look at the quest, the final approval of the quest should be done by the quest coordinator (Currently Brom). When the quest is approved, the wizard should add code in his (her, its) castle to put a properly configured quest object ("/obj/quest_obj") in the quest room ("/room/quest_room") each time the game reboots. The high/arch wizard should add a few lines in the /permissions/XXX.per file. (XXX=The name of the wizard who wrote the quest.) Each quest must have a unique name - either the wizard's own name, or the wizard's own name plus something more, as in "padrone" and "padrones_chaosdemon". Each quest must also have a hint, which the players can look at in the Adventurers Guild. *** ATTENTION! WARNING! READ THIS: The quest name should always start with the wizard's name! Quest points ------------ In the original LPmud, you had to solve all the quests (or all except some number, like 2) to become a wizard. All quests were considered equal. On NannyMUD, each quest gives a certain number of points. Angmar's quest is used as the "prototypical quest", and gives 100 points. Easier quests give less points, harder quests give more. The default, i. e. what you get if you don't set the quest points in your quest, is 50. To be able to advance to wizard, a player must - except from one million normal experience points - have collected a certain percentage, currently 70%, of the maximum number of quest points. This percentage is defined by the constant QUEST_POINTS_PERCENT_TO_WIZ in "/room/tune.h". But wait, it's more complicated than that! Earlier, many high-level players (on level 19 or so), used to be upset when new quests were added, since they then suddenly had to solve even more quests than they had thought they would. Because of that, each player will "remember" what the max number of quest points was when that player was created. To advance to wiz, he needs to have 70% of THAT number of quest points, instead of of the current max number. This means that the players will be happy instead of angry when a wizard installs a new quest, since they don't have to do more quests, they'll just have more of them to choose from! But wait (again), it's actually even more complicated than that! Since the max number quest points could decrease, for example if a wizard removes a quest or lowers the points for it, the player actually needs 70% of the smallest number of "max number when he was created" and "current max number". For players who - for some reason - don't want to kill a megapoint of monsters, there is an alternative: if you solve ALL the quests you can become immortal even without the experience points. As a "sanity check", this only works if the total number of quest points is at least 1000. Deciding how many quest points to give for your quest ----------------------------------------------------- Each wizard must decide (in cooperation with the other wizards and the arch wizards) how many quest points a quest he has made should give. Angmar's quest is used as the "prototypical quest", and gives 100 points. *** ATTENTION! WARNING! READ THIS: Start with a very conservative estimate of the value of your quest, i. e. set the number of quest points very low! You can always raise it later. Players who have already solved it will get the extra points too, since a player's number of solved quest points is re-calculated every time it is needed. *** ATTENTION! WARNING! READ THIS: Before you install a quest, the number of quest points (and the quest itself!) must be approved (se above). Easier quests should give fewer points, harder quests give more. How difficult a quest is to solve is of course hard to judge, and it depends on many things, but here is a list with some suggestions on things to consider: + Trickyness ("yes, of course, if I give the bone to the dog it'll start eating and become my friend and I can pass it into the treasury...") + Fighting (how many monsters you have to kill, and how big they are) + Dispersal (how much you have to run around in different parts of the game) + Time (just how much time it takes - maybe this is a function of dispersal and fighting?) + Programmed variation -- that is, can you ask someone how to solve Korkbert's quest, and then write a macro "solve-korkberts-quest" in your client, or are labyrinths and spells different each time? ? Stupid difficulties ("sigh! - you have to write 'pull the big black longsword from stone' instead of 'get sword'") - but then again, maybe you shouldn't give points for things like that, just fix them? - Is it possible to cheat -- i. e. can you let someone else solve the quest, buy the magic sword from him for 100 kilogold, and then you just give it to the king and get the princess and half the kingdom? - Availability on other muds -- the orc_slayer quest, which is present on every LPmud in the world, and everyone can solve in his sleep, should maybe not give as many points as a quest that only exists on this one mud? + Special requirements on the player - ("to kill the demon you must use this magic sword, and then your alignment must be over 1000") ? Difficulties getting started (the hint in the guild?) Examples of points for some quests on NannyMUD: Orc slayer 10 Padrone's walking castle 30 Angmar's treasury 100 Padrone's chaosdemon 110 Kobayashi (by Chrisp) 200 Automatic quest feedback ------------------------ To encourage feedback, a letter, similar to this one, will be sent automatically to each player that has solved a quest: From: Angmar Subj: The quest 'angmar' Date: Jan 24 Hello, Padrone! You have just solved the quest "Break into Angmar's treasury (100 points, by Angmar)", and we are now very interested in your opinions: Did you like this quest, and why (or why not?) Did you find any bugs or other problems? Do you have any suggestions for improvement? Was the number of quest points adequate? Please tell us what you think! This message was sent to you auto-magically by a small demon somewhere deep inside the game, in the name of Angmar. If you reply to this message with the 'r' command, your reply will be sent directly to Angmar. So don't be alarmed if someones sends you a reply to a mail message you don't remember sending, but try to use the suggestions and comments - player feedback (and doing something about it!) is very important if you want to have a really good quest! Programming ----------- Functions in "/obj/player.c": "set_quest" and "query_quests" Functions in "/obj/quest_obj.c": "set_name", "set_hint", "set_short", "set_points", "query_points" Functions in "/obj/quest_mailer.c": "set_mailtext", "set_other_wiz" Mailtext is used if you want your own text to be send instead of the default one and other_wiz could be useful when a new wiz have taken over an old, inactive wiz's area. Clone the quest object, call the functions "set_name", "set_hint", "set_short" and "set_points" in it, and put it in the quest room. Example (from Padrone's "castle.c"): object qobj; qobj = clone_object("obj/quest_obj"); qobj->set_name("padrone"); qobj->set_hint("Padrone is sad. He built a beautiful walking castle,\n" + "but a gang of pirates stole it and now he cannot\n" + "find it any more. Help him to get it back!\n" + "You don't have to be big and dangerous to solve this quest,\n" + "but it's always a good idea to bring a weapon and some armour...\n"); qobj->set_short("Find Padrone's walking castle"); qobj->set_points(30); move_object(qobj, "room/quest_room"); To mark that a quest is solved, call the function "set_quest" in the player object. Example: if (this_player()->query_quests("padrone")) { write("Padrone says: What? Have you solved the quest again?\n"); write("Padrone says: But Ok, I won't be angry.\n"); } else { write("Padrone says: You found my castle! I am so happy!\n"); this_player()->set_quest("padrone"); } Puzzles ------- Puzzles are similar to quests, but you don't have to solve them to become wizard, and they don't have to be approved by an arch wizard. Just use the functions "set_puzzle" and "query_puzzles" in the player object. There are no quest points involved here, just give the players some experience points the first time they solve the puzzle. The intended use of this "puzzle" mechanism is to award experience for something only the first time each player does it. Padrone, Jan 24, 1992 Padrone, Sept 6, 1993 doc/build/quest_obj010066400000240000044000000014760513170227000143040ustar00mudmud00000420000006The file obj/quest_obj.c should be cloned when setting up a quest. Look in /doc/build/QUESTS for how to initilize it. Every wizard may set up one or more quests. All quests must be approved by an arch wizard. The quests are not supposed to be very dangerous, just some kind of puzzle to solve. Even very easy quests are good, especially for the beginners. The quest object should be moved into the room room/quest_room. Look in this room, and in /doc/build/QUESTS, for more documentation. The quest must be documented how to solve, and with the name of an archwizard that approved of it. This documentation should be moved to /players/quests/. 'quests' is not the name of a player, but this directory is use to make it impossible for normal players to read the docs. If you have documentation ready to move, ask an archwizard. doc/build/banish010066400000240000044000000004510475505115100135530ustar00mudmud00000420000006It is important that monsters are not created that have the same name as players. To avoid this, a directory /banish contains one file for every reserved monster name. To enter new names, go to adventurers guild, and do "banish name". If there already exists such a player, the command will fail. doc/build/prices010066400000240000044000000013350500570544700136010ustar00mudmud00000420000006This is a recommended list of range of prices. As is known, no items gives more than 1000 coins in any shop. Items should never be worth more than 5000. An item worth 5000 is an extremly good item. Only the best of all good items should be worth this much. If you have an item that you think should be worth more, than it is too good and should not exist in the game ! Don't make lots and lots of high-value items. Keep the values down to decrease the inflation in this game. High-value items should be hard to get and seen as a reward for solving problems or killing a powerful monster, not just lying around waiting for someone to pick it up. Look at weapon.list and armour.list for examples of values of weapons and armours. doc/build/termcap010066400000240000044000000030650534651235600137540ustar00mudmud00000420000006NAME termcap SYNOPSIS #include int tinit(); int tclear(); int tgoto(int x, int y); int tputs(string str); int tflush(); int tclreol(); int tioctl(int cmd, mixed val); DESCRIPTION The termcap library consists of a number of support functions to be used if there is a need for more direct screen control. Please note that many MUD clients strip away control characters which many render this utility rather useless... Any object wishing to use these functions must include the header file, and call "tinit()" (once, at reset time) to initialize the system. tclear() clears the screen tgoto() moves the cursor to the specified position. The upper left corner is (1,1). tputs() sends the string to the terminal directly, unless the F_BUFFERED flag has been set using the tioctl(T_SETFL) call. tflush() flushes any buffered writes. This can be used to make sure that a series of writes (via tputs()) will get output in one chunk. tclreol() erases to the end of the current line. tioctl() is uses to set/unset flags that control the behaviour of the termcap library. Use "T_SETFL" to set the flags (arg is an "int") and "T_GETFL" to read the current flag setting. Currently only one flags is specified, "F_BUFFERED", which is used to control the behaviour of "tputs()". AUTHOR Peter Eriksson , Lpd@NannyMUD FILES /include/termcap.c - Header file for objects to include. /obj/termcap.c - Controlling object for the drivers. /obj/termlib/*.c - Terminal drivers. BUGS I'm sure there are many. doc/build/CLUBS010064400005540000036000000020330554633063000144140ustar00karinlysator00000420000006Feelings: ========= All clubs that uses feelings have to use them in combination with the soul. Clubline: ========= All clubs may have a chatline, however there is a minimum cost of 15 sp/chat. The following 4 files in the /open/line library should be used when making a line: 1. /open/line/line.c All functions needed for handling the line. 2. /open/line/send_player.c A statue of the player that automatically will be placed in the send_room. 3. send_room.c The room for keeping statues for the line. (Just make a copy of /open/line/send_room.c) 4. send.h All constants needed for specifying your own line. (Make a copy of /open/line/send.h and make your own adjustments) Here is an example of how to write in your guild-object: (OBS Do NOT change the order of these includefiles.) #include "/players/your-name/send.h" #include "/open/line/line.c" init(arg) { init_line(); } doc/build/food010066400000240000044000000016570526114146400132470ustar00mudmud00000420000006These are the rules concerning food: The total amount of sold healing per reset must not exceed 3000 hp. A maximum of 200 hp may be sold to one customer per reset. The cost of such healing is calculated using this formula: x = The amount of healing sold. Cost = 4*x + x^2/10 This means that the more healing an item contains, the more expensive it gets. These items must have a weight of at least 1. The "strength" of the food is equal to the amount of healing it makes to the player when he eats it. Typically this strength should not exceed 50. Use the file "obj/food" for cloning and inherting purposes. Please read the file find out which functions to call. Example of food can be found in /doc/examples/apple_pie.c Food that heals, should also stuff the person. Use "obj/food" or "eat_food(strength)" (lfun in player.c). Portable healing food is very very restricted and should have permission from the god or archwizards. doc/build/drinks010066400000240000044000000023740526114002600136000ustar00mudmud00000420000006These are the rules concerning alcoholic and non-alcoholic drinks: The total amount of sold healing per reset must not exceed 3000 hp. A maximum of 200 hp may be sold to one customer per reset. The cost of such healing is calculated using this formula: x = The amount of healing sold. Cost = 4*x + x^2/10 This means that the more healing an item contains, the more expensive it gets. These items must have a weight of at least 1. The "strength" of the drink is equal to the amount of healing it makes to the player when he eats it. Typically this strength should not exceed 50. Use the file "obj/alco_drink" and "obj/soft_drink" for cloning and inherting purposes. Please read the file find out which functions to call. NB! "obj/alco_drink" should now be used instead of "obj/drink" for alcoholic beverages. The older file remains only for backward-compatibility purposes but it will be removed within a near future together with the connected call "drink_alcohol()". Examples of drinks can be found in /doc/examples/apple_juice.c and /doc/examples/apple_cider.c All nonalcoholic drinks that are being sold, should use "obj/soft_drink" or "drink_soft(strength)". Portable healing drinks is very restricted and should have permission from the god or archwizards. doc/build/healing010066400000240000044000000003740506734152500137260ustar00mudmud00000420000006 Healing in any form should be limited and cost a lot. The current guideline is 4gc/hp. Portable healings should have permission from the god or archwizards. This means that you must not be able to take food and drinks out of a pub or a restaurant. doc/build/shops010066400000240000044000000001520506734150500134430ustar00mudmud00000420000006 Shops that sell or buy anything in unlimited amounts must have permission from archwizard or the god. doc/build/quest_rewards010066400000240000044000000034100513170260100151650ustar00mudmud00000420000006Note: This file is somewhat obsolete. You should read the file /doc/build/QUESTS about quests, quest points and puzzles, but the guidelines for gold and experience in this file can still be useful! /Padrone, Jan 5, 1992 --------------------------------------------- This is guidelines and recommendations for how to award players when you make quests or smaller scenarios. The award should naturally be dependant on the difficulty of the quest, and this might be very hard to judge objectivly. To faciliate this you can compare your quest with the examples given here. The suggested award is given as a pair of numbers. The numbers are Value of gold, equipment / Total ep given. This award should be given at two times. First while solving the quest. The second time is when the quest is completed. The gold should be given not just as coins, but also as equipment of different kinds. Major quest: 20000/30000 Hard to solve, takes about 3-5 hours to finish and requires the player to visit about 50-80 rooms. Max alignment adjustment: +/- 200 Medium quest: 10000/15000 Still not easy. Takes about 1-3 hours to finish and requires the player to visit about 30-60 rooms. Max alignment adjustment: +/- 100 Easy quest: 3000/5000 Quite easy. Takes about an hour to finish and requires the player to visit 10-20 rooms. Max alignment adjustment: +/- 50 scenario: 0-5000/0-5000 Very much like quests, but not registered as such. Because of this they don't have to be very hard or require him to visit a certain number of rooms. Intended to enhance the game and make it more interesting. Players should only be able to receive rewards once. Use the bit-functions to make sure of this. If he tries to solve it again, it should either be impossible or not yield any rewards. doc/build/smartmonster010066400000240000044000000375500523716716600150710ustar00mudmud00000420000006About the smartmonster - for version 0.4 (August 3, 1992) ------------------------------------------------------- Written by Padrone, latest change of this file August 3, 1992. This is a description of a monster object, "obj/smartmonster". This smartmonster is (almost) backwards compatible with the old /obj/monster, so you can replace most usages of /obj/monster with /obj/smartmonster. These functions, that were used to configure the old "obj/monster" object, have been replaced, but can still be used in the compatible version of the smartmonster: set_chance(int c) set_spell_mess1(string m) set_spell_mess2(string m) set_spell_dam(in d) load_chat(int chance, string *strs) load_a_chat(int chance, string *strs) set_match(object ob, mixed *func, mixed *type, mixed *match) set_aggressive(status a) set_alias(string a) set_alt_name(string a) set_whimpy() (Later we might do something about move_at_reset, set_dead_ob, and set_random_pick.) This file contains a description on how to do corresponding things, and more, in "obj/smartmonster". Contents of this file --------------------- 1. Some small changes 2. A kinder, gentler aggressivity 3. A more advanced (and correctly spelled) wimpy mode 4. Simple chats, similar to "load_chat" in the old "/obj/monster" 5. Responses to actions from players and monsters 7. Special attacks and other things to do in a fight 8. A function to call in each heart-beat 9. The smartmonsters can be friends! 10. Aliases 11. The functions to call to configure the object 12. Expanded stat format 13. An example: Harry 14. Incompatibilities with the old /obj/monster 1. Some small changes --------------------- There are more (and better used) possible directions in the random move, which is used both if the monster is trying to run away and if "move_at_reset" has ben set. To give the monster a soul, just call the function "set_soul". 2. A kinder, gentler aggressivity --------------------------------- "set_aggressive" has ben replaced by "set_aggressivity", which takes an argument between 0 (never attacks anything - corresponds to the old set_aggressive(0)) and 100 (attacks everything it sees - corresponds to the old set_aggressive(1)). The attack decision is now dependent of the alignments and levels of both the monster and the intended victim, and has an element of randomness. By default monsters are totally peaceful. 3. A more advanced (and correctly spelled) wimpy mode ----------------------------------------------------- The old "set_whimpy", which made the monster run away when its hitpoints became low, has been replaced by "set_wimpyness", which takes an argument between 0 (never run away) and 100 (run as soon as you are hurt). The monster will run when it has less per cent hitpoints left then the given argument. To get the same effect as the old "set_whimpy()", use "set_wimpyness(20)". By default monsters are totally un-wimpy, and will never run away. 4. Simple chats, similar to "load_chat" in the old "/obj/monster" ----------------------------------------------------------------- Usage: set_chat_chance CHAT-CHANCE set_chat_in_fight FLAG add_chat CHAT-MESSAGE set_chats CHAT-MESSAGES-ARRAY Examples: harry->set_chat_chance(2); harry->set_chat_in_fight(1); harry->add_chat("Harry says: What are you waiting for?\n"); harry->add_chat("Harry says: Nice weather, isn't it?\n"); smurf->set_chats(({ "The smurf smurfs.\n", "The smurf smurfs a smurf.\n" })); After the above calls to harry, there is now a 2 percent chance at each heartbeat (every two or three seconds), that one of the add_chat'ed strings will be printed by Harry. The reason for not having individual percentages for every string, i. e. with the usage add_chat CHAT-MESSAGE [ CHANCE ] is just because of efficiency. Maybe it can be changed later. 5. Responses to actions from players and monsters ------------------------------------------------- Usage: add_response ACTION RESPONSE [ PERSONAL-REPLY-MESSAGE ] [ CHANCE ] set_responses RESPONSE-ARRAY set_response_object OBJECT Or, in another way of putting it: add_response ACTION "REPLY-MESSAGE" [ "PERSONAL-REPLY-MESSAGE" ] [ CHANCE ] add_response ACTION "*FUNCTION-NAME" [ CHANCE ] add_response ACTION "!COMMAND" [ CHANCE ] add_response ACTION ARRAY-OF-RESPONSES [ CHANCE ] Examples of simple responses: harry->add_response("smiles happily", "Harry smiles happily.\n"); harry->add_response("smiles happily", "Harry smiles happily.\n", 100); harry->add_response("smiles happily", "Harry smiles happily.\n", 0, 100); harry->add_response("smiles happily", "Harry smiles happily.\n", "Harry smiles at you.\n", 100); harry->add_response("says:", "Harry looks at the one who was talking.\n", "Harry looks at you.\n"); harry->add_response("drops", "Harry says: Why did you drop that?\n"); harry->add_response("drops", "Harry says: Why did you drop that?\n", 75); If there is a second string, it is sent to the "opponent" instead of the first message. If no CHANCE is given, or if it is 0, it will be set to 100. Warning! Each matching response is tested against its chance in the order it was add_response'd, so if you set three responses, all with 50% chance, their probabilities, if they match a certain action, will be 50%, 25% and 12.5%! This also applies to responses and attacks. If the REPLY-MESSAGE starts with one of the characters '*' or a '!', it is used as a function to call, or a command for the monster to execute. Examples of advanced responses (function calls and commands): harry->set_response_object(this_object()); harry->add_response("sings", "*handle_sing") harry->add_response("pukes", "*handle_puke", 0) harry->add_response("smiles happily", "*handle_happy_smile", 35) harry->add_response("smiles", "*handle_smile", 100) harry->add_response("kicks you", "!scream") The function FUNCTION-NAME in the object OBJECT will be called with three arguments: who, what and how. If Harry now gets the message "Padrone smiles like a surgeon.\n", the call will be: handle_smile("Padrone", "smiles", "like a surgeon.") The RESPONSE can also be an array of responses: harry->add_response("bounce", ({ "!flip", "!smile", "!grin" }), 100); The response is performed in the next heart beat (1-2 seconds later). The value of this_player() will be the monster, so if you call a function (with the "*FUNCTION-NAME" syntax), messages from say() will go to everyone in the room except the monster, and write() will go to the monster itself. Warning! Messages printed by write() in a response function or a command will be seen by the monster (in the next heartbeat), and if they are matched by a response there might be an infinite loop. Often you want to use the name of the monster or player whose action we are responding to. You can use the string "$OTHER", which will be substituted with the other monster's or player's name. Example: harry->add_response("kicks you", "Harry glares at $OTHER.\n", "Harry glares at you.\n"); The string "$LOWOTHER" will be substituted with the lower-case form of the name. "$OTHER" and "$LOWOTHER" also works in commands and function calls: harry->add_response("kicks you", "!kick $LOWOTHER"); harry->add_response("kicks you", "*handle_kick_by_$LOWOTHER"); 6. Responses to certain frequently used actions ----------------------------------------------- Usage: set_say_handler [ OBJECT [ FUNCTION-NAME ] ] set_tell_handler [ OBJECT [ FUNCTION-NAME ] ] set_give_handler [ OBJECT [ FUNCTION-NAME ] ] set_give_money_handler [ OBJECT [ FUNCTION-NAME ] ] set_arrive_handler [ OBJECT [ FUNCTION-NAME ] ] set_leave_handler [ OBJECT [ FUNCTION-NAME ] ] Examples: harry->set_say_handler(); harry->set_tell_handler(this_object(), "handle_say_and_tell"); harry->set_give_handler("players/ugh/centcomp", "got_something"); Whenever one of the actions happen (someone saying something, etc.), the function FUNCTION-NAME in the object OBJECT will be called with some useful arguments. Default function names: "handle_say", "handle_tell", "handle_give", "handle_give_money", "handle_arrive", "handle_leave". The arguments that are sent are: 1. the object that did something (if it wasn't possible to find this object, the function is not called - except in the case of leaving), 2. the name of the player or monster that did it, and finally 3a. the phrase that was said, or 3b. the object (and it's name) that was given, or 3c. the way someone arrived or left. If we assume that the default function names are used, this might give an idea of how the calls are made: handle_say(who_obj, who_string, phrase_string); handler_tell(who_obj, who_string, phrase_string); handle_give(who_obj, who_string, what_obj, what_string); handle_give_money(who_obj, who_string, number_of_coins); handle_arrive(who_obj, who_string, how_string); handle_leave(who_obj, who_string, how_string); Don't forget that "handle_give" takes four arguments, that the third argument to handle_give_money is an integer, and that the first argument to handle_leave will be 0. Also remember the difference from response functions (see above), which are called with three strings as arguments: who, what and how. 7. Special attacks and other things to do in a fight ---------------------------------------------------- This is a replacement for both "load_a_chat" (attack chats) and the "set_spell_mess1" functions: Usage: add_attack ATTACK-MESSAGE [ PERSONAL-ATTACK-MESSAGE ] MAX-DAMAGE [ CHANCE ] Examples: harry->add_attack("Harry says: Help, someone!\n", 0, 0, 10); harry->add_attack("Harry punched his opponents nose.\n", "Harry punched your nose.\n", 2, 50); glumglot->add_attack("Glumglot casts a fireball.\n", "You are hit by a fireball.\n", 50, 10); glumglot->add_attack("Glumglot casts a fireball.\n", 50, 10); "$OTHER" can be used in the attack messages: harry->add_attack("Harry punched $OTHER's nose.\n", "Harry punched your nose.\n", 2, 50); 8. A function to call in each heart-beat ---------------------------------------- The smartmonster can be set up to call a function at every heartbeat while it's in a fight, and another function at every heartbeat while it's not in a fight. Usage: set_fight_beat [ OBJECT [ FUNCTION-NAME ] ] set_peace_beat [ OBJECT [ FUNCTION-NAME ] ] Examples: wizard->set_fight_beat(this_object(), "teleport_away"); cow->set_peace_beat("players/grendel/room/meadow", "munch_some_hay"); orc->set_fight_beat(); The function FUNCTION-NAME in the object OBJECT will be called each heart-beat, in the case of fight_beat with the current enemy as argument. Default function names: "fight_beat" and "peace_beat". 9. The smartmonsters can be friends! ------------------------------------ Usage: add_friend OBJECT-OR-NAME set_friends ARRAY-OF-OBJECTS-OR-NAMES Examples: wizard->add_friend("sheriff"); orc1->add_friend(orc2); orc1->set_friends( ({ orc2, orc3, orc4 }) ); Friends will help each other in a fight, i. e. they will attack the monster or player that their friends are fighting. 10. Aliases ----------- A smartmonster can have any number of aliases. Usage: add_alias STRING set_friends ARRAY-OF-STRINGS Examples: arnold->set_aliases( ({ "hero", "big-guy", "muscle" }) ); arnold->add_alias("terminator"); 11. The functions to call to configure the object ------------------------------------------------- These are the functions you should call to configure the monster. First, call these three functions: set_name(string n) set_short(string sh) set_level(int l) IT IS IMPORTANT that you call these functions FIRST, and that you call set_name BEFORE you call set_short, since they will set default values for some values. Then, call any of these functions that you want. It is strongly suggested that you always use at least set_long, set_al and the gender functions (one of set_male, set_female and set_neuter)! set_aliases(string *all_aliases) add_alias(string str) set_race(string r) set_long(string lo) set_wc(int wc) set_ac(int ac) set_hp(int hp) set_ep(int ep) set_str(int i) set_int(int i) set_con(int i) set_dex(int i) set_al(int al) set_aggressivity(int a) set_wimpyness(int w) set_male() set_female() set_neuter() set_attacks(mixed *all_attacks) add_attack(string msg, mixed arg2, mixed arg3, mixed arg4) set_chats(string *all_chats) add_chat(string the_chat) set_chat_chance(int percentage) set_chat_in_fight(status f) set_responses(mixed *all_responses) add_response(string act, mixed response, mixed arg3, mixed arg4) set_response_object(mixed obj) set_say_handler(mixed obj, string fun) set_tell_handler(mixed obj, string fun) set_give_handler(mixed obj, string fun) set_give_money_handler(mixed obj, string fun) set_arrive_handler(mixed obj, string fun) set_leave_handler(mixed obj, string fun) set_fight_beat(object obj, string fun) set_peace_beat(object obj, string fun) set_friends(mixed *all_friends) add_friend(mixed the_name) set_soul() set_move_at_reset() set_random_pick(status r) set_init_ob(mixed ob) 12. Expanded stat format ------------------------ If you call show_stats() in a smartmonster, for example with the wizard command "stat", you will see some additional smartmonster-specific data, for example as in this output from "stat harry": Harry the affectionate level: 3 coins: 0 hp: 66 (max: 66) spell 66 (max: 0) ep: 1522 ac: 0 wc: 5 carry: 0 align: 50 gender: male str: 3, int: 3, con: 3, dex: 3 age: 2 seconds. Additional smartmonster data: chat_data: 10 chats, chat_chance: 2, chat_in_fight: 0 say_handler: 'answer_say' in OBJ(room/vill_road2) tell_handler: 'answer_say' in OBJ(room/vill_road2) give_handler: 'handle_give' in OBJ(room/vill_road2) give_money_handler: 'handle_give_money' in OBJ(room/vill_road2) arrive_handler: 'say_hello' in OBJ(room/vill_road2) leave_handler: 'follow' in OBJ(room/vill_road2) handle_caught_texts = 1 Waiting texts from catch_tell(): 0 aggressivity: 0 attack_data: 9 attacks friends: 0 response_data: 12 responses, response_object = OBJ(room/vill_road2) Smartmonster responses: 'sells': '*why_did' - 100% 'attacks': '*why_did' - 100% 'left the game': '*why_did' - 100% 'takes': '*why_did' - 100% 'drops': '*why_did' - 100% 'is now level': '*how_does_it_feel' - 100% 'falls down laughing': 'Harry looks at the one who laughed.\n' ('Harry looks at you.\n') - 100% 'bounces': ['!flip', '!smile'] - 100% 'sings': 'Harry says: You really have a nice voice!\n' - 50% 'sings': 'Harry tries to sing too.\n' - 50% 'sings': '!applaud' - 50% 'smiles happily': 'Harry smiles happily.\n' - 100% 13. An example: Harry --------------------- I have re-written /room/vill_road2.c (the room which defines Harry) to use the smartmonster. 14. Incompatibilities with the old /obj/monster ----------------------------------------------- In the old monster, when it called a function set up by "set_match", the value of this_player() usually was the monster object, but sometimes (rather randomly) it could be the object that sent the string the monster reacted to. In the smartmonster, the value of this_player() will always be the monster object. If you have a randomly moving monster (move_at_reset or wimpy), and rely on it going only in some directions, your code could fail. The percentages for attack-chats will not be quite right. If the monster object is inherited, and the functions in it are called in non-standard ways, I don't know what will happen. doc/build/water_room010066400000240000044000000016230513416357200144720ustar00mudmud00000420000006/room/water_room may be used to simulate a room that is a water surface or under water. It is inherited froom /room/room, and you have too understand how that works in order to understand the rest of this file. A room inherited from /room/water_room may also be used as a normal room. Whether it is waterfilled or not is controlled by using properties: If the property "waterfilled" is set, the room's special behaviour will be activated. This makes it possible to simulate tides, airlocks, etc.. The things that are different when the room is waterfilled are: * Objects dropped will sink if there is a room defined for them to sink to. * A room may be defined as being underwater and having another room as its surface. Players without an air supply will be forced to that surface after a set time. Look at the file itself for more exact explanations on what functions are available and how they work.special behaviour will be activated. This makes it possible to simulate tides, airlocks, etc.. The things thdoc/build/COPYRIGHT010066400002410000044000000014400555501460700142040ustar00matpemud00000420000006A wizards files in NannyMUD is protected by the normal Real Life (Swedish) copyrights. When the wizard transfer files to NannyMUD, or creates files on NannyMUD, and store them on Lysators discs, the copyright gets the following modifications: The administrators on NannyMUD may not distribute, sell or make any monetary gain on the wizards files. The administrators may backup, modify or delete the wizards files. The wizard may not revert modified or deleted files before consulting the administrators. The wizard can force the deletion of the files, or get them back if they are closed or on backup tapes. All texts generated on NannyMUD are copyrighted, and may not be sold or distributed without permission from all participants in the generated texts, or the administrators of NannyMUD. doc/build/spells010066400005710000044000000012770553236124000141310ustar00henkemud00000420000006 Spells must be approved by an highwizard, archwizard or god. If you don't want magic to work in your room: realm() { return "no_magic"; } or property = "no_magic"; in function reset() in a room inheriting room/room. Spells must of course check realm() and query_property("no_magic"). Only one spell per heart beat. That means you always have to call check_busy() in the player. check_busy() works like this: Just call check_busy() every time you want to cast a spell, it returns 1 if you are busy and 0 otherwise. It will also make you busy one heartbeat. To make youreself busy longer just give the number of heartbeats you like to be busy as argument to check_busy(). doc/build/tourist_info010066400010330000036000000023640555451676300166660ustar00neotronlysator00000420000006-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- You want people to come to your area? You always get question from people asking you where your area is located? Then you should consider writing about it in the tourist office and this is the text telling you how. First of all you should make the directory '/open/info/' where all/the file(s) should be located. is ofcourse your name and it should be lowercase. When this is done, you just have to write the information file(s) and put them in that directory. The filename of the file is the name that get listed in the index of the booklet and those should also be lowercas, or it won't work. If you want space in the name, save as 'my_area' for example. In here you can write everything you think that players want to know. Ofcourse it should have something to do with the mud. A little hint is to not write exact directions as "To reach my area go w, s, w ...". Try do use nice descriptions as "Go to the humpbacked bridge and etc". This is mainly to make people explore and not just follow scripts. Have fun! If there is anything you want me to add, just notify me. /Slater 940418 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- doc/lfun/004077500000240000044000000000000556521002300122275ustar00mudmud00000420000006doc/lfun/exit010066400000240000044000000012170503244637000131260ustar00mudmud00000420000006void exit(ob) object ob; This function is called in rooms everytime a living object 'ob' leaves. The function this_player() will return a random value, don't use it at this point. WARNING: Using this function is EXTREMELY dangerous. A single bug, and you are forever (i.e. until the next reboot occurs) caught in the room. If you still insist upon using it, do the following in the reset function of the room: if (catch (exit ())) destruct(this_object()); It will check for problems in the exit() function and destruct the room should there be any. Note that this is not a complete check. This only checks for exit(0) to work. See also: lfun/init doc/lfun/query_value010066400000240000044000000003100475505116400145130ustar00mudmud00000420000006int query_value() Return the value of this object. If it is not possible to sell this object, then the value 0 should be returned. One gold coin corresponds to one experience point, as a reference. doc/lfun/catch_tell010066400000240000044000000005240475505116500142640ustar00mudmud00000420000006When tell_object() sends a message to a noninteractive player, it will get to the function catch_tell(string). This will enable communications between NPC's and from a player to an NPC. The only exception is shout, which the monster won't hear. The monster must be living, that is, call enable_commands(). See also efun/enable_commands() doc/lfun/README010066400000240000044000000003330475505116600131160ustar00mudmud00000420000006This directory describes functions that may or may not be declared in an object. If they are declared, they will be called when apropriate. It might be important to declare some functions, so always check all of them. doc/lfun/show_stats010066400000240000044000000001650475505116600143620ustar00mudmud00000420000006void show_stats() Living objects should define this function. It should print all important stats about the object. doc/lfun/reset010066400000240000044000000007070475505117000133030ustar00mudmud00000420000006void reset(flag) Reset is called everytime the object is resetted. The first time is when the object is loaded. If a room creates things when reset(), it should check that these objects has moved out before creating new. When reset is called for the first time, a null argument is passed. The second time reset is called, flag will have vaule 1. Every object will repetedly get resetted by a daemon. The game wouldn't be fun if no challenges remained. doc/lfun/hit_player010066400000240000044000000006210475505117100143150ustar00mudmud00000420000006int hit_player(dam) int dam; If the object can fight and get hit by other objects, it must have a hit_player function. The "dam" is the maximum damage the other object wants to give. Return the actual damage. This function should also tell other players in the current room that someone got hit (using say()). See example in player.c. See also efun/enable_commands, efun/living, lfun/attacked_by. doc/lfun/short010066400000240000044000000003550524431154700133200ustar00mudmud00000420000006string short() All objects must have a short() function. This function returns a short message describing what it is. Invisible object will return the value 0. The message should begin with a ***small-caps*** letter! See also: long(). doc/lfun/id010066400000240000044000000002640475505117200125550ustar00mudmud00000420000006int id(str) string str; This function is used to identify an object. If it identifies with the string "str", then return 1, else 0. See also lfun/long(), lfun/can_put_and_get(). doc/lfun/long010066400000240000044000000011450475505117400131210ustar00mudmud00000420000006void long(str) string str; This function prints out a elaborate description of it self. Minimum requirement is to print the value of short(). If there is an argument, then print description of that argument. An argument can only be passed to long() if id() has agreed. For example, a room with a door can allow id("door") to be true. Then it is possible to do "look at door". The long command will then have to print info about the door. To prevent the listing of all things in this room when "look at door", let can_put_and_get("door") return false. See also lfun/short(), lfun/can_put_and_get(), lfun/id(). doc/lfun/stop_wielding010066400000240000044000000003360475505117400150320ustar00mudmud00000420000006void stop_wielding() Objects able to wield weapons, should have this function. It is called by the weapon when it is not possible to continue wielding the weapon. It should adjust the weapon class of the current object. doc/lfun/query_money010066400000240000044000000001610475505117600145350ustar00mudmud00000420000006int query_money() Objects that can carry money, should define this function to return the amount of gold coins. doc/lfun/add_money010066400000240000044000000002330475505117700141210ustar00mudmud00000420000006void add_money(m) int m; Objects that can pick up the special "money" object, should have this function. It will be called with the amount of gold coins. doc/lfun/query_level010066400000240000044000000002530475505120000145030ustar00mudmud00000420000006int query_level() All mobile (living) objects must define this. The lowest level is 1. An apprentice wizard have level 20, and a full wizard with a castle have level 21. doc/lfun/heart_beat010066400000240000044000000011230475505120100142430ustar00mudmud00000420000006void heart_beat() This function will be called automatically every 2 seconds. The start and stop of heart beat is controlled by set_heart_beat(). Be careful not to have objects with heart beat running all the time, is it uses a lot of resources. If there is an error in the heart beat routine, the heart beat will be turned off until this object is recompiled, and can not be restarted with set_heart_beat. The function this_player() will return this object, but only if it is living. Otherwise, this_player() will return 0. See also: efun/set_heart_beat efun/call_out efun/enable_commands doc/lfun/get010066400000240000044000000004150475505120100127270ustar00mudmud00000420000006int get(str) string str; If an object wants control over when it is possible to pick it up, then it must define get(), and return 1 if ok to pick up. The "str" is comes from "get str" from the player command. id() has been called before this to identify the object. doc/lfun/query_attack010066400000240000044000000002060475505120300146440ustar00mudmud00000420000006object query_attack() All objects that can come under attack should define this function. It shall return the attacking object or 0. doc/lfun/query_weight010066400000240000044000000005110475505120400146640ustar00mudmud00000420000006int query_weight() This function is called to query the weight of this object. A design choise TAKEN, is that objects inside another objects, does not change the weight of that object. This makes it possible for a player to carry more if he puts it into a bag or something. Note that objects doesn't have a size, only weight. doc/lfun/drop010066400000240000044000000011470475505120500131230ustar00mudmud00000420000006int drop(silently) int silently; This function must be defined by all objects that want to control when they can be dropped. if 'silently' is true, then don't write any messages. drop() should return 1 to prevent dropping. This is the opposit of the get() function. That is because if drop() is not defined, it will always be possible to drop an object. If the object self-destructs when drop() is called, be sure to return 1, as the destructed item surely not can be dropped. Similarly, if drop() is called in another object, always test if the object did self-destruct, as the object variable will turn to 0. doc/lfun/can_put_and_ge010066400000240000044000000012660475505120600151100ustar00mudmud00000420000006int can_put_and_get(str) string str; Define this function if you want to make it possible to put something into current object. Return true if ok, otherwise 0. That means that default is that it is not possible to put something into an object. When a player does "look at xxx", then "xxx" will be sent to can_put_and_get(), to test if the player can look at the inventory. Otherwise, 'str' will be 0. This is trivial for containers. If the are open, they return 1. If id() accepts other things, like "lock" (in a chest for example). Then "lock" will be sent to can_put_and_get(), which should return false, because the lock has no inventory (of course). See also lfun/id(), lfun/long(). doc/lfun/add_weight010066400000240000044000000004660475505121400142610ustar00mudmud00000420000006int add_weight(w) int w; An object that can contain other objects must define this function. It is called with the extra weight of the new object. If this is ok, then it has to increment the local weight count, and return true. Otherwise, return false, and the new object can not be entered into this object. doc/lfun/init010066400000240000044000000002710475505121500131200ustar00mudmud00000420000006void init() This function is called everytime a living objects can "see" the object. It is good to the set up of add_action() and add_verb() in the init() routine. See also lfun/exit doc/lfun/attacked_by010066400000240000044000000002310475505121700144250ustar00mudmud00000420000006void attacked_by(ob) object ob; This routine is called by the object attacking this object. Define it if this object wants to know who the attacker is. doc/lfun/heal_self010066400000240000044000000002330475505122100140720ustar00mudmud00000420000006void heal_self(h) int h; This routine is called when the object is allowed to heal by 'h' points. Of course, this is only interesting for living objects. doc/lfun/query_name010066400000240000044000000001640475505122200143210ustar00mudmud00000420000006string query_name() All living objects, weapons and armour must return the name of itself. See also lfun/short(). doc/lfun/query_auto_load010066400000240000044000000015330525145030700153500ustar00mudmud00000420000006string query_auto_load() An object that wants to be loaded automatically when the player logs in, should define this function. There are some important rules about how to use it: 1. It must not have any weight. 2. It must prevent the player from dropping it. 3. query_auto_load() must return a string that is: file:arg The 'file' is the definition that will be cloned. The 'arg' is a string that will be sent as argument to the function 'init_arg()'. The 'arg' can be an empty string. 4. It must not be an actively usable item, like weapon or armour. 5. It must not help the player in combats. The idea with this feature is that a player can get a curse or membership, that will stick with him, even if he quits. The idea is not that the player will save his weapons etc. Look at /obj/shout_curse.c for an example. See also lfun/init_arg doc/lfun/extra_look010066400000240000044000000005540475505122400143300ustar00mudmud00000420000006string extra_look() If this function returns a string, and the object is carried by a player, then the string returned by this function will be printed after the character data, but before the list of what the character is carrying. This can be used to introduce curses for players, that gives some visual result. See also lfun/short(), lfun/query_auto_load(). doc/lfun/query_info010066400000240000044000000004300475505122400143320ustar00mudmud00000420000006string query_inf() Declare this function if the object has some information that is hidden. A scroll of identify would call query_info() to find out. The standard objects weapon.c, armour.c and treasure.c all have a function set_info(), to enable setting an information string. doc/lfun/query_gender_string010066400000240000044000000012700522602430400162250ustar00mudmud00000420000006string query_gender_string() This function is defined by living monsters and players. It will return either "neuter", "male" or "female". There are several functions to set and query about gender: set_neuter() set_male() set_female() query_neuter() query_male() query_female() query_gender_string() -- returns "neuter", "male" or "female" query_pronoun() -- returns "it", "he" or "she" query_possessive() -- returns "its", "his" or "her" query_objective() -- returns "it", "him" or "her" These two are "low-level" gender funs and should not be used except when they are needed, i. e. for things like monster2->set_gender(monster1->query_gender()): set_gender(g) query_gender() doc/lfun/query_npc010066400000240000044000000003000475505122600141550ustar00mudmud00000420000006int query_npc() This function is defined by all living objects and monsters. It will return 1 for monsters, and 0 for players. NPC = Non Player Character. See also: lfun/query_gender_string doc/lfun/stop_fight010066400000240000044000000003150475505122700143250ustar00mudmud00000420000006stop_fight() Defined by all monster and player objects. If you call this function, that player or monster will stop fighting. If you want to stop a fight, you have to call stop_fight() in both opponents. doc/lfun/exit.orig010066400000240000044000000001450475505122700140700ustar00mudmud00000420000006void exit() This function is called in rooms everytime a living object leaves. See also: lfun/init doc/lfun/init_arg010066400000240000044000000000260525145034700137500ustar00mudmud00000420000006See query_auto_load() doc/lfun/set_X_mult010066600006140000036000000041740542404424300160300ustar00cardecilysator00000420000006As you might have noticed, there are some new functions in living.c The reason is that some guilds wanted to have lower/higher values in some stats, So, seeing nothing wrong with this, I added some functionality to living.c (So, monsters can also use this) -------------------------------------------------------------------------- set_str_mult(X) set_int_mult(X) set_con_mult(X) set_dex_mult(X) These will set the apropriate multiplier to X/10, so if you do me->set_str_mult(20); you will have 2 * your usual strength. (The reason for the /10 is that you can do things like set_str_mult(5) to get 50% of your strength) -------------------------------------------------------------------------- reset_mults() This function will set all mults. to 10. -------------------------------------------------------------------------- query_str_mult() query_int_mult() query_con_mult() query_dex_mult() Returns the apropriate value... -------------------------------------------------------------------------- string query_stat_mults() This function will return a string like "Str_Mult : 1.0\nInt_Mult : 0.4\nCon_Mult : 2.2\nDex_Mult : 1.0\n" Or, Str_Mult : 1.0 Int_Mult : 0.4 Con_Mult : 2.2 Dex_Mult : 1.0 Used in show_stats. -------------------------------------------------------------------------- query_real_str() query_real_int() query_real_con() query_real_dex() These functions are the equivalent of the old query_ functions, in that they return the REAL stats. They can be used in guilds etc. when the real stat levels are requested. -------------------------------------------------------------------------- Also, these functions are changed: query_str() query_int() query_con() query_dex() These will now return (*)/10 -------------------------------------------------------------------------- query_stats() The output of this function is changed to Str: 20 (20) Int: 8 (20) Con: 44 (20) Dex: 20 (20) where the first number is the effective stat, and the second is the real one. -------------------------------------------------------------------------- doc/lfun/clean_up010066400003740000036000000042520555324673300151770ustar00hubbelysator00000420000006NAME clean_up - notify an object that it's time to clean up SYNTAX int clean_up(int ref_count) DESCRIPTION In an effort to save valuable memory space, here is your possibility to help reduce the load on the machine. clean_up() will be called when no function has been called in this object for a certain amount of time. (normally about half an hour) ref_count is a count of how many objects there is that has pointers to this object. If in doubt, never destruct an object with more than 1 refcount. (an object always has at least one refcount) It is up to the object itself to self destruct ("destruct(this_object());"). If clean_up() returns 1 it will be called again later. EXAMPLES A minimal and reasonably safe clean_up() for rooms would be this one: int clean_up(int ref_count) { if (ref_count>1 || /* If someone has a pointer to this object, or */ environment() || /* if we are inside another object, (room/bag/player) */ first_inventory(this_object()) /* or if there is someting inside us */ ) return 1; /* don't destruct, call me later */ destruct(this_object()); /* self destruct */ return 0; /* Don't call me again, I am gone */ } /* clean_up */ This clean_up will destruct a room if it empty and noone has visite it for 30 minutes. This is the default for rooms that inherit room/room.c on nannymud. A more general approach would be to take into consideration that any objects that was cloned in reset() will be cloned again if the room is destructed and loaded again, this is not normally the case. Here is an example of a clean_up that will destruct the master if there are no clones of it. (Note that it does not care if there is objects in the master or not) int clean_up(int arg) { if(environment()) return 0; while(first_inventory()) destruct(first_inventory()); if(_isclone(this_object()) || (arg<2 && this_object()==_next_clone(this_object()))) destruct(this_object()); return 1; } NOTA BENE Remember that if you have a room that keeps track of important variables or something, remember that to redefine clean_up so that you won't loose any data when it is destructed. SEE ALSO efun/destructdoc/helpdir/004077500000240000044000000000000554226561300127245ustar00mudmud00000420000006doc/helpdir/teleport010066400000240000044000000005230510335322600144710ustar00mudmud00000420000006command: cast teleport to argument: a player Teleports you to another player. Cost: 100 spellpoints. A failed teleport costs 20 spellpoints. You cannot teleport to a wizard or a monster. It is possible to prevent other players teleporting to you by using the command 'obscure'. You must be level 19 to use this spell. See also 'obscure' doc/helpdir/diagnose010066400000240000044000000001620510335277400144320ustar00mudmud00000420000006command: cast diagnose arguments: a player Will inform you of the health of another player. Cost: 5 spellpoints. doc/helpdir/whisper010066400000240000044000000003740510335323500143200ustar00mudmud00000420000006command: cast whisper argument:message If you have summoned a Watcher Spirit, you can make it whisper something to the others in the same room with this spell. Cost: 5 spellpoints. You must be level 18 to be able to use this spell. see also 'summon' doc/helpdir/abilities010066400003150000036000000013000542746614500155270ustar00scslysator00000420000006Lev Spell Spell-cost ======================================================================== 19 cast teleport to 100 18 cast whisper 5 17 cast dig 5 16 cast summon watcher spirit 40 13 cast locate 20 11 cast detect invisible 10 7 cast diagnose 5 3 cast light 20 2 cast bind 5*2^(number of bound items) 2 cast unbind 5 1 cast obscure 5 For more info, see also teleport, whisper, dig, summon, locate, detect, diagnose, light and obscure, bind, unbind. doc/helpdir/tell~010066400000240000044000000002510475505143600140010ustar00mudmud00000420000006command: tell first argument: a player (one word) second argument: a message Send a message to a specific player only. He can be anywhere in the game. See also 'say'. doc/helpdir/sigh010066400000240000044000000001740475505140500135750ustar00mudmud00000420000006command: sigh no arguments. Show a deep sigh to other players in the same room. See also 'say', 'grin', 'smile', 'laugh'. doc/helpdir/converse010066400000240000044000000001420475505140600144630ustar00mudmud00000420000006command: converse no arguments. Stay in conversation mode until stoped by '**'. See also 'say'. doc/helpdir/finger010066600000240000044000000003750505721114500141150ustar00mudmud00000420000006command: Finger argument: A player's name. You will get information on the player. Example : > Finger qqqq Qqqq the godslayer (one of the low level arches). He is a powerful and helpful high wizard. He is logged on right now. Qqqq plan is: Why?. > doc/helpdir/grin010066400000240000044000000001540475505140700136020ustar00mudmud00000420000006command: grin no arguments. Show an evil grin to other players in the same room. See also 'say', 'smile'. doc/helpdir/give010066400000240000044000000001660475505141000135720ustar00mudmud00000420000006command: give first argument: An item second argument 'to' third argument: A player Give an item to a living object. doc/helpdir/help010066400000240000044000000001220475505141100135610ustar00mudmud00000420000006command: help argument: any command. Show verbose information about any command. doc/helpdir/hug010066400000240000044000000001110475505141200134130ustar00mudmud00000420000006command: hug argument: a player Give a player a hug. See also 'thank'. doc/helpdir/tell010066400003740000036000000002760554226556600150410ustar00hubbelysator00000420000006command: tell first argument: a player (one word) second argument: a message Send a message to a specific player only. He can be anywhere in the game. Costs 5 spellpoints. See also 'say'. doc/helpdir/laugh010066400000240000044000000001540475505141400137410ustar00mudmud00000420000006command: laugh no arguments. Show a good laugh to other players in the same room. See also 'say', 'grin'. doc/helpdir/kill010066400000240000044000000003360526537615700136110ustar00mudmud00000420000006command: kill argument: a monster Start attacking a monster. It is possible to run away anytime from a fight. If you catch up with a fleeing person, you will get one attack for free. See also 'stop' and 'playerkilling'. doc/helpdir/stop010066400000240000044000000001640475505141600136310ustar00mudmud00000420000006command: stop no arguments Stop hunting a fleeing player. You can not stop being hunted though. See also: 'kill'. doc/helpdir/password010066400000240000044000000001620475505141700145050ustar00mudmud00000420000006command: password argument: The old password Change to a new password. The old password must be given correctly. doc/helpdir/thank010066400000240000044000000001210475505142000137350ustar00mudmud00000420000006command: thank argument: a player Personally thank a player. See also 'thank'. doc/helpdir/quit010066400000240000044000000003430475505142000136200ustar00mudmud00000420000006command: quit no arguments. Immediately quit the game. All objects are dropped. When you enter the game again next time, you always start at the village church. The stats about your character will be saved. See also 'save'. doc/helpdir/concept010066400000240000044000000040300475505142100142670ustar00mudmud00000420000006IDEA BEHIND THIS GAME. I played Abermud a lot, and wanted to do something better (who doesn't). 1. A wizard can extend the game. 2. The game can be extended on fly, without rebooting the mud. 3. There is no difference between objects. Rooms, players and things are just objects. 4. All objects are specified in interpreted C. The specifications are compiled (loaded) first time they are referenced. 5. There is no player parser. All commands are defined by the objects. For example, the knife defines the command 'wield', and the leather jacket defines 'wear'. An object defines a command by associating it with a local function, defined in the object. When the user types that command, the corresponding function will be called. If the user types 'wear jacket', then "jacket" will be sent as an argument to the wear function in the jacket object. If the user types 'wear plate', the jacket wear function will detect that "plate" != "jacket", and return false. Then, another 'wear' command is tried, until success. When the user drops the jacket, all commands are removed that were associated with that object. 6. The rooms are just objects that define some commands like 'look', 'east', 'north' and such things. When the user then types 'north', the room function will do something to the player. 7. An object may define a function "heart_beat". It will be called every third second. This can be used for automoving monsters, torches burning down and time delayed traps... 8. The most complex object is the player object. It defines commands like "get", "smile" and "kill". 9. When a player becomes wizard, he will get a small portable castle. He can drop this anywhere, and it will grow and become a full scale castle. He can then rename it and extend it. It is okey to rename it to "entrance to hell" or anything. 10. The language that defines objects are similar to C. It is interpreted. 11. There is a builtin ed-compatible editor for wizards creating objects. There is also 'ls' and 'cat'. doc/helpdir/save010066400000240000044000000003640475505142400136030ustar00mudmud00000420000006command: save no arguments. Save all data about your character. This is also done automatically when quiting the game. Thus, 'save' is only for paranoid players. A restore is done when you log into the game, and only then. See also 'quit'. doc/helpdir/score010066400000240000044000000002660553111336200137520ustar00mudmud00000420000006command: score arguments: stats or none If no argument: show current experience points, hit points and spell points. With an argument: shows current stats, i e int,con,dex and str. doc/helpdir/say010066400000240000044000000001770475505143100134410ustar00mudmud00000420000006command: say argument: a string The argument will be displayed to all players in the same room. See also 'converse', 'shout'. doc/helpdir/who010066400000240000044000000000660475505143200134400ustar00mudmud00000420000006command: who no arguments. Show all current players. doc/helpdir/stats010064400000240000044000000011730503741016000137660ustar00mudmud00000420000006Every player has four stats defined: Str - Strength, affects your carrying capacity. Dex - Dexterity, affects you fighting ability. Int - Intelligence, affects your spellcasting ability. Con - Constitution, affects you health. These values can be raised in adventurers guild by paying excessive experience points, points above your current level. The command 'score stats' will give information about your current stats. You raise these stats independently of your level in the adventurers guild. NB! Your sp-max and hp-max will NOT go up when you raise your level. You must raise the corresponding stat as well to accomplish that. doc/helpdir/shout010066400003740000036000000002210554226561300152220ustar00hubbelysator00000420000006command: shout argument: a string The argument will be displayed to all players everywhere. Costs 30 spellpoints. See also 'converse', 'say'b. doc/helpdir/smile010066400000240000044000000001540475505143500137550ustar00mudmud00000420000006command: smile no arguments. Show a good smile to other players in the same room. See also 'say', 'grin'. doc/helpdir/shout~010066400000240000044000000001720475505143500142040ustar00mudmud00000420000006command: shout argument: a string The argument will be displayed to all players everywhere. See also 'converse', 'say'b. doc/helpdir/typo010066400000240000044000000004470475505143600136450ustar00mudmud00000420000006command: typo argument: a string Store a message describing a spelling error. The game master will examine it. All messages are very welcome, so do not hesitate. If you are in a room created by a wizard, he will also get a copy of the message in a .rep file in /log. See also 'bug', 'idea'. doc/helpdir/dig010066400000240000044000000003220510335450000133670ustar00mudmud00000420000006command: cast dig argument: direction This powerful spell will blast a hole in the ground, or if you are underground, a hole in any direction. Cost: 5 spellpoints. It requires that you are at least level 17. doc/helpdir/brief010066400000240000044000000003440475505144000137300ustar00mudmud00000420000006command: brief no arguments. Toggle brief mode. If you are in brief mode, you will only see short descriptions of all rooms. Use the 'look' command to get the long. Default for a new player is verbose mode. See also 'wimpy'. doc/helpdir/wimpy010066400000240000044000000011470527425621400140130ustar00mudmud00000420000006command: wimpy optional argument: minimum number of hit points Without argument, defaults to 1/5 of your max hp. With argument, set the hit point limit when you run away. Toggle wimpy mode. If you are in wimpy mode, your legs will run away if your hit points goes below one fifth of max or the argument to 'wimpy'. Default for a new player is brave mode. This is no secure thing. It might save you, if you have a slow connection, or slow fingers. Some monsters hack away more than 1/5 of your HP, and you might find yourself dead without warning. And some monsters runs as fast as your legs. See also 'brief'. doc/helpdir/obscure010066400000240000044000000003770510335310200142750ustar00mudmud00000420000006command: cast obscure arguments: none This spell will make it impossible for other players to find out your location with the spells 'locate' and 'teleport'. The effect of the spell is time-limited. Cost: 5 spellpoints. see also 'teleport' and 'locate' doc/helpdir/source010066400000240000044000000003360475505144100141430ustar00mudmud00000420000006The source to LPmud 2.4 is available by ftp in pub from alcazar.cd.chalmers.se (129.16.48.100) As you know (if you play LPmud), there are bugs, so nothing is guaranteed. You can also get the source to Kantele's mansion. doc/helpdir/feelings010066400000240000044000000004010533261734200144300ustar00mudmud00000420000006If you see this text you don't have the new version of nannymuds great soul-object. That probably means you have some autoloading object that removes it. You can ask a wizard to help you to get a soul-object if you are curious as to what it does. Good luck.doc/helpdir/syntax010066400000240000044000000002440475505144200141700ustar00mudmud00000420000006When referencing to items, a number can be used to pick one item of a number of similar items. For example: sell knife 3 exa corpse 2 get axe from corpse 2 etc. doc/helpdir/levels010066400000240000044000000030340475505144300141350ustar00mudmud00000420000006Lvl Experience Male *TITLES* Female Creature =============================================================================== 20 1000000 apprentice Wizard a. W. a. W. 19 666666 grand master sorcerer g. m. sorceress ferocious tyrannosaur 18 444444 master sorcerer m. sorceress small tyrannosaur 17 296296 apprentice sorcerer a. sorceress vicious dragon 16 197530 warlock witch devious dragon 15 131687 enchanter enchantress small dragon 14 97791 magician magicienne powerful demon 13 77791 apprentice magician a. magicienne small demon 12 58527 conjurer conjuress beholder 11 39018 champion deadly amazon great monster 10 26012 warrior amazon experienced monster 9 17341 great adventurer g. adventuress medium monster 8 11561 experienced adventurer e. adventuress small monster 7 7707 small adventurer s. adventuress threatening shadow 6 5138 experienced fighter charming siren shadow 5 3425 small fighter siren wraith 4 2283 master ranger master ranger bugbear 3 1522 lowrank ranger lowrank ranger furry creature 2 1014 simple wanderer simple wanderer simple creature 1 0 utter novice utter novice utter creature enchantress small dragon 14 97791 magician magicienne powerful demon 13 77791 apprentice magician a. magicienne small demon 12 58527 conjurer conjuress beholder 11 39018 champion deadly amazon great monster 10 26012 warrior amazon experienced monster 9 17341 great adventurer g. adventuress medium monster 8 11561 edoc/helpdir/summon010066400000240000044000000005440510335315200141520ustar00mudmud00000420000006command: cast summon watcher spirit argument: none This spell will put a spirit in the room you are standing in, and will allow you to see through it's eyes, i.e. you will see and hear everything that happens in the room. The spirit's length of life is limited. Cost: 40 spellpoints. You must be level 16 to be able to use this spell. see also 'whisper' doc/helpdir/light010066400000240000044000000001470510335306100137410ustar00mudmud00000420000006command: cast light arguments: none Will light up your environment for a while. Cost: 20 spellpoints. doc/helpdir/locate010066400000240000044000000003170510335307200141020ustar00mudmud00000420000006command: cast locate argument: a player Write the location of another player. Cost: 20 spellpoints. It is possible to prevent other players using this spell on with the spell 'obscure'. see also 'obscure' doc/helpdir/email010066400000240000044000000002430475505144500137330ustar00mudmud00000420000006Command: email optional argument: new email address Without arguments, print your current electric mail address. With arguments, set a new electric mail address. doc/helpdir/spell010066400000240000044000000006610500566573000137640ustar00mudmud00000420000006command: any spell argument: optional name of a player Cast a spell. If no argument, then cast spell on current fighting opponent. Spell level Spell points Max damage missile 5 10 20 shock 10 15 30 fireball 15 20 40 You have to have enough experience points to be able to use the spells, but then they will work 100 %. If you cast a spell on an idle player, a fight will start. See also 'kill' and 'abilities'. doc/helpdir/detect010066400000240000044000000001730510335450600141060ustar00mudmud00000420000006command: cast detect invisible argument: none See if any invisible players are hiding in this room. Cost: 10 spellpoints. doc/helpdir/Finger010066600000240000044000000003750505721114000140500ustar00mudmud00000420000006command: Finger argument: A player's name. You will get information on the player. Example : > Finger qqqq Qqqq the godslayer (one of the low level arches). He is a powerful and helpful high wizard. He is logged on right now. Qqqq plan is: Why?. > doc/helpdir/Plan010066600000240000044000000003330505721220200135220ustar00mudmud00000420000006command: Plan argument: Your plan (if you want to see what your plan is then no argument) You can set your plan (used by the Finger-command). Example : >Plan HELP Your plan reads: HELP. >Plan Your plan reads: HELP. doc/helpdir/plan010066600000240000044000000003330505721217700135750ustar00mudmud00000420000006command: Plan argument: Your plan (if you want to see what your plan is then no argument) You can set your plan (used by the Finger-command). Example : >Plan HELP Your plan reads: HELP. >Plan Your plan reads: HELP. doc/helpdir/stty010064400000240000044000000006730534615150700136510ustar00mudmud00000420000006NAME stty SYNOPSIS stty [rows | cols | term | all] DESCRIPTION Set terminal size and type characteristics. If no arguments are given, display current size settings. If called with the "all" argument, include terminal type information. EXAMPLES stty rows 36 stty cols 132 stty term vt100 stty all BUGS You can't combine the options on the command line AUTHOR Peter Eriksson (Lpd@NannyMUD) doc/helpdir/quests010064400003740000036000000015540537676722400154260ustar00hubbelysator00000420000006A quest is a problem that the players can solve, and if you want to become an immortal wizard, you have to solve at least some of the quests. On NannyMUD, each quest gives a certain number of points. Easy quests give few points, hard quests give many. To become immortal, you must collect 70% of the maximum number of quest points - plus a million experience points. Don't worry if more quests are added. It is the maximum number of quest points on the day that you were born (that is, when your player character was created) that is used. (But see also "help questpoints"!) If you solve ALL the quests, you can become immortal even without the experience points. If you go to the Adventurers Guild in the village (or to your own guild, if you have joined another one), you can use the command 'list' to list the quests you can solve, and to see how many points you need. doc/helpdir/playerkilling010066600000240000044000000013530520350215700155050ustar00mudmud00000420000006By default, a player can not attack or kill another player. Each player gets a guardian angel when he (or she or it) is born, and this angel will protect you from other players who try to attack you. It will also stop you from attacking them. There are, however, places in the world where players can kill each other without interference from their guardian angels, or from the law. One of these is the ancient place of duels, behind the village church. A player can go to the Dark Temple - also behind the village church - and abolish his guardian angel. This will allow him to attack other players, who also have lost their guardian angels, but not those who still have their angels. Once you have lost your angel, you can never get it back. doc/helpdir/quest010064400000240000044000000000330526537611700140030ustar00mudmud00000420000006Try "help quests" instead. doc/helpdir/hpinfo010064400000240000044000000003660533375001200141200ustar00mudmud00000420000006NAME hpinfo SYNOPSIS hpinfo DESCRIPTION Toggle hp/sp info on/off. When in the on mode, hp and sp will be displayed everytime it changes. EXAMPLE >hpinfo HP/SP info turned on. > ** HP: 30/50 SP: 40/50 doc/helpdir/questpoints010064400003740000036000000025220537676725400164770ustar00hubbelysator00000420000006Some people have complained about their "required quest points" increasing, despite what "help quests" says: > Don't worry if more quests are added. It is the maximum number of > quest points on the day that you were born (that is, when your > player character was created) that is used. This is how it works, in more detail: To be able to advance to wizard, a player must have collected a certain percentage, currently 70%, of the maximum number of quest points. Each player will "remember" what the max number of quest points was when that player was created. To advance to wiz, he must collect 70% of THAT number of quest points, instead of of the current max number. Since the max number of quest points could get LOWER, for example if one or more quests are temporarily closed, the player actually needs 70% of the smallest number of "max number when he was created" and "current max number" - otherwise he would never be able to wiz! So, if the current number goes below your remembered number, you use the lower figure. But when the closed quests are back (or new ones are opened!) you will have to solve them. This means that sometimes your required points are suddenly higher than they were yesterday, but this is not because they've been raised - it's beacuse they were temporarily lowered yesterday, and now they are back to the original level. doc/helpdir/addhost010064400000240000044000000012160527273646400142770ustar00mudmud00000420000006NAME addhost SYNOPSIS addhost [host-ip-number] DESCRIPTION With no arguments, addhost prints out all of the current hosts that are allowed to login to your character. Otherwise host-ip-number is added to the table of allowed hosts. The host-ip-number may have wildcards, *, to specify an entire domain. EXAMPLE addhost 130.236.254.* Will only allow hosts from Lysator to use your char. addhost *.*.*.* Allow all hosts to try to login. addhost 130.236.*.* Allow everyone at LiU to try to login. SEE ALSO subhost doc/helpdir/subhost010064400000240000044000000006350527273650700143420ustar00mudmud00000420000006NAME subhost SYNOPSIS subhost host-ip-number | all DESCRIPTION Subhost simply removes an allowed host from your table of hosts. You may state 'all' to get rid of all hosts, and thus allow everyone to try to login and use your char. If a host was entered with wildcards, then it must be removed with the same wildcards supplied. ( ie textual matching ) SEE ALSO addhost doc/helpdir/bind010064400003150000036000000004260542746635100145030ustar00scslysator00000420000006command: cast bind argument: an item Will magically bind your item so you can't drop it, nor sell it at the regular shop. Also if you quit the item will be destructed and not dropped. This costs 5 sp for the first item, 10 for the next one, then 20, etc. See also 'unbind' doc/helpdir/unbind010064400003150000036000000002420542746645400150460ustar00scslysator00000420000006command: cast unbind argument: an item Will magically unbind your item so you can drop it and sell it at the regular shop. This costs 5 sp. See also 'bind' doc/helpdir/News010066400003740000036000000004030543221140200147570ustar00hubbelysator00000420000006NAME News SYNOPSIS News [on | off] DESCRIPTION Without parameters, will display general mud news. Use of on/off will toggle whether the news is displayed at login or not. EXAMPLE > News on You will now read news. > doc/helpdir/bug010066400003740000036000000004410546611372700146440ustar00hubbelysator00000420000006command: bug argument: a string Store a bug message. The game master will examine it. All bug messages are very welcome, so do not hesitate. If you are in a room created by a wizard, he will also get a copy of the message in a .rep file in /log. See also 'typo', 'idea' and 'praise'. doc/helpdir/praise010066400003740000036000000003070546611367700153570ustar00hubbelysator00000420000006command: praise argument: a string Store a message about what you like. If you are in a room created by a wizard, he will get the message in a .rep file in /log. See also 'typo', 'idea' and 'bug'. doc/helpdir/idea010066400003740000036000000005070546611403400147640ustar00hubbelysator00000420000006command: idea argument: a string Store a message describing a change or enhancement to the game. The game master will examine it. All messages are very welcome, so do not hesitate. If you are in a room created by a wizard, he will also get a copy of the message in a .rep file in /log. See also 'bug', 'typo' and 'praise'. doc/helpdir/mail010066400006540000036000000024130551240000100154670ustar00celebornlysator00000420000006COMMANDS these commands work at the '&' prompt d [message list] delete messages h print out active headers m [player] mail to a player q quit. r [message list] reply to message (sender only) R [message list] reply to sender and all recipients of messages s [message list] file append messages to file ? displays this text These commands work at the begining of a new-line when writing a mail ~q will abort the mail. . exits/ends the mail and prints out the Cc: prompt. mail will try to read your mail if you have any mail test will mail the player test. mail admin will mail all the admins on the mud. EXAMPLES d 10 deletes message number 10 d 10-14 deletes message number d deletes the current mail (the one that is pointed out by the '>' sign to the leftmost side of the row) If is hit in mail mode (when you have the '&' prompt) you will get the next mail displayed all the time just by pressing doc/helpdir/set_prompt010064400006140000036000000023560551305604400165610ustar00cardecilysator00000420000006 NAME set_prompt -- Set the prompt to something else than the standard '>' SYNOPSIS set_prompt DESCRIPTION Sets the prompt to . Variable replacement will also take place, using the variables listed below. $qp Your qp, updated when changed. $hp The current healthpoints of the player, updated once every heart-beat (Aproximately 2 sec.) $sp The current spellpoints of the player. Also updated once every 2 sec. $exp The experience level of the player, updated when changed. $gold The current amount of gold the player carries around. Updated when changed. $name The name of the player. $mud The name of the mud (Alwas equals NannyMUD on NannyMUD) \n A newline. EXAMPLES > set_prompt $$gold[$hp/$sp]> $1243[202/12]> set_prompt <$exp> <251641> set_prompt [ Hp: $hp Sp: $sp Money: $gold ] [ Hp: 202 Sp: 202 Money: 985 ] set_prompt > > set_prompt Hp: $hp Sp: $sp Exp: $exp Gold: $gold\n> Hp: 202 Sp: 202 Exp: 251641 Gold: 985 > (* My favourite *) BUGS The first character in the promptstring is ignored as far as variable substitution goes , thus 'set_prompt $money>' will result in the prompt " >", and not, as could be expected, "102332>" p Your qp, updated when changed. $hp The current healthpoints of the player, updated once every heart-beat (Aproximately 2 sec.) $sp The current spellpoints of the player. Also updated once every 2 sec. $exp The experience level of the pldoc/helpdir/rules010066400002410000036000000017570551653337000152420ustar00matpelysator00000420000006Nanny Mud Official Rules for Mortals. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Don't abuse bugs. If you find a serious bug please report it to a highwizard or the responsible wizard, if you know who it is. This is so the game will be more bugfree and enjoyable. This does not include typos, use the typo and bug command whenever possible. # If you have choosen an obnoxious or offending name you will be given the option to change it to something acceptable. # If another player asks you to leave him/her/it alone, you must respect their wishes. Harassment is not looked upon lightly. Do not annoy anyone by sending control-characters that beeps or messes up the screen. # Your character is personal, and should not be used by others in any way or form. The password is likewise personal, and should not be known by anyone but yourself. If you do give out your password or if someone crack it you are still responsible for your characters actions. [Last revision, 17 Jan 1993] doc/helpdir/coins010066400010330000036000000001100553111334600155510ustar00neotronlysator00000420000006command: coins arguments: none Show how much money you currently have. doc/w/004077500000240000044000000000000556521011400115325ustar00mudmud00000420000006doc/w/load010066400000240000044000000006640500565076000124030ustar00mudmud00000420000006Command: load Argument: file If the object defined in 'file' isn't loaded, it will be. 'reset(0)' will also be called in the object. If the object was loaded, nothing will happen. This command is implemented by teleporting the wizard to the object, which will force the object to load, and then teleporting the wizard back again. Rooms can also be loaded by just walking to them. That has exactly the same effect. See also w/clone. doc/w/README010066400000240000044000000001020500564603500124040ustar00mudmud00000420000006This directory documents all standard commands that a wizard has. doc/w/cat010066400000240000044000000007760475505145300122440ustar00mudmud00000420000006Command: cat Argument: file Print the file 'file'. If it is big, characters will be lost because all of the file is written to the socket, without delay. The file will be searched for in the current directory. 'cat castle.c' will print the castle of the wizard. 'cat' isn't really good for lookin at game files, but rather better for reading documentation. Only Arch wizards and higher can read files from other wizards. Files from the basic adventure can be read by all wizards. See also w/ls, w/ed, w/rm doc/w/ls010066400000240000044000000004170513234610700120740ustar00mudmud00000420000006Command: ls optional argument: path Give a list of all files in 'path'. If no argument is given, list the files in current directory, which is the home directory of the wizard. 'ls /' will give a list of all files in the game home directory. See also w/cat, w/ed, w/rm doc/w/ed010066400000240000044000000013730500565004200120430ustar00mudmud00000420000006Command: ed Argument: file Edit the file 'file'. For documentations about how to use 'ed', look at /doc/build. You can leave 'ed' with the command 'q', or 'Q' if the file has been modified. When in 'ed', the prompr will change to ':'. The file will be searched for in the current directory. 'ed castle.c' will edit the castle of the wizard. A wizard can only edit files in his home directory, /open and in /log. If 'ed' is started without argument, it will edit the file where you last had an error message, and print that message. 'ed' without arguments will edit the last file with an error in, either run time error, or compile time error. So, when you log in to the game, start with 'ed' to see if you have had any errors. See also w/ls, w/cat, w/rm doc/w/clone010066400000240000044000000011420500564664000125560ustar00mudmud00000420000006Command: clone Argument: file Clone a copy of an object. The "bluebrint" must not be used for anything else then cloning. If the object defined in 'file' isn't loaded, it will be. 'reset(0)' will also be called in the object. When the 'file' is loaded, a new copy of the object will be created, and moved to either the wizard giving the command, or to his room, depending on what 'get()' says in the object. When the object is being copied, it will have a new 'reset(0)' again. Rooms and castles should never be cloned, because they should always exist singularly, not in several copies. See also w/load. thing else then cloning. If the object defined in 'file' isn't loaded, it will be. 'reset(0)' will also be called in the object. When the 'file' is loaded, a new copy of the object will be created, and moved to either the wizard giving the command, or to his room, depending on what 'get()' says in the object. When the object is being copied, it will have a new 'reset(0)' again. Rooms and castles should neverdoc/w/destruct010066400000240000044000000006610475505145500133250ustar00mudmud00000420000006Command: destruct Argument: object If there is an object named "object" in the same room, it can be destroyed with 'destruct object'. If it is a cloned object, the original blue print will still remain loaded. If it is a singular object (not cloned), like a castle, then all data about the object will be discared. An 'update' of a castle will have the same effect. Never 'destruct' a player. See also w/clone, w/update, w/load. doc/w/update010066400000240000044000000007000475505145700127460ustar00mudmud00000420000006Command: update Argument: file Remove the definition of an object. If the object was cloned, all copies of it will remain. Use full path name if the file is not in your home directory. If it is a room, the room will be destroyed. The next refernce of the room will load it again from the file. The 'update' command is implemented as an LPC function that simply calls 'destruct()' on the object. See also w/clone w/destruct w/load efun/destruct doc/w/stat010066400000240000044000000001320475505146000124300ustar00mudmud00000420000006Command: stat argument: name Give status about a player or a monster. See also: w/snoop doc/w/heal010066400010540000036000000004240552426324100136130ustar00medinlysator00000420000006Command: heal argument: name Heal a player or a monster totally. Spell points are restored. The use of this command is restricted by the RULES. Using this command to heal mortals (this does not, of course, include your testcharacter) will result in loosing your wizardhood. doc/w/title010066400000240000044000000001560475505146100126050ustar00mudmud00000420000006Command: title argument: new title Without arguments, print your old title. With arguments, set a new title. doc/w/goto010066400000240000044000000004550500565025000124240ustar00mudmud00000420000006Command: goto argument: obj Teleport directly to a room or a player. If 'obj' is a room, the go to that room. If 'obj' is a player, then go to the same room as his. Bugs: When teleporting to a player or monster, you will not get a description of the contents of that room. See also: w/trans, w/in doc/w/in010066400000240000044000000001550475505146300120730ustar00mudmud00000420000006Command: in argument 1: obj argument 2: command Execute a command 'command' in room 'ob'. See also: w/goto doc/w/emote010066400000240000044000000003110500564727300125670ustar00mudmud00000420000006Command: emote argument: string Give a message 'string' to all in room. Your name willbe prepended to the message. The use of this command is restricted by the RULES. Never use it to confuse players. doc/w/people010066400000240000044000000007070475505146400127550ustar00mudmud00000420000006Command: people List fact of all players: The current name. What level the are at. Idle flag 'I' if the player has been idle for more than 5 minutes. What internet host or number they call from. What age they are. Where they are. There is also shown the number of active players, number of commands per second executed (averaged over the last 15 minutes) and number of lines compiled per second (averaged of the last 15 minutes). See also: w/wizlist doc/w/wizlist010066400000240000044000000017030475505146500131740ustar00mudmud00000420000006Command: wizlist (name) The wizard top score list. This is the purpose of the game: To be on the top of this list. Of course, you have to become wizard first. A wizard get one point for every command he has defined when it is used by a player. It is quite easy to cheat, of course, but cheating wizards are simply removed from the game (and the list). When you use commands defined by your objects, you will also get points, but this is legal for normal use. The score decays with 1 % every reset, and is saved and restored from file when reboot of game. If there are many wizards, not all wizlist data is printed. Give name of wizard as argument if you want to look at a special wizard. Columns: 1: Score of the castle. 2: Score % of total. 3: Rank sorted by column 1. 4: Total number of evaluated nodes. 5: Total number of heart beats. 6: Experience + money given to players by this wizard. 7: Total number of indices used in arrays. See also: w/people doc/w/setmin010066400000240000044000000002440475505146700127670ustar00mudmud00000420000006Command: setmin Argument: mess Set the message given when you enter a room. The message will have your name prepended. See also: w/setmout, w/setmmin, w/setmmout doc/w/setmout010066400000240000044000000002440475505146700131700ustar00mudmud00000420000006Command: setmout Argument: mess Set the message given when you leave a room. The message will have your name prepended. See also: w/setmin, w/setmmin, w/setmmout doc/w/setmmin010066400000240000044000000002520475505147000131350ustar00mudmud00000420000006Command: setmmin Argument: mess Set the message given when you teleport to a room. The message will have your name prepended. See also: w/setmout, w/setmin, w/setmmout doc/w/setmmout010066400000240000044000000002540475505147100133410ustar00mudmud00000420000006Command: setmmout Argument: mess Set the message given when you teleport from a room. The message will have your name prepended. See also: w/setmout, w/setmin, w/setmmin doc/w/review010066400000240000044000000001760475505147100127700ustar00mudmud00000420000006Command: review Show all messages given when you leave or enter a room. See also w/setmin, w/setmout, w/setmmin, w/setmmout doc/w/shutdown010066400000240000044000000003610500565164000133270ustar00mudmud00000420000006Command: shutdown Shutdown the game immediately. Don't do this if you don't have a very good reason for it. And if possible, give players time to sell their things and save. If possible you should use armageddon for this purpose instead. doc/w/trans010066400000240000044000000003020500565207100125750ustar00mudmud00000420000006Command: trans Argument: name Transport a player or monster to you. The use of this command is restricted by the RULES and should be handled with care. If you trans a player always ask first. doc/w/force010066400000240000044000000003550500564753700125670ustar00mudmud00000420000006Command: force Argument: name 'to' cmd Force a player or monster 'name' to execute command 'cmd'. The use of this command is restricted by the RULES and should be used with breat care. Bugs: Monsters don't have the command 'say' etc. doc/w/rm010066400000240000044000000004300475505150200120710ustar00mudmud00000420000006Command: rm Argument: file Remove the file 'file'. The file will be searched for in the current directory. 'rm castle.c' will remove the castle of the wizard (not to be recommended). Only Arch wizards and higher can remove files from other wizards. See also w/ls, w/ed, w/cat doc/w/cd010066400000240000044000000002760500564633600120550ustar00mudmud00000420000006Command: cd Argument: path Change current directory. If no argument is given, the path will be changed to the wizards home directory. If '..' is given you will move to the parent directory.doc/w/more010066400000240000044000000003340555456545100124330ustar00mudmud00000420000006Command: more Argument: file Print the file 'file' 16 lines and wait for input. space: 16 lines more. 'q': Stop printing. 'u': Backup 16 lines. '!' will execute . See also w/ls, w/ed, w/rm, w/cat doc/w/rmdir010066400000240000044000000003370475505150500126010ustar00mudmud00000420000006Command: rmdir Argument: file Remove the directory 'file'. The file will be searched for in the current directory. Only arch wizards and higher can remove directories from other wizards. See also w/ls, w/ed, w/cat w/rm doc/w/mkdir010066400000240000044000000002770475505150600125760ustar00mudmud00000420000006Command: mkdir Argument: file Create the directory 'file' in the current directory. Only arch wizards and higher can remove directories from other wizards. See also w/ls, w/ed, w/cat w/rm doc/w/pwd010066400000240000044000000000660475505150700122570ustar00mudmud00000420000006Command: pwd Argument: none Print current directory. doc/w/set_access010064400001710000036000000003030545751752100145050ustar00penlysator00000420000006Command: set_access Abbreviation: sac Syntax: -default set_access -like : [... :] Assigns ACL protection to a filesystem object . doc/w/echo010066400000240000044000000002510475505151000123710ustar00mudmud00000420000006Command: echo Argument: Any string The string is sent to all players in the same room. This should be used with great care, and is almost already illegal by the RULES. doc/w/echoall010066400000240000044000000003010475505151100130570ustar00mudmud00000420000006Command: echoall Argument: Any string The string is sent to all players in the game. This should be used with great care, and is almost already illegal by the RULES. See also: w/emote w/echo doc/w/snoop010066400000240000044000000002320475505151200126120ustar00mudmud00000420000006Command: snoop Argument: a player Listen to everything that player hears or says. You can also listen to wizards if they have a lower level than you do. doc/w/setenv010066400000240000044000000025150516557762300130020ustar00mudmud00000420000006NAME setenv - modify/view environment variables SYNOPSIS setenv [var value] DESCRIPTION With no arguments, setenv prints out all of the current environment variables and their values. setenv with one argu- ment sets a variable (the argument) to a null value. setenv with both arguments, sets the variable (first arg) to the value of the second argument. USEFUL VARIABLES WROOM Specifies the path for your workroom. Used by the command home. MIN, MOUT, MMIN, MMOUT, MDEST, MCLONE, MVIS, MINVIS (Not implemented yet :) The moving messages that are displayed when you do various things. Each has a few requirements in addi- tion to the message. The message must contain $N, which will be replaced with your name. In addition, MCLONE and MDEST require $O, which will be replaced with the name of the object you are cloning / destruct- ing. Also, MOUT requires $D, which will be replaced with the direction which you are leaving in. TITLE The title/name you have on "who" and in a room. If the title does not contain your name or $N, which will be replaced with your name, then your name will be add- ed first in the title. SEE ALSO unset doc/w/sac012077700006140000036000000000000553641074300160072set_accessustar00cardecilysator00000420000006doc/w/addhost010064400000240000044000000012160526733124700131100ustar00mudmud00000420000006NAME addhost SYNOPSIS addhost [host-ip-number] DESCRIPTION With no arguments, addhost prints out all of the current hosts that are allowed to login to your character. Otherwise host-ip-number is added to the table of allowed hosts. The host-ip-number may have wildcards, *, to specify an entire domain. EXAMPLE addhost 130.236.254.* Will only allow hosts from Lysator to use your char. addhost *.*.*.* Allow all hosts to try to login. addhost 130.236.*.* Allow everyone at LiU to try to login. SEE ALSO subhost doc/w/unsetenv010066400000240000044000000003130516557623300133330ustar00mudmud00000420000006 NAME unset - remove an environment variable SYNOPSIS unsetenv DESCRIPTION unsetenv removes the variable from the list of environ- ment variables. SEE ALSO setenv doc/w/subhost010064400000240000044000000006350526733156400131570ustar00mudmud00000420000006NAME subhost SYNOPSIS subhost host-ip-number | all DESCRIPTION Subhost simply removes an allowed host from your table of hosts. You may state 'all' to get rid of all hosts, and thus allow everyone to try to login and use your char. If a host was entered with wildcards, then it must be removed with the same wildcards supplied. ( ie textual matching ) SEE ALSO addhost doc/w/ftp010066400001710000036000000012500545736726600131770ustar00penlysator00000420000006This is not a command, merely an info-file. When connecting via 'ftp', just enter 'mud:{name}' or 'mud!{name}' (where { name} is your wizard character name) and then enter your LPMUD password. Please note that the 'dir' command may not work. The 'ls' command might work depending on how old your 'ftp' program is. On newer 'ftp' programs 'nlist' should give you a list of the files available. The host address you should use to access your MUD files in NannyMUD is 'ftp.mud.lysator.liu.se'! Please mail all bugs to Lpd (or pen@lysator.liu.se). The source is available for anonymous FTP at 'ftp.lysator.liu.se' in the directory 'pub/lpmud/ftpd' as 'wu-ftpd-2.1B-lpmud.tar.gz'. doc/w/blocker.doc010064400003150000036000000036420536664204200145710ustar00scslysator00000420000006 Blocker. -------- A hack made by Qqqq, feel free to do anything with it as long as you update this doc. and make comments in the code and ChangeLog. Blocker lets you block everyone but superiors, it also lets you, choose who to block or who not to block. This program is autoloading and needs no activation. To deactiate it simply, destruct the object (brutal), or just do 'Set 0 0 0' (Nice way). To use blocker you need to have a closed dir in your main directory. Do: 'cd' and then 'mkdir closed' if you don't have one. Well the commands in Blocker is: Save It will save your settings. Load It will load all your previously saved settings. Set [level] [trace block bag] This is sort of the magic function that does everything. Here you either set the minlevel of those you shall listen to or You set three things at once: Trace <0/1> 0 is disabled, 1 is enabled. Will let you trace who said something to you. Block <0/1/2> 0 is disabled, 1 is letting you block all but your friends (explained more in Blocked), 2 is blocking all but your enemies. Bag <0/1/2> 0 is disabled, 1 writes everything that is blocked to the file ~/closed/bag.log. 2 writes everything you see on your screen to the file ~/closed/last.log. This can only be used by 22++. Please try and remove the files now and then. Blocked If is given then it will show all your enemies otherwise it will show all your friends (Hey how about that!). Your friends is people who shall be able to tell/shout/etc you stuff even if your Block is 1. You enemies, people who bother you, will be blocked out if you set Block to 2, and everyone else can tell/shout/etc to you. Add Will add a person to your friends list. AddN Will add a person to your enemy list. Sub Will remove a person from your friends list. SubN Will remove a person from your enemy list. doc/w/man010066400010330000036000000002220555456547400140560ustar00neotronlysator00000420000006Command: man Argument: topic Will more the topic. Possible topic are most files in the /doc/*/* dirs. See also w/ls, w/ed, w/rm, w/cat, w/more doc/w/ACL010064400001710000036000000036120545737011200127670ustar00penlysator00000420000006This is not a comand, merely an informational file. ACL stands for Access Control List, and is a way to control what access a given LPC object or wizard can have to filesystem objects like directories and files. The following access rights are defined: P Protect, can modify ACLs D Delete, can delete filesystem objects A Add, can create filesystem objects L List, can get a directory listing U Use, (not currently implemented) R Read, can read files W Write, can write to already existing files X eXecute, can clone&load objects (not yet implemented) Two abbreviations also exists, ALL is all the above rights, and NONE is none of the above rights. Access can be given to a number of types of "objects", for example: Lpd A wizard (interactive player really) /obj/rope An LPC object /room/ All objects in the /room directory (and subdirs) .ArchWiz All "objects" in the .ArchWiz group. .Lpd.GuildFoo All "objects" in Lpd's .GuildFoo group. $REST A "catchall". An ACL can look something like this: Lpd:ALL (Lpd have ALL rights) Oros:LUR (Oros have List, Use and Read rights) /players/lpd/:ALL (All objects in my homedir have ALL rights) $REST:NONE (All other "objects" don't have any rights) One thing to notice is that if there isn't an ACL assigned to a filesystem object then the rights will be inherited from the nearest parent directory to that object. So if you have an ACL assigned to your home directory then the access rights specified in it will automatically apply to all your subdirs and files (unless you assign another ACL to one of the subdirs or files of course). For more information about how to view ACLs, see the "list_access" command (abbreviation "lac"). To assign and modify ACLs, see the "set_access" (abbreviation "sac") and "edit_access" ("edac") commands. See also: w/list_access, w/set_access, w/edit_access Author: Peter Eriksson , 15 Oct 1993. doc/w/more~010066400010330000036000000002120555456540300144320ustar00neotronlysator00000420000006Command: man Argument: topic Will more the topic. Possible topic are most files in the /doc/*/* dirs. See also w/ls, w/ed, w/rm, w/cat doc/w/list_access010064400001710000036000000004400545737011600146640ustar00penlysator00000420000006Command: list_access Abbreviation: lac Optional argument: path View the ACL protecting a certain filesystem object 'path'. If no argument is given, default to the current directory. See also: w/ACL, w/set_access, w/edit_access Author: Peter Eriksson , 15 Oct 1993. doc/w/edac012077700000000000001000000000000551221200000152352edit_accessustar00rootother00000420000006doc/w/lac012077700000000000001000000000000551221200000151262list_accessustar00rootother00000420000006doc/w/edit_access010064400001710000036000000010350545751721300146400ustar00penlysator00000420000006Command: edit_access Abbreviation: edac Arguments: path object:rights [... object:rights] Modify an ACL protecting a certail filesystem object 'path'. If the object was protected by a default ACL, then a specific ACL will be created by copying and modifying the default ACL (accordning to the arguments specified). Examples: edac ~ $rest:lurx edit_access myguild_dir rohan:DALURWX qqqq:DALURWX edac (foo.c bar.c fubar.c) $rest:NONE See also: w/ACL, w/set_access, w/list_access Author: Peter Eriksson , 15 Oct 1993 doc/LPC/004077500000240000044000000000000553642655600117235ustar00mudmud00000420000006doc/LPC/README010066400000240000044000000004410475505151400125650ustar00mudmud00000420000006This directory contains documentation about the language used to program objects. I tried to make it similar to C, as many people know how to program C. I called it LPC, to connect it to the name LPmud. Programs in an object are compiled into a special tree form, to speed up evaluation. doc/LPC/arrays010066400000240000044000000023260525035011600131240ustar00mudmud00000420000006ARRAYS There is support for arrays. The arrays are declared by putting a '*' in front of the variable name. Space for them can be allocated with the function 'allocate' or when you use '+', '-' and other operations on an array, space is allocated by those. Arrays are stored by reference, so all assignments of whole arrays will just copy the address. The array will be deallocated when no variable points to it any longer. When a variable points to an array (it has to be initialized to do that), items can be accessed with indexing: 'arr[3]' as an example. The name of the array being indexed can be any expression, even a function call: 'func()[2]'. It can also be another array, if this array has pointers to arrays: arr = allocate(2); arr[0] = allocate(3); arr[1] = allocate(3); or arr = ({ ({ 0,0,0 }), ({ 0,0,0 }) }); /* Gives the same as above */ Now 'arr[1][2]' is a valid value. The 'sizeof()' function (in true C, not a function) will give the number of elements in an array (see efun/sizeof). ARRAY CONSTRUCTOR Arrays can be constructed with a list inside '({' and '})'. Example: ({ 1, "xx", 2 }) will be construct a new array with size 3, initialized with 1, "xx" and 2 respectively. See also: efun/allocates on an array, space is allocated by those. Arrays are stored by reference, so all assignments of whole arrays will just copy the address. The array will be deallocated when no variable points to it any longer. When a variable points to an array (it has to be initialized to do that), items can bdoc/LPC/block010066400000240000044000000004230475505151500127230ustar00mudmud00000420000006BLOCK A block is a special statment, that begins with '{', contains a list of statements, and ends with '}'. The block may also define local variables. Note: Currently, the local variables are visible until the end of the function. This will be fixed later (any year :-). doc/LPC/do-while010066400000240000044000000005530500564465400133460ustar00mudmud00000420000006DO WHILE STATEMENT do { statement } while(expr); Execute 'statment' until 'expr' evaulates to 0. A 'break' in the 'statement' will terminate the loop. A 'continue' will continue the execution from the beginning of the loop. example: i = 0; do { write(i+" "); i += 1; } while ( i < 10 ); Would give the following output: 0 1 2 3 4 5 6 7 8 9 doc/LPC/for010066400000240000044000000010000500564112600123770ustar00mudmud00000420000006FOR STATEMENT for(expr1; expr2; expr3) statement; Execute 'expr1' once. Then, while 'expr2' returns a non-zero value, execute 'statement'. Every time 'statement' has been executed, or a 'continue' statement has been executed, execute 'expr3' before next loop. A 'break' in the 'statement' will terminate the loop. A 'continue' will continue the execution from the beginning of the loop. example: for (x=0; x<11; ++x) { write(x+" "); } will give the following output: 0 1 2 3 4 5 6 7 8 9 10 doc/LPC/function010066400000240000044000000021260525034631100134500ustar00mudmud00000420000006FUNCTIONS A locally defined function can have any number of arguments. All basic types can be sent in the argument. A return value is sent with the 'return' statement. All four data types can be used in the return statement. The type of the function is optional. If the type is given, typechecking is enabled for that function. If strict_types is used, typechecking is used for the whole file and you have to declare the type of functions. Uninitialized arguments are set to 0. The type of the argument must not be declared (except for 'static'). It is illegal to have a function with the same name as a global function, or local variable. Functions are reentrant. If there is no return statement, the number 0 will be returned. function_name(argument1, argument2 ...) { local variables; ... statements; ... return value; } Functions in other objects can be called with 'call_other(ob, "fun", arg...)'. This an also be written 'ob->fun(arg...)', which is nicer syntax. A function can have the type 'static', and it will not be possible to call with call_other() from another object. doc/LPC/inheritance010066400000240000044000000016200525034450400141140ustar00mudmud00000420000006INHERITANCE An object can inherit all variables and functions from another object. This is done with the declaration 'inherit "file";'. This must come before any local variables or functions. An example, defining a monster: inherit "obj/monster"; reset(arg) { ::reset(arg); set_name("troll"); set_level(9); set_hp(100); set_wc(12); set_al(-60); set_short("A troll"); set_long("It is a nasty troll that looks very aggressive.\n"); set_aggressive(1); } The following will also work: inherit "obj/monster"; reset(arg) { ::reset(arg); name = "troll"; level = 9; hit_point = 100; weapon_class = 12; alignment = -60; short_desc = "A troll"; long_desc = "It is a nasty troll that looks very aggressive.\n"; aggressive = 1; } As always, refer to the inherited file to see the functions and variables available. See also: /doc/efun/inheritdoc/LPC/operators010066400000240000044000000052530525034540600136510ustar00mudmud00000420000006These are the operators availailable in LPC. They are listed in the order or precedence (low priority first): expr1 , expr2 Evaluate 'expr1' and then 'expr2'. The returned value is the result of 'expr2'. The returned value of 'expr1' is thrown away. var = expr Evaluate 'expr', and assign the value to 'var'. The new value of 'var' is the result. var += expr Assign the value of 'expr' + 'var' to 'var'. This is equivalente to "var = var + expr". var -= expr Similar to '+=' above. var &= expr var |= expr var ^= expr var <<= expr var >>= expr var *= expr var %= expr var /= expr expr1 || expr2 The result is true if 'expr1' or 'expr2' is true. 'expr2' is not evaluated if 'expr1' was true. expr1 && expr2 The result is true i 'expr1' and 'expr2' is true. 'expr2' is not evaluated if 'expr1' was false. expr1 | expr2 The result is the bitwise or of 'expr1' and 'expr2'. expr1 ^ expr2 The result is the bitwise xor of 'expr1' and 'expr2'. expr1 & expr2 The result is the bitwise and of 'expr1' and 'expr2'. expr1 == expr2 Compare values. Valid for strings and numbers. expr1 != expr1 Compare values. Valid for strings and numbers. expr1 > expr2 Valid for strings and numbers. expr1 >= expr2 Valid for strings and numbers. expr1 < expr2 Valid for strings and numbers. expr1 <= expr2 Valid for strings and numbers. expr1 << expr2 Shift 'expr1' left 'expr2' bits. expr1 >> expr2 Shift 'expr1' right 'expr2' bits. expr1 + expr2 Add 'expr1' and 'expr2'. If numbers, then arithmetic addition is used. If one of the expressions are a string, then that string is concatenated with the other value. You can also add two arrays together which gives an array containing all the elements from both arrays. expr1 - expr2 Subtract 'expr2' from 'expr1'. Valid for numeric values and arrays. In the latter case an array with the elements from the first array where the elements also existing in array 2 has been excluded. expr1 * expr2 Multiply 'expr1' with 'expr2'. expr1 % expr2 The modulo operator of numeric arguments. expr1 / expr2 Integer division. ++ var Increment the value of variable 'var', and return the new value. -- var Decrement the value of variable 'var', and return the new value. - var Compute the negative value of 'var'. ! var Compute the logical 'not' of an integer. ~ var The boolean 'not' of an integer. var++ Increment the value of variable 'var', and return the old value. var-- Decrement the value of variable 'var', and return the old value. expr1[expr2] The array given by 'expr1' is indexed by 'expr2'. expr1->name(...) 'expr1' gives either an object or a string which is converted to an object, and calls the function 'name' in this object. d value is the result of 'expr2'. The returned value of 'expr1' is thrown away. var = expr Evaluate 'expr', and assign the value to 'var'. The new value of 'var' is the result. var += expr Assign the value of 'expr' + 'var' to 'var'. This is equivalente to "var = var + expr". var -= expr Similar to '+=' above. var &= expr var |=doc/LPC/types010066400000240000044000000016700525034623300127750ustar00mudmud00000420000006TYPES Variables can have one of the following types: int: An integer. Normally full 32 bits signed. status: A boolean, either 0 or 1 (really the same as int). string: A string (not pointer to string). object: Pointer to an object. mixed: Can have any of the types above and can be casted to a specific type. All uninitialized variables have the value 0. The type of a variable is really only a documentation, and has no effect at all on the program (if typechecking isn't enabled)! A pointer to a destructed object, will always have the value 0. Global variables in an object can have the type modifier 'static'. This means that they will not be saved in save_object(), or destroyed when in restore_object(). You can also have arrays of any of the types. They are declared with a '*' before the variable name, for example 'int *numbers;' declares 'numbers' to be an array of integers. An array must be initialized before you can index on it. doc/LPC/while010066400000240000044000000005460500564571100127430ustar00mudmud00000420000006WHILE STATEMENT while(expr) statement; While 'expr' evaluates to non 0, execute statement. A 'break' in the 'statement' will terminate the loop. A 'continue' will continue the execution from the beginning of the loop. example: i = 0; while ( i < 10 ) { write( i+" "); i += 1; } Would give the following output: 0 1 2 3 4 5 6 7 8 9 doc/LPC/Lesson1010066400000240000044000000366620503020676500131670ustar00mudmud00000420000006Lesson 1 (Introduction to LPC/Beginning Objects) LPC is a small, object oriented type C language developed by Lars Pensj| for LP-MUD, a Multi-User Dungeon environment under many UNIX systems. Since the premise of this language is based on C, it contains many of the syntactical qualities of C, but also maintains a large set of functions capable of performing many actions inside the game. The objective is to begin to look at LPC as a way of creating objects, rather than specific items, so that new coders can begin to experience the way LPC actually works. Rooms, weapons, monsters, armor, and whatever creation you can think of, even yourself, are objects. LPC allows you to create, modify, delete, and reproduce these objects in almost any manner you choose. This tutorial will guide you through some of the basic principles of LPC, and how to begin to design objects of your own choosing. All objects will be stored in .c files, using the 'ed' editor or some uploading method of your choice. Objects can be created easily, using some of the built-in functions that LPC allows. Here are a few of them; your local LPC site might have more available for you. From here on out, the functions listed below are RESERVED functions, in that they serve a special purpose. They should not be used in any manner except for what their purpose entails. NOTE: Always look in /doc/efun and /doc/lfun for a list of functions to use (These are the functions for 2.4.5...They may or may not be available for you to use.) -------------------- LIST OF FUNCTIONS FOR YOUR MUD ----------------------- add_action add_money add_verb add_weight allocate attacked_by call_other call_out can_put_and_get capitalize cat catch catch_tell clear_bit clone_object command create_wizard creator crypt ctime destruct drop ed enable_commands environment exit explode extra_look extract file_name file_size find_living find_object find_player first_inventory get heal_self heart_beat hit_player id implode init input_to intp living log_file long lower_case ls move_object next_inventory notify_fail objectp parse_command people pointerp present previous_object query_attack query_auto_load query_gender_string query_idle query_info query_level query_money query_name query_npc query_value query_verb query_weight random remove_call_out reset restore_object save_object say set_bit set_heart_beat set_light set_living_name short shout show_stats sizeof sscanf stop_fight stop_wielding stringp tell_object tell_room test_bit this_object this_player time transfer users write write_file --------------------------------------------------------------------------- Let's take an object of any kind, and build it from the ground up. In order to build something trivial, say, a small rose, we need to use certain functions given to us by LPC. To start, we will first need a description of the rose. Two of the functions from the list above that we will need are short() and long(). As a player of LP-MUD, you may recognize these as the verbose and brief descriptions of an object. short() is the short description of an object, and returns the string for that description, whereas the long() is a more verbose description of the object, as is seen when someone 'examines' it. So, back to our rose example, we might have in our rose.c file: short() { return "a small red rose"; } long() { write("This small red rose is very beautiful to look at.\n"); } NOTE: Your idea of style for writing code might be different from mine; it is simply a matter of taste. I usually put all of my one-line LPC code on one line, but you are welcome to use your own style. The two functions above works as follows. Let's take short() for starters. short() is a way of defining a function in LPC, where 'short' is the name of the function, and the information contained between the { and the } is the action list for that function name. short() is a RESERVED function, in that it serves a special purpose. short() returns to the user a string that will contain a brief description of the item. long(), on the other hand, uses write() to tell users about the object. We write out information to the person holding the object, and tell them something about the rose. In this case, we write out that the rose is beautiful to look at. By using write(), we can tell users various things. long() is another RESERVED function, and is called whenever someone 'exa' or 'examine's the object. So now we see how to make the objects with description. But other questions might pop up from this. How do we get the object, or drop the object? Can we set a price on the object? What about its weight? And how to we assign a name to an object? Let's finish off the object, and take a look at what it does. /* Check for a name of the object */ id(str) { return str == "rose"; } /* The short description of the object */ short() { return "a small red rose"; } /* The long description of the object */ long() { write("This small red rose is very beautiful to look at.\n"); } /* Make sure that the object can be picked up */ get() { return 1; } /* Set a weight of 1 on the object */ query_weight() { return 1; } /* Set a value of 10 coins on the object */ query_value() { return 10; } With all of the above code, you have just created a small rose! To complete our understanding of the code, we need to understand what get(), id(str), query_value(), and query_weight() do. get(), as you might guess, simply allows the item to be picked up. Without this get() function, no one can pick up the object, unless they have some object which allows them to do so (dicussion on that will continue later.) So, since get() is a RESERVED function, we can note that by returning 1 to the caller, as we do above, we are saying that yes, someone can pick up this object. id(str) is another RESERVED function, which serves to check if a string passed to id(str) is one of the names of the function. When we say (return str == "rose") what we are really doing is saying that if the string passed to id(str) is "rose", then return 1, or true; otherwise, return 0, or false. It is simply checking to see that the strings, when compared, are identical. In LPC (as well as C), 0 is used to represent a false condition, while 1 (or any other non-zero value) is used to represent a true condition. To add other strings to the comparison, separate them with the 'or' sign (||). For example, this is also a valid setting for the id(str) function: /* Add a name to the object */ id(str) { return str == "rose" || str == "red rose"; } If the caller of id(str) passes "rose" or "red rose", the function will return 1 back to the user, or 0 otherwise. query_weight() and query_value() are two functions which also return values to their caller, for weight and value respectively. We set a weight on the object so that someone carrying too much can't pick up more than possible, and we set a value on the object so that they can sell it for a certain amount of gold coins. In the example above, we have set the value of the object to 10 coins, and the weight on the object to 1. Weights and values will vary according to both your personal tastes, and specifications for your MUD. Once this is saved in a file, we can then update the file, and clone it, and it will appear in our inventory. Assuming that we are in the proper directory, and the code is in a file called 'rose.c', we can do the following: > load rose Ok. > clone rose Ok. > i a small red rose. > exa rose This small red rose is very beautiful to look at. > sell rose You get 10 gold coins. > As you will notice, the ability to create objects has been made very easy by the designers of LPC, and your usage of the RESERVED functions will enhance the objects you create. In order to spice up the rose we have created, we will append these two functions onto the end of our rose.c file: /* Set some initial actions for our object */ init() { add_action("smell_rose", "smell"); } /* smell_rose() -- smell the rose. An assigned action from init() */ smell_rose(str) { if ((!str) || (str != "rose")) { return 0; } write("You smell the sweet fragrance of the rose.\n"); return 1; } These lines will allow us the capability of actually 'smell'ing the object. In that sense, we are now assigning 'actions' to the object. This is an important point, in that everything in LPC revolves around an action of some sort. A person cannot move, walk, talk, breathe, or even exist if actions were not allowed. In the example above, we have added a function called init(). init(), as you will find out in future lessons, is one of the key functions in LPC. It will allow us to define actions, and functions associated to those actions. In the previous example, we have set up add_action("smell_rose", "smell"). "smell_rose" is the name of the function that will perform the write to the user, and "smell" is the action. So, when we type in "smell" in any sense, the add_action() will catch that word, and try to perform some action in the smell_rose() function. Within the smell_rose() function, we need to check for a couple of things. First, we need to make sure that the string that is being sent to the smell_rose() function is actually "rose". If it isn't, then we want to return 0 back to the user, as this function is useless. NOTE: By setting up an add_action() function, we are saying that we catch the word "smell", but we do not pass it to the associated function. So, in other words, when we type in "smell rose", only "rose" goes to smell_rose(). And likewise, if we type in "smell rose", then " rose" goes to smell_rose(). > update rose players/you/rose will be updated next reference. > clone rose Ok. > smell rose You smell the sweet fragrance of the rose. > smell rose What ? > smell What ? > >From the example above, we notice that we must say "smell rose" properly in order to get the function to work. We will deal with how to handle improper typing on the users side later, but for now, we will assume that the user holding the object will not add extra spaces when typing in "smell rose". There you have it! One complete object. Most objects from this point will now become easier to develop, because we are no longer set to the idea of some type of object, but rather an object in general. This will become very clear in the next lesson, when we begin to talk about objects as rooms, and how they will take shape. EXAMPLES TO USE AND STUDY FOR LESSON ONE ------------------------------------------------------------------------------- Example #1 -- A small rose. ------------------------------------------------------------------------------- /* // Rose -- A small rose example // By Matt D. Robinson */ /* Check for a name of the object */ id(str) { return str == "rose" || str == "red rose"; } /* The short description of the object */ short() { return "a small red rose"; } /* The long description of the object */ long() { write("This small red rose is very beautiful to look at.\n"); } /* Make sure that the object can be picked up */ get() { return 1; } /* Set a weight of 1 on the object */ query_weight() { return 1; } /* Set a value of 10 coins on the object */ query_value() { return 10; } /* Set some initial actions for our object */ init() { add_action("smell_rose", "smell"); } /* smell_rose() -- smell the rose. An assigned action from init() */ smell_rose(str) { /* // If the function obtains no string, or the string is not "rose", then // we return 0, or a false condition, to the caller. */ if ((!str) || (str != "rose") || (str != "red rose")) { return 0; } write("You smell the sweet fragrance of the rose.\n"); return 1; } ------------------------------------------------------------------------------- Example #2 -- A pair of cymbals. ------------------------------------------------------------------------------- /* // Cymbals -- Items to clang together // By Matt D. Robinson */ /* Check for a name of the object */ id(str) { return str == "cymbals"; } /* The short description of the object */ short() { return "a pair of shiny cymbals"; } /* The long description of the object */ long() { write("This is a pair of shiny cymbals. Try to 'clash' them together.\n"); } /* Make sure that the object can be picked up */ get() { return 1; } /* Set a weight of 2 on the object */ query_weight() { return 2; } /* Set a value of 40 coins on the object */ query_value() { return 40; } /* Set some initial actions for our object */ init() { add_action("clash_cymbals", "clash"); } clash_cymbals(str) { /* // If the function obtains no string, or the string is not "cymbals", then // we return 0, or a false condition, to the caller. */ if ((!str) || (str != "cymbals")) { return 0; } write("You clash the cymbals together, making a lot of noise!\n"); /* // This is another RESERVED function, say(), which will be discussed // later (if you would like to figure out what it does, then look at // /doc/efun/say.) */ say(this_player()->query_name() + " makes noise with cymbals!\n"); return 1; } ------------------------------------------------------------------------------- Example #3 -- A drinking glass, more advanced, reset(arg) as well as integers also explained in next lesson ------------------------------------------------------------------------------- /* // Drinking Glass -- Drink some good liquid. // By Matt D. Robinson */ /* // Declare the integer drinks */ int drinks; /* Change number on reset (IMPORTANT -- WILL BE COVERED IN LESSON 2) */ reset(arg) { if (arg) return; drinks = 3; return 1; } /* Check for a name of the object */ id(str) { return str == "glass" || str == "drinking glass"; } /* The short description of the object */ short() { return "a drinking glass"; } /* The long description of the object */ long() { write("This is a drinking glass. Perhaps you can 'drink from glass'.\n"); } /* Make sure that the object can be picked up */ get() { return 1; } /* Set a weight of 2 on the object */ query_weight() { return 3; } /* Set a value of 40 coins on the object */ query_value() { return 50; } /* Set some initial actions for our object */ init() { add_action("drink_liquid", "drink"); } drink_liquid(str) { /* // If the function obtains no string, or the string is not "from glass", // then we return 0, or a false condition, to the caller. */ if ((!str) || (str != "from glass")) { return 0; } /* // Check to see that drinks is 0. If so, say the glass is empty. */ if (!drinks) { write("The glass looks empty.\n"); return 1; } /* // Decrement the value of drinks by 1. (Using '--' syntax) */ drinks--; write("You take a sip from the glass, and spin in delight.\n"); return 1; } ------------------------------------------------------------------------------- Please refer to /doc/efun and /doc/lfun for more information about functions mentioned in this documentation, or, ask your local LPC guru for more help. doc/LPC/mapping010066400003740000036000000013710545157370000145070ustar00hubbelysator00000420000006NAME mapping - an associative array SYNTAX construction: ([ index1:data1 , index2:data2 , ... ]) indexing: data1=map[index1] OPERATORS [], + m_delete, mkmapping, mappingp, m_values, m_indices, m_sizeof map_mapping, filter_mapping DESCRIPTION A mapping is basically an array that can be indexed on any type, not not just integers. It can also be seen as a way of linking data (usaully strings) together. It consists of a lot of index-data pairs which are linked togeter in such a way that map[index1] returns data1. It is also possible to set that data by writing map[index1]=new_data1. If you try to set an index in a mapping that isn't already present in the mapping then it will be added or return 0 if you just query it. SEE ALSO arrays TION A mapping is basically an array that can be indexed on any type, not not just integers. It can also be seen as a way of linking data (usaully strings) together. It consists of a lot of index-data pairs which are linked togeter in such a way that map[indedoc/LPC/C_vs_LPC010064400003740000036000000216470547002763500144540ustar00hubbelysator00000420000006 Here's a summary of the biggest differencies between C and Lpc. o Files are never compiled, the source files are read directly into the driver. o There are no such thing as pointers. Read em and weap. o you don't need a main(). In lpc functions are called directly from the driver or when a command is typed. o there are many routines and functions that are hidden in the parser, equivalent to the kernal in UNIX, are basic system calls. o strings are not arrays the way they are in C the are much closer to the strs of BASIC (you remember being forced to learn that trash in High School right?). String functions are implied i.e. you may us the '+' operator to combine strings such that: ack=foo+bar; is equivelen to: strcpy(ack,foo); strcat(ack,bar); Also ack[foo] does not refer to a character, it just return the the integer value of the char foo. o lpc does not use typing. this means that you can do nonsense like this: do_it() { int i; i="ack"; return i; } This is of course not recommendable and the compiler will warn you if you use #pragma strinct_types o the object orientedness of lpc is mostly a illusion all your doing is modifing shared parameters, so don't expect C++ kinds of stuff to work o ++, --, +=, -=, *=, and /= can behave in strange ways, don't use them in very complicated combinations. o All low- to high-level lpc objects are not held togethor like a tradtional program it is closer to writing a module for a large program and using a incremental compilor apon each module independant of all other modules o Lpc is tokinised and interpreted, not compiled. o -> is not used for membership, in fact there are no such thing as structs in lpc. ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: In article <1991Sep21.170218.5667@bronze.ucs.indiana.edu> kellehe@silver.ucs.ini ana.edu (Mike Kelleher) writes: > >Most silly 3.0 questions, I hope there getting more intelligent as we go >allong. Does anybody have a suggestions as a whole for secuirty measures in >3.0? There are several calls like Get_rootid that really bother me. >anyone got some suggestions? The name 'root' has nothing to do with the login name 'root' on unix systems. The only common thing is the spelling. The 3.0 has a new security system, which is not used if -o is specified ! The new security system has been inspired by the Unix way of handling user id (uid) and effective user id (euid), but is not exactly the same. Every object will have a uid and a euid. It is the euid that governs what permissions the object will have. The euid can be changed. The game driver only maintains these two values, represented as strings. It is the master.c that defines what they mean. The values can be any string, but one good way is to use the name of the wizard. When an object wants to access a file, valid_read (or valid_write) will be called in master.c, which will make a decision depending on the path name of the file and the euid. The 2.4.5 game driver called the valid_read in player.c, which was quite bad when there were no "current player". The euid can be changed to only some other values by the object, but always to the value of the uid. This is also defined by the master.c object. There is no set-uid as in Unix, but there is a possibility to transfer your euid to another objects uid. If object A do seteuid(0), then any object B can do export_uid(A) which will set the uid of A to the euid of B. There are some special rules (which I won't list here) which define what happens when an object makes another object become loaded. These rules are currently hard-coded in the game driver, but will probably also be transfered to master.c. In general, a loaded object either gets the same uid as the euid of the loader, or 0 (means no permission). This new security system is in many ways compatible with the old system. The big difference is that when a wizard A makes a room be loaded that was defined by wizard B, then you don't want that room to have uid A. Instead, it will have 0, which means that it must set the euid to something to be able to do any file access. This might seem arduos, but as all new mudlib systems are defined in a hierarchical way, a single line in a single file will (should :-) do it. There are some interesting problems resulting from this. For example, a player.c object can't call save_object() without preparations because it doesn't normally have permission to modifiy player save files. This is solved by talking with the master.c. The player object first sets its euid to 0, then calls a special request function in master.c which will give the player object the "root" uid. Now, the object can do the save, set back to euid 0 and return control to master.c. Of course, the master.c will validate that it is actually the player object, not something made by a wizard. Even if an object has euid "root", it can't access files outside the mudlib directory. This is never ever supposed to be possible. The wizlist modifications are now based on the uid of the object. That means that "root" can show up, as well as "backbone". Lars Pensj| lars@cd.chalmers.se ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: Types declarations Types can be used at four places: Declaring type of global vari- ables. Declaring type of functions. Declaring type of arguments to functions. Declaring type of local variables to functions. Normally, the type information is completely ignored, and can be regarded purely sa documentation. However, when the basic type of a function is declared, then a more strict type checking will be enforced. That means that the type of all arguments must be defined. And, the variables can only be used to store values of the declared type. The function is defined to return an unkown type, as the compiler can't know the type. This value must al- ways be casted (when strict type checking is enabled). Casting a type is done by putting the type name inside a pair of '(' and An example when querying the short description of an object: (string)call_other(ob, "short"); There are two kinds of types. Basic types, and special types. There can be at most one basic type, but any number of special types. The strict type checking is only used by the compiler, not by the runtime. Hence, it is actually possible to store a number in a string variable even when strict type checking is en- abled. Why use strict type checking ? It is really recommended, because the compiler will find many errors at compile time, which will save a lot of hard work. It is in general much harder to trace an error occuring at run time. I recommend, that when a wizard is having problem with an object and wants help, that he first must make all functions have declared types. Basic types An integer 32 bit number. Pointer to an object. An object pointer can mainly be used for two things. Either giving as ar- gument to functions, or used for calling functions defined by that object with its specific instance of variables. An unlimit- ed string of characters. A lot of operators are allowed for strings, like and etc. This type is special, in that it is valid to use in any context. Thus, if everything was declared then the compiler would never complain. This is of course not the idea. It is really only supposed to be used when a variable really is going to contain different types of values. This be avoided if possible. It is good coding practice, to allow a function for example to return different types. This type is only usable for functions. It means that the function will not return any value. The compiler will complain (when type checking is enabled) if the return value is used. Arrays Arrays are declared using a '*' with a basic type. For example, declaring an array of numbers: "int *arr;". Use the type if you want an array of arrays, or a mixed combination of types. Special types There are some special types, which can be given before the basic type. These special types can also be combined. When using spe- cial type before an statement, all symbols defined by inheritance will also get the special type The only special case is symbols, which can not be redefined as in a statement. Can be given for both functions and variables. Functions that are in object can not be called through from another object. And, they are not ac- cessible to any object that inherits This special type behaves different for variables and functions. It is similar to for functions, in that they can not be called from other objects. variables will be neither saved nor restored when calling or A function defined as will always be accessible from other objects, even if is used. All symbols defined as can not be redefined by inheritance. They can still be used and accessed as usual. ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: doc/LPC/profezzorn_has_the_word010064400003740000036000000243320547003000500200030ustar00hubbelysator00000420000006 ***** Lpc, the stuff that dreams are made of ***** A great man once said "I am not a great man, I stand on the shoulders of giants." Another man said that in the computer business we stand on eachothers feet. I'd like to think that is not so and therefor I share some of my experiences here. Hacking There is a hack for every problem, and you can quote me on that. However there is a right and a wrong way to solve a problem. When the problem is caused by the mudlib, the right way is of course to change the mudlib, this may seem hopeless, but don't dispair, the archwizards are there to make the changes for you. Arches often equals lazy though, so you better have ample motivation for your change. Security Remember that anyone can call any functions that you haven't declared as static. Also remember that static functions can't be called by any other objects, not even your own or call_out:s. ALso remember that arrays are shared, that means that if you return an array from a function its contents can be modifyed from another object. Lpmud is never more safe than it's most unsafe object. Wizards beware Making good armours and weapons is probably the best way of ensuring that players will visit your area, but beware, too good stuff will invariably cause some sort of inflation in weapons and armours. You'll become inpopular among the older and higher wizards. Your chanses of advancing beyond wizardhood may reduce. If you still want to make a bunch of really good weapons then make sure that they are _very_ hard to get and that your area is inpeckable, variated and full of surprises. That way noone can complain and you can motivate your good weapons. Administrators beware Some of your wizards _will_ ignore the warning above, so what the heck, giv'em hell for it. There is of course another way to stop an evil trend: Example, someone dreams up an 'autobow' command, and suddenly everybody goes around bowing to everybody. As an administrator you can either perish by this evil, useless and extremly utter command or you can make your own generalized 'auto' command and put it in the playerobject. Now all the novelty with autobow is lost and with any luck, the trend will die all by itself. If not, well, nobody is perfect. Things not to do Don't do this, or you'll become very, very inpopular: o throw(0); It crashes most lpmuds. o destruct(this_object()); or destruct(this_player()); in init() It crashes some lpmuds. o explode() with a user-typed second argument can crash the mud. o Never do errors in auto_loading objects. Players can loose their commands. o Errors in exit() will stop people from leaving and that's not a pretty sight. o Don't trust find_call_out(), it can return -1 even if there are pending call_outs. o Never make super-monsters, you have no idea how usual it is that they escape and kill players. o Avoid putting \ at the end of strings in objects that use save_object(). It won't be able to restore that string on many muds. o In native mode, if an objects euid is zero it is not possible to call_out to other objects if you don't make absolutely sure that the other object is loaded first. It gives the error 'Illigal to load object with euid zero'. o Never trust the players not to do something, sooner or later they will anyway. o Be careful with call_outs if they multiply they stop the mud. o Be careful with inherit, if you inherit an object that inherit your object the mud stops in an eternal loop. o Don't use the efuns ed() & shout() without a this_player() o On some muds it's possible to catch() too long evaluation and then continue as nothing has happened. This can of course cause an eternal loop. o In native mode it is possible to initialize variables like this: int a=12; or int b=destruct(this_object()); Don't use the latter example, it crashes most muds. o Watch out for too deep recursions, it can actually crash the driver. o The preprocessor isn't bugfree either, division by zero or modulo by zero in #if will crash most drivers. o Don't make it possible to enter your workroom from the game, it's easy to forget superweapons etc. in the workroom. o Everybody loves to make wiztools, but think first, maybe your particular wiztool is already made. o explode() is not the inverse of implode(), rememeber that. o Never remember players by their playerobject, always use ob->query_real_name() and find_player() to remember the player as the playerobject may change. o Watch out with inherit, if your object inherit two objects which in their turn inherit the same object. You will have two sets of some variables. o Remember that lpmud is singel-threaded, that mean that if you succseed in keeping the cpu for yourself the mud will stop. o Watch out when using say() and call_out(), call_out saves this_player in all modern lpmuds, therefor say() will appear where this_player is even he/she has wandered across the whole game during the delay. There are lots of other things you shouldn't do, but with any common sense you won't make _every_ mistake in the book :) If you don't belive me, go ahead, make a fool out of yourself. Tips & trix o Mappings are sorted, for all types but integers this is uninportant, as they are sorted in a strange order. However, integers are sorted in numerical order and it's much faster than sort_array() o add_action() has a flag that makes it possible to catch all commands beginning with a certain string. add_action("com","",1) is a special case thogh, it catches _all_ commands typed by a player. Nifty, but dangerous, beware. o input_to() is another way of catching all the input from a player, but if the command is prepended with a ! it will still be interpreted like a normal command. o implode(explode(" alpha beta "," ")," ")=="alpha beta" Remember and use. o Don't get carried away and make zillions of rooms without anything interesting in them, mortals invariably find this boring. o Try not to copy code, use inherit instead, that is much more memory-efficient. o Avoid too much calling between objects, it makes the code unreadable and slow. If you want to split the code into lots of files, use inherit. o Don't take any responsibily youself, always let some higher wizard check your obejects so he can take part of the blame. o enable_commands() changes this_player() to this_object() use with care. o if simul_efun has defined an efun in a way you don't like, you can use efun::function() instead. Questions and answers about lpc. Q: How do I make a weapon that hits harder against some types of monsters. A: Here is an example of an weapon that has the upper hand on orcs. int weapon_hit(object attacked) { if(attacked->query_race()=="orc") { write("Ziing!\n"); return 10; /* This number is added to the damage */ }else{ return ; } } Q: Can I use ANSI codes to make objects look green? A: Yes, you can, No are not allowed to do it. Some muds will even filter out your escape sequences. Q: How do I know if an object is in the same room as my object? A: if(environment()==environment(the_object))) Q: How do I let another wizard read my files? A: The only way that works on all muds is the directory /open. Everybody can read and write there. Q: How do I know the filenames to the rooms when I use goto? A: You don't, you have to go there and check it out first. Q: How do I change a character within a string? A: You don't, you have to build a new string like this: string char; int pos; new_string=old_string[0..pos-1]+char+old_string[pos+1,10000]; Note that char is a string, not an int or char or anything like that. Q: How do I transform an ascii value to a character in a string? A: In standard lpc there is no way of doing this but to have an array with all the strings in and index it on the number, but some lpmuds have an efun sprintf, and then you can do like this: str=sprintf("%c",value); See the efun chapter for further details. Q: How do I make my monsters wander around without letting them leave my area? A: The easiest way is to put a function in your monsters that identifies them, let's say query_is_profezzorns_monster() and let this function return 1, then you put the following code in all your rooms that leads out: int no_way() { return 1; } void init() { ::init() if(this_player()->query_is_profezzorns_monster()) { /* Do this for every direction that leads out. */ add_action("no_way","south"); } } Some mudlibs has blocking function in their standarobjects and those functions are probably better, however, this solution should work almost everywhere. Q: Why doesn't the driver tell _me_ about the error, it just winds up in lpmud.log? A: Somewhere on the way to the error this_player() was changed to a monster, the most usual case is when enable_commands() is executed in the creation of a monster. Q: Are there any real manual or tutorial about lpc? A: If you don't count this document, then the answer is no. Q: Can I redefine an efun and still use the real efun? A: Yes, here is an example of how explode _should_ work: string my_extract(string a,int b,int c) { if(b<=c && b>-1 && c is either a single expression or function call or it's a block of statements enclosed in { } An expression is considered false in lpc _only_ if it es equal to the number zero, in all other caseses it is consider true. ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: STATEMENT if - else - run on condition SYNOPSIS if( expression ) or if( expression ) else DESCRIPTION If is the simplest of all control structures, in the first form it runs the statement if the expression is true and in the second form it runs the first statement if the expression is true and the second if it is false. ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: STATEMENT for - general loop statement SYNOPSIS for ( expression1 ; expression2 ; expression3 ) DESCRIPTION the above statement is exactly equal to: expression1; while( expression2 ) { expression3; } EXAMPLE int e; for(e=0;e<10;e++) write(e+"\n"); SEE ALSO while ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: STATEMENT while - execute a statement while an expression is true SYNOPSIS while( expression ) DESCRIPTION While runns the statement until the expression is false. The expression is evaluated once for every loop. If the expression is false the first time the statement is never executed. SEE ALSO for, do - while ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: STATEMENT do - while - execute a statement while an expression true SYNOPSIS do while ( expression ); DESCRIPTION do - while only differs from the ordinary while-loop in that it does _not_ evaluate the expression until after the statement has been executed once. Thus it always runs the statement once. SEE ALSO do - while ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: STATEMENT switch - case - Complicated conditional statement SYNOPSIS switch( expression ) { case constant1: case constant2: break; default: } DESCRIPTION Switch evaluates the expression give and then executes one or more statement accordingly to the result. If the result is equal to constant1 then statement1 will be executed, please observe that the second case-statement dos _not_ abort the execution in any way instead statement2 will also be executed. After that break will cause execution to continue after the after the last } in the switch statement. If the result is equal to constant2 only statement2 will be executed. In all other cases statement3 is executed because it is 'default'. Please note that the expression and constant can be either integers or string, but they can _not_ be mixed in the same switch-statement. ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: STATEMENT break - break a loop or switch SYNOPSIS break; DESCRIPTION Break jumps directly out of any loop or switch statement, it is a very vital part of every switch statement. SEE ALSO do - while, while, for, switch ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: STATEMENT continue - continue a loop SYNOPSIS continue; DESCRIPTION Continue work similarly to break only it does't finish the loop, it just aborts the rest of this turn in the loop. BUGS Don't use it in conjunction with the switch-statement. SEE ALSO do - while, while, for ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: STATEMENT return - return from a function SYNOPSIS return; or return expression; DESCRIPTION Return jumps directly out of a function returning the given value to the calling function. If no expression is given, 0 is returned. ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: doc/examples/004077700000240000044000000000000555721640400131155ustar00mudmud00000420000006doc/examples/apple_juice.c010066600000240000044000000003330524431160700155270ustar00mudmud00000420000006inherit "obj/soft_drink"; reset(arg) { ::reset(arg); if(arg) return; name="apple juice"; alt_name="juice"; short_desc="a bottle of apple juice"; long_desc="It looks very refreshing.\n"; strength=5; } doc/examples/apple_cider.c010066600000240000044000000003560524431157400155260ustar00mudmud00000420000006inherit "obj/alco_drink"; reset(arg) { ::reset(arg); name="apple cider"; alias="cider"; short_desc="a bottle of apple cider"; long_desc="Maybe you should drink it.\n"; drinking_mess=" h{fver en cider.\n"; strength=10; } doc/examples/forest1.c010066600000240000044000000011170524431162300146310ustar00mudmud00000420000006#include "room.h" object rabbit; #undef EXTRA_RESET #define EXTRA_RESET extra_reset(); extra_reset() { if (!rabbit) { rabbit=clone_object("obj/monster"); rabbit->set_name("rabbit"); rabbit->set_level(2); rabbit->set_wc(3); rabbit->set_hp(25); rabbit->set_short("a little rabbit"); rabbit->set_long("A little rabbit running around your feet.\n"); move_object(rabbit,this_object()); } } TWO_EXIT("room/forest1","south", "room/forest2","west", "In the forest", "You are walking in the forest.\n"+ "Birds are singing and the wind plays in the trees.\n",1) doc/examples/pc.c010066400000240000044000000003210526205214400136420ustar00mudmud00000420000006 init() { add_action("pc","pc"); } pc(str) { int i; mixed *ret; i = parse_command(str, environment(this_player()), "'take' / 'get' %i",ret); write(sprintf("I: %d\n %O\n", i , ret)); } doc/examples/apple_pie.c010066600000240000044000000012470526752740000152170ustar00mudmud00000420000006/* just an example PP 921015 */ inherit "obj/food"; reset(arg) { if(!arg) { set_name("apple pie"); set_alias("pie"); set_alt_name("an apple pie"); set_short("an apple pie"); set_long("A creamy and tasty apple pie.\n"); set_value(100); set_weight(1); /* this tells how stuffed you will be */ set_strength(10); /* this is how much the food will heal */ set_heal(20); /* message when eating the pie */ set_eater_mess("You slowly enjoy the apple pie.\n"); /* message others gets when you eat the pie */ set_eating_mess(" eats some delicius apple pie.\n"); } } doc/examples/room1.c010066400006540000036000000017530553017515700162450ustar00celebornlysator00000420000006inherit "room/room"; reset(arg) { object b_board; if (arg) return; if(!(b_board=present("board"))){ move_object(b_board=clone_object("obj/bboard"),this_object()); b_board->set_name("doc/examples/demoboard"); } set_light(1); short_desc = "First example room"; no_castle_flag = 0; inorout = 1; long_desc = "Example room 1.\n"+ "As you look about, you realize that you have entered a cozy exampleroom\n"+ "There is a board here, and mortals can echo and emote in this room (see \n"+ "rule 3.14 about emotes).\n"; dest_dir = ({ "/doc/examples/room2","north", });} init (arg) { ::init(arg); add_action("emote","emote"); add_action("emote",":"); add_action("ech","echo"); return 1; } emote(arg){ say (capitalize(this_player() -> query_name())+" "+arg+"\n"); write("You "+arg+"\n"); return 1; } ech(arg){ say (arg+"\n"); write ("You echo: "+arg+"\n"); return 1; } doc/examples/room2.c010064400003050000036000000020320553471037100155150ustar00matcalysator00000420000006inherit "room/room"; reset(arg) { if (arg) return; /* Set up once is enough. When the room is created, reset() is called with argument 0. Thereafter the argument is non-zero. */ set_light(1); no_castle_flag = 1; the_realm = "NT"; short_desc = "A small example room"; long_desc = "This is an example room by Brom. It has a few exits,\n"+ "and some of them are blocked for mortals and one even\n"+ "for normal wizards. Guess which?\n"; dest_dir = ({"room_shop", "north", "room/adv_inner", "south", "room/sea", "out", "room/sea_bottom", "down", "room/inner3", "arches" }); blocked_exits = ({ 0, "check_wiz", 0, 0, "check_arch"}); /* Blocked_exits has one item for every exit until the last that need a check. */ } check_wiz() { if ((this_player()->query_level())<20) return 1; /* Blocked */ /* No return is equal to return 0 in which case its NOT blocked. */ } check_arch() { if ((this_player()->query_level())<23) return 1; /* Blocked */ } doc/examples/room3.c010064400003050000036000000034500553471171500155260ustar00matcalysator00000420000006inherit "room/room"; reset(arg) { /* Make dwarf if there isn't one here. */ if (!present("dwarf", this_object())) make_dwarf(); if (arg) return; /* Set up once is enough. When the room is created, reset() is called with argument 0. Thereafter the argument is non-zero. */ set_light(1); no_castle_flag = 1; the_realm = "NT"; short_desc = "A small example room"; long_desc = "This is an example room by Brom. It has a few exits,\n"+ "and some of them are blocked for mortals and one even\n"+ "for normal wizards. Guess which?\n"+ " Also, one is blocked by a dwarf.\n"; dest_dir = ({"room_shop", "north", "room/adv_inner", "south", "room/sea", "out", "room/sea_bottom", "down", "room/inner3", "arches" }); blocked_exits = ({ 0, "check_wiz", "dwarf_here", 0, "check_arch"}); /* Blocked_exits has one item for every exit until the last that need a check. */ } check_wiz() { if ((this_player()->query_level())<20) { write("Only immortals can do that.\n"); return 1; /* Blocked */ } write("You go south.\n"); /* No return is equal to return 0 in which case its NOT blocked. */ } dwarf_here() { if (present("dwarf", this_object())) { write("The dwarfs says: I won't let YOU pass.\n"+ "You might drown out there, you know.\n"); return 1; } write("You go down.\n"); } check_arch() { if ((this_player()->query_level())<23) { write("Only the 23++ can do that.\n"); return 1; /* Blocked */ } write("You go the arches way.\n"); } make_dwarf() { object dwarf; dwarf = clone_object("obj/monster"); dwarf -> set_name("dwarf"); dwarf -> set_level(1); dwarf -> set_short("A small dwarf"); dwarf -> set_long("An old and shrunken dwarf.\n"); move_object(dwarf, this_object()); } doc/efun/004277500004030000044000000000000556520774300127135ustar00axel_fmud00000420000006doc/efun/Nonexistent/004077100004030000044000000000000531572511100152065ustar00axel_fmud00000420000006doc/efun/Nonexistent/break_string010066400004030000044000000011240514061503000175740ustar00axel_fmud00000420000006NAME break_string - break a string at regular intervals SYNOPSIS string break_string(string str|int foobar, int len, void|int indent|string indent) DESCRIPTION This function breaks a continous string without newlines into a a string with newlines inserted at every `len':th character. If `indent' is defined and is given as an integer, `indent' number of spaces are inserted after every newline. If `indent' is a string that string is inserted before every newline. If the first argument is an integer, the function simply returns 0. SEE ALSO implode, explode, sprintf ring(string str|int foobar, int len, void|int indent|string indent) DESCRIPTION This function breaks a continous string without newlines into a a string with newlines inserted at every `len':th character. If `indent' is defined and is given as an integer, `indent' number of spaces are inserted after every newline. If `indent' is a string that string is inserted before every newline. If the first argument idoc/efun/Nonexistent/exclude_array010064400004030000044000000003570510775726500200020ustar00axel_fmud00000420000006mixed *exclude_array(arr,from,to) mixed *arr; int from; int to; Returns an array with the given elements excluded. Indexes are numbered 0- If 'arr' is not an array or indexes are outside the limits of 'arr', then 0 will be returned. doc/efun/Nonexistent/get_localcmd010066400004030000044000000005260514061504000175450ustar00axel_fmud00000420000006NAME get_localcmd - return an array of an object's locally define commands SYNOPSIS string *get_localcmd(object ob|int foobar) DESCRIPTION This function returns an array of all local commands added to the object `ob'. If no argument is givent `this_object()' is used by default. If an integer is given as argument, 0 is returned. doc/efun/Nonexistent/object_time010066400004030000044000000003500514061504600174150ustar00axel_fmud00000420000006NAME object_time - return the time when the object was created SYNOPSIS int object_time(object ob) DESCRIPTION Gives the time in seconds since whatever 1970, when the object was created. SEE ALSO time, ctime, file_time doc/efun/Nonexistent/m_indexes010066400004030000044000000004660514061504200171100ustar00axel_fmud00000420000006NAME m_indexes - return the domain of a mapping SYNOPSIS mixed *m_indexes(mapping map|int foobar) DESCRIPTION This function returns the domain, the `index' part, of a mapping as an array. If an integer is given as argument, 0 is returned. SEE ALSO mkmapping, m_values, m_sizeof, m_delete, mappingp doc/efun/Nonexistent/map010066400004030000044000000013700514061504300157060ustar00axel_fmud00000420000006NAME map - map a function onto each element of an array or a mapping SYNOPSIS mixed *map(int foobar|mixed *array|mapping map, string map, object ob|string ob, mixed extra) DESCRIPTION This function is used to process all items in an array or a mapping through a specific function. The resulting array or mapping contains whatever was returned by the `map' function. If an integer is given as argument instead of an array or mapping, 0 is returned. `map' is simply given as a string with the name of the processing function to use. `ob' is either the actual object that contains the filter function or a path to to the object. `extra' can be any argument that you would like the `map' function to recieve as argument. SEE ALSO filter doc/efun/Nonexistent/people010066400004030000044000000002540475505123300164230ustar00axel_fmud00000420000006void people() A function that will list all interactive players, and some info about them. This function is normally connected to the "people" command, that wizards have. doc/efun/Nonexistent/process_value010066400004030000044000000012760514061504700200140ustar00axel_fmud00000420000006NAME process_value - give a value from a described function call SYNOPSIS mixed process_value(string calldescription) DESCRIPTION Get the replacement of one syntactic pattern. The pattern is on the form: "function[:filename][|arg1|arg2....|argN]" The returned value can be of any type. Note that both object and arguments are marked optional with the brackets and that the brackets are not included in the actual pattern. SEE ALSO process_string CAVEAT This is usually used to support 'value by function call' in the mudlib. It is wise to set the effuserid of the object to 0 before using process_value as any function in any object can be called with almost any arguments. doc/efun/Nonexistent/rename010066400004030000044000000011640514061505200164010ustar00axel_fmud00000420000006NAME rename - rename a file or move a subdirectory SYNOPSIS int rename(string frompath, string topath) DESCRIPTION Renames the file 'frompath' to the name 'topath'. This is functionally identical to copying the file 'frompath' to 'topath' and the remove 'frompath'. If 'topath' exists and is a file, it is removed. If 'topath' is a directory then move the file to that directory. If 'frompath' is a directory then move the entire subdirectory to 'topath'. Return 1 if UNSUCCESSFUL. SEE ALSO rmdir, rm, mkdir BUGS It should be changed to return 0 for unsuccessful move as all other efuns of this kind does.doc/efun/add_action010066400004030000044000000016630524767664500147340ustar00axel_fmud00000420000006NAME add_action - add an action to an object SYNOPSIS void add_action(string function, string verb, void|int part) DESCRIPTION This function adds an action to the `living' object that the command is run by. `function' is the function name that is to be run when the command verb `verb' is given. If `part' is defined (not 0) only a part of the given verb need to be given for the command to work For example: add_action("foobar", "tele", 1); will match on "tele" or "teleledning" while the whole verb "teleledningsanka" will have to be given for this expression: add_action("foobar", "teleledningsanka", 0); or add_action("foobar", "teleledningsanka"); NOTA BENE For this action to be added to an object, the object must be `living', i.e. the function "enable_commands()" must have been performed in the object prior to the "add_action()". SEE ALSO disable_commands, enable_commands, living, _query_action, query_verb doc/efun/all_inventory010066400004030000044000000004540525420117400155040ustar00axel_fmud00000420000006NAME all_inventory - return the contents of an object SYNOPSIS object *all_inventory(object ob) DESCRIPTION This function returns an array of the objects contained in `ob'. If `ob' is not specified "this_object()" is used by default. SEE ALSO first_inventory, next_inventory, deep_inventory doc/efun/allocate010066400004030000044000000003100514061502700143720ustar00axel_fmud00000420000006NAME allocate - create an array of n elements SYNOPSIS mixed *allocate(int n); DESCRIPTION This function returns an empty array of `n' elements. All values in the array are initialized to 0. doc/efun/first_inventory010066400004030000044000000002200525420102100160410ustar00axel_fmud00000420000006object first_inventory(ob) object ob; Get the first object in the inventory of "ob". See also: next_inventory, all_inventory, deep_inventory doc/efun/call_other010066400004030000044000000022510524770020700147330ustar00axel_fmud00000420000006NAME call_other - call a function in another object SYNOPSIS mixed call_other(object ob|string ob, string func, ...) DESCRIPTION This function is used to call another function in a given object. If the object `ob' is given as a string call_other tries to find it using "find_object()". If not found call_other tries to load it, otherwise the object pointer is used directly. If the object is given as a string, the absolute path to the object must be given. `func' should simply be the name of the function to be called. Any number of arguments to the function can be added to the call. Example: name = (string)call_other(find_player("commander"), "query_real_name"); access = (int)call_other("/secure/master", "valid_read", "/DONE", "commander", "my_func"); "call_other()" can also be performed using "->" with this syntax: name = (string)find_player("commander")->query_real_name(); access = (int)"/secure/master"->valid_read("/DONE", "commander", "my_func"); NOTA BENE The default type of "call_other()" is unknown, but as shown in the examples above it is always possible to cast to a type of your own choosing, if nothing else only to aid memory. doc/efun/call_out010066400004030000044000000012150524767765100144400ustar00axel_fmud00000420000006NAME call_out - delayed execution of a function SYNOPSIS void call_out(string func, int delay, void|mixed arg) DESCRIPTION With this function you can delay the call of a name function `func' for `delay' seconds. If `arg' is specified it is passed as an argument to the function. The value of "this_player()" in the function will be the same as it was when "call_out" was called. NOTA BENE The smallest time-unit in the game is a heartbeat (2 seconds). This means that even though you might specify an odd-second delay, it will still be executed on a full heartbeat (even second). SEE_ALSO call_out_info, find_call_out, remove_call_out doc/efun/capitalize010066400004030000044000000003230524770044700147500ustar00axel_fmud00000420000006NAME capitalize - make the first letter of a string uppercase SYNOPSIS string capitalize(string str) DESCRIPTION With this command the first letter of a string is made upper-case. SEE ALSO lower_case doc/efun/cat010066400004030000044000000005000514061503100133510ustar00axel_fmud00000420000006NAME cat - print part of a file on the screen SYNOPSIS int cat(string file, void|int start, void|int len) DESCRIPTION This functions prints a file or a part of a file on to the screen. `file' is the path the file, `start' (if given) is the starting line and `len' (if given) the number of lines to be printed doc/efun/cindent010066400004030000044000000003150514061503100142320ustar00axel_fmud00000420000006NAME cindent - indent and format an LPC program source file SYNOPSIS int cindent(string path) DESCRIPTION Indents and formats the named file in the same way as the UNIX program indent. SEE ALSO ed doc/efun/clear_bit010066400004030000044000000003300514061503200145300ustar00axel_fmud00000420000006NAME clear_bit - clear a bit in a string bitfield SYNOPSIS string clear_bit(string bitstring, int pos) DESCRIPTION This function will clear the indicated bit in the given bitstring. SEE ALSO set_bit, test_bit doc/efun/clone_object010066400004030000044000000002510524770615600152540ustar00axel_fmud00000420000006NAME clone_object - clone an object SYNOPSIS object clone_object(string path) DESCRIPTION This funciton clones an object indicated by the path. SEE ALSO destruct doc/efun/command010066400003050000044000000016760556054534000141020ustar00matcamud00000420000006NAME command - execute a command in a living object SYNOPSIS int command(string command, object obj) DESCRIPTION With this function an object can command itself to perform an action that previously has been added with add_action. The given string `command' should be on the same format as if it had been given from the command line. The object 'obj' is optional; default is this_object(). `command()' returns the number eval-cycles that was used to perform the command, or 0 if it proved impossble due to eval-cost. A force function can then simply be implemented in the player- object like this: nomask int /* We'd rather not have anyone shadowing this function */ force_player(string command) { if (ok_to_force()) if (command(command)) return 1; return 0; } The function `ok_to_force()' can then determine if it is permitted for the person that tries to execute the command to force the player or not. doc/efun/crypt010066400004030000044000000004230514061503200137500ustar00axel_fmud00000420000006NAME crypt - encrypt a string SYNOPSIS string crypt(string data, string key|int random) DESCRIPTION This function encrypts the given `data' using the given encryption `key'. If the the second argument is given as an integer, the encryption is done with a random key. doc/efun/ctime010066400004030000044000000002400514061503300137060ustar00axel_fmud00000420000006NAME ctime - convert time stamp to string SYNOPSIS string ctime(int time) DESCRIPTION This funtion converts the given `time' to a string. SEE ALSO time doc/efun/deep_inventory010066400004030000044000000006100525420116600156440ustar00axel_fmud00000420000006NAME deep_inventory - recursive inventory of an object SYNOPSIS object *deep_inventory(object ob) DESCRIPTION This function returns a list of the all the objects contained by the given `object' including the objects contained in other objects. The inventory of `object' is searched recursively in order to produce this list. SEE ALSO all_inventory, first_inventory, next_inventory doc/efun/destruct010066400004030000044000000002330524770741000144550ustar00axel_fmud00000420000006NAME destruct - destruct an object SYNOPSIS void destruct(object ob) DESCRIPTION This function destroys the indicated object. SEE ALSO clone_object doc/efun/disable_commands010066400004030000044000000004630514061503300161000ustar00axel_fmud00000420000006NAME disable_commands - set an object `non-living' SYNOPSIS void disable_commands() DESCRIPTION With this function an object is made `non-living'. This disables the adding of commands from entering rooms or objects that move into the inventory of this object. SEE ALSO enable_commands, move_object doc/efun/ed010066400004030000044000000006500524770771200132200ustar00axel_fmud00000420000006NAME ed - edit a file SYNOPSIS void ed(void|string path, void|string exit_func) DESCRIPTION With this function an interactive object (a player) can edit a file with the given path. If no `path' is given, the file of your's that last had an error in it is taken. `exit_func' is called on completion of the command. This function is subject to the rules given by the functions `valid_read()' and `valid_write()'. doc/efun/enable_commands010066400004030000044000000004470514061503400157260ustar00axel_fmud00000420000006NAME enable_commands - set an to be object `living' SYNOPSIS void enable_commands(void) DESCRIPTION This function makes an object `living'. It will now pick up commands defined by `add_action()' and can listen to what is said in its environment. SEE ALSO disable_commands, move_object doc/efun/environment010066400004030000044000000006170524771004700151720ustar00axel_fmud00000420000006NAME environment - find the environment of an object SYNOPSIS object environment(object ob) DESCRIPTION This function returns the object that has `ob' in its inventory, the environment of `ob'. If no object is given as argument, `this_object()' is used by default. If no environment to `ob' is found, 0 is returned. SEE ALSO all_inventory, deep_inventory, first_inventory, next_inventory doc/efun/exec010066400004030000044000000015440524771027000135500ustar00axel_fmud00000420000006NAME exec - connect a socket to a new object SYNOPSIS int exec(object new, object old) DESCRIPTION This function is used to shift an interactive user betwen two objects. The function `valid_exec()' is called in `/secure/master.c' with the calling object as argument. If `valid_exec()' accepts the calling object the interactive user is switched from the object `old' to `new'. NOTA BENE It is very easy to become confused when writing the code that uses this efun. All the internal variables like `this_player()' or `this_object()' remain unchanged, it is just the user that is switched between the objects. CAVEAT This is one of the greater threats to security in the system. Unless the use is this efun is rigorously restricted anyone can become arch or keeper. FRIENDLY ADVICE Don't do this unless you're damn certain you what you are doing. doc/efun/explode010066400004030000044000000007770524771116500142770ustar00axel_fmud00000420000006NAME explode - explode a string into subparts SYNOPSIS string *explode(string str, string break_string) DESCRIPTION This function returns an array of the strings resulting from dividing `str' into the component strings separated by `break_string'. If `break_string' is given as "", `str' is returned. All leading appearances of `break_string' is removed and so is one at the end if existing. If `str' only consist of repeating occurances of `break_string', 0 is returned. SEE ALSO implode, sprintf doc/efun/INDEX010066400004030000044000000103530524767516600135070ustar00axel_fmud00000420000006/* * This file specifies types and arguments for efuns. * An argument can have two different types with the syntax 'type1 | type2'. * An argument is marked as optional if it also takes the type 'void'. */ /* locally added efuns */ void _destruct(object); /* Destruct object without calling quit() et al */ void _disconnect(object); /* Close TCP/IP link to this object */ int _isclone(object); /* Is the object a clone? */ mixed *_query_action(object|string, void|string); /* Get info about actions */ string _query_ident(void|object); /* Get identification on player */ int _syslog(string); /* Log a message in the lpmud.log file */ /* standard efuns */ void add_action(string, void|string, void|int); void add_verb(string); void add_worth(int, void|object); void add_xverb(string); object *all_inventory(object default: F_THIS_OBJECT); mixed *allocate(int); mixed assoc(mixed, mixed *, mixed|void, mixed|void); void break_point(); unknown call_other(object|string, string, ...); void call_out(string, int, void|mixed); mixed *call_out_info(); string capitalize(string); int cat(string, void|int, void|int); int cindent(string); string clear_bit(string, int); object clone_object(string); int command(string, void|object); string crypt(string, string|int); /* An int as second argument ? */ string ctime(int); mixed debug_info(int, mixed|void, ...); object deep_inventory(object); void destruct(object); void disable_commands(); void ed(void|string, void|string); void enable_commands(); object environment(void|object); int exec(object, object); string *explode(string, string); string extract(string, void|int, void|int); string file_name(object default: F_THIS_OBJECT); int file_size(string); mixed *filter_array(mixed *, string, object|string, void|mixed); int find_call_out(string); object find_living(string); object find_object(string); object find_player(string); string function_exists(string, object default: F_THIS_OBJECT); string implode(string *, string); void input_to(string, void|int); mixed insert_alist(mixed, mixed, ...); int interactive(object default: F_THIS_OBJECT); mixed *intersect_alist(mixed *,mixed *); int intp(mixed); int living(object); void localcmd(); void log_file(string, string); string lower_case(string); string *get_dir(string); mixed *map_array(mixed *, string, object|string, void|mixed); int member_array(mixed, mixed *); int mkdir(string); void move_object(object|string, object|string); void notify_fail(string); int objectp(mixed); mixed *order_alist(mixed *, void|mixed *, ...); int pointerp(mixed); object present(object|string, void|object); object previous_object(); string process_string(string); string query_host_name(); int query_idle(object); string query_ip_name(void|object); string query_ip_number(void|object); string query_load_average(); object query_snoop(object); string query_verb(); int random(int); string read_bytes(string, void|int, void|int); string read_file(string, void|int, void|int); string *regexp(string *, string); int remove_call_out(string); int restore_object(string); int rm(string); void rmdir(string); string rusage(); void save_object(string); void say(string|mixed *, void|object|object *); string set_bit(string, int); int set_heart_beat(int); int set_light(int); void set_living_name(string); object shadow(object, int); void shout(string); void shutdown(); int sizeof(mixed *); object snoop(void|object, void|object); mixed *sort_array(mixed *,string,object|string default: F_THIS_OBJECT); int stringp(mixed); int strlen(string); void swap(object); /* Only used for debugging */ void tail(string); void tell_object(object, string); void tell_room(object|string, string, void|object *); int test_bit(string, int); object this_object(); object this_player(void|int); void throw(mixed); int time(); int trace(int); string traceprefix(string|int); mixed *unique_array(mixed *, string, void|mixed); object *users(); string version(); void wizlist(void|string); void write(mixed); int write_bytes(string, int, string); int write_file(string, string); string *inherit_list(object default: F_THIS_OBJECT); string creator(object); int transfer(object, object|string); string create_wizard(string, void|string); object first_inventory(object|string default: F_THIS_OBJECT); object next_inventory(object default: F_THIS_OBJECT); doc/efun/extract010066400004030000044000000012200524771153000142650ustar00axel_fmud00000420000006NAME extract - extract a subpart of a string SYNOPSIS string extract(string str, void|int start, void|int to) DESCRIPTION Get a subpart of a string. Both 'start' and 'to' is a position in 'str'. If the position(s) is negative then it is counted from the end of the string. If the 'start' is bigger than 'to' then an empty string is returned. An empty string is also returned if the subpart is outside the string in its entirety. Both positions is optional. If no position is given then 'str' is returned. If only 'start' is given then a string from 'start' to the end of 'str' is returned. SEE ALSO capitalize, lower_case, explode, implode doc/efun/file_name010066400004030000044000000006250514061503500145350ustar00axel_fmud00000420000006NAME file_name - find the filename of an object SYNOPSIS string file_name(object ob) DESCRIPTION This function gives the filename of an object concatenated with a possible instance number. This typically is a string on the form "/std/weapon#423". Instance numbers are unique for all objects in the game. If a filename has no instance number it is the 'master object' and not a 'cloned copy'. doc/efun/file_size010066400004030000044000000004640524771175500146060ustar00axel_fmud00000420000006NAME file_size - return the size of a file SYNOPSIS int file_size(string path) DESCRIPTION This function returns the size, in bytes, of an existing file. If the file does not exist, file_size returns -1. If the file is actually a directory and not a file, -2 will be returned. SEE ALSO file_name doc/efun/_isclone010064400004030000044000000003320521612140000143720ustar00axel_fmud00000420000006int _isclone(object) Returns 1 (true) if the object is a clone, else returns 0. This can be used to differentiate between clones and master objects without having to look at the file name. This is also much faster. doc/efun/_syslog010066400004030000044000000001060524767624000143040ustar00axel_fmud00000420000006int _syslog(string) Log a message in the muds system log, /lpmud.log doc/efun/find_call_out010066400004030000044000000004270525031524700154240ustar00axel_fmud00000420000006NAME find_call_out - find the remaining call_out time of a function SYNOPSIS int find_call_out(string func) DESCRIPTION This function returns the number of seconds left until the given function `func' is to be executed. SEE ALSO call_out, remove_call_out, call_out_info doc/efun/find_living010066400004030000044000000010270514061503700151050ustar00axel_fmud00000420000006NAME find_living - find a named living object SYNOPSIS object find_living(string name) DESCRIPTION This function returns the living object with the given `name'. The argument `name' must be given in lowercase for this function to work. NOTA BENE For this function to work, the object must have added its name to the game-driver internal list by calling the function `set_living_name()'. Just making it living with `enable_commands()' is not enough. SEE ALSO set_living_name, enable_commands, find_player, find_object doc/efun/find_object010066400004030000044000000007350514061503700150700ustar00axel_fmud00000420000006NAME find_object - find a named object SYNOPSIS object find_object(string path_name) DESCRIPTION If the object with the specified `path_name' is loaded, its pointer is returned by this function. If the filename is given merely as the path to the object, e.g. "/std/coins" the master object is returned, but it is possible to find specific objects by giving the name complete with instance number, e.g. "/std/coins#123". SEE ALSO present, find_living, find_player doc/efun/find_player010066400004030000044000000004360514061503700151140ustar00axel_fmud00000420000006NAME find_player - find a named player SYNOPSIS object find_player(string name) DESCRIPTION This function finds and returns the player object with the given `name'. The argument `name' must be given in lowercase for this function to work. SEE ALSO find_living, find_object doc/efun/function_exists010066400004030000044000000015340524771436400160570ustar00axel_fmud00000420000006NAME function_exists - find out if a named function is defined in an object and return the object filename. SYNOPSIS string function_exists(string func, object ob) DESCRIPTION This function searches for a named function `func' in the specified object `ob'. If it is found, the filename of that object is returned. The filename returned is not the same as the string returned by the function `file_name()', it does not have the instance number of the found object suffixed to it. If no argument `ob' is given, `this_object()' is used by default. NOTA BENE It is the filename of the object that contains the function that is returned, not the composite object that might inherit the file that contains the function. E.g: if the function is in an object inherited by `ob' the filename of the inherited object. SEE ALSO inherit_list doc/efun/get_dir010066400004030000044000000012620524771574500142520ustar00axel_fmud00000420000006NAME get_dir - return an array of filenames in a directory SYNOPSIS string *get_dir(string path) DESCRIPTION This function returns the names of all files contained in the specified directory. If 'path' doesn't end with '/' either an empty array is returned if nothing with that name exists or an array containing the name if it exists. If 'path ends with '/' 0 is returned if 'path' isn't a directory else the contents of that directory as an array is returned. It is possible to use wildcards like: get_dir("/a*") Would return all files starting with 'a' in the muds root directory. The function is subject to the rules defined by the function `valid_read()'. doc/efun/socket_acquire010066400004030000044000000031330534475542400156310ustar00axel_fmud00000420000006 socket_acquire(3) LPC LIBRARY FUNCTIONS socket_acquire(3) NAME socket_acquire() - assume ownership of a socket SYNOPSIS int socket_acquire( int socket, string read_callback, string write_callback, string close_callback ); DESCRIPTION socket_acquire() is called to complete the handshake begun by socket_release() for transferring ownership (and control) of a socket to a new object. socket_release() calls the release callback function within the new owner object to notify the object that it wishes to pass control of the socket on. It is the responsibility of the new owner socket to decide whether it wishes to accept the socket. It it does, then socket_acquire() is called to complete the transfer. If not, then the callback simply returns without completing the handshake. In the former case the handshake is completed and the new object becomes the socket owner. The read, write and close callback function parameters refer to functions within the new object. These are specified so that the MudOS driver will know which functions to call within the new object. Decling to acquire the socket will cause socket_release() to return EESOCKNOTRLSD so the owner can perform appropriate clean-up. socket_acquire() may only be called within the context of thr release callback function and only with the socket specified. SEE ALSO socket_release(3) MudOS Release 0.9 Last change: 11-15-92 doc/efun/_destruct010064400004030000044000000003330521612164000146020ustar00axel_fmud00000420000006void _destruct(object) Forcibly destruct an object even though the object contains bugs that normally would prevent the standard destruct() from succeding. This function can only be called by wizards of level > 21. doc/efun/implode010066400004030000044000000003660524771612400142620ustar00axel_fmud00000420000006NAME implode - concatenate an array of strings SYNOPSIS string implode(string *arr, string pad) DESCRIPTION This function concatenates all strings contained in `arr' with the string `pad' inserted between them. SEE ALSO explode, sprintf doc/efun/inherit_list010066400004030000044000000005330524772026700153250ustar00axel_fmud00000420000006NAME inherit_list - return a list of all inherited objects of an object SYNOPSIS string *inherit_list(object ob) DESCRIPTION This function returns a list of all files that are inherited in the specified object `ob'. If no argument `ob' is given, `this_object()' is used by default. NOTA BENE The filename of `ob' is included in the list doc/efun/input_to010066400004030000044000000011200524772064600144630ustar00axel_fmud00000420000006NAME input_to - redirect keyboard input to a function SYNOPSIS void input_to(string func, void|int noecho) DESCRIPTION With this function it is possible to redirect the keyboard input from a player into a function. The function `func' is then called with the next string from the player that was this_player() at the call of input_to instead of interpreting it as a command. If `noecho' is given, the string is not echoed on the player's screen, good for passwords and such. NOTA BENE This only works for interactive players. This will not work for an npc of any kind. doc/efun/interactive010066400004030000044000000004600524772101500151340ustar00axel_fmud00000420000006NAME interactive - determine if an object is interactive or not SYNOPSIS int interactive(object ob) DESCRIPTION This function returns true if the specified object `ob' is an interactive player and false otherwise. If no argument is given, `this_object' is used by default. SEE ALSO this_player doc/efun/intp010066400004030000044000000003450514061504200135650ustar00axel_fmud00000420000006NAME intp - determine if a variable is of type int SYNOPSIS int intp(mixed testvar) DESCRIPTION This function return 1 if `testvar' was of the type integer, and 0 otherwise. SEE ALSO mappingp, stringp, pointerp, objectp doc/efun/living010066400004030000044000000003370524772116600141210ustar00axel_fmud00000420000006NAME living - determine if an object is living SYNOPSIS int living(object ob) DESCRIPTION This function returns 1 if the specified object `ob' is living and 0 otherwise. SEE ALSO enable_commands, disable_commands doc/efun/lower_case010066400004030000044000000003450524772144000147460ustar00axel_fmud00000420000006NAME lower_case - decapitalize a string SYNOPSIS string lower_case(string str) DESCRIPTION This function returns a string that is a copy of the argument string `str' but with all letters lower-case. SEE ALSO capitalize doc/efun/m_delete010064400004030000044000000004400515077263700144020ustar00axel_fmud00000420000006mapping m_delete(mapping map, mixed index) Remove the entry with index 'index' from mapping 'map', and return the changed mapping. If the mapping does not have an entry with index 'index', the first argument is returned. See also: mappingp, mkmapping, m_indices, m_values, m_sizeof doc/efun/throw010066400004030000044000000006110525030401700137510ustar00axel_fmud00000420000006NAME throw - cause an execution to terminate with an error SYNOPSIS void throw(mixed errdata) DESCRIPTION Terminates the execution with an error message. If a prior catch is active then execution will resume after the catch statement. In that case `errdata' will be returned by the catch statement. Anything can be thrown except 0 which is the indicator of no error. SEE ALSO catch doc/efun/m_sizeof010064400004030000044000000002300515077400100144170ustar00axel_fmud00000420000006int m_sizeof(mapping map) Return the number of indices (or values) in mapping 'map'. See also: mappingp, mkmapping, m_indices, m_values, m_delete doc/efun/m_values010064400004030000044000000002230515077345500144350ustar00axel_fmud00000420000006mixed * m_values(mapping map) Return an array with the values of mapping 'map'. See also: mappingp, mkmapping, m_indices, m_delete, m_sizeof doc/efun/say010066400004030000044000000005770524773731400134350ustar00axel_fmud00000420000006void say(str) string str; void say(str,obj) string str; object obj; If this_player() is set, send a message "str" to all players in the same object (room) else to all players in the same object (room) as this_object(). This function is also used by the "say" command. If second argument "obj" is specified, messages is sent to all except "obj". See also write(), shout(), tell(). doc/efun/mappingp010064400004030000044000000003000515077363200144260ustar00axel_fmud00000420000006int mappingp(mixed arg) Return 1 if the argument 'map' is a mapping, or 0 if it is not. see also: intp, stringp, objectp, pointerp mkmapping, m_indices, m_values, m_delete, m_sizeof doc/efun/member_array010066400004030000044000000011010526314554700152650ustar00axel_fmud00000420000006NAME member_array - find the position of an element in an array SYNOPSIS int member_array(mixed element, mixed *array) DESCRIPTION Gives the index in 'array' which is occupied with the value 'element'. If 'element' is not found or an integer is given instead of an array as second argument, -1 is returned. Searching works like the equality operator, ie integers and strings are compared for equality and arrays and mappings for identity. This means that integers and strings must have the same value to match, while arrays and mappings must be the exactly same. doc/efun/mkdir010066400004030000044000000003610514061504400137210ustar00axel_fmud00000420000006NAME mkdir - make a directory SYNOPSIS int mkdir(string pathname) DESCRIPTION Makes a directory with the pathname 'pathname'. If it returns 1 then the directory was successfully created. If it fails 0 is returned. SEE ALSO rmdir doc/efun/mkmapping010064400004030000044000000005350515077334000146040ustar00axel_fmud00000420000006mapping mkmapping(mixed *arr1, mixed *arr2) Return a mapping with indices from 'arr1' and values from 'arr2'. arr1[0] will index arr2[0], arr1[1] will index arr2[1], etc. If the arrays are of unequal size, the mapping will only contain as much elements as are in the smallest array. See also: mappingp, m_indices, m_values, m_delete, m_sizeof doc/efun/move_object010066400004030000044000000025520524772362100151240ustar00axel_fmud00000420000006NAME move_object - move an object somewhere SYNOPSIS void move_object(object, object dest|string destfilename) DESCRIPTION Moves the object 'obj' to the destination indicated by 'dest' or if the argument is a string 'destfilename' then move_object tries to load the corresponding object and move this_object to that destination. When an object moves from a destination all the commands it has defined in nearby objects using add_action through init, will be automatically removed. If this_object is a living object then all commands from nearby objects will be removed automatically. Upon entering the destination object each living object which becomes nearby will be set to this_player respectively and init will be run in the entering object. Thus letting it add its commands with add_action to each nearby living object. If the entering object is itself living, then this_player will be set to the entering object and init will be called in each object already in the destination. Init will also be called in the destination object which is normally a room. SEE ALSO add_action, enable_commands, disable_commands, this_player CAVEAT As init is called from 'within' the move_object function, care must be taken that an infinit loop is not created by moving the wrong object within an init routine. If you are doubtful, never move an object in init. doc/efun/notify_fail010066400004030000044000000007230514061504500151210ustar00axel_fmud00000420000006NAME notify_fail - give a message to be printed if all commands failed SYNOPSIS void notify_fail(string message) DESCRIPTION With this function you can set a message that will be printed instead of the notorious 'What ?' when all commands fail. The message will be passed through process_string which allows you to decide the content of the string 'late' and also do other things in the function(s) called through process_string. SEE ALSO process_string doc/efun/tell_room010066400004030000044000000005120525030342100146000ustar00axel_fmud00000420000006void tell_room(ob, str, avoid) string | object ob; string str; void | object *avoid; Send the message `str' to object all objects in `ob'. 'Ob' can either be an object or the filename to an object. The optional third argument is an array of objects not to hear `str'. See also efun/write, efun/shout, efun/say, efun/tell_object doc/efun/objectp010066400004030000044000000003550514061504600142460ustar00axel_fmud00000420000006NAME objectp - true if the value of a variable is an object SYNOPSIS int objectp(mixed testvar) DESCRIPTION This function return 1 if `testvar' was of the type object, and 0 otherwise. SEE ALSO intp, stringp, pointerp, mappingp doc/efun/parse_command010066400004030000044000000025000526205062300154210ustar00axel_fmud00000420000006 int parse_command(string,ob/arr,string,destargs...) parse Returns 1 if pattern matches string Given command ob/arr if arr array holding the accessible objects if ob object from which to recurse and create the list of accessible objects, normally ob = environment(this_player()) string Parsepattern as list of words and formats: Example string = " 'get' / 'take' %i " Syntax: 'word' obligatory text [word] optional text / Alternative marker %o Single item, object %l Single living object %s Any text %w Any word %p Preposition %i Any items %d Number 0- or tx(0-99) destargs This is the list of result variables as in sscanf One variable is needed for each %_ The return types of different %_ is: %o Returns an object %l Returns an object %s Returns a string of words %w Returns a string of one word %p Can on entry hold a list of word in array or an empty variable Returns: if empty variable: a string if array: array[0]=matched word %i Returns a special array on the form: [0] = (int) +(wanted) -(order) 0(all) [1..n] (object) Objectpointers %d Returns a number Example: parse_command("take apple",environment(this_player()), " 'get' / 'take' %i ",items); epattern as list of words and formats: Example string = " 'get' / 'take' %i " Syntax: 'word' obligatory text [word] optional text / Alternative marker %o Single itemdoc/efun/pointerp010066400004030000044000000003630514061504600144570ustar00axel_fmud00000420000006NAME pointerp - determine if the value of a variable is an array SYNOPSIS int pointerp(mixed testvar) DESCRIPTION This function return 1 if `testvar' was of the type pointer, and 0 otherwise. SEE ALSO intp, stringp, mappingp, objectp doc/efun/present010066400004030000044000000006030524772443100143030ustar00axel_fmud00000420000006NAME present - find a present object through its id() function SYNOPSIS object present(object ob|string ob, object where) DESCRIPTION This function returns the specified object `ob' if it is found in the inventory of the object `where'. The object `ob' can be given either as an actual object or as a string. If the object is not present, 0 is returned. SEE ALSO find_object doc/efun/previous_object010066400004030000044000000006640514061504700160260ustar00axel_fmud00000420000006NAME previous_object - give object that called current object SYNOPSIS object previous_object() DESCRIPTION This function returns the previous object that called a function in this object from the outside, ie with `call_other()'. This include `call_other(this_object(), ...)' constructions. In this case, the returned value will be `this_object()'. CAVEAT If the function was called internally, the result is undefined. doc/efun/process_string010066400004030000044000000026410514061504700156650ustar00axel_fmud00000420000006NAME process_string - give a string with replaced calldescriptions SYNOPSIS string process_string(string combinestring) DESCRIPTION Processes a string by replacing specific syntactic patterns with what is returned when the pattern is interpreted as a function call description. The syntactic patterns are on the form: "@@function[:filename][|arg1|arg2....|argN]@@" This is interpreted as a call: filename->function(arg1, arg2, ....., argN) Note that process_string does not recurse over returned replacement values. If a function returns another syntactic pattern, that description will not be replaced. All such occurrences in 'combinestring' is processed and replaced if the return value is a string. If the return value is not a string the the pattern will remain unreplaced. Note that both object and arguments are marked optional with the brackets and that the brackets are not included in the actual pattern. SEE ALSO process_value CAVEAT This is usually used to support 'value by function call' in the mudlib. It is wise to set the effuserid of the object to 0 before using process_value as any function in any object can be called with almost any arguments. EXAMPLE A string: "You are chased by @@query_the_name:/obj/monster#123@@ eastward." is replaced by: "You are chased by the orc eastward." Assuming that query_the_name in monster#123 returns "the orc". doc/efun/call_out_info010064400004030000044000000004320525031506100154230ustar00axel_fmud00000420000006mixed *call_out_info() Get information about all pending call outs. An array is returned, where every item in the array consists 4 elements: .np The object. .np The function. .np The delay to go. .np The optional argument. .lp See also: call_out, remove_call_out, find_call_out doc/efun/query_host_name010066400004030000044000000002710514061504700160200ustar00axel_fmud00000420000006NAME query_host_name - give the hostname that the gamedriver is running on SYNOPSIS string query_host_name() DESCRIPTION Gives the name of the machine that the game is running on doc/efun/query_idle010066400004030000044000000005150514061505000147530ustar00axel_fmud00000420000006NAME query_idle - give time since last command from a player SYNOPSIS int query_idle(object player) DESCRIPTION Returns the number of seconds that an interactive player has been idle, ie the time since the last command was issued. NOTA BENE This is only relevant to interactive players and are not implemented for npc's. doc/efun/query_ip_name010066400004030000044000000010200524774012400154470ustar00axel_fmud00000420000006NAME query_ip_name - give the hostname from which a player is connected SYNOPSIS string query_ip_name(void|object player) DESCRIPTION Gives the host name of an interactive player, ie from which site the player is connecting to the game. The string returned is on the form: "milou.cd.chalmers.se" SEE ALSO query_ip_number BUGS This function demands an external process to be active on the machine running the gamedriver. If that process is not active query_ip_name will return the same as query_ip_number, always. doc/efun/query_ip_number010066400004030000044000000004630514061505000160200ustar00axel_fmud00000420000006NAME query_ip_number - give the ip number for a player SYNOPSIS string query_ip_number(void |object player) DESCRIPTION Gives the ip number of an interactive player, ie from which site the player is connecting to the game. The string returned is on the form: "129.16.48.2" SEE ALSO query_ip_name doc/efun/query_load_average010066400004030000044000000003550514061505000164510ustar00axel_fmud00000420000006NAME query_load_average - give a load average status message SYNOPSIS string query_load_average() DESCRIPTION Returns a string on the form: "0.68 cmds/s, 29.40 comp lines/s" This indicate the current workload of the gamedriver. doc/efun/query_snoop010066400004030000044000000004110514061505100151700ustar00axel_fmud00000420000006NAME query_snoop - check what object is snooping a given object SYNOPSIS object query_snoop(object snoopee) DESCRIPTION Gives objectpointer to the player that is snooping 'snoopee'. This function can only be executed by `/secure/master.c' SEE ALSO snoop doc/efun/query_verb010066400004030000044000000012200514061505100147670ustar00axel_fmud00000420000006NAME query_verb - give the currently active verb SYNOPSIS string query_verb() DESCRIPTION Returns the currently issued verb. This is only relevant when an interactive player has issued a command. This function will the return the first word of that command, ie all text upto but not including the first space. SEE ALSO add_action CAVEAT When the verb have been added with the short verb flag, ie with add_action("function","verb",1) then all text up to first space is not equivalent to what triggered the command to be executed. You must currently remember which verb you did add_action() on until there exists a query_trigverb() BUGS doc/efun/random010066400004030000044000000006620514061505100140750ustar00axel_fmud00000420000006NAME random - give a random value SYNOPSIS int random(int limit, void|int seed) DESCRIPTION Gives a random value between 0 and 'limit - 1'. Note that the 'limit' must be a positive integer. If the optional argument 'seed' is given then a specific random number will be given. random will always return the same value for a given limit and seed. NOTA BENE The last paragraph is badly tested, please report any bugs found doc/efun/read_bytes010066400004030000044000000010450521126656100147410ustar00axel_fmud00000420000006NAME read_bytes - read text from a given position in a file SYNOPSIS string read_bytes(string filename, void|int fromchar, void|int numchar) DESCRIPTION Gives the contents of the file 'filename'. If the optional arguments 'fromchar' and 'tochar' is given then the function gives the contents from byte 'fromchar' and 'numcars' forward. NOTA BENE There is a maximum limit to the number of bytes that can be read. This limit is defined when the gamedriver is compiled and is normally 50Kbytes. SEE ALSO write_file, read_file, write_bytes doc/efun/read_file010066400003050000044000000011320552571142300143570ustar00matcamud00000420000006NAME read_file - read lines from a file, there is a maximum limit SYNOPSIS string read_file(string filename, void|int startlin, void|int numlines) DESCRIPTION Gives the contents of the file 'filename'. If the optional arguments 'startlin' and 'num' is given then the function gives the textlines (separated by newlines), from the line 'startlin' to the line 'startlin' + 'numlines'. NOTA BENE There is a maximum limit to the number of bytes that can be read. This limit is defined when the gamedriver is compiled and is normally 50Kbytes. SEE ALSO write_file, read_bytes, write_bytes doc/efun/regexp010066400004030000044000000010570524774050500141210ustar00axel_fmud00000420000006NAME regexp - match a regular expression SYNOPSIS string *regexp(string *array, string pattern) DESCRIPTION Returns an array containing all matches of `pattern' in the strings contained in `array'. The rules for this operation is somewhat hazy, I haven't had the energy to penetrate the rather large bulk of code that takes care of this so for now you'll have to read the source code for yourself if you're interested. However, it seems that the rules are the same as for UNIX `grep', but don't count on it until you have verified by testing. doc/efun/remove_call_out010066400004030000044000000004630525031520000157660ustar00axel_fmud00000420000006NAME remove_call_out - remove a named, pending call_out for current object SYNOPSIS int remove_call_out(string funcname) DESCRIPTION Removes a pending call_out in the current object. Returns heartbeats left until the call out was going to take place. SEE ALSO call_out, find_call_out, call_out_info doc/efun/rm010066400004030000044000000002210514061505200132230ustar00axel_fmud00000420000006NAME rm - remove a file SYNOPSIS int rm(string filename) DESCRIPTION Removes a file 'filename'. Returns 1 if successful. SEE ALSO rmdir doc/efun/rmdir010066400004030000044000000002620514061505200137270ustar00axel_fmud00000420000006NAME rmdir - remove an empty directory SYNOPSIS void rmdir(string pathname) DESCRIPTION Removes an empty directory. Returns 1 on success, otherwise 0. SEE ALSO mkdir, rm doc/efun/restore_object010066400004030000044000000006430514061505200156260ustar00axel_fmud00000420000006NAME restore_object - load global variables in current object from file SYNOPSIS int restore_object(string filename) DESCRIPTION Loads all nonstatic global variables from a specifically formatted file given by 'filename'. The format of the file is: variable_name variable_value intvar number stringvar "stringvalue" arrayvar ({ variable_values }) mappingvar ([ index:value ]) SEE ALSO save_object doc/efun/save_object010066400004030000044000000007560514061505300151070ustar00axel_fmud00000420000006NAME save_object - save global variables in current object to a file SYNOPSIS void save_object(string filename) DESCRIPTION Saves all non static global variables of an object to a given file. All variables are saved except those currently of the type object. The filename gets a filetype ".o" appended and the format is: variable_name variable_value intvar number stringvar "stringvalue" arrayvar ({ variable_values }) mappingvar ([ index:value ]) SEE ALSO restore_object doc/efun/set_bit010066400004030000044000000010540514061505300142440ustar00axel_fmud00000420000006NAME set_bit - set a specific bit in a bitfield SYNOPSIS string set_bit(string bitfield, int bitnum) DESCRIPTION Sets a bit with the number 'bitnum' in a specifically coded string 'bitfield'. The bitfield string is a string consisting of writable characters. Each character represents six bits. The 'bitfield' string is automatically extended to satisfy the setting of bits outside the current string size. CAVEAT There is a maximum bitindex number which can be changed in config.h in the gamedriver source. This constant is normally 1200. doc/efun/set_heart_beat010066400004030000044000000011770514061505300155720ustar00axel_fmud00000420000006NAME set_heart_beat - turn the heart beat calling on/off in current object SYNOPSIS void set_heart_beat(int onflag) DESCRIPTION This function turns on and off automatic calls every 2 seconds to the lfun heart_beat. If 'onflag' is 0 then calls is turned off, otherwise calling is turned on. NOTA BENE heart_beats are costly. Use them only if neccessary. Especially do not use them for 'down counters' such as counting down the life time of a torch, use call_out for such purposes. SEE ALSO call_out CAVEAT If there is a runtime error in your heart_beat routine calling of the heart_beat will be automatically turned off. doc/efun/set_living_name010066400004030000044000000010700514061505300157540ustar00axel_fmud00000420000006NAME set_living_name - set the searchable name for a living object SYNOPSIS void set_living_name(string name) DESCRIPTION Sets a specific searchable name for a living object, ie an object that has done enable_commands. By doing so the object can be found by the function find_living. NOTA BENE This is normally used to allow finding of an npc globally in the game. SEE ALSO find_living, find_player, enable_commands CAVEAT If there is two living objects with the same name then only one of them will ever be found by find_living, undefined which one. doc/efun/next_inventory010066400004030000044000000004140525420104300157010ustar00axel_fmud00000420000006object next_inventory(ob) object ob; Get next object in the same inventory as "ob". Warning: If the object 'ob' is moved by move_object(), then next_inventory() will return an object from the new inventory. See also: first_inventory, all_inventory, deep_inventory doc/efun/_disconnect010064400004030000044000000003400521612167500151040ustar00axel_fmud00000420000006void _disconnect(object) This function is used to disconnect a player object from the network link (ie, simulate a network link down). Only wizards of level >= 23 and objects in /local, /obj and /room may use this efun. doc/efun/shadow010066400004030000044000000005010524773655700141210ustar00axel_fmud00000420000006NAME shadow - let the current object shadow another object or find a shadow SYNOPSIS object shadow(object shadowee, int setshadow) DESCRIPTION If 'setshadow' is 1 set the current object to shadow 'shadowee' if 'shadowee' hasn't denied shadowing. If setshadow is 0 return the object currently shadowing 'shadowee'. doc/efun/shutdown010066400004030000044000000002660524773622300145050ustar00axel_fmud00000420000006NAME shutdown - shut down the gamedriver SYNOPSIS void shutdown() DESCRIPTION This function should only be used in emergencies. Normally Armageddon is used to reboot the game. doc/efun/sizeof010066400004030000044000000002100524773606700141240ustar00axel_fmud00000420000006NAME sizeof - give the size of an array SYNOPSIS int sizeof(mixed *array) DESCRIPTION return the size in elements of a given array doc/efun/snoop010066400004030000044000000002300514061505500137460ustar00axel_fmud00000420000006NAME snoop - let one player snoop another SYNOPSIS object snoop(void|object snooper, object snoopee) DESCRIPTION NOTA BENE SEE ALSO CAVEAT BUGS doc/efun/sort_array010066400004030000044000000006050524773446300150200ustar00axel_fmud00000420000006NAME sort_array - sort an array through a specific sort function SYNOPSIS mixed *sort_array(mixed *array, string sortfunc, string|object sortob) DESCRIPTION Sort array calls 'sortfunc' in 'sortob' with two elements from the 'array' as args at a time and the function returns true if arg1 is bigger than arg2 to sort lower to higher in the resulting array and the other way around. doc/efun/sscanf010066400004030000044000000020350537105110300140640ustar00axel_fmud00000420000006NAME sscanf - Parse a string with a given format SYNOPSIS int sscanf(string str, string fmt, mixed var1, mixed var2 ...) DESCRIPTION Parse string `str' with the format `fmt' and return matched pieces in the given variables. %s and %d in the format string refers to a string and a number respectively. The variables must be defined earlier as `strings' for those connected to a %s and `int' for those connected to a %d. You can now also use %*s and %*d in the format string. These correspond to %s and %d respectively but do not need a matching variable for the result, thus eliminating unnecessary temporary variables if you're only interested in the pattern and not the actual contents of the string. EXAMPLE sscanf("good morning", "%s %s", var1, var2) == 2 var1 is set to "good" and var2 to "morning" sscanf("10 hi", "%d ", var) == 1 var is set to 10 sscanf("from bag", "%s %d", var1, var) == 1 var1 is set to from and var is unchanged sscanf(file_name(this_object()), "%*s#%*d") == 2 this_object() is a clone doc/efun/stringp010066400004030000044000000003550514061505700143100ustar00axel_fmud00000420000006NAME stringp - true if a given variables value is currently a string SYNOPSIS int stringp(mixed testvar) DESCRIPTION Returns 1 if the value of 'testvar' is currently of the type string. SEE ALSO intp, pointerp, mappingp, objectp doc/efun/strlen010066400004030000044000000002210524773132100141220ustar00axel_fmud00000420000006NAME strlen - give the length of a string SYNOPSIS int strlen(string str) DESCRIPTION Gives the length of a string in number of characters. doc/efun/tail010066400004030000044000000004130514061505700135460ustar00axel_fmud00000420000006NAME tail - print the last lines of a file SYNOPSIS void tail(string filename) DESCRIPTION Writes the approx 1080 last bytes of the file 'filename' to the current player, ie this_player It ensures that it starts writing on a new line. SEE ALSO write, cat doc/efun/tell_object010066400004030000044000000011050514061506000150740ustar00axel_fmud00000420000006NAME tell_object - send message to a specific living object SYNOPSIS void tell_object(object liveob, string message) DESCRIPTION Sends a message directly to the living object 'liveob'. If 'liveob' is an interactive object then the message is written directly to the socket. If 'liveob' is an npc then the lfun 'catch_tell' will be called with 'message' as parameter. NOTA BENE tell_object as well as write sends unprocessed messages to the recieving object. If the mudlib uses processing on messages then calling this function will send a raw message. SEE ALSO write doc/efun/test_bit010066400004030000044000000007520514061506000144320ustar00axel_fmud00000420000006NAME test_bit - test a given bit in a bitfield SYNOPSIS int test_bit(string bitfield, int bitnum) DESCRIPTION Tests a bit with the number 'bitnum' in a specifically coded string 'bitfield'. The bitfield string is a string consisting of writable characters. Each character represents six bits. test_bit returns 1 if the bit is set, otherwise 0. CAVEAT There is a maximum bitindex number which can be changed in config.h in the gamedriver source. This constant is normally 1200. doc/efun/_query_action010064400004030000044000000012040521612230100154400ustar00axel_fmud00000420000006mixed *_query_action(object|string, void|string) This function can be used to report which 'actions' are added for a certain object, and what function/object they are connected to. There are two ways this function can be used, the first: string *_query_action(object|string) will return an array with all actions defined. And the second: mixed *_query_action(object|string, string) will return a mixed array consisting of the following informaton for the action specified as the second argument: Element #0: Abbreviation length flag, of type "int". Element #1: Function name, type "string". Element #2: Object, type "object". doc/efun/this_object010066400004030000044000000002660514061506000151120ustar00axel_fmud00000420000006NAME this_object - give the object pointer to the executing object SYNOPSIS object this_object() DESCRIPTION Gives the object pointer to the object that is currently executing. doc/efun/this_player010066400004030000044000000004700524773004300151440ustar00axel_fmud00000420000006NAME this_player - give the current player SYNOPSIS object this_player() DESCRIPTION Gives the currently active player. This can be both an interactive player and an npc in the game. this_player is the object that gets all writes and is affected by add_action. SEE ALSO write, add_action, move_object doc/efun/time010066400004030000044000000004530524772757300135760ustar00axel_fmud00000420000006NAME time - give the current time SYNOPSIS int time() DESCRIPTION Gives the current time in number of seconds passed since January 1970, something. SEE ALSO ctime BUGS The actual time is only updated in the gamedriver each heartbeat. This means that time makes 'leaps' every heartbeat. doc/efun/trace010066400004030000044000000015570514061506200137210ustar00axel_fmud00000420000006NAME trace - let a player get trace information SYNOPSIS int trace(int bitflags) DESCRIPTION Sets the trace level for the current player. As long as this player is current the gamedriver will write trace information. This can be very excessive information. The bitcodes are as follows: 1 - Trace all calls 2 - Trace all call_others 4 - Trace all returns 8 - Write arguments when tracing call / call_other 16 - Trace stackcode execution (VERY MUCH INFORMATION) 32 - Trace code in run in heartbeat 64 - Trace all applys 128 - Write objectnames when tracing NOTA BENE This can most often only be used by some high level wizards in a mud for reasons of efficiency. This is implemented through the master object SEE ALSO traceprefix BUGS When very much information is printed it most often gets discarded because the socket can't keep up. doc/efun/socket_listen010066400004030000044000000026560534475545400155120ustar00axel_fmud00000420000006 socket_listen(3) LPC LIBRARY FUNCTIONS socket_listen(3) NAME socket_listen() - listen for connections on a socket SYNOPSIS #include #include int socket_listen(int s, string listen_callback) DESCRIPTION To accept connections, a socket is first created with socket_create(3), the socket is them put into listening mode with socket_listen(3), and the connections are accepted with socket_accept(3). The socket_listen() call applies only to sockets of type STREAM or MUD. The argument listen_callback is the name of a function for the driver to call when a connection is requested on the listening socket. The listen callback should follow this format: void listen_callback(int fd) Where fd is the listening socket. RETURN VALUES socket_listen() returns: EESUCCESS on success. a negative value indicated below on error. ERRORS EEFDRANGE Descriptor out of range. EEBADF Descriptor is invalid. EESECURITY Security violation attempted. EEMODENOTSUPP Socket mode not supported. EENOADDR Socket not bound to an address. EEISCONN Socket is already connected. EELISTEN Problem with listen. SEE ALSO socket_accept(3), socket_connect(3), socket_create(3) MudOS Release 0.9 Last change: 11-15-92 doc/efun/traceprefix010066400004030000044000000004540514061506200151320ustar00axel_fmud00000420000006NAME traceprefix - set the prefix for objects printed during a trace SYNOPSIS string traceprefix(int|string prefix) DESCRIPTION Sets the filenameprefix for objects that should be printed in trace. NOTA BENE Use this with caution as it is severly punishing on execution speed. SEE ALSO trace doc/efun/ls010066400004030000044000000005250524772164500132500ustar00axel_fmud00000420000006void ls(path) char path; List files in an optional path. It is not allowed to use '.' or space in the path. This function is normally connected to the "ls" command that a wiz have. This efun doesn't exist any more since get_dir is much better. It remains as a simul_efun for backward compatibility but shouldn't be used. See also get_dir doc/efun/unique_array010066400004030000044000000014330514061506200153200ustar00axel_fmud00000420000006NAME unique_array - Sort an array into arrays of unique groups SYNOPSIS mixed *unique_array(int|mixed *array, string uniqfunc, void|mixed del) DESCRIPTION Gives an array of arrays of nonunique objects. The function 'uniqfunc' is called on each of the objects in the array. The return values are used to group the objects into a number of arrays. For each object in such a subarray 'uniqfunc' returned the same value. Then an array on the below form are returned: ({ ({Same1:1, Same1:2, Same1:3, .... Same1:N }), ({Same2:1, Same2:2, Same2:3, .... Same2:N }), ({Same3:1, Same3:2, Same3:3, .... Same3:N }), .... .... ({SameM:1, SameM:2, SameM:3, .... SameM:N }), }) CAVEAT All elements of the array that is not objectpointers are ignored. BUGS doc/efun/users010066400004030000044000000004350514061506300137570ustar00axel_fmud00000420000006NAME users - give an array of the current players SYNOPSIS object *users() DESCRIPTION Gives an array of objectpointers to the currently interactive objects. This is most often the playerobjects, unless exec() has been run to swap a players interactivity into another object. doc/efun/version010066400004030000044000000003520524772664200143170ustar00axel_fmud00000420000006NAME version - give the version of the gamedriver SYNOPSIS string version() DESCRIPTION Simply returns a string indicating the gamedriver version, this is typically on the form: "3.1.2-Lxx", where xx is the current local-level. doc/efun/wizlist010066400004030000044000000013410524772637600143420ustar00axel_fmud00000420000006NAME wizlist - print some statistics on wizards SYNOPSIS void wizlist(void|string wizname) DESCRIPTION Print some statistics on wizards and objects created by them. If no argument is given the name of this_player() is used. This efun print some info in columns: first: commands executed that where defined by wiz second: percent of total commands third: where on the list wiz is fourth: evaluated nodes in wiz's objects fifth: heart_beats in wiz's monsters sixth: given/taken xp/money by this wizard seventh: nodes in arrays used by wiz's objects If the name isn't among the 15 first on the list that person, the two nearest after and the two nearest after is printed The top fifteen is printed in any case. doc/efun/write010066400004030000044000000006370524772510200137600ustar00axel_fmud00000420000006NAME write - write data (normally text) to the current player SYNOPSIS void write(mixed data) DESCRIPTION Writes data to the current 'command giver', ie the object returned by this_player. Data is normally text. If this_player() is 0 data is written to the muds system log. Make sire you don't use this efun without a this_player(), the logfile grows fast enough anyway. SEE ALSO tell_object, this_player doc/efun/write_bytes010066400004030000044000000011110514061506300151460ustar00axel_fmud00000420000006NAME write_bytes - write chars in a given position in a file SYNOPSIS int write_bytes(string filename, int position, string text) DESCRIPTION Write the string 'text' at a given position in a file. If the position is negative it is counted backwards from the end of the file. If the position is outside the file the nothing is written. If the 'text' extends outside the file then the file is extended. NOTA BENE Observe that you overwrite existing data in the file. Not like write_file where you only append data at the end. SEE ALSO read_bytes, write_file, read_file doc/efun/write_file010066400004030000044000000005610514061506300147470ustar00axel_fmud00000420000006NAME write_file - append text to a file SYNOPSIS int write_file(string filename, string text) DESCRIPTION This function appends a given string 'text' to the file 'filename'. NOTA BENE If you need to rewrite a file, that is not append but write from start, then you have to first remove the file with rm. SEE ALSO read_file, read_bytes, write_bytes, rm, rmdir doc/efun/README010066400004030000044000000001630517453202400135530ustar00axel_fmud00000420000006This directory documents all external functions accessible by objects. These functions may be used in all objects. doc/efun/add_verb010066400004030000044000000005610475505125600143750ustar00axel_fmud00000420000006void add_verb(str) string str; This function is connected to the "add_action()" function. It will set up the command "str" to trigger a call to the function set up by the previous call to "add_action()". This function is now obsolete as the verb can be given directly with add_action(). add_verb() remains for compatibility. See also efun/add_action efun/query_verb doc/efun/assoc010064400004030000044000000023160513723655400137360ustar00axel_fmud00000420000006mixed assoc(mixed key, mixed *keys, mixed *|void data_or_fail, mixed|void fail); Searches a key in an alist. Three modes of calling: i ) With exactly two arguments, the second being an array which's first element is no array. In this case the entire array is searched for the key; -1 is returned if not found, else the index ( like member_array, but faster ). ii) With two or three arguments, the second being an array which's first element is an array. The array has to have a second element of the same size; the key is searched in the first and the associated element of the second array that is element of second argument is returned if succesful; if not, 0 is returned, or the third argument, if given. iii) With three or four arguments, the second being an array of keys ( first element no array ) and the second is a matching data array. returns 0 or fourth argument ( if given ) for failure, or the matching entry in the array given as third argument for success. Complexity : O( lg(n) ) , where n is the number of keys. Return value is undefined if another list is given in place of a presorted key list. See also: LPC/alists order_alist insert_alist doc/efun/socket_release010066400004030000044000000035600534475545700156320ustar00axel_fmud00000420000006 socket_release(3) LPC LIBRARY FUNCTIONS socket_release(3) NAME socket_release() - release ownership of a socket to another object SYNOPSIS int socket_release( int socket, object ob, string release_callback ); DESCRIPTION socket_release() is used to change ownership (and control) of a socket to another object. It is useful in daemon objects (like inetd) which handle connection set-up and then transfer a connected socket to another object for further processing. Socket ownership transfer involves a handshake between the current owner object and the socket to which the current owner wishes to transfer the socket. The handshake is ini- tiated when socket_release() is called. socket_release() does appropriate security/integrity checking and then calls the release_callback function in object ob. This function is used to notify ob that socket ownership is being transferred to it. It is then ob's responsibility to call socket_acquire() within the release callback function. If socket_acquire() is called then the handshake is complete and socket ownership has been successfully transferred to ob. ob may decline to accept responsibility for the socket by not calling socket_acquire(), in which case ownership does not change and the current socket owner must decide how to respond to this. If the socket owner is successfully transfered then socket_release() returns EESUCCESS. If ob does not accept ownership for the socket then EESOCKNOTRLSD is returned. Other errors can be returned based on security violation, bad socket descriptor vbalues, etc. SEE ALSO socket_acquire(3) MudOS Release 0.9 Last change: 11-15-92 doc/efun/catch010066400004030000044000000005630524770150100137030ustar00axel_fmud00000420000006mixed catch(expr) Evaluate 'expr'. If there is no error, 0 is returned. If there is a standard error, a string (with a leading '*') will be returned. The function throw(value) can also be used to immediately return any value, except 0. The catch() is somewhat costly, and should not be used anywhere. Rather, use it at places where an error would destroy consistency. doc/efun/create_wizard010066400004030000044000000006520475505124300154470ustar00axel_fmud00000420000006string create_wizard(name) string name; Create the environment and castle for a wizard. Do NOT use this if you are not sure about what you are doing ! It will create a new directory for wizard with the name "name", and copy a definition of a castle to this directory. It will also set up automatic loading of this castle for the start of the game. It returns the name of the new castle. In case of error, false is returned. doc/efun/creator010066400004030000044000000002350475505130500142570ustar00axel_fmud00000420000006string creator(ob) object ob; Return as a string the name of the wizard that created object 'ob'. If the object was not created by a wizard, 0 is returned. doc/efun/socket_write010066400004030000044000000031210534475546200153310ustar00axel_fmud00000420000006 socket_write(3) LPC LIBRARY FUNCTIONS socket_write(3) NAME socket_write() - send a message from a socket SYNOPSIS #include #include int socket_write(int s, mixed message, string|void address) DESCRIPTION socket_write() sends a message on a socket s. If the socket s is of type STREAM or MUD, the socket must already be con- nected and the address is not specified. If the socket is of type DATAGRAM, the address must be specified. The address is of the form: "127.0.0.1 23". RETURN VALUES socket_write() returns: EESUCCESS on success. a negative value indicated below on error. ERRORS EEFDRANGE Descriptor out of range. EEBADF Descriptor is invalid. EESECURITY Security violation attempted. EENOADDR Socket not bound to an address. EEBADADDR Problem with address format. EENOTCONN Socket not connected. EEALREADY Operation already in progress. EETYPENOTSUPP Object type not supported. EEBADDATA Sending data with too many nested levels. EESENDTO Problem with sendto. EEMODENOTSUPP Socket mode not supported. EEWOULDBLOCK Operation would block. EESEND Problem with send. MudOS Release 0.9 Last change: 11-15-92 socket_write(3) LPC LIBRARY FUNCTIONS socket_write(3) EECALLBACK Wait for callback. SEE ALSO socket_connect(3), socket_create(3) Sun Release 4.1 Last change: 2 doc/efun/filter_array010066400004030000044000000006010524771355400153100ustar00axel_fmud00000420000006mixed *filter_array(mixed *arr, string fun, object ob, mixed extra); Returns an array holding the items of 'arr' filtered through ob->fun(). The function 'fun' in 'ob' is called for each element in 'arr' with that element as parameter. A second parameter 'extra' is sent in each call if given. If ob->fun(arr[.index.], extra) returns 1 the element is included in the returned array. doc/efun/inherit010066600004030000044000000021020524772001200142520ustar00axel_fmud00000420000006This is not a function in the normal matter, but merely a way to make all functions and variables from an object availiable to your object without copying it entirely. The syntax is: inherit ""; This statement must always come first in your file. All include-files and variable declarations must come after the inheritance statement. When using inherit you will save a lot of memory and this way please the game-administrators. The filename counts from the root and not, like the include statement, from the current directory. If you wish to make a function with the same name as one in the inherited object you can still access the inherited one using two colons in front of the functionname. Example: reset(arg) { ::reset(arg); ... will call reset(arg) in the inherited object. If you inherit more than one file you reach the functions in them by prepending the filename before '::' Example: inherit("/obj/monster"); inherit("/players/test/file"); reset(arg) { monster::reset(arg); ... will call reset(arg) in /obj/monster See also /doc/LPC/inheritance doc/efun/insert_alist010064400004030000044000000026730513723655400153340ustar00axel_fmud00000420000006mixed insert_alist( mixed key, mixed data_or_key_list..., mixed * alist); inserts an entry into an alist, or shows the place where this is to be done. When called with the last argument being an alist: The first argument is a key to be inserted, the second and all the following but the last are data to associate it with. The last has to be an array with as much elements as key and data arguments are given, the matching key and data arrays; this should be already an alist, or the return value will neither be an alist. Return value is the enlarged assoc list ( array of two arrays ). If the key is already in the list, the data is simply replaced in the returned list. When called with the last argument beinig a list of non-lists: The call has to be done with exactly two arguments. The first argument is a key to be inserted in the presorted key list ( first element of an array that is an alist ) that has to be given as second argument. Return value is the index where the key has to be inserted to preserve the structure of a presorted alist, or the index where the key has been found. Return value is an int. CAVEATS: when called with certain string keys, the correct place might change after the call. So better don't use this mode of calling with a string key. Complexity O( lg(n) + a*n ) Where n is the number of keys and s is a very small constant ( for block move ); See also: LPC/alists order_alist assoc doc/efun/log_file010066400004030000044000000003330524772131000143740ustar00axel_fmud00000420000006void log_file(file, message) string file; string message; Append a message to a log file. All log files are in the directory mudlib/log. '/log/' is automatically prepended to the file name. See also: efun/write_file doc/efun/map_array010066400004030000044000000007200524772301700145750ustar00axel_fmud00000420000006mixed *map_array(mixed *arr, string fun, object ob, mixed extra) Returns an array holding the items of 'arr' mapped through ob->fun(). The function 'fun' in 'ob' is called for each element in 'arr' with that element as parameter. A second parameter 'extra' is sent in each call if given. Principal function: foreach (index) arr[index] = ob->fun(arr[index],extra); The value returned by ob->fun(arr[.index.], extra) replaces the existing element in the array. doc/efun/_object_cpu010066400004030000044000000001100526217456400150730ustar00axel_fmud00000420000006int _object_cpu(object) Returns how much eval_cost an object have used.doc/efun/order_alist010064400004030000044000000016120513723655500151340ustar00axel_fmud00000420000006mixed *order_alist(mixed *keys, mixed *|void data, ...); Creates an alist. Either takes an array containing keys, and others containing the associated data, where all arrays are to be of the same length, or takes a single array that contains as first member the array of keys and has an arbitrary number of other members containing data, each of wich has to be of the same length as the key array. Returns an array holding the sorted key array and the data arrays; the same permutation that is applied to the key array is applied to all data arrays. Complexity is O( n * lg(n) * m ) , where n is the number of elements in the key array and m is the number of data arrays + 1; Note that the the dimensions of the arrays are used the other way than in lisp to allow for faster searching. Keys have to be of type integer, string or object. Types can be mixed. See also LPC/alists, insert_alist, assoc. doc/efun/socket_bind010066400004030000044000000021140534475543300151120ustar00axel_fmud00000420000006 socket_bind(3) LPC LIBRARY FUNCTIONS socket_bind(3) NAME socket_bind() - bind a name to a socket SYNOPSIS #include #include int socket_bind(int s, int port) DESCRIPTION socket_bind() assigns a name to an unnamed socket. When a socket is created with socket_create(3) it exists in a name space (address family) but has no name assigned. socket_bind() requests that the port be assigned to the socket s. RETURN VALUES socket_bind() returns: EESUCCESS on success. a negative value indicated below on error. ERRORS EEFDRANGE Descriptor out of range. EEBADF Descriptor is invalid. EESECURITY Security violation attempted. EEISBOUND Socket is already bound. EEADDRINUSE Address already in use. EEBIND Problem with bind. EEGETSOCKNAME Problem with getsockname. SEE ALSO socket_connect(3), socket_create(3), socket_listen(3) MudOS Release 0.9 Last change: 11-15-92 doc/efun/set_light010066400004030000044000000004540475505126700146140ustar00axel_fmud00000420000006int set_light(n) int n; An object is by default dark. It can be set to not dark by calling set_light(1). The environment will the also get this light. The returned value is the total number of lights in this room. Note that the value of the argument is added to the light of the current argument ! doc/efun/shout010066400004030000044000000002360475505123600137660ustar00axel_fmud00000420000006void shout(str) string str; Send a string "str" to all players. This function is also used by the "shout" command. See also write(), tell_object(), say(). doc/efun/slice_array010066400004030000044000000004570524773573700151420ustar00axel_fmud00000420000006mixed *slice_array(mixed *arr,int from,int to) Returns an array that is a slice of the array 'arr' from the index 'from' to the index 'to'. Indices are numbered 0- If indices are outside the limits of 'arr' an empty array is returned. Note also that you can use the operators '+' and '-' on arrays. doc/efun/transfer010066400004030000044000000012120475505130400144370ustar00axel_fmud00000420000006int transfer(item, dest) object item; object dest; Move the object "item" to the object "dest". All kinds of tests are done, and a number is returned specifying the result: 0: Success. 1: To heavy for destination. 2: Can't be dropped. 3: Can't take it out of it's container. 4: The object can't be inserted into bags etc. 5: The destination doesn't allow insertions of objects. 6: The object can't be picked up. If an object is transfered to a newly created object, make sure that the new object first is transfered to it's destination. See also efun/move_object, lfun/drop, lfun/get, lfun/prevent_insert, lfun/can_put_and_get, lfun/add_weight is returned specifying the result: 0: Success. 1: To heavy for destination. 2: Can't be dropped. 3: Can't take it out of it's container. 4: The object can't be inserted into bags etc. 5: The destination doesn't allow insertions of objects. 6: The object can't be picked up. If an object is transfered to a newly created object, make sure that the new object first is trandoc/efun/m_indices010064400004030000044000000002320515077261500145510ustar00axel_fmud00000420000006mixed * m_indices(mapping map) Return an array containing the indices of mapping 'map'. See also: mappingp, mkmapping, m_values, m_delete, m_sizeof doc/efun/sprintf010066400004030000044000000051150521121223000142670ustar00axel_fmud00000420000006 An implementation of (s)printf() for LPC, with quite a few extensions (note that as no floating point exists, some parameters have slightly different meaning or restrictions to "standard" (s)printf.) Implemented by Lynscar (Sean A Reith). This version supports the following as modifiers: " " pad positive integers with a space. "+" pad positive integers with a plus sign. "-" left adjusted within field size. NB: std (s)printf() defaults to right justification, which is unnatural in the context of a mainly string based language but has been retained for "compatability" ;) "|" centered within field size. "=" column mode if strings are greater than field size. this is only meaningful with strings, all other types ignore this. columns are auto-magically word wrapped. "#" table mode, print a list of '\n' separated 'words' in a table within the field size. only meaningful with strings. n specifies the field size, a '*' specifies to use the corresponding arg as the field size. if n is prepended with a zero, then is padded zeros, else it is padded with spaces (or specified pad string). "."n presision of n, simple strings truncate after this (if presision is greater than field size, then field size = presision), tables use presision to specify the number of columns (if presision not specified then tables calculate a best fit), all other types ignore this. ":"n n specifies the fs _and_ the presision, if n is prepended by a zero then it is padded with zeros instead of spaces. "@" the argument is an array. the corresponding format_info (minus the "@") is applyed to each element of the array. "'X'" The char(s) between the single-quotes are used to pad to field size (defaults to space) (if both a zero (in front of field size) and a pad string are specified, the one specified second overrules). NOTE: to include "'" in the pad string, you must use "\\'" (as the backslash has to be escaped past the interpreter), similarly, to include "\" requires "\\\\". The following are the possible type specifiers. "%" in which case no arguments are interpreted, and a "%" is inserted, and all modifiers are ignored. "O" the argument is an LPC datatype. "s" the argument is a string. "d" the integer arg is printed in decimal. "i" as d. "c" the integer arg is to be printed as a character. "o" the integer arg is printed in octal. "x" the integer arg is printed in hex. "X" the integer arg is printed in hex (in capitals). doc/efun/parse_command.native010066400004030000044000000150760526205055600167270ustar00axel_fmud00000420000006NAME parse_command - try to match a string with a given pattern SYNOPSIS int parse_command(string command, object env|object *oblist, string pattern, mixed arg, ...) DESCRIPTION This is one of the most complex efun in LPmud to use. It takes some effort to learn and use, but when mastered, very powerfull constructs can be implemented. Basically parse_command() is a piffed up sscanf operating on word basis. It works similar to sscanf in that it takes a pattern and a variable set of destination arguments. It is together with sscanf the only efun to use pass by reference for other variables than arrays. To make the efun usefull it must have a certain support from the mudlib, there is a set of functions that it needs to call to get relevant information before it can parse in a sensible manner. In earlier versions it used the normal id() lfun in the LPC objects to find out if a given object was identified by a certain string. This was highly inefficient as it could result in hundreds or maybe thousands of calls when very long commands were parsed. The new version relies on the LPC objects to give it three lists of 'names'. 1 - The normal singular names. 2 - The plural forms of the names. 3 - The acknowledged adjectives of the object. These are fetched by calls to the functions: 1 - string *parse_command_id_list(); 2 - string *parse_command_plural_id_list(); 3 - string *parse_command_adjectiv_id_list(); The only really needed list is the first. If the second does not exist than the efun will try to create one from the singluar list. For grammatical reasons it does not always succeed in a perfect way. This is especially true when the 'names' are not single words but phrases. The third is very nice to have because it makes constructs like 'get all the little blue ones' possible. Apart from these functions that should exist in all objects, and which are therefore best put in /std/object.c there is also a set of functions needed in /secure/master.c These are not absolutely necessary but they give extra power to the efun. Basically these /secure/master.c lfuns are there to give default values for the lists of names fetched from each object. The names in these lists are applicable to any and all objects, the first three are identical to the lfun's in the objects: string *parse_command_id_list() - Would normally return: ({ "one", "thing" }) string *parse_command_plural_id_list() - Would normally return: ({ "ones", "things", "them" }) string *parse_command_adjectiv_id_list() - Would normally return ({ "iffish" }) The last two are the default list of the prepositions and a single so called 'all' word. string *parse_command_prepos_list() - Would normally return: ({ "in", "on", "under" }) string parse_command_all_word() - Would normally return: "all" The function returns 1 if 'command' is considered to have matched 'pattern'. The 'env' or 'oblist' parameter either holds an object or a list of objects. If it holds a single object than a list of objects are automatically created by adding the deep_inventory of the object, ie this is identical: parse_command(cmd, environment(), pattern, arg) and parse_command(cmd, ({ environment() }) + deep_inventory(environment()), pattern, arg) 'pattern' is a list of words and formats: Example string = " 'get' / 'take' %i " Syntax: 'word' obligatory text [word] optional text / Alternative marker %o Single item, object %l Living objects %s Any text %w Any word %p One of a list (prepositions) %i Any items %d Number 0- or tx(0-99) The 'arg' list is zero or more arguments. These are the result variables as in sscanf. Note that one variable is needed for each %_ The return types of different %_ is: %o Returns an object %s Returns a string of words %w Returns a string of one word %p Can on entry hold a list of word in array or an empty variable Returns: if empty variable: a string if array: array[0]=matched word %i Returns a special array on the form: [0] = (int) +(wanted) -(order) 0(all) [1..n] (object) Objectpointers %l Returns a special array on the form: [0] = (int) +(wanted) -(order) 0(all) [1..n] (object) Objectpointers These are only living objects. %d Returns a number The only types of % that uses all the loaded information from the objects are %i and %l. These are in fact identical except that %l filters out all nonliving objects from the list of objects before trying to parse. The return values of %i and %l is also the most complex. They return an array consisting of first a number and then all possible objects matching. As the typical string matched by %i/%l looks like: 'three red roses', 'all nasty bugs' or 'second blue sword' the number indicates which of these numerical constructs was matched: if numeral >0 then three, four, five etc were matched if numeral <0 then second, twentyfirst etc were matched if numeral==0 then 'all' or a generic plural form such as 'apples' were matched. NOTE! The efun makes no semantic implication on the given numeral. It does not matter if 'all apples' or 'second apple' is given. A %i will return ALL possible objects matching in the array. It is up to the caller to decide what 'second' means in a given context. Also when given an object and not an explicit array of objects the entire recursive inventory of the given object is searched. It is up to the caller to decide which of the objects are actually visible meaning that 'second' might not at all mean the second object in the returned array of objects. SEE ALSO sscanf, deep_inventory CAVEAT Patterns of type: "%s %w %i" Might not work as one would expect. %w will always succeed so the arg corresponding to %s will always be empty. BUGS Patterns of the type: 'word' and [word] The 'word' can not contain spaces. It must be a single word. This is so because the pattern is exploded on " " (space) and a pattern element can therefore not contain spaces. EXAMPLE: if (parse_command("spray car",environment(this_player()), " 'spray' / 'paint' [paint] %i ",items)) { /* If the pattern matched then items holds a return array as described under 'destargs' %i above. */ } y necessary but they give extra power to the efun. Basically these /secure/master.c lfuns are there to give default values for the lists of names fetched from each object. The names in these lists are applicable to any and all objects, the first three are identical to the lfun's in the objects: string *parse_command_id_list() - Would normally return: ({ "one", "thing" }) string *parse_command_plural_id_doc/efun/_query_ident010064400004030000044000000005400521612273300153010ustar00axel_fmud00000420000006string _query_ident(void|object) Returns the user identifier as returned by the Identification Server Protocol (se RFC931 or later revisions for more information about the protocol) for the current or specified player object. If an argument is specified, then this function can only be called by wizards of level >= 23. Otherwise it will return 0. doc/efun/socket_error010066400004030000044000000011430534475545100153300ustar00axel_fmud00000420000006 socket_error(3) LPC LIBRARY FUNCTIONS socket_error(3) NAME socket_error() - return a text description of a socket error SYNOPSIS #include #include string socket_error(int error) DESCRIPTION socket_error() returns a string describing the error signi- fied by error. RETURN VALUES socket_error() returns: a string describing the error on success. "socket_error: invalid error number" on bad input. SEE ALSO socket_create(3), socket_connect(3) MudOS Release 0.9 Last change: 11-15-92 doc/efun/dump_socket_status010066400004030000044000000054060534475551100165520ustar00axel_fmud00000420000006 dump_socket_status(3)LPC LIBRARY FUNCTIONS dump_socket_status(3) NAME dump_socket_status() - display the status of each LPC socket SYNOPSIS void dump_socket_status( void ); DESCRIPTION dump_socket_status() is a diagnostic facility which displays the current status of all LPC sockets configured into the MudOS driver. It is useful for debugging LPC sockets appli- cations. Each row in the output corresponds to a single LPC socket. The first row corresponds to LPC socket descriptor 0, the second row, 1, etc. The total number of sockets is configured when the driver is built. The first column "Fd" is the operating system file descrip- tor associated with the LPC socket. "State" is the current operational state of the LPC socket. "Mode" is the socket mode, which is passed as an argument to socket_create(). The local and remote addresses are the Internet address and port numbers in Internet dot notations. '*' indicates an address or which is 0. N.B. LPC sockets that are in the CLOSED state are not currently in use; therefore the data displayed for that socket may be idiosyncratic. The following output was generated on Portals, where the only socket application running at the time was MWHOD. It indicates that two sockets are current in use, one is listening for connection requests on a STREAM mode socket. The other is waiting for incoming data on a DATAGRAM mode socket. Fd State Mode Local Address Remote Address -- --------- -------- --------------------- --- ------------------ 13 LISTEN STREAM *.6889 *.* 14 BOUND DATAGRAM *.6888 *.* -1 CLOSED MUD *.* *.* -1 CLOSED MUD *.* *.* -1 CLOSED MUD *.* *.* -1 CLOSED MUD *.* *.* -1 CLOSED MUD *.* *.* -1 CLOSED MUD *.* *.* -1 CLOSED MUD *.* *.* -1 CLOSED MUD *.* *.* -1 CLOSED MUD *.* *.* -1 CLOSED MUD *.* *.* -1 CLOSED MUD *.* *.* -1 CLOSED MUD *.* *.* -1 CLOSED MUD *.* *.* -1 CLOSED MUD *.* *.* MudOS Release 0.9 Last change: 11-15-92 dump_socket_status(3)LPC LIBRARY FUNCTIONS dump_socket_status(3) SEE ALSO debug_info(3), dump_file_descriptors(3) Sun Release 4.1 Last change: 2 doc/efun/socket_close010066400004030000044000000012650534475544000153070ustar00axel_fmud00000420000006 socket_close(3) LPC LIBRARY FUNCTIONS socket_close(3) NAME socket_close() - close a socket SYNOPSIS #include #include int socket_close(int s) DESCRIPTION socket_close() closes socket s. This frees a socket efun slot for use. RETURN VALUES socket_close() returns: EESUCCESS on success. a negative value indicated below on error. ERRORS EEFDRANGE Descriptor out of range. EEBADF Descriptor is invalid. EESECURITY Security violation attempted. SEE ALSO socket_accept(3), socket_create(3) MudOS Release 0.9 Last change: 11-15-92 doc/efun/socket_connect010066400004030000044000000040430534475544200156320ustar00axel_fmud00000420000006 socket_connect(3) LPC LIBRARY FUNCTIONS socket_connect(3) NAME socket_connect() - initiate a connection on a socket SYNOPSIS #include #include int socket_connect(int s, string address, string read_callback, string write_callback) DESCRIPTION The argument s is a socket. s must be either a STREAM mode or a MUD mode socket. address is the address to which the socket will attempt to connect. address is of the form: "127.0.0.1 23" The argument read_callback is the name of a function for the driver to call when the socket gets data from its peer. The read callback should follow this format: void read_callback(int fd, mixed message) Where fd is the socket which received the data, and message is the data which was received. The argument write_callback is the name of a function for the driver to call when the socket is ready to be written to. The write callback should follow this format: void write_callback(int fd) Where fd is the socket which is ready to be written to. RETURN VALUES socket_connect() returns: EESUCCESS on success. a negative value indicated below on error. ERRORS EEFDRANGE Descriptor out of range. EEBADF Descriptor is invalid. EESECURITY Security violation attempted. EEMODENOTSUPP Socket mode not supported. EEISLISTEN Socket is listening. MudOS Release 0.9 Last change: 11-15-92 socket_connect(3) LPC LIBRARY FUNCTIONS socket_connect(3) EEISCONN Socket is already connected. EEBADADDR Problem with address format. EEINTR Interrupted system call. EEADDRINUSE Address already in use. EEALREADY Operation already in progress. EECONNREFUSED Connection refused. EECONNECT Problem with connect. SEE ALSO socket_accept(3), socket_close(3), Sun Release 4.1 Last change: 2 doc/efun/socket_address010066400004030000044000000012110534475543100156160ustar00axel_fmud00000420000006 socket_address(3) LPC LIBRARY FUNCTIONS socket_address(3) NAME socket_address() - return the remote address for an efun socket SYNOPSIS #include #include string socket_address(int s) DESCRIPTION socket_address() returns the remote address for an efun socket s. The returned address is of the form: "127.0.0.1 23". RETURN VALUES socket_address() returns: a string format address on success. an empty string on failure. SEE ALSO socket_connect(3), socket_create(3) MudOS Release 0.9 Last change: 11-15-92 doc/efun/socket_create010066400004030000044000000040450534475544600154520ustar00axel_fmud00000420000006 socket_create(3) LPC LIBRARY FUNCTIONS socket_create(3) NAME socket_create() - create an efun socket SYNOPSIS #include #include int socket_create(int mode, string read_callback, string|void close_callback) DESCRIPTION socket_create() creates an efun socket. mode determines which type of socket is created. Currently supported socket modes are: MUD - for sending LPC data types using TCP protocol. STREAM - for sending raw data using TCP protocol. DATAGRAM - for using UDP protocol. The argument read_callback is the name of a function for the driver to call when the socket gets data from its peer. The read callback should follow this format: void read_callback(int fd, mixed message) Where fd is the socket which received the data, and message is the data which was received. The argument close_callback is the name of a function for the driver to call if the socket closes unexpectedly, i.e. not as the result of a socket_close(3) call. The close call- back should follow this format: void close_callback(int fd) Where fd is the socket which has closed. NOTE: close_callback is not used with DATAGRAM mode sockets. RETURN VALUES socket_create() returns: a non-negative descriptor on success. a negative value indicated below on error. ERRORS EEMODENOTSUPP Socket mode not supported. MudOS Release 0.9 Last change: 11-15-92 socket_create(3) LPC LIBRARY FUNCTIONS socket_create(3) EESOCKET Problem creating socket. EESETSOCKOPT Problem with setsockopt. EENONBLOCK Problem setting non-blocking mode. EENOSOCKS No more available efun sockets. EESECURITY Security violation attempted. SEE ALSO socket_accept(3), socket_bind(3), socket_close(3), socket_connect(3), socket_listen(3), Sun Release 4.1 Last change: 2 doc/efun/socket_accept010066400004030000044000000051250534477246100154420ustar00axel_fmud00000420000006 socket_accept(3) LPC LIBRARY FUNCTIONS socket_accept(3) NAME socket_accept() - accept a connection on a socket SYNOPSIS #include #include int socket_accept(int s, string read_callback, string write_callback) DESCRIPTION The argument s is a socket that has been created with socket_create(3), bound to an address with socket_bind(3), and is listening for connections after a socket_listen(3). socket_accept() extracts the first connection on the queue of pending connections, creates a new socket with the same properties of s and allocates a new file descriptor for the socket. If no pending connections are present on the queue, socket_accept() returns an error as described below. The accepted socket is used to read and write data to and from the socket which connected to this one; it is not used to accept more connections. The original socket s remains open for accepting further connections. The argument read_callback is the name of a function for the driver to call when there is something to read on the socket. The read call-back should follow this format: void read_callback(int fd, string message) Where fd is the socket which has the message. The argument write_callback is the name of a function for the driver to call when the new socket (not the accepting socket) is ready to be written to. The write callback should follow this format: void write_callback(int fd) Where fd is the socket which is ready to be written to. RETURN VALUES socket_accept() returns a non-negative descriptor for the accepted socket on success. On failure, it returns a nega- tive value. socket_error(3) can be used on the return value to get a text description of the error. ERRORS EEFDRANGE Descriptor out of range. MudOS Release 0.9 Last change: 11-15-92 socket_accept(3) LPC LIBRARY FUNCTIONS socket_accept(3) EEBADF Descriptor is invalid. EESECURITY Security violation attempted. EEMODENOTSUPP Socket mode not supported. EENOTLISTN Socket not listening. EEWOULDBLOCK Operation would block. EEINTR Interrupted system call. EEACCEPT Problem with accept. EENOSOCKS No more available efun sockets. SEE ALSO socket_bind(3), socket_connect(3), socket_create(3), socket_listen(3) Sun Release 4.1 Last change: 2 with the same properties of s and allocates a new file descriptor for the socket. If no pending connections are present on the queue, socket_accept() returns an error as described below. The accepted socket is used to read and write data to and from the socket which connected to this one; it is not used to accept more connections. The original socket s remains open for accepdoc/basic012077700000000000001000000000000551221311500174352/users/cardeci/doc/basic/ustar00rootother00000420000006doc/README010066400000240000044000000010270500564036300121430ustar00mudmud00000420000006This directory contains documentation about how to make new objects, and how the program works. Some short info about the different subdirectories: LPC - info on the language itself build - general guidelines and help on how to make objects efun - a complete(?) list of all the external functions that can be called by an object lfun - info on the functions that may appear in the objects and could be called by the MUD-code w - some help on the wizard commands helpdir - the files for the helpsystem in the game doc/wiz_help010066400003740000044000000012510555456525600133560ustar00hubbemud00000420000006Do 'cat /doc/w/' or 'man for more information. Wizard commands: ls cat load destruct ed clone update rm cd more pwd lac edac man Apprentice wizard commands: wizlist stat heal title goto in emote people setmin setmout setmmin setmmout review shutdown trans force to invis vis wiz zap General info about creating rooms and objects: Look in /doc/build For info on how to edit/create files locally: Type 'man ftp' doc/PLAYERKILLING010066600000240000044000000110030520350224400132040ustar00mudmud00000420000006 Killing your fellow players on NannyMUD --------------------------------------- In the original LPmud, there was no difference between monsters and players when it came to fighting and killing (except that the players usually became very annoyed with you if you killed him, and the poor monsters just died). The idea was of course that it's rather "unrealistic" to meet someone (let's say Harry) and be able to slaughter the poor man, and then you meet someone else, who happens to be a player, and suddenly some mysterious force stops your sword in the middle of your attack. Also, killing other players - and being killed by them - can be seen as a part of the game. You get experience and treasure from players you kill, just like monsters, and in the same way that you have to be careful with all those dangerous monsters, you have to be prepared for an attack from an aggressive player. On the other hand, not everyone agrees on this. One reason is of course that it's no fun to be killed, especially if you have played for a long time, maybe days and days, and you are on the verge of wizardgood - and then some stupid idiot comes and kills you just for the lousy experience - or even worse, just for fun! Arrgh! Also, the ability to kill players has been misused, here on NannyMUD. Some wizards (now ex-wizards, or soon-to-become-ex-wizards), have gone around - maybe using another, mortal, character - and killed other players, just out of maliciousness. Then there is the question of what MUD really is - is it a role-playing game where you can play a murderous orc and go around and attack everything you see, and get points for it, or is it some sort of communications program, maybe like irc, where you (the real you) say and do things in a form of virtual reality? Well, MUD is both - for example, sometimes when I play MUD, I go dragon-hunting (a game!) and sometimes I and some other people are stand in the chrch and discuss LPC programming practices (now it's a communications program!). Some of us, though, seem to be stuck in one of these views, and if a game-player attacks and kills a communications-program-user, the communications-program-user is of course angry - to him it's the same thing as if the game-player had walked up to his terminal and pulled the plug. So how do we solve this problem? Well we don't, but this is how it works on Nanny! :-) By default, a player can not attack or kill another player. This is done with some checks in the code, and is explained with a "guardian angel" that each player gets when he is born. The angel will protect you from other players who try to attack you, and it will also stop you from attacking them. There are, however, places (certain rooms) in the world where this is allowed, and in those places players can fight and kill each other all they want, since the guardian angels will be a bit slack in precisely those rooms. From the programmer's standpoint, think of it as a function called "query_playerkilling" that is defined in these rooms, and that returns a true value. If a player wants to, he can abolish his own guardian angel. This will allow him to attack other players, who also have lost their guardian angels, but not those who still have their angels. Once you have lost the angel, you can never get it back. To summarize: Playerkillers can kill each other, but they can not kill non-playerkillers except in certain rooms where playerkilling is allowed. Non-playerkillers can not kill other players, except in the playerkilling- rooms. Everyone starts out as a non-playerkiller, and a non-playerkiller can become a playerkiller, but a playerkiller can not go back to being a non-playerkiller. From the help file ("help playerkilling"): ------------------------------------------------------------ By default, a player can not attack or kill another player. Each player gets a guardian angel when he (or she or it) is born, and this angel will protect you from other players who try to attack you. It will also stop you from attacking them. There are, however, places in the world where players can kill each other without interference from their guardian angels, or from the law. One of these is the ancient place of duels, behind the village church. A player can go to the Dark Temple - also behind the village church - and abolish his guardian angel. This will allow him to attack other players, who also have lost their guardian angels, but not those who still have their angels. Once you have lost your angel, you can never get it back. ------------------------------------------------------------ doc/NANNYMUD.EFUNS010064400000240000044000000006600520750257100133200ustar00mudmud00000420000006void _destruct(object) Used to destruct an object even though the object contains bugs void _disconnect(object) Close the TCP/IP link for the player mixed *_query_action(object|string, void|string) Returns a list of actions defined for a player string _query_ident(void|object) Returns the identifier from the Identification Server Protocol for a player. int _syslog(string) Log a message in the lpmud.log file doc/templates012077700000000000001000000000000551221331700221662../players/darkmoon/doc_templatesustar00rootother00000420000006doc/Newspaper010064400003230000044000000046070535401325200135030ustar00anvilmud00000420000006 NannyMUD times walked into a new era when the new system of many separate writers was created. To help the writers in their despair this file was created. It will be kept up to date when the system gets better end more advanced. ( Hopefully ) How to become a writer. To become a writer you only need to mail a 23++, and then he will put your newsdirectory in /etc/newssources. The directory can be named as you wish, but preferable is "Newspaper". In this directory you must then put a file namned "INDEX". This file must contain the name of your section of the paper. Only the first line of that file will be used in the index of the paper. How to write articles. This may be the hard part, since you need some inspiration. Write your articles, and then format the pages. Each page must be its own file, and should never be longer than 20 lines, including your header. If an article is longer than 20 lines, split it into two or more pages. Then put the pages into your newspaperdirectory. Remember that the pages are put into the paper exactly the same way as they are listed when doing 'ls' in the directory. So, to make it simple, name your pages "page", where is the pagenumber. This pagenumber should not be confused with the pagenumber in the paper. The numbering is for your part only, it will have other numbers in the paper. So, don't put pagenumbering in the text. Next, if you want a table of contents in your section you will have to put together a file named "CONTENTS". This file must contain one line for each page in your section, either the name of the article or a blank line to indicate that the article is several pages long. How to update the paper to see your articles. Simply go to the /room/adv_inner and type 'update_paper' with the magic device present in the room. This will update the database, so it may take a while. Don't do this too often, as it takes power from the MUD, and will lag it down temporarily. Some special features. If you do not want to type in your header at the top of every page you can now have a file in your newspaperdirectory called "HEADER". This file will be printed before the main text of the article, and also before the pagenumber. As long as you don't have the file "INDEX" in the newspaperdirectory, your pages will not be included in the newspaper. If you still have questions, ask a 23++. ( Preferably Anvil ) If you have ideas, talk to Anvil. doc/RULES010066400005540000044000000566220556503505500124510ustar00karinmud00000420000006The following text contains the rules for wizards on NannyMUD. They should be used whenever you are in doubt. If, after reading them, you still don't know if something is allowed: ASK! The inforcers of these laws are the wizards with level 23 and above. NannyMUD is not a democracy. Wizards are free to debate and try to convince the inforcers, but in the end they decide. Proper punishment for breaking the rules will be decided by the wizards of level 25 and above. Repeated or major rulebreakers will probably be demoted and banished from NannyMUD, never to be seen again. Rules may be changed, added or deleted at any time by any 23++ without any notice. 1. Mortals This part contains rules on how to interact with mortal players. 1.1 Do not harm a mortal directly. This means, among other things, that you should never attack or kill a mortal. Never heal, trans or patch a monster that the mortal is fighting. 1.2 Do not help a mortal directly. This means, for example, that you must not help by killing or attacking monsters, healing mortals or giving away items, not even lost autoloading items. Your rooms or monsters can of course sell or give away items. Never teleport a mortal without very good reason. Never give away information on quests or how things are done. Never stat a monster and tell the mortal. Never stat the mortal and give him information on his condition. Never leave valuable items lying around, ie don't zap monsters and leave its weapon- containing corpse to rot in the street. Be careful when quitting the game, be sure that you do not drop items. 1.3 Do not make deadly traps. A mortal must never die because he didn't know what happens in the next room. If some room is dangerous, make a hint like the giant footprints outside the giant's lair or the smell of bear from a cave. Don't make another Kantele's snakepit. 1.4 Do not change mortals titles, stats or anything else. This means that you cannot give a mortal his level back if he has lost it in a crash. He will have to turn to the 23++. 3.10.6 is an exception from this rule, in the sense of changing mortals titles. 1.5 Do not force a mortal if it isn't utterly necessary. A case of utterly necessarity would be if you managed to drop something that mortals shouldn't have and a mortal happened to get hold of it. In this case you may force him to drop the item. 2. Wizards This part contains rules for how a wizard should behave. 2.0 If you find any bugs in the game, it is your responsibility to report them to the highwizards. This concerns bugs that gives mortals an advantage they shouldn't have. Unlimited money bugs, unlimited healing bugs, etc. 2.1 You are always responsible for what your character does. If someone sees your password and uses your char, you will be held responsible. 2.2 Testcharacters must contain the wizards name with jr, ii or test or any combination thereof appended. It is not enough to include your name in the testchars title. If your testchar doesn't follow this simple rule all you do to it will be judged as if you were doing it to a mortal, and you would be considered a cheater and be demoted. Testchars may never appear on the high-score list. The testchar may never become wizard. 2.2.1 Continued play after becoming wizard If you, after becoming a wizard, wish to start playing as a mortal again, but under a different name, be sure to let the arches know, and they will register your second character. This character may under NO CIRCUMSTANCES help normal mortal players with questsolving or puzzles! It is, however, legal to party with them and/or give them money and equipment. Your wizardcharacter may never help your second character. You may not have more than one character logged on at the same time. Just remember that it is STRICLY forbidden helping mortals with quests and puzzles and you are not either allowed to tell them about stats on monsters or equipment. 2.3 Don't have an insulting title, msgout etc. Try to keep the fantasy setting. Don't have msgouts like "jumps onto a passing plane" or "drives off in his ferrari". 2.3.1 Try to keep all text in the MUD that is written to the players in english. Be courteous to the people who do not speak or read your language. English is a must in quests and other crucial texts, but only recommended for titles, msgout, etc. 2.4 Don't misuse your powers to echo, emote, echoall etc. Never generate messages that look like something they are not. Never try to fool a mortal that someone says something when it isn't true. The game can be enough confusing anyway. This includes not sending controlcharacters. 2.5 Never snoop a mortal if not necessary. Let him have his privacy. Snooping other wizards or archwizards is not allowed. 2.6 It is important that monsters are not created with the same name as mortals. To avoid this, banish your monsters in /room/adv_guild using the command banish . If the command fails, there is already a mortal with that name. 2.7 Never put objects in the /room area. Your castle is an exception from this rule. 2.8 Your castle may not be in the village. 2.9 Always keep an eye on your .rep file and your logfile. All objects that are accessible in the world must be errorfree. 2.10 Be creative, don't make things that have already been implemented. This rule will always be used when 23++ approve things. Do not use the "This has been made before, so I will make my own similar thing, only a little cheaper and easier to get" way of thinking. 2.11 Use your common sense and when it is not enough: ASK! 23++ are there to help. 2.12 If the game crashes and you think one of your objects is responsible, don't load it again just to find out. Repeatedly crashing the game will be considered as sabotage. Talk to 23++. 3. Creating This part contains rules on what you may or may not create. If ever in doubt, talk to a 23++. If your idea will change the game and how it is played must be discussed and preferably approved. Approvals must always reside in /permissions or the item will be considered illegal and unapproved. Doubtful objects not mentioned in /permissions will be removed from the game until approved. Approvals may at a later time be reverted, depending on how the world evolves. This means that the argument "It was approved by X" will not make your object a holy one, it may still be removed from the game if circumstances are such that the object no longer fulfills the rules. 3.1 Never make mortals loose experience. The only exception from this rule is dying. 3.2 Do not create killer-monsters that can leave your castle. If you ever make a monster that can walk around outside your castle, make it a nice monster that doesn't attack players. If the monster is supposed to stroll around the world, permission must be granted from 23++. 3.3 Do not create too good things. Do not consider the wizlist a highscore list. Wizards at the top of the wizlist are the most probable targets of archwizard inquieries. This part contains rules for creating certain objects. Items worth more than 1000 coins should be very rare. No item may be worth more than 5000 and items worth close to that sum must be extremly rare. Items worth more than 5000 are too good and do not belong in this mud. 23++ may at any time adjust your object, if they are found to be too good. Too good objects are considered bugs and must be corrected at once. The wizard who made the object will be notified by mail and there will be a comment in the code stating where, when and by whom the adjustment was made. You may not revert the adjustment, but you may discuss it with 23++ and seek approval for the original object. 3.3.1 Free things Free things are defined as items just lying around, without any guardians. Items hidden or in rooms far far away are not considered as free. You may have free things in your castle. The total value of them may not exceed 500 gold coins per reset. You may not give away good weapons or armours for free. 3.3.2 Weapons Never create weapons with class higher than 20 if there is no big drawback with them. Weapons with class 20 must be at least as hard to get as the swords of the three giants in the giant conference. Weapons with class 20 and above must be approved by 23++. Never make lots of highclass weapons without a good reason, like a reward for a quest. The amount of highclass weapons in the world should be kept low. Highclass is defined as weapons with higher class than 17. Remember that if all wizards make one then there would be hundreds of them in the world. It is possible to change the hitmessage, this must always be approved by 23++. Approvals must reside in /permissions or the weapon will be considered illegal. Refer to /doc/build/weapon.list for some hints on weight and value on weapons. Refer to /doc/build/weapon on how to create a weapon. 3.3.3 Armours Bodyarmour, type "armour", should be max class 12 and all other types of armour max class 3. The class must be set with set_class, set_ac is obsolete and only kept for compatibility reasons. The difference between ac and class is class = 3*ac. If you always use set_class there will be no problem and no troubles. Also remember to make armours weigh something. A class 12 armour should be a heavy one, weighing at least 9. A wizard may be granted to create an armour with class 15, but must ask permission first. Classes differing from these figures must be approved and the permission hereof must reside in /permissions or the armour will be considered illegal. As always, highclass armour should be hard to get and its number kept low. The only allowed types of armour that can have class not equal to 0 are armour, amulet, helmet, shield, ring, glove, cloak and boot. You are free to make own new types, but try to avoid it, since your type might create a silly appearence. For instance if you use the types "cap" and "hat" instead of "helmet" we might end up with players wearing a hat, a cap and a helmet. Refer to /doc/build/armour.list for some hints on weight/value/ class on different types of armour. Refer to /doc/build/armour on how to create an armour. 3.3.4 Monsters Don't make monsters too easy to kill. A monster with much treasure and experience points should be big, dangerous and very hard to kill. Never have more than hp*wc*ac/20 coins of TOTAL value in the monster. Never put more than 1000 coins in any monster, unless it is a VERY tough one. 3.3 about adjusting will apply here. Make monsters use spells, mortals have spells, so why shouldn't monsters. Make small monsters whimpy. Remember that even though a monster is hard to kill for one person today there are draining spells that do lots of damage. This and the fact that mortals have partys makes even the toughtest monster easy. Alignment should lie between -1000 and +1000. Don't make lots of highlevel monsters, make few, really tough ones. Monsters carrying money must have a logical reason for doing so. Rabbits and other animals may not have money. Monsters differing much from stated figures must be approved and the approval must reside in /permissions or the monster will be considered illegal. Refer to /doc/build/monster.list for some hints on hp, wc, ac for monsters of different levels. Refer to /doc/build/monster for information on how to create a monster. 3.3.5 Rooms Don't make too simple rooms, make it possible for the mortals to examine things. Try to keep the fantasy setting or create a realm only accessable via gates that stop mortals from bringing objects from your setting into the world. Objects found in the world that clearly doesn't belong there will always get the creator into trouble. So, don't create plastic things. Use the function query_inorout(), that states whether a room is indoor or outdoor. Use the function realm() that states what realm the room is in. See 3.4 on teleportation. 3.3.5.1 Pubs Do not build lots of extra pubs. If you do, be sure that there is a very long walk to the nearest one. Remember that the pub is a natural meeting point and an important source of information. Remember that drinks sold must be consumed in the pub, and it must therefore be impossible to leave with unfinished drinks. See further 3.3.6 on drinks. Make sure that your pub is in the realm "NT", for no teleportation. See 3.4 on teleportation. Avoid selling unlimited amounts of drinks. 3.3.5.2 Restaurants etc Do not build lots of restaurants. If you do, be sure that there is a very long walk to the nearest one. Remember that bought food must be consumed in the restaurant, and it must therefore be impossible to leave with unfinished dishes. See 3.3.7 on food. Make sure that your restaurant is in the realm "NT", for no teleportation. See 3.4 on teleportation. Never sell unlimited amounts of food. 3.3.5.3 Shops buying things Do not build extra shops. If you want to have a shop, then ask permission of 23++. The shop, as the pub, is a natural meeting point. Never give more than 1000 gold coins for any item. The value of items is given by query_value(). Approval must reside in /permissions or the shop will be considered illegal. 3.3.5.4 Shops selling things Never have unlimited amounts of anything. Never sell things cheaper than they are sold somewhere else. Always have your shop approved. Make sure that mortals never can decide exactly how good the thing is that they are buying. Never sell swords by class, sell them good, average, poor etc. 3.3.6 Drinks Drinks that are sold may never be portable. This rule applies to both alcoholic and nonalcoholic drinks. All drinks that are sold or given out are recommended to use /obj/soft_drink and /obj/alco_drink. Always call drink_alco(strength) and drink_soft(strength) in the playerobject when the mortal drinks it. Strength is equal to the amount of healing it gives the mortal when he drinks it. The strength should never exceed 50. See 3.5 on healing. Drinks must always make the mortal less thirsty and if the drink is alcoholic, more drunk. The drinks must weigh at least 1. 3.3.7 Food Food that is sold may never be portable. All food that is sold or given out is recommended to use /obj/food. Always call eat_food(strength) in the playerobject when the mortal eats it. Strength is equal to the amount of healing it gives the mortal when eating it. The strength should never exceed 50. Food must always make mortals more stuffed. The food must weigh at least 1. See 3.5 on healing. 3.4 Teleportation Teleportation in general must be restricted. Items that lets mortals teleport must either teleport to a fix location or use the realm-mechanism. The realm of a room is defined by the function realm() in that room. The function must return a string or 0 stating the abscence of a realm. Teleportation is never allowed between different realms. Teleportation to a fix location is allowed from all realms but "NT". "NT" is the realm where teleportation never is allowed. You may not teleport a player to or from the realm "NT". If you wish to teleport-protect your room, simple make the realm "NT". Always make teleportation cost lots of spellpoints. 3.5 Healing Never make healing too easily available. It is an important part of the game that mortals have to wait for their hitpoints to regenerate. Even if mortals have to type long commands to get a little healing, they can create macros and heal almost instantly. Make the mortal drunk, not thirsty, satiated, the healing very limited, very costly or very hard to get to. Healing that can be bought may never be portable. Healpotions that cost very much, 10 000 coins or more, excepted. Healing that make players drunk etc must cost 4 gold coins per hitpoint or more. Free healing may be given as at most 20 hp/room and reset. Hard to get to is difficult to define, but slaying about 10 highlevel aggressive monsters in the same room might be considered difficult. When selling healing, you may not sell more than 3000 hp per reset. A maximum of 200 hp may be sold to one mortal per reset. The cost of this healing should be 4*x + x*x/10, where x is the amount of healing being sold. 3.6 Prices Don't make lots of highvalue items. Keep the value down to keep the inflation in this game at a minimum. Remember that other wizards are creating as well, the world is constantly growing and so is the number of items. No item should be worth more than 5000. An item worth 5000 should be very rare. Shops may never give more than 1000 coins for any item. See 3.2.4.3 on shops. 3.7 Spells All spells that you create must be approved by 23++. The permission must reside in /permissions or the spell is considered illegal. Spells must always check if the room is in the realm "no_magic" and if the property "no_magic" exists. Spells must always cost spellpoints and it should only be possible to cast one spell per heart beat. More info in /doc/build/spells. 3.8 Quests Every wizard may set up quests. Quests must always be approved by 23++. The quest must be documented on background and how to solve it. Before approval, the quest must have been testplayed by a fellow wizard. Each quest must contain a hint to be given to mortals trying to solve it. Each quest must have questpoints. Tougher quests get more questpoints. See /doc/build/QUESTS for more info on how to make a quest. All quests must contain some random events. New quests should be qualitychecked by some 23++. 3.8.1 Reward for solving quests Reward should depend on the questpoints given. There is no rule saying that one must have a reward. See 3.6, 3.3.2, 3.3.3 3.9 Puzzles Puzzles are easier quests that need not be solved to become a wizard. They don't have to be approved by 23++. Use this mechanism to give mortals an experiencereward only the first time they solve the puzzle. See /doc/build/QUESTS for more info on how to make a puzzle. 3.10 Guilds Wizards wanting to make a guild must have a guildroom where mortals can advance, join, etc. The levels of your guild must be the same as in /room/adv_guild. Always call "room/adv_guild"->query_cost_for_level(curr_level,exp). This ensures that mortals with equal experience will have the same level. Guildmakers must also have a guildobject, see 3.10.1. All features of the guild must be documented in /open/GUILDS/ under the name GUILD_. Features in your guild not documented are considered illegal. Mortals in your guild must get equally many questpoints as they would have had to do if not members of any guild. Refer to /doc/build/GUILDS for further info. All guilds and changes in guilds must be approved by the guildcoordinator. 3.10.1 Guildobject A guildobject is carried by a mortal to show that he is a member of your guild. The object need not be visible, but must have id equal to "guild_mark". The guildmark must be autoloading, weightless and not dropable. 3.10.2 Joining a guild When joining a guild it is the new guild's responsibility to check if the mortal already is a member of a guild. If he is, he may not join your guild. When joining, the mortal must be given the guildmark of your guild. From this it should be clear that mortals can only be members of one guild at the time. Level 23++ must be able to clone the guildobject to join. 3.10.3 Leaving a guild It must always be possible to leave a guild. You may have a punishment for this, but it must be known to the player before they join. The punishment may not inflict with 3.0. You may not kill or take gold coins from a mortal when leaving your guild. 3.10.4 Balance of a guild Being a member of a guild gives mortals advantages. However there must be enough disadvantages to balance the guild. A guild is balanced when the advantages and disadvantages taken together makes the guild no more powerful than mageguild. 3.10.5 Advantages of being in a guild There may be a free tell to other members of the guild and also an infochannel for all guildmembers, much like the wizline. You may have special rooms where only your guildmembers can go. 3.10.6 Titles The guild may give the members special titles for each level. The title must begin with the name of the player. 3.11 Clubs Clubs are a kind of guilds, but they don't give many features and advantages. They may not have free tells/channel, but may give a member tell at the cost of 3 sp and a channel at the cost of 15 sp. They may not have any attackspells or healingspells. Clubs should have a background and a purpose. Mortals may be member of many clubs. There is no spellpoint reduction for being a member of a club. Also read /doc/build/CLUBS. 3.11.1 Clubobject A clubobject is carried by a mortal to show that he is a member of your club. The object need not be visible, but must have an id equal to "club_mark". The object must be autoloading, weightless and not dropable. 3.11.2 Joining a club When joining a club you must give the mortal a clubobject. This for making it easy to keep track of which clubs the mortal is a member in. 3.11.3 Leaving a club It must always be possible to leave a club. You may not punish the mortal for leaving your club. 3.11.4 Advantages of being in a club You may have special rooms where only clubmembers can go. 3.12 Souls Objects giving feelings to mortals are not allowed. /obj/soul is there for this purpose. If you invent a new feeling, mail 23++ about it and it will be added to the standard soul. It is now possible to patch in new adverbs and feelings directly into /obj/soul and thus you need not have a separate soul in your guild. See /doc/build/feelings for further info. See also 3.15 on autoloading objects. 3.13 Hp/Sp info Items giving players information on their current hp/sp status periodically are not allowed. There is a command hpinfo for giving this service. 3.14 Emote It is not allowed to give mortals objects that give them the power to emote. It is allowed to have this command at fixed locations. 3.15 Autoloading objects Autoloading objects that are accessible for mortals must be approved, and the approval must reside in /permissions or the object is considered illegal. 4.7.11 Mis- and overused shouts, echoalls etc. Certain listed wizards may not shout, nor echoall, nor use any other means to communicate with all players simultaneously since they have misused those abilities. The wizards not allowed to use these commands are: want to have a shop, then ask permission of 23++. The shop, as the pub, is a natural meeting point. Never gdoc/help010066400000240000044000000012410554216755200121460ustar00mudmud00000420000006COMMUNICATIONS: say , shout , tell , converse INFO: rules, score, help, who, i (inventory), email, hpinfo, coins OTHER: password , bug , typo , idea , praise save, quit, brief, wimpy, give to , get [from ], email [
], Finger , Plan , News on|off ATTACKS: kill , stop (hunting), OTHER TOPICS: 'help spell' or 'help abilities' for more info. Other topics: stats levels spell feelings syntax abilities quests playerkilling *** Note - A mortal should know the rules (help rules). Violation of them may lead to demotion or other punishments. doc/intermediate012077700000000000001000000000000551221342400224222/users/cardeci/doc/intermediate/ustar00rootother00000420000006doc/newmapp.txt010066400006540000044000000024560552146650600145270ustar00celebornmud00000420000006Welcome to NannyMud ------------------- The mud contains of more than 16000 rooms, and many of them are illogically connected. Anyway, here is a map of the city just to get you started: | | (1) (A) | | | \| | | | | -(2)-(3)-(4)-(5)-(6)-(7)-(8)----(9)----(L)----(M)-( )-( )- | | | | | | | | (B)-(C)- (S)-(N) 1-Orc Cave. | | 2-Orc Valley -(D)- (P)-(O)- 3- | 4- -(E)- 5-A small Cleaning. | 6-Forest. -(F)- L-Track going into Village. 7-Wilderness. | M-Village Road. 8-Humpbacked Bridge. -(G)- N-Narrow Alley 9-Open Green Place. | O-Narrow Alley. A-The Church! -(H)- B-Box Service. | C-Lane of Ingis. -(I)- D-Lane of Ingis. | E-Lane... -(J)- F-Country Road. | G-Country... -(K)- H-Track in Wilderness. | I-Path over a plain. J-Narrow pass K-South Coast solve the puzzle. See /doc/build/QUESTS for more info on how to make a puzzle. 3.10 Guilds Wizards wanting to make a guild must have a guildroom where mortals can advance, join, etc. The levels of your guild must be the same as in /room/adv_guild. Always call "room/adv_guild"->query_cost_for_level(curr_level,exp). This ensures that mortals with equal experience will have the same level. Guildmakers must also have a guildobject, see 3.10.1. All features of the guild must be documented in /open/GUILDS/ under the name GUILD_. Features in your guild not documented are considered illegal. Mortals in your guild must get equally many questpoints as they would have had to do if not members of any guild. Refer to /doc/build/GUILDS for further info. All guilds and changes in guilds must be approved by the guildcoordinator. 3.10.1 Guildobject A guildobject is carried by a mortal to show that he is a member of your guild. The object need not be visible, but must have id equal to "guild_mark". The guildmark must be autoloading, weightless and not dropable. 3.10.2 Joining a guild When joining a guild it is the new guild's responsibility to check if the mortal already is a member of a guild. If he is, he may not join your guild. When joining, the mortal must be given the guildmark of your guild. From this it should be clear that mortals can only be members of one guild at the time. Level 23++ must be able to clone the guildobject to join. 3.10.3 Leaving a guild It must always be possible to leave a guild. You may have a punishment for this, but it must be known to the player before they join. The punishment may not inflict with 3.0. You may not kill or take gold coins from a mortal when leaving your guild. 3.10.4 Balance of a guild Being a member of a guild gives mortals advantages. However there must be enough disadvantages to balance the guild. A guild is balanced when the advantages and disadvantages taken together makes the guild no more powerful than mageguild. 3.10.5 Advantages of being in a guild There may be a free tell to other members of the guild and also an infochannel for all guildmembers, much like the wizline. You may have special rooms where only your guildmembers can go. 3.10.6 Titles The guild may give the members special titles for each level. The title must begin with the name of the player. 3.11 Clubs Clubs are a kind of guilds, but they don't give many features and advantages. They may not have free tells/channel, but may give a member tell at the cost of 3 sp and a channel at the cost of 15 sp. They may not have any attackspells or healingspells. Clubs should have a background and a purpose. Mortals may be member of many clubs. There is no spellpoint reduction for being a member of a club. Also read /doc/build/CLUBS. 3.11.1 Clubobject A clubobject is carried by a mortal to show that he is a member of your club. The object need not be visible, but must have an id equal to "club_mark". The object must be autoloading, weightless and not dropable. 3.11.2 Joining a club When joining a club you must give the mortal a clubobject. This for making it easy to keep track of which clubs the mortal is a member in. 3.11.3 Leaving a club It must always be possible to leave a club. You may not punish the mortal for leaving your club. 3.11.4 Advantages of being in a club You may have special rooms where only clubmembers can go. 3.12 Souls Objects giving feelings to mortals are not allowed. /obj/soul is there for this purpose. If you invent a new feeling, mail 23++ about it and it will be added to the standard soul. It is now possible to patch in new adverbs and feelings directly into /obj/soul and thus you need not have a separate soul in your guild. See /doc/build/feelings for further info. See also 3.15 on autoloading objects. 3.13 Hp/Sp info Items giving players information on their current hp/sp status periodically are not allowed. There is a command hpinfo for giving this service. 3.14 Emote It is not allowed to give mortals objects that give them the power to emote. It is allowed to have this command at fixed locations. 3.15 Autoloading objects Autoloading objects that are accessible for mortals must be approved, and the approval must reside in /permissions or the object is considered illegal. 4.7.11 Mis- and overused shouts, echoalls etc. Certain listed wizards may not shout, nor echoall, nor use any other means to communicate with all players simultaneously since they have misused those abilities. The wizards not allowed to use these commands are: want to have a shop, then ask permission of 23++. The shop, as the pub, is a natural meeting point. Never gdoc/help010066400000240000044000000012410554216755200121460ustar00mudmud00000420000006COMMUNICATIONS: say , shout , tell , converse INFO: rules, score, help, who, i (inventory), email, hpinfo, coins OTHER: password , bug , typo , idea , praise save, quit, brief, wimpy, give to , get [from ], email [
], Finger , Plan , News on|off ATTACKS: kill , stop (hunting), OTHER TOPICS: 'help spell' or 'help abilities' for more info. Other topics: stats levels spell feelings syntax abilities quests playerkilling *** Note - A mortal should know the rules (help rules). Violation of them may lead to demotion or other punishments.