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/
********   Please note this is a rough draft of how verbs work.  ************
********   Until this has beeks and the rest of the lima admin   ************
********   approval it will be considered just that a rough      ************ 
********   draft.  The purpose of this is to give someone a very ************ 
********   high level picture of what is happening in the verbs. ************

********       Updated by Loriel 2003                            ************

One of the most often asked questions is what is the difference between a verb
and a command.  

     The "major" difference between verbs and commands is the way in which they 
     are parsed and the 'tokens' the recognize.

     Commands use tokens like cfile etc which parse filenames etc.
 
     Verbs use tokens like OBJ, LIV and are suited for game like stuff.

     Verbs are used for game type stuff ( i.e. look, get, drop etc.), and 
     most verbs have heavy interaction with other objects.    


The first part of this document is a post on Lima Bean from Beek regarding 
the parser.

___________________________________________________________________________________
....  [ snipped for the reason that it wasnt necessary ] ....

   First of all, I'm not guaranteeing that
   the current interface will be the final one, so the given
   examples are a good indication of what things will probably
   look like, but not necessarily.  [ more snipped ].

   Basically, if you are thinking of writing 100s of verbs, you're
   jumping the gun a bit as the parser isn't finished yet.  If you
   don't mind making small tweaks to them as design changes roll
   through, though, you'll be fine.

_____________________________________________________________________________________


The following is the spec that Beek supplied:

The efun interface:

void parse_init()

   This efun alerts the driver that this_object() is an object that the
   parser should recognize as a 'game' object.  All objects that do not
   call parse_init() are ignored by the parser.  Nothing is actually
   done at this time; the internal parser structures for the object are
   set up, and the object is marked as being a parseable object, and is
   marked as being in a non-setup state.

   Objects that are not setup will have the parse_* functions called on
   them *once* at a later point when the driver decides it needs the
   information for that object.  After that, the driver remembers what
   the functions returned.  See parse_refresh().

void parse_refresh()
   
   Notifies the driver that the result of the parse_* functions may have
   changed.  Basically, the driver throws away it's saved information and
   marks the object as not being set up.

void parse_add_rule(string verb, string rule, int flags)

   Adds rule 'rule' for verb 'verb' to the internal parse tables.  Rule
   is in the form 'OBJ in OBJ'.  'flags' is reserved for future use.

mixed parse_sentence(string input)

   Asks the driver to handle the input string 'input'.  Return values are
   1 for everything went spiffy, 0 for 'I haven't a clue what the hell that
   is' and a string error message if 'input' doesn't make sense, but the
   parser has a good idea what was intended.  parse_sentence("put belboz in
   trashcan") -> "Belboz vehemently refuses to be put anywhere."; many of
   these messages are the result of negotiation with the mudlib, altough
   there are some canned ones (parse_sentence("get foo") -> "There is no
   foo here.").

   This is by far the most complex one.  The others are bookkeeping/interface
   more or less.  The algorithm is more or less as follows:

   1. Find the first word and lookup the appropriate verb.

   2. For each rule for the verb, match it to the remaining input string
      and attempt to fit parse the sub parts
      (i.e. for 'belboz in bag' and 'OBJ in OBJ' try to parse 'belboz'
       and 'bag' as OBJs)
      -> at this moment, support for OBJ, OBS, LIV, STR, WRD is planned. 
          Probably more to specified stuff like 'an object I am holding' 
          etc.

   3. The basic algorithm for parsing an object is to first check if
      the object table has been loaded (from a previous attempt to parse
      an OBJ rule).  If not, parsing information is loaded from the
      objects in environment(this_player()).

   4. The substring is then iterated over, checking the grammatical types
      of the words, and seeing if it makes sense/matches an object

   5. Assuming a rule is properly matched (there is a non-ambiguous object
      that matches each OBJ rule, etc) the parser then attempts to check if
      the rule make sense.  It calls the following:
      -> can_verb() in the zorker object
           e.g. can_look() { if (!light) return "It is dark"; }
     
   
 
   6. Actually execute the verb.  verb_obj->do_verb(object io, object do)

There are some details about imprecise matches, error recovery, and error
priorities which have been left out here for simplicity.  They only improve
the error messages, not the functionality.

-Beek

___________________________________________________________________________________

One of the most important things to remember to do in your verb handler 
  ( the file in /cmds/verbs/) is to 

  inherit VERB_OB


the important functions are as follows:
    
  do_(verb)()  --
     This is where the functionality of the verb takes place.

  add_rules()
     this function tells the driver what 'rules' can be associated with the verb 
     i.e. OBJ, LIV, STR etc.  
     Also this is where you set the aliases.
     e.g. get and take will be aliases so that there is only one verb for those.
      
  can_(verb)()  --  
     This function should do nothing other than tell the driver if it is possible
     for this to happen. By default it returns 1, meaning "yes, it can happen"

The following 2 functions are used with direct/indirect object respectively, 
to check whether the action is allowed.

    direct_<verb>()
      called when there is a direct object. 
      Should return 1 for "Yes it can happen", 
      with 0 or a string meaning "No, it can't happen"
      0 will result in a generic error message. eg "You can't do that",
      whilst a returned string will be used as the message for why the verb
      can't be executed (eg "You need to have a spade to dig")
      
    indirect_<verb>()
      indirect called when there is a indirect object.
      Works in a similar fashio to direct_<verb>()

______________________________________________________________________________
Lets look at a very simple verb:  xyzzy (from the original ZORK adventures).

inherit VERB_OB;

mixed do_xyzzy()
{
  write("A hollow voice says: Fool!\n");
}

void create()
{
  add_rules( ({ "" }), ({ "plugh", "plover" }) );
}

This is a very simple verb.  the do_xyzzy does the action for the verb.
There is no can_xyzzy, so the default tells the driver 
"OK, this action can happen".

the add_rules sets the optional arguments for the verb (in this case 
only the verb xyzzy by itself is valid).  plugh and plover are aliases.

______________________________________________________________________________

Lets look at another simple example of a verb - extinguish.


inherit VERB_OB;

void do_extinguish_obj(object ob) {
    ob->do_extinguish();
}

void create()
{
  add_rules( ({ "OBJ" }) );
}        

This means that the only syntax is "extinguish <object>",
that the can_ and direct_ checks will be in the object rather than the verb,
and that the action will call do_extinguish() in the object - so that different
objects can implement "extinguish" in different ways.

In fact, the do_extinguish() function here is unnecessary, as this is the 
default action for a verb, but is retained for clarity.
______________________________________________________________________________
A simpler form of the "give" verb could be implemented as :

inherit VERB_OB;


mixed do_give_obj_to_liv(object ob, object liv)
{
  this_body()->targetted_action("$N $vgive $o to $t.\n", liv, ob);
  ob->move(liv);
}

void create()
{
  add_rules( ({ "OBJ to LIV" }), ({ "hand" }) );
}

In the above example, notice the difference in the function names.  They correspond 
to the rule/rules  in query_verb_info().

please note the existence of the following in /std/living.c:

indirect_give_obj_to_liv()
{
  ......
}
         
direct_give_obj_to_liv is in /std/object/vsupport.c: (which is where things go
that dont really have a home yet)

The actual implementation of the "give" verb is somewhat more complicated than
the simple version above, adding error checking for the do_give_obj_to_liv() 
function, and implementing other cases to handle giving multiple objects
(ie the "OBS" rule) and to handle money via the "WRD STR to LIV" rule and 
do_give_wrd_str_to_liv() function ("give 2 gold coins to fred" etc).