Inform - Support - Source

Back to List

Inventory
Complete

Plain
Coloured
Gaudy

Browsing verblibm.h

This is the complete source code of the example game verblibm.inf.

0001  ! ----------------------------------------------------------------------------
0002  !  VERBLIBM:  Core of standard verbs library.
0003  !
0004  !  Supplied for use with Inform 6                         Serial number 991113
0005  !                                                                 Release 6/10
0006  !  (c) Graham Nelson 1993, 1994, 1995, 1996, 1997, 1998, 1999
0007  !      but freely usable (see manuals)
0008  ! ----------------------------------------------------------------------------
0009   
0010  #IFDEF MODULE_MODE;
0011  Constant DEBUG;
0012  Constant Grammar__Version2;
0013  Include "linklpa";
0014  Include "linklv";
0015  #ENDIF;
0016   
0017  System_file;
0018   
0019  ! ----------------------------------------------------------------------------
0020   
0021  [ Banner i;
0022     if (Story ~= 0)
0023     {
0024  #IFV5; style bold; #ENDIF;
0025     print (string) Story;
0026  #IFV5; style roman; #ENDIF;
0027     }
0028     if (Headline ~= 0)
0029         print (string) Headline;
0030     print "Release ", (0-->1) & $03ff, " / Serial number ";
0031     for (i=18:i<24:i++) print (char) 0->i;
0032     print " / Inform v"; inversion;
0033     print " Library ", (string) LibRelease, " ";
0034  #ifdef STRICT_MODE;
0035     print "S";
0036  #endif;
0037  #ifdef INFIX;
0038     print "X";
0039  #ifnot;
0040  #ifdef DEBUG;
0041     print "D";
0042  #endif;
0043  #endif;
0044     new_line;
0045  ];
0046   
0047  [ VersionSub;
0048    Banner();
0049    if (standard_interpreter > 0)
0050        print "Standard interpreter ",
0051            standard_interpreter/256, ".", standard_interpreter%256,
0052            " (", 0->$1e, (char) 0->$1f, ") / ";
0053    else print "Interpreter ", 0->$1e, " Version ", (char) 0->$1f, " / ";
0054    print "Library serial number ", (string) LibSerial, "^";
0055  #IFDEF LanguageVersion;
0056    print (string) LanguageVersion, "^";
0057  #ENDIF;
0058  ];
0059   
0060  [ RunTimeError n p1 p2;
0061  #IFDEF DEBUG;
0062    print "** Library error ", n, " (", p1, ",", p2, ") **^** ";
0063    switch(n)
0064    {   1: print "preposition not found (this should not occur)";
0065        2: print "Property value not routine or string: ~",
0066                 (property) p2, "~ of ~", (name) p1, "~ (", p1, ")";
0067        3: print "Entry in property list not routine or string: ~",
0068                 (property) p2, "~ list of ~", (name) p1, "~ (", p1, ")";
0069        4: print "Too many timers/daemons are active simultaneously.  The
0070                  limit is the library constant MAX_TIMERS (currently ",
0071                  MAX_TIMERS, ") and should be increased";
0072        5: print "Object ~", (name) p1, "~ has no ~time_left~ property";
0073        7: print "The object ~", (name) p1, "~ can only be used as a player
0074                  object if it has the ~number~ property";
0075        8: print "Attempt to take random entry from an empty table array";
0076        9: print p1, " is not a valid direction property number";
0077        10: print "The player-object is outside the object tree";
0078        11: print "The room ~", (name) p1, "~ has no ~description~ property";
0079        12: print "Tried to set a non-existent pronoun using SetPronoun";
0080        13: print "A 'topic' token can only be followed by a preposition";
0081        default: print "(unexplained)";
0082    }
0083    " **";
0084  #IFNOT;
0085    "** Library error ", n, " (", p1, ",", p2, ") **";
0086  #ENDIF;
0087  ];
0088   
0089  ! ----------------------------------------------------------------------------
0090  !  The WriteListFrom routine, a flexible object-lister taking care of
0091  !  plurals, inventory information, various formats and so on.  This is used
0092  !  by everything in the library which ever wants to list anything.
0093  !
0094  !  If there were no objects to list, it prints nothing and returns false;
0095  !  otherwise it returns true.
0096  !
0097  !  o is the object, and style is a bitmap, whose bits are given by:
0098  ! ----------------------------------------------------------------------------
0099   
0100  Constant NEWLINE_BIT    1;    !  New-line after each entry
0101  Constant INDENT_BIT     2;    !  Indent each entry by depth
0102  Constant FULLINV_BIT    4;    !  Full inventory information after entry
0103  Constant ENGLISH_BIT    8;    !  English sentence style, with commas and and
0104  Constant RECURSE_BIT   16;    !  Recurse downwards with usual rules
0105  Constant ALWAYS_BIT    32;    !  Always recurse downwards
0106  Constant TERSE_BIT     64;    !  More terse English style
0107  Constant PARTINV_BIT  128;    !  Only brief inventory information after entry
0108  Constant DEFART_BIT   256;    !  Use the definite article in list
0109  Constant WORKFLAG_BIT 512;    !  At top level (only), only list objects
0110                                !  which have the "workflag" attribute
0111  Constant ISARE_BIT   1024;    !  Print " is" or " are" before list
0112  Constant CONCEAL_BIT 2048;    !  Omit objects with "concealed" or "scenery":
0113                                !  if WORKFLAG_BIT also set, then does _not_
0114                                !  apply at top level, but does lower down
0115  Constant NOARTICLE_BIT 4096;  !  Print no articles, definite or not
0116   
0117  [ NextEntry o odepth;
0118    for(::)
0119    {   o=sibling(o);
0120        if (o==0) return 0;
0121        if (lt_value ~=0 && o.list_together~=lt_value) continue;
0122        if (c_style & WORKFLAG_BIT ~= 0 && odepth==0 && o hasnt workflag)
0123            continue;
0124        if (c_style & CONCEAL_BIT ~= 0 && (o has concealed || o has scenery))
0125            continue;
0126        return o;
0127    }
0128  ];
0129   
0130  [ WillRecurs o;
0131    if (c_style & ALWAYS_BIT ~= 0) rtrue;
0132    if (c_style & RECURSE_BIT == 0) rfalse;
0133    if (o has transparent
0134        || o has supporter
0135        || (o has container && o has open)) rtrue;
0136    rfalse;
0137  ];
0138   
0139  [ ListEqual o1 o2;
0140    if (child(o1)~=0 && WillRecurs(o1)~=0) rfalse;
0141    if (child(o2)~=0 && WillRecurs(o2)~=0) rfalse;
0142   
0143    if (c_style & (FULLINV_BIT + PARTINV_BIT) ~= 0)
0144    {   if ((o1 hasnt worn && o2 has worn)
0145            || (o2 hasnt worn && o1 has worn)) rfalse;
0146        if ((o1 hasnt light && o2 has light)
0147            || (o2 hasnt light && o1 has light)) rfalse;
0148    }
0149   
0150    return Identical(o1,o2);
0151  ];
0152   
0153  [ SortTogether obj value;
0154  !  print "Sorting together possessions of ",
0155  !         (object) obj, " by value ", value, "^";
0156  !  for (x=child(obj):x~=0:x=sibling(x))
0157  !      print (the) x, " no: ", x, " lt: ", x.list_together, "^";
0158    while (child(obj)~=0)
0159    {   if (child(obj).list_together~=value) move child(obj) to out_obj;
0160        else move child(obj) to in_obj;
0161    }
0162    while (child(in_obj)~=0)
0163        move child(in_obj) to obj;
0164    while (child(out_obj)~=0)
0165        move child(out_obj) to obj;
0166  ];
0167   
0168  [ SortOutList obj i k l;
0169  !  print "^^Sorting out list from ", (name) obj, "^  ";
0170  !  for (i=child(location):i~=0:i=sibling(i))
0171  !      print (name) i, " --> ";
0172  !  new_line;
0173   .AP_SOL;
0174    for (i=obj:i~=0:i=sibling(i))
0175    {   k=i.list_together;
0176        if (k~=0)
0177        {   ! print "Scanning ", (name) i, " with lt=", k, "^";
0178            for (i=sibling(i):i~=0 && i.list_together==k:) i=sibling(i);
0179                if (i==0) rfalse;
0180            !print "First not in block is ", (name) i,
0181            ! " with lt=", i.list_together, "^";
0182            for (l=sibling(i):l~=0:l=sibling(l))
0183                if (l.list_together==k)
0184                {   SortTogether(parent(obj), k);
0185  !  print "^^After ST:^  ";
0186  !  for (i=child(location):i~=0:i=sibling(i))
0187  !      print (name) i, " --> ";
0188  !  new_line;
0189                    obj = child(parent(obj));
0190                    jump AP_SOL;
0191                }
0192        }
0193    }
0194  ];
0195   
0196  [ Print__Spaces n;         ! To avoid a bug occurring in Inform 6.01 to 6.10
0197    if (n==0) return; spaces n; ];
0198   
0199  [ WriteListFrom o style depth;
0200    if (o==child(parent(o)))
0201    {   SortOutList(o); o=child(parent(o)); }
0202    c_style=style;
0203    wlf_indent=0; WriteListR(o,depth);
0204    rtrue;
0205  ];
0206   
0207  [ WriteListR o depth stack_pointer  classes_p sizes_p i j k k2 l m n q senc mr;
0208   
0209    if (depth>0 && o==child(parent(o)))
0210    {   SortOutList(o); o=child(parent(o)); }
0211    for (::)
0212    {   if (o==0) rfalse;
0213        if (c_style & WORKFLAG_BIT ~= 0 && depth==0 && o hasnt workflag)
0214        {   o = sibling(o); continue; }
0215        if (c_style & CONCEAL_BIT ~= 0
0216            && (o has concealed || o has scenery))
0217        {   o=sibling(o); continue; }
0218        break;
0219    }
0220   
0221    classes_p = match_classes + stack_pointer;
0222    sizes_p   = match_list + stack_pointer;
0223   
0224    for (i=o,j=0:i~=0 && (j+stack_pointer)<128:i=NextEntry(i,depth),j++)
0225    {   classes_p->j=0;
0226        if (i.plural~=0) k++;
0227    }
0228   
0229    if (c_style & ISARE_BIT ~= 0)
0230    {   if (j==1 && o hasnt pluralname)
0231            print (string) IS__TX; else print (string) ARE__TX;
0232        if (c_style & NEWLINE_BIT ~= 0) print ":^"; else print (char) ' ';
0233        c_style = c_style - ISARE_BIT;
0234    }
0235   
0236    stack_pointer = stack_pointer+j+1;
0237   
0238    if (k<2) jump EconomyVersion;   ! It takes two to plural
0239    n=1;
0240    for (i=o,k=0:k<j:i=NextEntry(i,depth),k++)
0241        if (classes_p->k==0)
0242        {   classes_p->k=n; sizes_p->n=1;
0243            for (l=NextEntry(i,depth), m=k+1:l~=0 && m<j:
0244                 l=NextEntry(l,depth), m++)
0245                if (classes_p->m==0 && i.plural~=0 && l.plural~=0)
0246                {   if (ListEqual(i,l)==1)
0247                    {   sizes_p->n = sizes_p->n + 1;
0248                        classes_p->m = n;
0249                    }
0250                }
0251            n++;
0252        }
0253    n--;
0254   
0255    for (i=1, j=o, k=0: i<=n: i++, senc++)
0256    {   while (((classes_p->k) ~= i)
0257               && ((classes_p->k) ~= -i)) { k++; j=NextEntry(j,depth); }
0258        m=sizes_p->i;
0259        if (j==0) mr = 0;
0260        else
0261        {   if (j.list_together~=0 or lt_value
0262                && ZRegion(j.list_together)==2 or 3
0263                && j.list_together==mr) senc--;
0264            mr=j.list_together;
0265        }
0266    }
0267    senc--;
0268   
0269    for (i=1, j=o, k=0, mr=0: senc>=0: i++, senc--)
0270    {   while (((classes_p->k) ~= i)
0271               && ((classes_p->k) ~= -i)) { k++; j=NextEntry(j,depth); }
0272        if (j.list_together~=0 or lt_value)
0273        {   if (j.list_together==mr) { senc++; jump Omit_FL2; }
0274            k2=NextEntry(j,depth);
0275            if (k2==0 || k2.list_together~=j.list_together) jump Omit_WL2;
0276            k2=ZRegion(j.list_together);
0277            if (k2==2 or 3)
0278            {   q=j; listing_size=1; l=k; m=i;
0279                while (m<n && q.list_together==j.list_together)
0280                {   m++;
0281                    while (((classes_p->l) ~= m)
0282                           && ((classes_p->l) ~= -m))
0283                    {   l++; q=NextEntry(q,depth); }
0284                    if (q.list_together==j.list_together) listing_size++;
0285                }
0286  !              print " [", listing_size, "] ";
0287                if (listing_size==1) jump Omit_WL2;
0288                if (c_style & INDENT_BIT ~= 0)
0289                    Print__Spaces(2*(depth+wlf_indent));
0290                if (k2==3)
0291                {   q=0; for (l=0:l<listing_size:l++) q=q+sizes_p->(l+i);
0292                    EnglishNumber(q); print " ";
0293                    print (string) j.list_together;
0294                    if (c_style & ENGLISH_BIT ~= 0) print " (";
0295                    if (c_style & INDENT_BIT ~= 0) print ":^";
0296                }
0297                q=c_style;
0298                if (k2~=3)
0299                {   inventory_stage=1;
0300                    parser_one=j; parser_two=depth+wlf_indent;
0301                    if (RunRoutines(j,list_together)==1) jump Omit__Sublist2;
0302                }
0303   
0304                @push lt_value; @push listing_together; @push listing_size;
0305                lt_value=j.list_together; listing_together=j; wlf_indent++;
0306                WriteListR(j,depth,stack_pointer); wlf_indent--;
0307                @pull listing_size; @pull listing_together; @pull lt_value;
0308   
0309                if (k2==3)
0310                {   if (q & ENGLISH_BIT ~= 0) print ")";
0311                }
0312                else
0313                {   inventory_stage=2;
0314                    parser_one=j; parser_two=depth+wlf_indent;
0315                    RunRoutines(j,list_together);
0316                }
0317               .Omit__Sublist2;
0318                if (q & NEWLINE_BIT ~= 0 && c_style & NEWLINE_BIT == 0)
0319                    new_line;
0320                c_style=q;
0321                mr=j.list_together;
0322                jump Omit_EL2;
0323            }
0324        }
0325   
0326       .Omit_WL2;
0327        if (WriteBeforeEntry(j,depth,-senc)==1) jump Omit_FL2;
0328        if (sizes_p->i == 1)
0329        {   if (c_style & NOARTICLE_BIT ~= 0) print (name) j;
0330            else
0331            {   if (c_style & DEFART_BIT ~= 0) print (the) j; else print (a) j;
0332            }
0333        }
0334        else
0335        {   if (c_style & DEFART_BIT ~= 0)
0336                PrefaceByArticle(j, 1, sizes_p->i);
0337            print (number) sizes_p->i, " ";
0338            PrintOrRun(j,plural,1);
0339        }
0340        WriteAfterEntry(j,depth,stack_pointer);
0341   
0342       .Omit_EL2;
0343        if (c_style & ENGLISH_BIT ~= 0)
0344        {   if (senc==1) print (string) AND__TX;
0345            if (senc>1) print ", ";
0346        }
0347       .Omit_FL2;
0348    }
0349    rtrue;
0350   
0351    .EconomyVersion;
0352   
0353    n=j;
0354   
0355    for (i=1, j=o: i<=n: j=NextEntry(j,depth), i++, senc++)
0356    {   if (j.list_together~=0 or lt_value
0357            && ZRegion(j.list_together)==2 or 3
0358            && j.list_together==mr) senc--;
0359        mr=j.list_together;
0360    }
0361   
0362    for (i=1, j=o, mr=0: i<=senc: j=NextEntry(j,depth), i++)
0363    {   if (j.list_together~=0 or lt_value)
0364        {   if (j.list_together==mr) { i--; jump Omit_FL; }
0365            k=NextEntry(j,depth);
0366            if (k==0 || k.list_together~=j.list_together) jump Omit_WL;
0367            k=ZRegion(j.list_together);
0368            if (k==2 or 3)
0369            {   if (c_style & INDENT_BIT ~= 0)
0370                    Print__Spaces(2*(depth+wlf_indent));
0371                if (k==3)
0372                {   q=j; l=0;
0373                    do
0374                    {   q=NextEntry(q,depth); l++;
0375                    } until (q==0 || q.list_together~=j.list_together);
0376                    EnglishNumber(l); print " ";
0377                    print (string) j.list_together;
0378                    if (c_style & ENGLISH_BIT ~= 0) print " (";
0379                    if (c_style & INDENT_BIT ~= 0) print ":^";
0380                }
0381                q=c_style;
0382                if (k~=3)
0383                {   inventory_stage=1;
0384                    parser_one=j; parser_two=depth+wlf_indent;
0385                    if (RunRoutines(j,list_together)==1) jump Omit__Sublist;
0386                }
0387   
0388                @push lt_value; @push listing_together; @push listing_size;
0389                lt_value=j.list_together; listing_together=j; wlf_indent++;
0390                WriteListR(j,depth,stack_pointer); wlf_indent--;
0391                @pull listing_size; @pull listing_together; @pull lt_value;
0392   
0393                if (k==3)
0394                {   if (q & ENGLISH_BIT ~= 0) print ")";
0395                }
0396                else
0397                {   inventory_stage=2;
0398                    parser_one=j; parser_two=depth+wlf_indent;
0399                    RunRoutines(j,list_together);
0400                }
0401               .Omit__Sublist;
0402                if (q & NEWLINE_BIT ~= 0 && c_style & NEWLINE_BIT == 0) new_line;
0403                c_style=q;
0404                mr=j.list_together;
0405                jump Omit_EL;
0406            }
0407        }
0408       .Omit_WL;
0409        if (WriteBeforeEntry(j,depth,i-senc)==1) jump Omit_FL;
0410        if (c_style & NOARTICLE_BIT ~= 0) print (name) j;
0411        else
0412        {   if (c_style & DEFART_BIT ~= 0) print (the) j; else print (a) j;
0413        }
0414        WriteAfterEntry(j,depth,stack_pointer);
0415   
0416       .Omit_EL;
0417        if (c_style & ENGLISH_BIT ~= 0)
0418        {   if (i==senc-1) print (string) AND__TX;
0419            if (i<senc-1) print ", ";
0420        }
0421       .Omit_FL;
0422    }
0423  ];
0424   
0425  [ WriteBeforeEntry o depth sentencepos  flag;
0426    if (c_style & INDENT_BIT ~= 0) Print__Spaces(2*(depth+wlf_indent));
0427   
0428    if (c_style & FULLINV_BIT ~= 0)
0429    {   if (o.invent~=0)
0430        {   inventory_stage=1;
0431            flag=PrintOrRun(o,invent,1);
0432            if (flag==1)
0433            {   if (c_style & ENGLISH_BIT ~= 0)
0434                {   if (sentencepos == -1) print (string) AND__TX;
0435                    if (sentencepos < -1) print ", ";
0436                }
0437                if (c_style & NEWLINE_BIT ~= 0) new_line;
0438            }
0439        }
0440    }
0441    return flag;
0442  ];
0443   
0444  [ WriteAfterEntry o depth stack_p  flag flag2 flag3 p comb;
0445   
0446    if (c_style & PARTINV_BIT ~= 0)
0447    {   comb=0;
0448        if (o has light && location hasnt light) comb=comb+1;
0449        if (o has container && o hasnt open)     comb=comb+2;
0450        if ((o has container && (o has open || o has transparent))
0451            && (child(o)==0)) comb=comb+4;
0452        if (comb==1) L__M(##ListMiscellany, 1, o);
0453        if (comb==2) L__M(##ListMiscellany, 2, o);
0454        if (comb==3) L__M(##ListMiscellany, 3, o);
0455        if (comb==4) L__M(##ListMiscellany, 4, o);
0456        if (comb==5) L__M(##ListMiscellany, 5, o);
0457        if (comb==6) L__M(##ListMiscellany, 6, o);
0458        if (comb==7) L__M(##ListMiscellany, 7, o);
0459    }
0460   
0461    if (c_style & FULLINV_BIT ~= 0)
0462    {   if (o.invent ~= 0)
0463        {   inventory_stage=2;
0464            if (RunRoutines(o,invent)~=0)
0465            {   if (c_style & NEWLINE_BIT ~= 0) new_line;
0466                rtrue;
0467            }
0468        }
0469        if (o has light && o has worn)
0470        {    L__M(##ListMiscellany, 8); flag2=1; }
0471        else
0472        {   if (o has light) {  L__M(##ListMiscellany, 9, o); flag2=1; }
0473            if (o has worn)  {  L__M(##ListMiscellany, 10, o); flag2=1; }
0474        }
0475        if (o has container)
0476        {   if (o has openable)
0477            {   if (flag2==1) print (string) AND__TX;
0478                else L__M(##ListMiscellany, 11, o);
0479                if (o has open)
0480                {   if (child(o)==0) L__M(##ListMiscellany, 13, o);
0481                    else L__M(##ListMiscellany, 12, o);
0482                }
0483                else
0484                {   if (o has lockable && o has locked)
0485                        L__M(##ListMiscellany, 15, o);
0486                    else L__M(##ListMiscellany, 14, o);
0487                }
0488                flag2=1;
0489            }
0490            else
0491                if (child(o)==0 && o has transparent)
0492                {   if (flag2==1) L__M(##ListMiscellany, 16, o);
0493                    else L__M(##ListMiscellany, 17, o);
0494                }
0495        }
0496        if (flag2==1) print ")";
0497    }
0498   
0499    if (c_style & CONCEAL_BIT == 0)
0500    {   flag3 = children(o);
0501        flag2 = child(o);
0502    }
0503    else
0504    {   flag3 = 0;
0505        objectloop (p in o)
0506            if (p hasnt concealed && p hasnt scenery) { flag3++; flag2 = p; }
0507    }
0508   
0509    if (c_style & ALWAYS_BIT ~= 0 && flag3>0)
0510    {   if (c_style & ENGLISH_BIT ~= 0) L__M(##ListMiscellany, 18, o);
0511        flag=1;
0512    }
0513   
0514    if (c_style & RECURSE_BIT ~= 0 && flag3>0)
0515    {   if (o has supporter)
0516        {   if (c_style & ENGLISH_BIT ~= 0)
0517            {   if (c_style & TERSE_BIT ~= 0)
0518                     L__M(##ListMiscellany, 19, o);
0519                else L__M(##ListMiscellany, 20, o);
0520                if (o has animate) print (string) WHOM__TX;
0521                else print (string) WHICH__TX;
0522            }
0523            flag=1;
0524        }
0525        if (o has container && (o has open || o has transparent))
0526        {   if (c_style & ENGLISH_BIT ~= 0)
0527            {   if (c_style & TERSE_BIT ~= 0)
0528                     L__M(##ListMiscellany, 21, o);
0529                else L__M(##ListMiscellany, 22, o);
0530                if (o has animate) print (string) WHOM__TX;
0531                else print (string) WHICH__TX;
0532            }
0533            flag=1;
0534        }
0535    }
0536   
0537    if (flag==1 && c_style & ENGLISH_BIT ~= 0)
0538    {   if (flag3 > 1 || flag2 has pluralname)
0539             print (string) ARE2__TX;
0540        else print (string) IS2__TX;
0541    }
0542   
0543    if (c_style & NEWLINE_BIT ~= 0) new_line;
0544   
0545    if (flag==1)
0546    {   o = child(o);
0547        @push lt_value; @push listing_together; @push listing_size;
0548        lt_value = 0; listing_together = 0; listing_size = 0;
0549        WriteListR(o, depth+1, stack_p);
0550        @pull listing_size; @pull listing_together; @pull lt_value;
0551        if (c_style & TERSE_BIT ~= 0) print ")";
0552    }
0553  ];
0554   
0555  ! ----------------------------------------------------------------------------
0556  !  Much better menus can be created using the optional library extension
0557  !  "menus.h".  These are provided for compatibility with previous practice:
0558  ! ----------------------------------------------------------------------------
0559   
0560  [ LowKey_Menu menu_choices EntryR ChoiceR lines main_title i j;
0561    menu_nesting++;
0562   .LKRD;
0563    menu_item=0;
0564    lines=indirect(EntryR);
0565    main_title=item_name;
0566   
0567    print "--- "; print (string) main_title; print " ---^^";
0568   
0569    if (menu_choices ofclass Routine) menu_choices.call();
0570    else print (string) menu_choices;
0571   
0572    for (::)
0573    {   L__M(##Miscellany, 52, lines);
0574        print "> ";
0575   
0576        #IFV3; read buffer parse;
0577        #IFNOT; read buffer parse DrawStatusLine;
0578        #ENDIF;
0579   
0580        i=parse-->1;
0581        if (i==QUIT1__WD or QUIT2__WD || parse->1==0)
0582        {   menu_nesting--; if (menu_nesting>0) rfalse;
0583            if (deadflag==0) <<Look>>;
0584            rfalse;
0585        }
0586        i=TryNumber(1);
0587        if (i==0) jump LKRD;
0588        if (i<1 || i>lines) continue;
0589        menu_item=i;
0590        j=indirect(ChoiceR);
0591        if (j==2) jump LKRD;
0592        if (j==3) rfalse;
0593    }
0594  ];
0595   
0596  #IFV3;
0597  [ DoMenu menu_choices EntryR ChoiceR;
0598    LowKey_Menu(menu_choices,EntryR,ChoiceR);
0599  ];
0600  #ENDIF;
0601   
0602  #IFV5;
0603  [ DoMenu menu_choices EntryR ChoiceR
0604           lines main_title main_wid cl i j oldcl pkey;
0605   
0606    if (pretty_flag==0)
0607        return LowKey_Menu(menu_choices,EntryR,ChoiceR);
0608   
0609    menu_nesting++;
0610    menu_item=0;
0611    lines=indirect(EntryR);
0612    main_title=item_name; main_wid=item_width;
0613    cl=7;
0614   
0615    .ReDisplay;
0616        oldcl=0;
0617        @erase_window $ffff;
0618        i=lines+7;
0619        @split_window i;
0620        i = 0->33;
0621        if (i==0) i=80;
0622        @set_window 1;
0623        @set_cursor 1 1;
0624        style reverse;
0625        spaces(i); j=i/2-main_wid;
0626        @set_cursor 1 j;
0627        print (string) main_title;
0628        @set_cursor 2 1; spaces(i);
0629        @set_cursor 2 2; print (string) NKEY__TX;
0630        j=i-12; @set_cursor 2 j; print (string) PKEY__TX;
0631        @set_cursor 3 1; spaces(i);
0632        @set_cursor 3 2; print (string) RKEY__TX;
0633        j=i-17; @set_cursor 3 j;
0634        if (menu_nesting==1) print (string) QKEY1__TX;
0635                        else print (string) QKEY2__TX;
0636        style roman;
0637        @set_cursor 5 2; font off;
0638   
0639        if (menu_choices ofclass String) print (string) menu_choices;
0640        else menu_choices.call();
0641   
0642        for (::)
0643        {   if (cl ~= oldcl)
0644            {   if (oldcl>0) { @set_cursor oldcl 4; print " "; }
0645                @set_cursor cl 4; print ">";
0646            }
0647            oldcl=cl;
0648            @read_char 1 -> pkey;
0649            if (pkey==NKEY1__KY or NKEY2__KY or 130)
0650            {   cl++; if (cl==7+lines) cl=7; continue;
0651            }
0652            if (pkey==PKEY1__KY or PKEY2__KY or 129)
0653            {   cl--; if (cl==6)  cl=6+lines; continue;
0654            }
0655            if (pkey==QKEY1__KY or QKEY2__KY or 27 or 131) break;
0656            if (pkey==10 or 13 or 132)
0657            {   @set_window 0; font on;
0658                new_line; new_line; new_line;
0659      
0660                menu_item=cl-6;
0661                EntryR.call();
0662      
0663                @erase_window $ffff;
0664                @split_window 1;
0665                i = 0->33; if (i==0) { i=80; }
0666                @set_window 1; @set_cursor 1 1; style reverse; spaces(i);
0667                j=i/2-item_width;
0668                @set_cursor 1 j;
0669                print (string) item_name;
0670                style roman; @set_window 0; new_line;
0671      
0672                i = ChoiceR.call();
0673                if (i==2) jump ReDisplay;
0674                if (i==3) break;
0675      
0676                L__M(##Miscellany, 53);
0677                @read_char 1 -> pkey; jump ReDisplay;
0678            }
0679        }
0680   
0681        menu_nesting--; if (menu_nesting>0) rfalse;
0682        font on; @set_cursor 1 1;
0683        @erase_window $ffff; @set_window 0;
0684        new_line; new_line; new_line;
0685        if (deadflag==0) <<Look>>;
0686  ];  
0687  #ENDIF;
0688   
0689  ! ----------------------------------------------------------------------------
0690  !   A cunning routine (which could have been a daemon, but isn't, for the
0691  !   sake of efficiency) to move objects which could be in many rooms about
0692  !   so that the player never catches one not in place
0693  ! ----------------------------------------------------------------------------
0694   
0695  [ MoveFloatingObjects i k l m address flag;
0696    objectloop (i)
0697    {   address=i.&found_in;
0698        if (address~=0 && i hasnt absent)
0699        {   if (ZRegion(address-->0)==2)
0700            {   if (i.found_in() ~= 0) move i to location; else remove i;
0701            }
0702            else
0703            {   k=i.#found_in;
0704                for (l=0: l<k/2: l++)
0705                {   m=address-->l;
0706                    if (m==location || m in location)
0707                    {   if (i notin location) move i to location;
0708                        flag = true;
0709                    }
0710                }
0711                if (flag == false) { if (parent(i)) remove i; }
0712            }
0713        }
0714    }
0715  ];
0716   
0717  ! ----------------------------------------------------------------------------
0718  !   Two little routines for moving the player safely.
0719  ! ----------------------------------------------------------------------------
0720   
0721  [ PlayerTo newplace flag;
0722    move player to newplace;
0723    while (parent(newplace)~=0) newplace=parent(newplace);
0724    location=newplace;
0725    real_location=location; MoveFloatingObjects();
0726    AdjustLight(1);
0727    if (flag==0) <Look>;
0728    if (flag==1) { NoteArrival(); ScoreArrival(); }
0729    if (flag==2) LookSub(1);
0730  ];
0731   
0732  [ MovePlayer direc; <Go direc>; <Look>; ];
0733   
0734  ! ----------------------------------------------------------------------------
0735  !   The handy YesOrNo routine, and some "meta" verbs
0736  ! ----------------------------------------------------------------------------
0737   
0738  [ YesOrNo i;
0739    for (::)
0740    {   if (location == nothing || parent(player) == nothing) read buffer parse;
0741        else read buffer parse DrawStatusLine;
0742        i=parse-->1;
0743        if (i==YES1__WD or YES2__WD or YES3__WD) rtrue;
0744        if (i==NO1__WD or NO2__WD or NO3__WD) rfalse;
0745        L__M(##Quit,1); print "> ";
0746    }
0747  ];
0748   
0749  [ QuitSub; L__M(##Quit,2); if (YesOrNo()~=0) quit; ];
0750   
0751  [ RestartSub; L__M(##Restart,1);
0752    if (YesOrNo()~=0) { @restart; L__M(##Restart,2); }
0753  ];
0754   
0755  [ RestoreSub;
0756    restore Rmaybe;
0757    return L__M(##Restore,1);
0758    .RMaybe; L__M(##Restore,2);
0759  ];
0760   
0761  [ SaveSub flag;
0762    #IFV5;
0763    @save -> flag;
0764    switch (flag) {
0765        0: L__M(##Save,1);
0766        1: L__M(##Save,2);
0767        2: L__M(##Restore,2);
0768    }
0769    #IFNOT;
0770    save Smaybe;
0771    return L__M(##Save,1);
0772    .SMaybe; L__M(##Save,2);
0773    #ENDIF;
0774  ];
0775   
0776  [ VerifySub;
0777    @verify ?Vmaybe;
0778    jump Vwrong;
0779    .Vmaybe; return L__M(##Verify,1);
0780    .Vwrong;
0781    L__M(##Verify,2);
0782  ];
0783   
0784  [ ScriptOnSub;
0785    transcript_mode = ((0-->8) & 1);
0786    if (transcript_mode) return L__M(##ScriptOn,1);
0787    @output_stream 2;
0788    if (((0-->8) & 1) == 0) return L__M(##ScriptOn,3);
0789    L__M(##ScriptOn,2); VersionSub();
0790    transcript_mode = true;
0791  ];
0792  	
0793  [ ScriptOffSub;
0794    transcript_mode = ((0-->8) & 1);
0795    if (transcript_mode == false) return L__M(##ScriptOff,1);
0796    L__M(##ScriptOff,2);
0797    @output_stream -2;
0798    if ((0-->8) & 1) return L__M(##ScriptOff,3);
0799    transcript_mode = false;
0800  ];
0801   
0802  [ NotifyOnSub; notify_mode=1; L__M(##NotifyOn); ];
0803  [ NotifyOffSub; notify_mode=0; L__M(##NotifyOff); ];
0804   
0805  [ Places1Sub i j k;
0806    L__M(##Places);
0807    objectloop(i has visited) j++;
0808   
0809    objectloop(i has visited)
0810    {   print (name) i; k++;
0811        if (k==j) ".";
0812        if (k==j-1) print (string) AND__TX; else print ", ";
0813    }
0814  ];
0815  [ Objects1Sub i j f;
0816    L__M(##Objects,1);
0817    objectloop(i has moved)
0818    {   f=1; print (the) i; j=parent(i);
0819   
0820        if (j)
0821        {   if (j==player)
0822            {   if (i has worn) L__M(##Objects, 3);
0823                else L__M(##Objects, 4);
0824                jump obj__ptd;
0825            }
0826   
0827            if (j has animate)   { L__M(##Objects, 5); jump obj__ptd; }
0828            if (j has visited)   { L__M(##Objects, 6, j); jump obj__ptd; }
0829            if (j has container) { L__M(##Objects, 8, j); jump obj__ptd; }
0830            if (j has supporter) { L__M(##Objects, 9, j); jump obj__ptd; }
0831            if (j has enterable) { L__M(##Objects, 7, j); jump obj__ptd; }
0832        }
0833   
0834        L__M(##Objects, 10);
0835        .obj__ptd; new_line;
0836    }
0837    if (f==0) L__M(##Objects,2);
0838  ];
0839   
0840  ! ----------------------------------------------------------------------------
0841  !   The scoring system
0842  ! ----------------------------------------------------------------------------
0843   
0844  [ ScoreSub;
0845    L__M(##Score);
0846    PrintRank();
0847  ];
0848   
0849  [ Achieved num;
0850    if (task_done->num==0)
0851    {   task_done->num=1;
0852        score = score + task_scores->num;
0853    }
0854  ];
0855   
0856  [ PANum m n;
0857    print "  ";
0858    n=m;
0859    if (n<0)    { n=-m; n=n*10; }
0860    if (n<10)   { print "   "; jump panuml; }
0861    if (n<100)  { print "  "; jump panuml; }
0862    if (n<1000) { print " "; }
0863  .panuml;
0864    print m, " ";
0865  ];
0866   
0867  [ FullScoreSub i;
0868    ScoreSub();
0869    if (score==0 || TASKS_PROVIDED==1) rfalse;
0870    new_line;
0871    L__M(##FullScore,1);
0872   
0873    for (i=0:i<NUMBER_TASKS:i++)
0874        if (task_done->i==1)
0875        {   PANum(task_scores->i);
0876            PrintTaskName(i);
0877        }
0878    
0879    if (things_score~=0)
0880    {   PANum(things_score); L__M(##FullScore,2); }
0881    if (places_score~=0)
0882    {   PANum(places_score); L__M(##FullScore,3); }
0883    new_line; PANum(score); L__M(##FullScore,4);
0884  ];
0885   
0886  ! ----------------------------------------------------------------------------
0887  !   Real verbs start here: Inventory
0888  ! ----------------------------------------------------------------------------
0889   
0890  [ InvWideSub;
0891    inventory_style = FULLINV_BIT + ENGLISH_BIT + RECURSE_BIT;
0892    <Inv>;
0893  ];
0894   
0895  [ InvTallSub;
0896    inventory_style = FULLINV_BIT + INDENT_BIT + NEWLINE_BIT + RECURSE_BIT;
0897    <Inv>;
0898  ];
0899   
0900  [ InvSub x;
0901    if (child(player)==0) return L__M(##Inv,1);
0902    if (inventory_style==0) return InvTallSub();
0903   
0904    L__M(##Inv,2);
0905    if (inventory_style & NEWLINE_BIT ~= 0) print ":^"; else print " ";
0906   
0907    WriteListFrom(child(player), inventory_style, 1);
0908    if (inventory_style & ENGLISH_BIT ~= 0) print ".^";
0909   
0910  #IFNDEF MANUAL_PRONOUNS;
0911    objectloop(x in player) PronounNotice(x);
0912  #ENDIF;
0913    x = 0; ! To prevent a "not used" error
0914    AfterRoutines();
0915  ];
0916   
0917  ! ----------------------------------------------------------------------------
0918  !   The object tree and determining the possibility of moves
0919  ! ----------------------------------------------------------------------------
0920   
0921  [ CommonAncestor o1 o2 i j;
0922    !  Find the nearest object indirectly containing o1 and o2,
0923    !  or return 0 if there is no common ancestor.
0924   
0925    i = o1;
0926    while (i ~= 0)
0927    {
0928        j = o2;
0929        while (j ~= 0)
0930        {   if (j == i) return i;
0931            j = parent(j);
0932        }
0933        i = parent(i);
0934    }
0935    return 0;
0936  ];
0937   
0938  [ IndirectlyContains o1 o2;
0939    !  Does o1 indirectly contain o2?  (Same as testing if their common
0940    !  ancestor is o1.)
0941   
0942    while (o2~=0)
0943    {   if (o1==o2) rtrue;
0944        o2=parent(o2);
0945    }
0946    rfalse;
0947  ];
0948   
0949  [ ObjectScopedBySomething item i j k l m;
0950    i = item;
0951    while (parent(i) ~= 0) i=parent(i);
0952    objectloop (j .& add_to_scope)
0953    {   l = j.&add_to_scope;
0954        k = (j.#add_to_scope)/2;
0955        if (l-->0 ofclass Routine) continue;
0956        for (m=0:m<k:m++)
0957            if (l-->m == i)
0958                return j;
0959    }
0960    rfalse;
0961  ];
0962   
0963  [ ObjectIsUntouchable item flag1 flag2 ancestor i;
0964   
0965    ! Determine if there's any barrier preventing the player from moving
0966    ! things to "item".  Return false if no barrier; otherwise print a
0967    ! suitable message and return true.
0968    ! If flag1 is set, do not print any message.
0969    ! If flag2 is set, also apply Take/Remove restrictions.
0970   
0971    ! If the item has been added to scope by something, it's first necessary
0972    ! for that something to be touchable.
0973   
0974    i = ObjectScopedBySomething(item);
0975    if (i ~= 0)
0976    {   if (ObjectIsUntouchable(i)) return;
0977        ! An item immediately added to scope
0978    }
0979   
0980    ancestor = CommonAncestor(player, item);
0981   
0982    ! First, a barrier between the player and the ancestor.  The player
0983    ! can only be in a sequence of enterable objects, and only closed
0984    ! containers form a barrier.
0985   
0986    if (player ~= ancestor)
0987    {   i = parent(player);
0988        while (i~=ancestor)
0989        {   if (i has container && i hasnt open)
0990            {   if (flag1) rtrue;
0991                return L__M(##Take,9,i);
0992            }
0993            i = parent(i);
0994        }
0995    }
0996   
0997    ! Second, a barrier between the item and the ancestor.  The item can
0998    ! be carried by someone, part of a piece of machinery, in or on top
0999    ! of something and so on.
1000   
1001    if (item ~= ancestor)
1002    {   i = parent(item);
1003        while (i~=ancestor)
1004        {   if (flag2 && i hasnt container && i hasnt supporter)
1005            {   if (i has animate)
1006                {   if (flag1) rtrue;
1007                    return L__M(##Take,6,i);
1008                }
1009                if (i has transparent)
1010                {   if (flag1) rtrue;
1011                    return L__M(##Take,7,i);
1012                }
1013                if (flag1) rtrue;
1014                return L__M(##Take,8,item);
1015            }
1016            if (i has container && i hasnt open)
1017            {   if (flag1) rtrue;
1018                return L__M(##Take,9,i);
1019            }
1020            i = parent(i);
1021        }
1022    }
1023    rfalse;
1024  ];
1025   
1026  [ AttemptToTakeObject item     ancestor after_recipient i j k;
1027    ! Try to transfer the given item to the player: return false
1028    ! if successful, true if unsuccessful, printing a suitable message
1029    ! in the latter case.
1030   
1031    ! People cannot ordinarily be taken.
1032    if (item == player) return L__M(##Take,2);
1033    if (item has animate) return L__M(##Take,3,item);
1034   
1035    ancestor = CommonAncestor(player, item);
1036   
1037    if (ancestor == 0)
1038    {   i = ObjectScopedBySomething(item);
1039        if (i ~= 0) ancestor = CommonAncestor(player, i);
1040    }
1041   
1042    ! Are player and item in totally different places?
1043   
1044    if (ancestor == 0) return L__M(##Take,8,item);
1045   
1046    ! Is the player indirectly inside the item?
1047    if (ancestor == item) return L__M(##Take,4,item);
1048   
1049    ! Does the player already directly contain the item?
1050    if (item in player) return L__M(##Take,5,item);
1051   
1052    ! Can the player touch the item, or is there (e.g.) a closed container
1053    ! in the way?
1054    if (ObjectIsUntouchable(item,false,true)) return;
1055   
1056    ! The item is now known to be accessible.
1057   
1058    ! Consult the immediate possessor of the item, if it's in a container
1059    ! which the player is not in.
1060   
1061    i=parent(item);
1062    if (i ~= ancestor && (i has container || i has supporter))
1063    {   after_recipient=i;
1064        k=action; action=##LetGo;
1065        if (RunRoutines(i,before)~=0) { action=k; rtrue; }
1066        action=k;
1067    }
1068   
1069    if (item has scenery) return L__M(##Take,10,item);
1070    if (item has static)  return L__M(##Take,11,item);
1071   
1072    ! The item is now known to be available for taking.  Is the player
1073    ! carrying too much?  If so, possibly juggle items into the rucksack
1074    ! to make room.
1075   
1076    k=0; objectloop (j in player) if (j hasnt worn) k++;
1077   
1078    if (k >= ValueOrRun(player,capacity))
1079    {   if (SACK_OBJECT~=0)
1080        {   if (parent(SACK_OBJECT)~=player)
1081                return L__M(##Take,12);
1082            j=0;
1083            objectloop (k in player) 
1084                if (k~=SACK_OBJECT && k hasnt worn && k hasnt light) j=k;
1085   
1086            if (j~=0)
1087            {   L__M(##Take,13,j);
1088                keep_silent = 1; <Insert j SACK_OBJECT>; keep_silent = 0;
1089                if (j notin SACK_OBJECT) rtrue;
1090            }
1091            else return L__M(##Take,12);
1092        }
1093        else return L__M(##Take,12);
1094    }
1095   
1096    ! Transfer the item.
1097   
1098    move item to player;
1099   
1100    ! Send "after" message to the object letting go of the item, if any.
1101   
1102    if (after_recipient~=0)
1103    {   k=action; action=##LetGo;
1104        if (RunRoutines(after_recipient,after)~=0) { action=k; rtrue; }
1105        action=k;
1106    }
1107    rfalse;
1108  ];
1109   
1110  ! ----------------------------------------------------------------------------
1111  !   Object movement verbs
1112  ! ----------------------------------------------------------------------------
1113   
1114  [ TakeSub;
1115    if (onotheld_mode==0 || noun notin player)
1116        if (AttemptToTakeObject(noun)) rtrue;
1117    if (AfterRoutines()==1) rtrue;
1118    notheld_mode=onotheld_mode;
1119    if (notheld_mode==1 || keep_silent==1) rtrue;
1120    L__M(##Take,1);
1121  ];
1122   
1123  [ RemoveSub i;
1124    i=parent(noun);
1125    if (i has container && i hasnt open) return L__M(##Remove,1,noun);
1126    if (i~=second) return L__M(##Remove,2,noun);
1127    if (i has animate) return L__M(##Take,6,i);
1128    if (AttemptToTakeObject(noun)) rtrue;
1129    action=##Remove; if (AfterRoutines()==1) rtrue;
1130    action=##Take;   if (AfterRoutines()==1) rtrue;
1131   
1132    if (keep_silent==1) rtrue;
1133    return L__M(##Remove,3,noun);
1134  ];
1135   
1136  [ DropSub;
1137    if (noun == player) return L__M(##PutOn, 4);
1138    if (noun in parent(player)) return L__M(##Drop,1,noun);
1139    if (noun notin player) return L__M(##Drop,2,noun);
1140    if (noun has worn)
1141    {   L__M(##Drop,3,noun);
1142        <Disrobe noun>;
1143        if (noun has worn && noun in player) rtrue;
1144    }
1145    move noun to parent(player);
1146    if (AfterRoutines()==1) rtrue;
1147    if (keep_silent==1) rtrue;
1148    return L__M(##Drop,4,noun);
1149  ];
1150   
1151  [ PutOnSub ancestor;
1152    receive_action=##PutOn; 
1153    if (second == d_obj || player in second) <<Drop noun>>;
1154    if (parent(noun)~=player) return L__M(##PutOn,1,noun);
1155   
1156    ancestor = CommonAncestor(noun, second);
1157    if (ancestor == noun) return L__M(##PutOn,2,noun);
1158    if (ObjectIsUntouchable(second)) return;
1159   
1160    if (second ~= ancestor)
1161    {   action=##Receive;
1162        if (RunRoutines(second,before)~=0) { action=##PutOn; return; }
1163        action=##PutOn;
1164    }
1165    if (second hasnt supporter) return L__M(##PutOn,3,second);
1166    if (ancestor == player) return L__M(##PutOn,4);
1167    if (noun has worn)
1168    {   L__M(##PutOn,5,noun); <Disrobe noun>; if (noun has worn) return;
1169    }
1170   
1171    if (children(second)>=ValueOrRun(second,capacity))
1172        return L__M(##PutOn,6,second);
1173   
1174    move noun to second;
1175   
1176    if (AfterRoutines()==1) return;
1177   
1178    if (second ~= ancestor)
1179    {   action=##Receive;
1180        if (RunRoutines(second,after)~=0) { action=##PutOn; return; }
1181        action=##PutOn;
1182    }
1183    if (keep_silent==1) return;
1184    if (multiflag==1) return L__M(##PutOn,7);
1185    L__M(##PutOn,8,noun);
1186  ];
1187   
1188  [ InsertSub ancestor;
1189    receive_action = ##Insert;
1190    if (second==d_obj || player in second) <<Drop noun>>;
1191    if (parent(noun)~=player) return L__M(##Insert,1,noun);
1192   
1193    ancestor = CommonAncestor(noun, second);
1194    if (ancestor == noun) return L__M(##Insert, 5, noun);
1195    if (ObjectIsUntouchable(second)) return;
1196   
1197    if (second ~= ancestor)
1198    {   action=##Receive;
1199        if (RunRoutines(second,before)~=0) { action=##Insert; rtrue; }
1200        action=##Insert;
1201        if (second has container && second hasnt open)
1202            return L__M(##Insert,3,second);
1203    }
1204    if (second hasnt container) return L__M(##Insert,2,second);
1205   
1206    if (noun has worn)
1207    {   L__M(##Insert,6,noun); <Disrobe noun>; if (noun has worn) return;
1208    }
1209   
1210    if (children(second) >= ValueOrRun(second,capacity))
1211        return L__M(##Insert,7,second);
1212   
1213    move noun to second;
1214   
1215    if (AfterRoutines()==1) rtrue;
1216   
1217    if (second ~= ancestor)
1218    {   action=##Receive;
1219        if (RunRoutines(second,after)~=0) { action=##Insert; rtrue; }
1220        action=##Insert;
1221    }
1222    if (keep_silent==1) rtrue;
1223    if (multiflag==1) return L__M(##Insert,8,noun);
1224    L__M(##Insert,9,noun);
1225  ];
1226   
1227  ! ----------------------------------------------------------------------------
1228  !   Empties and transfers are routed through the actions above
1229  ! ----------------------------------------------------------------------------
1230   
1231  [ TransferSub;
1232    if (noun notin player && AttemptToTakeObject(noun)) return;
1233    if (second has supporter) <<PutOn noun second>>;
1234    if (second == d_obj) <<Drop noun>>;
1235    <<Insert noun second>>;
1236  ];
1237   
1238  [ EmptySub;
1239    second=d_obj; EmptyTSub();
1240  ];
1241   
1242  [ EmptyTSub i j k flag;
1243    if (noun == second) return L__M(##EmptyT,4);
1244    if (ObjectIsUntouchable(noun)) return;
1245    if (noun hasnt container) return L__M(##EmptyT,1,noun);
1246    if (noun hasnt open) return L__M(##EmptyT,2,noun);
1247    if (second~=d_obj)
1248    {   if (second hasnt supporter)
1249        {   if (second hasnt container) return L__M(##EmptyT,1,second);
1250            if (second hasnt open) return L__M(##EmptyT,2,second);
1251        }
1252    }
1253    i=child(noun); k = children(noun);
1254    if (i==0) return L__M(##EmptyT,3,noun);
1255    while (i~=0)
1256    {   j=sibling(i);
1257        flag = 0;
1258        if (ObjectIsUntouchable(noun)) flag = 1;
1259        if (noun hasnt container) flag = 1;
1260        if (noun hasnt open) flag = 1;
1261        if (second~=d_obj)
1262        {   if (second hasnt supporter)
1263            {   if (second hasnt container) flag = 1;
1264                if (second hasnt open) flag = 1;
1265            }
1266        }
1267        if (k-- == 0) flag = 1;
1268        if (flag) break;
1269        if (keep_silent == 0) print (name) i, ": ";
1270        <Transfer i second>;
1271        i=j;
1272    }
1273  ];
1274   
1275  ! ----------------------------------------------------------------------------
1276  !   Gifts
1277  ! ----------------------------------------------------------------------------
1278   
1279  [ GiveSub;
1280    if (parent(noun)~=player) return L__M(##Give,1,noun);
1281    if (second==player)  return L__M(##Give,2,noun);
1282    if (RunLife(second,##Give)~=0) rfalse;
1283    L__M(##Give,3,second);
1284  ];
1285   
1286  [ GiveRSub; <Give second noun>; ];
1287   
1288  [ ShowSub;
1289    if (parent(noun)~=player) return L__M(##Show,1,noun);
1290    if (second==player) <<Examine noun>>;
1291    if (RunLife(second,##Show)~=0) rfalse;
1292    L__M(##Show,2,second);
1293  ];
1294   
1295  [ ShowRSub; <Show second noun>; ];
1296   
1297  ! ----------------------------------------------------------------------------
1298  !   Travelling around verbs
1299  ! ----------------------------------------------------------------------------
1300   
1301  [ EnterSub ancestor j k;
1302    if (noun has door || noun in compass) <<Go noun>>;
1303   
1304    if (player in noun) return L__M(##Enter,1,noun);
1305    if (noun hasnt enterable) return L__M(##Enter,2,noun);
1306    if (noun has container && noun hasnt open) return L__M(##Enter,3,noun);
1307   
1308    if (parent(player) ~= parent(noun))
1309    {   ancestor = CommonAncestor(player, noun);
1310        if (ancestor == player or 0) return L__M(##Enter,4,noun);
1311        while (player notin ancestor)
1312        {   j = parent(player);
1313            k = keep_silent; 
1314            if (parent(j) ~= ancestor || noun ~= ancestor)
1315            {   L__M(##Enter,6,j);
1316                keep_silent = 1;
1317            }
1318            <Exit>;
1319            keep_silent = k;
1320            if (player in j) return;
1321        }
1322        if (player in noun) return;
1323        if (noun notin ancestor)
1324        {   j = parent(noun);
1325            while (parent(j) ~= ancestor) j = parent(j);
1326            L__M(##Enter,7,j);
1327            k = keep_silent; keep_silent = 1;
1328            <Enter j>;
1329            keep_silent = k;
1330            if (player notin j) return;
1331            <<Enter noun>>;
1332        }
1333    }
1334   
1335    move player to noun;
1336    if (AfterRoutines()==1) rtrue;
1337    if (keep_silent==1) rtrue;
1338    L__M(##Enter,5,noun);
1339    Locale(noun);
1340  ];
1341   
1342  [ GetOffSub;
1343    if (parent(player)==noun) <<Exit>>;
1344    L__M(##GetOff,1,noun);
1345  ];
1346   
1347  [ ExitSub p;
1348    p=parent(player);
1349    if (p==location || (location==thedark && p==real_location))
1350    {   if ((location.out_to~=0)
1351            || (location==thedark && real_location.out_to~=0)) <<Go out_obj>>;
1352        return L__M(##Exit,1);
1353    }
1354    if (p has container && p hasnt open)
1355        return L__M(##Exit,2,p);
1356   
1357    move player to parent(p);
1358   
1359    if (AfterRoutines()==1) rtrue;
1360    if (keep_silent==1) rtrue;
1361    L__M(##Exit,3,p); LookSub(1);
1362  ];
1363   
1364  [ VagueGoSub; L__M(##VagueGo); ];
1365   
1366  [ GoInSub;
1367    <<Go in_obj>>;
1368  ];
1369   
1370  [ GoSub i j k df movewith thedir old_loc;
1371   
1372    if (second ~= 0 && second notin Compass
1373        && ObjectIsUntouchable(second)) return;
1374   
1375    old_loc = location;
1376    movewith=0;
1377    i=parent(player);
1378    if ((location~=thedark && i~=location)
1379        || (location==thedark && i~=real_location))
1380    {   j=location;
1381        if (location==thedark) location=real_location;
1382        k=RunRoutines(i,before); if (k~=3) location=j;
1383        if (k==1)
1384        {   movewith=i; i=parent(i);
1385        }
1386        else
1387        {   if (k==0) L__M(##Go,1,i);
1388            rtrue;
1389        }
1390    }
1391   
1392    thedir=noun.door_dir;
1393    if (ZRegion(thedir)==2) thedir=RunRoutines(noun,door_dir);
1394    
1395    j=i.thedir; k=ZRegion(j);
1396    if (k==3) { print (string) j; new_line; rfalse; }
1397    if (k==2) { j=RunRoutines(i,thedir);
1398                if (j==1) rtrue;
1399              }
1400   
1401    if (k==0 || j==0)
1402    {   if (i.cant_go ~= 0) PrintOrRun(i, cant_go);
1403        rfalse;
1404    }
1405   
1406    if (j has door)
1407    {   if (j has concealed) return L__M(##Go,2);
1408        if (j hasnt open)
1409        {   if (noun==u_obj) return L__M(##Go,3,j);
1410            if (noun==d_obj) return L__M(##Go,4,j);
1411            return L__M(##Go,5,j);
1412        }
1413        k=RunRoutines(j,door_to);
1414        if (k==0) return L__M(##Go,6,j);
1415        if (k==1) rtrue;
1416        j = k;
1417    }
1418    if (movewith==0) move player to j; else move movewith to j;
1419   
1420    location=j; MoveFloatingObjects();
1421    df=OffersLight(j);
1422    if (df~=0) { location=j; real_location=j; lightflag=1; }
1423    else
1424    {   if (old_loc == thedark)
1425        {   DarkToDark();
1426            if (deadflag~=0) rtrue;
1427        }
1428        real_location=j;
1429        location=thedark; lightflag=0;
1430    }
1431    if (AfterRoutines()==1) rtrue;
1432    if (keep_silent==1) rtrue;
1433    LookSub(1);
1434  ];
1435   
1436  ! ----------------------------------------------------------------------------
1437  !   Describing the world.  SayWhatsOn(object) does just that (producing
1438  !   no text if nothing except possibly "scenery" and "concealed" items are).
1439  !   Locale(object) runs through the "tail end" of a Look-style room
1440  !   description for the contents of the object, printing up suitable
1441  !   descriptions as it goes.
1442  ! ----------------------------------------------------------------------------
1443   
1444  [ SayWhatsOn descon j f;
1445    if (descon==parent(player)) rfalse;
1446    objectloop (j in descon)
1447        if (j hasnt concealed && j hasnt scenery) f=1;
1448    if (f==0) rfalse;
1449    L__M(##Look, 4, descon); rtrue;
1450  ];
1451   
1452  [ NotSupportingThePlayer o i;
1453    i=parent(player);
1454    while (i~=0 && i~=visibility_ceiling)
1455    {   if (i==o) rfalse;
1456        i = parent(i);
1457        if (i~=0 && i hasnt supporter) rtrue;
1458    }
1459    rtrue;
1460  ];
1461   
1462  [ Locale descin text1 text2 o k p j f2 flag;
1463   
1464    objectloop (o in descin) give o ~workflag;
1465   
1466    k=0;
1467    objectloop (o in descin)
1468        if (o hasnt concealed && NotSupportingThePlayer(o))
1469        {  #IFNDEF MANUAL_PRONOUNS;
1470           PronounNotice(o);
1471           #ENDIF;
1472           if (o hasnt scenery)
1473           {   give o workflag; k++;
1474               p=initial; f2=0;
1475               if ((o has door || o has container)
1476                   && o has open && o provides when_open)
1477               {   p = when_open; f2 = 1; jump Prop_Chosen; }
1478               if ((o has door || o has container)
1479                   && o hasnt open && o provides when_closed)
1480               {   p = when_closed; f2 = 1; jump Prop_Chosen; }
1481               if (o has switchable
1482                   && o has on && o provides when_on)
1483               {   p = when_on; f2 = 1; jump Prop_Chosen; }
1484               if (o has switchable
1485                   && o hasnt on && o provides when_off)
1486               {   p = when_off; f2 = 1; }
1487   
1488               .Prop_Chosen;
1489   
1490               if (o hasnt moved || o.describe~=NULL || f2==1)
1491               {   if (o.describe~=NULL && RunRoutines(o,describe)~=0)
1492                   {   flag=1;
1493                       give o ~workflag; k--;
1494                   }    
1495                   else
1496                   {   j=o.p;
1497                       if (j~=0)
1498                       {   new_line;
1499                           PrintOrRun(o,p);
1500                           flag=1;
1501                           give o ~workflag; k--;
1502                           if (o has supporter && child(o)~=0) SayWhatsOn(o);
1503                       }
1504                   }
1505               }
1506           }
1507           else
1508               if (o has supporter && child(o)~=0) SayWhatsOn(o);
1509        }
1510   
1511    if (k==0) return 0;
1512   
1513    if (text1~=0)
1514    {   new_line;
1515        if (flag==1) text1=text2;
1516        print (string) text1, " ";
1517        WriteListFrom(child(descin),
1518            ENGLISH_BIT + WORKFLAG_BIT + RECURSE_BIT
1519            + PARTINV_BIT + TERSE_BIT + CONCEAL_BIT);
1520        return k;
1521    }
1522             
1523    if (flag==1) L__M(##Look,5,descin); else L__M(##Look,6,descin);
1524  ];
1525   
1526  ! ----------------------------------------------------------------------------
1527  !   Looking.  LookSub(1) is allowed to abbreviate long descriptions, but
1528  !     LookSub(0) (which is what happens when the Look action is generated)
1529  !     isn't.  (Except that these are over-ridden by the player-set lookmode.)
1530  ! ----------------------------------------------------------------------------
1531   
1532  [ LMode1Sub; lookmode=1; print (string) Story; L__M(##LMode1); ];  ! Brief
1533   
1534  [ LMode2Sub; lookmode=2; print (string) Story; L__M(##LMode2); ];  ! Verbose
1535   
1536  [ LMode3Sub; lookmode=3; print (string) Story; L__M(##LMode3); ];  ! Superbrief
1537   
1538  [ NoteArrival descin;
1539    if (location==thedark) { lastdesc = thedark; return; }
1540    if (location~=lastdesc)
1541    {   if (location.initial~=0) PrintOrRun(location, initial);
1542        descin = location;
1543        NewRoom();
1544        lastdesc = descin;
1545    }
1546  ];
1547   
1548  [ ScoreArrival;
1549    if (location hasnt visited)
1550    {   give location visited;
1551        if (location has scored)
1552        {   score = score + ROOM_SCORE;
1553            places_score = places_score + ROOM_SCORE;
1554        }
1555    }
1556  ];
1557   
1558  [ FindVisibilityLevels visibility_levels;
1559    visibility_levels = 1;
1560    visibility_ceiling = parent(player);
1561    while ((parent(visibility_ceiling) ~= 0)
1562           && (visibility_ceiling hasnt container
1563               || visibility_ceiling has open
1564               || visibility_ceiling has transparent))
1565    {   visibility_ceiling = parent(visibility_ceiling);
1566        visibility_levels++;
1567    }      
1568    return visibility_levels;
1569  ];
1570   
1571  [ LookSub allow_abbrev  visibility_levels i j k;
1572    if (parent(player)==0) return RunTimeError(10);
1573   
1574    .MovedByInitial;
1575    if (location == thedark) { visibility_ceiling = thedark; NoteArrival(); }
1576    else
1577    {   visibility_levels = FindVisibilityLevels();
1578        if (visibility_ceiling == location)
1579        {   NoteArrival();
1580            if (visibility_ceiling ~= location) jump MovedByInitial;
1581        }
1582    }
1583   
1584    !   Printing the top line: e.g.
1585    !   Octagonal Room (on the table) (as Frodo)
1586   
1587    new_line;
1588    style bold;
1589    if (visibility_levels == 0) print (name) thedark;
1590    else
1591    {   if (visibility_ceiling ~= location) print (The) visibility_ceiling;
1592        else print (name) visibility_ceiling;
1593    }
1594    style roman;
1595   
1596    for (j=1, i=parent(player):j<visibility_levels:j++, i=parent(i))
1597        if (i has supporter) L__M(##Look,1,i);
1598                        else L__M(##Look,2,i);
1599   
1600    if (print_player_flag==1) L__M(##Look,3,player);
1601    new_line;
1602   
1603    !   The room description (if visible)
1604   
1605    if (lookmode<3 && visibility_ceiling==location)
1606    {   if ((allow_abbrev~=1) || (lookmode==2) || (location hasnt visited))
1607        {   if (location.describe~=NULL) RunRoutines(location,describe);
1608            else
1609            {   if (location.description==0) RunTimeError(11,location);
1610                else PrintOrRun(location,description);
1611            }
1612        }
1613    }
1614   
1615    if (visibility_levels == 0) Locale(thedark);
1616    else
1617    {   for (i=player, j=visibility_levels: j>0: j--, i=parent(i))
1618            give i workflag;
1619        
1620        for (j=visibility_levels: j>0: j--)
1621        {   for (i=player, k=0: k<j: k++) i=parent(i);
1622            if (i.inside_description~=0)
1623            {   new_line; PrintOrRun(i,inside_description); }
1624            Locale(i);
1625        }
1626    }
1627   
1628    LookRoutine();
1629    ScoreArrival();
1630   
1631    action=##Look;
1632    if (AfterRoutines()==1) rtrue;
1633  ];
1634   
1635  [ ExamineSub i;
1636    if (location==thedark) return L__M(##Examine,1);
1637    i=noun.description;
1638    if (i==0)
1639    {   if (noun has container) <<Search noun>>;
1640        if (noun has switchable) { L__M(##Examine,3,noun); rfalse; }
1641        return L__M(##Examine,2,noun);
1642    }
1643    PrintOrRun(noun, description);
1644    if (noun has switchable) L__M(##Examine,3,noun);
1645    if (AfterRoutines()==1) rtrue;
1646  ];
1647   
1648  [ LookUnderSub;
1649    if (location==thedark) return L__M(##LookUnder,1);
1650    L__M(##LookUnder,2);
1651  ];
1652   
1653  [ SearchSub i f;
1654    if (location==thedark) return L__M(##Search,1,noun);
1655    if (ObjectIsUntouchable(noun)) return;
1656    objectloop (i in noun) if (i hasnt concealed && i hasnt scenery) f=1;
1657    if (noun has supporter)
1658    {   if (f==0) return L__M(##Search,2,noun);
1659        return L__M(##Search,3,noun);
1660    }
1661    if (noun hasnt container) return L__M(##Search,4,noun);
1662    if (noun hasnt transparent && noun hasnt open)
1663        return L__M(##Search,5,noun);
1664    if (AfterRoutines()==1) rtrue;
1665   
1666    i=children(noun);
1667    if (f==0) return L__M(##Search,6,noun);
1668    L__M(##Search,7,noun);
1669  ];
1670   
1671  ! ----------------------------------------------------------------------------
1672  !   Verbs which change the state of objects without moving them
1673  ! ----------------------------------------------------------------------------
1674   
1675  [ UnlockSub;
1676    if (ObjectIsUntouchable(noun)) return;
1677    if (noun hasnt lockable) return L__M(##Unlock,1,noun);
1678    if (noun hasnt locked)   return L__M(##Unlock,2,noun);
1679    if (noun.with_key~=second) return L__M(##Unlock,3,second);
1680    give noun ~locked;
1681    if (AfterRoutines()==1) rtrue;
1682    if (keep_silent==1) rtrue;
1683    L__M(##Unlock,4,noun);
1684  ];
1685   
1686  [ LockSub;
1687    if (ObjectIsUntouchable(noun)) return;
1688    if (noun hasnt lockable) return L__M(##Lock,1,noun);
1689    if (noun has locked)     return L__M(##Lock,2,noun);
1690    if (noun has open)       return L__M(##Lock,3,noun);
1691    if (noun.with_key~=second) return L__M(##Lock,4,second);
1692    give noun locked;
1693    if (AfterRoutines()==1) rtrue;
1694    if (keep_silent==1) rtrue;
1695    L__M(##Lock,5,noun);
1696  ];
1697   
1698  [ SwitchonSub;
1699    if (ObjectIsUntouchable(noun)) return;
1700    if (noun hasnt switchable) return L__M(##SwitchOn,1,noun);
1701    if (noun has on) return L__M(##SwitchOn,2,noun);
1702    give noun on;
1703    if (AfterRoutines()==1) rtrue;
1704    if (keep_silent==1) rtrue;
1705    L__M(##SwitchOn,3,noun);
1706  ];
1707   
1708  [ SwitchoffSub;
1709    if (ObjectIsUntouchable(noun)) return;
1710    if (noun hasnt switchable) return L__M(##SwitchOff,1,noun);
1711    if (noun hasnt on) return L__M(##SwitchOff,2,noun);
1712    give noun ~on;
1713    if (AfterRoutines()==1) rtrue;
1714    if (keep_silent==1) rtrue;
1715    L__M(##SwitchOff,3,noun);
1716  ];
1717   
1718  [ OpenSub;
1719    if (ObjectIsUntouchable(noun)) return;
1720    if (noun hasnt openable) return L__M(##Open,1,noun);
1721    if (noun has locked)     return L__M(##Open,2,noun);
1722    if (noun has open)       return L__M(##Open,3,noun);
1723    give noun open;
1724    if (AfterRoutines()==1) rtrue;
1725    if (keep_silent==1) rtrue;
1726    if (noun has container && noun hasnt transparent && child(noun)~=0
1727        && IndirectlyContains(noun,player)==0)
1728        return L__M(##Open,4,noun);
1729    L__M(##Open,5,noun);
1730  ];
1731   
1732  [ CloseSub;
1733    if (ObjectIsUntouchable(noun)) return;
1734    if (noun hasnt openable) return L__M(##Close,1,noun);
1735    if (noun hasnt open)     return L__M(##Close,2,noun);
1736    give noun ~open;
1737    if (AfterRoutines()==1) rtrue;
1738    if (keep_silent==1) rtrue;
1739    L__M(##Close,3,noun);
1740  ];
1741   
1742  [ DisrobeSub;
1743    if (ObjectIsUntouchable(noun)) return;
1744    if (noun hasnt worn) return L__M(##Disrobe,1,noun);
1745    give noun ~worn;
1746    if (AfterRoutines()==1) rtrue;
1747    if (keep_silent==1) rtrue;
1748    L__M(##Disrobe,2,noun);
1749  ];
1750   
1751  [ WearSub;
1752    if (ObjectIsUntouchable(noun)) return;
1753    if (noun hasnt clothing)  return L__M(##Wear,1,noun);
1754    if (parent(noun)~=player) return L__M(##Wear,2,noun);
1755    if (noun has worn)        return L__M(##Wear,3,noun);
1756    give noun worn;
1757    if (AfterRoutines()==1) rtrue;
1758    if (keep_silent==1) rtrue;
1759    L__M(##Wear,4,noun);
1760  ];
1761   
1762  [ EatSub;
1763    if (ObjectIsUntouchable(noun)) return;
1764    if (noun hasnt edible) return L__M(##Eat,1,noun);
1765    if (noun has worn)
1766    {   L__M(##Drop,3,noun);
1767        <Disrobe noun>;
1768        if (noun has worn && noun in player) rtrue;
1769    }
1770    remove noun;
1771    if (AfterRoutines()==1) rtrue;
1772    if (keep_silent==1) rtrue;
1773    L__M(##Eat,2,noun);
1774  ];
1775   
1776  ! ----------------------------------------------------------------------------
1777  !   Verbs which are really just stubs (anything which happens for these
1778  !   actions must happen in before rules)
1779  ! ----------------------------------------------------------------------------
1780   
1781  [ YesSub; L__M(##Yes); ];
1782  [ NoSub; L__M(##No); ];
1783  [ BurnSub; L__M(##Burn,1,noun); ];
1784  [ PraySub; L__M(##Pray,1,noun); ];
1785  [ WakeSub; L__M(##Wake,1,noun); ];
1786  [ WakeOtherSub;
1787    if (ObjectIsUntouchable(noun)) return;
1788    if (RunLife(noun,##WakeOther)~=0) rfalse;
1789    L__M(##WakeOther,1,noun);
1790  ];
1791  [ ThinkSub; L__M(##Think,1,noun); ];
1792  [ SmellSub; L__M(##Smell,1,noun); ];
1793  [ ListenSub; L__M(##Listen,1,noun); ];
1794  [ TasteSub; L__M(##Taste,1,noun); ];
1795  [ DigSub; L__M(##Dig,1,noun); ];
1796  [ CutSub; L__M(##Cut,1,noun); ];
1797  [ JumpSub; L__M(##Jump,1,noun); ];
1798  [ JumpOverSub; L__M(##JumpOver,1,noun); ];
1799  [ TieSub; L__M(##Tie,1,noun); ];
1800  [ DrinkSub; L__M(##Drink,1,noun); ];
1801  [ FillSub; L__M(##Fill,1,noun); ];
1802  [ SorrySub; L__M(##Sorry,1,noun); ];
1803  [ StrongSub; L__M(##Strong,1,noun); ];
1804  [ MildSub; L__M(##Mild,1,noun); ];
1805  [ SwimSub; L__M(##Swim,1,noun); ];
1806  [ SwingSub; L__M(##Swing,1,noun); ];
1807  [ BlowSub; L__M(##Blow,1,noun); ];
1808  [ RubSub; L__M(##Rub,1,noun); ];
1809  [ SetSub; L__M(##Set,1,noun); ];
1810  [ SetToSub; L__M(##SetTo,1,noun); ];
1811  [ WaveHandsSub; L__M(##WaveHands,1,noun); ];
1812  [ BuySub; L__M(##Buy,1,noun); ];
1813  [ SingSub; L__M(##Sing,1,noun); ];
1814  [ ClimbSub; L__M(##Climb,1,noun); ];
1815  [ SleepSub; L__M(##Sleep,1,noun); ];
1816  [ ConsultSub; L__M(##Consult,1,noun); ];
1817  [ TouchSub;
1818    if (noun==player) return L__M(##Touch,3,noun);
1819    if (ObjectIsUntouchable(noun)) return;
1820    if (noun has animate) return L__M(##Touch,1,noun);
1821    L__M(##Touch,2,noun); ];
1822  [ WaveSub;
1823    if (parent(noun)~=player) return L__M(##Wave,1,noun);
1824    L__M(##Wave,2,noun); ];
1825  [ PullSub;
1826    if (ObjectIsUntouchable(noun)) return;
1827    if (noun has static)   return L__M(##Pull,1,noun);
1828    if (noun has scenery)  return L__M(##Pull,2,noun);
1829    if (noun has animate)  return L__M(##Pull,4,noun);
1830    L__M(##Pull,3,noun);
1831  ];
1832  [ PushSub;
1833    if (ObjectIsUntouchable(noun)) return;
1834    if (noun has static)   return L__M(##Push,1,noun);
1835    if (noun has scenery)  return L__M(##Push,2,noun);
1836    if (noun has animate)  return L__M(##Pull,4,noun);
1837    L__M(##Push,3,noun);
1838  ];
1839  [ TurnSub;
1840    if (ObjectIsUntouchable(noun)) return;
1841    if (noun has static)   return L__M(##Turn,1,noun);
1842    if (noun has scenery)  return L__M(##Turn,2,noun);
1843    if (noun has animate)  return L__M(##Pull,4,noun);
1844    L__M(##Turn,3,noun);
1845  ];
1846   
1847  [ WaitSub;
1848    if (AfterRoutines()==1) rtrue;
1849    L__M(##Wait,1,noun);
1850  ];
1851   
1852  [ PushDirSub; L__M(##PushDir,1,noun); ];
1853  [ AllowPushDir i;
1854    if (parent(second)~=compass) return L__M(##PushDir,2,noun);
1855    if (second==u_obj or d_obj)  return L__M(##PushDir,3,noun);
1856    AfterRoutines(); i=noun; move i to player;
1857    <Go second>;
1858    if (location==thedark) move i to real_location;
1859    else move i to location;
1860  ];
1861   
1862  [ SqueezeSub;
1863    if (ObjectIsUntouchable(noun)) return;
1864    if (noun has animate) return L__M(##Squeeze,1,noun);
1865    L__M(##Squeeze,2,noun);
1866  ];
1867   
1868  [ ThrowAtSub;
1869    if (ObjectIsUntouchable(noun)) return;
1870    if (second>1)
1871    {   action=##ThrownAt;
1872        if (RunRoutines(second,before)~=0) { action=##ThrowAt; rtrue; }
1873        action=##ThrowAt;
1874    }
1875    if (noun has worn)
1876    {   L__M(##Drop,3,noun);
1877        <Disrobe noun>;
1878        if (noun has worn && noun in player) rtrue;
1879    }
1880    if (second hasnt animate) return L__M(##ThrowAt,1);
1881    if (RunLife(second,##ThrowAt)~=0) rfalse;
1882    L__M(##ThrowAt,2,noun);
1883  ];
1884   
1885  [ AttackSub;
1886    if (ObjectIsUntouchable(noun)) return;
1887    if (noun has animate && RunLife(noun,##Attack)~=0) rfalse;
1888    L__M(##Attack,1,noun); ];
1889   
1890  [ KissSub;
1891    if (ObjectIsUntouchable(noun)) return;
1892    if (RunLife(noun,##Kiss)~=0) rfalse;
1893    if (noun==player) return L__M(##Touch,3,noun);
1894    L__M(##Kiss,1,noun);
1895  ];
1896   
1897  [ AnswerSub;
1898    if (second~=0 && RunLife(second,##Answer)~=0) rfalse;
1899    L__M(##Answer,1,noun);
1900  ];  
1901   
1902  [ TellSub;
1903    if (noun==player) return L__M(##Tell,1,noun);
1904    if (RunLife(noun,##Tell)~=0) rfalse;
1905    L__M(##Tell,2,noun);
1906  ];  
1907    
1908  [ AskSub;
1909    if (RunLife(noun,##Ask)~=0) rfalse;
1910    L__M(##Ask,1,noun);
1911  ];  
1912   
1913  [ AskForSub;
1914    if (noun==player) <<Inv>>;
1915    L__M(##Order,1,noun);
1916  ];
1917   
1918  ! ----------------------------------------------------------------------------
1919  !   Debugging verbs
1920  ! ----------------------------------------------------------------------------
1921   
1922  #IFDEF DEBUG;
1923  [ TraceOnSub; parser_trace=1; "[Trace on.]"; ];
1924  [ TraceLevelSub; parser_trace=noun;
1925    print "[Parser tracing set to level ", parser_trace, ".]^"; ];
1926  [ TraceOffSub; parser_trace=0; "Trace off."; ];
1927  [ RoutinesOnSub;  debug_flag=debug_flag | 1; "[Message listing on.]"; ];
1928  [ RoutinesOffSub; debug_flag=debug_flag & 14; "[Message listing off.]"; ];
1929  [ ActionsOnSub;  debug_flag=debug_flag | 2; "[Action listing on.]"; ];
1930  [ ActionsOffSub; debug_flag=debug_flag & 13; "[Action listing off.]"; ];
1931  [ TimersOnSub;  debug_flag=debug_flag | 4; "[Timers listing on.]"; ];
1932  [ TimersOffSub; debug_flag=debug_flag & 11; "[Timers listing off.]"; ];
1933  IFDEF VN_1610;
1934  [ ChangesOnSub;  debug_flag=debug_flag | 8; "[Changes listing on.]"; ];
1935  [ ChangesOffSub; debug_flag=debug_flag & 7; "[Changes listing off.]"; ];
1936  IFNOT;
1937  [ ChangesOnSub; "[Changes listing only available under Inform 6.2.]"; ];
1938  [ ChangesOffSub; "[Changes listing only available under Inform 6.2.]"; ];
1939  ENDIF;
1940  [ CommandsOnSub;
1941    @output_stream 4; xcommsdir=1; "[Command recording on.]"; ];
1942  [ CommandsOffSub;
1943    if (xcommsdir==1) @output_stream -4;
1944    xcommsdir=0;
1945    "[Command recording off.]"; ];
1946  [ CommandsReadSub;
1947    @input_stream 1; xcommsdir=2; "[Replaying commands.]"; ];
1948  [ PredictableSub i; i=random(-100);
1949    "[Random number generator now predictable.]"; ];
1950  [ XTestMove obj dest;
1951    if ((obj<=InformLibrary) || (obj == LibraryMessages) || (obj in 1))
1952       "[Can't move ", (name) obj, ": it's a system object.]";
1953    while (dest ~= 0)
1954    {   if (dest == obj)
1955            "[Can't move ", (name) obj, ": it would contain itself.]";
1956        dest = parent(dest);
1957    }
1958    rfalse;
1959  ];
1960  [ XPurloinSub;
1961    if (XTestMove(noun,player)) return;
1962    move noun to player; give noun moved ~concealed;
1963    "[Purloined.]"; ];
1964  [ XAbstractSub;
1965    if (XTestMove(noun,second)) return;
1966    move noun to second; "[Abstracted.]"; ];
1967  [ XObj obj f;
1968    if (parent(obj) == 0) print (name) obj; else print (a) obj;
1969    print " (", obj, ") ";
1970    if (f==1 && parent(obj) ~= 0)
1971        print "(in ", (name) parent(obj), " ", parent(obj), ")";
1972    new_line;
1973    if (child(obj)==0) rtrue;
1974    if (obj == Class)
1975        WriteListFrom(child(obj),
1976        NOARTICLE_BIT + INDENT_BIT + NEWLINE_BIT + ALWAYS_BIT, 1);
1977    else
1978        WriteListFrom(child(obj),
1979        FULLINV_BIT + INDENT_BIT + NEWLINE_BIT + ALWAYS_BIT, 1);
1980  ];
1981  [ XTreeSub i;
1982    if (noun==0)
1983    {   objectloop(i) if (i ofclass Object && parent(i)==0) XObj(i);
1984    }
1985    else XObj(noun,1);
1986  ];
1987  [ GotoSub;
1988    if (~~(noun ofclass Object) || (parent(noun)~=0)) "[Not a safe place.]";
1989    PlayerTo(noun);
1990  ];
1991  [ GonearSub x; x=noun; while (parent(x)~=0) x=parent(x); PlayerTo(x); ];
1992  [ Print_ScL obj; print_ret ++x_scope_count, ": ", (a) obj, " (", obj, ")"; ];
1993  [ ScopeSub; x_scope_count=0; LoopOverScope(#r$Print_ScL, noun);
1994    if (x_scope_count==0) "Nothing is in scope.";
1995  ];
1996  #ENDIF;
1997   
1998  ! ----------------------------------------------------------------------------
1999  !   Finally: the mechanism for library text (the text is in the language defn)
2000  ! ----------------------------------------------------------------------------
2001   
2002  [ L__M act n x1 s;
2003    s=sw__var; sw__var=act; if (n==0) n=1;
2004    L___M(n,x1);
2005    sw__var=s;
2006  ];
2007   
2008  [ L___M n x1 s;
2009    s=action;
2010    lm_n=n; lm_o=x1;
2011    action=sw__var;
2012    if (RunRoutines(LibraryMessages,before)~=0) { action=s; rfalse; }
2013    action=s;
2014   
2015    LanguageLM(n, x1);
2016  ];
2017   
2018  ! ----------------------------------------------------------------------------


Last updated 27 February 2004. This web site has not been fully supported since April 2008. Information may be out of date. This page was originally managed by Graham Nelson (graham@gnelson.demon.co.uk) assisted by C Knight.