Originally appeared in: Merc release 2.2 Wednesday 24 November 1993 N'atas-Ha natasha@gs118.sp.cs.cmu.edu Kahn Modified for ROM 2.4 in January 1996 Newt@Imperium Gothique Modified for Feudal Realm (9/25/2004) Moeve Rockbrain TABLE OF CONTENTS The Basic Idea About This Version MOBprogram Syntax Linking MOBprograms Trigger Types Variables Control Flow Syntax Operators If_checks in Control Flow New Commands of Interest Regarding CPU Slowdown Loading Mobiles and Objects Miscellaneous Information -------------------------- Quick Reference Sheet Examples -----------------------------The Basic Idea--------------------------------- Ever wonder why most muds either seem dead or overcrowded? The answer is probably partially due to the fact that the mobiles never do anything but wait to be slaughtered. Unless someone has gone to great lengths and added many special procedures, most mobiles have no idea you are in the room with them and rarely listen to what you say. The typical Midgaard mayor wanders happily along even when the populace pokes him, waves his City Key about, unlocks his gates, or frenchs his secretary, etc. So a way to give the mobiles a bit more spirit would be neat. Enter the MOBprograms. TRIGGERS AND SCRIPTS The backbone of the MOBprograms shall be called triggers from this point on. Essentially, they are procedure calls placed in sneaky places in the mud code which provide the context for what is going on around the mobile. So, if something happens in the mobile's room and a trigger is activated, then a list of commands is sent to the interpreter in the mobile's name, thus making her/it/him do an appropriate something. VARIABLES Since knowing the appropriate response for every mobile to every possible trigger is not easy, this command list shouldnt be a rigid script, but needs to be somehow unique for the mobile and the situation. However, in order to know the situation, a mobile needs to know more about the trigger than that it just happened. So, we have to include some sort of variables as well to set the context appropriately. MOBPROGRAMS VS. SPEC_PROCS As most implementors know, most area creators are not versed in coding, but usually have great ideas. Therefore, whatever system is used needs to be quite simple. This is not to demean creators in anyway. Simply, it is useless to have a powerful system, if the only person able to write anything is someone who finds C coding in general to be exciting and non frustrating. If that is going to be the case, then stick to the special procedures, since there is no bound to what a complex special procedure can accomplish. Yet, from experience working on several muds, most admins and implementors prefer not to be writing one shot spec_procs to satisfy the needs of their creators. Thus, the basic idea: let mobiles react to a myriad of mud events/situations by having them perform a list of commands which can be tailored to the moment through a simple and unintimidating scheme usable by any creator. ---------------------------About This Version------------------------------- My implementation of MOBprograms owes a lot to the original MOBprogram code by Natasha. However, having heard reports about unstability of the code supplied, and because the code seemed unnecessarily complex to me, I decided to rewrite the MOBprogram driver. Admittedly, I have dropped out several features that were present in the original version, such as reacting to several triggers at once and string comparison in if_checks. On the other hand, the MOBprogram code has been simplified and made more stable (there are no memory leaks), and several new if_checks and MOBcommands have been added. The system of linking MOBprograms to mobiles has been changed to allow procedure-like calls. This version is an adaptation of my earlier MOBprogram system I created for Imperium Gothique MUD. The IG system has object and room programs as well, but I chose to omit them from this version. -- Newt ----------------------------MOBprogram Syntax-------------------------------- The simplest way to describe any syntax is by example, so here goes. First, define the notation: anything contained in braces {} is required, anything in brackets [] is optional, anything in quotes "" is a case insensitive literal, NL refers to a required new-line. The meanings of the labels used will be described following the syntax diagram. To use MOBprograms, you must add a #MOBPROGS section(s) to your area file(s). Section syntax: #MOBPROGS #{Vnum} {program_command_1} NL {program_command_2} NL {program_command_3} NL . . . {program_command_N} NL "~" NL . . . #0 -- Explanations A VNUM is the MOBprogram virtual number that identifies the program the number must be unique across area files (like mobile and object vnums). A PROGRAM_COMMAND can be any legal mud command, or a control flow command. NOTE 1: Any whitespaces (space, tab, newline) are NOT stripped from the programs when loading the database (why? because I'm too damn lazy to have implemented it). Thus, to save memory and execution time, omit all unnecessary spaces from your MOBprogram scripts. If you must have indentation, use TAB. NOTE 2: MOBprograms do NOT have to be in the same area file as the mobile definitions, since the programs are linked to the mobiles after the database has been loaded. A MOBprogram can also be used as a subroutine (see MOB CALL command) without having to be linked to any mobile. -- Example #MOBPROGS #3001 say Hey, no loitering! poke $n ~ #0 --------------------------Linking MOBprograms-------------------------------- Once you've written your MOBprograms, you must link the programs to appropriate mobiles. In the #MOBILES section, for each mobile you wish to have a MOBprogram, add lines of the following type to the end of the mobile definition: "M" {Keyword} {Vnum} {Argument}~ NL --Explanations The KEYWORD is a single word, see below for explanations. The VNUM is the MOBprogram virtual number. The ARGUMENT is the argument that triggers the event. --Example M act 3001 sits down~ In the above example, an ACT trigger is defined. When the mobile sees someone sitting down in the room, the mobile will execute program number 3001 (defined in #MOBPROGS section). NOTE: Several mobiles can use the same MOBprogram, i.e. MOBprograms can be SHARED with several mobiles. The keyword and trigger argument can be different for each mobile even if they share the same MOBprogram code. -----------------------------Trigger Types---------------------------------- Here's a summary of triggers: Triggers are fairly easy to add, but this basic list should hold for most needs. Their names, argument list syntaxes, and translation into more articulate English are given below: ACT Keyword : 'act' Argument: string The argument is a phrase, a text string. The trigger is activated whenever the phrase is contained in the act() message. NOTE: Most general trigger. Applies to almost every event which happens in the mud. Anytime the function act() is called with a message to be delivered TO_CHAR,TO_VICT,TO_ROOM,etc. the act can be triggered. Basically this will trigger on almost everything you'll ever want. Output of "say", "shout" and "emote" do not trigger this event. SPEECH Keyword : 'speech' Argument: string NOTE: This is only triggered when the phrase is contained in a message which has been said by a PC in the same room as the mob. The PC restriction is not necessary, but makes infinite loops between two talking mobiles impossible. It also makes it impossible for two NPC's to stand and discuss the weather however. RANDOM Keyword : 'random' Argument: number The argument is a number between 0 and 100 inclusive. NOTE: This trigger is checked at each PULSE_MOBILE and if the argument is greater than a percentage roll the trigger is activated. This will happen even if there is no PC in the room with the mob, but there must be players in the same area. It is useful to give mobiles a bit of a personality. For instance a janitor who stops to spit tobacco, or complain about the hours, or wonder why there are no woman janitors on muds, or a fido which barks or growls or pees on the curb is much more alive than one which just sits there scavenging. Note that this trigger is checked only when there are players in the area. If you want this event to be triggered always, you must set the ACT_UPDATE_ALWAYS flag of the mobile. GREET/GREET ALL Keyword : 'greet' Argument: number Argument is the exit number (0:north, 1:east, 2:south, 3:west, 4:up, 5:down, -1:portal, 100:any) NOTE: Whenever someone enters the room with the mobile, through a room through an exit indicated by the argument, and the mobile saw the person enter, this is checked. Good for shopkeepers who want to welcome customers, or for pseudo-aggressive mobiles which need to discriminate on who they attack. Greet trigger activates only when the mobile is not busy (fighting, sitting, sleeping etc.). If you want to be sure to catch all players, use grall. Immortals, even when visible, do not trigger this. Keyword : 'grall' Argument: number Argument is the exit number (0:north, 1:east, 2:south, 3:west, 4:up, 5:down, -1:portal, 100:any) NOTE: Like greet, but it can be triggered even if the mobile didn't see the arrival (i.e. sneak, invis, etc) or is busy. Most useful for faking teleport rooms or for impassable guardians. Immortals, even when visible, do not trigger this. ENTRY Keyword : 'entry' Argument: number Again a percentage argument. NOTE: The opposite of greet trigger. Whenever the mobile itself enters a new room, this can be triggered. Useful for looking around, or waving or other things that real PCs do when they arrive at a crowded room. IMPORTANT: In an entry program, the mobile can only refer to a random pc ($r in if checks) -- there's no way to know how many PCs exist in the room the mobile enters! Also, you must check visibility of the target in your program. EXIT/EXIT ALL Keyword : 'exit' Argument: number Argument is the exit number (0:north, 1:east, 2:south, 3:west, 4:up, 5:down) NOTE: The opposite of entry trigger. This is activated when PC tries to leave a room through an exit indicated by the argument, and the mobile sees the person leave. Useful for having a single guardian to watch several exits. An exit trigger works better than an entry trigger, since you can refer to a specific PC instead of a random PC. IMPORTANT: If this event is triggered, the victim will not move through the exit. If necessary, you must move the character yourself in your program (see MOB TRANSFER/MOB GTRANSFER). Also, this event is not triggered when a character flees from combat or the mobile is not in its default position. Immortals, even when visible, do not trigger this. Keyword : 'exall' Argument: number Argument is the exit number (0 = north etc.) The same as exit trigger, but it can be triggered even if the mobile cannot see the person trying to leave the room or if the mobile is busy. Immortals, even when visible, do not trigger this. GIVE Keyword : 'give' Argument: string or object vnum The argument is either the a string containing words to be matched against the keywords of the object, or the word "all"; e.g. argument "long sword" will match to objects "long bow" and "small sword". Alternatively, the argument can be the virtual number of a single object. NOTE: This is triggered whenever something is given to the mobile. Best used for quests. Since the first successful trigger is the only one of this type which is processed, having an "all" argument in the script at the end of the MOBprogram list is essentially a default response. Variables: mob, ch, obj BRIBE Keyword : 'bribe' Argument: number The argument is any positive integer number. NOTE: This trigger is activated whenever money is given to the mobile. If the amount given exceeds the number, then process the commands. Note again, that an argument of '1' would act as a default response. Also note that if the script is not triggered (because of too little money having been given), the mobile still keeps the money... ROM 2.4 NOTE: Since ROM 2.4 has two different types of currency (gold and silver coins), for bribe trigger the amount to be given is converted to silver coins with the rate of 1 gold = 100 silver. Thus, the number in the argument should be the expected amount in silver coins. FR NOTE: For multiple bribe triggers, the trigger with the largest value, which is less than the amount given to the mobile will be triggered. For example, if the mobile has two programs, one triggered by 10 coins which make the mobile laugh and one triggered by 100 coins which makes the mobile beam, then the mobile will do nothing if given less than 10 coins; the mobile will laugh if given 10 through 99 coins and beam for any amount greater than 100. KILL Keyword : 'kill' Argument: number The argument is a percent once again. NOTE: This trigger is checked whenever a PC attacks the mobile. The check occurs only ONCE, in the beginning of combat. Useful for summoning assistance etc. (See MOB MLOAD). FIGHT Keyword : 'fight' Argument: number The argument is a percentage. NOTE: Useful for giving mobiles combat attitude. It is checked every PULSE_VIOLENCE when the mobile is fighting. Can be used to cast spells (see MOB CAST), curse at the opponent, or whatever. Only the first successful one will be processed to save time. Also, this means that the mobile wont get lucky and 1. curse, cast a fireball and 2. spit on the player, cast another fireball in the same pulse. HIT POINT PERCENTAGE Keyword : 'hpcnt' Argument: number The argument is a percentage. NOTE: Is activated at each PULSE_VIOLENCE when the mobile is fighting. It checks to see if the hitpoints of the mobile are below the given percentage. Multiple hpcnt triggers should be listed in increasing order of percent since a 40% will always be activated before a 20% and, only the first successful trigger is performed. DEATH Keyword : 'death' Argument: number The argument is a percent once again. NOTE: When the mobile dies, if the random percentage is less than the argument the mobile performs the MOBprogram commands rather than the usual death_cry() sequence. This is done before the corpse is made, so the commands can be considered the mobiles last gasp. It could perhaps destroy the items it was holding (see MOB REMOVE and MOB JUNK), or create some (see MOB OLOAD), or cast a spell (see MOB CAST) on the killer and the room, or even goto a new location (see MOB GOTO) and die there (with a text message, the corpse would seem to vanish) The position of the mobile is set to STANDING, and so it can do all the normal commands, without worrying about being DEAD. However, even if the mobile restores itself to full hitpoints, it will still die. This is not a way to immortal mobiles. However, the last thing this mobile does could be to goto some vacant room, load a fresh version of itself, drop all its items, force the new mobile to get all the items and wear them, send the new mobile back to the character who killed it and force the new mobile to attack that character. Along with a text message which said the mobile restored itself, this might be a convincing effect. (Note that your kitten could turn into a dragon this way too). DELAY Keyword : 'delay' Argument: number The argument is a tag. NOTE: This trigger activates when the delay of a mobile (set with the MOB DELAY command) expires. This trigger can be used to create staged mobile behavior, for example, a guardian could see a player entering a room, give a warning and activate a delay. If the player is still present when the delay expires, the guard would attack the player. (See also MOB REMEMBER). A mobile can have several delay triggers, but every time the delay timer expires, all the triggers are checked and the first one whose tag matches the delay is executed. SURRENDER Keyword : 'surr' Argument: number The argument is a percentage. NOTE: This trigger activates when the mobile is fighting and the opponent issues a "surrender" command. When triggered, both parties will cease fighting, and the mobile can accept the surrender (perhaps taking all equipment from the character with MOB REMOVE). Note that if the mobile does not accept the surrender, it must resume fighting with MOB KILL. If a character surrenders and the mobile does not have a surrender trigger, or the trigger does not activate, the fight resumes normally. FR NOTE: this trigger does not active on Feudal Realms. MOUNT Keyword : 'mount' Argument: string The argument is the event name: 'mount', 'dismount', 'fall', or 'attack'. NOTE: This trigger activates when the mobile is mounted, dismounted or when a rider falls off the horse or is attacked by the horse. This is done before messages regarding the mount state are sent to the rider and the room. The MOBprogram cannot change the state of the mount, i. e., the character has already rolled a successful mount. This is useful for changing the messages send to the rider and the room. TIME Keyword : 'time' Argument: number A time value (1/6 th of an hour). NOTE: Same of the object time trigger FLEE Keyword : 'flee' Argument: none NOTE: This trigger activates whenever a character who is fighting with the mobile attempts to flee. Similarly to exit triggers, this trigger does not let the character flee. If you wish to make the character flee you have to transfer him/her in the program. SPECIAL Keyword : 'special' Argument: none NOTE: This trigger activates whenever a ROM special function invokes a mobprogram on the mobile. ROM special functions that invoke mobprogram are usually specific to an area and purpose. NOTE: No MOBprograms will be successful when the mobile is charmed (since it has no self volition, it should act like it has none) to protect mobiles which are given special powers from being implemented by a player. ---------------------------Trigger Summary--------------------------------- Trigger | Player | Must| Default | | Trigger | see | Position | - - - - -|- - - - -|- - -|- - - - - |- - - - - - - - - - - - - - - - - - - ACT | yes | no | no | SPEECH | yes | no | no | RANDOM | no | no | yes | GREET | yes | yes | yes | GRALL | yes | no | no | ENTRY | no | no | no | EXIT | yes | yes | yes | EXALL | yes | no | no | GIVE | yes | no | no | BRIBE | yes | no | no | KILL | yes | no | no | FIGHT | | no | no | HPCNT | | no | no | DEATH | | no | no | DELAY | no | no | yes | MOUNT | yes | no | no | TIME | no | no | no | SPECIAL | | | | - - - - -|- - - - -|- - -|- - - - - |- - - - - - - - - - - - - - - - - - - ------------------------------Variables------------------------------------ To make things come alive, variables are needed. These are represented in the MOBprograms by using a dollar sign convention as in the socials. When the mud command is processed, these variables are expanded into the values shown below. Usually, it is best to use the short descriptions of mobiles and the names of players when speaking them, but if you are performing an action to someone almost always you want the name. The title field for players is an extra that probably wont often be used. Without further hesitation... the variables: $i the first of the names of the mobile itself. $I the short description of the mobile itself. $n the name of whomever caused the trigger to happen. $N the name and title of whomever caused the trigger to happen. $t the name of a secondary character target (i.e A smiles at B) $T the short description, or name and title of target (NPC vs PC) $r the name of a random PC in the room with the mobile $R the short description, or name and title of the random PC $q the name of the MOBprogram target (see MOB REMEMBER) $Q the short description of the MOBprogram target $j he,she,it based on sex of $i. $e he,she,it based on sex of $n. $E he,she,it based on sex of $t. $J he,she,it based on sex of $r. $X he,she,it based on sex of $q. $k him,her,it based on sex of $i. $m him,her,it based on sex of $n. $M him,her,it based on sex of $t. $K him,her,it based on sex of $r. $Y him,her,it based on sex of $q. $l his,hers,its based on sex of $i. $s his,hers,its based on sex of $n. $S his,hers,its based on sex of $t. $L his,hers,its based on sex of $r. $Z his,hers,its based on sex of $q. $u the noble title of $n. $v the noble title of $t. $w the noble title of $r, a random PC. $f the noble title of $q, the MOBprogram target. $U the house rank of $n. $V the house rank of $t. $W the house rank of $r. $F the house rank of the MOBprogram target. $o the first of the names of the object (GIVE trigger) $O the short description of the object Also, in if_checks, the accepted variables are the basic ones (i,n,t,r,o,q). If a variable is referenced that doesnt exist, then the value is replaced with "<@@@>", "_something" or "_someones" in output (i.e referring to $o when the trigger is: A kisses B) If variable $q has not been defined, it is automatically set to the last player that has triggered the program being executed (i.e. variable $n). Once $q has been defined, it can be modified with MOB REMEMBER and MOB FORGET commands in a program. Variable $q lets the mobile "remember" a player across different programs, which can be useful. Note that $q is set automatically only the FIRST TIME the mobile executes a program, every time thereafter it must be set with MOB REMEMBER. The only problem with the variables is that the secondary object and the secondary target are passed by act() in the same location. This means that if you reference $t in an A puts B in C situation, the result will probably be a happy mud crash or some weird side effect, espescially if $t is used in an if_check (i.e. if isnpc($t) in the above situation) The basic fix for this is to change everyone who calls the act() procedure to specify a secondary object and a secondary character. But that is a fairly comprehensive trivial twiddle, so we left it the way it is so that, you arent forced to make all those twiddles to use the MOBprograms. The variables $t, $T, $E, $M, $S, $V are only available for mobprograms triggered by act. In Feudal Realms mobprograms triggered by ACT do not set any variable other than $i, the mobile itself, and $n, the character which caused the trigger to happen. Thus the variable $t is never available. Only mobprograms triggered by GIVE set the variable $o. ---------------------------Control Flow Syntax------------------------------ In place of any legal mud command in a MOBprogram, one can substitute a flow of control command. Here is the syntax for a flow of control command. The parts between [ and ] are optional. "if" " " {if_check_1} {argument} [ {operator} {value} ] NL [ "or" " " {if_check_2} {argument} [ {operator} {value} ] NL ] [ "or" " " {if_check_N} {argument} [ {operator} {value} ] NL ] . . . [ "and" " " {if_check_N} {argument} [ {operator} {value} ] NL ] [ "and" " " {if_check_N} {argument} [ {operator} {value} ] NL ] . . . [ {program_command_1} NL ] [ {program_command_2} NL ] . . . [ "break" NL ] . . . [ {program_command_N} NL ] [ "else" NL ] [ {program_command_1} NL ] [ {program_command_2} NL ] . . . [ "break" NL ] . . . [ {program_command_N} NL ] "endif" NL Basically, it is: an 'if' line, followed by zero or more 'or' lines, followed by zero of more 'and' lines ('and' and 'or' lines can be in any order) followed by zero or more legal mud commands, which may contain a 'break' line, possibly followed by an 'else' line , followed by zero or more legal mud commands, which may contain a 'break' line, followed by an 'endif' line. The only new syntax labels are all in the IF/OR/AND line: --Explanations An IF_CHECK is a string which describes under what context to compare things. The ARGUMENT is the reference point from which the LHS of an expression comes. The OPERATOR indicates how the LHS and RHS are going to be compared. The VALUE is the RHS of the expression to be compared by the operator. The BREAK command bails out of the entire MOBprogram regardless of the level if nesting. (END is a synonym for BREAK). If that looks confusing, skip to the end of the document and review the examples. Hopefully that should clear things, otherwise you'll probably have to give me a mail since examples are the best way I know to explain syntax. --Debugging The 'debug' keyword, followed by a new line will broadcast on wiznet:mobprog a line by line account of your program. --Comments Comments are line which start with an asterisk (*). --------------------------------Operators----------------------------------- Most of the basic numeric operators are legal and perform the same function as in C. Operators: == != > < >= <= ------------------------If_Checks In Control Flow--------------------------- The provided list of if_checks and their arguments are below. They should all be fairly obvious in what they do, but some of the more obtuse deserve a slight explanation. Any '==' operator can be replaced with any of the available ones described above. The argument $* refers to any of the variables which make sense for that if_check (i.e. for an if_check which is referencing a person the only valid variables would be $i, $n, $t, $r or $q) A value type of string is a sequence of characters. It does not need to be included in quotes or anything like that (i.e. if name $n fido ) There are five types of if checks: Type 1: Keyword and value rand num Is random percentage less than or equal to num mobhere vnum Is a NPC with this vnum in the room mobhere name Is a NPC with this name in the room objhere vnum Is an object with this vnum in the room objhere name Is an object with this name in the room mobexists name Does NPC 'name' exist somewhere in the world objexists name Does object 'name' exist somewhere in the world Type 2: Keyword, comparison and value people == integer Is the number of people in the room equal to integer players == integer Is the number of PCs in the room equal to integer mobs == integer Is the number of NPCs in the room equal to integer clones == integer Is the number of NPCs in the room with the same vnum as the NPC who activated the program equal to integer order == integer Is the order (of several similar NPCs) of the NPC who activated the trigger equal to integer hour == integer Is the hour (game time) equal to integer Type 3: Keyword and actor isnpc $* Is $* an NPC ispc $* Is $* a PC isgood $* Does $* have a good alignment isneutral $* Does $* have a neutral alignment isevil $* Does $* have an evil alignment isimmort $* Is $* an immortal (level of $* > LEVEL_HERO) ischarm $* Is $* affected by charm isfollow $* Is $* a follower with their master in the room isactive $* Is $*'s position > POS_SLEEPING isdelay $* Does $* have a delayed MOBprogram pending isvisible $* Is $* visible to NPC who activated the program hastarget $* Does $* have a MOBprogram target in the room istarget $* Is $* the target of NPC who activated the program ispthief $* Is $* a player flagged as thief isoutlaw $* Is $* a player flagged as outlaw ishostile $* Is $* a player flagged as hostile Type 4: Keyword, actor and value affected $* 'affect' Is $* affected by 'affect' act $* 'act' Is $*'s ACT bit 'act' set off $* 'off' Is $*'s OFF bit 'off' set imm $* 'imm' Is $*'s IMM bit 'imm' set carries $* 'name' Is $* carrying object 'name' carries $* 'vnum' Is $* carrying object of this vnum wears $* 'name' Is $* wearing object 'name' wears $* 'vnum' Is $* wearing object of this vnum has $* 'type' Does $* have object of item_type 'type' uses $* 'type' Is $* wearing object of item_type 'type' name $* 'name' Is $*'s name 'name' pos $* 'position' Is $*'s position 'position' (sleeping etc.) clan $* 'name' Does $* belong to clan 'name' race $* 'name' Is $* of race 'name' class $* 'name' Is $*'s class 'name' objtype $* 'type' Is $*'s item_type 'type' marked $* 'vnum' Is $* marked by vnum isfollowed $* 'name' Is $* followed by name isfollowed $* 'vnum' Is $* followed by a mob of this vnum isordo1 $* 'string' Is $*'s ordo1 'string' isordo2 $* 'string' Is $*'s ordo2 'string' isordo3 $* 'string' Is $*'s ordo3 'string' isguild $* 'string' Is $*'s guild 'string' Type 5: Keyword, actor, comparison and value vnum $* == integer Is $*'s virtual number equal to integer hpcnt $* == integer Is $*'s hitpoint percentage equal to integer room $* == integer Is vnum of the room $* is in equal to integer area $* == integer Is the area $* is in equal to integer zone $* == integer Is the zone $* is in equal to integer sex $* == integer Is $*'s sex equal to integer level $* == integer Is $*'s level equal to integer align $* == integer Is $*'s alignment equal to integer money $* == integer Does $* have money (in silver) equal to integer objval# $* == integer Is $*->value[#] equal to integer (# from 0-4) NOTE: The original MERC 2.2 MOBprograms used parenthesis '(' and ')' around variables. In this version, they are not allowed. Also,parameters MUST BE separated with spaces (if level $n<10 is NOT valid, correct syntax is: if level $n < 10). ------------------------New Commands Of Interest----------------------------- 1. GENERAL COMMANDS Syntax: SURRENDER This command can be issued in combat. If the one giving the command is a PC and the opponent is a NPC, the NPC will be checked for a surrender trigger. If the trigger activates, the fight will be terminated. Otherwise the combat will resume normally. Note that the mobile can resume the combat in the MOBprogram (see MOB KILL). If anyone (PC or NPC) surrenders to a PC, the combat will terminate. The PC can resume the combat with 'kill' command. With this command, and the use of surrender trigger, non-lethal combat can be implemented (arenas etc.). 2. DIAGNOSTIC COMMANDS These two new commands are available to immortal players. Syntax: MPSTAT [mobile] Displays the triggers and MOBprogram vnums defined for the mobile. Syntax: MPDUMP [vnum] Displays the MOBprogram code of given vnum. 3. MOBCOMMANDS MOBcommands are special commands that allow mobiles to perform immortal-like actions within a MOBprogram (transferring players or loading items, for example). Most MOBcommands them are wiz commands which have been changed to allow for mobiles to perform the commands. In this version of MOBprograms, players have been prevented from using these commands by adding a separate interpreter for MOBcommands. This also speeds up (in most cases) MOBprogram execution when MOBcommands are used. All MOBcommands are preceded with the word 'MOB' on the command line. Syntax: MOB ASOUND [string] MOB ZECHO [string] MOB GECHO [string] ASOUND prints the text string to the rooms around the mobile in the same manner as a death cry. This is really useful for powerful aggressive and is also nice for wandering minstrels or mobiles like that in concept. ZECHO prints the string to all players in the same area with the mobile. GECHO prints the string to all players in the game. Syntax: MOB ECHO [string] MOB ECHOAT [victim] [string] MOB ECHOAROUND [victim] [string] ECHO displays the string to everyone in the room. ECHOAT displays the string to the victim only. ECHOAROUND displays the string to everyone except the victim. The three options let you tailor the message to goto victims or to do things sneaky like having a merchant do: mob at guard mob echoat guard rescue_please This coupled with a guard act trigger on rescue_please to: mob goto $n mob echo $I has arrived. It is an affective way of quickly bringing guards to the scene of an attack. (Note that the merchant has to be the only one of its kind in the game or have a unique name, otherwise the guard might go to different mobile...). Syntax: MOB MLOAD [vnum] MOB OLOAD [vnum] {'room'|'wear'} MLOAD creates a mobile and places it in the same room with the mobile. OLOAD loads the object into the inventory of the mobile. Even if the item is non-takable, the mobile will receive it in the inventory. This lets a mobile distribute a quest item or load a key or something. The optional 2nd parameter can be specified; 'room' means to load the object to the room, 'wear' means to force the mobile to wear the object loaded (useful for equipping mobiles on the fly). The object does not load if doing so would exceed load limits. Syntax: MOB KILL [victim] {'unseen'} Lets a mobile kill a player without checking the rules for attacking. Lots of MOBprograms end up with mpkill $n commands floating around. It works on both mobiles and players. The mobile must see the victim, unless the optional 'unseen' parameter is used. systax: MOB ASSIST [character] Lets a mobile assist another character, player or non-player. If the mobile is already fighting, then no assistance is given. The mobile must see the character that is being assisted. If the character being assisted is not fighting, then no assistance can be given. If the character being assisted is fighting an opponent, then the mobile will attack this opponent, regarless of whether the mobile can see the opponent. Syntax: MOB REMOVE [victim] [vnum|'all'|'random'] Lets the mobile to strip an object of given vnum from the victim. Objects removed are destroyed. If the vnum is replaced with "all", the whole inventory of the victim is destroyed. If the vnum is replaced with "random", a random object is removed. This command is probably most useful for extracting quest items from a player after a quest has been completed. Syntax: MOB JUNK [object] Destroys the object refereed to in the mobile's inventory. It prints no message to the world and you can do things like junk all.bread or junk all. This is nice for having janitor mobiles clean out their inventory if they are carrying too much (have a MOBprogram trigger on the 'full inventory') Syntax: MOB PURGE [argument] Destroys the argument from the room of the mobile. Without an argument the result is the cleansing of all NPC's and items from the room with the exception of the mobile itself. However, 'mob purge self' and 'mob purge $i' are disabled. Instead of purging the mobile itself, transfer it to room 3. Do not make the mobile make another mobile purge the first mobile. Syntax: MOB AT [location] [command] Performs the command at the designated location. Very useful for doing magic slight of hand tricks that leave players dumbfounded such as metamorphing mobiles, or guard summoning, or corpse vanishing. For example mob at Mandrake mob echoat Mandrake You think you see a cockroach. Syntax: MOB GOTO [location] Moves the mobile to the room or mobile or object requested. It makes no message of its departure or of its entrance, so these must be supplied with echo commands if they are desired. Syntax: MOB TRANSFER {'nolook'} [victim|'all'] {location} MOB GTRANSFER [victim] {location} MOB GPTRANSFER {'fromroom' from-location} [victim] {location} MOB OTRANSFER [object] [location] Sends the victim to the destination or to the room of the mobile as a default. If the victim is "all" then all the player characters in the room of the mobile are transferred to the destination. Good for starting quests or things like that. There is no message given to the player that it has been transferred. Gtransfer works like transfer, except that all the members of the victim's group who are in the same same room as the mobile are transferred (the victim must also be in the same room as the mobile). Gptransfer also transfers the victim's group, and, in addition, the pets, charmies and mounts of all the group members. Like gtransfer, gptransfer is limited to characters in the room of the mobile. If the optional parameter 'fromroom' is used, then the mobile will transfer only when the mobile is in the specified room. This is useful from making mobile that operate as doormans where one typically does not want the tranfer unless the mobile is still standing at the door. If the optional parameter 'nolook' is used, then the character being transfer will not be forced to do a look when tranferred. This will result in your players being totally confused, but maybe that is what you want. Otransfer transfers an object in the room of the mobile to a location. Syntax: MOB FORCE [victim|'all'] [command] MOB GFORCE [victim] [command] MOB VFORCE [vnum] [command] Forces the victim to do the designated command. The victim is not told that they are forced, they just do the command so usually some mpecho message is nice. You can force players to remove belongings and give them to you, etc. The player sees the normal command messages (such as removing the item and giving it away in the above example) Again, if the victim is "all" then everyone in the mobiles room does the command. Gforce works like force except that it affects the group the victim belongs to. Vforce affects all mobiles with given vnum in the game world. This is useful for, for example, purging certain type of NPCs from the game (by forcing them to purge themselves). Syntax: MOB CAST {'level'} {'silent'} [spell] {victim} Lets the mobile to cast spells. Beware, this does only crude validity checking and does not use up any mana. All spells are available regardless of the race or other abilities of the mobile. Casting the spell occurs silently if the optional "silent" parameter is used, but spell effects are displayed normally. Syntax: MOB DAMAGE [victim|'all'] [min] [max] {type} {lethal} Causes unconditional damage to the victim. Specifying "all" as victim causes damage to all characters in the room except the mobile. Min and max parameters define the minimum and maximum amounts of damage caused. The optional 'type' parameter can be used to indicate a specific type of damage. Allowed values are: 'fire', 'cold', 'lightning', 'acid', 'poison', and 'light'. By default, the damage is non-lethal, but by supplying the optional 'lethal' parameter, the damage can kill the victim. This command is silent, you must echo all messages yourself in the program. Useful for implementing special attacks for mobiles. Syntax: MOB DELAY [pulses] [tag] MOB CANCEL MOB DELAY sets the time in PULSE_MOBILE after which the mobile's delay trigger is activated. If the mobile has a program defined for delay trigger, the program is executed when the timer expires. The tag is used to select a specific delay among many. A mobile can have only one delay pending. MOB CANCEL resets the delay timer. Syntax: MOB REMEMBER [victim] MOB FORGET This command enables the mobile to remember a player for future reference in a MOBprogram. The player can subsequently be referred as '$q' in programs activated by the mobile. MOB FORGET clears the target. Note that if the first time the mobile runs a program, $q is automatically set to the player who triggered the event. Most commonly this command is used in delayed programs, where the mobile has to remember the player who triggered the original event, for example to continue conversation. Syntax: MOB CALL [vnum] {victim} {target1} This command lets you call MOBprograms from within a running one, i.e. to call a MOBprogram subroutine. The first parameter is the vnum of the program to execute, the second is the victim's name (for example $n), and the third is an optional object name. All other parameters except vnum can be replaced with word 'null' indicating ignored parameter. MOBprograms can be called recursively, but as a safety measure, parser allows only 5 recursions. Syntax: MOB MARK [victim] This command enables the mobile to mark a player for future reference in a MOBprogram. Unlike MOB REMEMBER this mark can be seen by MOBprogram on other mobiles. --------------------------Regarding CPU Slowdown------------------------------- In the original MERC 2.2 MOBprogram documentation Nata'sha and Kahn wrote: "We have no real idea how slow this makes a mud. However, you will find that if you are judicious with your use of MOBprograms, you can either do little damage, or even reduce the effort on your server! This means that mobile polling (including the rand_progs) need only be checked when players are around. This reduces computation of random_stuff a little, but it is still a polling method, and subject to a basic inefficiency there. However, aside from the rand_progs, the only additional slowdowns will be when the mobile is responding to the situation, and you would get that from a special procedure as well (although MOBprograms are surely not as efficient as compiled C code)" I have used MOBprograms extensively in my own mud without adverse effects. This version of MOBprograms polls random triggers only when there are players in the area, so the load is kept to minimum. I would venture to claim that in most cases, line lag will exceed machine lag even with ample and complex use of MOBprograms. --------------------------Loading Mobiles and Objects-------------------------- No doubt you want to load objects and mobiles in your MOBprograms with "mob oload" and "mob mload". There are two problems connected to this. One is that mloaded mobiles will appear without equipment and the other is that it is difficult to keep track of the number of created mobiles and objects. If you want to mobiles to appear in your area as a result of the players' action, create a "storage room". Define resets for the mobiles as usual (equipment etc.) and place them in the storage room. When you need to use the mobiles, just "mob transfer" them to the location you want. This is better than creating mobiles on the fly, since you don't have to worry about creating too many mobiles or equipping them, area resets take care of all that. If you have a MOBprogram that creates new mobiles, you might want to make the mobiles "self-destructing". This is easiest to do with a random trigger that checks if the mobile is doing anything useful and possibly does 'mob purge $i'. Another possibility is to use a "purgemaster". Create a storage room with a single mobile. Attach a random trigger that does 'mob purge' to that mobile. Now, when you need to get rid of anything, just 'mob transfer' the mobile or item to purgemaster, and it will be destroyed sometime later. -------------------------Miscellaneous Information----------------------------- There is really no limit to the number of MOBprograms a given mobile can have. However, the length of a single command block is limited by the value of MAX_STRING_LENGTH. In my version it was around 4k, so that is probably about 100 lines. The indentation spaces shown in the example above are NOT required, but do make it easier to read (and debug). HOWEVER, all spaces and indentations are loaded into memory as a part of the program, so you're using up memory unnecessarily. Memory usage can also be reduced by using subroutines (see MOB CALL). It IS possible to accidentally make mobiles which can trigger in loops. Infinite loops have been prevented, but in case of a loop, the mobile behavior is undefined. The list of variables and triggers and if_checks will grow continuously as mud creators demand the ability to do certain things. If you have a request or if you have a new one, I don't mind hearing about them, and if you find bugs, I shall gladly attempt to squash them for you. As additions or fixes are made, the code will occasionally be redistributed. However, if you want a current version, please feel free to ask. When the code is redistributed, a file containing the change history from the original release will be provided (when possible) to allow you to patch in the changes with low grief. ----------------------------------Credits----------------------------------- The reason this code was written was to enhance the playing experience at ThePrincedom (a Merc 2.0 based world scheduled to open in October 1993) The original idea for this type of MOBprogram came from playing on: WORLDS of CARNAGE, a dikumud implemented by Robbie Roberts and Aaron Buhr. Aaron (known as Dimwit Flathead the First) was the original author from what I have been told, and I hope he will not be totally offended and angered by my coding and sharing a mimicked version with the world. This version is probably not as good as the original and I do feel remorse for publishing the idea. However, since Carnage has been down for months without a word of information regarding its return, I am glad to let one of the best features live on in future generations of MUDs. There are no objections to this code being shared, since, aside from a nuclear destruction of all the Temples of Midgaard (excepting the original one!!), bland mobiles are the greatest bane of Dikumuds today. It would be nice to get a message saying you are using the code just for our references. We shant answer questions from anyone until told where they are using the code. *grin* Since this code is not copyrighted, you of course dont have to do anything we say, but it would be nice of you to put the mobprog help screen into your database. and have mobinfo show up somewhere on a more visable help screen (possibly tagged onto the bottom of credits as a see also...) I acknowledge all the work done by the original Diku authors as well as those at Merc Industries and appreciate their willingness to share code. Also, quick thanks to Wraith for doing a little beta-installation testing. N'Atas-Ha June, 1993 natasha@gs118.sp.cs.cmu.edu In addition to this DOC file credit section, I'd like to add a thank you to Yaz, Mahatma, Zelda, and the rest of the 4th Realm crew for extensively testing MOBProgram 2.1 for me. You may see MOBPrograms in action as well as their own "flavor" of mud at marble.bu.edu 4000. Kahn Oct 28th, 1993 MERC Industries This driver was rewritten by me in summer '95. I also added room and object programs (not in ROM 2.4 version). While I acknowledge the skill and insight of the above people who conceived the original MOBprogram idea, they should not be held responsible in any way for this release. I can't promise I will be able to support this code in the future, use at your own risk. However, if you're using this code, and/or have bug reports or improvements, I'd be glad to hear from you. The revised MOBprograms can be seen in action at Imperium Gothique, mud.pitek.fi 4000. This code may be freely used and distributed, but some favorable publicity (such as having my name appended to your in-game credits) would encourage me to develop this software. Newt@Imperium Gothique May 1995-Jan 1996 mn54196@uta.fi (am I lazy or what?) ===================CUT HERE FOR QUICK REFERENCE SHEET======================== MOBprogram quick reference to triggers/variables/ifchecks/mobcommands ----------------------------------------------------------------------------- Area file format ----------------------------------------------------------------------------- #MOBILES M {trigger} {program vnum} {argument}~ #MOBPROGS #{program vnum} {program code}~ ----------------------------------------------------------------------------- trigger argument and what must happen to activate trigger ----------------------------------------------------------------------------- act STRING to match from act() to mobile speech STRING to match in dialogue (say, tell) to mobile rand PERCENT chance to check whenever a PC is in the mobiles zone bribe INTEGER minimum amount of silver coins given to mobile give OBJECT NAME, OBJECT VNUM or ALL to match when obj given to mobile greet EXIT NUMBER chance to check if visible char enters mobile's room grall EXIT NUMBER chance to check when any char enters mobile's room entry PERCENT chance to check when mobile moves to a new room exit EXIT NUMBER a visible char tries to exit mobile's room exall EXIT NUMBER any char tries to exit mobile's room kill PERCENT chance to check when the mobile begins fighting fight PERCENT chance to check at fight_pulse if mobile is fighting hpcnt PERCENT lower than mobile's hit/max_hit if mobile is fighting death PERCENT chance to check after mobile has been slain surr PERCENT chance to activate when a char surrenders to mobile ---------------------------------------------------------------------------- variable mobile actor victim random target ----------------------------------------------------------------------------- name $i $n $t $r $q shrt_desc/title $I $N $T $R $Q he/she/it $j $e $E $J $X him/her/it $l $m $M $L $Y his/hers/its $k $s $S $K $Z title $u $v $w $f rank $U $V $W $F ---------------------------------------------------------------------------- variable object ----------------------------------------------------------------------------- name $o shrt_desc/title $O ---------------------------------------------------------------------------- ifcheck argument(s) meaning ----------------------------------------------------------------------------- rand num Is random percentage less than or equal to num mobhere vnum Is a NPC with this vnum in the room mobhere name Is a NPC with this name in the room objhere vnum Is an object with this vnum in the room objhere name Is an object with this name in the room mobexists name Does NPC 'name' exist somewhere in the world objexists name Does object 'name' exist somewhere in the world - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - people == integer Is the number of people in the room equal to integer players == integer Is the number of PCs in the room equal to integer mobs == integer Is the number of NPCs in the room equal to integer clones == integer Is the number of NPCs in the room with the same - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - isnpc $* Is $* an NPC ispc $* Is $* a PC isgood $* Does $* have a good alignment isneutral $* Does $* have a neutral alignment isevil $* Does $* have an evil alignment isimmort $* Is $* an immortal (level of $* > LEVEL_HERO) ischarm $* Is $* affected by charm isfollow $* Is $* a follower with their master in the room isactive $* Is $*'s position > POS_SLEEPING isdelay $* Does $* have a delayed MOBprogram pending isvisible $* Is $* visible to NPC who activated the program hastarget $* Does $* have a MOBprogram target in the room istarget $* Is $* the target of NPC who activated the program ispthief $* Is $* a player flagged as thief isoutlaw $* Is $* a player flagged as outlaw ishostile $* Is $* a player flagged as hostile - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - affected $* 'affect' Is $* affected by 'affect' act $* 'act' Is $*'s ACT bit 'act' set off $* 'off' Is $*'s OFF bit 'off' set imm $* 'imm' Is $*'s IMM bit 'imm' set carries $* 'name' Is $* carrying object 'name' wears $* 'name' Is $* wearing object 'name' has $* 'type' Does $* have object of item_type 'type' uses $* 'type' Is $* wearing object of item_type 'type' name $* 'name' Is $*'s name 'name' pos $* 'position' Is $*'s position 'position' (sleeping etc.) clan $* 'name' Does $* belong to clan 'name' race $* 'name' Is $* of race 'name' class $* 'name' Is $*'s class 'name' objtype $* 'type' Is $*'s item_type 'type' isfollowed $* 'name' Is $* followed by name isfollowed $* 'vnum' Is $* followed by a mob of this vnum - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - vnum $* == integer Is $*'s virtual number equal to integer hpcnt $* == integer Is $*'s hitpoint percentage equal to integer room $* == integer Is vnum of the room $* is in equal to integer sex $* == integer Is $*'s sex equal to integer level $* == integer Is $*'s level equal to integer align $* == integer Is $*'s alignment equal to integer money $* == integer Does $* have money (in silver) equal to integer objval# $* == integer Is $*->value[#] equal to integer (# from 0-4) ----------------------------------------------------------------------------- MOBcommand argument_list MOBcommand argument_list ----------------------------------------------------------------------------- ASOUND [text_string] ECHO [text_string] GECHO [text_string] ZECHO [text_string] ECHOAT [victim] [text_string] ECHOAROUND [victim] [text_string] MLOAD [vnum] OLOAD [vnum] [level] {wear|room} KILL [victim] REMOVE [victim] [vnum] MOB JUNK [object] PURGE [argument] AT [dest] [command] GOTO [dest] TRANSFER [victim] [dest] GTRANSFER [victim] [dest] OTRANSFER [object] [dest] FORCE [victim] [command] GFORCE [victim] [command] VFORCE [vnum] [command] CAST [spell] [victim] DAMAGE [victim] [min] [max] {lethal} DELAY CANCEL REMEMBER [victim] FORGET CALL [vnum] [victim] [target1] [target2] ======================END OF QUICK REFERENCE SHEET=========================== +++++++++++++++++++++++++++++++ EXAMPLES ++++++++++++++++++++++++++++++++++++ In #MOBILES: M act 1000 pokes you in the ribs.~ In #MOBPROGS: #1000 if isnpc $n chuckle poke $n break else if level $n <= 5 or isgood $n tell $n I would rather you didnt poke me. else if level $n > 15 scream say Ya know $n. I hate being poked!!! if mobhere guard mob force guard kill $n endif kill $n break endif slap $n shout MOMMY!!! $N is poking me. endif endif ~ Ok.. time to translate.. the trigger will only happen when the mobile gets the message "... pokes you in the ..." If the offender (recall the $n and $N refer to the char who did the poking...) is an NPC, then the mobile merely chuckles and pokes back. If the offender was a PC then good and low level characters get a warning, high level chars get attacked, and midlevel chars get slapped and whined at. Also, when attacking, the mobile will check if there are guards in the room (if mobhere guard) and if one is found, it will be forced to attack the player, too (mob force guard kill $n). Notice the use of a MOBcommand "mob force". Note that two of these mobiles could easily get into an infinite poke war which slows down (or frequently crashes) the mud just a bit :( Be very careful about things like that if you can. (i.e dont respond to a poke with a poke, and try not to let heavily programmed robot mobiles wander around together. More on that is given above.) Also, it is clear that the 'order' command could get confused with the 'or' control flow. However, this is only the case when 'order' is abbreviated to its two letter form, and placed immediately following an 'if' line. Thus, if you want to be that malicious in trying to break the MOBprogram code, no one is going to stand in your way (However, the result of this would be a bug message and a bail out from the ifcheck so things dont really break) Another example: This program could be used on a temple guardian mobile, whose job is to prevent evil characters from entering the sanctuary. Let's assume the exit to the temple is north (exit 0) and the temple antechamber is room 2301 In #MOBILES M exit 1001 0 In #MOBPROGS #1001 if isgood $n say Hail! emote salutes $n. if carries $n holy mob transfer $n 2301 else say If you wish to enter the temple, get a holy symbol. endif else curse $n say Get lost, you scum! endif ~ How this works: The trigger is activated when the player tries to exit north from the room. If the player is of good alignment, the guard will greet the player. However, the guard will not let the player to the temple unless he or she carries a holy symbol. If the player is neutral or evil, the guard will curse and block the way. Example of using DELAY and REMEMBER: In #MOBILES M greet 1002 100 M delay 1003 100 In #MOBPROGS #1002 if isevil $n say You infidel! Go away or face the wrath of mighty Mota! mob remember $n mob delay 10 break endif ~ #1003 if hastarget $i growl mob echo $I screams and attacks $Q. mob kill $q else mob forget endif ~ How this works: When the player enters a room, the mobile checks if the player is evil. If this is the case, the mobile makes the player the target (mob remember) and sets up a delay of 10 * PULSE_MOBILE. When the delay expires, program #1003 is activated. The mobile checks if the target is still in the room (hastarget), and if the player hasn't left, the mobile attacks ($q and $Q refer to the target). If the player has left, the mobile will forget the player (mob forget). Example of MOB CALL: In #MOBILES: M greet 1004 100 In #MOBPROGS: #1004 if isgood $n mob call 1005 $n null null else mob call 1006 $n null null endif ~ #1005 mob echo Suddenly, a bright aura surrounds $I! mob cast 'heal' $n ~ #1006 mob echoat $n $I points $l finger at you in fury! mob echoaround $I points $l finger at $N in fury! mob cast 'curse' $n ~ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ OBJECT and ROOM PROGRAMS Object and room programs are basically mob programs on an object or a room. Syntactic rules of room and object program are the same as those of mob programs, while triggers and commands are appropriate for objects and rooms. Object and room programs are modification of the mob program code. -----------------------------Trigger Types---------------------------------- Here's a summary of triggers: OPEN Keyword : 'open' Argument: a percent number Valid : objects only Variables: $p, $P - the object that has the program $n, $N - ch opening the object $r - random character NOTE: This is triggered when the container is opened, unless the object trap has been disabled. The object must be in the room not on inventory or in a container. TRAPPED Keyword : 'trapped' Argument: a percent number Valid : objects only Variables: $p, $P - the object that has the program $n, $N - ch opening the object $r - random character NOTE: This is triggered when the container is opened, unless the object trap has been disabled. The object must be in the room not on inventory or in a container. EQUIP Keyword : 'equip' Argument: a percent number Valid : objects only NOTE: This is triggered when the item is worn, held or wielded. TAKE Keyword : 'take' Argument: a percent number Valid : objects only NOTE: This is triggered when the item is taken. The item can be taken from the room or from a container. The trigger is activated immediately after the object is placed on the taker inventory, so that commands which require that the object be a in a room will not work. ENTER Keyword : 'enter' Argument: none Valid : objects only Variables: $p, $P - the object that has the program $n, $N - ch passing though the portal $r - random character NOTE: This is triggered when a portal is crossed. The portal crossing is silent, so the OBJprogram has to send messages to the room. The trigger is activated before the character crosses, so that room echoes will go the the enter start room. The object must be in a room, not on inventory or in a container. FIGHT keyword : 'fight' Argument: a percent number Valid : objects only Variables: $p, $P - the object that has the program $n, $N - ch wielding the weapon $t - the character being hit by the weapon $r - random character NOTE: This is triggered only on weapons, when the weapon is being used in melee combat. The variable $t, $T, etc is available as the victim when the weapon strikes. The weapon must be flagged "special". EQUIP Keyword : 'equip' Argument: a percent number Valid : objects only NOTE: This is triggered when the item is worn, held or wielded. TAKE Keyword : 'take' Argument: a percent number Valid : objects only NOTE: This is triggered only on weapons, when the weapon is being used in melee combat. The variable $t, $T, etc is available as the victim if the melee strikes. The weapon must be flagged "special". REMOVE Keyword : 'remove' Argument: a percent number Valid : objects only NOTE: This is triggered when a item is removed. This is opposite of the equip trigger. GREET ALL Keyword : 'grall' Argument: number Argument is the exit number (0:north, 1:east, 2:south, 3:west, 4:up, 5:down, -1:portal, 100:any) Variables for object prog: $p, $P - the object that has the program $n, $N - ch arriving $r - random character Variables for room prog: $n, $N - ch arriving $r - random character NOTE: Whenever someone enters the room that contains the object, through an exit indicated by the argument, this is checked. The object must be in the room and not in inventory or in an container. The numeric parameter specifies which entrance should trigger the program. Immortals, even when visible, do not trigger this. EXIT ALL Keyword : 'exall' Argument: number Argument is the exit number (0:north, 1:east, 2:south, 3:west, 4:up, 5:down) Variables for object prog: $p, $P - the object that has the program $n, $N - ch trying to leave $r - random character Variables for room prog: $n, $N - ch trying to leave $r - random character NOTE: The opposite of entry trigger. This is activated when PC tries to leave a room through an exit indicated by the argument. An exit trigger works better than an entry trigger, since you can refer to a specific PC instead of a random PC. IMPORTANT: If this event is triggered, the victim will not move through the exit. If necessary, you must move the character yourself in your program (see OBJ TRANSFER/OBJ GTRANSFER). Immortals, even when visible, do not trigger this. DROP Keyword : 'drop' Argument: a percent number Valid : objects only NOTE: This is triggered when a item is dropped. This is opposite of the take trigger. TAKEFROM Keyword : 'takeform' Argument: a percent number Valid : objects only NOTE: This trigger is used for container type object and is activated whenever an item is taken from the container. The trigger is activated immediately after the object is placed on the taker inventory. PUTIN Keyword : 'putin' Argument: a percent number Valid : objects only NOTE: This trigger is used for container type object and is activated whenever an item is put in the container. The trigger is activated immediately after the object is placed in the container, and the put in messages are sent to the room. (If the object being placed in the container has a DROP trigger, then this is activated after the PUTIN trigger. Note that since the trigger is activated after the object is a container, there are many commands that will not work, notably obj echo. Please note that drop triggers are no longer activated when an object is placed into a container.) LOOK Keyword : 'look' Argument: a percent number Valid : objects only Variables: $p, $P - the object that has the program $n, $N - ch looking at the object $r - random character NOTE: This is triggered whenever a character looks at the object. The object cannot have extra description with the same name as the object. TIME Keyword : 'time' Argument: number A time value (1/6 th of an hour). Variables: $p, $P - the object that has the program $r - random character NOTE: This triggers when the game clock reaches the parameter time. In Feudal Realms the time is divided in 10 minutes game time intervals. There are 24 hours in the day, and 144 time intervals, numbered 0 through 143. For example, setting the parameter to 1 causes the Object program to execute at 10 minutes after midnight; setting it to 6, at 1 am; setting it to 72 at noon. Some variables, notably $n, $N, etc. are not available with ObjProgram with this trigger. INTERP Keyword : 'interp' Argument: string Valid : rooms, then objects. The argument is the command string. Variables for object prog: $p, $P - the object that has the program $n, $N - ch sending the command $r - random character Variables for room prog: $n, $N - ch sending the command $r - random character NOTE: This is triggered whenever a character in the same room as the object sends (types) a command to the mud which is not interpreted as a command. This is useful for expanding the mud commands to include special keywords. The argument string must match the command exactly. This is triggered before the socials and after the mud commands, so that for example 'push couch' is not a possible argument but 'sing' and 'cut bush' is a valid argument. This trigger is akin to the diku/circle object and room specials. FURNITURE Keyword : 'furniture' Argument: string Valid : objects only The argument is 'sit', 'rest', 'sleep', 'stand', or 'off'. Variables: $p, $P - the object that has the program $n, $N - ch using the furniture $r - random character NOTE: This is triggered when furniture is used, by either sitting, resting, sleeping or standing on it. If a player is already using the furniture then a simple change in position will not trigger the object program. The object program is only triggered when a character begins to use the furniture and when a character stops using an object. ------------------------------Variables------------------------------------ Variables used by OBJprograms are similar to those used by MOBprograms with $p and $P referring to the object itself, $n and $N referring to the character that caused the trigger to happen. Variables used by ROOMprograms are similar to those used by OBJprograms except that $i, $I are undefined. Thus $p the first of the names of the object itself, for OBJprograms; undefined for ROOMprograms. $P the short description of the object itself, for OBJprograms; undefined for ROOMprograms. $n the name of whomever caused the trigger to happen. $N the name and title of whomever caused the trigger to happen. $t the name of the victim (FIGHT trigger only) $T the name and title of the victim (FIGHT trigger only) $r the name of a random PC in the room with the object $R the short description, or name and title of the random PC $q undefined $Q undefined $j undefined $e he,she,it based on sex of $n. $E he,she,it based on sex of $t. $J he,she,it based on sex of $r. $X undefined $k undefined $m him,her,it based on sex of $n. $M him,her,it based on sex of $t. $K him,her,it based on sex of $r. $Y undefined $l undefined. $s his,hers,its based on sex of $n. $S his,hers,its based on sex of $t. $L his,hers,its based on sex of $r. $Z undefined $u the noble title of $n. $v the noble title of $t. $w the noble title of $r, a random PC. $f undefined $U the house rank of $n. $V the house rank of $t. $W the noble title of $r. $F ------------------------If_Checks In Control Flow--------------------------- Like variable, is checks used by are similar to those used by MOBporgram, except that clone, isvisible, istarget are not available. There are five types of if checks: Type 1: Keyword and value rand num Is random percentage less than or equal to num mobhere vnum Is a NPC with this vnum in the room mobhere name Is a NPC with this name in the room objhere vnum Is an object with this vnum in the room objhere name Is an object with this name in the room mobexists name Does NPC 'name' exist somewhere in the world objexists name Does object 'name' exist somewhere in the world Type 2: Keyword, comparison and value people == integer Is the number of people in the room equal to integer players == integer Is the number of PCs in the room equal to integer mobs == integer Is the number of NPCs in the room equal to integer hour == integer Is the hour (game time) equal to integer Type 3: Keyword and actor isnpc $* Is $* an NPC ispc $* Is $* a PC isgood $* Does $* have a good alignment isneutral $* Does $* have a neutral alignment isevil $* Does $* have an evil alignment isimmort $* Is $* an immortal (level of $* > LEVEL_HERO) ischarm $* Is $* affected by charm isfollow $* Is $* a follower with their master in the room isactive $* Is $*'s position > POS_SLEEPING isdelay $* Does $* have a delayed MOBprogram pending hastarget $* Does $* have a MOBprogram target in the room istarget $* Is $* the target of NPC who activated the program ifpthief $* Is $* a player flagged as thief isoutlaw $* Is $* a player flagged as outlaw ishostile $* Is $* a player flagged as hostile Type 4: Keyword, actor and value affected $* 'affect' Is $* affected by 'affect' act $* 'act' Is $*'s ACT bit 'act' set off $* 'off' Is $*'s OFF bit 'off' set imm $* 'imm' Is $*'s IMM bit 'imm' set carries $* 'name' Is $* carrying object 'name' wears $* 'name' Is $* wearing object 'name' has $* 'type' Does $* have object of item_type 'type' uses $* 'type' Is $* wearing object of item_type 'type' name $* 'name' Is $*'s name 'name' pos $* 'position' Is $*'s position 'position' (sleeping etc.) clan $* 'name' Does $* belong to clan 'name' race $* 'name' Is $* of race 'name' class $* 'name' Is $*'s class 'name' objtype $* 'type' Is $*'s item_type 'type' contains $* 'name' Does $* contains object 'name' Type 5: Keyword, actor, comparison and value vnum $* == integer Is $*'s virtual number equal to integer hpcnt $* == integer Is $*'s hitpoint percentage equal to integer room $* == integer Is vnum of the room $* is in equal to integer sex $* == integer Is $*'s sex equal to integer level $* == integer Is $*'s level equal to integer align $* == integer Is $*'s alignment equal to integer money $* == integer Does $* have money (in silver) equal to integer objval# $* == integer Is $*->value[#] equal to integer (# from 0-4) ------------------------New Commands Of Interest----------------------------- 1. DIAGNOSTIC COMMANDS A new commands is available to immortal players. Syntax: OPSTAT [object] Displays the triggers and MOBprogram vnums defined for the object. Syntax: MPDUMP [vnum] Displays the MOBprogram code of given vnum. OBJprograms and ROOMprograms are displayed like MOBprograms. 2. OBJCOMMANDS OBJcommands are special commands that allow objects to perform immortal-like actions within an OBJprogram (transferring players or loading items, for example). Most OBJcommands them are wiz commands which have been changed to allow for objects to perform the commands. In this version of OBJprograms, players have been prevented from using these commands by adding a separate interpreter for OBJcommands. All OBJ commands may preceded with the word 'OBJ' on the command line and all ROOM commands by the word 'ROOM. Unlike MOBprograms, OBJprograms and ROOMprograms cannot execute normal MUD commands. Syntax: OBJ ZECHO [string] OBJ GECHO [string] ROOM ZECHO [string] ROOM GECHO [string] ZECHO prints the string to all players in the same area with the object or the room. GECHO prints the string to all players in the game. The object must be in a room or on a player to execute the ZECHO command. Syntax: OBJ ECHO [string] OBJ ECHOAT [victim] [string] OBJ ECHOAROUND [victim] [string] ROOM ECHO [string] ROOM ECHOAT [victim] [string] ROOM ECHOAROUND [victim] [string] ECHO displays the string to everyone in the room. ECHOAT displays the string to the victim only. ECHOAROUND displays the string to everyone except the victim. The object must be in a room or in inventory. The echoat and echoaround commands for rooms can select a victim anywhere in the world. Syntax: OBJ MLOAD [vnum] OBJ OLOAD [vnum] {'inside'} ROOM MLOAD [vnum] ROOM OLOAD [vnum] MLOAD creates a mobile and places it in the same room with the object or in the program room. OBJ OLOAD loads a second object either in the room with the first object or inside the first object, if the first object is a container. The optional second parameter can be used to specify to load the second object into the first. The object does not load if doing so would exceed load limits. ROOM OLOAD loads an object in the room. Syntax: OBJ AT [location] [command] Performs the command at the designated location. The command must be an object program command, since objects cannot perform regular MUD commands. For example, obj at 17000 echo A rumbling sound is heard. Syntax: OBJ GOTO [location] Moves the object to the room requested. It makes no message of its departure or of its entrance, so these must be supplied with echo commands if they are desired. Syntax: OBJ TRANSFER [victim|'all'] {location} OBJ RTRANSFER [victim|'all'] [location] OBJ GTRANSFER [victim] [location] OBJ GPTRANFER [victim] [location] OBJ OTRANSFER [object] [location] ROOM TRANSFER [victim|'all'] {location} ROOM RTRANSFER [victim|'all'] [location] ROOM GTRANSFER [victim] [location] ROOM GPTRANSFER [victim] [location] ROOM OTRANSFER [object] [location] Sends the victim to the destination or to the room of the object or the room as a default. if the victim is "all" then all the characters in the room are transferred to the destination. If the 'all' parameter is used, then the object must be in the room (not in a character's inventory or equipped on a character). RTRANSFER transfers always characters from the same room as the object, or in the room that is running the program. Otransfer transfers an object in the room or the room with the object to a location. Syntax: OBJ FORCE [victim|'all'] [command] OBJ GFORCE [victim] [command] OBJ VFORCE [vnum] [command] ROOM FORCE [victim|'all'] [command] ROOM GFORCE [victim] [command] ROOM VFORCE [vnum] [command] Forces the victim to do the designated command. The victim is not told that they are forced, they just do the command. Again, if the victim is "all" then everyone in the room does the command. Gforce works like force except that it affects the group the victim belongs to. Vforce affects all mobiles with a given vnum in the game world. See the equivalent mob command for example of its use. Syntax: OBJ PURGE [argument] ROOM PURGE [argument] Destroys the argument from the room or the room of the object. Without an argument the result is the cleansing of all NPC's and items from the room with the exception of the object itself. The object must be in a room an not on player to execute the PURGE command. The object cannot purge itself. Syntax: OBJ DAMAGE [victim|'all'] [min] [max] {type} {lethal} ROOM DAMAGE [victim|'all'] [min] [max] {type} {lethal} Causes unconditional damage to the victim. Specifying "all" as victim causes damage to all characters in the room. Min and max parameters define the minimum and maximum amounts of damage caused. The optional 'type' parameter can be used to indicate a specific type of damage. Allowed values are: 'fire', 'cold', 'lightning', 'acid', 'poison', and 'light'. By default, the damage is non-lethal, but by supplying the optional 'lethal' parameter, the damage can kill the victim. This command is silent, you must echo all messages yourself in the program. Syntax: OBJ CAST [spell] [victim] ROOM CAST [level] [spell] [victim] A spell is cast on the victim by the victim, without affecting the victim mana. All spells are available. Casting the spell occurs silently. Syntax: INVOKE [vnum] ['mob'|'obj'|'room'] [vnum|'self'] {victim} {targ1} This command lets you call MOBprograms from within a running one, i.e. to call a program subroutine. The first parameter is the vnum of the program to execute; the second indicates whether mobiles or objects should run the program; the third is the vnum of the mobiles or objects that are to run the program; the fourth is the optional victim's name (for example $n), and the fifth is an optional object names. The third parameter can be replaced with the word 'self', indicating the the new program should be ran on the invoking object or mobile. Note that the MOBprogram will be invoked on all the mobiles or the objects with the specified vnum. MOBprograms can be called recursively, but as a safety measure, the interpreter allows only five recursions. This is a very similar to MOB CALL, except that there is it is now possible to call program on different mobiles or objects. This is useful to do things sneaky like having a merchant do: * invoke the rescue program on guards invoke mob $n This coupled with a mobprogram of mpvnum mob goto merchant mob echo $I has arrived. emote scolds and beats $n. It is an effective way of quickly bringing guards to the scene of an attack. (Note that the merchant has to be the only one of its kind in the game or have a unique name, otherwise the guard might go to different mobile...). Syntax: OBJ ELINK [exit] ROOM ELINK [exit] The "unlinked" flags is removed from an existing exit. The same flag is removed from the reverse exit. The exit must already exist. This command is used in conjunction with the exit affect "unlinked". The "unlinked" affect or flag makes the exit as though it was non existant. The exit cannot be crossed, picked etc. The reverse action is "eunlink". This command is used to make temporary exits such as drawbridges, rotating libraries which are really secret doors and the like. The object must be in the room. Syntax: OBJ EUNLINK [exit] ROOM EUNLINK [exit] The "unlinked" flags is added to an existing exit. The same flag is added to the reverse exit. The exit must already exist. This command addes the "unlinked" exit affect or flag which majes the exit as though it was non existant. The exit cannot be crossed, picked etc. The reverse action is "elink". This command is used to close temporary exits such as drawbridges, rotating libraries which are really secret doors and the like. The object must be in the room. +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ A few gotcha and item of interest on mob and obj programs. Immortals - Because of the exceptional condition under which immortal characters operate, the triggering or object and mob program for immortal is not reliable, especially if the immortal is wizinvisible. The programs, however, work reliably on mortals. Greet trigger - In the exceptional case where a mobile is following a player character, the greet trigger is activated on every move. Act trigger - The execution timing of an act triggered mob program depends on the placement of the act() method call with respect to the actual event. In some case the event which changes state of characters and objects will take place before the act call, but in other cases the act call is done immediately before the event. There are roughly 2000 calls to act, so it is hard to predict when an act triggered mob program would run. Use this trigger with caution, and consider using or even introducing different triggers. echoat, echoaround - Often echoat or echoaround are used to display multiple lines of text to players. The strings that follow echoat and echoaround have their first character capitalized, if it is a letter. Sometimes this is undesirable, so to avoid use the color control as the first characters in the string, for example, '{x'. This ensures that the string is not improperly capitalized. Purging - the purge commands cannot delete the running object or mobile. To delete these, move the object or mobile to room 3. They will be safely purged at the end of the processing loop.