=== MOBprograms
*NOTE: Please do NOT use these if you do
not understand how to, a bad prog WILL Crash the Mud*
MOBprograms are a way to make your mobiles more interesting. This
basic version has enough to get things going, and should be quite
readable and
understandable and more to the point, extendable. The remainder
of this
document describes MOBprograms and gives a couple trivial
examples.
For information on how to install the MOBprograms into a Merc 2.0
beta
coding platform consult INSTALL.
Table of Contents:
The Basic Idea
MOBprogram Syntax
Associating MOBprograms With A Mobile
MOBprogram Files
Trigger Types
Variables
Control Flow Syntax
Operators
If_Checks In Control Flow
MOBcommands Of Interest
Regarding CPU Slowdown
Miscellaneous Information
Credits
-----------------------------The Basic
Idea---------------------------------
Ever wonder why most muds either seem dead or overcrowded? The
answer
is probably partially due to the fact that the mobiles never do
anything
but wait to be slaughtered. Unless someone has gone to great
lengths
and added many special procedures, most mobiles have no idea you
are in
the room with them and rarely listen to what you say. The typical
Midgaard
mayor wanders happily along even when the populace pokes him,
waves his
City Key about, unlocks his gates, or frenchs his secretary, etc.
So a way to
give the mobiles a bit more spirit would be neat. Enter the
MOBprograms.
The backbone of the MOBprograms shall be called triggers from
this
point on. Essentially, they are procedure calls placed in sneaky
places in
the mud code which provide the context for what is going on
around the
mobile. So, if something happens in the mobile's room and a
trigger is
activated, then a list of commands is sent to the interpreter in
the
mobile's name, thus making her/it/him do an appropriate
something.
Since knowing the appropriate response for every mobile to every
possible trigger is not easy, this command list shouldnt be a
rigid script,
but
needs to be somehow unique for the mobile and the situation.
However, in
order to know the situation, a mobile needs to know more about
the trigger
than that it just happened. So, we have to include some sort of
variables
as well to set the context appropriately.
As most implementors know, most area creators are not versed in
coding, but usually have great ideas. Therefore, whatever system
is used needs
to be quite simple. This is not to demean creators in anyway.
Simply, it is
useless to have a powerful system, if the only person able to
write anything
is someone who finds C coding in general to be exciting and non
frustrating.
If that is going to be the case, then stick to the special
procedures, since
there is no bound to what a complex special procedure can
accomplish. Yet,
from experience working on several muds, most admins and
implementors prefer
not to be writing one shot spec_procs to satisfy the needs of
their creators.
Thus, the basic idea: let mobiles react to a myriad of mud
events/situations by having them perform a list of commands which
can be
tailored to the moment through a simple and unintimidating scheme
usable by
any creator.
----------------------------MOBprogram
Syntax--------------------------------
The simplest way to describe any syntax is by example, so here
goes.
First, define the notation: anything contained in braces {} is
required,
anything in brackets [] is optional, anything in quotes
"" is a case
insensitive literal, NL refers to a required new-line. The
meanings of
the labels used will be described following the syntax diagram.
">" {trigger_type} " " {argument_list}
"~" NL
{program_command_1} NL
{program_command_2} NL
{program_command_3} NL
. . .
{program_command_N} NL
"~" NL
-- Explainations
A TRIGGER_TYPE is one of the available triggers.
A PROGRAM_COMMAND can be any legal mud command, or a control flow
command.
The ARGUMENT_LIST depends upon the trigger, but it is always
parsed into the
system as a character string.
This is an example of ONE MOBProgram block for a mob.
-------------------Associating MOBprograms With A
Mobile--------------------
There are two ways for the mud to associate the program with the
mobile. In either case, the result is a link list of mob_programs
which are
attached to the mobile_prototype. This is done at boot time, and
so only one
copy is kept, regardless of how many instances of the mobile are
running
about. This also means that there is no dynamic way to edit or
modify the
MOBprograms.
Back to ways to associate...
The first involves a simple in-file approach. In the mobile
section
of your area files, at the end of the mobile's block (i.e. on the
line
following the typical position/default position/sex line), append
any number
of MOBprograms blocks (using the syntax above) followed by a line
starting
with one '|' (pipe). Example provided: Example.are
The second method is to add a #MOBPROGS section to the area
files.
Logically this section should follow the #MOBILE section since
otherwise the
mobiles probably wont have space allocated for them. In the
#MOBPROGS section,
list as many lines as you desire of:
"M" {Vnum} {MOBprogram_filename} NL
followed by a line starting with a 'S' (case insensitive)
--Explainations
The VNUM is whatever number mobile to which you are associating
the
MOBprogram.
The MOBPROGRAM_FILENAME is the name of the external file of
MOBprograms.
It is not case INsensitive and may include directory heirarchies
(foo/bar/xx)
NOTE: MERC 2.2 provides for a separate directory called MOBProgs.
Any
directory heirarchies branch from the Merc2/area/MOBProgs
directory.
----------------------------MOBprogram
Files----------------------------------
Since it is often useful to have the same MOBprograms affecting
several
different mobiles, referencing MOBprograms stored in an external
file
is needed. As described above, if the second method is used, such
a file
is already being referenced. Using the first method, in place of
a true
MOBprogram block, one can place the dummy line in the #MOBILE
section of the
*.are file in place of the MOBProgram block(s).
">" "in_file_prog" {MOBprogram_filename}
"~" NL
Note there is no list of program_commands as well as no second
tilde ~.
In a file, the syntax is exactly the same as it is for a in_file
approach:
A list of MOBprogram (NOT including any dummy in_file_prog
lines, sorry but recursion was outlawed for simplicity)
blocks followed by a line starting with one '|' (pipe).
Example provided: Beggar.prg
More than one mobile can use the same file and one mobile can
call more
than one file. Files referenced using the dummy in_file_prog line
are
placed in the MOBprogram list at the point where the dummy line
exists.
Files referenced using the #MOBPROG section are added to the end
of the
mobiles MOBprogram list. This is important because the only the
first
successful MOBprogram of some trigger_types is checked. These are
described
below.
-----------------------------Trigger
Types----------------------------------
Triggers are fairly easy to add, but this basic list should hold
for
most needs. Their names, argument list syntaxes, and translation
into
more articulate english are given below:
Syntax: in_file_prog <ARGUMENT>
The argument is a single word which is the location of the stored
file as referenced from the running directory (MOBProgs).
NOTE: Dummy trigger. Not valid in any file, only for use in
loading files
from the first method described two sections above.
Syntax: act_prog [p] <ARGUMENT>
The argument is a list of keywords separated by spaces. If the
first word is the character 'p' by itself then the rest of the
word list is
considered to be a phrase. The trigger is activated whenver a
keyword (or
the phrase) is contained in the act() message. Both the phrase
and keywords
are case insensitive.
NOTE: Most general trigger. Applies to almost every event which
happens
in the mud. Anytime the function act() is called with a message
to be delivered TO_CHAR,TO_VICT,TO_ROOM,etc. the act can be
triggered. Basically this will trigger on almost everything
you'll ever want (and some things you wont as well) For example:
MOBprogram: >act_prog p pokes you in the ribs.~
This trigger will only be activated if a mobile receives a
message
in which the above five words are found in the exact order and
spacing given. Note that the period is needed because the words
must be found on their own. This eliminates confusion when the
keyword is 'hi' and a message with the word 'this' is being
checked.
Syntax: speech_prog [p] <ARGUMENT>
The argument is the same as for an act_prog.
NOTE: This is only triggered when the keyword or phrase is
contained in a
message which has been said by a PC in the same room as the mob.
The PC restriction is not necessary, but makes infinite loops
between two talking mobiles impossible. It also makes it
impossible
for two NPC's to stand and discuss the weather however.
Syntax: rand_prog <NUMBER>
The argument is a number betweeen 1 and 100 inclusive.
NOTE: This trigger is checked at each PULSE_MOBILE and if the
argument is
greater than a percentage roll the trigger is activated. This
will happen even if there is no PC in the room with the mob,
but there must be players in the same area.
It is useful to give mobiles a bit of a personality. For instance
a janitor who stops to spit tobacco, or complain about the hours,
or wonder why there are no woman janitors on muds, or a fido
which
barks or growls or pees on the curb is much more alive than one
which just sits there scavenging.
Syntax: fight_prog <NUMBER>
The argument is a percentage like in rand_prog.
NOTE: Useful for giving mobiles combat attitude. It is checked
every
PULSE_VIOLENCE when the mobile is fighting. Can be used to cast
spells, curse at the opponent, or whatever. Only the first
successful
one will be processed to save time. Also, this means that the
mobile wont get lucky and 1. curse, cast a fireball and 2. spit
on the
player, cast another fireball in the same pulse.
Syntax: hitprcnt_prog <NUMBER>
The argument is a percentage.
NOTE: Is activated at each PULSE_VIOLENCE when the mobile is
fighting. It
checks to see if the hitpoints of the mobile are below the given
percentage. Multiple hitprcnt_progs should be listed in
increasing
order of percent since a 40% will always be activated before a
20%
and, only the first successful hitprcnt trigger is performed.
Syntax: greet_prog <NUMBER>
Again a percentage argument.
NOTE: Whenever someone enters the room with the mobile, and the
mobile saw
the person enter, this is checked. Good for shopkeepers who want
to welcome customers, or for pseudo-aggressive mobiles which need
to
discriminate on who they attack.
Syntax: all_greet_prog <NUMBER>
Again a percentage argument.
NOTE: Like greet_prog, but it can be triggered even if the mobile
didnt
see the arrival (i.e. sneak, invis, etc). Most useful for faking
teleport rooms (if your mobiles can transfer) or for impassable
guardians.
**NOTE: neither greet_prog is activated if the mobile is
fighting.**
Syntax: entry_prog <NUMBER>
Again a percentage argument.
NOTE: The opposite of a greet_prog. Whenver the mobile itself
enters a new
room, this can be triggered. Useful for looking around, or waving
or other things that real PCs do when they arrive at a crowded
room.
Only the first successful one of these is done so the mobile
doesnt
look stupid by repeating commands resulting from multiple
MOBprograms.
Syntax: give_prog <ARGUMENT>
The argument is either the complete name of an object, or the
word
'all'. A complete name is like: "sword shiny magic" vs
"sword". It
is whatever is on the line of the object section following the
VNUM.
NOTE: This is triggered whenever something is given to the
mobile. Best used
for quests. Since the first successful trigger is the only one of
this type which is processed, having an "all" argument
give_prog
at the end of the MOBprogram list is essentially a default
response.
Syntax: bribe_prog <NUMBER>
The argument is any positive integer number.
NOTE: This trigger is activated whenever money is given to the
mobile. If the
amount given exceeds the number, then process the commands. Note
again, that an argument of '1' would act as a default response.
If money is given to a mobile with this trigger type, instead of
the
cash being added to mob->gold, the mobile is instead given a
pile of
coins in the proper amount. In this way, the mobile can drop the
coins
or refer to the object by "amount" (short
description:"%d gold coins")
This surely has some drawbacks, but it lets the mobile do
something
with the bribe (NOTE: dropping it and getting it turns it into
cash)
This can be done sneakily if a NPC-only "at" command
exists.
Syntax: death_prog <NUMBER>
The argument is a percent once again.
NOTE: When the mobile dies, if the random percentage is less than
the
argument
the mobile performs the MOBprogram commands rather than the usual
death_cry sequence. This is done before the corpse is made, so
the
commands can be considered the mobiles last gasp. It could
perhaps
destroy the items it was holding, or create some, or cast a spell
on the killer and the room, or even goto a new location and die
there (with a text message, the corpse would seem to vanish) The
position of the mobile is set to STANDING, and so it can do all
the
normal commands, without worrying about being DEAD. However, even
if the mobile restores itself to full hitpoints, it will still
die.
This is not a way to immortal mobiles. However, the last thing
this
mobile does could be to goto some vacant room, load a fresh
version
of itself, drop all its items, force the new mobile to get all
the
items and wear them, send the new mobile back to the character
who
killed it and force the new mobile to attack that character.
Along
with a text message which said the mobile restored itself, this
might be a convincing effect. (Note that your kitten could turn
into
a dragon this way too). Of course this assumes that some NPC
commands have been implemented.
Note that the first successful bribe_prog, give_prog,
hitprcnt_prog,
death_prog, fight_prog, rand_prog and entry_prog is the only one
which
is executed. All the successful greet(_all)_progs, speech_progs,
and
act_progs will be done. This is the best arrangement we found for
handling
situations where you imported several MOBprogram files for a
mobile. If you
are going to write lots of little files and piece them together
to create
the effect you want, it is advisible to not mix things together
all that
much, otherwise you have to pay close attention to the order in
which the
programs are added to the link list.
Also, no MOBprograms will be successful when the mobile is
charmed
(since it has no self violition, it should act like it has none)
to protect
mobiles which are given special powers from being implemented by
a player.
One bug we had in early testing was a player who charmed a mobile
and then
used its aggressive greet_prog to attack other players.
------------------------------Variables------------------------------------
To make things come alive, variables are needed. These are
represented
in the MOBprograms by using a dollar sign convention as in the
socials.
When the mud command is processed, these variables are expanded
into the
values shown below. Usually, it is best to use the short
descriptions
of mobiles and the names of players when speaking them, but if
you are
performing an action to someone almost always you want the name.
The
title field for players is an extra that probably wont often be
used.
Without further hesitation... the variables:
$i the first of the names of the mobile itself.
$I the short description of the mobile itself.
$n the name of whomever caused the trigger to happen.
$N the name and title of whomever caused the trigger to happen.
$t the name of a secondary character target (i.e A smiles at B)
$T the short description, or name and title of target (NPC vs PC)
$r the name of a random char in the room with the mobile (never
== $i)
$R the short description, or name and title of the random char
$j he,she,it based on sex of $i.
$e he,she,it based on sex of $n.
$E he,she,it based on sex of $t.
$J he,she,it based on sex of $r.
$k him,her,it based on sex of $i.
$m him,her,it based on sex of $n.
$M him,her,it based on sex of $t.
$K him,her,it based on sex of $r.
$l his,hers,its based on sex of $i.
$s his,hers,its based on sex of $n.
$S his,hers,its based on sex of $t.
$L his,hers,its based on sex of $r.
$o the first of the names of the primary object (i.e A drops B)
$O the short description of the primary object
$p the first of the names of the secondary object (i.e A puts B
in C)
$P the short description of the secondary object
$a a,an based on first character of $o
$A a,an based on first character of $p
Also, in if_checks, the accepted variables are the basic ones
(i,n,t,r,o,p). If a variable is referenced that doesnt exist,
then the value
is simply left blank. (i.e referring to $o when the trigger is: A
kisses B)
The only problem with the variables is that the secondary object
and
the secondary target are passed by act() in the same location.
This means
that
if you reference $t in an A puts B in C situation, the result
will probably
be a happy mud crash or some weird side effect, espescially if $t
is used in
an if_check (i.e. if isnpc($t) in the above situation) The basic
fix for this
is to change everyone who calls the act() procedure to specify a
secondary
object and a secondary character. But that is a fairly
comprehensive trivial
twiddle, so we left it the way it is so that, you arent forced to
make all
those twiddles to use the MOBprograms.
---------------------------Control Flow
Syntax------------------------------
In place of any legal mud command in a MOBprogram, one can
substitute a
flow of control command. Here is the syntax for a flow of control
command.
"if" " " {if_check_1} "("
{argument} ")" [ {operator} {value} ] NL
[ "or" " " {if_check_2} "("
{argument} ")" [ {operator} {value} ] NL ]
. . .
[ "or" " " {if_check_N} "("
{argument} ")" [ {operator} {value} ] NL ]
[ {program_command_1} NL ]
[ {program_command_2} NL ]
. . .
[ "break" NL ]
. . .
[ {program_command_N} NL ]
[ "else" NL ]
[ {program_command_1} NL ]
[ {program_command_2} NL ]
. . .
[ "break" NL ]
. . .
[ {program_command_N} NL ]
"endif" NL
Basically, it is: an 'if' line, followed by zero or more 'or'
lines,
followed by zero or more legal mud commands, which may contain a
'break' line,
possibly followed by an 'else' line , followed by zero or more
legal mud
commands, which may contain a 'break' line, followed by an
'endif' line.
The only new syntax labels are all in the IF line:
--Explainations
An IF_CHECK is a string which describes under what context to
compare things.
The ARGUMENT is the reference point from which the LHS of an
expression comes.
The OPERATOR indicates how the LHS and RHS are going to be
compared.
The VALUE is the RHS of the expression to be compared by the
operator.
The BREAK command bails out of the entire MOBprogram regardless
of the
level if nesting.
If that looks confusing, skip to the end of the document and
review the
Example. Hopefully that should clear things, otherwise you'll
probably have
to give us a mail since examples are the best way we know to
explain syntax.
--------------------------------Operators-----------------------------------
Most of the basic numeric operators are legal and perform the
same
function as in C. The string operators are a bit more confusing.
There are
negative versions of some of the operators. These are not
strictly needed,
since the if/else construct of Control Flow commands can handle
either case.
Numeric Operators: == != > < >= <= & | String
Operators: == != / !/
For strings, == and != check for exact match between the two
strings
and the other two, / and !/ check to see if the second string is
contained in
the first one. This is so things like: if name($n) / guard will
respond
true to "cityguard" "guard"
"guardian" etc. Using == on a name implies
that you are matching the complete name "cityguard
guard" or whatever.
The string operators are case SENSITIVE.
------------------------If_Checks In Control
Flow---------------------------
The provided list of if_checks and their arguments are below.
They
should all be fairly obvious in what they do, but some of the
more obtuse
deserve a slight explanation. Any '==' operator can be replaced
with any of
the
available ones described above. The argument ($*) refers to any
of the
variables which make sense for that if_check (i.e. for an
if_check which is
referencing a person the only valid variables would be $i, $n, $t
or $r)
A value type of string is a sequence of characters. It does not
need to be
included in quotes or anything like that (i.e. name($n)== orc
large brown)
rand (num) Is random percentage less than or equal to num
isnpc ($*) Is $* an NPC
ispc ($*) Is $* a PC
isgood ($*) Does $* have a good alignment
isfight ($*) Is $* fighting
isimmort ($*) Is the level of $* greater than max_mortal
ischarmed ($*) Is $* affected by charm
isfollow ($*) Is $* a follower with their master in the room
isaffected($*) & integer Is ($*->affected_by &
integer) true
(person only)
hitprcnt ($*) == percent Is the hit/max_hit of $* equal to
percent
inroom ($*) == integer Is the room of $* equal to integer
(person only)
sex ($*) == integer Is the sex of $* equal to integer
position ($*) == integer Is the position of $* equal to integer
level ($*) == integer Is the level of $* equal to integer
class ($*) == integer Is the class of $* equal to integer
goldamt ($*) == integer Does $* have a gold total equal to
integer
objtype ($*) == integer Is the type of $* equal to integer
(armor,boat,etc)
objval# ($*) == integer Is $*->value[#] equal to integer (#
from 0-3)
number ($*) == integer Is the vnum of $* equal to integer
name ($*) == string Is the name of $* equal to string
------------------------MOBCommands Of
Interest-----------------------------
These are fairly basic things, most of them are wiz commands
which have
been changed to allow for mobiles to perform the commands. If you
have the
problem of immortals abusing these powers on your mud either
ditch the
immortals, or add a check in all of them to only let NPC's with
null
descriptors do the commands. (However, you lose a little
debugging help that
way). MERC 2.2 has provided a little security feature against
this but
it is by no means comprehensive. Please check yourself if you are
concerned.
Here are the basic MOBcommands that we found to be enticing:
Syntax: MPSTAT <mobile>
Shows the MOBprograms which are set on the mob of the given name
or
vnum and some basic stats for the mobile
Syntax: MPASOUND <text_string>
Prints the text string to the rooms around the mobile in the same
manner as a death cry. This is really useful for powerful
aggressives
and is also nice for wandering minstrels or mobiles like that in
concept.
Syntax: MPJUNK <object>
Destroys the object refered to in the mobiles inven. It prints no
message to the world and you can do things like junk all.bread or
junk all. This is nice for having janitor mobiles clean out their
inventory if they are carrying too much (have a MOBprogram
trigger on
the 'full inventory')
Syntax: MPECHO <text_string>
MPECHOAT <victim> <text_string>
MPECHOAROUND <victim> <text_string>
Prints the text message to the room of the mobile. The three
options
let you tailor the message to goto victims or to do things sneaky
like having a merchant do: mpat guard mpechoat guard
rescue_please
This coupled with a guard act_prog trigger on rescue_please to
mpgoto $n and mpecho $I has arrived. It is an affective way of
quickly
bringing guards to the scene of an attack.
Syntax: MPMLOAD <vnum>
MPOLOAD <vnum> <level>
Loads the obj/mobile into the inven/room of the mobile. Even if
the
item is non-takable, the mobile will receive it in the inventory.
This lets a mobile distribute a quest item or load a key or
something.
Syntax: MPKILL <victim>
Lets a mobile kill a player without having to murder and be fifth
level. Lots of MOBprograms end up with mpkill $n commands
floating
around. It works on both mobiles and players.
Syntax: MPPURGE [argument]
Destroys the argument from the room of the mobile. Without an
argument
the result is the cleansing of all NPC's and items from the room
with
the exception of the mobile itself. However, mppurge $i will
indeed
purge the mobile, but it MUST be the last command the mobile
tries to
do, otherwise the mud cant reference the acting mobile trying to
do the
commands and bad things happen.
Syntax: MPGOTO <dest>
Moves the mobile to the room or mobile or object requested. It
makes
no message of its departure or of its entrance, so these must be
supplied with mpecho commands if they are desired.
Syntax: MPAT <dest> <command>
Perfoms the command at the designated location. Very useful for
doing
magic slight of hand tricks that leave players dumbfounded.. such
as
metamorphing mobiles, or guard summoning, or corpse vanishing.
Syntax: MPTRANSFER <victim> [dest]
Sends the victim to the destination or to the room of the mobile
as a
default. if the victim is "all" then all the characters
in the room
of the mobile are transfered to the destination. Good for
starting
quests or things like that. There is no message given to the
player
that it has been transfered and the player doesnt do a look at
the
new room unless the mob forces them to. Immortals cannot be
tranfered.
Syntax: MPFORCE <victim> <command>
Forces the victim to do the designated command. The victim is not
told
that they are forced, they just do the command so usually some
mpecho
message is nice. You can force players to remove belongings and
give
them to you, etc. The player sees the normal command messages
(such as
removing the item and giving it away in the above example) Again,
if
the victim is "all" then everyone in the mobiles room
does the command.
This cannot be used on immortals.
--------------------------Regarding CPU
Slowdown-------------------------------
We have no real idea how slow this makes a mud. However, you will
find
that if you are judicious with your use of MOBprograms, you can
either do
little damage, or even reduce the effort on your server! This
means that
mobile polling (including the rand_progs) need only be checked
when players
are around. This reduces computation of random_stuff a little,
but it is
still a polling method, and subject to a basic inefficiency
there. However,
aside from the rand_progs, the only additional slowdowns will be
when the
mobile is responding to the situation, and you would get that
from a special
procedure as well (although MOBprograms are surely not as
efficient as
compiled C code)
For those who are afraid that MOBprograms will drown their CPU,
here is a
brazen suggestion which could put you a bit more at ease. Instead
of having
aggressive mobiles, try the following MOBprogram block on all
would be
aggressives.
>greet_prog 100~
if ispc($n)
if isimmort($n)
bow $n
else
mkill $n
endif
endif
~
This has the effect of making the mobile attack the FIRST visable
mortal player who walks into the room. [Merc 2.0 has a random
char be the
victim, so we allow our fighting mobiles a high chance to switch
their target
to any random player in the opposing group at each
pulse_violence.]
What this has allowed us to do, is to comment out the aggr_update
section of the code and thus reduce our computation by a bunch.
There is no
continuous polling through all the mobiles in occupied zones and
checking to
see if there is an NPC aggressor and a PC victim. We also dont
have to worry
about players skipping through aggressives, since the trigger
catches folk as
soon as they enter the room.
Note that the price we paid for this, was that if a second player
walked in during the combat, and the first character flees, the
mobile didnt
realize that there is a new target. So, we compromised by adding
a rand_prog
which had the mobile appear to peer around the room and then do
an mkill $r.
AHA! you say, we are back to polling. Well true, but since
mobile_update
is called anyway (at 1/16 the frequency of aggr_update in default
Merc 2.0)
and we only add an if check, a walk of a short link_list and the
MOBprogram
execution itself, we have still reduced the aggr_update stuff by
major
amounts.
Of course the act_prog updates are currently done in the
aggr_update
section but if you decrease the mobile_update time a bit, and
move the
act_progs over to there, the result is act_progs which have a
brief delay
(like a PC who has to type things over a modem does)
-------------------------Miscellaneous
Information-----------------------------
There is really no limit to the number of MOBprograms a given
mobile
can have. However, the length of a single command block is
limited by the
value of MAX_STRING_LENGTH. In my version it was around 4k, so
that is
probably about 100 lines. The indentation spaces shown in the
example
above are NOT required, but do make it easier to read (and debug)
The MOBprogram stuff runs totally without anything in the
mob_commands.c file, but letting mobiles be a bit more godlike
has allowed
us to do what we consider to be wonderful things. The replicant
and
polymorphing mobiles described above as well as some nifty mob
helping mob
interactions are an example.
It IS possible to accidentally make mobiles which can trigger in
loops. As mentioned in the example at the end of this document,
the result is
usually a mud crash or major CPU dent. We dont know any way to
prevent this
from happening, other than careful coding and a restriction of
mobile travel
from zones of one creator to another (another good reason to not
have charmed
mobiles do anything). Tracking down the culprit mobile is not
always easy.
The only thing we have found which always works, is to add a log
statement
into the MOBprogram driver and fill some disk space until it
becomes apparent
what commands are repetitively issued. Also, most infinite loops
are flukes
where the situation just happens to be right and usually it never
happens
again.
The list of variables and triggers and if_checks will grow
continuously as our creators demand the ability to do certain
things. If you
have a request or if you have a new one, we don't mind hearing
about them,
and if you find bugs, we shall gladly attempt to squash them for
you. As
additions or fixes are made, the code will occasionally be
redistributed.
However, if you want a current version, please feel free to ask.
When the
code is redistributed, a file containing the change history from
the original
release will be provided (when possible) to allow you to patch in
the changes
with low grief.
The code has been written for a Merc 2.0 release mud. We were
considering trying to port it back to 1.0, but this really had no
gain for us.
Also, much of the internal mud structure has changed and makes
this almost a
hopeless task. We will be glad to lend advice to someone who is
trying to
install this for 1.0 and if something develops we will be glad to
make that
public as well.
----------------------------------Credits-----------------------------------
The reason this code was written was to enhance the playing
experience at ThePrincedom (a Merc 2.0 based world scheduled to
open in
October 1993)
The original idea for this type of MOBprogram came from playing
on:
WORLDS of CARNAGE, a dikumud implemented by Robbie Roberts and
Aaron Buhr.
Aaron (known as Dimwit Flathead the First) was the original
author from what
I have been told, and I hope he will not be totally offended and
angered
by my coding and sharing a mimicked version with the world. This
version
is probably not as good as the original and I do feel remorse for
publishing
the idea. However, since Carnage has been down for months without
a word of
information regarding its return, I am glad to let one of the
best features
live on in future generations of MUDs.
There are no objections to this code being shared, since, aside
from
a nuclear destruction of all the Temples of Midgaard (excepting
the original
one!!), bland mobiles are the greatest bane of Dikumuds today. It
would be
nice to get a message saying you are using the code just for our
references.
We shant answer questions from anyone until told where they are
using the
code. *grin* Since this code is not copyrighted, you of course
dont have to
do anything we say, but it would be nice of you to put the
mobprog help
screen into your database. and have mobinfo show up somewhere on
a more
visable help screen (possibly tagged onto the bottom of credits
as a see
also...)
I acknowledge all the work done by the original Diku authors as
well as
those at Merc Industries and appreciate their willingness to
share code.
Also, quick thanks to Wraith for doing a little beta-installation
testing.
N'Atas-Ha June, 1993
murph@ri.cmu.edu
In addition to this DOC file credit section, I'd like to add
a thank you to Yaz, Mahatma, Zelda, and the rest of the Marble
Mud crew for
extensively testing MOBProgram 2.1 for me. You may see
MOBPrograms in
action as well as their own "flavor" of mud at
marble.bu.edu 4000.
Kahn Oct 28th, 1993
MERC Industries
{+}+{+}+{+}+{+}+{+}+{+}+{+}+{+}+{+}+{+}+{+}+{+}+{+}+{+}+{+}+{+}+{+}+{+}+{+}+
{+}
===================CUT HERE FOR QUICK REFERENCE
SHEET========================
MOBprogram quick reference to
triggers/variables/ifchecks/mobcommands
trigger argument and what must happen to activate trigger
-----------------------------------------------------------------------------
act_prog WORDLIST or P WORD_PHRASE to match from act() to mobile
bribe_prog INTEGER amount of miminum gold amount given to mobile
entry_prog PERCENT chance to check when mobile moves to a new
room
give_prog FULL OBJECT NAME or ALL to match when obj given to
mobile
greet_prog PERCENT chance to check if visable char enters
mobile's room
all_greet_prog PERCENT chance to check when any char enters
mobile's room
fight_prog PERCENT chance to check at fight_pulse if mobile is
fighting
hitprcnt_prog PERCENT lower than mobiles hit/max_hit if mobile is
fighting
death_prog PERCENT chance to check after mobile has been slain
rand_prog PERCENT chance to check whenever a PC is in the mobiles
zone
speech_prog WORDLIST or P WORD_PHRASE to match in dialogue to
mobile
variable mobile actor victim random object 2nd_object
-----------------------------------------------------------------------------
name $i $n $t $r $o $p
shrt_desc/title $I $N $T $R $O $P
he/she/it $j $e $E $J -- -- '$'symbol=$$
him/her/it $l $m $M $L -- --
his/hers/its $k $s $S $K -- --
a/an -- -- -- -- $a $A
ifcheck argument? meaning
-----------------------------------------------------------------------------
rand(num) Is a random percentage less than or equal to num
isnpc($*) Is $* an NPC
ispc($*) Is $* a PC
isgood($*) Does $* have a good alignment
isfight($*) Is $* fighting
isimmort($*) Is the level of $* greater than max_mortal
ischarmed($*) Is $* affected by charm
isfollow($*) Is $* a follower with their master in the room
isaffected($*) & integer Is ($*->affected_by &
integer) true (person only)
hitprcnt($*) == percent Is the hit/max_hit of $* equal to percent
inroom($*) == integer Is the room of $* equal to integer (person
only)
sex($*) == integer Is the sex of $* equal to integer
position($*) == integer Is the position of $* equal to integer
level($*) == integer Is the level of $* equal to integer
class($*) == integer Is the class of $* equal to integer
goldamt($*) == integer Does $* have a gold total equal to integer
objtype($*) == integer Is the type of $* equal to integer
(armor,boat,etc)
objval#($*) == integer Is $*->value[#] equal to integer (#
from 0-3)
number($*) == integer Is the vnum of $* equal to integer
name($*) == string Is the name of $* equal to string
MOBcommand argument_list MOBcommand argument_list
-----------------------------------------------------------------------------
MPSTAT <mobile> MPASOUND <text_string>
MPJUNK <object> MPECHO <text_string>
MPMLOAD <mobile> MPECHOAT <victim>
<text_string>
MPOLOAD <object> <level> MPECHOAROUND <victim>
<text_string>
MPKILL <victim> MPPURGE [argument]
MPGOTO <dest> MPAT <dest> <command>
MPTRANSFER <dest> [location] MPFORCE <victim>
<command>
======================END OF QUICK REFERENCE
SHEET===========================
++++++++++++++++++++++++++++++++EXAMPLE++++++++++++++++++++++++++++++++++++++
Referenced from above in the Control Flow section
>act_prog p pokes you in the~
if isnpc($n)
chuckle
poke $n
else
if level($n) <= 5
or isgood($n)
tell $n I would rather you didnt poke me.
else
if level($n)>15
scream
say Ya know $n. I hate being poked!!!
kill $n
break
endif
slap $n
shout MOMMY!!! $N is poking me.
endif
endif
~
Ok.. time to translate.. the trigger will only happen when the
mobile
gets the message "... pokes you in the ..." If the
offender (recall
the $n and $N refer to the char who did the poking...) is an NPC,
then
the mobile merely chuckles and pokes back. If the offender was a
PC
then good and low level characters get a warning, high level
chars
get attacked, and midlevel chars get slapped and whined at.
Note that two of these mobiles could easily get into an infinite
poke
war which slows down (or frequently crashes) the mud just a bit
:(
Be very careful about things like that if you can. (i.e dont
respond
to a poke with a poke, and try not to let heavily programmed
robot mobiles
wander around together. More on that is given above.)
Also, it is clear that the 'order' command could get confused
with the 'or'
control flow. However, this is only the case when 'order' is
abbreviated to
its two letter form, and placed immediately following an 'if'
line. Thus,
if you want to be that malicious in trying to break the
MOBprogram code,
noone is going to stand in your way (However, the result of this
would be
a bug message and a bail out from the ifcheck so things dont
really break)
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
CAUTION! Be very careful and thorough when doing the mob_progs,
because
they easily backfire and in the worst cases crash the mud,
sometimes even
keeping it from rebooting!! Avoid working with them when there
are many
other builders logged on. Avoid experimenting with them too, if
you are not
a very experienced builder.
(There are certain things you can't do, with the mob_progs,
because they
will crash the mud. I've listed the ones we found out so far
below, but
there might be a lot more. If you follow the directions beneath
exactly,
you should be OK though.)
PROGRAM TYPES
There are several types of different programs, but they all work
basically
the same, the difference being the trigger, that sets the program
off.
There are also programs that works for mobiles (mob_progs), for
rooms
(room_progs) and for objects (obj_progs). You'll find a list of
different
prog types and commands at the end of the manual.
It's usually easiest to understand a principle by giving an
example, so
below are some examples of how to do different mob_progs:
1 TALKING MOBILES (speech_prog)
Create the mobile you want to have the mob_prog.
type mpedit create vnum
type speech_prog
type trigger p >phrase< (The phrase can be several words)
type pro or just p
This last command gets you into verbose mode.
The first thing you must do in verbose is to clear the desc, by
typing .c
(There is the word "break" in the pro by default, and
that has to be
removed or the programs don't work).
Then
Type the action desired, use one line for each action.
Use $n to enter the players name
To exit verbose mode, type @ as usual
Then type done
(You can edit like any other desc, when you are in verbose, just
don't
format the string, and don't make any action longer than one
line!)
Example:
(The trigger can be any phrase, that is said by a player, for
instance
"hello"
say Hi, $n.
say I don't like your face, $n!
grin $n
zap $n
To add another mob_prog while still in mpedit:
type add
This gets you into 2nd mob_prog
Then procede as before.
Type done to exit mpedit
To check a mob_prog while in mpedit just hit return, it shows you
what's
in it so far.
You can add as many mob_progs you want to the same mob, for
instance if
you want it to carry out a lengthy conversation. Try to put some
keywords
into the mob's cues to make it easier to trigger off the second
step, but
be careful not to use the keywords in the lines the mob is
saying, or he
will trigger off himself, and this creates a loop that will crash
the Mud!
(For instance if the trigger is yes or no, make the mob say:
yes?/no?)
You can also make the mob do a lot of other things than just talk
with a
speech_prog, more of that below.
To edit an existing mob_prog while out of mpedit:
just type mpedit vnum num (the last number being the number of
the
mobprogram). Then procede as before.
To add a second or third program while out of mpedit:
type mpedit create vnum 2 , mpedit create vnum 3 etc. Then
procede as
before. Or just type mpedit vnum and the add, once you are in
mpedit.
If you want to get rid of a bad mob_prog, just type mpedit vnum
and then
delete, when in editor.
Comments:
You can make a mob use socials in speech_prog, and also use emote
+ action.
You can also make it do things, like giving you an item (see also
give_prog, below)
Some of the commands are different in Mobprogs though, see below
under
COMMANDS.
The speech_prog is triggered, as soon as someone in the room says
a phrase
with the trigger in it. You can use a full sentence as a trigger
too, but
it's often a better idea using a single word, because the program
is
sensitive, and only reacts to the EXACT wording in the trigger.
If the trigger is a single word or a short phrase, it will set
the mob off
every time that word or phrase is uttered in the room, even if it
is
contained in a longer phrase. This can be used to make it react
to multiple
phrases.
For instance the trigger:
trigger p a beer
will set the mob off if someone says "I'd like a beer"
or "Give me a beer
please" etc. However it won't react to "Give me a beer,
please" because of
the comma.
2 RAND_PROG
This makes the mob say and do things randomly. The percentage in
the
trigger decides how often he does it. If you want the action to
occur all
the time, use percentage 100. Below is an example of a rand_prog
for my
puppy:
Rand_prog Trigger 10
typ pro (sends you into verbose mode)
.c (to clear the string)
emote wags her tail
tackle $n
@
You have to test this type of program, to get the trigger at a
suitable
level, or it can get too spammy. Trigger 7-10 is usually OK.
A good example of a built-in rand_prog is the Mob spec
spec_drunk.
3 GREET_PROGRAM
Type mpedit create vnum
Type greet_prog
Type trigger 100
Type pro (to get into verbose)
Type .c to clear the string
Type whatever you want the mob to say or do (1 line per action as
usual)
Type @ to exit verbose
This program will start the mob saying or doing things as soon as
someone
enters the room. It is the easiest program to make, and it
usually doesn't
cause any crashes.
Note
It's usually a better idea to use tell than say in the prog, or
it can
get awully spammy when a group enters the room.
You can have more than one greeter in each room. They will
trigger off in
the opposite order that they were reset. You can also trigger the
second
mob by using a word in the first mob's phrase as a trigger word
for the
second. (Be sure you don't make the first mob use tell instead of
say then,
because only the person adressed hears a tell).
4 MAKE A MOB GIVE AND RECIEVE ITEMS
Type mpedit create vnum
Type give_prog
Type trigger (item name)
(This is the item you give the mob)
Type pro (to get into verbose)
Type .c to clear the string
Type mpoload vnum number(number being the level the item is
loaded at)
Type give item $n
Type whatever you want the mob to say or do
pe @ to exit verbose
Note:
The mob will give the item as long as it is in his inventory.
This is why
it is better to have the mpoload command in the mob_prog, than
just
resetting the item on the mob. In the last case a second player
arriving
at the scene soon after the first will find an empty mob.
The mob should have a very high level, so that you can't get the
item by
simply killing him. Might be a good idea to sanc him too!
In some codes the mob needs to be at least level 54 too, to use
the
mpoload or mpmload command, you have to modify the code so that
"Imm
commands" can be used by lower level Mobs too.(See SPECIAL
MOB_PROG
COMMANDS below!)
This program should be useful for built in quests,where the mob
asks you
to bring him an item, and receive a reward for it. The item he
gives
should be really good, to make it worth the effort.
Mark: It's really important that the item you want the mob to
give/recieve
has exactly the same name (full object name)that you type into
the prog
as >give item $n<. And i mean really wordproof: You can't
for instance
name the item "Short dagger" and then type >give
dagger $n<. Even names
like "A dagger" is enough to stop the mob from giving
it.
We once spent a whole evening trying to figure out what was wrong
with a
mob_prog, and then I found, that the only problem was the item
name.
(Another detail was, that I had made the weapon nodrop, but I'm
sure you
are to smart to do silly mistakes like that, hehe!).
5 ENTER_PROG
This is a room_prog, that works exactly the same as a greet_prog,
and
it triggers off by the person entering the room. (One important
thing
about room_progs though: You have to be in the room when you
create them
and type done before you leave the room, or the Mud will crash!)
6 MAKE A MOB FOLLOW ANOTHER MOB ("Mob-groups")
type mpedit create vnum
type rand_prog
type trigger 100
type pro
The last command sends you into verbose
type .c to clear the string
type mpfollow (name of leader)
type @ to exit verbose mode
type done
Note
1. Decide which mob you want to be the leader. The level of the
mob is not
important, the only condition is that he must be mobile.
2. Make all the following mob sentinel or they will wander off on
their own
3. Go into redit
4. Load the leading mob first - (otherwise it won't work) - and
order him
to rest.
5. all the mobs in the group must follow the same leader
6. type done after the reset is finished
Comment
Let the long descs on the mob decide which one should be the
leader. Like
always, the one you load first is the one that will show at the
bottom in
the room.
This have a tendency to get messed up at reboot, so don't try to
make too
big groups. If the leader starts walking away before the others
are loaded,
it obviously doesn't work.
7 FIGHT_PROG
This is used to make the mob say and do things during a fight to
make it a
bit livelier. Basically it's a Rand_prog, where the percentage
you give the
trigger decides how often the action occurs. However the action
is only
triggered when the mob is fighting. Below is an example of what a
fight_prog
might look like.
Fight_prog
Trigger 20
pro
.c
shout Help! $n is hurting me!
shout Guards! Come to my rescue!!!
@
You can also make the mob use a wand or a staff, by equipping him
with the
item and then putting "zap $n" or "brandish
staff" into the prog. A mob can
be made to trans a player too, thus making it impossible to flee.
And you
can make the mob actually summon the guards to the room by using
the
command <mptransfer mobname vnum>.
8 BRIBE_PROG
This can be used to make a Mob give the player for instance a
key, or some
directions for money. The trigger is the amount of gold it takes
to set off
the action. It's usually a good idea to start this type of
program with a
simple greet_prog, where the Mob informs the player that he is
"open to
suggestions" by saying for instance:
"Want to know the way to the Tower?
Money has a way of loosening my tongue!"
Like for instance 5000 gold
"
Bribe_prog Trigger 5000
tell $n From this room go 1s, 4e, 5n.
Tell $n A pleasure doing business with you $n
grin $n
@
9 MAKE A MOB SWITCH INTO ANOTHER MOB AND/OR DISAPPEAR
1.Create a room without exits within the area, only meant to be
used for
this purpose.
2.When in pro type:
mpmload Vnum (Vnum being the number of the mob you want it
switched into)
mpecho The Wizard has changed into a fearsome dragon!
mpgoto Vnum (Vnum being the no-entrance room you created)
mppurge
mppurge $i
This makes the wizard magically disappear, while the dragon
remains in the
room he left.
The mpecho isn't absolutely necessary of course, but it gives the
player
information of what has happened.
Obviously the command mpgoto and mppurge $i must be the last the
mob
makes. (He should always end the program by purging himself, or
the
repops will not work as they should. The very last command will
be
mpurge $i ($i being the name of the mob itself)).
Be a bit careful when using this, especially if the mob you load
is high
level and aggro. Should the player not succeed in killing the
mob, it will
stay in the game till next reboot, thus creating a hazard to
lower level
players.
10 TELEPORTING MOBS
You can make a mob teleport randomly around the game port, by
equipping
him with a staff that's got the teleport command, and then
putting the
command "brandish staff" into a rand_prog.
Be a bit careful doing this though, at least don't make the mob
high level
and aggro, or he will be a threat to low level players. Also
don't give
him any speech_progs, because he might set other mob_progs off
accidently,
thus in the worst case causing the mud to crash.
11 MAKE A MOB TRANSFER A PLAYER TO ANOTHER ROOM
This program can be set off by the player entering the room
(greet_prog or
enter_prog) or by a phrase said by the player (speech_prog).
mpechoat $n <message>
mpechoaround $n <message>
mptransfer $n vnum
The essential command in this prog is the mptranfer $n of course.
The mpechoat and mpechoaround commands give information to the
players
of what has happened. For instance a typical message could be:
The player that triggered the program sees:
"You are surrounded by a swirling mist.
Suddenly you find yourself in a different time and a different
place".
Other player in the room see:
"$n is surrounded by a swirling mist and vanishes".
(These are the lines used by the timewarp mob and in some of the
time-traps
in 4D. There should be lots of variations to them though).
SPECIAL MOB_PROG COMMANDS
You can use almost any of the usual commands, for the actions in
the
mob_progs. However there are some commands that are special, or
doesn't
work at all. These are mostly the Imm commands, which you need to
be
level 51 or higher to use. However some of the mortal commands
are a bit
special too. What you do is mostly to put mp in front of the
usual command.
Below is a list of some commands you can use:
$n= name of the player that set off the program
$i= name of the mob, being triggered off
kill= mpkill
goto= mpgoto
oload= mpoload
mload= mpmload
transfer= mptransfer
at $n= mpat $n
recho= mpecho (sends a message to all in the room with the mobile
using it)
mpechoat $n(sends a message only to the player that triggered off
the
program)
mpechoaround $n(sends a message to all players in the room except
the
one the triggered the program)
echo Doesn't work as a mobprog, you can only recho in the room
where
the mobile is.
mpasound text-string Prints the text string to the rooms around
the mobile
in the same manner as a death cry. This is really useful for
powerful
aggressives and is also nice for wandering minstrels.
emote Can be used the same way as the usual command.
Socials Can be used the normal way as actions inside a mob_prog.
However you can't trigger off a program with a social like
"Kiss Mob-name" = "$n kisses you". The reason
for this is that
most socials have a built-in rand_prog, that makes the Mob react
to them in a certain way.(You kiss a mob, and he either kisses
you back or slaps you, for instance.)
Comment: In stock Mythran the Imm commands can only be used by
mobiles
being level 54+. To make it possible for low level mobs to use
the Imm
commands too, you will have to change the code.
"SENSITIVE" MOB_PROGS
You can make the mob do different things depending on the stats
of the
char setting it off. For instance it can react to:
Sex (0=neutral, 1=male, 2=female)
Immortal or mortal
PC or Mob
You can make it react to things like Align, Race, Class, Level
etc too.
A list of the if-checks is at the end of the manual. What you do
is to
put in an "if-command" in the prog.
Below is an example of what a sex- and PC-sensitive Greet_program
would
look like.
Greet_prog
trigger 100
if ispc($n)
if sex($n) == 2
tell $n Greetings, My Lady!
else
tell $n Greetings, Sir!
endif
endif
Comment: Actually it is a good idea to make a rule of always
putting the
restriction <if ispc($n)> into all greet_progs, so that
they don't get
triggered off by mobs walking into the room. It is also usually a
good
idea to use <tell $n> instead of say in the greet_progs, or
they can get
awfully spammy, when a group enters the room.
BAD MOB_PROGS AND CRASHES:
There are a lot of things that can cause a mob_prog to crash the
Mud, or
just not to function. Some of the most common causes are listed
below:
· The trigger phrase is used in one of the phrases the Mob says
itself. This creates a loop that crashes the Mud.
· The Mob isn't high level enough to use commands like mpecho,
mpgoto etc. (in not modified code)
· The item the mob is supposed to give is badly named. It can be
a
typo in the object name, or just that the name is different from
what you
type in "give item $n"
· There is a small typo somewhere in the program, that you don't
even notice when checking it, like a blank in the wrong place for
instance.
· The item the Mob is supposed to give is nodrop
· You forgot to type trigger p >phrase< (not just trigger
>phrase<)
in a speech_prog or an act_prog.
· You used tell instead of say in a phrase that was supposed to
trigger off the speech_prog of a second mob
· You forgot to put in the endif line in a
"restrictive" program.
· It's night, so the mobile can't see you because it's dark in
the
room. (You can avoid this by flagging the room indoors)
· You are invisible, so the mobile can't detect you
· NEVER leave an unfinished mob_prog (infile_prog or empty prog)
behind you. This will keep the Mud from rebooting next time it
crashes.
· Act_progs usually don't work very good for some reason.
If a mob_prog gets screwed up for some reason, it's often a good
idea to
delete it completely and start from scratch.
It's also a good idea to test a mob_prog before you save it. If
it
crashes, the program itself will be deleted, but at least the Mud
will
be able to reboot itself. A bad mob_prog that is saved, can
prevent the
Mud from rebooting, thus also preventing you and other builders
from
entering the port until an Imp fixes it.
There may be a lot more traps, but these are the ones I found out
so far.
SOME COMMENTS AND PIECES OF ADVICE
Always save your work before you start making a mobprog, in case
it
crashes the mud.
Always warn the other players before you test a new program, so
they can
save their work before you evt. crash the mud. If you are the
least
unsure, preferably do the test when an Imp is on, who can restart
the
port, if the worst should happen.
NEVER leave an unfinished mob_prog when you log out, it not only
crashes
the mud, it keeps it from rebooting itself.
NEVER use the trigger word to any of the mob_progs in the line
the mob
is saying, or he'll trigger himself off incessantly till it
crashes the Mud.
Don't put the trigger phrase in " " or ' ', or the mob
will only respond
if the player does the same, which isn't very likely.
You can't make the mob attack a PC by using the command >kill
$n< in
a mob_prog. Instead you must use the special mobprog command
>mpkill
$n<. Or equip the mob with a wand, and use >zap $n<.
A mob can only fight one pc or npc at a time. If you put in a
mpkill
command on a mob that is already fighting, it creates a bug that
might
crash the Mud.
Watch out for spam! It's a good idea to make a rule of always
putting
the restriction <if ispc($n)> into all greet_progs, so that
they don't
get triggered off by mobs walking into the room. It is also good
to use
"tell $n" instead of "say" in the
greet_progs, or they can get awfully
spammy, when a group enters the room.
Be careful what words you use as triggers. If they are too
common, like
yes or no, the program might trigger off unintentionally, if a
couple of
players start a conversation in the same room as the mob. On the
other
hand, if the trigger is too far fetched, the program won't start
at all,
making all the work you put into it useless.
The way to get around this, is to give some hints how to start
the
programs on a sign in the room or in the entrance to the area.
That way,
the careful player, that takes his time reading signs, will be
rewarded,
whereas the "power player", who just rushes through the
area to get exp,
might miss valuable information given in the tells of the
mobiles.
MOB_prog quick REFERENCE SHEET
trigger argument and what must happen to activate trigger
-----------------------------------------------------------------------------
act_prog WORDLIST or P WORD_PHRASE to match from act() to mobile
bribe_prog INTEGER amount of minimum gold amount given to mobile
entry_prog PERCENT chance to check when mobile moves to a new
room
give_prog FULL OBJECT NAME or ALL to match when obj given to
mobile
greet_prog PERCENT chance to check if visible char enters
mobile's room
hour_prog PERCENT chance to set off every hour.
all_greet_prog PERCENT chance to check when any char enters
mobile's room
fight_prog PERCENT chance to check at fight_pulse if mobile is
fighting
hitprcnt_prog PERCENT lower than mobiles hit/max_hit if mobile is
fighting
death_prog PERCENT chance to check after mobile has been slain
rand_prog PERCENT chance to check whenever a PC is in the mobiles
zone
rest_prog somebody resting in room
sleep_prog somebody sleeping in room
speech_prog WORDLIST or P WORD_PHRASE to match in dialogue to
mobile
time_prog NUMBER (trigger 3 will set the program off at three am)
variable mobile actor victim random object 2nd_object
-----------------------------------------------------------------------------
name $i $n $t $r $o $p
shrt_desc/title $I $N $T $R $O $P
he/she/it $j $e $E $J -- -- $'symbol=$$
him/her/it $l $m $M $L -- --
his/hers/its $k $s $S $K -- --
a/an -- -- -- -- $a $A
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 f_check (i.e. for an
if_check
which is referencing a person the only valid variables would be
$i, $n,
$t or $r). A value type of string is a sequence of characters. It
does
not need to be included in quotes or anything like that (i.e.
name($n)==
orc large brown)
ifcheck argument? meaning
-----------------------------------------------------------------------------
rand(num) Is a random percentage less than or equal to num
isnpc($*) Is $* an NPC
ispc($*) Is $* a PC
isgood($*) Does $* have a good alignment
isfight($*) Is $* fighting
isimmort($*) Is the level of $* greater than max_mortal
ischarmed($*) Is $* affected by charm
isfollow($*) Is $* a follower with their master in the room
isaffected($*) & integer Is ($*->affected_by &
integer) true (person only)
hitprcnt($*) == percent Is the hit/max_hit of $* equal to percent
inroom($*) == integer Is the room of $* equal to integer (person
only)
sex($*) == integer Is the sex of $* equal to integer
position($*) == integer Is the position of $* equal to integer
level($*) == integer Is the level of $* equal to integer
class($*) == integer Is the class of $* equal to integer
goldamt($*) == integer Does $* have a gold total equal to integer
objtype($*) == integer Is the type of $* equal to integer
(armor,boat,etc)
objval#($*) == integer Is $*->value[#] equal to integer (#
from 0-3)
number($*) == integer Is the vnum of $* equal to integer
name($*) == string Is the name of $* equal to string
MOBcommand argument_list MOBcommand argument_list
-----------------------------------------------------------------------------
MPSTAT <mobile> MPASOUND <text_string>
MPJUNK <object> MPECHO <text_string>
MPMLOAD <mobile> MPECHOAT <victim>
<text_string>
MPOLOAD <object> <level> MPECHOAROUND<victim>
<text_string>
MPKILL <victim> MPPURGE [argument]
MPGOTO <dest> MPAT <dest> <command>
MPTRANSFER <dest> [location] MPFORCE <victim>
<command>
Help files on line
rpstat/opstat/mpstat
rpedit/opedit/mpedit
rptriggers/optriggers/mptriggers
mpcommands
Some examples of mob_progs with multiple if-checks
It's always easiest to show a principle by examples, so below are
a couple
of examples of mob_progs with multiple if-checks:
>give_prog Bronze-token~
if ispc($n)
if level($n) => 30
if sex($n) == 2
tell $n Thank you, M'Lady! :-)
tell $n Now say "Hire guard <align>", please.
tell $n The align option being good, evil or neutral.
else
tell $n Thank you, Sir! :-)
tell $s Now say "Hire guard <align>", please.
tell $n The align option being good, evil or neutral.
endif
else
tell $n Sorry mate, you are too low level for this!
endif
endif
This prog will make the mob - if given a bronze token - check the
sex and
level of the giver and act accordingly.
>greet_prog 100~
if ispc($n)
if level($n) > 39
if isgood($n)
tell $n Welcome to Camelot Castle, $n! :-)
unlock door
open door
smile $n
mpechoat $n The Guard escorts you to the Entrance Hall.
mpechoaround $n The Guard escorts $n to the Entrance Hall.
mptrans $n 15020
close door
lock door
else
tell $n Evil is not wanted in the Castle of Camelot!
tell $n You must better your alignment if you want to enter!
frown $n
endif
else
tell $n Sorry kid, you are too young to get in here!
tell $n Run along and play!:P
mpechoat $n The guard pats you patronisingly on your head.
mpechoaround $n The guard pats $n on the head.
endif
endif
This greet_prog will check if the person that enters the room is
pc or npc
(that is a check you should always put ot greet_progs, to avoid
spamming).
The mobile then checks the align and level of the pc, and does
different
things, depending on those if-checks.
>act_prog p squeezes your~
if name($n) == Kalten
say Hey Babe, I've missed you.
else
mpechoat $n A gorgous babe slaps you across the face.
mpechoaround $n A gorgous babe slaps $n across $S face.
Endif
This prog is triggered by the social "goose $n" which
in the other end
comes out as "$n squeezes your tush". It then checks
the name of the
"perpetrator" and acts accordingly.
I aim to complete this manual later, when I have learnt some
more, so
anything you find out, I'd be grateful if you'd mail me. I'm
still a
beginner at mob_progs.
Have fun, and try not to crash the mud too often!
1998-01-22
Molly
I owe special thanks to:
Nimbus, who taught me to how to make my first speech_progs and
mob groups.
Kalten and Shorty, who helped me check the programs, and guided
me past the
traps and pitfalls along the way.
Eldoran, who developed what I had started, and taught me a lot in
the process.
All the builders in 4D, who with unending patience tolerated the
crashes
I caused while experimenting, and didn't once reproach me for
causing them
to lose work.