(included with Basternae's offline zone editor DE)

=== MOBprograms

	MOBprograms are a way to make your mobiles more interesting.  This
basic version has enough to get things going, and should be quite readable and
understandable and more to the point, extendable. The remainder of this
document describes MOBprograms and gives a couple trivial examples.

Table of Contents:
	The Basic Idea
	MOBprogram Syntax
	Associating MOBprograms With A Mobile
	MOBprogram Files
	Trigger Types
	Variables
	Control Flow Syntax
	Operators
	If_Checks In Control Flow
	MOBcommands Of Interest
	Regarding CPU Slowdown
        Miscellaneous Information
	Credits
	

-----------------------------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.

	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.

	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.

	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.

        This is meant only for the use of experienced area builders, preferably
those who have some experience with programming.  Anyone can write mobprogs,
but those with programming experience will find it easier.

----------------------------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.

">" {trigger_type} " " {argument_list} "~" NL
{program_command_1} NL
{program_command_2} NL
{program_command_3} NL
     .   .   .
{program_command_N} NL
"~" NL

-- Explainations

A TRIGGER_TYPE is one of the available triggers.
A PROGRAM_COMMAND can be any legal mud command, or a control flow command.
The ARGUMENT_LIST depends upon the trigger, but it is always parsed into the
	system as a character string.

This is an example of ONE MOBProgram block for a mob.


-------------------Associating MOBprograms With A Mobile--------------------
*NOTE*

        This is something that is done by the area admin of the MUD.  In order
to have a mobprog file associated with your mobile, include the vnum of
the mob and the name of the mobprogram file in your text file accompanying
your zone.  For instance if you had three mobs that used mobprograms, and
two of them used the same one and one of them used a third, you would add this
to your text file so we know what you mean:
  
#MOBPROGS
M 745 beggar.prg
M 746 beggar.prg
M 747 executioner.prg

This would mean that mobs 745 and 746 would use the beggar mobprogram and mob 747
would use the executioner mobprogram, both of which are included as examples.  If
you use that format we can just cut and paste it into the final area file.

*END OF NOTE*

	There is an easy way for the mud to associate the program with the
mobile.  This is done by adding a #MOBPROGS section to the area files.
Logically this section should follow the #MOBILE section since otherwise the
mobiles probably wont have space allocated for them. In the #MOBPROGS section,
list as many lines as you desire of:

M {Vnum} {MOBprogram_filename}

followed by a line starting with a 'S' (case insensitive)

-----------------------------Trigger Types----------------------------------

	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:

Syntax:  in_file_prog <ARGUMENT>

	The argument is a single word which is the location of the stored
file as referenced from the running directory (MOBProgs).

NOTE:  Dummy trigger. Not valid in any file, only for use in loading files
	from the first method described two sections above.

Syntax:  act_prog [p] <ARGUMENT>

	The argument is a list of keywords separated by spaces. If the
first word is the character 'p' by itself then the rest of the word list is
considered to be a phrase.  The trigger is activated whenver a keyword (or
the phrase) is contained in the	act() message. Both the phrase and keywords
are case insensitive.

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 (and some things you wont as well) For example:
	MOBprogram: >act_prog p pokes you in the ribs.~
	This trigger will only be activated if a mobile receives a message
	in which the above five words are found in the exact order and
	spacing given. Note that the period is needed because the words
	must be found on their own. This eliminates confusion when the
	keyword is 'hi' and a message with the word 'this' is being checked.

Syntax:  speech_prog [p] <ARGUMENT>

	The argument is the same as for an act_prog.

NOTE:  This is only triggered when the keyword or 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. 

Syntax:  rand_prog <NUMBER>

	The argument is a number betweeen 1 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.

Syntax:  fight_prog <NUMBER>

	The argument is a percentage like in rand_prog.

NOTE:  Useful for giving mobiles combat attitude.  It is checked every
	PULSE_VIOLENCE when the mobile is fighting.  Can be used to cast
	spells, 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.

Syntax:  hitprcnt_prog <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 hitprcnt_progs should be listed in increasing
	order of percent since a 40% will always be activated before a 20%
	and, only the first successful hitprcnt trigger is performed.

Syntax:  greet_prog <NUMBER>

	Again a percentage argument.

NOTE:  Whenever someone enters the room with the mobile, 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.
	
Syntax:  all_greet_prog <NUMBER>

	Again a percentage argument.

NOTE:  Like greet_prog, but it can be triggered even if the mobile didnt
	see the	arrival (i.e. sneak, invis, etc). Most useful for faking
	teleport rooms (if your mobiles can transfer) or for impassable
	guardians.

    **NOTE: neither greet_prog is activated if the mobile is fighting.**
	
Syntax:  entry_prog <NUMBER>

	Again a percentage argument.

NOTE:  The opposite of a greet_prog. Whenver 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.
	Only the first successful one of these is done so the mobile doesnt
	look stupid by repeating commands resulting from multiple MOBprograms.

Syntax:  give_prog <ARGUMENT>

	The argument is either the complete name of an object, or the word
	'all'. A complete name is like: "sword shiny magic" vs "sword". It
	is whatever is on the line of the object section following the VNUM.

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 give_prog
	at the end of the MOBprogram list is essentially a default response.

Syntax:  bribe_prog <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.
	If money is given to a mobile with this trigger type, instead of the
	cash being added to mob->gold, the mobile is instead given a pile of
	coins in the proper amount. In this way, the mobile can drop the coins
	or refer to the object by "amount" (short description:"%d gold coins")
	This surely has some drawbacks, but it lets the mobile do something
	with the bribe (NOTE: dropping it and getting it turns it into cash)
	This can be done sneakily if a NPC-only "at" command exists.

Syntax:  death_prog <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, or create some, or cast a spell
	on the killer and the room, or even goto a new location 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).  Of course this assumes that some NPC
	commands have been implemented. 

	Note that the first successful bribe_prog, give_prog, hitprcnt_prog,
death_prog, fight_prog, rand_prog and entry_prog is the only one which
is executed.  All the successful greet(_all)_progs, speech_progs, and
act_progs will be done. This is the best arrangement we found for handling
situations where you imported several MOBprogram files for a mobile.  If you
are going to write lots of little files and piece them together to create
the effect you want, it is advisible to not mix things together all that
much, otherwise you have to pay close attention to the order in which the
programs are added to the link list.

	Also, no MOBprograms will be successful when the mobile is charmed
(since it has no self violition, it should act like it has none) to protect
mobiles which are given special powers from being implemented by a player.
One bug we had in early testing was a player who charmed a mobile and then
used its aggressive greet_prog to attack other players. 


------------------------------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 char in the room with the mobile (never == $i)
$R	the short description, or name and title of the random char

$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.

$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.

$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.

$o	the first of the names of the primary object (i.e A drops B)
$O	the short description of the primary object
$p	the first of the names of the secondary object (i.e A puts B in C)
$P	the short description of the secondary object

$a	a,an based on first character of $o
$A	a,an based on first character of $p

	Also, in if_checks, the accepted variables are the basic ones
(i,n,t,r,o,p).  If a variable is referenced that doesnt exist, then the value
is simply left blank. (i.e referring to $o when the trigger is: A kisses B)

	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.


---------------------------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.

"if" " " {if_check_1} "(" {argument} ")" [ {operator} {value} ] NL
[ "or" " " {if_check_2} "(" {argument} ")" [ {operator} {value} ] NL ]
                        .           .           .
[ "or" " " {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 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 line:

--Explainations

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.

If that looks confusing, skip to the end of the document and review the
Example. Hopefully that should clear things, otherwise you'll probably have
to give us a mail since examples are the best way we know to explain syntax.


--------------------------------Operators-----------------------------------

	Most of the basic numeric operators are legal and perform the same
function as in C. The string operators are a bit more confusing. There are
negative versions of some of the operators. These are not strictly needed,
since the if/else construct of Control Flow commands can handle either case.

Numeric Operators: == != > < >= <= & |     String Operators: == != / !/

	For strings, == and != check for exact match between the two strings
and the other two, / and !/ check to see if the second string is contained in
the first one.  This is so things like:  if name($n) / guard  will respond
true to "cityguard" "guard" "guardian"  etc. Using == on a name implies
that you are matching the complete name "cityguard guard" or whatever.
The string operators are case SENSITIVE.


------------------------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 or $r)
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. name($n)== orc large brown)

rand     (num)			Is random percentage less than or equal to num
isnpc     ($*)			Is $* an NPC
ispc      ($*)			Is $* a PC
isgood    ($*)			Does $* have a good alignment 
isneutral ($*)			Does $* have a neutral alignment 
isevil    ($*)			Does $* have a evil alignment 
isfight   ($*)			Is $* fighting
isimmort  ($*)			Is the level of $* greater than max_mortal
ischarmed ($*)			Is $* affected by charm
isfollow  ($*)			Is $* a follower with their master in the room
isaffected($*)	& integer	Is ($*->affected_by & integer) true
				(person only) 
hitprcnt  ($*)	== percent	Is the hit/max_hit of $* equal to percent
inroom	  ($*)	== integer	Is the room of $* equal to integer
				(person only)
sex	  ($*)	== integer	Is the sex of $* equal to integer
position  ($*)	== integer	Is the position of $* equal to integer
level	  ($*)	== integer	Is the level of $* equal to integer
class	  ($*)	== integer	Is the class of $* equal to integer
goldamt	  ($*)	== integer	Does $* have a gold total equal to integer
objtype	  ($*)	== integer	Is the type of $* equal to integer
				(armor,boat,etc)
objval#	  ($*)	== integer	Is $*->value[#] equal to integer (# from 0-3)
number	  ($*)	== integer	Is the vnum of $* equal to integer
name	  ($*)	== string	Is the name of $* equal to string


------------------------MOBCommands Of Interest-----------------------------

	These are fairly basic things, most of them are wiz commands which have
been changed to allow for mobiles to perform the commands.  If you have the
problem of immortals abusing these powers on your mud either ditch the
immortals, or add a check in all of them to only let NPC's with null
descriptors do the commands.  (However, you lose a little debugging help that
way).  MERC 2.2 has provided a little security feature against this but
it is by no means comprehensive.  Please check yourself if you are concerned.

Here are the basic MOBcommands that we found to be enticing:

Syntax:  MPSTAT <mobile>

	Shows the MOBprograms which are set on the mob of the given name or
	vnum and some basic stats for the mobile

Syntax:  MPASOUND <text_string>

	Prints the text string to the rooms around the mobile in the same
	manner as a death cry. This is really useful for powerful aggressives
	and is also nice for wandering minstrels or mobiles like that in
	concept.

Syntax:  MPJUNK <object>

	Destroys the object refered to in the mobiles inven. 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:  MPECHO                 <text_string>
	 MPECHOAT      <victim> <text_string>
	 MPECHOAROUND  <victim> <text_string>

	Prints the text message to the room of the mobile. The three options
	let you tailor the message to goto victims or to do things sneaky
	like having a merchant do: mpat guard mpechoat guard rescue_please 
	This coupled with a guard act_prog trigger on rescue_please to
	mpgoto $n and mpecho $I has arrived.  It is an affective way of quickly
	bringing guards to the scene of an attack.

Syntax:  MPMLOAD <vnum>
	 MPOLOAD <vnum> <level>

	Loads the obj/mobile into the inven/room 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.

Syntax:  MPKILL <victim>

	Lets a mobile kill a player without having to murder and be fifth
	level.  Lots of MOBprograms end up with mpkill $n commands floating
	around. It works on both mobiles and players.

Syntax:  MPPURGE [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, mppurge $i will indeed
	purge the mobile, but it MUST be the last command the mobile tries to
	do, otherwise the mud cant reference the acting mobile trying to do the
	commands and bad things happen.  

Syntax:  MPGOTO <dest>

	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 mpecho commands if they are desired.

Syntax:  MPAT <dest> <command>

	Perfoms 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.

Syntax:  MPTRANSFER <victim> [dest]

	Sends the victim to the destination or to the room of the mobile as a
	default.  if the victim is "all" then all the characters in the room
	of the mobile are transfered to the destination.  Good for starting
	quests or things like that.  There is no message given to the player
	that it has been transfered and the player doesnt do a look at the
	new room unless the mob forces them to. Immortals cannot be tranfered.

Syntax:  MPFORCE <victim> <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.
	This cannot be used on immortals.


--------------------------Regarding CPU Slowdown-------------------------------

	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)

For those who are afraid that MOBprograms will drown their CPU, here is a
brazen suggestion which could put you a bit more at ease.  Instead of having
aggressive mobiles, try the following MOBprogram block on all would be
aggressives. 

			>greet_prog 100~
			if ispc($n)
			  if isimmort($n)
			    bow $n
			  else
			    mkill $n
			  endif
			endif
			~

	This has the effect of making the mobile attack the FIRST visable
mortal player who walks into the room. [Merc 2.0 has a random char be the
victim, so we allow our fighting mobiles a high chance to switch their target
to any random player in the opposing group at each pulse_violence.]

	What this has allowed us to do, is to comment out the aggr_update
section of the code and thus reduce our computation by a bunch. There is no
continuous polling through all the mobiles in occupied zones and checking to
see if there is an NPC aggressor and a PC victim. We also dont have to worry
about players skipping through aggressives, since the trigger catches folk as
soon as they enter the room.

	Note that the price we paid for this, was that if a second player
walked in during the combat, and the first character flees, the mobile didnt
realize that there is a new target. So, we compromised by adding a rand_prog
which had the mobile appear to peer around the room and then do an mkill $r.
AHA! you say, we are back to polling. Well true, but since mobile_update
is called anyway (at 1/16 the frequency of aggr_update in default Merc 2.0)
and we only add an if check, a walk of a short link_list and the MOBprogram
execution itself, we have still reduced the aggr_update stuff by major amounts.

	Of course the act_prog updates are currently done in the aggr_update
section but if you decrease the mobile_update time a bit, and move the
act_progs over to there, the result is act_progs which have a brief delay
(like a PC who has to type things over a modem does) 


-------------------------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)  

	The MOBprogram stuff runs totally without anything in the
mob_commands.c file, but letting mobiles be a bit more godlike has allowed
us to do what we consider to be wonderful things. The replicant and
polymorphing mobiles described above as well as some nifty mob helping mob
interactions are an example.

	It IS possible to accidentally make mobiles which can trigger in
loops. As mentioned in the example at the end of this document, the result is
usually a mud crash or major CPU dent.  We dont know any way to prevent this
from happening, other than careful coding and a restriction of mobile travel
from zones of one creator to another (another good reason to not have charmed
mobiles do anything).  Tracking down the culprit mobile is not always easy.
The only thing we have found which always works, is to add a log statement
into the MOBprogram driver and fill some disk space until it becomes apparent
what commands are repetitively issued. Also, most infinite loops are flukes
where the situation just happens to be right and usually it never happens
again.

	The list of variables and triggers and if_checks will grow
continuously as our creators demand the ability to do certain things.  If you
have a request or if you have a new one, we don't mind hearing about them,
and if you find bugs, we 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.

	The code has been written for a Merc 2.0 release mud. We were
considering trying to port it back to 1.0, but this really had no gain for us.
Also, much of the internal mud structure has changed and makes this almost a
hopeless task.  We will be glad to lend advice to someone who is trying to
install this for 1.0 and if something develops we will be glad to make that
public as well.


----------------------------------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
murph@ri.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 Marble Mud 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

{+}+{+}+{+}+{+}+{+}+{+}+{+}+{+}+{+}+{+}+{+}+{+}+{+}+{+}+{+}+{+}+{+}+{+}+{+}+{+}



===================CUT HERE FOR QUICK REFERENCE SHEET========================

    MOBprogram quick reference to triggers/variables/ifchecks/mobcommands

trigger         argument and what must happen to activate trigger
-----------------------------------------------------------------------------
act_prog        WORDLIST or P WORD_PHRASE to match from act() to mobile
bribe_prog      INTEGER amount of miminum gold amount given to mobile
entry_prog      PERCENT chance to check when mobile moves to a new room
give_prog       FULL OBJECT NAME or ALL to match when obj given to mobile
greet_prog      PERCENT chance to check if visable char enters mobile's room
all_greet_prog  PERCENT chance to check when any char enters mobile's room
fight_prog      PERCENT chance to check at fight_pulse if mobile is fighting
hitprcnt_prog   PERCENT lower than mobiles hit/max_hit if mobile is fighting
death_prog      PERCENT chance to check after mobile has been slain
rand_prog       PERCENT chance to check whenever a PC is in the mobiles zone
speech_prog     WORDLIST or P WORD_PHRASE to match in dialogue to mobile

variable         mobile actor victim random     object 2nd_object
-----------------------------------------------------------------------------
  name             $i    $n     $t     $r         $o       $p      
shrt_desc/title    $I    $N     $T     $R         $O       $P          
he/she/it          $j    $e     $E     $J         --       --    '$'symbol=$$
him/her/it         $l    $m     $M     $L         --       --          
his/hers/its       $k    $s     $S     $K         --       --
a/an               --    --     --     --         $a       $A
 
ifcheck       argument?        meaning
-----------------------------------------------------------------------------
rand(num)                   Is a random percentage less than or equal to num
isnpc($*)                   Is $* an NPC
ispc($*)                    Is $* a PC
isgood($*)                  Does $* have a good alignment 
isfight($*)                 Is $* fighting
isimmort($*)                Is the level of $* greater than max_mortal
ischarmed($*)               Is $* affected by charm
isfollow($*)                Is $* a follower with their master in the room
isaffected($*) & integer    Is ($*->affected_by & integer) true (person only) 
hitprcnt($*)  == percent    Is the hit/max_hit of $* equal to percent
inroom($*)    == integer    Is the room of $* equal to integer (person only)
sex($*)       == integer    Is the sex of $* equal to integer
position($*)  == integer    Is the position of $* equal to integer
level($*)     == integer    Is the level of $* equal to integer
class($*)     == integer    Is the class of $* equal to integer
goldamt($*)   == integer    Does $* have a gold total equal to integer
objtype($*)   == integer    Is the type of $* equal to integer (armor,boat,etc)
objval#($*)   == integer    Is $*->value[#] equal to integer (# from 0-4)
number($*)    == integer    Is the vnum of $* equal to integer
name($*)      == string     Is the name of $* equal to string

MOBcommand	argument_list		MOBcommand	argument_list
-----------------------------------------------------------------------------
MPSTAT		<mobile>		MPASOUND	<text_string>
MPJUNK		<object>		MPECHO		<text_string>
MPMLOAD		<mobile>		MPECHOAT	<victim> <text_string>
MPOLOAD		<object> <level>	MPECHOAROUND	<victim> <text_string>
MPKILL		<victim>		MPPURGE		[argument]
MPGOTO		<dest>			MPAT		<dest> <command> 
MPTRANSFER	<dest> [location]	MPFORCE		<victim> <command>

======================END OF QUICK REFERENCE SHEET===========================

++++++++++++++++++++++++++++++++EXAMPLE++++++++++++++++++++++++++++++++++++++

Referenced from above in the Control Flow section

>act_prog p pokes you in the~
if isnpc($n)
   chuckle
   poke $n
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!!!
         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.

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,
noone 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)
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

