fbmuck-6.01/contrib/jresolver/
fbmuck-6.01/contrib/jresolver/org/
fbmuck-6.01/contrib/jresolver/org/fuzzball/
fbmuck-6.01/docs/devel/
fbmuck-6.01/game/
fbmuck-6.01/game/logs/
fbmuck-6.01/game/muf/
fbmuck-6.01/scripts/
fbmuck-6.01/src_docs/
                  MPI Reference Manual for FBMuck 6.00
                   by Revar Desmera <revar@belfry.com>


                  <continued from mpidocs>


----------------------------------------------------------------------------
                             Looping Functions
----------------------------------------------------------------------------


{for:varname,start,end,increment,command}
    Acts as a counting loop, like BASIC's for loops.  The varname is the name
of the variable that it will create and use to store the count value.  The
start value will be the initial value of the variable, and the end value will
be the value that the variable is working towards.  The increment is how much
the variable will be incremented by in each loop.  The command will be eval-
uated for each value of the variable between the beginning and ending values.
For example:
    {null:{for:i,10,1,-1,{tell:{&i}}}}
will echo a countdown from ten to one, inclusive, to the user.


{while:check,expr}
    This is a looping structure.  It evaluates the 'check' argument, and
if it evaluates true, then it evaluates the expr argument, and repeats
the process.  If 'check' evaluates false, then the loop is exited.
This returns the result of the last evaluation of expr.


{foreach:var,list,expr}
{foreach:var,list,expr,sep}
    This evaluates expr for each and every item in the given list.  On
each evaluation, the temporary variable var will contain the value of the
item under scrutiny.  var will only be defined for the duration of expr,
and will be undefined after the {foreach} construct finishes.  If sep is
given, then it uses that string as the item seperator in list, instead of
the usual carriage return character.  sep can be multiple characters
long.  This structure returns the result of the last evaluation of expr.
Example:
    {foreach:thing,{contents:here},{tell:{name:{&thing}}}}
This will display the name of every object in the room, then it will return
the name of the last object it displayed.


{filter:var,list,expr}
{filter:var,list,exp,sep}
{filter:var,lst,exp,sep,s2}
    This evaluates expr for each and every item in the given list.  On
each evaluation, the temporary variable var will contain the value of the
item under scrutiny.  This function returns a list containing all of the
items from the input list, for which expr evaluated true.  var will only
be defined for the duration of expr, and will be undefined after the
{filter} construct finishes.  If sep is given, then it uses that string
as the item seperator in the input list, instead of the usual carriage
return character.  If s2 is defined, then it will use that string to
seperate the items in the list it returns, instead of the normal carriage
return.  sep and s2 can be multiple characters long.


{parse:var,list,expr}
{parse:var,list,expr,sep}
{parse:var,list,expr,sep,s2}
    This evaluates expr for each and every item in the given list.  On
each evaluation, the temporary variable var will contain the value of the
item under scrutiny.  This function returns a list containing the output
of expr for each item within the list.  This lets you do direct translat-
ion of a list of dbrefs, for example, into a list of names.  var will
only be defined for the duration of expr, and will be undefined after the
{filter} construct finishes.  If sep is given, then it uses that string
as the item seperator in the input list, instead of the usual carriage
return character.  If s2 is defined, then it will use that string to
seperate the items in the list it returns, instead of the normal carriage
return.  sep and s2 can be multiple characters long.


{fold:var1,var2,list,expr}
{fold:var1,var2,lst,expr,sep}
    This takes a list and stores the first two items in var1 and var2, then
evaluates expr.  The value returned by expr is then put in var1, and the next
list item is put in var2.  Expr keeps being evaluated in this way until there
are no more list items left.  This returns the last value returned by expr.
If a sep argument is given, the input list is assumed to have its individual
items delimited by that string, otherwise it assumes a carriage return.



----------------------------------------------------------------------------
                         Database Related Functions
----------------------------------------------------------------------------


{ref:obj}
    Returns the dbref of the given object in the form #xxxx.  The object
must be in the vicinity, or controlled by the owner of the trigger object.


{name:obj}
    Returns the name of the given object.  If the object is an exit, the
name returned is the first exit name it has before the first ';'.  The object
must be in the vicinity, or controlled by the owner of the trigger object.


{fullname:obj}
    Returns the name of the given object.  In the case where the object
is an exit, then the full name of the exit is given, including all the ;
aliases.  The object must be in the immediate vicinity, or be controlled
by the owner of the trigger object.


{owner:obj}
    Returns the owner of the given object.  The object must be in the
vicinity, or be controlled by the trigger object's owner.


{loc:obj}
    Returns the location of the given object.  The object must either be in
the vicinity, or it must be controlled by the owner of the trigger object.


{flags:obj}
    Returns a flaglist string from obj. ie: PM2J.  The object must either
be in the vicinity, or it must be controlled by the owner of the trigger
object.


{created:obj}
    Returns the time and date that obj was created.  The number returned is
suitable for use with {convsecs}.


{modified:obj}
    Returns the time and date that obj was last modified.  The number returned
is suitable for use with {convsecs}.


{lastused:obj}
    Returns the time and date that obj was last used.  The number returned is
suitable for use with {convsecs}.


{usecount:obj}
    Returns the usage count that obj has incurred since it was created.


{controls:obj}
{controls:obj,player}
    If one argument is given, then this returns true ("1") if the trigger
object's owner controls the given object.  If two arguments are given, then
it returns true if the given player controls the given object.  Otherwise,
this returns false.  ("0")  Wizards control everything.


{nearby:obj}
{nearby:obj,obj2}
    If one argument is given, then this returns true ("1") if the given
object is nearby to the trigger object.  If two arguments are given, then
it returns true if the two objects are nearby one another.  Otherwise,
this returns false. ("0")  Nearby is defined as: 1) The two objects are
in the same location, or 2) One object contains the other, or 3) the two
objects are in fact the same object.


{money:obj}
    This returns the value of an object of TYPE_THING, or returns how many
pennies a player has.


{type:obj}
    Returns the type of an object.  The possible values are:  Bad, Room,
Exit, Thing, Player, and Program.


{istype:obj,typ}
    Returns true if the given object if of the given type.  Valid types are:
Bad, Room, Exit, Thing, Player, and Program.


{contents:obj}
{contents:obj,type}
    Returns a list of the contents of the given object.  If a second
argument is passed to it, it restricts the listing to only those objects
that are of the given type.  Either the object must be nearby the trigger
object, or else the owner of the trigger object must control the object.
Otherwise this will error out with a Permission Denied error.  The valid
object type values are Room, Thing, Exit, Player, Program, and Bad.
HINT:  If you need to get a list of two types of objects from the room,
just concatenate the lists from two calls to this function, with each
object type you want.  ie:
    {mklist:{contents:here,player},{contents:here,thing}}    or
    {contents:here,player}{nl}{contents:here,thing}


{exits:obj}
    Returns a list of all the exits on the given object.  The owner of
the trigger object has to control obj, or else this errors out with
Permission Denied.  Programs and exits never have exits attached to them.


{links:obj}
    Returns the object reference of what the given object if linked to.
Since exits can be meta-links, linked to multiple exits, if there is more
than one link, then this function returns a list of all the destinations,
seperated by carriage return characters.  (\r)


{force:object,command}
    Forces the given player or thing to do the given command.  The thing
forced must be @flock'ed to the trigger object, or the trigger object's
owner, and it must be set XFORCIBLE, or else this function will get a
Permission Denied error.  This function returns a null string.  {Force}
cannot force a thing-object to do something, if it is set Dark, is in a
room set Zombie, or is owned by a player set Zombie.


{dbeq:obj1,obj2}
    Returns true if obj1 and obj2 refer to the same object.  This does
name matching, so {dbeq:*Wizard,#1} will return true if #1 is named Wizard.


{locked:player,obj}
    Tests the _/lok (@lock) standard lock property on obj against the given
player.  Returns true if the lock is locked against the player.


{testlock:obj,prop}
{testlock:obj,prop,who}
{testlock:obj,prop,who,def}
    Tests the lock property 'prop', on 'obj' against the given player 'who'.
If no 'who' argument is given, then it checks the lock against the using
player.  If a def argument is given, then the lock will default to that
value, if there is no lock property of the given name on the given object.
Returns true if the lock is locked against the player.


{holds:obj1}
{holds:obj1,obj2}
    Returns true if the location of obj1 is obj2.  If no obj2 argument is
given, then this will return true if the location of obj1 is the player.


{contains:obj1}
{contains:obj1,obj2}
    Returns true if obj1 is within obj2, or within anything it contains, or
within anything they contain.  If obj2 is not given, then it checks to see
is obj1 is held by the player, or by anything they hold, etc.  Basically,
this just sees if obj1 is within the locational environment of obj2.



----------------------------------------------------------------------------
                        Connection Related Functions
----------------------------------------------------------------------------


{online}
    Returns a list of players who are online.  This function can only be
executed with blessed permissions.


{awake:player}
    Returns how many times player is connected.  This means that it will
returns 0 if the player is not connected.  If the given object is NOT a
player, it will return 0.  If the given player is NOT local to the trigger,
and is not the owner of the trigger, and this is not run with blessed perms,
then this will return 0.  In all other cases, it will return a positive
number, being how many times the given player is connected to the server.


{ontime:player}
    Returns player online time in seconds.  If the given player is not
connected, or is not a player object at all, then this will return -1.
This returns the online time for the most recently connected connection,
if there are multiple connects.


{idle:player}
    Returns player idle time in seconds.  If the given player is not
connected, or is not a player object at all, then this will return -1.
This returns the idle time for the most recently connected connection,
if there are multiple connects.



----------------------------------------------------------------------------
                        Variable Handling Functions
----------------------------------------------------------------------------


{&VAR}
{v:VAR}
    These are two ways of trying to do the same thing.  They return the
value of the named variable VAR.  If there is no variable with the given
name currently defined, then this gives an error stating as much.  Variables
can be defined either with the {with:} function or within a looping command.


There are three standard variables that every MPI program can read:

{&how}  
    The {&how} variable is a short string telling what ran the MPI command.
It can have the values "(@desc)", "(@succ)", "(@osucc)", etc. for when it
is run from an @desc, an @succ, an @osucc, or whatever.  It can also have
the value "(@lock)" for when it is run from a lock test.


{&cmd}
    The {&cmd} variable contains the command name the user used, that
caused the MPI to run.  This is generally the exit name that the player
triggered.  For example, if the player typed 'east', and triggered the exit
named 'east;e;out', which ran some MPI commands, the {&cmd} variable would
have a value of "east".


{&arg}
    The {&arg} variable contains a string with the value of the command
line arguments the user entered.  This is so that you can have stuff like
MPI in the fail of an exit, and when the user triggers the exit, and has
some extra text on the line they entered, other than the exitname, the
MPI can take that extra stuff as arguments for use.  Note that you need
to set an action HAVEN to get it to accept command line arguments.


Other MPI functions used to work with variables are:

{set:var,value}
    This sets the value of the given named variable to the given value.
If no variable with that given name is currently defined, then this gives
an error message complaining about that.


{with:var,val,expr..}
    This defines a new variable with the given name, and sets it's value
to the given val.  Up to 7 expr's are allowed, but the only value
returned to {with}'s caller, is the value returned by the evaluation of
the last expr.  If there is already a variable of the same name, then
this command will override that variable, for the duration of the {with:}
command.  The new variable is only valid to use within the confines of
the {with:} command, and it will go away after the command completes.
This provides scoped variables quite effectively.  NOTE:  There can be no
more than 32 variables defined at any one time, total.  This includes
variables that are defined within macros, or properties or lists that are
executed with {exec:} or {lexec:}.   Here's an example to illustrate the
scope of variables inside of {with:} commands:

    {prop:_mydesc}                           <- {&people} not defined.
    {with:people,{contents:here,players},    <- Defining.  Not available yet.
        {if:{count:{&people}},               <- It's usable now.
            The players awake here are
            {lit: }                          <- just puts in a space.
            {commas:{&people},{lit: and },
                who,{name:{&who}}            <- uses {&who} as temp var.
            }                                <- {&who} no longer defined.
        }
    }                                        <- {&people} no longer defined.



----------------------------------------------------------------------------
                          List Handling Functions
----------------------------------------------------------------------------


{count:list}
{count:list,sep}
    This counts the number of \r delimited items that are in the given list.
This is effectively a list item count.  If the sep argument if given, then
it counts the number of sep delimited substrings in list.  ie: The default
sep is \r. (A carriage return.)


{mklist:value...}       Returns a list with all given values.
    This returns a list with all the given values as list items, seperated
by carriage returns.  ('\r's) Example:
    {mklist:Tom,Dick,Harry}
returns "Tom\rDick\rHarry".  Note:  A maximum of nine items can be passed to
the {mklist} function.  If you need more, you can chain {mklist}s together.
Example:
    {mklist:{mklist:a,b,c,d,e,f,g,h,i},j,k,l,m,n,o,p}


{sublist:list,pos1}
{sublist:list,pos1,pos2}
{sublist:list,pos1,pos2,sep}
    Takes a list, and returns a subset of the list items within it.  The
subset is all the list items between list item pos1, and list item pos2,
inclusive.  If the pos2 argument is omitted, it assumes that pos2 is the
same as pos1.  If pos2 is less than pos1, then all the list items between
pos2 and pos1 are returned, in reversed order.  If pos1 or pos2 are negative,
it counts that many list items back from the end of the list, so -1 is the
last list item, and -5 would be the fifth from last list item.  The input
list is assumed to be delimited by carriage returns (\r) unless the sep
argument is given.


{lrand:list}
{lrand:list,seperator}
    Returns a randomly picked stringlist item from the given list.  If the
seperator argument is given, then it will assume that the stringlist has it's
items delimited by the given seperator string, instead of by carriage returns.


{lunique:list}
    Returns list with all duplicate items removed.


{lunion:list1,list2}
    Combines the contents of list1 and list2, removing any duplicates.


{lcommon:list1,list2}
    Creates a list containing every item that appears in BOTH list1 and
list2.  Any duplicate items in the resulting list are removed.


{lremove:list1,list2}
    Returns the contents of list1, with any items that match an item in
list2 removed.  The resulting list has all duplicate items removed.


{lmember:list,item}
{lmember:list,item,delimiter}
    Returns 0 if the given item is NOT in the given list, otherwise, it
returns the item's position in the list.  The first list item in the list
would return 1, and the third would return 3, for example.  If the delimiter
argument is given, then it treats the list as if it were delimited by that
string, instead of by carriage returns. (\r's)
Example:
    {lmember:{mklist:a,b,c,d,e,f},d}
would return 4.


{lsort:list}
{lsort:list,var1,var2,expr}
    Returns the sorted contents of list.  If 4 arguments are given, then
it evaluates expr with a pair of values, in var1 and var2.  If expr
returns true, then it will swap the positions of the two values in the
list.  It runs this comparison on every pair of items in the list, so it
will be evaluated N*N times, where N is the number of items in the list.
This method can also be used to randomize a list.  Example:
    {lsort:{&list},v1,v2,{gt:{dice:100},50}}


{commas:list}
{commas:list,lastsep}
{commas:list,lastsep,var,expr}
    Takes a list and returns a plain english comma delimited string with
the items in it.  For example, {commas:{mklist:Tom,Dick,Harry}} will return
"Tom, Dick and Harry".  If you specify the lastsep argument, you can replace
the "and" with something else, such as "or" to get a result like "a, b or c".
Note:  You need to be careful to include spaces around the "or" or else you
might get a result like "a, borc".  Example:
    {commas:{mklist:a,b,c}, or }
If the var and expr arguments are passed, then for every item in the list,
it will set the value of the given variable name (which it will declare)
to the item, then evaluate expr, and use the result in the string it outputs.
Example:
    {commas:{contents:here},\, or ,v,{name:{&v}}}
will return the name of every object in the room in a comma separated list,
using ", or " as the final conjunction.  ie:  "Tom, Can of SPAM, Dick, or
Harry."



----------------------------------------------------------------------------
                          Miscellaneous Functions
----------------------------------------------------------------------------


{isnum:number}
    Returns true if the string passed to it is a valid number.


{isdbref:dbref}
    Returns true if the string passed to it is a valid dbref.


{version}
    Returns the version string for the server.


{muckname}
    Returns the muck name string.  For example, it might return: "FurryMUCK"


{muf:prog,arg}
    Runs the given MUF prog with the string arg on the stack.  This returns
the top stack value when the prog exits.  If the MPI code was run from a
propqueue like _listen, or _connect, then {muf} cannot run a MUF program
with a mucker level of less than 3 


{debug:expr}
    This will show MPI debugging information for all the commands within the
given expression.  This is useful for seeing why something isn't working.
This returns the result of the evaluation of expr.



{debugif:cond,expr}
    This will evaluate the conditional cond, and, if the result is true,
(not an empty string, and not 0), then this will show MPI debugging info
for all the commands within the given expression.  If cond evaluated as
false, then expr is evaluated without the debugging info being displayed.
This is useful for Debugging code selectively.  This returns the result
of the evaluation of expr.

Example:
    {parse:v,{contents:here},{debugif:{dbeq:{&v},me},{dostuff:{&v}}}}
to only debug the running of the command {dostuff} when the argument will
be the player who is running the MPI.




----------------------------------------------------------------------------
                            Macros and Functions
----------------------------------------------------------------------------


Macros:
    If the MPI interpreter comes across a function name that it does not
recognize, it will look in the _msgmacs/ propdirs down the environment from
the trigger object, for a property with the name of the function.  If it does
find it there, then it takes the value of that property, and substitutes it
in for the function as a macro.  The arguments to the function replace the
{:1} through {:9} markers in the macro definition.  For example, if there were
a property set on #0, defined as:
    _msgmacs/div_rand:{add:{div:{:2},10},{dice:{:1}}}
And you had some MPI code that looked like:
    {div_rand:22,160}
Then the macro would expand out to:
    {add:{div:160,10},{dice:22}}
After the macro argment substitution is complete, it is then evaluated.


{func:name,vars...,def}
    This effectively defines a function in MPI, with the given name, that
takes the given named variables.  The function is not immediately evaluated,
so it needs to be invoked later, to do anything.  Here's an example:
  
    {func:sqr,val,{mult:{&val},{&val}}}
  
This defines the function 'sqr', that takes a single argument.  That
argument is stored in the 'val' variable.  The function will multiply
the value of the number passed to it, by itself, returning the result.
It's invoked like:
    {sqr:10}
  
Effectively, the above {func} declaration is the same as the following
macro, and in fact, it's internally handled the same way:
  
    _msgmacs/sqr:{with:val,{:1},{mult:{&val},{&val}}}
  
You can define a function that takes more than one argument, but the maximum
number of args you can pass to the function is seven.  Example of multiple
arguments:
  
    {func:names,list,numsp,flagsp,
        {parse:v,{&list},
            {name:{&v}}
            {if:{or:{&numsp},{&flagsp}},
                {lit:(}
                {if:{&numsp},{ref:{&v}}}
                {if:{&flagsp},{flags:{&v}}}
                {lit:)}
            }
        }
    }
    {names:{contents:here},1,1}