lima-1.0b5/
lima-1.0b5/driver/
lima-1.0b5/driver/ChangeLog.old/
lima-1.0b5/driver/Win32/
lima-1.0b5/driver/compat/
lima-1.0b5/driver/include/
lima-1.0b5/driver/testsuite/
lima-1.0b5/driver/testsuite/clone/
lima-1.0b5/driver/testsuite/command/
lima-1.0b5/driver/testsuite/data/
lima-1.0b5/driver/testsuite/etc/
lima-1.0b5/driver/testsuite/include/
lima-1.0b5/driver/testsuite/inherit/
lima-1.0b5/driver/testsuite/inherit/master/
lima-1.0b5/driver/testsuite/log/
lima-1.0b5/driver/testsuite/single/
lima-1.0b5/driver/testsuite/single/tests/compiler/
lima-1.0b5/driver/testsuite/single/tests/efuns/
lima-1.0b5/driver/testsuite/single/tests/operators/
lima-1.0b5/driver/testsuite/u/
lima-1.0b5/driver/tmp/
lima-1.0b5/etc/
lima-1.0b5/lib/WWW/help/
lima-1.0b5/lib/cmds/
lima-1.0b5/lib/cmds/create/
lima-1.0b5/lib/cmds/player/attic/
lima-1.0b5/lib/contrib/bboard/
lima-1.0b5/lib/contrib/boards/
lima-1.0b5/lib/contrib/marriage/
lima-1.0b5/lib/contrib/roommaker/
lima-1.0b5/lib/contrib/transient_effect/
lima-1.0b5/lib/daemons/channel/
lima-1.0b5/lib/daemons/imud/
lima-1.0b5/lib/data/
lima-1.0b5/lib/data/config/
lima-1.0b5/lib/data/links/
lima-1.0b5/lib/data/news/
lima-1.0b5/lib/data/players/
lima-1.0b5/lib/data/secure/
lima-1.0b5/lib/domains/
lima-1.0b5/lib/domains/std/2.4.5/maze1/
lima-1.0b5/lib/domains/std/2.4.5/npc/
lima-1.0b5/lib/domains/std/2.4.5/post_dir/
lima-1.0b5/lib/domains/std/2.4.5/sub/
lima-1.0b5/lib/domains/std/camera/
lima-1.0b5/lib/domains/std/config/
lima-1.0b5/lib/domains/std/cult/
lima-1.0b5/lib/domains/std/effects/
lima-1.0b5/lib/domains/std/misc/
lima-1.0b5/lib/domains/std/monsters/
lima-1.0b5/lib/domains/std/recorder/
lima-1.0b5/lib/domains/std/rooms/
lima-1.0b5/lib/domains/std/rooms/beach/
lima-1.0b5/lib/domains/std/rooms/labyrinth/
lima-1.0b5/lib/domains/std/school/
lima-1.0b5/lib/domains/std/school/O/
lima-1.0b5/lib/domains/std/spells/
lima-1.0b5/lib/domains/std/spells/stock-mage/
lima-1.0b5/lib/domains/std/spells/stock-priest/
lima-1.0b5/lib/help/
lima-1.0b5/lib/help/admin/
lima-1.0b5/lib/help/hints/General_Questions/
lima-1.0b5/lib/help/hints/Pirate_Quest/
lima-1.0b5/lib/help/player/
lima-1.0b5/lib/help/player/bin/
lima-1.0b5/lib/help/player/quests/
lima-1.0b5/lib/help/wizard/
lima-1.0b5/lib/help/wizard/coding/guilds/
lima-1.0b5/lib/help/wizard/coding/rooms/
lima-1.0b5/lib/help/wizard/lib/daemons/
lima-1.0b5/lib/help/wizard/lib/lfun/
lima-1.0b5/lib/help/wizard/lib/std/
lima-1.0b5/lib/help/wizard/mudos_doc/
lima-1.0b5/lib/help/wizard/mudos_doc/applies/
lima-1.0b5/lib/help/wizard/mudos_doc/applies/interactive/
lima-1.0b5/lib/help/wizard/mudos_doc/applies/parsing/
lima-1.0b5/lib/help/wizard/mudos_doc/concepts/
lima-1.0b5/lib/help/wizard/mudos_doc/driver/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/arrays/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/buffers/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/compile/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/filesystem/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/floats/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/functions/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/general/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/mappings/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/mixed/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/numbers/
lima-1.0b5/lib/help/wizard/mudos_doc/efuns/parsing/
lima-1.0b5/lib/help/wizard/mudos_doc/lpc/constructs/
lima-1.0b5/lib/help/wizard/mudos_doc/lpc/types/
lima-1.0b5/lib/include/driver/
lima-1.0b5/lib/log/
lima-1.0b5/lib/obj/admtool/
lima-1.0b5/lib/obj/admtool/internal/
lima-1.0b5/lib/obj/admtool/mudinfo/
lima-1.0b5/lib/obj/admtool/secure/
lima-1.0b5/lib/obj/secure/
lima-1.0b5/lib/obj/secure/cmd/
lima-1.0b5/lib/obj/secure/mailers/
lima-1.0b5/lib/obj/secure/shell/
lima-1.0b5/lib/obj/secure/shell/classes/
lima-1.0b5/lib/obj/tasktool/
lima-1.0b5/lib/obj/tasktool/internal/
lima-1.0b5/lib/open/
lima-1.0b5/lib/secure/
lima-1.0b5/lib/secure/cgi/
lima-1.0b5/lib/secure/modules/
lima-1.0b5/lib/secure/simul_efun/
lima-1.0b5/lib/std/adversary/
lima-1.0b5/lib/std/adversary/advancement/
lima-1.0b5/lib/std/adversary/armor/
lima-1.0b5/lib/std/adversary/blows/
lima-1.0b5/lib/std/adversary/death/
lima-1.0b5/lib/std/adversary/formula/
lima-1.0b5/lib/std/adversary/health/
lima-1.0b5/lib/std/adversary/pulse/
lima-1.0b5/lib/std/adversary/wield/
lima-1.0b5/lib/std/classes/event_info/
lima-1.0b5/lib/std/container/
lima-1.0b5/lib/std/living/
lima-1.0b5/lib/std/modules/contrib/
lima-1.0b5/lib/std/patterns/
lima-1.0b5/lib/std/race/
lima-1.0b5/lib/std/race/restricted/
lima-1.0b5/lib/std/room/
lima-1.0b5/lib/tmp/
lima-1.0b5/lib/trans/
lima-1.0b5/lib/trans/admincmds/
lima-1.0b5/lib/trans/obj/
lima-1.0b5/lib/wiz/
M_TRIGGERS

The M_TRIGGERS module is designed to work with the M_ACTIONS module, so
inherit that as well.  M_TRIGGERS is separate because it causes an object
to parse everything it sees, which can be expensive in terms of CPU time,
and is unecessary for objects that do not use it.

M_TRIGGERS is implemented using a catch_tell() function.  If you override
this function, M_TRIGGERS will fail to work.

The main interface is through 'add_pattern' and 'add_sub_pattern'.  The
simplest use is as follows:

add_pattern("The door slides open.", "say Wow!");

This will cause the object to say "Wow!" whenever it sees the first phrase.
The pattern can either be an exact match, or it can be a pattern for
sscanf() with either 1 or 2 arguments.  (Note for power users: sscanf can
handle regexps, so patterns like: "%([a-zA-Z]*@[a-zA-Z]*) tells you: %s"
are legal).  For example:

add_pattern("%s smiles.", "smile");

will cause your object to smile whenever anyone in the room smiles.
The response can also be a function pointer, in which the arguments
from sscanf are passed to the function pointer, allowing you to do
different things depending on what the matched argument was:

add_pattern("%s smiles.", (: "slap " + $1 :)); // we're in a bad mood

Multiple patterns may be added, and each will be tried until one returns
a valid command.

*** add_sub_pattern ***

add_sub_pattern() can be used to create more complex behaviors.

First, some terminology.  A 'pattern' is a string to match and an 'action'.
In the above examples we omitted the fact that add_pattern can actually
take two more arguments specifying 'rule's for the first and second
parts which were matched by the pattern.  What is a 'rule'?  A 'rule' 
s a list of 'pattern's which are associated with a name.  The to level
patterns (which are added by add_pattern) are actually members of the
rule named '0'.  You can add a pattern which has a sub rule as follows:

// specify first arg uses "smile_sub_rule"
add_pattern("%s smiles.", (: my_smile_action :), "smile_sub_rule");

// specify second arg uses "say_rule"
add_pattern("%s says %s.", (: handle_say :), 0, "say_rule");

Now, we saw above that the 'piece's that matches each part of the pattern
passed as strings to the 'action'.  That is actually the _default_ behavior,
when no subrule exists.  If a subrule exists and one of the patterns in
that subrule matches the 'piece', the result of the subpattern's 'action' 
is substituted for the 'piece'.  Patterns are added to subrules as follows:

varargs void add_sub_pattern(rule, pattern, action, left, right);

sub patterns can have their own sub rules ad infinitum.
If all this is a bit confusing, here is a quick example:

// no left subrule, right subrule is "kick_sub_rule"
add_pattern("%s kicks %s.", (: $2 :), 0, "kick_sub_rule");

add_sub_pattern("kick_sub_rule", 
	                  "you", "say Hey! stop that!");
// default
add_sub_pattern("kick_sub_rule", 
	                  0, (: "say Yeah, " + $1 + " is a piece of junk." :) );

A zero 'pattern' matches anything.

When the object sees: Foo kicks bar.
It matches the first 'pattern', with the left side being "Foo" and the right
side being "bar".  We have no left subrules, so we leave that alone.  Now we
try to parse "bar" according to the right sub rules.  "bar" does not match
"you", so we go on to the next one.  It DOES match 0, so we evaluate the
function for this subrule, creating the string 
"say Yeah, bar is a piece of junk.".  The top level 'action' is then called
with the args ("Foo", "say Yeah, bar is a piece of junk.") returning the
second string.  That string is then interpreted as a command.

When the object sees: Foo kicks you.
It matches the first 'pattern', with the left side being "Foo" and the right
side being "you".  This time, the "you" 'pattern' matches.  The action is
simply a string so we return that to the level above.  The top level function
gets called with ("Foo", "say Hey! stop that!"), and again the second string
is taken as a command.

Note: What is passed between levels is completely arbitrary, since it
is generated by a user function, and interpreted by a user function. 
The above example followed the convention that a string command is
passed back up.  The following example passes up a function pointer to
be evaluated.

(This is a much more involved example, a bit of lispish-ness may be 
noted here :) )

int starts_with(string str, string pref) {
    return str[0..strlen(pref)-1] == pref;
}

int ends_with(string str, string suff) {
    return str[