1stMud/CVS/
1stMud/area/CVS/
1stMud/backup/CVS/
1stMud/bin/
1stMud/bin/CVS/
1stMud/bin/extras/
1stMud/bin/extras/CVS/
1stMud/data/CVS/
1stMud/data/i3/CVS/
1stMud/doc/1stMud/
1stMud/doc/1stMud/CVS/
1stMud/doc/CVS/
1stMud/doc/Diku/
1stMud/doc/Diku/CVS/
1stMud/doc/MPDocs/CVS/
1stMud/doc/Merc/CVS/
1stMud/doc/Rom/
1stMud/doc/Rom/CVS/
1stMud/log/CVS/
1stMud/notes/
1stMud/notes/CVS/
1stMud/player/CVS/
1stMud/player/backup/CVS/
1stMud/player/deleted/CVS/
1stMud/src/CVS/
1stMud/src/config/CVS/
1stMud/src/h/CVS/
1stMud/src/o/CVS/
1stMud/win/CVS/
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

OBJ and ROOM progs added in December 2000
	Ralgha@Gateway to the Night

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.

Ever wanted a room to trap someone?  Or an object to explode on contact?
Enter OBJ and ROOM progs.

TRIGGERS AND SCRIPTS

	The backbone of the Programs 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/object/room.  So, if something happens and a trigger is
activated, then a list of commands is sent to the interpreter in the
mobile/object/room's name, thus making her/it/him do an appropriate something.

VARIABLES

	Since knowing the appropriate response for everything to every
possible trigger is not easy, this command list shouldnt be a rigid script,
but needs to be somehow unique for the thing and the situation.  However, in
order to know the situation, a mobile/object/room 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 Newt's 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

---------------------------About This Version--------------------------------

	I implemented OBJ and ROOM programs because I was wanting to have a more
active world.  I couldn't find any code on the internet, so I adapted the current
ROM2.4 MOBprograms to include objects and rooms.  Objects and rooms can not
perform any normal MUD commands at this point, all of their actions will be
obj or room calls.  No new if_checks have been added, and the object and room
programs use most of the if_checks available to MOBprograms.
	You can see these object and room programs in action on Gateway to the Night.

	--Ralgha

----------------------------Program 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).  To use OBJprograms, you must add a #OBJPROGS section to your area
file(s).  To use ROOMprograms, you must add a #ROOMPROGS section to your area
file(s).

The syntax is identical for each program type, so only a MOBprog is given as 
the example here.

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 Program 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 (unless is is an object 
or room program), 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 Program scripts. If you must have
indentation, use TAB.

NOTE 2: Programs do NOT have to be in the same area file as the 
mobile/object/room definitions, since the programs are linked to the 
mobiles/objects/rooms after the database has been loaded. A Program can also 
be used as a subroutine (see MOB CALL, OBJ CALL, ROOM CALL commands) without 
having to be linked to any mobile/object/room.

-- MOBprogram Example
#MOBPROGS
#3001
say Hey, no loitering!
poke $n
~
#0

-- OBJprogram Example
#OBJPROGS
#3001
obj echo spikes shoot out of $i, impailing your hands!
obj damage $n 50 50
~
#0

-- ROOMprogram Example
#ROOMPROGS
#3001
room echo A bright light flashes and you find yourself in a different place.
room transfer $n 3054
room force $n look
~
#0

--------------------------Linking Programs--------------------------------

	Once you've written your Programs, you must link the programs
to appropriate mobiles/objects/rooms. 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

For Objects:
	"O" {Keyword} {Vnum} {Argument}~ NL

For Rooms:
	"R" {Keyword} {Vnum} {Argument}~ NL

--Explanations
The KEYWORD is a single word, see below for explanations.
The VNUM is the Program 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).

Objects and rooms will react to anyone preforming the act regardless of there
visibility status.  Immortals be careful, as of this writing, they don't check
to see if you're wizi (consult the README to see any changes made after this writing).

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.  Likewise for the
objects and rooms.


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

Program types: MOB, OBJ, ROOM
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

Program types: MOB, OBJ, ROOM
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/obj/room.
	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

Program types: MOB, OBJ, ROOM
Keyword : 'random'
Argument: number

	The argument is a number betweeen 0 and 99 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/object/room,
	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.

	This trigger for objects is checked at each PULSE_TICK, and for rooms at
	each PULSE_AREA.

GREET/GREET ALL

Program types: MOB, OBJ, ROOM
Keyword : 'greet'
Argument: number

	Again a percentage argument.

NOTE:  	Whenever someone enters the room with the mobile/object/room, 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.

	Objects and rooms will always fire on this trigger regardless of the PC's 
	visibility status.

Program types: MOB
Keyword : 'grall'
Argument: number

	Again a percentage argument.

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

Program types: MOB
Keyword : 'entry'
Argument: number

	Again a percentage argument.

NOTE:  	The opposite of greet trigger. 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.
	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

Program types: MOB, OBJ, ROOM
Keyword : 'exit'
Argument: number

	Argument is the exit number (0:north, 1:east, 2:south 3:west etc.)

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/object/room 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/OBJ/ROOM TRANSFER/MOB/OBJ/ROOM GTRANSFER). Also, 
	this event is not triggered when a character flees from combat or the mobile
	is not in its default position.

	Objects and rooms will always fire on this trigger regardless of the PC's
	visibility status.

Program types: MOB
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.

GIVE 

Program types: MOB, OBJ, ROOM
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.

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

OBJ NOTE:   This is triggered whenever the object is given to someone else.
	Also, the argument is ignored in this case.

ROOM NOTE:  This is triggered whenever the object (according to argument) is 
	given to someone in the room.

GET

Program types: OBJ, ROOM
Keyword: 'get'
Argument: string or object vnum

	The argument is either 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.

OBJ NOTE: Fires whenever the object is picked up, argument is ignored.

ROOM NOTE: Fires whenever the object (according to argument) is picked up in the room.

DROP

Program types: OBJ, ROOM
Keyword: 'drop'
Argument: string or object vnum

	The argument is either 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.

OBJ NOTE: Fires whenever the object is dropped, argument is ignored.

ROOM NOTE: Fires whenever the object (according to argument) is dropped in the room.
BRIBE

Program types: MOB
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.

KILL

Program type: MOB
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

Program type: MOB, OBJ, ROOM
Keyword : 'fight'
Argument: number

	The argument is a percentage.

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

OBJ NOTE:	Fires when the object is worn when the player wearing it is fighting.
		Targets the opponent.  Checked every PULSE_VIOLENCE.

ROOM NOTE:	Fires when there is a fight going on in the room.  Targets the first
		person fighting.  Checked every PULSE_VIOLENCE.

HIT POINT PERCENTAGE

Program type: MOB
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. (See also
	MOB FLEE).

DEATH

Program type: MOB
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

Program type: MOB, OBJ, ROOM
Keyword : 'delay'
Argument: number

	The argument is a percentage chance.

NOTE:  	This trigger activates when the delay of a mobile/object/room (set 
	with the MOB/OBJ/ROOM DELAY command) expires. This trigger can be used 
	to create staged mobile/object/room 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/object/room can have several delay triggers, but every time the
	delay timer expires, all the triggers are checked and the first
	successful one executed.

SURRENDER

Program type: MOB
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.

SIT

Program type: OBJ
Keyword: 'sit'
Argument: number

	The argument is a percentage.

NOTE:	This trigger activates when the object is sat on/in/at, rested on/in/at,
	slept on/in/at, or stood on/in/at.


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.

------------------------------Variables------------------------------------

	To make things come alive, variables are needed.  These are
represented in the Programs 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/object itself (doesn't work on rooms).
$I	the short description of the mobile/object itself or name of room.
$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
$R	the short description, or name and title of the random PC
$q	the name of the Program target (see MOB/OBJ/ROOM REMEMBER)
$Q	the short description of the Program target

$j	he,she,it based on sex of $i (doesn't work with rooms).
$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 (doesn't work with rooms).
$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 (doesn't work with room).
$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

	Also, in if_checks, the accepted variables are the basic ones
(i,n,t,r,o,p,q).  If a variable is referenced that doesnt exist, then the
value is simply left blank or replaced with "someone"/"something" 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 REMEMBER and
FORGET commands in a program. Variable $q lets the mobile/object/room "remember" a player
across different programs, which can be useful. Note that $q is set
automatically only the FIRST TIME the mobile/object/room executes a program, every time
thereafter it must be set with a REMEMBER command.

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

---------------------------Control Flow Syntax------------------------------

	Flow of control commands may also be used in the programs. 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 Program 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.


--------------------------------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 ).  The if_checks
work for all types of programs unless otherwise noted.

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.  ONLY WORKS WITH MOBprogs
order      ==	integer    Is the order (of several similar NPCs) of the NPC
			     who activated the trigger equal to integer ONLY WORKS WITH MOBprogs
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

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'

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)

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 six 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.
	
Syntax: OPSTAT [object]
	Displays the triggers and OBJprogam vnums defined for the object.

Syntax: OPDUMP [vnum]
	Displays the OBJprogram code of given vnum.

Syntax: RPSTAT [vnum]
	Displays the triggers and ROOMprogram vnums defined for the room vnum.  If no vnum
	is given, it shows the information for the current room.

Syntax: RPDUMP [vnum]
	Displays the ROOMprogram 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
Programs, 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
	aggressives 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] [level] {'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 3rd 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).

Syntax:  MOB KILL [victim]

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

Syntax:  MOB FLEE

	Causes a mobile to unconditionally flee from combat. Can be used
	for example with the hit point percentage trigger to simulate
	"wimpy" behavior.

Syntax:  MOB REMOVE [victim] [vnum|'all']

	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. 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 refered 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, 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:  MOB AT [location] [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:  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  [victim|'all'] [location]
	 MOB GTRANSFER [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 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.
	Gtransfer works like transfer, except that the group the victim
	belongs	to is transferred with the victim. Otransfer transfers an
	object in the room.

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 [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, but spell effects are displayed normally.

Syntax:  MOB DAMAGE [victim|'all'] [min] [max] {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. 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
	 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.
	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} {target2}

	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 and fourth are optional object
	names. 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.
	
4. 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
Programs, players have been prevented from using these commands by adding
a separate interpreter for OBJcommands. This also speeds up (in most cases)
MOBJprogram execution when OBJcommands are used. All OBJcommands are
preceded with the word 'OBJ' on the command line.


Syntax:  OBJ ZECHO  [string]
	     OBJ GECHO  [string]

	ZECHO prints the string to all players in the same area with the
	object. GECHO prints the string to all players in the game.

Syntax:  OBJ ECHO                 [string]
	 OBJ ECHOAT      [victim] [string]
	 OBJ 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 do other
	sneaky stuff:).

Syntax:  OBJ MLOAD [vnum]
	 OBJ OLOAD [vnum] [level]

        MLOAD creates a mobile and places it in the same room with the
	object.
	OLOAD loads the object into the room.

Syntax:  OBJ REMOVE [victim] [vnum|'all']

	Lets the object 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. 

Syntax:  OBJ PURGE [argument]

	Destroys the argument from 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.  However, mppurge $i will indeed
	purge the object, but it MUST be the last command the object tries to
	do, otherwise the mud cant reference the acting object trying to do the
	commands and bad things happen.  

Syntax:  OBJ GOTO [location]

	Moves the object 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:  OBJ TRANSFER  [victim|'all'] [location]
	 OBJ GTRANSFER [victim]       [location]
	 OBJ OTRANSFER [object]       [location]

	Sends the victim to the destination or to the room of the object as a
	default.  if the victim is "all" then all the characters in the room
	of the object 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 object forces them to.
	Gtransfer works like transfer, except that the group the victim
	belongs	to is transferred with the victim. Otransfer transfers an
	object in the room.

Syntax:  OBJ FORCE  [victim|'all'] [command]
	 OBJ GFORCE [victim]       [command]
	 OBJ 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 opecho
	message is nice.  You can force players to remove belongings and drop them,
	etc.  The player sees the normal command messages (such as
	removing the item and dropping it in the above example)  Again, if
	the victim is "all" then everyone in the object's 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:  OBJ DAMAGE [victim|'all'] [min] [max] {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. 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 DELAY
	 OBJ CANCEL

	OBJ DELAY sets the time in PULSE_TICK after which the object's
	delay trigger is activated. If the object has a program defined
	for delay trigger, the program is executed when the timer expires.
	OBJ CANCEL resets the delay timer.


Syntax:  OBJ REMEMBER [victim]
	 OBJ FORGET

	This command enables the object to remember a player for future
	reference in a OBJprogram. The player can subsequently be referred
	as '$q' in programs activated by the object. OBJ FORGET clears
	the target. Note that if the first time the object 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
	object has to remember the player who triggered the original
	event.

Syntax:  OBJ CALL [vnum] {victim} {target1} {target2}

	This command lets you call OBJprograms from within a running one,
	i.e. to call a OBJprogram 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 and fourth are optional object
	names. All other parameters except vnum can be replaced with
	word 'null' indicating ignored parameter.
	OBJprograms can be called recursively, but as a safety measure,
	parser allows only 5 recursions.

Syntax:  OBJ ATTRIB [target] [level] [condition] [v0] [v1] [v2] [v3] [v4]

	This command will change the object's stats to those specified.
	The target argument is the character who's level you want to compare,
	each other argument corresponds to the object stat with that name.
	All arguments must be included, see following list for details on
	argument options.

	Target may be a $ code or if you put "worn" as the argument, it will
	target the character that is wearing the object.

	Each of the other arguments must be an integer value, if you want to
	compare against the target's level, at an operator (+,-,*,/) just
	before the number with no space.
	EXAMPLE:
	    obj attrib worn 20 *3 /2 +5 -14 8 8

	In this case the target will be the character wearing the object.
	The object's level will be set to 20,
	object's condition will be set to the target's level * 3,
	object's v0 will be set to the target's level / 2,
	object's v1 will be set to the target's level + 5,
	object's v2 will be set to the target's level -14,
	objects v3 and v4 will both be set to 8

5. ROOMCOMMANDS

	ROOMcommands are special commands that allow rooms to perform
immortal-like actions within a ROOMprogram (transferring players or loading
items, for example). Most ROOMcommands them are wiz commands which have been
changed to allow for rooms to perform the commands. In this version of
Programs, players have been prevented from using these commands by adding
a separate interpreter for ROOMcommands. This also speeds up (in most cases)
ROOMprogram execution when ROOMcommands are used. All ROOMcommands are
preceded with the word 'ROOM' on the command line.


Syntax:  ROOM ASOUND [string]
	 ROOM ZECHO  [string]
	 ROOM GECHO  [string]

	ASOUND prints the text string to the rooms around the room in the
	same manner as a death cry.
	ZECHO prints the string to all players in the same area. 
	GECHO prints the string to all players in the game.

Syntax:  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 three options let you tailor the message to goto victims or do
	other sneaky stuff:).
	
Syntax:  ROOM MLOAD [vnum]
	 ROOM OLOAD [vnum] [level]

        MLOAD creates a mobile and places it in the room.
	OLOAD loads the object into the room.

Syntax:  ROOM REMOVE [victim] [vnum|'all']

	Lets the room 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. This command is
	probably most useful for extracting quest items from a player
	after a quest has been completed.

Syntax:  ROOM PURGE [argument]

	Destroys the argument from the room. Without an argument
	the result is the cleansing of all NPC's and items from the room.

Syntax:  ROOM TRANSFER  [victim|'all'] [location]
	 ROOM GTRANSFER [victim]       [location]
	 ROOM OTRANSFER [object]       [location]

	Sends the victim to the destination or to the room as a
	default.  if the victim is "all" then all the characters in the room
	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 room forces them to.
	Gtransfer works like transfer, except that the group the victim
	belongs	to is transferred with the victim. Otransfer transfers an
	object in the room.

Syntax:  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 so usually some rpecho
	message is nice.  You can force players to remove belongings and drop
	them, 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 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:  ROOM DAMAGE [victim|'all'] [min] [max] {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. 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:  ROOM DELAY
	 ROOM CANCEL

	ROOM DELAY sets the time in PULSE_AREA after which the room's
	delay trigger is activated. If the room has a program defined
	for delay trigger, the program is executed when the timer expires.
	ROOM CANCEL resets the delay timer.


Syntax:  ROOM REMEMBER [victim]
	 ROOM FORGET

	This command enables the room to remember a player for future
	reference in a ROOMprogram. The player can subsequently be referred
	as '$q' in programs activated by the room. ROOM FORGET clears
	the target. Note that if the first time the room 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
	room has to remember the player who triggered the original
	event.

Syntax:  ROOM CALL [vnum] {victim} {target1} {target2}

	This command lets you call ROOMprograms from within a running one,
	i.e. to call a ROOMprogram 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 and fourth are optional object
	names. All other parameters except vnum can be replaced with
	word 'null' indicating ignored parameter.
	ROOMprograms can be called recursively, but as a safety measure,
	parser allows only 5 recursions.
	
--------------------------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 Programs extensively in my own mud without adverse
effects. This version of Programs 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 Programs, especially with the speed of today's servers..

--------------------------Loading Mobiles and Objects--------------------------

	No doubt you want to load objects and mobiles in your Programs
with the various "mload" and "oload" commands. 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 "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 Program 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
'purge $i'.
	Another possibility is to use a "purgeroom". Create a storage
room and attach a random trigger that does 'room purge'
to that room. Now, when you need to get rid of anything, just 'transfer' 
the mobile or item to purgeroom, and it will be destroyed sometime later.
	
-------------------------Miscellaneous Information-----------------------------

	There is really no limit to the number of Programs a given mobile/object/room
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/objects/rooms which can trigger in
loops. Infinite loops have been prevented, but in case of a loop, the behavior is undefined.

-----------ORIGINAL MOBprog CODE NOTE-----------------------------
	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.

--Newt
--------------OBJprog and ROOMprog NOTE-----------------------------
I am happy to hear about new trigger ideas, and also major bugs.  Please don't
bother me with minor bugs such as "it won't compile because of ______ error".
It compiles fine for me, and a little coding knowledge will enable you to solve any
compiler issues.

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

	I added object and room programs for ROM 2.4 version in winter of 2000.
My thanks to the previous people who developed the original MOBprogam code
from which I developed the object and room programs.  If you are using this code, it
would be nice to get a message saying so, but you don't have to.  This code is also
only "half-supported" I don't have time to personally aid everyone who has a problem, but
if you do find a bug, I would appreciate an email about it so I can fix it and redistribute this
code minus bugs:)
My thanks also to Elderon@Gateway to the Night along with the rest of the staff and players 
of Gateway to the Night who were the guinea pigs for this code and found many bugs 
(all of which have been fixed:)).

--Ralgha                                                                   December 2000
ralgha@gatewaynight.betterbox.net

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

Program quick reference to triggers/variables/ifchecks/mobcommands

-----------------------------------------------------------------------------
Area file format
-----------------------------------------------------------------------------
#MOBILES

M {trigger} {program vnum} {argument}~

#OBJECTS

O {trigger} {program vnum} {argument}~

#ROOMS

R {trigger} {program vnum} {argument}~

#MOBPROGS

#{program vnum}
{program code}~

#OBJPROGS

#{program vnum}
{program code}~

#ROOMPROGS

#{program vnum}
{program code}~

-----------------------------------------------------------------------------
trigger    argument and what must happen to activate trigger
-----------------------------------------------------------------------------
act        STRING 	to match from act() to mobile, for obj and rooms it matchs acts TO_ROOM and TO_NOTVICT
speech     STRING 	to match in dialogue (say, tell) to mobile, matches says in the room for objects and rooms
rand       PERCENT 	chance to check whenever a PC is in the mobile/object/room's zone
bribe      INTEGER 	miminum amount of silver coins given to mobile ONLY MOB
give       OBJECT NAME, OBJECT VNUM or ALL to match when obj given to mobile, 
				for objects: fires when the object with the tirgger is given, for rooms: fires when object is given in the room.
greet      PERCENT 	chance to check if visible char enters mobile's room, for objects and rooms it is basically grall
grall      PERCENT 	chance to check when any char enters mobile's room MOB ONLY
entry      PERCENT 	chance to check when mobile moves to a new room MOB ONLY
exit       EXIT NUMBER	a visible char tries to exit mobile's room, for objects and rooms it is basically exall
exall      EXIT NUMBER	any char tries to exit mobile's room MOB ONLY
kill       PERCENT	chance to check when the mobile begins fighting MOB ONLY
fight      PERCENT 	chance to check at fight_pulse if mobile is fighting, object is worn in a fight, or there is a fight in the room
hpcnt      PERCENT 	lower than mobile's hit/max_hit if mobile is fighting MOB ONLY
death      PERCENT 	chance to check after mobile has been slain MOB ONLY
surr       PERCENT      chance to activate when a char surrenders to mobile MOB ONLY

----------------------------------------------------------------------------
variable              mobile/obj/room  actor    victim    random    target    object   2nd_object
-----------------------------------------------------------------------------
  name                           $i                $n         $t          $r            $q         $o          $p      
shrt_desc/title                $I               $N         $T        $R          $Q         $O         $P          
he/she/it                        $j               $e          $E        $J           $X          --            --  
him/her/it                       $l               $m         $M        $L           $Y          --            --          
his/hers/its                     $k              $s          $S        $K           $Z          --            --
a/an                                --                --           --            --             --           --           --

----------------------------------------------------------------------------
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 MOB ONLY
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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]		                   FLEE
REMOVE            [victim] [vnum]                 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 ++++++++++++++++++++++++++++++++++++

These examples all use MOBprogs, OBJ and ROOM progs are done in the same formate (excepting the
trigger on each obj/room).


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

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
~

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++