home *** CD-ROM | disk | FTP | other *** search
/ Amiga Games Extra 1996 May / Amiga_Games_Extra_CD_5-96.bin / spiele / publicdomain / amdoc / builtins.txt next >
Text File  |  1996-02-19  |  171KB  |  4,057 lines

  1. AmigaMUD, Copyright 1996 by Chris Gray
  2.  
  3.  
  4.             The AmigaMUD Builtin Functions
  5.  
  6.  
  7. This file documents all of the builtin functions in the AmigaMUD
  8. system. The functions are listed in alphabetical order. Each is given
  9. with the category it is in, along with its prototype. Each is then
  10. described and, if appropriate, examples are given. More general
  11. discussions can be found in the ProgConcepts.txt file. The "utility"
  12. in the prototypes indicates that the builtin function does not change
  13. the effective user when it is executed. Some builtins have "wizard" in
  14. their prototype, which means they can only be used by full wizards,
  15. and not by apprentices. Also, some functions can only be executed by
  16. SysAdmin, but this is not indicated in their header.
  17.  
  18.  
  19. AAn: output
  20. proc utility AAn(string s1, s2)string
  21.  
  22.     AAn is used to make output look more like proper English. It
  23.     returns a string which is the concatenation of its two string
  24.     arguments, with either " a " or " an " inserted between them,
  25.     depending on whether the first letter of the second string is a
  26.     vowel or not. E.g.
  27.  
  28.     AAn("You do not have", "apple") => "You do not have an apple"
  29.     AAn("You do not have", "tree")    => "You do not have a tree"
  30.     AAn("", "whatzit") => "a whatzit"
  31.  
  32. AbortEffect: effects
  33. proc utility AbortEffect(thing who; int kind, id)void
  34.  
  35.     AbortEffect is used to abort an ongoing effect in a full client.
  36.     'who' is the thing of the client to be affected, or nil to mean
  37.     the active client. 'kind' is the kind of effect to be aborted,
  38.     with values: 0 => sound, 1 => speech, 2 => music. 'id' is the
  39.     identifier of the specific affect to be aborted. This id is
  40.     also given when the effect is started. E.g.
  41.  
  42.     VSpeak(nil, "Hello there!", 777);
  43.     ...
  44.     AbortEffect(nil, EFFECT_SPEECH, 777);
  45.  
  46. ABPrint: output
  47. proc utility ABPrint(thing location, agent1, agent2; string str)void
  48.  
  49.     ABPrint outputs string 'str' to all clients with the given
  50.     location, except those whose things are identified by 'agent1' and
  51.     'agent2'. Either or both of these can be nil to be ignored. The
  52.     standard scenario uses ABPrint during combat, to allow three
  53.     different messages to be given: one to the attacker, one to the
  54.     victim, and one to any onlookers. The last uses ABPrint.
  55.  
  56. AddButton: effects
  57. proc utility AddButton(int x, y, n; string str)void
  58.  
  59.     AddButton is used to add a mouse-button to the graphics window of
  60.     the active client. 'x' and 'y' give the co-ordinates of the top-
  61.     left corner of the button, 'n' gives the identifier of the button,
  62.     and 'str' is the text contents of the button. The length of the
  63.     text determines the width of the button. Buttons are 16 pixels
  64.     high and 16 + 8 * <text-length> pixels wide. Empty buttons can be
  65.     produced by using strings containing only spaces. When the user
  66.     clicks on the button, the identifier, 'n', is sent to the server
  67.     for processing by the character's current "button action". If
  68.     there is already a button with the indicated id, then the new
  69.     button is ignored. E.g.
  70.  
  71.     AddButton(20, 10, BUTTON_ID, "Hit");
  72.  
  73. AddHead: database
  74. proc utility AddHead(<any list> theList;
  75.     <corresponding element type> theElement)void
  76.  
  77.     AddHead is used to add an element to the front of a list. It is a
  78.     generic function in that it works for any type of list. The new
  79.     element is inserted before any existing elements, so it will have
  80.     index 0 in the list. E.g.
  81.  
  82.     private l CreateIntList().
  83.     l[0]. => error
  84.     AddHead(l, 10).
  85.     l[0]. => 10
  86.     l[1]. => error
  87.     AddHead(l, 999).
  88.     l[0]. => 999
  89.     l[1]. => 10
  90.  
  91. AddRegion: effects
  92. proc utility AddRegion(int x1, y1, x2, y2, n)void
  93.  
  94.     AddRegion adds a mouse sensitive rectangular region to the
  95.     graphics window of the active client. The region is not visible,
  96.     but a mouse-click inside of it (that doesn't hit a button or a
  97.     region with lower identifier) will return the identifier of the
  98.     region and the co-ordinates of the click relative to the top-left
  99.     corner of the region. 'x1' and 'y1' are the co-ordinates of the
  100.     top-left corner of the region, and 'x2' and 'y2' are the co-
  101.     ordinates of the bottom-right corner of the region. Point (x2, y2)
  102.     is included in the region. 'n' is the identifier for the region.
  103.     Such a region is used in the standard scenario over the entire
  104.     map-view area of the graphics window. The position of the click
  105.     relative to the position of the player cursor determines which
  106.     direction the user wants to move in. Another region is used for
  107.     the icon editor. Attempting to add a region using an identifier
  108.     that is already in use has no effect. When regions are clicked in,
  109.     the "mouse click" action associated with the character for that
  110.     client is called, with the identifier 'n' and the offset of the
  111.     click within the region, given as parameters. E.g.
  112.  
  113.     AddRegion(10, 10, 90, 150, REGION_ID);
  114.  
  115. AddTail: database
  116. proc utility AddTail(<any list> theList;
  117.     <corresponding element type> theElement)void
  118.  
  119.     AddTail adds the indicated element to the end of the list. It is
  120.     generic, in that it will work on any type of list. See also:
  121.     'AddHead'. E.g.
  122.  
  123.     private l CreateIntList().
  124.     l[0]. => error
  125.     AddTail(l, 10).
  126.     l[0] => 10
  127.     l[1] => error
  128.     AddTail(l, 999).
  129.     l[0] => 10
  130.     l[1] => 999
  131.  
  132. After: machine/character
  133. proc utility After(int seconds; action theAction)void
  134.  
  135.     After is the heart of automatic activities in AmigaMUD. It
  136.     arranges things so that after 'seconds' seconds, function
  137.     'theAction' is called (with no parameters). The function must be
  138.     one which returns no result (void). When the function is called,
  139.     the active agent will be either the character who was active when
  140.     After was called, or the machine which was active when After was
  141.     called. Note that all such scheduled actions are cancelled when
  142.     the server is shut down - they are not automatically re-installed
  143.     when the server is restarted. Characters and machines have
  144.     activation actions, which are called when the server restarts,
  145.     which can be used to restart any 'After' actions. Any machine
  146.     which does things independently of players will normally have one
  147.     or more 'After' activities. Continuous scheduling of actions can
  148.     be done by using After as the last thing done in a function called
  149.     by After. E.g.
  150.  
  151.     private proc machineStep()void:
  152.         /* Do things based on the machine's state and what is
  153.            happening around it. */
  154.         ...
  155.         After(30 + Random(30), machineStep);
  156.     corp;
  157.  
  158. AgentLocation: machine/character
  159. proc utility AgentLocation(thing theAgent)thing
  160.  
  161.     AgentLocation returns the thing which is the current location of
  162.     the agent whose thing is passed as 'theAgent'. 'theAgent' can be
  163.     the thing of a player character or of a machine. Note that it is
  164.     possible for an agent to be nowhere, so that AgentLocation returns
  165.     nil. Builtin "Here()" is similar to "AgentLocation(Me())". If a
  166.     player character thing is passed, and that character is not
  167.     currently connected, AgentLocation will return nil.
  168.  
  169. APrint: output
  170. proc utility APrint(string message)void
  171.  
  172.     APrint is the AmigaMUD broadcast facility. It sends the given
  173.     'message' to all active clients on the MUD. It is useful for use
  174.     by SysAdmin to make announcements, like "system going down in five
  175.     minutes". The standard scenario uses it to announce when a
  176.     character solves a quest. Note that the server flushes output to
  177.     any given client before it starts output to another client. Thus,
  178.     any messages printed using "APrint" should be done all at once,
  179.     otherwise unwanted newlines may appear.
  180.  
  181. BootClient: machine/character
  182. proc utility BootClient(character who)void
  183.  
  184.     BootClient can be used to force a player off of the system. It is
  185.     equivalent to code running for the player executing "Quit()". The
  186.     client will be shutdown when it is next non-active (which is
  187.     normally immediately). Note that BootClient allows the character
  188.     to execute any shutdown code. BootClient is a graceful boot. If
  189.     something is wrong (e.g. the shutdown code causes troubles), the
  190.     more forceful 'NukeClient' can be used. NukeClient will often mess
  191.     up the character, however.
  192.  
  193. CallEffect: effects
  194. proc utility CallEffect(thing who; int whichEffect)void
  195.  
  196.     CallEffect is used to execute an effect which has been defined
  197.     for the client 'who'. Effects are identified by an identifier
  198.     given when the effect is created using 'DefineEffect' and
  199.     'EndEffect'. If the identified effect is not known to the remote
  200.     client (the "MUD" program), then nothing is done. CallEffect
  201.     can be used inside an effect being defined, in which case it is
  202.     like an effect subroutine call. E.g.
  203.  
  204.     DefineEffect(nil, EFFECT_ID);
  205.     ...
  206.     /* graphics, sound, etc. effect calls */
  207.     ...
  208.     CallEffect(nil, SUBROUTINE_EFFECT_ID);
  209.     ...
  210.     EndEffect();
  211.     ...
  212.     CallEffect(nil, EFFECT_ID);
  213.  
  214. CanEdit: machine/character
  215. proc utility CanEdit()bool
  216.  
  217.     CanEdit returns an indication of whether or not the active agent
  218.     can edit functions and strings. Thus, the scenario can use
  219.     'EditString' to allow editing of a description, or can use line-
  220.     by-line input to read it. In general, a player using "MUD" can
  221.     edit, as can a local player using "SMUD", and all others cannot.
  222.  
  223. Capitalize: utility
  224. proc utility Capitalize(string str)string
  225.  
  226.     Capitalize returns its string argument 'str', but with its first
  227.     character capitalized (made upper-case) if it is a letter. E.g.
  228.  
  229.     Capitalize("hello") => "Hello"
  230.     Capitalize("123") => "123"
  231.  
  232. ChangeName: machine/character
  233. proc utility wizard ChangeName(string newName)void
  234.  
  235.     ChangeName allows the active character to change his/her name.
  236.     Just assigning to property "p_pName" does not work, and will
  237.     result in an inconsistent character. Valid names must be non-
  238.     empty, must not contain any punctuation, must be no more than 20
  239.     characters long, and must not match any existing character name.
  240.  
  241. Character: machine/character
  242. proc utility Character(string name)character
  243.  
  244.     Character looks up the passed 'name' in the 'Characters' table,
  245.     returning nil or the named character. The character does not have
  246.     to be connected. Note that the value returned is of type character
  247.     and not of type thing - use 'CharacterThing' to return the thing
  248.     for the character.
  249.  
  250. CharacterLocation: machine/character
  251. proc utility CharacterLocation(character theCharacter)thing
  252.  
  253.     CharacterLocation is similar to AgentLocation, in that it returns
  254.     the thing which is the location of 'theCharacter'. Only character
  255.     values can be passed, however, and the character's location is
  256.     returned even if the character is not currently connected to the
  257.     MUD.
  258.  
  259. CharacterTable:  machine/character
  260. proc utility CharacterTable(character theCharacter)table
  261.  
  262.     CharacterTable returns the table which is the private table of
  263.     'theCharacter'. All player characters have such a table.
  264.  
  265. CharacterThing: machine/character
  266. proc utility CharacterThing(character theCharacter)thing
  267.  
  268.     CharacterThing returns the thing associated with player character
  269.     'theCharacter'. All characters have such a thing. The reverse
  270.     action is performated by 'ThingCharacter'.
  271.  
  272. ClearButtons: effects
  273. proc utility ClearButtons()void
  274.  
  275.     ClearButtons removes all buttons from the active client's display,
  276.     and also removes the corresponding data structures. This is used
  277.     when a new set of buttons is to be drawn. When the buttons are
  278.     removed, the spaces they occupied are filled in with colour 0.
  279.  
  280. ClearRegions: effects
  281. proc utility ClearRegions()void
  282.  
  283.     ClearRegions removes all mouse-hit regions from the active client.
  284.     Since such regions are not visible, this operation is not visible.
  285.  
  286. ClearThing: database
  287. proc utility ClearThing(thing theThing)void
  288.  
  289.     ClearThing removes all properties from the passed thing. Even
  290.     properties which cannot normally be changed by the effective user
  291.     are removed. The use-counts on the properties themselves and on
  292.     their values (if appropriate) are decremented appropriately. If
  293.     the thing has a usecount of 0, it will be released, and the space
  294.     it occupied in the database will be available for reuse.
  295.     Similarly, any properties or values whose usecounts become 0 will
  296.     also be freed. ClearThing is normally used for operations like
  297.     destroying objects and rooms. Note that a local variable (or
  298.     function parameter) pointing to a thing does not consititute a
  299.     formal use of that that thing, so that variable becomes invalid if
  300.     there are no uses of the thing and it is ClearThing'd. E.g.
  301.  
  302.     th := CreateThing(nil); /* thing has no uses yet! */
  303.     ClearThing(th);     /* thing is now gone! th is invalid */
  304.     th@prop := 6;        /* this can crash the system! */
  305.  
  306. ClientsActive: utility
  307. proc utility ClientsActive()bool
  308.  
  309.     ClientsActive returns 'true' if there are currently any player
  310.     characters active in the MUD, and 'false' otherwise. It is useful
  311.     in the step functions of machines to determine whether or not they
  312.     should be normally active or should go quiescent for a while.
  313.     Well-behaved machines go mostly quiescent when there are no active
  314.     clients, to minimize the load that the AmigaMUD server puts on the
  315.     system when there are no players. E.g.
  316.  
  317.     define tp_myMachine proc machineStep()void:
  318.  
  319.         doLotsOfNeatThings();
  320.         if ClientsActive() then
  321.         After(10 + Random(10), machineStep);
  322.         else
  323.         After(100, machineStep);
  324.         fi;
  325.     corp;
  326.  
  327. ClientVersion: machine/character
  328. proc utility ClientVersion(thing who)int
  329.  
  330.     ClientVersion returns the version number of the indicated client
  331.     program. This allows scenarios to do different actions depending
  332.     on that version. E.g. if newer versions of the clients offer more
  333.     capabilities, then they can be used, and older versions can use
  334.     older capabilities. The version number is the integral part of the
  335.     displayed version number times ten plus the decimal part. E.g. for
  336.     release V0.6 ClientVersion returns 6. Unfortunately, this builtin
  337.     returned an incorrect value in version 0.5. Also unfortunately,
  338.     the version released as V0.7 still contained internal version
  339.     numbers of 0.6 . Version information has been correct since then.
  340.     E.g.
  341.  
  342.     if ClientVersion(nil) >= 20 then
  343.         doFancyNewSuperNeatEffect(nil);
  344.     else
  345.         doGrungyOldUglyEffect(nil);
  346.     fi;
  347.  
  348. Count: utility
  349. proc utility Count(<any list> theList)int
  350.  
  351.     Count is a generic function, accepting any type of list. It
  352.     returns the count of the number of elements in that list. E.g.
  353.  
  354.     for i from 0 upto Count(theList) - 1 do
  355.         doSomethingWith(theList[i]);
  356.     od;
  357.  
  358. CreateActionList: database
  359. proc utility CreateActionList()list action
  360.  
  361.     CreateActionList returns a new, empty list of actions.
  362.  
  363. CreateActionListProp: database
  364. proc utility CreateActionListProp()property list action
  365.  
  366.     CreateActionListProp returns a new property which can be used to
  367.     attach a list of actions to a thing. The new property has no name,
  368.     so it should be put into a table to give it one. E.g.
  369.  
  370.     define myTable myNewProp CreateActionListProp().
  371.     myTestThing@myNewProp := CreateActionList().
  372.     AddTail(myTestThing@myNewProp, myNeatFunction).
  373.  
  374. CreateActionProp: database
  375. proc utility CreateActionProp()property action
  376.  
  377.     CreateActionProp returns a new property which can be used to
  378.     attach a single action to a thing. The new property has no name,
  379.     so it should be put into a table to give it one. E.g.
  380.  
  381.     define myTable myNewProp CreateActionProp().
  382.     myTestThing@myNewProp := myNeatFunction.
  383.  
  384. CreateBoolProp: database
  385. proc utility CreateBoolProp()property bool
  386.  
  387.     CreateBoolProp returns a new property which can be used to attach
  388.     a bool flag to a thing. The new property has no name, so it should
  389.     be put into a table to give it one. E.g.
  390.  
  391.     define myTable myNewProp CreateBoolProp().
  392.     myTestThing@myNewProp := true.
  393.  
  394. CreateCharacter: machine/character
  395. proc utility CreateCharacter(string name, password)void
  396.  
  397.     CreateCharacter creates a new character. The other way that
  398.     characters can be created is by players themselves when they are
  399.     connecting to the system. The latter requires that they know the
  400.     creation password (if one is set) and that the creation password
  401.     not start with an asterisk ("*"). If the system administrator
  402.     decides to disallow such character creations, then all characters
  403.     must be explicitly created using CreateCharacter. 'name' is the
  404.     desired name of the new character, and as usual, must not contain
  405.     any spaces or punctuation characters. 'password' is the initial
  406.     password for the character - the player can change it later. E.g.
  407.  
  408.     CreateCharacter("Fred_Smith", "xyzzy").
  409.  
  410. CreateGrammar: parsing
  411. proc utility CreateGrammar()grammar
  412.  
  413.     CreateGrammar returns a new, empty grammar. A grammar in AmigaMUD
  414.     is a type of table used to hold command words, and the information
  415.     on how to handle those words. Grammars separate from the main
  416.     grammar are useful for implementing "subcommands" like the build
  417.     commands, and for implementing sets of special commands for use in
  418.     special locations or on special occasions.
  419.  
  420. CreateGrammarProp: database
  421. proc utility CreateGrammarProp()property grammar
  422.  
  423.     CreateGrammarProp returns a new property which can be used to
  424.     attach a grammar to a thing. The new property has no name, so it
  425.     should be put into a table to give it one. E.g.
  426.  
  427.     define myTable myNewProp CreateGrammarProp().
  428.     myTestThing@myNewProp := CreateGrammar().
  429.     VerbTail(myTestThing@myNewProp, "spelunk", doSpelunk).
  430.  
  431. CreateIntArray: database
  432. proc utility CreateIntArray(int size)list int
  433.  
  434.     CreateIntArray returns and fills in a new list of integers. Unlike
  435.     'CreateIntList', the list returned by CreateIntArray is not empty.
  436.     It has space for 'size' elements, and those elements are all
  437.     initialized to 0. This routine is a convenient way to initialize
  438.     such things as icons and mapping tables for coordinate based
  439.     areas. E.g.
  440.  
  441.     list int li;
  442.  
  443.     li := CreateIntArray(10);
  444.     li[5] := 7;
  445.  
  446. CreateIntList: database
  447. proc utility CreateIntList()list int
  448.  
  449.     CreateIntList returns a new, empty list of integers.
  450.  
  451. CreateIntListProp: database
  452. proc utility CreateIntListProp()property list int
  453.  
  454.     CreateIntListProp returns a new property which can be used to
  455.     attach a list of ints to a thing. The new property has no name,
  456.     so it should be put into a table to give it one. E.g.
  457.  
  458.     define myTable myNewProp CreateIntListProp().
  459.     myTestThing@myNewProp := CreateIntList().
  460.     AddTail(myTestThing@myNewProp, 27).
  461.  
  462. CreateIntProp: database
  463. proc utility CreateIntProp()property int
  464.  
  465.     CreateIntProp returns a new property which can be used to attach
  466.     an int to a thing. The new property has no name, so it should be
  467.     put into a table to give it one. E.g.
  468.  
  469.     define myTable myNewProp CreateIntProp().
  470.     myTestThing@myNewProp := 145.
  471.  
  472. CreateMachine: machine/character
  473. proc utility CreateMachine(string name; thing theThing, location;
  474.     action startup)void
  475.  
  476.     CreateMachine is used to create a new machine. Machines are used
  477.     in AmigaMUD to perform actions independent of any players. Each
  478.     machine has a corresponding thing, just like players do. The name
  479.     of a machine can be similar to a player's name, like "Packrat", or
  480.     it can be more like an object's name, like "rat;big,hairy".
  481.     Machines can also have empty names, in which case they will not
  482.     show up in rooms, unless 'ForEachAgent' is used to scan agents.
  483.     'theThing' is the thing which holds all of the machine's
  484.     properties. 'location' is the initial location for the machine; it
  485.     can be nil. 'startup' is an action, having no parameters and no
  486.     result, which will be called when the machine has been created.
  487.     It is normally used to start up any "step" routine which the
  488.     machine uses to perform periodic action. 'startup' can be nil.
  489.     E.g.
  490.  
  491.     private tp_witches CreateTable().
  492.     use tp_witches
  493.     define tp_witches witchSpell CreateActionProp().
  494.     define tp_witches witchCharacter CreateIntProp().
  495.     define tp_witches WC_GOOD 0.
  496.     define tp_witches WC_NEUTRAL 1.
  497.     define tp_witches WC_EVIL 2.
  498.     define tp_witches proc spellTurnNosePurple(thing who)void:
  499.         /* turn somebody's nose purple */
  500.     corp;
  501.     define tp_witches proc witchStep()void:
  502.         /* various and sundry nasty stuff */
  503.         After(10, witchStep);
  504.     corp;
  505.     define tp_witches proc witchInit()void:
  506.         After(10, witchStep);
  507.     corp;
  508.     define tp_witches proc createWitch()void:
  509.         thing theWitch;
  510.  
  511.         theWitch := CreateThing(modelWitch);
  512.         theWitch@witchSpell := spellTurnNosePurple;
  513.         theWitch@witchCharacter := WC_EVIL;
  514.         CreateMachine("Crondik;Witch", theWitch, r_blackPit,
  515.               witchInit);
  516.     corp;
  517.  
  518. CreateStringProp: database
  519. proc utility CreateStringProp()property string
  520.  
  521.     CreateStringProp returns a new property which can be used to
  522.     attach a string to a thing. The new property has no name, so it
  523.     should be put into a table to give it one. E.g.
  524.  
  525.     define myTable myNewProp CreateStringProp().
  526.     myTestThing@myNewProp := "hello there world".
  527.  
  528. CreateTable: database
  529. proc utility CreateTable()table
  530.  
  531.     CreateTable returns a new empty table. The table can be used to
  532.     store symbols. Separate tables are used so that the number of
  533.     symbols in your private table (or the public one) does not get too
  534.     large. Having too many symbols in a single table can cause
  535.     problems for the database cache, uses a lot of memory, and is hard
  536.     to handle for the user. The source files for the standard scenario
  537.     create quite a few new tables, usually one or more per major
  538.     source file. The symbols defined in that source file that are not
  539.     needed outside of that source file are put into that table. See
  540.     the example given with 'CreateMachine' for an example of using
  541.     such a table.
  542.  
  543. CreateTableProp: database
  544. proc utility CreateTableProp()property table
  545.  
  546.     CreateTableProp returns a new property which can be used to attach
  547.     a table to a thing. The new property has no name, so it should be
  548.     put into a table to give it one. E.g.
  549.  
  550.     define myTable myNewProp CreateTableProp().
  551.     myTestThing@myNewProp := CreateTable().
  552.  
  553. CreateThing: database
  554. proc utility CreateThing(thing parent)thing
  555.  
  556.     CreateThing returns a new thing in the database. The new thing's
  557.     parent is set to 'parent', which can be nil. CreateThing is used
  558.     to create nearly all items that a player will interact with in
  559.     AmigaMUD: rooms, objects, monsters, etc. A newly created thing has
  560.     no properties other than any inherited from its parent (and its
  561.     parent's parent, etc.)
  562.  
  563. CreateThingList: database
  564. proc utility CreateThingList()list thing
  565.  
  566.     CreateThingList returns a new, empty list of things.
  567.  
  568. CreateThingListProp: database
  569. proc utility CreateThingListProp()property list thing
  570.  
  571.     CreateThingListProp returns a new property which can be used to
  572.     attach a list of things to a thing. The new property has no name,
  573.     so it should be put into a table to give it one. E.g.
  574.  
  575.     define myTable myNewProp CreateThingListProp().
  576.     myTestThing@myNewProp := CreateThingList().
  577.     AddTail(myTestThing@myNewProp, myOtherTestThing).
  578.  
  579. CreateThingProp: database
  580. proc utility CreateThingProp()property thing
  581.  
  582.     CreateThingProp returns a new property which can be used to attach
  583.     a thing to another thing. The new property has no name, so it
  584.     should be put into a table to give it one. This kind of property
  585.     is used, for example, to point from one room to another, to
  586.     indicate a connection between the rooms. E.g.
  587.  
  588.     define myTable myNewProp CreateThingProp().
  589.     myTestThing@myNewProp := myOtherThing.
  590.  
  591. Date: utility
  592. proc utility Date()string
  593.  
  594.     Date returns a string containing the current time and date. E.g.
  595.  
  596.     Date() => "Sat Jun 11 16:49:14 1994"
  597.  
  598. DateShort: utility
  599. proc utility DateShort()string
  600.  
  601.     Date returns a string containing the current time and date. The
  602.     form returned is shorter than that returned by 'Date', and is
  603.     sortable.
  604.  
  605.     DateShort() => "94/06/11 16:49:17"
  606.  
  607. DefineAction: symbols
  608. proc utility DefineAction(table theTable; string name;
  609.     action theAction)bool
  610.  
  611.     DefineAction adds an entry to the 'theTable', with name 'name'
  612.     which is a new name for the passed action 'theAction'. This
  613.     routine is mainly of use in the builder code. The value returned
  614.     is 'true' if the definition was successful, else 'false'.
  615.  
  616. DefineCounter: symbols
  617. proc utility DefineCounter(table theTable; string name;
  618.     property int theCounter)bool
  619.  
  620.     DefineCounter adds a new int property symbol to the indicated
  621.     table. It is mainly used in the builder code. DefineCounter
  622.     returns 'true' if the definition succeeded.
  623.  
  624. DefineEffect: effects
  625. proc utility DefineEffect(thing who; int whichEffect)void
  626.  
  627.     DefineEffect starts the definition of a new effect for the client
  628.     indicated by 'who'. 'whichEffect' is an identifier for the new
  629.     effect; it must be different for each effect defined. Defining an
  630.     affect sends the "code" for the effect to the client, and the
  631.     client adds that effect code to its effect cache. From then on,
  632.     unless that effect is flushed from the effect cache, the effect
  633.     can be called in that client by simply sending a CallEffect
  634.     request. An effect can be an entire global effect, such as the
  635.     standard scenario's view of the streets scene, or can be an
  636.     "effects subroutine" such as one for a horizontal door. The
  637.     scenario can test whether or not a client has a copy of an effect
  638.     with a given id using the 'KnowsEffect' builtin. For example, here
  639.     is the code in the standard scenario for displaying one of the
  640.     locations in the Squirrel quest area:
  641.  
  642.     if not KnowsEffect(nil, SQ_VALLEY13_ID) then
  643.         DefineEffect(nil, SQ_VALLEY13_ID);
  644.         GSetImage(nil, "sq_valley13");
  645.         IfFound(nil);
  646.         GShowImage(nil, "", 0, 0, 160, 100, 0, 0);
  647.         Else(nil);
  648.         AutoOpenSpace();
  649.         GSetPen(nil, C_FOREST_GREEN);
  650.         GAMove(nil, 80, 50);
  651.         GEllipse(nil, 70, 40, true);
  652.         Fi(nil);
  653.         EndEffect();
  654.     fi;
  655.     CallEffect(nil, SQ_VALLEY13_ID);
  656.  
  657.     If the current client (nil) does not know the effect indicated by
  658.     int constant "SQ_VALLEY13_ID", then the definition of that effect
  659.     is sent to the client. After that definition, if needed, the
  660.     effect is called to display the image. Inside the effect, the
  661.     client program is asked to look for an image called "sq_valley13".
  662.     If that image is found, then it is displayed, and the effect is
  663.     complete. If the image is not found, then an approximation of the
  664.     image is drawn using the "AutoOpenSpace" autographics routine, and
  665.     adding a green ellipse to it, representing the oak tree.
  666.  
  667. DefineFlag: symbols
  668. proc utility DefineFlag(table theTable; string name;
  669.     property bool theFlag)bool
  670.  
  671.     DefineFlag adds a new bool property symbol to the indicated
  672.     table. It is mainly used in the builder code. DefineFlag returns
  673.     true if the definition succeeded.
  674.  
  675. DefineString: symbols
  676. proc utility DefineString(table theTable; string name;
  677.     property string theString)bool
  678.  
  679.     DefineString adds a new string property symbol to the indicated
  680.     table. It is mainly used in the builder code. DefineString returns
  681.     true if the definition succeeded.
  682.  
  683. DefineTable: symbols
  684. proc utility DefineTable(table theTable; string name; table newTable)bool
  685.  
  686.     DefineTable adds a reference to a table, 'newTable', to another
  687.     table, 'theTable', with name 'name'. Thus, 'theTable' now contains
  688.     'newTable' as one of its entries. This function is mostly used by
  689.     the builder code.
  690.  
  691. DefineThing: symbols
  692. proc utility DefineThing(table theTable; string name; thing theThing)bool
  693.  
  694.     DefineThing adds a reference to a thing, 'theThing', to a table,
  695.     'theTable', with name 'name'. Thus, 'theTable' now contains
  696.     'theThing' as one of its entries. This function is mostly used by
  697.     the builder code.
  698.  
  699. DelElement: database
  700. proc utility DelElement(<any list> theList;
  701.     <corresponding element type> valu)void
  702.  
  703.     DelElement is used to delete an element from a list. It is a
  704.     generic function in that it works for any kind of list. 'valu',
  705.     the element to be deleted, must be of the corresponding type. It
  706.     is not an error if the element is not found in the list. If the
  707.     list contains more than one occurrence of the element, only the
  708.     first one (the one with the lowest index) is deleted. E.g.
  709.  
  710.     private th CreateThing(nil).
  711.     private listIntProp CreateIntListProp().
  712.     th@listIntProp := CreateIntArray(5).
  713.     th@listIntProp[0] := 7.
  714.     th@listIntProp[4] := 7.
  715.     th@listIntProp.
  716.     ==> {7, 0, 0, 0, 7}
  717.     DelElement(th@listInt, 7).
  718.     th@listIntProp.
  719.     ==> {0, 0, 0, 7}
  720.     DelElement(th@listInt, 7).
  721.     th@listIntProp.
  722.     ==> {0, 0, 0}
  723.  
  724. DeleteSymbol: symbols
  725. proc utility DeleteSymbol(table theTable; string name)bool
  726.  
  727.     DeleteSymbol attempts to delete symbol 'name' from table
  728.     'theTable'. If it can, it does so and returns 'true', otherwise
  729.     it returns 'false'. If it fails to delete the symbol, an error
  730.     comment will have been printed to the active client. This routine
  731.     is intended only for interactive use.
  732.  
  733. DeleteWord: parsing
  734. proc utility DeleteWord(grammar theGrammar; string theWord)void
  735.  
  736.     DeleteWord deletes word 'theWord' from grammar 'theGrammar'. It is
  737.     an error to try to delete a word that is not in the grammar, or if
  738.     you do not own the grammar. Also, if the word has any existing
  739.     synonyms, it cannot be deleted - those synonyms must be deleted
  740.     first. This routine is intended only for interactive use.
  741.  
  742. DescribeKey: database
  743. proc utility DescribeKey(int key)void
  744.  
  745.     DescribeKey considers the int argument passed to it to be a valid
  746.     AmigaMUD internal key, and attempts to describe the value of that
  747.     key. This function can be run ONLY by SysAdmin, since it is
  748.     potentially dangerous. SysAdmin should be careful to only use key
  749.     values that are known to be valid, since invalid keys can result
  750.     in aborts in the database code. Keys are usually expressed as
  751.     hexadecimal int constants for this purpose. This routine is
  752.     intended only for interactive use.
  753.  
  754. DescribeSymbol: symbols
  755. proc utility DescribeSymbol(table theTable; string name)void
  756.  
  757.     DescribeSymbol will print out a description of the value of symbol
  758.     'name' in table 'theTable', provided that that symbol is in the
  759.     table. This is very similar to the "describe" wizard-mode command,
  760.     except that only one specific table is searched for the key. This
  761.     function is used to implement the "@describe" builder command.
  762.  
  763. DestroyCharacter: machine/character
  764. proc utility DestroyCharacter(string theCharacter)void
  765.  
  766.     DestroyCharacter is used to remove an unwanted player character
  767.     from the database. If the character is currently connected, they
  768.     will be disconnected (as in 'BootClient') and the destruction will
  769.     happen after the connection is gone. This function deletes the
  770.     character from the 'Characters' table, but does little else. This
  771.     is because any things, functions, tables or grammars that the
  772.     character may have created all point to the character data
  773.     structure, which in turn points to the character's private symbol
  774.     table and thing. To avoid problems with scenario code which
  775.     accesses these values after the character has been made unuseable,
  776.     DestroyCharacter does not even remove any properties from the
  777.     character's thing. Only SysAdmin, or code that SysAdmin writes,
  778.     can use DestroyCharacter. E.g.
  779.  
  780.     DestroyCharacter("Bad_Boy").
  781.  
  782. DestroyMachine: machine/character
  783. proc utility DestroyMachine(thing machine)void
  784.  
  785.     DestroyMachine is used to destroy a machine that is no longer
  786.     needed. For example, in the standard scenario DestroyMachine is
  787.     used to destroy monsters in the Proving Grounds that are killed.
  788.     The thing of the specific machine to be destroyed is passed. If
  789.     there is still a reference to the machine's thing when this
  790.     function is called, the machine data structure and all properties
  791.     of the thing are deleted, but the thing itself will stay until all
  792.     references to it are gone. Note that whatever references to the
  793.     thing are left are now pointing at a thing with no properties
  794.     other than those inherited from parents. Scenario code should be
  795.     aware of this.
  796.  
  797. DumpThing: utility
  798. proc utility DumpThing(thing key)void
  799.  
  800.     DumpThing can only be executed by SysAdmin, directly at the
  801.     wizard-mode prompt. It symbolically dumps out everything about the
  802.     passed thing. It does not matter what tables the needed symbols
  803.     are in - they will be found. This operation can be quite
  804.     expensive, in that it may have to access all of the tables in the
  805.     system. The operation could also crash the server if not enough
  806.     cache space or memory is available. This is why the function is so
  807.     restricted. The symbols are printed as "paths" if they are not in
  808.     the public symbol table. A path starts with the name of the player
  809.     who owns the table, followed by possibly more table names, and
  810.     finally a symbol, all separated by slashes. If a private symbol
  811.     table itself is printed, then it is printed as the name of the
  812.     character followed by "/PRIVATE". All of these paths are enclosed
  813.     in angle brackets ("<" and ">") to distinguish them from normal
  814.     symbolic output. Here is some example output:
  815.  
  816. > DumpThing(Parent(Me()@p_pWeapon)).
  817. <THING:08000953>: thing, parent <NIL-THING>, owner SysAdmin, useCount 2,
  818.     propCount 8, ts_readonly:
  819.   <p_oName>: "Thor;Hammer,of.hammer"
  820.   <t_base/p_oDesc>:
  821. "The Hammer of Thor appears to be a special weapon. It smashes instead of "
  822. "slashes, but that is likely to be just as effective. It appears to be quite "
  823. "heavy and unwieldy, but you seem to have no trouble with it."
  824.   <t_base/p_oPrice>: 1000000
  825.   <t_base/p_oHome>: <SysAdmin/tp_misc/r_lostAndFound>
  826.   <t_fight/p_oStrBonus>: 3
  827.   <t_fight/p_oAccuracy>: 10
  828.   <t_fight/p_oDamage>: 15
  829.   <t_fight/p_oWieldAction>: <SysAdmin/tp_fight/weaponWield>
  830.  
  831. Editing: utility
  832. proc utility Editing()bool
  833.  
  834.     Editing returns 'true' if the active client is currently using an
  835.     editor within the AmigaMUD system. This happens when the user
  836.     edits a string or a function. Editing a string can be triggered by
  837.     the scenario code calling 'EditString', or by a wizard or
  838.     apprentice calling it directly. Editing a function can be
  839.     triggered by the "edit" wizard-mode command or by using the
  840.     'EditProc' builtin. 'Editing' is useful to prevent attempts to
  841.     start a second edit when one is already in progress.
  842.  
  843. EditProc: utility
  844. proc utility EditProc(action theProc)void
  845.  
  846.     EditProc is a way for executing AmigaMUD code to trigger editing
  847.     of an AmigaMUD function. This has the same effect as a user in
  848.     wizard mode using the "edit" command.
  849.  
  850. EditString: utility
  851. proc utility EditString(string str; action handler; bool raw;
  852.     string prompt)void
  853.  
  854.     EditString throws the active client into an editor (either the
  855.     internal one or an external one), editing the string given by
  856.     'str'. 'handler' must be supplied, and must be a function of type:
  857.  
  858.     proc editHandler(string newString; bool success)void
  859.  
  860.     'prompt' is the string that will appear in the message bar at the
  861.     bottom of the editing window in the internal editor. If 'raw' is
  862.     'true', then when the string is read back from the edit session,
  863.     any newlines in the string are copied directly, as are any
  864.     occurences of '\'. If 'raw' is false, then any newlines in the
  865.     string are converted to spaces, if not following another space (in
  866.     the latter case they are just discarded), and any '\' escape
  867.     sequences are replaced by the character they represent. When this
  868.     is all done, the resulting string is passed to the 'handler'
  869.     function, along with a flag saying whether or not the edit was
  870.     successful. The edit can fail if the user aborts out of the
  871.     builtin editor, or if the AmigaMUD system has any problem starting
  872.     an external editor. Also, if the builtin editor fails to allocate
  873.     memory to hold the string, the edit will fail. So, if the handler
  874.     is called with 'success' 'false', it should not modify anything.
  875.     The standard scenario sets 'raw' to true for news articles and
  876.     usenet mail, and sets it to 'false' for everything else (in-MUD
  877.     mail, descriptions, etc.). All of this is done by the
  878.     "GetDocument" function defined in "util2.m".
  879.  
  880. Else: effects
  881. proc utility Else(thing who)void
  882.  
  883.     Else is used in effects routines to switch to an alternative.
  884.     The Else is executed at effect generation time, in the remote
  885.     client program, not at any time in the server. Currently, the only
  886.     condition that it can work with is that set up by 'IfFound', which
  887.     tests for the success of one of: GLoadBackGround, GSetImage,
  888.     GShowImage with a name included, GShowBrush, SPlaySound or
  889.     MPlaySong.
  890.  
  891. EndEffect: effects
  892. proc utility EndEffect()void
  893.  
  894.     EndEffect marks the end of an effect definition. See the
  895.     description of DefineEffect for an example.
  896.  
  897. EraseButton: effects
  898. proc utility EraseButton(int n)void
  899.  
  900.     EraseButton removes and erases the mouse button identified by 'n'
  901.     from the display of the active client.
  902.  
  903. EraseRegion: effects
  904. proc utility EraseRegion(int n)void
  905.  
  906.     EraseRegion removes the mouse-select region identified by 'n' from
  907.     the records of the active client.
  908.  
  909. Execute: utility
  910. proc utility Execute(string command)void
  911.  
  912.     Execute attempts to execute the passed 'command' as an AmigaOS
  913.     shell command line. The command is executed on the server machine.
  914.     Only SysAdmin, or a function written by SysAdmin, can use this
  915.     function. SysAdmin is warned to never write a function that allows
  916.     any users to execute an arbitrary command. Technically, the call
  917.     to AmigaOS used is:
  918.  
  919.     nilHandle := Open("nil:", MODE_READWRITE);
  920.     Execute(command, 0, nilHandle);
  921.  
  922.     The sample scenario sources use Execute to call on the UUCP
  923.     programs to post usenet mail and news.
  924.  
  925.     WARNING: Do not try to Execute the MUDShut program - that will
  926.     result in a deadlock between it and MUDServ!
  927.  
  928. FailText: effects
  929. proc utility FailText(thing who; string message)void
  930.  
  931.     FailText can be used in a scenario to indicate to the remote user
  932.     which file, requested as part of an effect, could not be opened.
  933.     The standard scenario uses it to print "The birds sing." if the
  934.     sound file "AmigaMUD:Sounds/birds" cannot be opened when needed.
  935.     The failure message, preceeded by the path to the file, is printed
  936.     in the text window of the client. E.g.
  937.  
  938.     define tp_proving0 proc birdsSingOnce(thing client)void:
  939.         if SOn(client) then
  940.         SPlaySound(client, "birds", BIRDS_SING_ID);
  941.         IfFound(client);
  942.         Else(client);
  943.             FailText(client, "The birds sing.");
  944.         Fi(client);
  945.         else
  946.         SPrint(client, "The birds sing.\n");
  947.         fi;
  948.     corp;
  949.  
  950.     Note that this code only tries to find and play the file if the
  951.     client has Sound enabled.
  952.  
  953. Fi: effects
  954. proc utility Fi(thing who)void
  955.  
  956.     Fi is used to end a condition inside an effect. See the
  957.     description of IfFound for more details, and the description of
  958.     GPolygonStart for an example.
  959.  
  960. FileClose: utility
  961. proc utility FileClose(int fileId)void
  962.  
  963.     FileClose closes the indicated file. Any buffered output data is
  964.     written to the real file. The file indicated by 'fileId' is no
  965.     longer valid for 'FileRead'/'FileWrite' operations. Only SysAdmin,
  966.     or code written by SysAdmin, may use this function.
  967.  
  968. FileOpenForRead: utility
  969. proc utility FileOpenForRead(string fileName)int
  970.  
  971.     FileOpenForRead will open the named file for reading. 'fileName'
  972.     is a full path or is relative to where MUDServ was started. The
  973.     value returned is 0 to indicate some kind of failure, or some
  974.     other value to indicate success. The resulting identifier can be
  975.     used with 'FileRead', and should eventually be closed with
  976.     'FileClose'. Only SysAdmin, or code written by SysAdmin, can use
  977.     FileOpenForRead.
  978.  
  979. FileOpenForWrite: utility
  980. proc utility FileOpenForWrite(string fileName)int
  981.  
  982.     FileOpenForWrite will open the named file for reading. 'fileName'
  983.     is a full path or is relative to where MUDServ was started. The
  984.     value returned is 0 to indicate some kind of failure, or some
  985.     other value to indicate success. The resulting identifier can be
  986.     used with 'FileWrite', and should eventually be closed with
  987.     'FileClose'. Only SysAdmin, or code written by SysAdmin, can use
  988.     FileOpenForWrite. Note that this routine opens the file in the
  989.     Amiga's exclusive mode, and empties the file.
  990.  
  991. FileOpenForUpdate: utility
  992. proc utility FileOpenForUpdate(string fileName)int
  993.  
  994.     FileOpenForUpdate will open the named file for update. 'fileName'
  995.     is a full path or is relative to where MUDServ was started. The
  996.     value returned is 0 to indicate some kind of failure, or some
  997.     other value to indicate success. The resulting identifier can be
  998.     used with 'FileReadBinary', 'FileWrite', 'FileWriteBinary' and
  999.     'FileSeek', and should eventually be closed with 'FileClose'. Only
  1000.     SysAdmin, or code written by SysAdmin, can use FileOpenForUpdate.
  1001.  
  1002. FileRead: utility
  1003. proc utility FileRead(int fileId)string
  1004.  
  1005.     FileRead reads and returns a line from the indicated file. The
  1006.     file must have been opened for reading. If the line in the file is
  1007.     longer than 512 characters, then only the first 512 are returned,
  1008.     but the entire line is consumed in the file. Reading an empty line
  1009.     returns a string containing a single space. An end-of-file
  1010.     condition on the file returns an empty string. FileRead can only
  1011.     be used on a file that was opened using 'FileOpenForRead'.
  1012.  
  1013. FileReadBinary: utility
  1014. proc utility FileReadBinary(int fileId; list int data)int
  1015.  
  1016.     FileReadBinary reads binary data from the indicated file. The
  1017.     amount of data read is determined by the size of the passed list.
  1018.     For each element in the list, 4 bytes will be read and placed in
  1019.     that element of the list. If there is not enough data in the file,
  1020.     then some elements of the list may not be updated, and one may be
  1021.     only partially updated. The number of bytes read will be returned.
  1022.     This will be no more than 4 times the number of elements in the
  1023.     list. FileWriteBinary can only be used with a file that was opened
  1024.     using 'FileOpenForUpdate'.
  1025.  
  1026. FileSeek: utility
  1027. proc utility FileSeek(int fileId, position)void:
  1028.  
  1029.     The current position in the indicated file will be moved to the
  1030.     given position. Subsequent 'FileReadBinary', 'FileWriteBinary' or
  1031.     'FileWrite' calls will start at that position. FileSeek can only
  1032.     be used on files opened with 'FileOpenForUpdate'.
  1033.  
  1034. FileWrite: utility
  1035. proc utility FileWrite(int fileId; string theString)void
  1036.  
  1037.     FileWrite writes string 'theString' to the open file identified by
  1038.     'fileId'. No modifications are made to the string - it is written
  1039.     exactly as it is given. A runtime error results if 'fileId' is not
  1040.     currently valid, or was not opened for writing. Only SysAdmin, or
  1041.     code owned by SysAdmin, can use FileWrite.
  1042.  
  1043. FileWriteBinary: utility
  1044. proc utility FileWriteBinary(int fileId; list int data)void
  1045.  
  1046.     The data in the list is written as binary data to the file. The
  1047.     data in the list is not modified. The file must have been opened
  1048.     with 'FileOpenForUpdate'. Four bytes of data are written for each
  1049.     element of the list.
  1050.  
  1051. FindActionSymbol: symbols
  1052. proc utility FindActionSymbol(table theTable; action theAction)string
  1053.  
  1054.     FindActionSymbol is used to try to find a symbol, in table
  1055.     'theTable' for action 'theAction'. If such a symbol is found, it
  1056.     is returned, else an empty string is returned. This function is
  1057.     used in the builder code to try to print a symbolic name for an
  1058.     action in a checker list.
  1059.  
  1060. FindAgent: machine/character
  1061. proc utility FindAgent(string name)thing
  1062.  
  1063.     FindAgent is the basic means of identifying a reference to an
  1064.     agent (a player character or a machine) by a user command. It
  1065.     searches the lists of active players and active machines, looking
  1066.     for one in the same room as the active agent, whose name matches
  1067.     that given. If 'name' is the name of a player character, then that
  1068.     character is looked for and returned if found in the room.
  1069.     Otherwise, 'name' is matched, using 'MatchName', against all of
  1070.     the machines in the room. The first one matched, if any, is
  1071.     returned. As a special case, the strings "me", "myself", "self"
  1072.     and "yourself" return either the active character or the active
  1073.     machine. This search is done by substituting the "MeString" value
  1074.     for 'name'. Thus, if 'SetMeString' has been used to alter that
  1075.     name, then the altered version is searched for. This technique is
  1076.     used with Packrat, so that commands such as "Give xxx to me" will
  1077.     do the expected thing. If no such agent is found, nil is returned.
  1078.  
  1079. FindAgentAsChild: machine/character
  1080. proc utility FindAgentAsChild(thing room, parent)thing
  1081.  
  1082.     FindAgentAsChild searches for a machine in the indicated room
  1083.     which is a direct child of the thing 'parent'. For example, in the
  1084.     standard scenario, the monsters in the Proving Grounds are
  1085.     normally direct children of the generic monsters defined in
  1086.     "monsters.m". Thus, FindAgentAsChild can be used to search a room
  1087.     for a monster cloned from one of those original models. If no such
  1088.     machine is found, nil is returned.
  1089.  
  1090. FindAgentAsDescendant: machine/character
  1091. proc utility FindAgentAsDescendant(thing room, parent)thing
  1092.  
  1093.     FindAgentAsDescendant is very similar to FindAgentAsChild. The
  1094.     difference is that FindAgentAsDescendant will look all the way
  1095.     back through the parentage chain of each machine it checks, to see
  1096.     if 'parent' is on that chain. Thus if machine "three" inherits
  1097.     from machine "two" which inherits from machine "one" and machine
  1098.     "three" is in the room being searched, then FindAgentAsDescendant
  1099.     will find it, but FindAgentAsChild will not. Both will find
  1100.     machine "two".
  1101.  
  1102. FindAgentAt: machine/character
  1103. proc utility FindAgentAt(thing location; string name)thing
  1104.  
  1105.     FindAgentAt is related to FindAgent. It looks in the given room
  1106.     for a player character or machine whose name matches 'name'.
  1107.     FindAgentAt does NOT do the special handling of "me", etc.
  1108.     however. It is most useful for code which wants to determine if
  1109.     someone or something is in some other specific room. If no such
  1110.     agent is found, nil is returned.
  1111.  
  1112. FindAgentWithChildOnList: machine/character
  1113. proc utility FindAgentWithChildOnList(thing room;
  1114.     property list thing listProp; thing parent)thing
  1115.  
  1116.     FindAgentWithChildOnList performs a search of the form 'look for
  1117.     an agent which has an XXX'. 'room' is the room to search in.
  1118.     'listProp' is the property on the agents which points to a list of
  1119.     things, in which to search for a thing which is a child of
  1120.     'parent'. For example, if a magic fountain is only active if
  1121.     someone or something in the room is carrying the magic doodad,
  1122.     then "FindAgentWithChildOnList(room, p_oCarrying, o_doodad)" will
  1123.     perform the required search. Note that the search will not find
  1124.     the doodad inside a container being carried, nor will it find it
  1125.     in any list other than the one indicated. This, and other similar
  1126.     searches, can be done using AmigaMUD code, but the builtin is much
  1127.     more efficient, provided it performs the required search.
  1128.  
  1129. FindAgentWithFlag: machine/character
  1130. proc utility FindAgentWithFlag(thing room; property bool flagProp)thing
  1131.  
  1132.     FindAgentWithFlag looks for an agent (player character or machine)
  1133.     in the given room which has property 'flagProp' set to true. For
  1134.     example, if a scenario were to define a flag "p_pHasCold",
  1135.     indicating that the player has a cold, then the search for
  1136.     infection could be done by "FindAgentWithFlag(room, p_pHasCold)".
  1137.     If no such agent is found, nil is returned.
  1138.  
  1139. FindAgentWithFlagOnList: machine/character
  1140. proc utility FindAgentWithFlagOnList(thing room;
  1141.     property list thing listProp; property bool flagProp)thing
  1142.  
  1143.     FindAgentWithFlagOnList performs a search of the form 'look for an
  1144.     agent who has something which is XXX". 'room' is the room to
  1145.     search in. 'listProp' is the property on the agents which points
  1146.     to a list of things, in which to search for a thing which has
  1147.     property 'flagProp' set to 'true'. The standard scenario uses this
  1148.     routine to see if anyone in a given room is carrying a light with
  1149.     "FindAgentWithFlagOnList(room, p_pCarrying, p_oLight)". Note that
  1150.     the search will not find a light source that is inside a container
  1151.     being carried. If no such agent is found, then nil is returned.
  1152.  
  1153. FindAgentWithNameOnList: machine/character
  1154. proc utility FindAgentWithNameOnList(thing room;
  1155.     property list thing listProp;
  1156.     property string nameProp; string name)thing
  1157.  
  1158.     FindAgentWithNameOnList performs a search of the form 'look for an
  1159.     agent who has something called XXX". 'room' is the room to search
  1160.     in. 'listProp' is the property on the agents which points to a
  1161.     list of things, in which to search for a thing which has string
  1162.     property 'nameProp' which matches 'name'. The searching of the
  1163.     lists is done using 'FindName'. This function is a bit more
  1164.     general than 'FindAgentWithFlagOnList', but it is also quite a bit
  1165.     more expensive to use. Instead of looking for someone with one of
  1166.     a specific type of "apple", this function can look for someone
  1167.     with any kind of "apple", for example.
  1168.  
  1169. FindAnyWord: parsing
  1170. proc utility FindAnyWord(grammar theGrammar; string theWord)int
  1171.  
  1172.     FindAnyWord is a generalization of 'FindWord'. It looks for word
  1173.     'theWord' in the indicated grammar. The id code for the word is
  1174.     returned if it is found, else 0 is returned. If the word is a
  1175.     synonym of another word, then the code of that other word is
  1176.     returned.
  1177.  
  1178. FindChildOnList: database
  1179. proc utility FindChildOnList(list thing theList; thing parent)bool
  1180.  
  1181.     FindChildOnList looks through the elements of 'theList', looking
  1182.     for a thing which is a direct child of 'parent'. If one is found,
  1183.     then FindChildOnList returns 'true', and 'FindResult' can be used
  1184.     to retrieve the actual thing, else 'false' is returned.
  1185.  
  1186. FindElement: database
  1187. proc utility FindElement(<any list> theList;
  1188.     <corresponding element type> valu)int
  1189.  
  1190.     FindElement is a generic routine used to search lists. It works on
  1191.     any kind of list, searching for the corresponding type of value.
  1192.     If the value is found in the list, then the index of the first one
  1193.     is returned, else -1 is returned.
  1194.  
  1195. FindFlagOnList: database
  1196. proc utility FindFlagOnList(list thing theList; property bool flagProp)
  1197.     bool
  1198.  
  1199.     FindFlagOnList is used to search a list of things for a thing
  1200.     which has property 'flagProp' set to true. Note that this search
  1201.     searches for the flag on the things in the list as well as on all
  1202.     of their ancestors. Thus, its result is 'true' if and only if the
  1203.     found thing yields 'true' when looking up the property on it. If
  1204.     such a thing is found, then it can be retrieved with 'FindResult'.
  1205.  
  1206. FindKey: utility
  1207. proc utility FindKey(int key)void
  1208.  
  1209.     FindKey is a very powerful and very expensive routine. It will
  1210.     search the entire database for a symbol whose value is the passed
  1211.     key. The key is normally given as a hexadecimal int constant. All
  1212.     definitions of the key are printed out, one per line, showing the
  1213.     paths of tables to the key. Because of the expense of this
  1214.     function, only SysAdmin can execute it. E.g. if wizard "Fred" has
  1215.     the key in his table "lower" in his table "castle" as "rose", and
  1216.     wizard "Joe" has the key in his table "rooms" as symbol "redRose",
  1217.     then the output would be:
  1218.  
  1219.     FindKey(0xXXXXXXXX).
  1220.     Fred/castle/lower/rose
  1221.     Joe/rooms/redRose
  1222.  
  1223. FindMachineIndexed: machine/character
  1224. proc utility FindMachineIndexed(string name; int index)thing
  1225.  
  1226.     FindMachineIndexed returns the 'index'th machine whose name
  1227.     matches (using MatchName) 'name'. If no such machine exists, then
  1228.     nil is returned. Thus, we can scan through all of the goblins
  1229.     currently active in the scenario with:
  1230.  
  1231.     i := 1;
  1232.     while
  1233.         goblin := FindMachineIndexed("goblin", i);
  1234.         goblin ~= nil
  1235.     do
  1236.         processGoblin(goblin);
  1237.         i := i + 1;
  1238.     od;
  1239.  
  1240.     Note that if "processGoblin" deletes the goblin, this simple loop
  1241.     will skip the next one, so "processGoblin" should return a value
  1242.     indicating that it has done so, and "i" should not be incremented.
  1243.     If it is known beforehand that scanning through all of the goblins
  1244.     is needed, then it is probably easier to just link them together
  1245.     in a big linked list as they are created/destroyed.
  1246.  
  1247. FindName: parsing
  1248. proc utility FindName(list thing theList; property string nameProp;
  1249.     string theName)status
  1250.  
  1251.     FindName is the general string-searching routine in AmigaMUD. It
  1252.     searches the elements of 'theList', looking for a value of string
  1253.     property 'nameProp' which matches 'theName'. Matching is
  1254.     determined by builtin function 'MatchName'. If no such element is
  1255.     found, then 'fail' is returned. If one such element is found, then
  1256.     'succeed' is found, and if more than one is found, 'continue' is
  1257.     returned. If either 'succeed' or 'continue' is returned, then
  1258.     builtin 'FindResult' can be used to return the found thing. Note
  1259.     that the string 'theName' is in the internal "noun;adj,adj" form.
  1260.     If the string begins with a decimal number and a colon, which is
  1261.     the form that 'GetNounPhrase' and 'Parse' yield for the syntax
  1262.     "adj adj noun #number", then the 'continue' result is not
  1263.     possible, and the 'number'th matching thing is returned. 'number'
  1264.     is treated as one-origin here. E.g.
  1265.  
  1266.     st := FindName(Me()@p_pCarrying, p_oName, name);
  1267.     if st = fail then
  1268.         Print("You aren't carrying any " + FormatName(name));
  1269.     elif st = continue then
  1270.         Print(FormatName(name) + " is ambiguous here");
  1271.     else
  1272.         theThing := FindResult();
  1273.         /* process theThing */
  1274.     fi;
  1275.  
  1276. FindResult: parsing
  1277. proc utility FindResult()thing
  1278.  
  1279.     FindResult is used to return the matching thing from three kinds
  1280.     kinds of searches. These are: 'FindName', 'FindFlagOnList', and
  1281.     'FindChildOnList'.
  1282.  
  1283. FindThingSymbol: symbols
  1284. proc utility FindThingSymbol(table theTable; thing theThing)string
  1285.  
  1286.     FindThingSymbol is used to try to find a symbol, in table
  1287.     'theTable' for thing 'theThing'. If such a symbol is found, it
  1288.     is returned, else an empty string is returned. This function is
  1289.     used in the builder code to supply a symbol for the "current"
  1290.     object.
  1291.  
  1292. FindWord: parsing
  1293. proc utility FindWord(grammar theGrammar; string theWord)int
  1294.  
  1295.     FindWord looks up word 'theWord' in grammar 'theGrammar'. If the
  1296.     word is found, then its unique identifier in the grammar is
  1297.     returned. If the word is not found, then 0 is returned. If the
  1298.     word is not a base definition, i.e. it is a synonym of some other
  1299.     word, then 0 is also returned. See 'FindAnyWord'.
  1300.  
  1301. Flush: database
  1302. proc utility Flush()void
  1303.  
  1304.     Flush forces the internal server caches to be written through to
  1305.     the database files. Its effect is very transitory, however, in
  1306.     that further execution in the server, including by machines, can
  1307.     modify the internal cached forms, thus making the stored forms
  1308.     invalid again. Flush performs the same action as the "MUDFlush"
  1309.     program.
  1310.  
  1311.     It is possible to arrange a time-driven event in AmigaMUD which
  1312.     will call Flush, then use "Execute" to copy the database files to
  1313.     a backup location. This saved copy will be fully complete and
  1314.     valid, as far as the AmigaMUD server is concerned. However, the
  1315.     machines will not have called their "idle actions", nor will any
  1316.     active players. Thus, the saved copy may not be consistent from
  1317.     the point of view of the scenario. An example in the standard
  1318.     scenario could be a Flush when a player is in Questor's office.
  1319.     The stored database has that player present, and therefore will
  1320.     lock others out of that room. If that saved copy of the database
  1321.     is used, then when the server starts up the player will not be
  1322.     active, even though the scenario code thinks he/she/it is in
  1323.     Questor's office. Hence, Questor's office will be unusable until
  1324.     that character is logged in and leaves it. Worse problems will
  1325.     occur with the TimeKeeper machine, since it will not be able to
  1326.     compensate for the time passed while the scenario was not running.
  1327.  
  1328.     To allow this kind of backup operation to work, the standard
  1329.     scenario implements a number of special activities in its main
  1330.     startup, and in the startup of some machines. These special
  1331.     activities check for situations such as then mentioned above and
  1332.     attempt to fix them up. In the case of Questor's Office, the
  1333.     character is moved out of the office, and the office is reset. A
  1334.     temporary action (one which removes itself after executing) is
  1335.     added to the player's startup action list. This action informs the
  1336.     player of what happened.
  1337.  
  1338. ForceAction: machine/character
  1339. proc utility ForceAction(thing theAgent; action theAction)status
  1340.  
  1341.     ForceAction is used to force another agent, either a player
  1342.     character or a machine, to perform an action. The action to be
  1343.     performed is the function 'theAction' which must have no
  1344.     parameters and must return a "status" result. That result is
  1345.     returned by ForceAction. When the action is forced, it is executed
  1346.     on behalf of the agent, so that, for example, "Me()" will be that
  1347.     agent, and "Here()" will be that agent's location. "TrueMe()" can
  1348.     still be used to find the agent which is active at the time of the
  1349.     call to ForceAction. The standard scenario uses ForceAction for a
  1350.     number of purposes, including activities relating to killing
  1351.     monsters in combat.
  1352.  
  1353. ForEachAgent: machine/character
  1354. proc utility ForEachAgent(thing location; action theAction)void
  1355.  
  1356.     ForEachAgent is a general routine which can be used to perform
  1357.     searches that the specific 'FindAgentXXX' routines cannot. It can
  1358.     also be used to perform actions on a number of agents. It scans
  1359.     through the active agents, both player characters and machines,
  1360.     and for each one which is in the given location (or for each one
  1361.     if 'location' is nil) calls the passed action with that agent as
  1362.     its parameter. E.g. we can write a routine which will have each
  1363.     agent announce its location:
  1364.  
  1365.     private proc announce(thing theAgent)void:
  1366.         thing where;
  1367.         string m;
  1368.  
  1369.         m := FormatName(theAgent@p_pName) + " is ";
  1370.         where := AgentLocation(theAgent);
  1371.         if where = nil then
  1372.         m := m + "nowhere";
  1373.         else
  1374.         m := m + where@p_rName;
  1375.         fi;
  1376.         APrint(m + ".\n");
  1377.     corp;
  1378.     ForEachAgent(nil, announce).
  1379.  
  1380. ForEachClient: machine/character
  1381. proc utility ForEachClient(action theAction)void
  1382.  
  1383.     ForEachClient is like ForEachAgent, except that it simply scans
  1384.     through all of the active clients in the system. This, in
  1385.     combination with 'ScanTable' used with 'Characters', allows just
  1386.     about any kind of scan needed. Here is some sample code which does
  1387.     the same as the builtin 'APrint':
  1388.  
  1389.     private p_pAnnouncement CreateStringProp().
  1390.  
  1391.     private proc announce(thing who)void:
  1392.         SPrint(who, Me()@p_pAnnouncement);
  1393.     corp;
  1394.  
  1395.     private proc myAPrint(string message)void:
  1396.         Me()@p_pAnnouncement := message;
  1397.         ForEachClient(announce);
  1398.         Me() -- p_pAnnouncement;
  1399.     corp;
  1400.  
  1401.     Note that ForEachClient does not scan through the active machines.
  1402.  
  1403. FormatName: output
  1404. proc utility FormatName(string theName)string
  1405.  
  1406.     FormatName converts a string in "internal" noun-phrase form to one
  1407.     in "external" form. The internal form is the form that consists of
  1408.     a noun (or a set of alternatives, separated by commas), optionally
  1409.     followed by a semicolon and a comma-separated list of adjectives.
  1410.     Any number of those complete forms can be given as alternatives,
  1411.     separated by periods. The external form uses only the first
  1412.     complete alternative. It consists of the adjectives, separated by
  1413.     spaces, followed by another space and the first noun alternative.
  1414.     E.g.
  1415.  
  1416.     FormatName("dog") => "dog"
  1417.     FormatName("dog;big,black") => "big black dog"
  1418.     FormatName("dog,pooch;big,black") => "big black dog"
  1419.     FormatName("Spot.dog,pooch;big,black") => "Spot"
  1420.  
  1421. GAMove: effects
  1422. proc utility GAMove(thing who; int x, y)void
  1423.  
  1424.     GAMove moves the drawing cursor (not any displayed curser) of the
  1425.     given client to the given absolute position. Valid absolute
  1426.     positions with the V1.0 MUD client are: 0 <= x < 320, 0 <= y < 99.
  1427.  
  1428. GCircle: effects
  1429. proc utility GCircle(thing who; int r; bool fill)void
  1430.  
  1431.     GCircle draws a circle on the graphics window of the given client.
  1432.     The circle is of radius 'r', and is centered at the current
  1433.     drawing cursor position. The circle is drawn using the currently
  1434.     selected graphics pen. If 'fill' is true, then the circle is
  1435.     filled in, else just an outline is drawn. Note that the entire
  1436.     circle must be within the graphics drawing area, or it will not be
  1437.     drawn.
  1438.  
  1439. GClear: effects
  1440. proc utility GClear(thing who)void
  1441.  
  1442.     GClear clears the entire graphics area of the selected client to
  1443.     the background colour (pen 0).
  1444.  
  1445. GColours: effects
  1446. proc utility GColours(thing who)int
  1447.  
  1448.     GColours returns the number of colours that the indicated client
  1449.     can display. For the V1.0 Amiga "MUD" client, this is 32.
  1450.  
  1451. GCols: effects
  1452. proc utility GCols(thing who)int
  1453.  
  1454.     GCols returns the number of graphics columns that the indicated
  1455.     client can display. For the V1.0 Amiga "MUD" client, this is 320.
  1456.  
  1457. GDefineTile: effects
  1458. proc utility GDefineTile(thing who; int id, width, height;
  1459.     list int data)void
  1460.  
  1461.     GDefineTile sends a tile definition to the indicated client. From
  1462.     then on, that tile can be referenced by 'GDisplayTile' without
  1463.     being sent from the server again. 'id' is a unique identifier for
  1464.     that tile pattern. 'width' and 'height' are the width and height
  1465.     of the tile in pixels. 'data' is an int array whose size must be
  1466.     equal to (width * height + 3) / 4, i.e. the number of pixels
  1467.     rounded up to the nearest 4. Each int in the list represents 4
  1468.     pixels, with 8 bits used for each one. The pixels are stored row
  1469.     by row. For example, here is a routine to return a 32 pixel wide
  1470.     by 20 pixel high tile which is a miniature of the town view in the
  1471.     standard scenario:
  1472.  
  1473.     define t_tiles proc makeTownTile()list int:
  1474.         list int tile;
  1475.     
  1476.         tile := CreateIntArray(160);
  1477.         tile[0] := 0x1d1d1d1d;
  1478.         tile[1] := 0x1d1d1d1d;
  1479.         tile[2] := 0x1d1d1d1d;
  1480.         tile[3] := 0x1d1d0301;
  1481.         tile[4] := 0x0101031d;
  1482.         tile[5] := 0x1d1d1d1d;
  1483.         tile[6] := 0x1d1d1d1d;
  1484.         tile[7] := 0x1d1d1d1d;
  1485.         tile[8] := 0x1d1d1d1d;
  1486.         tile[9] := 0x1d1d1d1d;
  1487.         tile[10] := 0x1d1d1d1d;
  1488.         tile[11] := 0x1d1d0301;
  1489.         tile[12] := 0x0101031d;
  1490.         tile[13] := 0x1d1d1d1d;
  1491.         tile[14] := 0x1d1d1d1d;
  1492.         tile[15] := 0x1d1d1d1d;
  1493.         tile[16] := 0x1d1d1d1d;
  1494.         tile[17] := 0x1d1d1d1d;
  1495.         tile[18] := 0x1d1d1d1d;
  1496.         tile[19] := 0x1d1d0301;
  1497.         tile[20] := 0x0101031d;
  1498.         tile[21] := 0x1d1d1d1d;
  1499.         tile[22] := 0x1d1d1d1d;
  1500.         tile[23] := 0x1d1d1d1d;
  1501.         tile[24] := 0x1d1d1d1d;
  1502.         tile[25] := 0x1d1d1d1d;
  1503.         tile[26] := 0x1d1d1d1d;
  1504.         tile[27] := 0x1d1d0301;
  1505.         tile[28] := 0x0101031d;
  1506.         tile[29] := 0x1d1d1d1d;
  1507.         tile[30] := 0x1d1d1d1d;
  1508.         tile[31] := 0x1d1d1d1d;
  1509.         tile[32] := 0x1d1d1d1d;
  1510.         tile[33] := 0x1d1d1d1d;
  1511.         tile[34] := 0x1d1d1d1d;
  1512.         tile[35] := 0x1d1d0301;
  1513.         tile[36] := 0x0101031d;
  1514.         tile[37] := 0x1d1d1d1d;
  1515.         tile[38] := 0x1d1d1d1d;
  1516.         tile[39] := 0x1d1d1d1d;
  1517.         tile[40] := 0x1d1d1d1d;
  1518.         tile[41] := 0x1d1d1d1d;
  1519.         tile[42] := 0x1d1d1d1d;
  1520.         tile[43] := 0x1d1d0301;
  1521.         tile[44] := 0x0101031d;
  1522.         tile[45] := 0x1d1d1d1d;
  1523.         tile[46] := 0x1d1d1d1d;
  1524.         tile[47] := 0x1d1d1d1d;
  1525.         tile[48] := 0x1d1d1d1d;
  1526.         tile[49] := 0x1d1d1d1d;
  1527.         tile[50] := 0x1d1d1d1d;
  1528.         tile[51] := 0x1d1d0301;
  1529.         tile[52] := 0x0101031d;
  1530.         tile[53] := 0x1d1d1d1d;
  1531.         tile[54] := 0x1d1d1d1d;
  1532.         tile[55] := 0x1d1d1d1d;
  1533.         tile[56] := 0x1d1d1d1d;
  1534.         tile[57] := 0x1d1d1d1d;
  1535.         tile[58] := 0x1d1d1d1d;
  1536.         tile[59] := 0x1d1d0301;
  1537.         tile[60] := 0x0101031d;
  1538.         tile[61] := 0x1d1d1d1d;
  1539.         tile[62] := 0x1d1d1d1d;
  1540.         tile[63] := 0x1d1d1d1d;
  1541.         tile[64] := 0x03030303;
  1542.         tile[65] := 0x03030303;
  1543.         tile[66] := 0x03030303;
  1544.         tile[67] := 0x03030301;
  1545.         tile[68] := 0x01010303;
  1546.         tile[69] := 0x03030303;
  1547.         tile[70] := 0x03030303;
  1548.         tile[71] := 0x03030303;
  1549.         tile[72] := 0x01010101;
  1550.         tile[73] := 0x01010101;
  1551.         tile[74] := 0x01010101;
  1552.         tile[75] := 0x01010101;
  1553.         tile[76] := 0x01010101;
  1554.         tile[77] := 0x01010101;
  1555.         tile[78] := 0x01010101;
  1556.         tile[79] := 0x01010101;
  1557.         tile[80] := 0x01010101;
  1558.         tile[81] := 0x01010101;
  1559.         tile[82] := 0x01010101;
  1560.         tile[83] := 0x01010101;
  1561.         tile[84] := 0x01010101;
  1562.         tile[85] := 0x01010101;
  1563.         tile[86] := 0x01010101;
  1564.         tile[87] := 0x01010101;
  1565.         tile[88] := 0x03030303;
  1566.         tile[89] := 0x03030303;
  1567.         tile[90] := 0x03030303;
  1568.         tile[91] := 0x03030301;
  1569.         tile[92] := 0x01010303;
  1570.         tile[93] := 0x03030303;
  1571.         tile[94] := 0x03030303;
  1572.         tile[95] := 0x03030303;
  1573.         tile[96] := 0x1d1d1d1d;
  1574.         tile[97] := 0x1d1d1d1d;
  1575.         tile[98] := 0x1d1d1d1d;
  1576.         tile[99] := 0x1d1d0301;
  1577.         tile[100] := 0x0101030d;
  1578.         tile[101] := 0x0f0d0d0e;
  1579.         tile[102] := 0x0d030d0d;
  1580.         tile[103] := 0x0f0d0d03;
  1581.         tile[104] := 0x1d1d1d1d;
  1582.         tile[105] := 0x1d1d1d1d;
  1583.         tile[106] := 0x1d1d1d1d;
  1584.         tile[107] := 0x1d1d0301;
  1585.         tile[108] := 0x0101030f;
  1586.         tile[109] := 0x0f0f0e0e;
  1587.         tile[110] := 0x0e030d0f;
  1588.         tile[111] := 0x0f0f0d03;
  1589.         tile[112] := 0x1d1d1d1d;
  1590.         tile[113] := 0x1d1d1d1d;
  1591.         tile[114] := 0x1d1d1d1d;
  1592.         tile[115] := 0x1d1d0301;
  1593.         tile[116] := 0x0101030e;
  1594.         tile[117] := 0x0f0d0d0e;
  1595.         tile[118] := 0x0303030d;
  1596.         tile[119] := 0x0f0d0d03;
  1597.         tile[120] := 0x1d1d1d1d;
  1598.         tile[121] := 0x1d1d1d1d;
  1599.         tile[122] := 0x1d1d1d1d;
  1600.         tile[123] := 0x1d1d0301;
  1601.         tile[124] := 0x01010e0e;
  1602.         tile[125] := 0x0e0d0d1d;
  1603.         tile[126] := 0x0316031d;
  1604.         tile[127] := 0x0d0d0d03;
  1605.         tile[128] := 0x1d1d1d1d;
  1606.         tile[129] := 0x1d1d1d1d;
  1607.         tile[130] := 0x1d1d1d1d;
  1608.         tile[131] := 0x1d1d0301;
  1609.         tile[132] := 0x0101030e;
  1610.         tile[133] := 0x0d0f0d0d;
  1611.         tile[134] := 0x0303030d;
  1612.         tile[135] := 0x0d0f0d03;
  1613.         tile[136] := 0x1d1d1d1d;
  1614.         tile[137] := 0x1d1d1d1d;
  1615.         tile[138] := 0x1d1d1d1d;
  1616.         tile[139] := 0x1d1d0301;
  1617.         tile[140] := 0x0101030d;
  1618.         tile[141] := 0x0f0f0f0d;
  1619.         tile[142] := 0x0d030d0d;
  1620.         tile[143] := 0x0f0f0f03;
  1621.         tile[144] := 0x1d1d1d1d;
  1622.         tile[145] := 0x1d1d1d1d;
  1623.         tile[146] := 0x1d1d1d1d;
  1624.         tile[147] := 0x1d1d0301;
  1625.         tile[148] := 0x0101030d;
  1626.         tile[149] := 0x0d0f0d0d;
  1627.         tile[150] := 0x0d030d0d;
  1628.         tile[151] := 0x0d0f0d03;
  1629.         tile[152] := 0x1d1d1d1d;
  1630.         tile[153] := 0x1d1d1d1d;
  1631.         tile[154] := 0x1d1d1d1d;
  1632.         tile[155] := 0x1d1d0301;
  1633.         tile[156] := 0x01010303;
  1634.         tile[157] := 0x03030303;
  1635.         tile[158] := 0x03030303;
  1636.         tile[159] := 0x03030303;
  1637.         tile
  1638.     corp;
  1639.  
  1640.     The use of hexadecimal for the numbers makes it easier to see the
  1641.     individual pixels, since there are two hexadecimal digits for each
  1642.     one. The value for the pixel is the pen to use to draw that pixel.
  1643.     If the width of the tile is not a multiple of 4, then the values
  1644.     get quite a bit harder to see in this form. This routine was
  1645.     produced by a short program which reads an IFF ILBM image of the
  1646.     tile and writes out the definition of the tile for AmigaMUD. As of
  1647.     the V1.0 release, the scenario does not make use of the tile
  1648.     facility.
  1649.  
  1650. GDeleteIcon: effects
  1651. proc utility GDeleteIcon(thing who, whoseIcon)void
  1652.  
  1653.     GDeleteIcon removes the icon for agent 'whoseIcon' from the
  1654.     display of agent 'who'. The "MUD" program for 'who' also forgets
  1655.     the definition of the icon. This variant is used when the icon is
  1656.     that of a transient machine (like a monster), so that if the same
  1657.     thing key happens to get re-used for another machine, the system
  1658.     will not accidentally display the icon for the old use of that
  1659.     key, rather than the new one. See GRemoveIcon for an example.
  1660.  
  1661. GDisplayTile: effects
  1662. proc utility GDisplayTile(thing who; int id)void
  1663.  
  1664.     GDisplayTile instructs the "MUD" program of 'who' to display the
  1665.     indicated tile at the current drawing position. The top-left
  1666.     corner pixel of the tile will go at the drawing position, and the
  1667.     drawing position will not be changed.
  1668.  
  1669. GEllipse: effects
  1670. proc utility GEllipse(thing who; int a, b; bool fill)void
  1671.  
  1672.     GEllipse is very similar to GCircle, except that it draws an
  1673.     ellipse with major radius 'a' and minor radius 'b'.
  1674.  
  1675. GetIndent: output
  1676. proc utility GetIndent()int
  1677.  
  1678.     GetIndent returns the current output indent value for the active
  1679.     client. See 'SetIndent' for more information.
  1680.  
  1681. GetNounPhrase: parsing
  1682. proc utility GetNounPhrase(grammar theGrammar; string theString;
  1683.     int separator)string
  1684.  
  1685.     GetNounPhase is part of the AmigaMUD input parsing facility. It is
  1686.     normally called internal to 'Parse' as part of parsing a verb with
  1687.     a direct object or both direct and indirect objects. It can be
  1688.     called directly by user code however. It basically strips one noun
  1689.     phrase from the front of the passed string. The noun phrase is
  1690.     terminated by the end of the string, a punctuation mark such as
  1691.     ".", ",", or ";", or by the occurrence of the given separator
  1692.     word, as defined in the given grammar. Note that GetNounPhrase can
  1693.     return an empty string if a terminator is found at the beginning
  1694.     of the passed string. Any leading "a", "an" or "the" will be
  1695.     stripped from the noun phrase. Any leading "#<number" will be
  1696.     placed at the beginning of the returned noun-phrase, separated
  1697.     from the rest of the phrase by a ":". If the scanned input
  1698.     contained only articles ("a", "an", "the") and "#<number>", but no
  1699.     other words, then GetNounPhrase will print "I need a noun in that
  1700.     sentence." and return an empty string. In a successful operation,
  1701.     the part of the input string not consumed by the noun phrase will
  1702.     be left in the "tail buffer" (see 'GetTail', 'SetTail',
  1703.     'GetWord'). The returned string is the parsed noun phrase in
  1704.     AmigaMUD internal form, i.e. <noun;adj,adj,...>.
  1705.  
  1706.     GetNounPhrase is typically used in a 'VerbTail' verb, which is
  1707.     doing nonstandard parsing of an input command. See, for example,
  1708.     its use in Caretaker's input parsing or the "with" verb in the
  1709.     standard scenario. GetNounPhrase can also be used as the inverse
  1710.     of 'FormatName'.
  1711.  
  1712. GetSeed: utility
  1713. proc utility GetSeed()int
  1714.  
  1715.     GetSeed returns the current value of the server's random number
  1716.     seed. This, in combination with 'SetSeed' can be used to generate
  1717.     reproducible pseudo-random events or structures.
  1718.  
  1719. GetString: utility
  1720. proc utility GetString(string initial; action handler; string prompt)void
  1721.  
  1722.     GetString is used to prompt the user for a string value, and to
  1723.     supply it to the scenario code. Note, however, that GetString does
  1724.     not return the string from the user. The server cannot wait for
  1725.     the user to type the string in, so the result comes back
  1726.     indirectly. GetString is passed a handler action, which will be
  1727.     called with the string the user typed in, when the user has
  1728.     finished typing in that string. Because 'GetString' invokes a
  1729.     string requester in the "MUD" client program, it can only be used
  1730.     when the player is using that client program, either locally or
  1731.     remotely. The 'GOn' builtin can be used to test this. 'prompt'
  1732.     will appear as a prompt in the top of the string requester, and
  1733.     'initial' will be the initial contents of the string requester's
  1734.     input area. When the handler action is called, it is called with
  1735.     two parameters. The first is the string, and the second is a bool
  1736.     value indicating whether or not the user aborted out of the string
  1737.     requester. GetString is used in several places in the button
  1738.     operated building code. For example:
  1739.  
  1740.     proc gotNameString(string s; bool ok)void:
  1741.         if ok then
  1742.         if s = "" then
  1743.             Me()@p_pWhichThing -- p_oNameProp;
  1744.         else
  1745.             Me()@p_pWhichThing@p_oNameProp := s;
  1746.         fi;
  1747.         fi;
  1748.         Me() -- p_pWhichThing;
  1749.     corp;
  1750.  
  1751.     proc requestNewName(thing theThing)void:
  1752.         Me()@p_pWhichThing := thing;
  1753.         GetString(theThing@p_oNameProp, gotNameString,
  1754.               "Enter new name:");
  1755.     corp;
  1756.  
  1757. GetTail: parsing
  1758. proc utility GetTail()string
  1759.  
  1760.     GetTail returns the current contents of the server's "tail
  1761.     buffer". This value can be set by 'SetTail', or 'GetNounPhrase',
  1762.     but is usually set by the internal parsing code. When a 'VerbTail'
  1763.     verb is being parsed, the tail buffer is set to contain the
  1764.     remainder of the input command, after the verb. 'GetWord' can be
  1765.     used to pull "words" out of the tail buffer, one at a time. This
  1766.     allows such a verb to do whatever kind of parsing it wants on the
  1767.     input command.
  1768.  
  1769. GetThingStatus: database
  1770. proc utility GetThingStatus(thing theThing)<thing status>
  1771.  
  1772.     GetThingStatus returns the access status of the passed thing. This
  1773.     can be one of: 'ts_public', 'ts_private', 'ts_readonly', and
  1774.     'ts_wizard', as explained in previous documents.
  1775.  
  1776. GettingString: utility
  1777. proc utility GettingString()bool
  1778.  
  1779.     GettingString returns 'true' if there is currently an active
  1780.     client (i.e. the code running is not that for a machine, triggered
  1781.     independently), and that client is already involved in a
  1782.     'GetString' call. Otherwise, it returns 'false'. This can be used
  1783.     to avoid getting run-time errors from trying to use 'GetString'
  1784.     when it is already in use.
  1785.  
  1786. GetWord: parsing
  1787. proc utility GetWord()string
  1788.  
  1789.     GetWord returns the next "word" from the current tail buffer. For
  1790.     this purpose, a "word" is either a string enclosed in quotation
  1791.     marks (") or a word ended with a space. GetWord does not strip off
  1792.     leading spaces before looking for a word. It assumes that that
  1793.     has already been done, which is the case when 'SetTail', or
  1794.     'GetNounPhrase' sets up the tail buffer, and when a VerbTail is
  1795.     being handled. GetWord removes any trailing spaces after the word
  1796.     it returns, thus preserving the assumption. GetWord can return an
  1797.     empty string if the tail buffer is empty, or if it encountered a
  1798.     pair of adjacent quotation marks. GetWord is most often used
  1799.     inside VerbTail verbs, which require special parsing.
  1800.  
  1801. GiveThing: database
  1802. proc utility GiveThing(thing theThing; character theCharacter)void
  1803.  
  1804.     GiveThing changes the ownership of the passed thing to be the
  1805.     passed character. The operation will fail with a runtime error if
  1806.     either is nil, or the current owner of the thing is not the
  1807.     effective player, and the effective player is not SysAdmin.
  1808.     Changing the owner of a thing can be used when giving an object to
  1809.     a different player. It effects the access rights to the thing.
  1810.  
  1811. GLoadBackGround: effects
  1812. proc utility GLoadBackGround(thing who; string name)void
  1813.  
  1814.     GLoadBackGround is a graphic effect routine which instructs the
  1815.     remote "MUD" client to load in a background image. This image is
  1816.     loaded from "AmigaMUD:BackGrounds/<name>" on the client machine.
  1817.     The image should be be at least 320 x 100 pixels. If the IFF file
  1818.     contains a colour palette, then that palette is loaded, and
  1819.     replaces the current one for the entire graphics window. If the
  1820.     background file is not found, nothing is done, but the "failure"
  1821.     flag is set in the client, and can be tested via 'IfFound'.
  1822.  
  1823. GNewIcon: effects
  1824. proc utility GNewIcon(thing theCharacter; list int newIcon)void
  1825.  
  1826.     GNewIcon associates a new icon with the specified character. Icons
  1827.     are attached to the thing as property 'p_pIcon', which is of type
  1828.     "property list int". The list of ints given must be exactly 8
  1829.     elements long. This function is used to assign the new icon value
  1830.     instead of just using a direct assignment statement, since it
  1831.     checks for a valid icon, and it will update the display of any
  1832.     clients who are currently displaying the icon for this character,
  1833.     and will invalidate any copies of the icon in the icon caches of
  1834.     other clients. Icons are 16 pixel by 16 pixel bitmaps which are
  1835.     displayed on top of client graphics images to indicate the
  1836.     presence of the character in the same room as the client's
  1837.     character. Note that icons are not full-colour - they are shown
  1838.     using the currently selected icon colour only. The client "MUD"
  1839.     programs keep a backup copy of the graphics imagery behind the
  1840.     icon, so removing an icon can be done without having to redraw the
  1841.     graphics imagery. Also, the clients keep a cache of all icons that
  1842.     they have seen, so that the icon data does not have to be resent
  1843.     to redisplay the icon.
  1844.  
  1845. GOn: effects
  1846. proc utility GOn(thing who)bool
  1847.  
  1848.     GOn returns 'true' if the indicated client can display graphics.
  1849.     This is currently true only if the client is running the "MUD"
  1850.     client, either locally or remotely. Note that the "MUD" program
  1851.     can hide the graphics window (e.g. while editing), but it will
  1852.     indicate that graphics are "on" at that time, and will update the
  1853.     hidden graphics window appropriately. The "MUD" program can turn
  1854.     graphics off altogether, in which case 'GOn' on that client will
  1855.     return 'false', and graphics effects operations for that client
  1856.     are not sent.
  1857.  
  1858.     GOn is really just an efficiency measure, allowing the scenario to
  1859.     avoid executing a bunch of graphics-related code if the results
  1860.     would be discarded anyway.
  1861.  
  1862. GPalette: effects
  1863. proc utility GPalette(thing who)bool
  1864.  
  1865.     GPalette on a given client returns 'true' if that client has a
  1866.     palette containing alterable graphics pens. A client running on a
  1867.     system which has only fixed colours would return 'false'. The
  1868.     scenario does not currently use this information.
  1869.  
  1870. GPixel: effects
  1871. proc utility GPixel(thing who)void
  1872.  
  1873.     GPixel writes a single pixel, using the current graphics pen, at
  1874.     the current graphics position, on the indicated client. Neither
  1875.     the pen nor the position are changed.
  1876.  
  1877. GPolygonEnd: effects
  1878. proc utility GPolygonEnd(thing who)void
  1879.  
  1880.     GPolygonEnd is used to close off and draw the current polygon. See
  1881.     GPolygonStart for an example.
  1882.  
  1883. GPolygonStart: effects
  1884. proc utility GPolygonStart(thing who)void
  1885.  
  1886.     GPolygonStart starts drawing a polygon on the indicated client.
  1887.     The polygon will be filled with the current graphics pen. The
  1888.     sides of the polygon are defined using the 'GRDraw' effects
  1889.     routine. Multiple polygons can be drawn at once by using the
  1890.     'GAMove' and 'GRMove' routines to move without drawing. For
  1891.     example, the following code uses polygon drawing to draw part of
  1892.     the "doors room" in the Proving Grounds, as seen from beyond the
  1893.     doors:
  1894.  
  1895.     define tp_proving5 PR_DOORS2_ID NextEffectId().
  1896.     define tp_proving5 proc drawDoors2()void:
  1897.     
  1898.         if not KnowsEffect(nil, PR_DOORS2_ID) then
  1899.         DefineEffect(nil, PR_DOORS2_ID);
  1900.         GSetImage(nil, "pr_doors2");
  1901.         IfFound(nil);
  1902.             GShowImage(nil, "", 0, 0, 160, 100, 0, 0);
  1903.         Else(nil);
  1904.             GSetPen(nil, C_DARK_GREY);
  1905.             GAMove(nil, 0, 0);
  1906.             GRectangle(nil, 159, 99, true);
  1907.     
  1908.             GSetPen(nil, C_LIGHT_GREY);
  1909.             GPolygonStart(nil);
  1910.             GAMove(nil, 70, 99);
  1911.             GRDraw(nil, -10, -19);
  1912.             GRDraw(nil, -20, 0);
  1913.             GRDraw(nil, 0, -20);
  1914.             GRDraw(nil, 20, -20);
  1915.             GRDraw(nil, 40, 0);
  1916.             GRDraw(nil, 20, 20);
  1917.             GRDraw(nil, 0, 20);
  1918.             GRDraw(nil, -20, 0);
  1919.             GRDraw(nil, -10, 19);
  1920.             GPolygonEnd(nil);
  1921.     
  1922.             drawDoors1();
  1923.         Fi(nil);
  1924.         EndEffect();
  1925.         fi;
  1926.         CallEffect(nil, PR_DOORS2_ID);
  1927.     corp;
  1928.  
  1929. GRDraw: effects
  1930. proc utility GRDraw(thing who; int deltaX, deltaY)void
  1931.  
  1932.     GRDraw is used to draw a line, starting at the current graphics
  1933.     position, moving the relative X-Y distance specified by the passed
  1934.     delta values. The graphics drawing position is updated to the new
  1935.     position. The line is drawn using the current graphics pen. GRDraw
  1936.     is also used when drawing polygons - see 'GPolygonStart'.
  1937.  
  1938. GRectangle: effects
  1939. proc utility GRectangle(thing who; int width, height; bool fill)void
  1940.  
  1941.     GRectangle is used to draw a rectangle on the graphics window of
  1942.     the indicated client. The top-left corner of the rectangle is at
  1943.     the current graphics position. The bottom-right corner is
  1944.     determined by the passed 'width' and 'height' values. If 'fill' is
  1945.     'true', then the rectangle is filled with the current graphics pen,
  1946.     else only the border of the rectangle is drawn with that pen. Note
  1947.     that the rectangle is actually drawn as one larger than the
  1948.     indicated 'width' and 'height', since both the top-left and the
  1949.     bottom-right corners are considered to be within the rectangle.
  1950.     This can be a little misleading, but it was felt to be simpler
  1951.     then describing the subtraction of 1 from the values to get the
  1952.     coordinates of the lower-right corner. Thus, to fill the entire
  1953.     graphics window on the "MUD" client, one could use:
  1954.  
  1955.     GSetPen(nil, <colour>);
  1956.     GAMove(nil, 0, 0);
  1957.     GRectangle(nil, 159, 99);
  1958.  
  1959. GRedrawIcons: effects
  1960. proc utility GRedrawIcons(thing who)void
  1961.  
  1962.     GRedrawIcons causes the selected client "MUD" program to redisplay
  1963.     all of the icons that it believes should currently be displayed.
  1964.     This, in combination with 'GUndrawIcons', allows the graphics
  1965.     imagery behind the icons to be changed without having to manually
  1966.     remove and then re-draw all of the icons. Note that 'PlaceCursor'
  1967.     and 'RemoveCursor' should also be used, to make sure that the
  1968.     cursor appears again. If the entire graphics display is going to
  1969.     be redrawn, then 'GUndrawIcons' and 'RemoveCursor' need not be
  1970.     used. For example, to make a small change to the graphics display,
  1971.     e.g. opening or closing a door, etc., the following could be used:
  1972.  
  1973.     ...
  1974.     RemoveCursor();
  1975.     GUndrawIcons(nil);
  1976.     /* modify picture */
  1977.     GRedrawIcons(nil);
  1978.     PlaceCursor(cursorX, cursorY);
  1979.     ...
  1980.  
  1981.     Note that 'RemoveCursor' and 'PlaceCursor' operate implicitly on
  1982.     the active client, so most situations of changing the display for
  1983.     a given room should use 'ForEachAgent' to cause the displays of
  1984.     all clients whose characters are in the room to be properly
  1985.     updated.
  1986.  
  1987. GRemoveIcon: effects
  1988. proc utility GRemoveIcon(thing who, whoseIcon)void
  1989.  
  1990.     GRemoveIcon removes the display of the icon for character
  1991.     'whoseIcon' from the display of client 'who'. The pattern of the
  1992.     icon is not removed from 'who's icon cache. This is the normal way
  1993.     to remove an icon from a display - 'GDeleteIcon' is used when the
  1994.     client should also forget the definition of the icon. This needs
  1995.     to be done, for example, when 'whoseIcon' represents a monster
  1996.     being killed, in which case the thing for the monster might be
  1997.     soon re-used for another monster that should have a different
  1998.     icon. Here is how this is handled in the standard scenario:
  1999.  
  2000.     /*
  2001.      * UnShowIcon - remove my icon from anyone else here.
  2002.      */
  2003.     
  2004.     define t_icons proc utility UnShowIconOnce(thing th)void:
  2005.         thing me;
  2006.     
  2007.         me := Me();
  2008.         if (me@p_pIcon ~= nil or me@p_pStandard) and Parent(me) = nil
  2009.         then
  2010.         /* If the player or machine has a specific icon, or
  2011.            this is a player or a "standard" machine (Packrat,
  2012.            etc.), and this is not a cloned entity, then we
  2013.            just tell the client to undisplay the icon, but to
  2014.            remember it for later use. */
  2015.         GRemoveIcon(th, me);
  2016.         else
  2017.         /* Otherwise, we tell the client to undisplay the icon, 
  2018.            but also to forget it, since the thing associated
  2019.            with it may be reused later for something with a
  2020.            different icon. */
  2021.         GDeleteIcon(th, me);
  2022.         fi;
  2023.     corp;
  2024.     
  2025.     define t_icons proc utility public UnShowIcon()void:
  2026.     
  2027.         ForEachAgent(Here(), UnShowIconOnce);
  2028.     corp;
  2029.  
  2030. GResetColours: effects
  2031. proc utility GResetColours(thing who)void
  2032.  
  2033.     GResetColours resets the graphics palette of the indicated client
  2034.     to the default set of colours:
  2035.  
  2036.     0x000,        /* 00 - black */
  2037.     0x777,        /* 01 - dark grey */
  2038.     0x999,        /* 02 - medium grey */
  2039.     0xccc,        /* 03 - light grey */
  2040.     0xfff,        /* 04 - white */
  2041.     0xd00,        /* 05 - brick red */
  2042.     0xf00,        /* 06 - red */
  2043.     0xf80,        /* 07 - red-orange */
  2044.     0xf90,        /* 08 - orange */
  2045.     0xfc0,        /* 09 - gold */
  2046.     0xfd0,        /* 10 - cadmium yellow */
  2047.     0xff0,        /* 11 - lemon yellow */
  2048.     0xbf0,        /* 12 - lime green */
  2049.     0x0f0,        /* 13 - green */
  2050.     0x8e0,        /* 14 - light green */
  2051.     0x2c0,        /* 15 - dark green */
  2052.     0x0b1,        /* 16 - forest green */
  2053.     0x0ca,        /* 17 - blue green */
  2054.     0x0db,        /* 18 - aqua */
  2055.     0x1fb,        /* 19 - light aqua */
  2056.     0x6fe,        /* 20 - sky blue */
  2057.     0x6ce,        /* 21 - light blue */
  2058.     0x00f,        /* 22 - blue */
  2059.     0x69f,        /* 23 - dark blue */
  2060.     0xc1f,        /* 24 - violet */
  2061.     0xc0e,        /* 25 - purple */
  2062.     0xf1f,        /* 26 - magenta */
  2063.     0xfac,        /* 27 - pink */
  2064.     0xdb9,        /* 28 - tan */
  2065.     0xc80,        /* 29 - brown */
  2066.     0xa70,        /* 30 - medium brown */
  2067.     0xa87        /* 31 - dark brown */
  2068.  
  2069. GResetIcons: effects
  2070. proc utility GResetIcons(thing who)void
  2071.  
  2072.     GResetIcons instructs the indicated client to believe that it
  2073.     currently has no icons displayed. This is quicker when moving from
  2074.     room to room (i.e. icon-set to icon-set) than removing all of the
  2075.     individual icons. Note that this routine does not remove the icon
  2076.     imagery from the graphics window. Any icons which were initially
  2077.     displayed as "temporary" (see 'GShowIcon'), are removed from the
  2078.     client's icon cache.
  2079.  
  2080. GRMove: effects
  2081. proc utility GRMove(thing who; int deltaX, deltaY)void
  2082.  
  2083.     GRMove moves the graphics cursor in the indicated direction from
  2084.     its current position. No drawing on the screen takes place. This
  2085.     routine can also be used while drawing a polygon, and has a
  2086.     similar effect.
  2087.  
  2088. GRows: effects
  2089. proc utility GRows(thing who)int
  2090.  
  2091.     GRows returns the number of rows of pixels in the graphics window
  2092.     of the indicated client. Currently, the only graphics client is
  2093.     the "MUD" client, and it has 100 rows of pixels. If the client in
  2094.     use does not support graphics, then 0 is returned.
  2095.  
  2096. GScrollRectangle: effects
  2097. proc utility GScrollRectangle(thing who;
  2098.     int xDelta, yDelta, x1, y1, x2, y2)void
  2099.  
  2100.     GScrollRectangle instructs the client to shift a rectangular
  2101.     region of its graphics window. The coordinates of the top-left and
  2102.     bottom-right corners of the affected rectangle are given. The
  2103.     delta values indicate the direction in which to scroll the
  2104.     rectangle. Positive values for the deltas indicate scrolling away
  2105.     from the top-left corner in that direction. Data scrolled out of a
  2106.     side of the rectangle is lost. The contents of the region of the
  2107.     rectangle scrolled away from is undefined. One good use of
  2108.     GScrollRectangle is in implementing a scrolling map-view type of
  2109.     display: when the character walks off of the edge of the visible
  2110.     area (or comes close), use GScrollRectangle to scroll the entire
  2111.     graphics window, and then fill in the scrolled-from area with
  2112.     tiles or imagery for newly visible terrain.
  2113.  
  2114. GSetColour: effects
  2115. proc utility GSetColour(thing who; int which, colour)void
  2116.  
  2117.     GSetColour sets graphics pen 'which' in client 'who' to colour
  2118.     'colour'. For the Amiga "MUD" client, the 'which' values can range
  2119.     from 0 to 31, and the 'colour' value is a 12 bit RGB value (4 bits
  2120.     of red, 4 bits of green, and 4 bits of blue).
  2121.  
  2122. GSetIconPen: effects
  2123. proc utility GSetIconPen(thing who; int colour)void
  2124.  
  2125.     GSetIconPen sets which pen (colour) is to be used to draw icons in
  2126.     the graphics window. The entire set of icons currently displayed
  2127.     by the client is redrawn using the new pen.
  2128.  
  2129. GSetImage: effects
  2130. proc utility GSetImage(thing who; string name)void
  2131.  
  2132.     GSetImage sets the given image name to be the current "active"
  2133.     image. The active image is used by 'GShowImage' if 'GShowImage' is
  2134.     passed an empty string. With the Amiga "MUD" client program, path
  2135.     "AmigaMUD:Images/" is prepended to the image name. If the image
  2136.     file is found, it is loaded into the client's cache. If it is not
  2137.     found, nothing happens, but the "failed" flag is set in the
  2138.     client, and can be tested by subsequent 'IfFound' tests.
  2139.  
  2140. GSetPen: effects
  2141. proc utility GSetPen(thing who; int pen)void
  2142.  
  2143.     GSetPen sets the pen to use for subsequent graphics operations,
  2144.     such as line drawing, rectangles, circles, polygons, etc.
  2145.  
  2146. GSetTextColour: effects
  2147. proc utility GSetTextColour(thing who; int which, colour)void
  2148.  
  2149.     GSetTextColour sets the colour of pen 'which' in client 'who',
  2150.     used in the text window. In the Amiga "MUD" client, pen numbers
  2151.     can be from 0 to 3, and 'colour' is a 12 bit RGB value, with 4
  2152.     bits for red, 4 bits for green, and 4 bits for blue. Note that
  2153.     setting the text colours will also affect either the background of
  2154.     the text window, or one of the border-and-menu colours, so the
  2155.     colours used should be selected carefully.
  2156.  
  2157. GShowBrush: effects
  2158. proc utility GShowBrush(thing who; string name;
  2159.     int displayX, displayY)void
  2160.  
  2161.     GShowBrush overlays a brush image onto the graphics window at the
  2162.     indicated position. The brush is loaded from "AmigaMUD:Brushes/
  2163.     <name>". If the brush file cannot be found, then nothing happens,
  2164.     but the "not found" flag is set, and can be tested by 'IfFound'.
  2165.     The difference between a brush and an image is that a brush has
  2166.     either a mask plane or a background colour, so that it can be
  2167.     overlayed on top of the existing graphics as a non-rectangular
  2168.     shape.
  2169.  
  2170. GShowIcon: effects
  2171. proc utility GShowIcon(thing who, whoseIcon;
  2172.     bool isMonster, isTemporary)void
  2173.  
  2174.     GShowIcon shows the icon for character (or NPC) 'whoseIcon' on the
  2175.     graphics window of client 'who'. If the client has no record of
  2176.     the indicated icon, then it will either use the default non-
  2177.     monster icon (the smiley face) or the default monster icon (the
  2178.     growly thing), depending on 'isMonster'. If the icon is displayed
  2179.     as temporary, then when a 'GResetIcons' is done, the icon is
  2180.     deleted from the client completely. This is used when 'whoseIcon'
  2181.     is inheriting its icon from a parent thing, since then 'whoseIcon'
  2182.     is not a unique identifier for the icon.
  2183.  
  2184. GShowImage: effects
  2185. proc utility GShowImage(thing who; string name;
  2186.     int imageX, imageY, imageWidth, imageHeight, displayX, displayY)void
  2187.  
  2188.     GShowImage loads an IFF image file from "AmigaMUD:Images/<name>"
  2189.     onto the graphics window. The image is placed with its top-left
  2190.     corner at 'displayX', 'displayY', and is taken from the whole
  2191.     image file at offset 'imageX', 'imageY', with size 'imageWidth' by
  2192.     'imageHeight'. Being able to display a smaller segment from a
  2193.     large image file allows one image file to contain several images.
  2194.     For example, one file could contain all of the needed images to
  2195.     represent a 3D maze view. This allows the entire set of images to
  2196.     be accessed quickly, and treated as a whole in the client's cache.
  2197.     Also, making changes to the set of images can be easier if they
  2198.     are all displayed at once in a paint program.
  2199.  
  2200. GText: effects
  2201. proc utility GText(thing who; string text)void
  2202.  
  2203.     GText displays the given string as text, using the default system
  2204.     font, in the current graphics pen, at the current graphics
  2205.     position, in the given client's graphics window. The graphics
  2206.     position is moved up to just past the end of the text (such that
  2207.     another GText would append the text properly). Note that, in the
  2208.     Amiga "MUD" client, the current position row is used as the
  2209.     position for the baseline of the font, which is the conceptual
  2210.     line drawn at the bottom of the non-descending part of the
  2211.     characters.
  2212.  
  2213. GType: effects
  2214. proc utility GType(thing who)string
  2215.  
  2216.     GType returns the name of the graphics display of the client.
  2217.     Since the Amiga "MUD" client is the only client so far, the value
  2218.     returned is either "Amiga", or an empty string.
  2219.  
  2220. GUndrawIcons: effects
  2221. proc utility GUndrawIcons(thing who)void
  2222.  
  2223.     GUndrawIcons instructs the specified client to remove all of the
  2224.     currently displayed icons from the graphics window. The client
  2225.     does not forget about the icons, it only undraws them (by
  2226.     replacing the background imagery which was saved when the icons
  2227.     were drawn). GUndrawIcons, in combination with 'GRedrawIcons', can
  2228.     be used to allow easy modification of the imagery that is "behind"
  2229.     the icons. See GRedrawIcons.
  2230.  
  2231. HasAdjective: parsing
  2232. proc utility HasAdjective(string name, adjective)bool
  2233.  
  2234.     HasAdjective returns 'true' if the given 'name', which must be in
  2235.     the standard AmigaMUD "noun;adj,adj..." form, contains 'adjective'
  2236.     as one of its adjectives. Note that HasAdjective handles only a
  2237.     simple internal form for the name - multiple alternatives are not
  2238.     handled.
  2239.  
  2240. Here: machine/character
  2241. proc utility Here()thing
  2242.  
  2243.     Here returns the current location of the active character (or
  2244.     machine.) The return value can be nil if the character has no
  2245.     location. The location of something can be set by the calls
  2246.     'SetLocation', 'SetCharacterLocation' and 'SetAgentLocation'.
  2247.  
  2248. IfFound: effects
  2249. proc utility IfFound(thing who)void
  2250.  
  2251.     This effect routine causes the specified client to test the last-
  2252.     set value of its "not found" flag, and either enable or disable
  2253.     the execution of effects code as a result. See GPolygonStart for a
  2254.     typical example of using IfFound.
  2255.  
  2256. Index: utility
  2257. proc utility Index(string s1, s2)int
  2258.  
  2259.     Index returns the index in string 's1' of the first (leftmost)
  2260.     occurrence of string 's2'. Index positions, like string substring
  2261.     positions, start with index 0. If string 's2' cannot be found in
  2262.     string 's1', then Index returns -1.
  2263.  
  2264. IntToString: utility
  2265. proc utility IntToString(int n)string
  2266.  
  2267.     IntToString returns a string containing the decimal form of the
  2268.     passed int value. If the value is negative, the returned string
  2269.     will start with a minus sign, but no plus sign is inserted for
  2270.     positive values of 'n'.
  2271.  
  2272. IPrint: output
  2273. proc utility IPrint(int number)void
  2274.  
  2275.     IPrint prints the decimal form of 'number' to the current client.
  2276.     It is equivalent to "Print(IntToString(number))", but a bit more
  2277.     efficient, since it doesn't have to allocate and free a string,
  2278.     and is only one call instead of two.
  2279.  
  2280. IsAncestor: database
  2281. proc utility IsAncestor(thing myKey, parentKey)bool
  2282.  
  2283.     IsAncestor returns 'true' if 'parentKey' is the parent of 'myKey',
  2284.     or the parent of the parent of 'myKey', or the parent of... i.e.
  2285.     it returns 'true' if 'parentKey' is on the ancestor chain of
  2286.     'myKey'.
  2287.  
  2288. IsApprentice: machine/character
  2289. proc utility IsApprentice()bool
  2290.  
  2291.     IsApprentice returns 'true' if the active client is a player, and
  2292.     that player is an apprentice.
  2293.  
  2294. IsAre: output
  2295. proc utility IsAre(string s1, s2, s3, s4)string
  2296.  
  2297.     IsAre eases the output of correct English for plural nouns. This
  2298.     is perhaps best described by examples:
  2299.  
  2300.     IsAre("There", "no", "pie", "here.")  => "There is no pie here."
  2301.     IsAre("There", "no", "pies", "here.") => "There are no pies here."
  2302.     IsAre("There", "", "pie", "here.")      => "There is a pie here."
  2303.     IsAre("There", "", "apple", "here.")  => "There is an apple here."
  2304.     IsAre("There", "", "pies", "here.")   => "There are some pies here."
  2305.  
  2306.     If 's2' is empty, then IsAre uses either "a" or "an", depending on
  2307.     whether 's3' starts with a consonant or a vowel ("aeiou"). It uses
  2308.     "is" or "are" depending on whether 's3' ends in an "s" or not.
  2309.     Note that this test for plurality can easily be wrong. Note also
  2310.     that IsAre inserts all needed spaces.
  2311.  
  2312. IsDefined: symbols
  2313. proc utility IsDefined(table theTable; string name)bool
  2314.  
  2315.     IsDefined returns 'true' if string 'name' is defined in table
  2316.     'theTable', else it returns 'false'. If 'theTable' is nil, then
  2317.     'name' is looked up in all "in-use" tables.
  2318.  
  2319. IsNormal: machine/character
  2320. proc utility IsNormal()bool
  2321.  
  2322.     IsNormal returns 'true' if the active agent is a player who has
  2323.     status 'normal'.
  2324.  
  2325. IsProgrammer: machine/character
  2326. proc utility IsProgrammer()bool
  2327.  
  2328.     IsProgrammer returns 'true' if the active agent is a player who
  2329.     has status 'wizard' or 'apprentice', i.e. is someone who can do
  2330.     programming.
  2331.  
  2332. IsWizard: machine/character
  2333. proc utility IsWizard()bool
  2334.  
  2335.     IsWizard returns 'true' if the active agent is a player who has
  2336.     status 'wizard'.
  2337.  
  2338. It: utility
  2339. proc utility It()thing
  2340.  
  2341.     It returns the thing last set via 'SetIt'. The thing stored in
  2342.     this special "global variable" is reset to nil whenever a message
  2343.     arrives at the server, and whenever 'Parse' starts a new command.
  2344.     Thus It is valid only during the parsing of one input command. By
  2345.     convention, It is the object (in the English language sense) of
  2346.     the current input sentence, if there is one. See the description
  2347.     of programming within the standard scenario for information on how
  2348.     It is used in that scenario. See also: 'ItName' and 'WhoName'.
  2349.  
  2350. ItName: parsing
  2351. proc utility ItName()string
  2352.  
  2353.     ItName returns a string containing the internal form of the noun
  2354.     phrase used with a 'Verb1' verb, or the first noun phrase (the
  2355.     direct object) used with a 'Verb2' verb. ItName is maintained
  2356.     directly by the AmigaMUD parser ('Parse'). Similarly, 'WhoName'
  2357.     returns the internal form string of the indirect object (the
  2358.     second noun phrase) associated with a 'Verb2' verb. The only use
  2359.     of ItName in the standard scenario is in a "getaction" attached to
  2360.     a fake bugtape piece in the toolshed - it is used to see if the
  2361.     phrase the player gave for the object contained the words "long"
  2362.     or "longer", via 'HasAdjective'. See also: 'WhoName'.
  2363.  
  2364. KnowsEffect: effects
  2365. proc utility KnowsEffect(thing who; int whichEffect)bool
  2366.  
  2367.     KnowEffect returns 'true' if client 'who' knows the contents of
  2368.     effect 'whichEffect'. This is asking if the client "MUD" program
  2369.     has already been sent the definition of the effect, so that it
  2370.     doesn't have to be sent again (via 'DefineEffect') before being
  2371.     called up (via 'CallEffect').
  2372.  
  2373. Length: utility
  2374. proc utility Length(string str)int
  2375.  
  2376.     Length returns the number of characters in the passed string. This
  2377.     includes any special newline or tab characters. The length of an
  2378.     empty string is 0.
  2379.  
  2380. Log: utility
  2381. proc utility wizard Log(string message)void
  2382.  
  2383.     Log causes the passed string to be appended to the server's "MUD.
  2384.     log" file. This is used in the standard scenario for commands like
  2385.     "complain", "typo", etc. Log can also be used to record error
  2386.     situations. Care should be taken, however, to not Log too much,
  2387.     else the MUD.log file can grow very large. That is why this
  2388.     function is restricted to full wizards.
  2389.  
  2390. LookupAction: symbols
  2391. proc utility LookupAction(table theTable; string name)action
  2392.  
  2393.     'name' is looked up in 'theTable'. If it is found, and the symbol
  2394.     is an action, then that action is returned, else nil is returned.
  2395.     If 'theTable' is nil, then 'name' is looked up in all currently
  2396.     "in-use" tables.
  2397.  
  2398. LookupCounter: symbols
  2399. proc utility LookupCounter(table theTable; string name)property int
  2400.  
  2401.     'name' is looked up in 'theTable'. If it is found, and the symbol
  2402.     is an int property, then that property is returned, else nil is
  2403.     returned. If 'theTable' is nil, then 'name' is looked up in all
  2404.     currently "in-use" tables.
  2405.  
  2406. LookupFlag: symbols
  2407. proc utility LookupFlag(table theTable; string name)property bool
  2408.  
  2409.     'name' is looked up in 'theTable'. If it is found, and the symbol
  2410.     is a bool property, then that property is returned, else nil is
  2411.     returned. If 'theTable' is nil, then 'name' is looked up in all
  2412.     currently "in-use" tables.
  2413.  
  2414. LookupString: symbols
  2415. proc utility LookupString(table theTable; string name)property string
  2416.  
  2417.     'name' is looked up in 'theTable'. If it is found, and the symbol
  2418.     is a string property, then that property is returned, else nil is
  2419.     returned. If 'theTable' is nil, then 'name' is looked up in all
  2420.     currently "in-use" tables.
  2421.  
  2422. LookupTable: symbols
  2423. proc utility LookupTable(table theTable; string name)table
  2424.  
  2425.     'name' is looked up in 'theTable'. If it is found, and the symbol
  2426.     is a table, then that table is returned, else nil is returned. If
  2427.     'theTable' is nil, then 'name' is looked up in all currently "in-
  2428.     use" tables.
  2429.  
  2430. LookupThing: symbols
  2431. proc utility LookupThing(table theTable; string name)thing
  2432.  
  2433.     'name' is looked up in 'theTable'. If it is found, and the symbol
  2434.     is a thing, then that thing is returned, else nil is returned. If
  2435.     'theTable' is nil, then 'name' is looked up in all currently "in-
  2436.     use" tables.
  2437.  
  2438. MakeApprentice: machine/character
  2439. proc utility MakeApprentice(character who; bool doNow)void
  2440.  
  2441.     The given character is made into an apprentice. If 'doNow' is
  2442.     'true', and the character is currently connected, then the client
  2443.     the character is connected through is immediately put into "wizard
  2444.     mode". The status of SysAdmin cannot be changed, and only full
  2445.     wizards can change someone's status. The wizard who promotes a
  2446.     character is recorded as that character's sponsor.
  2447.  
  2448. MakeNormal: machine/character
  2449. proc utility MakeNormal(character who)void
  2450.  
  2451.     The given player is made into a normal player. Only SysAdmin can
  2452.     demote someone, and SysAdmin cannot demote himself. If the player
  2453.     was an apprentice or wizard, and was currently active in wizard
  2454.     mode, then the character's client is immediately forced out of
  2455.     wizard mode.
  2456.  
  2457. MakeWizard: machine/character
  2458. proc utility MakeWizard(character who; bool doNow)void
  2459.  
  2460.     The given character is made into a full wizard. If 'doNow' is
  2461.     'true', and the character is currently connected, then the client
  2462.     the character is connected through is immediately put into "wizard
  2463.     mode". The status of SysAdmin cannot be changed, and only full
  2464.     wizards can change someone's status. The wizard who promotes a
  2465.     character is recorded as that character's sponsor.
  2466.  
  2467. MatchName: parsing
  2468. proc utility MatchName(string stored, parsed)int
  2469.  
  2470.     MatchName is the bottom-level of the AmigaMUD routines which tie
  2471.     together input commands and the database. It matches an internal
  2472.     form of a user input noun phrase against an internal form of a
  2473.     stored one. The stored internal form can have several noun phrase
  2474.     alternatives, separated by periods. Each internal form consists of
  2475.     a comma-separated list of noun alternatives, possibly followed by
  2476.     a semicolon and a comma-separated list of adjectives. There must
  2477.     be no spaces anywhere. If the parsed form can be matched by any of
  2478.     the stored forms, then the index of that stored form (the first is
  2479.     index 0) is returned. If none of the stored forms can match the
  2480.     parsed form, then -1 is returned. Examples:
  2481.  
  2482.     stored                    parsed        result
  2483.     ------------------------------------------------------------------
  2484.     dog,pooch,canine;large,black.Fido        pooch;black    0
  2485.     dog,pooch,canine;large,black.Fido        fido        1
  2486.     dog,pooch,canine;large,black.Fido        Fido;black    -1
  2487.     dog,pooch,canine;large,black.Fido        dog;black,large 0
  2488.     dog,pooch,canine;large,black.Fido        canine        0
  2489.     shelf;wooden.shelf,shelve,shelving;wood,wooden
  2490.                         shelves;wood    1
  2491.                         shelf;wooden    0
  2492.                         shelves;wooden    1
  2493.                         shelving;wood    1
  2494.  
  2495.     Note that excess trailing 's's on the parsed nouns are assumed to
  2496.     be for pluralization and are ignored. Also, case is ignored. The
  2497.     'shelf' example illustrates the use of two alternatives, the first
  2498.     of which is "clean", in that it will come out nicely via
  2499.     'FormatName', and the second of which contains lots of forms, so a
  2500.     variety of user input forms will work.
  2501.  
  2502. Me: utility
  2503. proc utility Me()thing
  2504.  
  2505.     Me returns the thing associated with the active agent. This can be
  2506.     a player character or a machine. Me can never return nil.
  2507.  
  2508. MeCharacter: utility
  2509. proc utility MeCharacter()character
  2510.  
  2511.     MeCharacter returns the character for an active player character.
  2512.     If the active agent is a machine, then MeCharacter returns the
  2513.     character of the owner of the active machine.
  2514.  
  2515. Mine: database
  2516. proc utility Mine(thing theThing)bool
  2517.  
  2518.     Mine returns 'true' if the passed thing is owned by the current
  2519.     effective player.
  2520.  
  2521. MOn: effects
  2522. proc utility MOn(thing who)bool
  2523.  
  2524.     MOn returns 'true' if the indicated client currently has music
  2525.     playing enabled. As of version 1.0, music is not implemented in
  2526.     the "MUD" client, so this function is irrelevant.
  2527.  
  2528. MoveSymbol: symbols
  2529. proc utility MoveSymbol(table fromTable, toTable; string name)bool
  2530.  
  2531.     MoveSymbol moves symbol 'name' from table 'fromTable' to table
  2532.     'toTable'. MoveSymbol will not move symbols to or from the
  2533.     Character or Builtin tables, and will not add a duplicate symbol
  2534.     to 'toTable'. Each table must either be the public table, or owned
  2535.     by the effective player, or the effective player must be SysAdmin.
  2536.  
  2537. MPlaySong: effects
  2538. proc utility MPlaySong(thing who; string name; int id)void
  2539.  
  2540.     MPlaySong starts the playing of a song in the indicated client.
  2541.     The song is loaded from "AmigaMUD:Music/<name>". If the indicated
  2542.     song cannot be found, then nothing is done, and the "not found"
  2543.     flag is set, and can be tested by 'IfFound'. 'id' is an identifier
  2544.     associated with the playing of the song, and will be given as the
  2545.     second parameter to a call to the character's "effectdone action"
  2546.     triggered when the song finishes playing or is aborted with
  2547.     'AbortEffect'. The first parameter will be 2 for a music effect.
  2548.     As of V1.0 of the "MUD" client, music playing is not implemented.
  2549.  
  2550. MVolume: effects
  2551. proc utility MVolume(thing who; int volume)void
  2552.  
  2553.     MVolume sets the volume for music that is played in the indicated
  2554.     client. The default volume is full volume, which is represented as
  2555.     10000; thus a value of 5000 is half volume.
  2556.  
  2557. NewCharacterPassword: utility
  2558. proc utility wizard NewCharacterPassword()void
  2559.  
  2560.     NewCharacterPassword triggers a sequence of events between the
  2561.     server and the client whereby the client is asked to enter and
  2562.     verify a new password. If verified, the new password is entered as
  2563.     the character's password.
  2564.  
  2565. NewCreationPassword: utility
  2566. proc utility NewCreationPassword()void
  2567.  
  2568.     NewCreationPassword triggers a sequence of events between the
  2569.     server and the client whereby the client is asked to enter and
  2570.     verify a new password. If verified, the new password is entered as
  2571.     the new character creation password. This builtin can only be
  2572.     called directly by SysAdmin. If the character creation password is
  2573.     empty, then no password is needed to create a new character. If
  2574.     the new password starts with an asterisk ('*'), then new
  2575.     characters cannot be created by clients, but must be manually
  2576.     created by SysAdmin, using 'CreateCharacter'.
  2577.  
  2578. Normal: utility
  2579. proc utility Normal()void
  2580.  
  2581.     Normal puts the active client into normal (non-wizard) mode, if it
  2582.     is not already in that mode. If the active character is a newly
  2583.     created one that has not yet connected, then the new character
  2584.     action is run for that character. Normal will fail at that point
  2585.     if the scenario does not have a handler proc for text input.
  2586.  
  2587. Note: utility
  2588. proc utility Note()void
  2589.  
  2590.     Note prints a copyright notice to the active client.
  2591.  
  2592. NPrint: output
  2593. proc utility NPrint(string str)void
  2594.  
  2595.     NPrint is much the same as 'Print', except that it will not print
  2596.     newlines. It will stop before any newline in the string that it is
  2597.     passed. NPrint prints a single newline at the end of the string.
  2598.     NPrint also temporarily sets the status of the active client to
  2599.     "wizard", so that no '@'s will appear in front of the output line.
  2600.     NPrint is used to print an arbitrarily retrieved string, in a way
  2601.     that doesn't unnecessarily include the leading '@'s, but in a way
  2602.     that precludes most "spoofing" by apprentices and wizards.
  2603.  
  2604. NukeClient: machine/character
  2605. proc utility NukeClient(character who)void
  2606.  
  2607.     NukeClient violently forces the indicated character out of the
  2608.     game. No attempt is made to nicely shut the character down by
  2609.     allowing the character's "inactive action" to run. This routine
  2610.     should be used only as a last resort, since it can leave things in
  2611.     a confused state.
  2612.  
  2613. OPrint: output
  2614. proc utility OPrint(string str)void
  2615.  
  2616.     OPrint prints the passed string to all clients in the same room
  2617.     (with the same location) as the active client, except the active
  2618.     client. If used from a machine, then the string is printed to all
  2619.     clients in the same room as the machine.
  2620.  
  2621. Owner: database
  2622. proc utility Owner(thing theThing)character
  2623.  
  2624.     Owner returns the character who owns the passed thing. Note that
  2625.     it is a character value that is returned, not that character's
  2626.     thing.
  2627.  
  2628. Parent: database
  2629. proc utility Parent(thing theThing)thing
  2630.  
  2631.     Parent returns the parent thing of the passed thing. The returned
  2632.     value can be nil if the thing has no parent. A thing's parent is
  2633.     the first in the chain of other things that it will inherit
  2634.     properties from. See also 'SetParent'.
  2635.  
  2636. Parse: parsing
  2637. proc utility Parse(grammar theGrammar; string sentence)int
  2638.  
  2639.     Parse is the starting point for the internal parsing capabilities
  2640.     of AmigaMUD. It is passed a grammar to parse with, and a string
  2641.     containing one or more commands to be parsed. The commands in the
  2642.     string are separated by periods or semicolons. Each command is
  2643.     assumed to start with a verb, and that verb is looked up in the
  2644.     grammar. If the verb is not found, then Parse will complain "I
  2645.     don't know the word XXX.\n" and will return without parsing any
  2646.     more sentences. Similar errors in handling the expected noun
  2647.     phrases for the verb also result in early termination. Parse
  2648.     returns the number of commands that were successfully parsed and
  2649.     executed. Note that early termination can also be triggered by the
  2650.     semantic code associated with the verbs. See the section on
  2651.     parsing in file "ProgConcepts.txt" for much more information.
  2652.  
  2653. PlaceCursor: effects
  2654. proc utility PlaceCursor(int x, y)void
  2655.  
  2656.     PlaceCursor instructs the "MUD" client program for the active
  2657.     client to place the cursor at position 'x', 'y'. If the cursor was
  2658.     already shown somewhere, then it is removed from that location,
  2659.     and the background imagery and icons replaced, before it is
  2660.     redrawn at the new location.
  2661.  
  2662. Pluralize: output
  2663. proc utility Pluralize(string str)string
  2664.  
  2665.     Pluralize uses simple checks to attempt to pluralize the passed
  2666.     string, and return the new result. The rules that Pluralize uses
  2667.     are:
  2668.  
  2669.     if the string ends in "y" then
  2670.         if there is a vowel before the "y", add "s"
  2671.         else replace the "y" with "ies"
  2672.     if the string ends in "x", "s", "i" or "o", add "es"
  2673.     otherwise, add "s"
  2674.  
  2675.     Note: the rules here have changed since the original releases.
  2676.  
  2677.     Examples:
  2678.     toy => toys, day => days, guy => guys
  2679.     fly => flies, try => tries
  2680.     box => boxes, kiss => kisses, potato => potatoes
  2681.     dog => dogs, bill => bills
  2682.  
  2683. Pose: machine/character
  2684. proc utility Pose(string alternateName, what)void
  2685.  
  2686.     If 'alternateName' is an empty string, the name of the active
  2687.     agent is used. That name, formatted, followed by a space and then
  2688.     string "what", is printed to all clients in the same room as the
  2689.     active agent. Also, the same string is passed to a generated call
  2690.     to the "poseAction" of all machines in the same room which have
  2691.     one. The order in which these things happen is not defined.
  2692.  
  2693. Print: output
  2694. proc utility Print(string str)void
  2695.  
  2696.     Print is the basic output function in AmigaMUD. The passed string
  2697.     is printed to the active client, if there is one. As with all
  2698.     other output to a client, the system will word-wrap and indent the
  2699.     output text into the output width of the client's display.
  2700.  
  2701. PrintAction: output
  2702. proc utility PrintAction(action theAction)void
  2703.  
  2704.     A textual, pretty-printed representation of the passed action is
  2705.     printed to the active client. The only current use for this
  2706.     builtin is in the standard scenario's building code, when the user
  2707.     asks to describe the direction checkers on an exit.
  2708.  
  2709. PrintNoAts: output
  2710. proc utility PrintNoAts(bool flag)bool
  2711.  
  2712.     This builtin allows the selection of whether or not '@'s are
  2713.     prepended to all output lines which contain text produced by
  2714.     AmigaMUD code written by apprentices rather than full wizards.
  2715.     This provision is made so that players who wish to be protected
  2716.     from possible "spoofing" by apprentices can be, while those who
  2717.     like such things as part of the game can allow it to be unmarked.
  2718.     In the standard scenario, this is used by the "ats" verb.
  2719.  
  2720. PrivateTable: utility
  2721. proc utility PrivateTable()table
  2722.  
  2723.     PrivateTable returns the private symbol table of the active
  2724.     client. Machines do not have symbol tables. The private symbol
  2725.     table, like the public symbol table and the Builtin table, is
  2726.     always "in-use".
  2727.  
  2728. PublicTable: utility
  2729. proc utility PublicTable()table
  2730.  
  2731.     PublicTable returns the public symbol table. The public symbol
  2732.     table, like the client's private symbol table and the Builtin
  2733.     table, is always "in-use".
  2734.  
  2735. QueryFile: effects
  2736. proc utility QueryFile(string path; action handler)void
  2737.  
  2738.     QueryFile can be used (with some difficulty) by a scenario to find
  2739.     out if the remote client has a given file under the AmigaMUD:
  2740.     directory tree. The 'path' should not contain the "AmigaMUD:"
  2741.     prefix - this is added on by the system. A request is sent off to
  2742.     the client to check for the file. The client checks, then sends a
  2743.     reply back. When the reply arrives, the server will call the
  2744.     supplied 'handler' action, passing a single bool parameter, which
  2745.     is 'true' if the file was found, and 'false' otherwise. This test
  2746.     can be used to make a quick check for an image or tiles file, so
  2747.     that the server can avoid sending over a large effect or set of
  2748.     tiles, which are not actually needed. Remember that the server can
  2749.     never wait for a client, thus this indirect way of getting an
  2750.     answer from the client must be used. The file querying capability
  2751.     exists only in the full 'MUD' client. GOn can be used to see if
  2752.     the user is running the full client.
  2753.  
  2754. Quit: utility
  2755. proc utility Quit()void
  2756.  
  2757.     Quit sets a flag on the active client, so that when the processing
  2758.     of the current message is complete, that client will be shut down
  2759.     and terminated. This is the standard way for a client to exit from
  2760.     the MUD via a command. Exiting in this way, like an exit request
  2761.     directly from a client (e.g. the close box in "MUD"), allows the
  2762.     client's "idle action" to be executed. In the standard scenario
  2763.     this action is used to do any area specific exit actions, such as
  2764.     moving the character out of SysAdmin's office; to make the current
  2765.     room dark if the character had the only source of light; to print
  2766.     a message indicating the character is exiting; and to clear some
  2767.     properties on the client thing.
  2768.  
  2769. Random: utility
  2770. proc utility Random(int range)int
  2771.  
  2772.     Random returns a random integer between zero and one less than the
  2773.     passed range. E.g. Random(2) will return 0 or 1. The random number
  2774.     seed used by Random can be accessed via 'GetSeed' and 'SetSeed'.
  2775.     The random number generator used is seeded by the time of day at
  2776.     the server, and is a version of the minimal standard generator as
  2777.     described in "Random Number Generators: Good Ones are Hard to
  2778.     Find" by Stephen K. Park and Keith W. Miller in Volume 31 Number
  2779.     10 of the Communications of the ACM.
  2780.  
  2781. RemHead: database
  2782. proc utility RemHead(<any list> theList)void
  2783.  
  2784.     RemHead removes the head (first) element from the passed list. The
  2785.     list will now have one less element then it had before, and all
  2786.     elements will be shuffled one position towards the front.
  2787.  
  2788. RemoveCursor: effects
  2789. proc utility RemoveCursor()void
  2790.  
  2791.     RemoveCursor removes the cursor from the active client's graphics
  2792.     window. The background and icons behind the cursor are put back as
  2793.     of when the cursor was drawn.
  2794.  
  2795. RemTail: database
  2796. proc utility RemTail(<any list> theList)void
  2797.  
  2798.     RemTail removes the tail (last) element from the passed list. The
  2799.     list will now have one less element then it had before, but all
  2800.     other elements are still at the same place as they were.
  2801.  
  2802. RenameSymbol: symbols
  2803. proc utility RenameSymbol(table theTable; string oldName, newName)bool
  2804.  
  2805.     RenameSymbol changes the name of symbol 'oldName' in table
  2806.     'theTable' to be 'newName'. The effective user must own the table
  2807.     or be SysAdmin, or the table must be the public table. 'oldName'
  2808.     must exist in the table, and 'newName' must not.
  2809.  
  2810. RunLimit: utility
  2811. proc utility RunLimit(int newValue)int
  2812.  
  2813.     RunLimit sets the execution time limit within the MUD to be the
  2814.     given number of seconds. The old limit is returned. MUDServ
  2815.     enforces this limit for the processing of each message from a
  2816.     client (and hence of the processing of each input line, keypad
  2817.     keypress, mouse action, effect completion, etc.) and for the
  2818.     processing resulting from a machine or client's 'After' code. If
  2819.     the limit is exceeded, the execution is aborted and MUDServ goes
  2820.     on to the next input message or 'After' event. Time spent in the
  2821.     database code flushing the cache does not count as execution time.
  2822.     This limit should be fairly large (I use 100 seconds) while
  2823.     compiling a large scenario, but should be smaller (I use 10
  2824.     seconds) during normal operation. An even smaller limit may be
  2825.     appropriate on faster processors.
  2826.  
  2827. Say: machine/character
  2828. proc utility Say(string alternateName, what)void
  2829.  
  2830.     If 'alternateName' is an empty string, then the name of the active
  2831.     agent is used. That name, formatted, followed by " says: ", and
  2832.     string "what" is printed to all clients in the same room as the
  2833.     active agent. Also, the same string is passed to a generated call
  2834.     to the "sayAction" of all machines in the same room which have
  2835.     one. The order in which these things happen is not defined. The
  2836.     standard scenario has a wrapper, 'DoSay', around Say, which checks
  2837.     for and calls a "sayChecker" in the current room, and which will
  2838.     optionally echo the say back to the active client.
  2839.  
  2840. ScanTable: symbols
  2841. proc utility wizard ScanTable(table theTable; action theAction)void
  2842.  
  2843.     The symbols in the table are scanned (in no defined order), and
  2844.     the name of each is passed as the parameter to a call to action
  2845.     'theAction'. This allows code to do something for each symbol in a
  2846.     table. In particular, the "Characters" table can be scanned to get
  2847.     the names of all characters in the MUD, active or inactive.
  2848.  
  2849. SelectName: parsing
  2850. proc utility SelectName(string names; int which)string
  2851.  
  2852.     SelectName returns a substring of 'names' which is the 'which'th
  2853.     internal-form name within it. Indexing starts at 0, and if the
  2854.     index is out of range, an empty string is returned. E.g.
  2855.  
  2856.     "dog;big.puppy;red.canine;large,ferocious" 0 => "dog;big"
  2857.     "dog;big.puppy;red.canine;large,ferocious" 1 => "puppy;red"
  2858.     "dog;big.puppy;red.canine;large,ferocious" 2 =>
  2859.         "canine;large,ferocious"
  2860.     "dog;big.puppy;red.canine;large,ferocious" 4 => ""
  2861.  
  2862.     Actually, SelectName simply returns the 'which'th period-separated
  2863.     substring of a string. SelectName is useful for extracting the
  2864.     name indicated by a successful 'MatchName' call.
  2865.  
  2866. SelectWord: parsing
  2867. proc utility SelectWord(string words; int which)string
  2868.  
  2869.     SelectWord returns the 'which'th comma- or period- separated
  2870.     substring of the passed 'words' string. E.g.
  2871.  
  2872.     "red,blue,green.yellow,cyan"    0 => "red"
  2873.     "red,blue,green.yellow,cyan"    1 => "blue"
  2874.     "red,blue,green.yellow,cyan"    2 => "green"
  2875.     "red,blue,green.yellow,cyan"    3 => "yellow"
  2876.     "red,blue,green.yellow,cyan"    4 => "cyan"
  2877.     "red,blue,green.yellow,cyan"    5 => ""
  2878.  
  2879. ServerVersion: utility
  2880. proc utility ServerVersion()int
  2881.  
  2882.     ServerVersion returns the version of the MUDServ server, as an
  2883.     integer. The integer is the actual version number times 10. E.g.
  2884.     for V0.7 of the server, ServerVersion returned 7, and for V1.0 it
  2885.     returns 10.
  2886.  
  2887. SetAgentLocation: machine/character
  2888. proc utility wizard SetAgentLocation(thing agent, where)void
  2889.  
  2890.     SetAgentLocation sets the location of the passed agent to be the
  2891.     passed thing. This can be used to "teleport" a player or machine
  2892.     to some other location. Note that other things would have to be
  2893.     done in a typical scenario. SetAgentLocation will only work on an
  2894.     active character - inactive characters are not agents.
  2895.  
  2896. SetButtonPen: effects
  2897. proc utility SetButtonPen(int which, pen)void
  2898.  
  2899.     SetButtonPen selects pen 'pen' of the graphics pens to be the
  2900.     'which'th button pen. The button pens are as follows:
  2901.  
  2902.     pen    default         use
  2903.     -------------------------------------------------
  2904.      0    1 - dark grey        background of letters
  2905.      1    9 - gold        letters
  2906.      2    2 - medium grey     outer border colour
  2907.      3    3 - light grey        middle border colour
  2908.      4    4 - white        inner border colour
  2909.      5    9 - gold        background of highlighted letters
  2910.      6    1 - dark grey        highlighted letters
  2911.  
  2912. SetCharacterActiveAction: machine/character
  2913. proc utility wizard SetCharacterActiveAction(action newAction)action
  2914.  
  2915.     SetCharacterActiveAction sets the action that is executed whenever
  2916.     the character becomes active, i.e. connects to the MUD after not
  2917.     being connected. It is NOT called when the character is first
  2918.     being initialized - the "new character action" set by
  2919.     'SetNewCharacterAction' is executed then, and that is when the
  2920.     "active action" is usually set up. The old "active action", if
  2921.     any, is returned. The "active action" is usually used to do
  2922.     something like a "look around" command to display graphics, etc.
  2923.     for the user, and to create a standard set of mouse-buttons. The
  2924.     action used must have no parameters and no result.
  2925.  
  2926. SetCharacterButtonAction: machine/character
  2927. proc utility wizard SetCharacterButtonAction(action newAction)action
  2928.  
  2929.     SetCharacterButtonAction sets the action that will be called by
  2930.     the system in response to a button-click in the Amiga "MUD" client
  2931.     program. The action must have one int parameter (the identifier
  2932.     of the button clicked) and no result. The old "button action", if
  2933.     any, is returned.
  2934.  
  2935. SetCharacterEffectDoneAction: machine/character
  2936. proc utility wizard SetCharacterEffectDoneAction(action newAction)action
  2937.  
  2938.     SetCharacterEffectDoneAction sets the action that is called by the
  2939.     system when an effect completes on the client for the active
  2940.     character, or is aborted using 'AbortEffect'. The action must have
  2941.     two int parameters. The first is a code indicating which kind of
  2942.     action is completing:
  2943.  
  2944.     0 => sound
  2945.     1 => speech
  2946.     2 => music
  2947.  
  2948.     The second parameter is the identifier for the particular effect
  2949.     that is completing (or has been aborted with 'AbortEffect'), as
  2950.     given when the effect was started. This routine can be used to
  2951.     create continuously-running or looping graphical, sound and
  2952.     musical effects. The old such action, if any, is returned.
  2953.  
  2954. SetCharacterIdleAction: machine/character
  2955. proc utility wizard SetCharacterIdleAction(action newAction)action
  2956.  
  2957.     SetCharacterIdleAction sets on the active character the action to
  2958.     be called by the system when the character leaves the game. The
  2959.     action must have no parameters and no result. Note that the action
  2960.     is not called if the client is forced out of the game with
  2961.     'NukeClient' (that is how to get rid of a client when its "idle
  2962.     action" goes into an infinite loop when there is a very long
  2963.     timeout in effect!) The "idle action" will often do things like
  2964.     taking the character out of single-occupancy areas like Questor's
  2965.     Office in the standard scenario, and other scenario-dependent
  2966.     character shutdown things. The previous "idle action" for the
  2967.     character, if any, is returned.
  2968.  
  2969. SetCharacterInputAction: machine/character
  2970. proc utility wizard SetCharacterInputAction(action newAction)action
  2971.  
  2972.     SetCharacterInputAction sets on the active character the action to
  2973.     be called by the system when the player running the character
  2974.     enters an input line when not in "wizard mode". The action must
  2975.     have one string parameter - the input line entered, and no result.
  2976.     The action will typically check for one or two special cases (like
  2977.     a leading " or :), and then pass most lines to the AmigaMUD
  2978.     'Parse' function for general parsing. The character's previous
  2979.     "input action", if any, is returned.
  2980.  
  2981. SetCharacterLocation: machine/character
  2982. proc utility SetCharacterLocation(character theCharacter;
  2983.     thing newLocation)void
  2984.  
  2985.     SetCharacterLocation sets the location of character 'theCharacter'
  2986.     to be the given thing. Unlike 'SetAgentLocation', this routine can
  2987.     be used on a character that is not currently active. It cannot,
  2988.     however, be used on a machine. See also: 'SetLocation'.
  2989.  
  2990. SetCharacterMouseDownAction: machine/character
  2991. proc utility wizard SetCharacterMouseDownAction(action newAction)action
  2992.  
  2993.     SetCharacterMouseDownAction sets on the active character the
  2994.     action that the system will call when the user clicks the left
  2995.     mouse button and releases it inside a defined rectangular "mouse
  2996.     region" set up with 'AddRegion'. The action must have 3 int
  2997.     parameters and no result. When called, it is passed the identifier
  2998.     of the region clicked in (supplied to 'AddRegion') and the x and y
  2999.     coordinates of the click relative to the top-left corner of the
  3000.     region. "mouse down" actions are used for things like the icon
  3001.     editor in the standard scenario. The previous "mouse down" action,
  3002.     if any, is returned.
  3003.  
  3004. SetCharacterRawKeyAction: machine/character
  3005. proc utility wizard SetCharacterRawKeyAction(action newAction)action
  3006.  
  3007.     SetCharacterRawKeyAction sets on the active character the action
  3008.     that the system will call when the user presses a numeric keypad
  3009.     key or other special key supported by the system. This allows the
  3010.     scenario to control the shortcut actions performed in response to
  3011.     those keypresses. The keycodes supported in this way are:
  3012.  
  3013.     scenario symbol   value (hex)    meaning
  3014.     -------------------------------------------
  3015.     KEY_HELP        0x0020    HELP key
  3016.     KEY_KP_UL        0x0001    keypad 7
  3017.     KEY_KP_U        0x0002    keypad 8
  3018.     KEY_KP_UR        0x0003    keypad 9
  3019.     KEY_KP_L        0x0004    keypad 4
  3020.     KEY_KP_C        0x0005    keypad 5
  3021.     KEY_KP_R        0x0006    keypad 6
  3022.     KEY_KP_DL        0x0007    keypad 1
  3023.     KEY_KP_D        0x0008    keypad 2
  3024.     KEY_KP_DR        0x0009    keypad 3
  3025.     KEY_KP_PLUS        0x000a    keypad +
  3026.     KEY_KP_MINUS        0x000b    keypad -
  3027.     
  3028.     The previous "rawkey action", if any, is returned.
  3029.  
  3030. SetContinue: utility
  3031. proc utility SetContinue(bool state)void
  3032.  
  3033.     SetContinue instructs the parser whether or not to allow the
  3034.     definition of actions that contain errors. If the state is set to
  3035.     'true', then such actions are defined and entered into the
  3036.     database. They cannot be executed, however. If the state is set to
  3037.     'false', then an error in defining an action (proc) prevents it
  3038.     from being entered into any symbol tables. The normal state will
  3039.     be 'false'. The 'true' state is useful when sourcing large source
  3040.     files so that an error in one function will not cause further
  3041.     errors, in functions which call the first, due to the first not
  3042.     being defined.
  3043.  
  3044. SetCursorPattern: effects
  3045. proc utility SetCursorPattern(list int newPattern)void
  3046.  
  3047.     SetCursorPattern sets the pattern to be used for the graphics
  3048.     cursor available in the graphics window. Like icons, the cursor,
  3049.     manipulated by 'PlaceCursor' and 'RemoveCursor', is a 16 pixel by
  3050.     16 pixel pattern in a single colour ('SetCursorPen'). The list of
  3051.     ints used to define the cursor must have exactly 8 elements (16 *
  3052.     16 / 32), even if the defined cursor is not fully 16 x 16. The
  3053.     cursor pattern is sent to the client, and will take effect
  3054.     immediately if the cursor is currently visible.
  3055.  
  3056. SetCursorPen: effects
  3057. proc utility SetCursorPen(int pen)void
  3058.  
  3059.     SetCursorPen selects the pen to be used for drawing the cursor in
  3060.     the graphics window. The pen is any of the graphics drawing pens.
  3061.     If the cursor is currently visible, it will be redrawn in the new
  3062.     colour. Note that neither SetCursorPen nor SetCursorPattern can
  3063.     directly affect a client other than the one for the active player.
  3064.     If needed, that can be accomplished using 'ForceAction'.
  3065.  
  3066. SetEffectiveTo: utility
  3067. proc utility SetEffectiveTo(character thePlayer)void
  3068.  
  3069.     SetEffectiveTo sets the "effective character", i.e. the one whose
  3070.     access rights are to be in effect, to 'thePlayer'. For obvious
  3071.     security reasons, only SysAdmin, or code written by SysAdmin, can
  3072.     use this function. In other words, the effective player can only
  3073.     be changed in this way if it is currently SysAdmin. The effective
  3074.     player is usually set automatically to the owner of any function
  3075.     called, if that function is not marked as 'utility'. The
  3076.     "effective status" is set to 'apprentice', giving only apprentice
  3077.     access rights.
  3078.  
  3079. SetEffectiveToNone: utility
  3080. proc utility SetEffectiveToNone()void
  3081.  
  3082.     SetEffectiveToNone sets the "effective character" to be no-one.
  3083.     This removes any access that was previously available via the
  3084.     effective player. Any wizard or apprentice can use this function,
  3085.     since it only removes access rights. The "effective status" is set
  3086.     to 'normal', giving neither apprentice nor wizard access rights.
  3087.  
  3088. SetEffectiveToReal: utility
  3089. proc utility SetEffectiveToReal()void
  3090.  
  3091.     SetEffectiveToReal sets the "effective character" back to the real
  3092.     character, i.e. the active character or the owner of the active
  3093.     machine. This is only allowed if the effective character is
  3094.     SysAdmin, since it involves the addition of access rights. The
  3095.     "effective status" is set to the status of the real player, giving
  3096.     whatever access that real player has.
  3097.  
  3098. SetIndent: output
  3099. proc utility wizard SetIndent(int newIndent)void
  3100.  
  3101.     SetIndent sets the current output indentation column. Subsequent
  3102.     lines of output, via 'Print', or any other mechanism, will be
  3103.     indented on the left by 'newIndent'. This is useful when printing
  3104.     lists of things, such as inventories, contents, etc. This, in
  3105.     combination with automatic word wrap and the ability to set the
  3106.     output width, almost makes AmigaMUD seem like a little text
  3107.     formatter. The programmer is advised to check that things are
  3108.     working out correctly, however, since things get complicated with
  3109.     text going to multiple clients, and with some clients desiring
  3110.     '@'s in front of any line containing apprentice-generated output.
  3111.     Because of the buffering of output text that is done (each use of
  3112.     'Print', etc. does not cause a separate message to the remote
  3113.     client), the effect of SetIndent will not take place until after a
  3114.     newline has been output. SetIndent should be called before
  3115.     outputting the newline that the indent is desired after. The
  3116.     indent amount is a very short-lived value. It is cleared at the
  3117.     end of each top-level handler call done by the server. See also:
  3118.     'SetPrefix'.
  3119.  
  3120. SetIt: utility
  3121. proc utility SetIt(thing theThing)void
  3122.  
  3123.     SetIt sets the value of the 'It' global variable, which is
  3124.     accessible via the 'It' builtin. See the description of 'It' for
  3125.     more details.
  3126.  
  3127. SetLocation: machine/character
  3128. proc utility wizard SetLocation(thing where)void
  3129.  
  3130.     SetLocation sets the location of the active character or machine
  3131.     to the given thing. This is the most common way of moving from one
  3132.     room to another (in conjunction with other scenario-specific
  3133.     things of course).
  3134.  
  3135. SetMachineActive: machine/character
  3136. proc utility SetMachineActive(thing machine; action theAction)action
  3137.  
  3138.     SetMachineActive sets, on the machine structure associated with
  3139.     'machine', the action that will be called by the system on behalf
  3140.     of that machine (with 'Me' set accordingly) when the server is
  3141.     restarted. This allows the machine to restart its periodic
  3142.     actions, and do any other system-startup initializations. The
  3143.     machine's previous "active action", if any, is returned.
  3144.  
  3145. SetMachineIdle: machine/character
  3146. proc utility SetMachineIdle(thing machine; action theAction)action
  3147.  
  3148.     SetMachineIdle sets, on the machine structure associated with
  3149.     'machine', the action that will be called by the system on behalf
  3150.     of that machine (with 'Me' set accordingly) when the server is
  3151.     being shut down. This allows the machine to do any shutdown
  3152.     activities that the scenario might need. The old "idle action", if
  3153.     any, is returned. The standard scenario uses this capability with
  3154.     the 'TimeKeeper' machine to subtract off the shutdown time from
  3155.     the wait time of each of its events.
  3156.  
  3157. SetMachineOther: machine/character
  3158. proc utility SetMachineOther(thing machine; action theAction)action
  3159.  
  3160.     SetMachineOther sets, on the machine structure associated with
  3161.     'machine', the action that will be called by the system whenever
  3162.     any agent in the same room as the machine calls 'OPrint',
  3163.     'ABPrint', 'Pose' or 'Say'. The text passed to those routines is
  3164.     passed to the action setup by SetMachineOther, and can then be
  3165.     processed by the machine. This allows the programmer to set up
  3166.     machines that watch what is happening in a given room, and which
  3167.     can then pass it on (e.g. a TV camera), record it, or perform
  3168.     actions based on it. Note that this facility, being quite general,
  3169.     is fairly expensive. Thus, programmers should seek less general,
  3170.     but cheaper alternatives wherever possible. Also note that it is
  3171.     unwise to use either of 'OPrint' or 'ABPrint' from inside a
  3172.     handler set up by SetMachineOther, as this can, if care is not
  3173.     taken, result in an infinite recursion loop.
  3174.  
  3175. SetMachinePose: machine/character
  3176. proc utility SetMachinePose(thing machine; action theAction)action
  3177.  
  3178.     SetMachinePose sets, on the machine structure associated with
  3179.     'machine', the action that will be called by the system whenever
  3180.     any agent does a 'Pose' in the room the machine is in. The action
  3181.     must have one string parameter, which will be the string passed to
  3182.     the 'Pose' builtin, with the posing agent's name prefixed. This
  3183.     allows a machine to respond to things like people waving, etc. The
  3184.     previous "pose action", if any, is returned. The standard scenario
  3185.     uses a "pose action" on Packrat to allow her to copy any pose that
  3186.     anyone nearby does.
  3187.  
  3188. SetMachinesActive: machine/character
  3189. proc utility SetMachinesActive(bool state)void
  3190.  
  3191.     SetMachinesActive controls whether or not machines are to be
  3192.     active at all in the scenario. A value of 'false' for 'state'
  3193.     makes machines inactive. This control is useful for debugging, and
  3194.     for controlling wayward machines.
  3195.  
  3196.     If this flag is 'false', then the time until a machine action is
  3197.     to happen is never decreased for any machines. Thus, if an action
  3198.     for a machine is scheduled for 2 seconds, it will never actually
  3199.     happen. However, if the flag is set to 'true', the action will
  3200.     again be scheduled for 2 seconds in the future. This provides a
  3201.     way to keep machines from executing, without stopping them
  3202.     completely, and without changing their timing relationships.
  3203.  
  3204. SetMachineSay: machine/character
  3205. proc utility SetMachineSay(thing machine; action theAction)action
  3206.  
  3207.     SetMachineSay sets, on the machine structure associated with
  3208.     'machine', the action that will be called by the system whenever
  3209.     any agent does a 'Say' in the room the machine is in. The action
  3210.     must have one string parameter, which will be the string passed to
  3211.     the 'Say' builtin, with the speaking agent's name prefixed. This
  3212.     allows machines to respond to spoken commands and comments. The
  3213.     previous "say action", if any, is returned. The standard scenario
  3214.     uses machine "say actions" in a number of places. 'SetSay' can be
  3215.     used to easily pull off the added parts of the string.
  3216.  
  3217. SetMachineWhisperMe: machine/character
  3218. proc utility SetMachineWhisperMe(thing machine; action theAction)action
  3219.  
  3220.     SetMachineWhisperMe sets, on the machine structure associated with
  3221.     'machine', the action that will be called by the system whenever
  3222.     any agent whispers directly to the machine. The action must have
  3223.     one string parameter, which will be the text whispered, preceeded
  3224.     by "<name> whispers:", where <name> is the formatted name of the
  3225.     agent doing the whispering. The previous "whisperme action", if
  3226.     any, is returned. 'SetWhisperMe' can be used to pull the string
  3227.     apart easily.
  3228.  
  3229. SetMachineWhisperOther: machine/character
  3230. proc utility SetMachineWhisperOther(thing machine; action theAction)action
  3231.  
  3232.     SetMachineWhisperOther sets, on the machine structure associated
  3233.     with 'machine', the action that will be called by the system
  3234.     whenever the machine "overhears" an agent whispering to another
  3235.     agent. The chance of the overhearing is controlled by the call to
  3236.     'Whisper' used. The action must have one string parameter and no
  3237.     result. The parameter will the the string whispered, preceeded by
  3238.     "<name1> whispers to <name2>:", where <name1> is the formatted
  3239.     name of the agent doing the whispering, and <name2> is the
  3240.     formatted name of who they are whispering to. The previous
  3241.     "whisperother action", if any, is returned. 'SetWhisperOther' can
  3242.     be used to pull apart the argument string.
  3243.  
  3244. SetMeString: utility
  3245. proc utility SetMeString(string name)void
  3246.  
  3247.     SetMeString sets the string that is used as the name of the active
  3248.     client when FindAgent is asked to find "self", "myself",
  3249.     "yourself" or "me". This string is set by the system to the name
  3250.     of the active client when any action is started on behalf of the
  3251.     client. Modifying the value is useful for some situations
  3252.     involving 'ForceAction'.
  3253.  
  3254. SetNewCharacterAction: machine/character
  3255. proc utility SetNewCharacterAction(action newAction)action
  3256.  
  3257.     SetNewCharacter sets the global action which is executed whenever
  3258.     a new character is initialized. This is done when a player first
  3259.     connects to that character in non-wizard mode, or when 'Normal' is
  3260.     first executed by the character. The old value of the
  3261.     "newcharacter action" is returned. This action will typically do
  3262.     things like initializing the character for properties that the
  3263.     scenario assumes all characters have, moving the character to the
  3264.     entry location, etc.
  3265.  
  3266. SetParent: database
  3267. proc utility SetParent(thing theThing, newParent)void
  3268.  
  3269.     SetParent sets the parent (in terms of property inheritance) of
  3270.     thing 'theThing' to be thing 'newParent'. This can be used in a
  3271.     scenario to change what an object or room inherits from, thus
  3272.     changing its basic nature. SetParent will not allow the setting if
  3273.     'newParent', or any of its parents, is equal to 'theThing'. This
  3274.     is to prevent the programmer from creating an inheritance loop in
  3275.     the system.
  3276.  
  3277. SetPrefix: utility
  3278. proc utility SetPrefix(string newPrefix)void
  3279.  
  3280.     SetPrefix sets a prefix which will be printed in front of output
  3281.     lines. The new prefix will appear before the next output line.
  3282.     Note that output lines can be caused by explicit newlines, or by
  3283.     the word wrapping of text that does not contain any newlines.
  3284.     There are three optional things that can be inserted at the front
  3285.     of output lines: an '@', a prefix, and an indent. They are
  3286.     inserted in that order. Note that any prefix is a very short-lived
  3287.     thing - it is cleared at the end of the current top-level call
  3288.     done by the server. They are not saved with the client structure,
  3289.     and are not saved on the character. Thus, code which desires a
  3290.     prefix in all or most places must set the prefix explicitly at the
  3291.     beginning of each handler call. See also: 'SetIndent'.
  3292.  
  3293. SetPrompt: utility
  3294. proc utility wizard SetPrompt(string prompt)string
  3295.  
  3296.     SetPrompt sets the prompt for the active client. The old prompt is
  3297.     returned. The default prompt is "input> ". Note that "wizard mode"
  3298.     has prompts of its own, not related to the character's prompt. The
  3299.     prompt will change immediately, unless there is currently a
  3300.     partial input line typed. The prompt associated with a character
  3301.     is saved in the database.
  3302.  
  3303. SetRemoteSysAdminOK: utility
  3304. proc utility SetRemoteSysAdminOK(bool state)void
  3305.  
  3306.     SetRemoteSysAdminOK sets whether or not the server will accept a
  3307.     login of SysAdmin via a remote connection. A connection via
  3308.     'MUDAgent' is always a remote connection, and a connection via
  3309.     'SMUD' is remote if the '-r' flag is given to 'SMUD'. The default
  3310.     is to not accept a remote SysAdmin connection, and it is highly
  3311.     recommended that you never change the setting. Doing so makes it
  3312.     possible for someone to learn or guess your SysAdmin password,
  3313.     which makes your entire system (not just AmigaMUD) wide open to
  3314.     that person.
  3315.  
  3316. SetSay: parsing
  3317. proc utility SetSay(string what)string
  3318.  
  3319.     SetSay is useful for interpreting a string passed to a machine
  3320.     "say action". It takes a string of the form "xxx says: yyy",
  3321.     returns "xxx" and puts "yyy" into the tail buffer, where it can be
  3322.     accessed with 'GetTail' and 'GetWord'.
  3323.  
  3324. SetSeed: utility
  3325. proc utility SetSeed(int newSeed)void
  3326.  
  3327.     SetSeed sets the seed for the server's random number generator.
  3328.     The value of the seed can be obtained via 'GetSeed'. Setting the
  3329.     seed allows for the generation of repeatable pseudo-random
  3330.     sequences, which can be used to reproduce a randomly generated
  3331.     area each time it is needed.
  3332.  
  3333. SetSingleUser: utility
  3334. proc utility SetSingleUser(bool state)void
  3335.  
  3336.     SetSingleUser sets a flag inside the database that controls
  3337.     whether the database represents a single-user "Adventure"-style
  3338.     game or a multi-user MUD. In single-user mode, the concept of
  3339.     "characters" does't really exist - when a client connects (only
  3340.     one is ever allowed at a time), no character name or password is
  3341.     required - the game goes right into handling user input. Note that
  3342.     because of the way MUDServ operates, the current state is always
  3343.     saved implicitly, and in order to make a saved position, the
  3344.     entire MUD database (MUD.data, MUD.index) must be backed up.
  3345.  
  3346. SetTail: parsing
  3347. proc utility SetTail(string str)void
  3348.  
  3349.     SetTail directly sets the value of the server's "tail" string.
  3350.     This string is set implicitly by a number of actions, including
  3351.     the parsing of a 'VerbTail' verb. The value of the string can be
  3352.     retrieved using 'GetTail', and individual words in it can be
  3353.     retrieved one at a time using 'GetWord'.
  3354.  
  3355. SetThingStatus: database
  3356. proc utility SetThingStatus(thing theThing; <thing status> status)void
  3357.  
  3358.     SetThingStatus sets the status of 'theThing' to 'status'. The
  3359.     "effective player" must own the thing, or the effective and real
  3360.     players must both be SysAdmin (i.e. SysAdmin is typing directly in
  3361.     wizard mode, or is running his own actions). The value of 'status'
  3362.     must be one of: 'ts_public', 'ts_private', 'ts_readonly', and
  3363.     'ts_wizard', as explained in previous documents.
  3364.  
  3365. SetWhisperMe: parsing
  3366. proc utility SetWhisperMe(string what)string
  3367.  
  3368.     SetWhisperMe is useful for interpreting a string passed to a
  3369.     machine "whisperme action". It takes a string of the form "xxx
  3370.     whispers: yyy", returns "xxx" and puts "yyy" into the tail buffer,
  3371.     where it can be accessed with 'GetTail' and 'GetWord'.
  3372.  
  3373. SetWhisperOther: parsing
  3374. proc utility SetWhisperOther(string what)string
  3375.  
  3376.     SetWhisperOther is useful for interpreting a string passed to a
  3377.     machine "whisperother action". It takes a string of the form "xxx
  3378.     whispers to yyy: zzz", returns "xxx" and puts "yyy zzz" into the
  3379.     tail buffer, where it can be accessed with 'GetWord' and
  3380.     'GetTail'.
  3381.  
  3382. ShowCharacter: utility
  3383. proc utility ShowCharacter(character who)void
  3384.  
  3385.     ShowCharacter prints to the active client the status of the
  3386.     indicated character. This includes the connection status, the
  3387.     character status (normal/apprentice/wizard), and an indication of
  3388.     whether or not the character is "new" (has executed the "newplayer
  3389.     action").
  3390.  
  3391. ShowCharacters: utility
  3392. proc utility ShowCharacters(bool longForm)int
  3393.  
  3394.     If 'longForm' is 'true', then ShowCharacters effectively calls
  3395.     'ShowCharacter' for each existing character. If 'longForm' is
  3396.     'false', then ShowCharacters prints just the names of all of the
  3397.     existing characters. Both lists are preceeded by "Existing
  3398.     characters as of " and the time and date. ShowCharacters returns
  3399.     the number of existing characters.
  3400.  
  3401. ShowClients: utility
  3402. proc utility ShowClients(bool longForm)int
  3403.  
  3404.     If 'longForm' is 'true' then ShowClients shows the name of all
  3405.     active clients, followed by their connection time and whether or
  3406.     not they are currently in "wizard mode". If 'longForm' is 'false',
  3407.     then ShowClients just shows the names of all active clients. Both
  3408.     forms are preceeded by "Active clients as of " and the current
  3409.     time and date. ShowClients returns the number of active clients.
  3410.  
  3411. ShowTable: symbols
  3412. proc utility ShowTable(table theTable)void
  3413.  
  3414.     ShowTable shows the symbols in the passed table. Only the names of
  3415.     the symbols are shown - 'DescribeSymbol' can be used to show the
  3416.     definition of a given symbol.
  3417.  
  3418. ShowWord: parsing
  3419. proc utility ShowWord(grammar theGrammar; string theWord)void
  3420.  
  3421.     ShowWord looks 'theWord' up in 'theGrammar' and prints, to the
  3422.     active client, the definition of that word. The output is one of:
  3423.  
  3424.     - not in grammar
  3425.     - code <n> {a separator word}
  3426.     - synonym of "xxx"
  3427.     - code <n> string tail verb => <action>
  3428.     - code <n> verb with alternatives:
  3429.         - no object
  3430.         - direct object
  3431.         - direct and indirect objects
  3432.         separator {<NONE> or "yyy"}
  3433.         => <action>
  3434.  
  3435. ShowWords: parsing
  3436. proc utility ShowWords(grammar theGrammar)void
  3437.  
  3438.     ShowWords prints, to the active client, the words in 'theGrammar'.
  3439.     The list is not sorted, but is in multiple columns. 'ShowWord' can
  3440.     be used to see the definition of a given word in the grammar.
  3441.  
  3442. ShutDown: utility
  3443. proc utility ShutDown(bool yesNo)bool
  3444.  
  3445.     ShutDown can be used by SysAdmin to set or clear the "shutdown
  3446.     flag". If this flag is set when the server reaches the state of
  3447.     having no clients, the server will shut itself down and exit.
  3448.  
  3449. SOn: effects
  3450. proc utility SOn(thing who)bool
  3451.  
  3452.     SOn returns 'true' if the indicated client ('who') has sound
  3453.     output enabled, and 'false' otherwise. A text-only client will
  3454.     always have all effects disabled.
  3455.  
  3456. SPlaySound: effects
  3457. proc utility SPlaySound(thing who; string name; int id)void
  3458.  
  3459.     SPlaySound instructs client 'who' to start playing an IFF 8SVX
  3460.     sound sample from "AmigaMUD:Sounds/<name>". The operation of the
  3461.     effect is given identifier 'id', and proceeds without the server
  3462.     or client waiting for it. When the sound is complete (or is
  3463.     aborted with 'AbortEffect'), the server will call the client's
  3464.     "effect done" action with parameters 0 and 'id'.
  3465.  
  3466. SPrint: output
  3467. proc utility SPrint(thing agent; string str)void
  3468.  
  3469.     SPrint prints string 'str' to client 'agent'. This is typically
  3470.     used when one character or machine is affecting another. As usual,
  3471.     the string will be word-wrapped into the client's display width.
  3472.  
  3473. StringReplace: utility
  3474. proc utility StringReplace(string s1; int pos; string s2)string
  3475.  
  3476.     StringReplace returns a string which is a copy of 's1', but with
  3477.     the characters starting at position 'pos' (zero origin) replaced
  3478.     by the characters of 's2'. If there is more of 's1' beyond the
  3479.     end of the 's2' replacement, it remains unchanged.
  3480.  
  3481. StringToAction: utility
  3482. proc utility StringToAction(string str)action
  3483.  
  3484.     StringToAction is one of the more powerful features of AmigaMUD.
  3485.     It takes a string, generated in whatever manner is needed, and
  3486.     attempts to parse and compile it into an action. The set of "in-
  3487.     use" tables controls the set of symbols that can be used, as
  3488.     usual. Any error messages generated as a result of the compilation
  3489.     will go to the active client (if any). If the compilation is
  3490.     successful, the newly created action is returned, else nil is
  3491.     returned. The standard scenario uses StringToAction to compile
  3492.     "builder actions" created by builders.
  3493.  
  3494. StringToInt: utility
  3495. proc utility StringToInt(string str)int
  3496.  
  3497.     StringToInt attempts to turn string 'str' into an integer value,
  3498.     which it returns. A leading '+' or '-' sign can be present. If the
  3499.     string cannot be decoded into a decimal integer, then a run-time
  3500.     error is generated. Note that 'StringToInt' simply stops at the
  3501.     first non-digit, as long as at least one digit is present.
  3502.  
  3503. StringToPosInt: utility
  3504. proc utility StringToPosInt(string str)int
  3505.  
  3506.     StringToPosInt is a safer alternative than 'StringToInt' for
  3507.     converting user input into an integer. It does not accept a '+' or
  3508.     '-' sign, but it will return -1 if the string it is passed does
  3509.     not start with a decimal digit.
  3510.  
  3511. Strip: utility
  3512. proc utility Strip(string st)string
  3513.  
  3514.     Strip will remove quotation marks (") from around a string and
  3515.     will expand escaped characters ('\n' and '\t') from the passed
  3516.     string, returning the processed result. The result is also left in
  3517.     the "tail buffer", where it can be accessed with 'GetWord'. If the
  3518.     string starts with a quotation mark, then that mark is stripped
  3519.     off, and any trailing mark is also stripped off, but internal
  3520.     marks are kept. If the first character of the string was not a
  3521.     quotation mark, then all marks are kept intact.
  3522.  
  3523. SubString: utility
  3524. proc utility SubString(string str; int start, length)string
  3525.  
  3526.     SubString returns a substring of 'str', starting at position
  3527.     'start' (zero origin) for length 'length'. If 'start' + 'length'
  3528.     is greater than the length of 'str', then the resulting substring
  3529.     will be cut short. SubString will only abort execution if either
  3530.     'start' or 'length' is less than zero.
  3531.  
  3532. SVolume: effects
  3533. proc utility SVolume(thing who; int volume)void
  3534.  
  3535.     SVolume sets the sound playback volume in client 'who'. 'volume'
  3536.     is a value from 0 - 10000, with, e.g. 5000 representing half of
  3537.     the full volume.
  3538.  
  3539. Synonym: parsing
  3540. proc utility Synonym(grammar theGrammar; string oldWord, newWord)void
  3541.  
  3542.     Synonym defines a synonym in 'theGrammar'. 'oldWord' is looked up
  3543.     in the grammar, and must be found, else a run-time error is
  3544.     produced. 'newWord', which must not exist in the grammar, is made
  3545.     to be a synonym of that word. Note that you cannot make a synonym
  3546.     of a synomym - you must make another synonym of the original word
  3547.     instead.
  3548.  
  3549. TextHeight: output
  3550. proc utility wizard TextHeight(int newHeight)int
  3551.  
  3552.     TextHeight sets the active client's text output height to
  3553.     'newHeight' lines of text, returning the old value. A client using
  3554.     the Amiga "MUD" program has the text height set to the height of
  3555.     the full text window, which will vary depending on overscan and
  3556.     PAL versus NTSC. For other clients, the default height is 23
  3557.     lines. The number of lines is useful for code which wants to
  3558.     paginate output, such as the email and news readers in the
  3559.     standard scenario. As a special case, if the passed height is 0,
  3560.     then the height is not changed, but is still returned.
  3561.  
  3562. TextWidth: output
  3563. proc utility wizard TextWidth(int newWidth)int
  3564.  
  3565.     TextWidth sets the active client's text output width to 'newWidth'
  3566.     columns, returning the old value. A client using the Amiga "MUD"
  3567.     program has the text width set to the width of the text window,
  3568.     which will vary depending on overscan. For other clients, the
  3569.     default width is 76 characters. The text output width is the width
  3570.     to which the server's output code will wrap output text going to
  3571.     the client. Note that the Amiga "MUD" client program will also
  3572.     wrap output text to its actual text window width, so making the
  3573.     client's text width value too large makes a real mess. As a
  3574.     special case, if the passed width is 0, then the width is not
  3575.     changed, but is still returned.
  3576.  
  3577. ThingCharacter: machine/character
  3578. proc utility ThingCharacter(thing theThing)character
  3579.  
  3580.     ThingCharacter returns the character associated with 'theThing',
  3581.     if there is one. If there isn't one, then nil is returned. The
  3582.     opposite conversion, from character to thing, is done by
  3583.     'CharacterThing'. Note that 'ThingCharacter' is quite a bit more
  3584.     expensive than 'CharacterThing', since it has to search for the
  3585.     associated character structure.
  3586.  
  3587. Time: utility
  3588. proc utility Time()int
  3589.  
  3590.     Time returns the current time in seconds, from some arbitrary
  3591.     start point, as an integer. This is useful for comparing when
  3592.     events happen, by storing the time value as the event happens.
  3593.  
  3594. Trace: utility
  3595. proc utility wizard Trace(int n)void
  3596.  
  3597.     Trace will add an entry to the server's trace buffer, titled "user
  3598.     trace", and with numerical value 'n'. This trace buffer is a
  3599.     circular buffer, currently of size 100 entries (although this may
  3600.     change in the future), in which the server records a history of
  3601.     recent events. This trace buffer is dumped out, latest event to
  3602.     earliest event, if the server aborts. The entire trace facility
  3603.     may be compiled out of the server in some future release.
  3604.  
  3605. Trim: utility
  3606. proc utility Trim(string str)string
  3607.  
  3608.     Trim returns a copy of its argument string, but with any leading
  3609.     and trailing spaces removed. Internal spaces are not altered.
  3610.  
  3611. TrueMe: utility
  3612. proc utility TrueMe()thing
  3613.  
  3614.     TrueMe returns the identity of the original character or machine
  3615.     for this execution. The use of 'ForceAction' will not change the
  3616.     value returned, unlike that returned from 'Me'. The standard
  3617.     scenario uses TrueMe from some of the Packrat code, to determine
  3618.     the identity of the player who instructs her to do something.
  3619.  
  3620. UnUseTable: symbols
  3621. proc utility UnUseTable(table theTable)bool
  3622.  
  3623.     UnUseTable removes 'theTable' from the set of "in-use" tables.
  3624.     Symbols defined in that table, and not in any other in-use table,
  3625.     will no longer be available for use when compiling. This is the
  3626.     same as the "unuse" command in wizard mode.
  3627.  
  3628.     Note: there is a minor bug in the AmigaMUD system relating to the
  3629.     inuse set of tables and the symbol cache in a client. Clients like
  3630.     "MUD" and "SMUD" can cache the meaning of symbols (see their
  3631.     documentation for how to enable or disable this caching), so that
  3632.     they do not have to ask MUDServ each time a symbol is referenced.
  3633.     When a table is "unused", all symbols in the table are "uncached"
  3634.     from the client. However, when a table is "used", it may contain
  3635.     symbols that are also contained in tables that are already in use.
  3636.     The order of table searches in MUDServ is not specified, so that
  3637.     it is possible that when looking for a symbol that has multiple
  3638.     definitions, MUDServ will find a different definition than one
  3639.     cached in the client. I don't currently plan to fix this "bug".
  3640.     So, you should be careful to never have tables in use such that
  3641.     multiple tables contain definitions for a given symbol.
  3642.  
  3643. UseTable: symbols
  3644. proc utility UseTable(table theTable)bool
  3645.  
  3646.     UseTable adds 'theTable' to the set of "in-use" tables. Symbols in
  3647.     the table will now be available for use when compiling. This is
  3648.     the same as the "use" command in wizard mode.
  3649.  
  3650. Verb: parsing
  3651. proc utility Verb()string
  3652.  
  3653.     Verb returns the string which the user entered as the verb for the
  3654.     current command. In the presence of synonyms for a verb, this
  3655.     allows the scenario code to know which form of a verb the user
  3656.     typed. This can be useful when making minor distinctions of
  3657.     meaning or usage.
  3658.  
  3659. Verb0: parsing
  3660. proc utility Verb0(grammar theGrammar; string theVerb; int separatorCode;
  3661.     action theAction)void
  3662.  
  3663.     Verb0 enters string 'theVerb' into grammer 'theGrammar' as a verb
  3664.     which takes no (0) objects (in the English language sense). If
  3665.     'separatorCode' is nonzero, then it is the code for a word which
  3666.     can be given with this verb in order to distinguish it from other
  3667.     possible uses of the same word as a verb. The AmigaMUD parser will
  3668.     call action 'theAction' with no parameters when it parses this
  3669.     verb/separator combination. The action should return a boolean
  3670.     value, with 'false' indicating that something has gone wrong, and
  3671.     any remaining commands on the input line should not be processed.
  3672.     Some examples:
  3673.  
  3674.     private proc goNorth()bool:
  3675.         if Here()@p_rNorth = nil then
  3676.         Print("You can't go that way.\n");
  3677.         false
  3678.         else
  3679.         SetLocation(Here()@p_rNorth);
  3680.         true
  3681.         fi
  3682.     corp;
  3683.     Verb0(G, "north", 0, goNorth).
  3684.     Synonym(G, "north", "n").
  3685.  
  3686.     private proc sitUp()bool:
  3687.         ...
  3688.     corp;
  3689.     Verb0(G, "sit", FindWord(G, "up"), sitUp).
  3690.  
  3691. Verb1: parsing
  3692. proc utility Verb1(grammar theGrammar; string theVerb; int separatorCode;
  3693.     action theAction)void
  3694.  
  3695.     Verb1 adds to grammar 'theGrammar' verb 'theVerb' which expects a
  3696.     direct object when it is used. 'separatorCode', if not zero, is a
  3697.     word which can be between the verb and its direct object noun-
  3698.     phrase, or after the noun-phrase. The AmigaMUD parser will
  3699.     automatically handle multiple noun phrases, separated by commas or
  3700.     "and"s, and will pass them, in internal "noun;adj,adj,..." form,
  3701.     in turn to action 'theAction'. The action should return a bool,
  3702.     with 'false' indicating that some error has occurred, and no more
  3703.     calls to it should be made for this command, and that no more
  3704.     commands from the current input line should be processed. It is
  3705.     possible for 'theAction' to be called with an empty string if the
  3706.     verb is used by itself, and no object-less variant of that verb
  3707.     exists. Examples:
  3708.  
  3709.     private proc pickUp(string what)bool:
  3710.         status st;
  3711.         thing th;
  3712.  
  3713.         if what = "" then
  3714.         Print("Pick up what?\n");
  3715.         false
  3716.         else
  3717.         st := FindName(Here()@p_rContents, what);
  3718.         if st = continue then
  3719.             Print(FormatName(what) + " is ambiguous.\n");
  3720.             false
  3721.         elif st = fail then
  3722.             Print("There is no " + FormatName(what) + " here.\n");
  3723.             false
  3724.         else
  3725.             th := FindResult();
  3726.             AddTail(Me()@p_pCarrying, th);
  3727.             DelElement(Here()@p_rContents, th);
  3728.             Print(FormatName(what) + " picked up.\n");
  3729.             true
  3730.         fi
  3731.         fi
  3732.     corp;
  3733.     Verb1(G, "pick", FindWord(G, "up"), pickUp).
  3734.     Verb1(G, "take", 0, pickUp).
  3735.  
  3736.     Note that it is important to do the 'AddTail' before the
  3737.     'DelElement', so that if there are no other references to the
  3738.     object, it doesn't get deleted by the database code. Assume the
  3739.     player is in a room containing:
  3740.  
  3741.     small whisk broom
  3742.     straw broom
  3743.     pewter mug
  3744.     brass bell
  3745.     large red ball
  3746.  
  3747.     then, the following commands should produce:
  3748.  
  3749.     pick up the pewter mug
  3750.         -> pewter mug picked up.
  3751.     pick the basket up.
  3752.         -> There is no basket here.
  3753.     take
  3754.         -> Pick up what?
  3755.     Pick the broom up.
  3756.         -> broom is ambiguous.
  3757.     Take small broom, straw broom and the large red ball.
  3758.         -> small whisk broom picked up.
  3759.         -> straw broom picked up.
  3760.         -> large red ball picked up.
  3761.     Pick up the brass bell and mug.
  3762.         -> brass bell picked up.
  3763.         -> pewter mug picked up.
  3764.  
  3765. Verb2: parsing
  3766. proc utility Verb2(grammar theGrammar; string theVerb; int separatorCode;
  3767.     action theAction)void
  3768.  
  3769.     Verb2 adds to 'theGrammar' verb 'theVerb' as a verb which takes
  3770.     both a direct object and an indirect object. 'separatorCode' must
  3771.     be nonzero, and the word it is the code for (or a synonym) must be
  3772.     present in an input command that matches the verb. The separator
  3773.     word separates the direct object noun-phrase from the indirect
  3774.     object noun-phrase, as in "Put the marble INTO the bag.".
  3775.     'theAction' is an action which the parser will call to handle the
  3776.     verb. It will be passed two strings - the internal form of the
  3777.     direct object, and the internal form of the indirect object. The
  3778.     AmigaMUD parser will automatically handle input commands with
  3779.     multiple direct objects, separated by commas or "and"s and will
  3780.     call the action sequentially with them and the single indirect
  3781.     object. If no objects of either kind are given, the parser will
  3782.     complain with "<verb> who/what <separator> who/what?". If a direct
  3783.     object is given, but no indirect object, then the complaint will
  3784.     be of the form "<verb> <direct object> <separator> who/what?". If
  3785.     an indirect object but no direct object is given, then the parser
  3786.     will complain "<verb> who/what <separator> <indirect object>?".
  3787.     Thus, a Verb2 handler does not have to worry about handling empty
  3788.     strings. The handler returns a bool value, with 'false' indicating
  3789.     that something has gone wrong, and the parser should not call it
  3790.     for any further objects in this command, and any further commands
  3791.     in the current input line should also be cancelled. An example:
  3792.  
  3793.     private proc doPutIn(string itemRaw, containerRaw)bool:
  3794.     thing item, container;
  3795.     string itemName, containerName;
  3796.     status st;
  3797.  
  3798.     itemName := FormatName(itemRaw);
  3799.     containerName := FormatName(containerRaw);
  3800.     st := MatchName(Me()@p_pCarrying, itemRaw);
  3801.     if st = continue then
  3802.         Print(Capitalize(itemName) + " is ambiguous.\n");
  3803.         false
  3804.     elif st = fail then
  3805.         Print("You have no " + itemName + ".\n");
  3806.         false
  3807.     else
  3808.         item := FindResult();
  3809.         st := FindName(Me()@p_pCarrying, containerRaw);
  3810.         if st = continue then
  3811.         Print(Capitalize(containerName) + " is ambiguous.\n");
  3812.         false
  3813.         elif st = fail then
  3814.         Print("You have no " + containerName + ".\n");
  3815.         false
  3816.         else
  3817.         container := FindResult();
  3818.         if container@p_oContents = nil then
  3819.             Print("You can't put things into the " +
  3820.             containerName + ".\n");
  3821.             false
  3822.         else
  3823.             AddTail(container@p_oContents, item);
  3824.             DelElement(Me()@p_pCarrying, item);
  3825.             Print("You put the " + itemName + " into the " +
  3826.             containerName + ".\n");
  3827.             true
  3828.         fi
  3829.         fi
  3830.     fi
  3831.     corp;
  3832.     Verb2(G, "put", FindWord(G, "in"), doPutIn).
  3833.     Verb2(G, "put", FindWord(G, "into"), doPutIn).
  3834.     Synonym(G, "put", "place").
  3835.  
  3836.     Assume the player is carrying:
  3837.  
  3838.     small whisk broom
  3839.     straw broom
  3840.     pewter mug
  3841.     brass bell
  3842.     large red ball
  3843.     canvas sack
  3844.  
  3845.     then, the following commands should produce:
  3846.  
  3847.     put mug in sack
  3848.         -> You put the pewter mug into the canvas sack.
  3849.     Place the large red ball into the brass bell.
  3850.         -> You can't put things into the brass bell.
  3851.     put broom in sack
  3852.         -> Broom is ambiguous.
  3853.     place the bell into broom
  3854.         -> Broom is ambiguous.
  3855.     put bell, ball and whisk broom into sack
  3856.         -> You put the brass bell into the canvas sack.
  3857.         -> You put the large red ball into the canvas sack.
  3858.         -> You put the small whisk broom into the canvas sack.
  3859.  
  3860. VerbTail: parsing
  3861. proc utility VerbTail(grammar theGrammar; string theVerb;
  3862.     action theAction)void
  3863.  
  3864.     VerbTail adds verb 'theVerb' to grammar 'theGrammar' as a verb
  3865.     which is simply given the rest of the command to interpret as it
  3866.     sees fit. 'theAction' must have no parameters and return a bool
  3867.     result, with 'false' meaning that any further commands in the
  3868.     current input line should be skipped. When 'theAction' is called,
  3869.     the rest of the command will be in the "tail buffer", where it can
  3870.     be accessed using 'GetWord' and 'GetTail'. VerbTail verbs are used
  3871.     to handle verb forms which do not fit into the Verb0, Verb1 or
  3872.     Verb2 formats. The standard scenario uses VerbTail forms for many
  3873.     of the building commands (and the build command itself), since
  3874.     their formats do not involve noun-phrases at all. An example:
  3875.  
  3876.     private proc doTell()bool:
  3877.         string name, word;
  3878.         thing who;
  3879.  
  3880.         name := GetWord();
  3881.         if name = "" then
  3882.         Print("Tell who to what?\n");
  3883.         false
  3884.         else
  3885.         who := FindAgent(name);
  3886.         if who = nil then
  3887.             Print("There is no-one here by that name.\n");
  3888.             false
  3889.         else
  3890.             word := GetWord();
  3891.             if word == "to" then
  3892.             Say(name + "," + GetTail());
  3893.             else
  3894.             Say(name + "," + word + " " + GetTail());
  3895.             fi;
  3896.             true
  3897.         fi
  3898.         fi
  3899.     corp;
  3900.     VerbTail(G, "tell", doTell).
  3901.     Synonym(G, "tell", "instruct").
  3902.  
  3903.     This makes the form "tell xxx [to] yyy" an alternate way to try to
  3904.     speak commands to others in the room. The following inputs could
  3905.     result in the given spoken output or complaints:
  3906.  
  3907.     tell SysAdmin to go away
  3908.         -> "SysAdmin, go away
  3909.     tell
  3910.         -> Tell who to what?
  3911.     tell Furklewitz to snybuld the whulsyp.
  3912.         -> There is no-one here by that name.
  3913.     Instruct SysAdmin go north.
  3914.         -> "SysAdmin, go north
  3915.  
  3916. VNarrate: effects
  3917. proc utility VNarrate(thing who; string phonemes; int id)void
  3918.  
  3919.     VNarrate instructs the specified client to use its narrator.device
  3920.     to speak the given phoneme sequence. If that client doesn't have
  3921.     the device, then nothing happens except a small error comment in
  3922.     the client's text window. This will only happen if the client has
  3923.     voice output enabled, however. 'id' is supplied as an identifier
  3924.     for this effect. When the effect completes, or is aborted, the
  3925.     system will call the character's "effects done" action, if any,
  3926.     passing it the values 1 and 'id'. See the Amiga manuals for a
  3927.     description of the format of a phoneme sequence. Phoneme sequences
  3928.     can be produced by using the 'VTranslate' builtin, provided the
  3929.     server is running on a system containing 'translator.library' in
  3930.     its LIBS: directory. For example:
  3931.  
  3932.     define tp_mall proc bankSay()status:
  3933.         if VOn(nil) then
  3934.         VParams(nil, 150, 120, 0, 0, 64);
  3935.         VNarrate(nil,
  3936.             "WEH5LKAHM KAH4STAHMER. DIH4PAAZIHT MAH4NIY TUWDEY1.",
  3937.             BANK_SPEECH_ID);
  3938.         VReset(nil);
  3939.         fi;
  3940.         continue
  3941.     corp;
  3942.  
  3943. VOn: effects
  3944. proc utility VOn(thing who)bool
  3945.  
  3946.     VOn returns 'true' if the specified client can accept voice
  3947.     output, and that feature has not been disabled by the user. Note
  3948.     that the presence of 'narrator.device' is NOT checked.
  3949.  
  3950. VParams: effects
  3951. proc utility VParams(thing who; int rate, pitch, mode, sex, volume)void
  3952.  
  3953.     VParams sets the parameters for voice output on the specified
  3954.     client. These parameters are only the old, pre 2.0 'narrator.
  3955.     device' parameters, and are:
  3956.  
  3957.     rate - the speed of the speech, default 150
  3958.     pitch - the pitch of the speech, default 110
  3959.     mode - the mode (natural = 0, robotic = 1), default natural
  3960.     sex - the speaker sex (male = 0, female = 1), default male
  3961.     volume - the volume of the speech, with 64 being full volume
  3962.  
  3963. VReset: effects
  3964. proc utility VReset(thing who)void
  3965.  
  3966.     VReset instructs the specified client to reset its voice
  3967.     parameters to the default values. See 'VParams' for those values.
  3968.  
  3969. VSpeak: effects
  3970. proc utility VSpeak(thing who; string words; int id)void
  3971.  
  3972.     VSpeak instructs the specified client to speak the given English
  3973.     text. The text is translated to phonemes in the server, and will
  3974.     thus fail if the server does not have "LIBS:translator.library".
  3975.     The speaking is given effects identifier 'id', and the system will
  3976.     arrange to call the character's "effects done" action with
  3977.     parameters 1 and 'id' when it completes or is aborted. No speech
  3978.     will be produced if the client does not have "narrator.device"
  3979.     available. Example:
  3980.  
  3981.     VSpeak(CharacterThing(Character("SysAdmin")),
  3982.         "Hey wimp! Your mother wears army boots!", 1234).
  3983.  
  3984. VTranslate: effects
  3985. proc utility VTranslate(string words)string
  3986.  
  3987.     VTranslate translates English text string 'words' into a phoneme
  3988.     sequence, which it returns. If the server does not have access to
  3989.     "LIBS:translator.library", then an empty string is returned.
  3990.     Output phoneme sequences are restricted to 999 characters.
  3991.  
  3992. VVolume: effects
  3993. proc utility VVolume(thing who; int volume)void
  3994.  
  3995.     VVolume sets the overall speech volume for the given client. A
  3996.     value of 10000 is full volume, 5000 is half volume, etc. This
  3997.     value is a long-term value, and is used to scale any individual
  3998.     volume set via 'VParams'.
  3999.  
  4000. Whisper: machine/character
  4001. proc utility Whisper(string alternateName, what; thing who;
  4002.     int percent)bool
  4003.  
  4004.     Whisper is used to attempt to whisper to a specific other agent in
  4005.     the same room as the active one. 'what' is what is to be
  4006.     whispered, 'who' is who to whisper it to, and 'percent' is the
  4007.     likelihood that any other agent in the room will overhear the
  4008.     whisper (evaluated once for each other agent in the room). If
  4009.     'who' is a player, they will see: "<name> whispers: <what>", where
  4010.     <name> is either 'alternateName', or the name of the active agent
  4011.     if 'alternateName' is an empty string. If 'who' is a machine, then
  4012.     that machine's "whisperme action", if any, is called with a string
  4013.     of the same format. If 'percent' is greater than zero then each
  4014.     other character or machine in the same room may overhear the
  4015.     whisper ('percent' = 50 gives a 50 percent chance, etc.). Players
  4016.     will see a message of the form "<name> whispers to <who-name>: <
  4017.     what>". Machines will have their "whisperother action", if any,
  4018.     called with a string of that form. For example, if player "Fred"
  4019.     whispers to player "Joe" the string "help me fool sam", then Joe
  4020.     will see:
  4021.  
  4022.     Fred whispers: help me fool sam
  4023.  
  4024.     and any overhearer will see:
  4025.  
  4026.     Fred whispers to Joe: help me fool sam
  4027.  
  4028. WhoName: parsing
  4029. proc utility WhoName()string
  4030.  
  4031.     WhoName returns the internal form of the indirect object given by
  4032.     the user for a Verb2 verb. This can be used for special checks for
  4033.     particular adjectives, etc. See also: 'ItName'.
  4034.  
  4035. WizardMode: utility
  4036. proc utility WizardMode()bool
  4037.  
  4038.     WizardMode attempts to put the active client into "wizard mode",
  4039.     where input lines go directly to the AmigaMUD programming language
  4040.     parser, rather than to the character's "input action". The attempt
  4041.     will fail (silently) if the active agent is a machine, or if the
  4042.     active client is not enabled for wizarding (has status normal), or
  4043.     if the client program in use is not capable of going into wizard
  4044.     mode. There currently aren't any such client programs, but it is
  4045.     easier to produce a client for a machine other than the Amiga if
  4046.     the wizard-mode stuff (programming language parsing, etc.) can be
  4047.     left out.
  4048.  
  4049. Word: parsing
  4050. proc utility Word(grammar theGrammar; string theWord)int
  4051.  
  4052.     Word adds word 'theWord' to grammar 'theGrammar'. The word is not
  4053.     a verb, but is available for use as a "separator word" with a
  4054.     verb, or for whatever other use is needed. The identifying code
  4055.     for the word is returned. If the word cannot be added to the
  4056.     grammar, then 0 is returned.
  4057.