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 site is no longer supported; information may be out of date.
Maintained as a historical archive by the Interactive Fiction Technology Foundation. Copyright 1993-2018 IFTF, CC-BY-SA unless otherwise noted.
This page was originally managed by Graham Nelson (graham@gnelson.demon.co.uk) assisted by C Knight.