home *** CD-ROM | disk | FTP | other *** search
/ Sunny 1,000 Collection / SUNNY1000.iso / Files / Dos / infoco3 / LIBRARY.ZIP / verblib.h < prev   
Encoding:
Text File  |  1995-10-24  |  59.5 KB  |  1,844 lines

  1. ! ----------------------------------------------------------------------------
  2. !  "VERBLIB" header for Inform 5: release 5/12, serial number 951023
  3. !
  4. !  (c) Graham Nelson 1993, 1994, 1995, but freely usable (see documentation)
  5. ! ----------------------------------------------------------------------------
  6. System_file;
  7. Default MAX_CARRIED  100;
  8. Default MAX_SCORE    0;
  9. Default NUMBER_TASKS 1;
  10. Default OBJECT_SCORE 4;
  11. Default ROOM_SCORE   5;
  12. Default SACK_OBJECT  0;   
  13. Default AMUSING_PROVIDED 1;
  14. Default TASKS_PROVIDED   1;
  15. #IFNDEF task_scores; Constant MAKE__TS; #ENDIF;
  16. #IFDEF MAKE__TS;
  17. Array  task_scores --> 0 0;
  18. #ENDIF;
  19. Array  task_done --> NUMBER_TASKS;
  20.  
  21. ! ----------------------------------------------------------------------------
  22. !  First, printing a number n in English.
  23. !  It's this sort of thing which makes you realise just what an irregular
  24. !  language English is...
  25. ! ----------------------------------------------------------------------------
  26.  
  27. [ EnglishNumber n m f;
  28.   if (n==0) { print "zero"; rfalse; }
  29.   if (n<0) { print "minus "; n=-n; }
  30.   if (n>=1000) { EnglishNumber(n/1000); print " thousand"; n=n%1000; f=1; }
  31.   if (n>=100)  { if (f==1) print ", ";
  32.                  EnglishNumber(n/100); print " hundred"; n=n%100; f=1; }
  33.   if (n==0) rfalse;
  34.   if (f==1) print " and ";            ! Americans may want to delete this line
  35.   if (n<10) { EnglishDigit(n); rfalse; }
  36.   if (n>=20)
  37.   {   m=n/10;
  38.       if (m==2) print "twenty";
  39.       if (m==3) print "thirty";
  40.       if (m==4) print "forty";
  41.       if (m==5) print "fifty";
  42.       if (m==6) print "sixty";
  43.       if (m==7) print "seventy";
  44.       if (m==8) print "eighty";
  45.       if (m==9) print "ninety";
  46.       if (n%10==0) rfalse;
  47.       print "-"; EnglishDigit(n%10); rfalse;
  48.   }
  49.   if (n==10) { print "ten"; rfalse; }
  50.   if (n==11) { print "eleven"; rfalse; }
  51.   if (n==12) { print "twelve"; rfalse; }
  52.   if (n==13) { print "thirteen"; rfalse; }
  53.   if (n==14) { print "fourteen"; rfalse; }
  54.   if (n==15) { print "fifteen"; rfalse; }
  55.   if (n==16) { print "sixteen"; rfalse; }
  56.   if (n==17) { print "seventeen"; rfalse; }
  57.   if (n==18) { print "eighteen"; rfalse; }
  58.   print "nineteen";
  59. ];
  60.  
  61. [ EnglishDigit n;
  62.   if (n==1) { print "one"; rfalse; }
  63.   if (n==2) { print "two"; rfalse; }
  64.   if (n==3) { print "three"; rfalse; }
  65.   if (n==4) { print "four"; rfalse; }
  66.   if (n==5) { print "five"; rfalse; }
  67.   if (n==6) { print "six"; rfalse; }
  68.   if (n==7) { print "seven"; rfalse; }
  69.   if (n==8) { print "eight"; rfalse; }
  70.   if (n==9) { print "nine"; rfalse; }
  71. ];
  72.  
  73. ! ----------------------------------------------------------------------------
  74. !  Next the WriteListFrom routine, a flexible object-lister taking care of
  75. !  plurals, inventory information, various formats and so on.  This is used
  76. !  by everything in the library which ever wants to list anything.
  77. !
  78. !  If there were no objects to list, it prints nothing and returns false;
  79. !  otherwise it returns true.
  80. !
  81. !  o is the object, and style is a bitmap, whose bits are given by:
  82. ! ----------------------------------------------------------------------------
  83.  
  84. Constant NEWLINE_BIT    1;    !  New-line after each entry
  85. Constant INDENT_BIT     2;    !  Indent each entry by depth
  86. Constant FULLINV_BIT    4;    !  Full inventory information after entry
  87. Constant ENGLISH_BIT    8;    !  English sentence style, with commas and and
  88. Constant RECURSE_BIT   16;    !  Recurse downwards with usual rules
  89. Constant ALWAYS_BIT    32;    !  Always recurse downwards
  90. Constant TERSE_BIT     64;    !  More terse English style
  91. Constant PARTINV_BIT  128;    !  Only brief inventory information after entry
  92. Constant DEFART_BIT   256;    !  Use the definite article in list
  93. Constant WORKFLAG_BIT 512;    !  At top level (only), only list objects
  94.                               !  which have the "workflag" attribute
  95. Constant ISARE_BIT   1024;    !  Print " is" or " are" before list
  96. Constant CONCEAL_BIT 2048;    !  Omit objects with "concealed" or "scenery":
  97.                               !  if WORKFLAG_BIT also set, then does _not_
  98.                               !  apply at top level, but does lower down
  99. Constant NOARTICLE_BIT 4096;  !  Print no articles, definite or not
  100.  
  101. [ NextEntry o odepth;
  102.   o=sibling(o);
  103.   if (lt_value~=0)
  104.   {   if (c_style & WORKFLAG_BIT ~= 0 && odepth==0)
  105.       {   while (o~=0 && (o.list_together~=lt_value
  106.                           || o hasnt workflag)) o=sibling(o);
  107.           return o;
  108.       }
  109.       if (c_style & CONCEAL_BIT ~= 0)
  110.       {   while (o~=0 &&
  111.                  (o has concealed || o has scenery
  112.                   || o.list_together~=lt_value)) o=sibling(o);
  113.           return o;
  114.       }
  115.       while (o~=0 && o.list_together~=lt_value) o=sibling(o);
  116.       return o;
  117.   }
  118.   if (c_style & WORKFLAG_BIT ~= 0 && odepth==0)
  119.   {   while (o~=0 && o hasnt workflag) o=sibling(o);
  120.       return o;
  121.   }
  122.   if (c_style & CONCEAL_BIT ~= 0)
  123.       while (o~=0 && (o has concealed || o has scenery)) o=sibling(o);
  124.   return o;
  125. ];
  126.  
  127. [ WillRecurs o;
  128.   if (c_style & ALWAYS_BIT ~= 0) rtrue;
  129.   if (c_style & RECURSE_BIT == 0) rfalse;
  130.   if (o has transparent
  131.       || o has supporter
  132.       || (o has container && o has open)) rtrue;
  133.   rfalse;
  134. ];
  135.  
  136. [ ListEqual o1 o2;
  137.   if (child(o1)~=0 && WillRecurs(o1)~=0) rfalse;
  138.   if (child(o2)~=0 && WillRecurs(o2)~=0) rfalse;
  139.  
  140.   if (c_style & (FULLINV_BIT + PARTINV_BIT) ~= 0)
  141.   {   if ((o1 hasnt worn && o2 has worn)
  142.           || (o2 hasnt worn && o1 has worn)) rfalse;
  143.       if ((o1 hasnt light && o2 has light)
  144.           || (o2 hasnt light && o1 has light)) rfalse;
  145.   }
  146.  
  147.   return Identical(o1,o2);
  148. ];
  149.  
  150. [ SortTogether obj value;
  151. !  print "Sorting together possessions of ",
  152. !         object obj, " by value ", value, "^";
  153.   while (child(obj)~=0)
  154.   {   if (child(obj).list_together~=value) move child(obj) to out_obj;
  155.       else move child(obj) to in_obj;
  156.   }
  157.   while (child(in_obj)~=0)
  158.       move child(in_obj) to obj;
  159.   while (child(out_obj)~=0)
  160.       move child(out_obj) to obj;
  161. ];
  162.  
  163. [ SortOutList obj i k l;
  164. !  print "^^Sorting out list from ", (name) obj, "^  ";
  165. !  for (i=child(location):i~=0:i=sibling(i))
  166. !      print (name) i, " --> ";
  167. !  new_line;
  168.  .AP_SOL;
  169.   for (i=obj:i~=0:i=sibling(i))
  170.   {   k=i.list_together;
  171.       if (k~=0)
  172.       {   ! print "Scanning ", (name) i, " with lt=", k, "^";
  173.           for (i=sibling(i):i~=0 && i.list_together==k:) i=sibling(i);
  174.               if (i==0) rfalse;
  175.           ! print "First not in block is ", (name) i,
  176.           ! " with lt=", i.list_together, "^";
  177.           for (l=sibling(i):l~=0:l=sibling(l))
  178.               if (l.list_together==k)
  179.               {   SortTogether(parent(obj), k);
  180. !  print "^^After ST:^  ";
  181. !  for (i=child(location):i~=0:i=sibling(i))
  182. !      print (name) i, " --> ";
  183. !  new_line;
  184.                   obj = child(parent(obj));
  185.                   jump AP_SOL;
  186.               }
  187.       }
  188.   }
  189. ];
  190.  
  191. [ WriteListFrom o style depth;
  192.   if (o==child(parent(o)))
  193.   {   SortOutList(o); o=child(parent(o)); }
  194.   c_style=style;
  195.   if (style & WORKFLAG_BIT ~= 0)
  196.   {   while (o~=0 && o hasnt workflag) o=sibling(o);
  197.   }
  198.   else
  199.   {   if (c_style & CONCEAL_BIT ~= 0)
  200.           while (o~=0 && (o has concealed || o has scenery)) o=sibling(o);
  201.   }
  202.   if (o==0) rfalse;
  203.   wlf_indent=0; WriteListR(o,depth);
  204.   rtrue;
  205. ];
  206.  
  207. [ WriteListR o depth stack_pointer  classes_p sizes_p i j k k2 l m n q senc mr;
  208.  
  209.   if (depth>0 && o==child(parent(o)))
  210.   {   SortOutList(o); o=child(parent(o)); }
  211.  
  212.   classes_p = match_classes + stack_pointer;
  213.   sizes_p   = match_list + stack_pointer;
  214.  
  215.   for (i=o,j=0:i~=0 && (j+stack_pointer)<128:i=NextEntry(i,depth),j++)
  216.   {   classes_p->j=0;
  217.       if (i.plural~=0) k++;
  218.   }
  219.  
  220.   if (c_style & ISARE_BIT ~= 0)
  221.   {   if (j==1) print " is"; else print " are";
  222.       if (c_style & NEWLINE_BIT ~= 0) print ":^"; else print char ' ';
  223.       c_style = c_style - ISARE_BIT;
  224.   }
  225.  
  226.   stack_pointer = stack_pointer+j+1;
  227.  
  228.   if (k<2) jump EconomyVersion;   ! It takes two to plural
  229.  
  230.   n=1;
  231.   for (i=o,k=0:k<j:i=NextEntry(i,depth),k++)
  232.       if (classes_p->k==0)
  233.       {   classes_p->k=n; sizes_p->n=1;
  234.           for (l=NextEntry(i,depth), m=k+1:l~=0 && m<j:
  235.                l=NextEntry(l,depth), m++)
  236.               if (classes_p->m==0 && i.plural~=0 && l.plural~=0)
  237.               {   if (ListEqual(i,l)==1)
  238.                   {   sizes_p->n = sizes_p->n + 1;
  239.                       classes_p->m = n;
  240.                   }
  241.               }
  242.           n++;
  243.       }
  244.   n--;
  245.  
  246.   for (i=1, j=o, k=0: i<=n: i++, senc++)
  247.   {   while (((classes_p->k) ~= i)
  248.              && ((classes_p->k) ~= -i)) { k++; j=NextEntry(j,depth); }
  249.       m=sizes_p->i;
  250.       if (j.list_together~=0 or lt_value
  251.           && ZRegion(j.list_together)==2 or 3
  252.           && j.list_together==mr) senc--;
  253.       mr=j.list_together;
  254.   }
  255.   senc--;
  256.   for (i=1, j=o, k=0, mr=0: senc>=0: i++, senc--)
  257.   {   while (((classes_p->k) ~= i)
  258.              && ((classes_p->k) ~= -i)) { k++; j=NextEntry(j,depth); }
  259.       if (j.list_together~=0 or lt_value)
  260.       {   if (j.list_together==mr) { senc++; jump Omit_FL2; }
  261.           k2=NextEntry(j,depth);
  262.           if (k2==0 || k2.list_together~=j.list_together) jump Omit_WL2;
  263.           k2=ZRegion(j.list_together);
  264.           if (k2==2 or 3)
  265.           {   q=j; listing_size=1; l=k; m=i;
  266.               while (m<n && q.list_together==j.list_together)
  267.               {   m++;
  268.                   while (((classes_p->l) ~= m)
  269.                          && ((classes_p->l) ~= -m))
  270.                   {   l++; q=NextEntry(q,depth); }
  271.                   if (q.list_together==j.list_together) listing_size++;
  272.               }
  273. !              print " [", listing_size, "] ";
  274.               if (listing_size==1) jump Omit_WL2;
  275.               if (c_style & INDENT_BIT ~= 0) spaces 2*(depth+wlf_indent);
  276.               if (k2==3)
  277.               {   q=0; for (l=0:l<listing_size:l++) q=q+sizes_p->(l+i);
  278.                   EnglishNumber(q); print " ";
  279.                   print_paddr j.list_together;
  280.                   if (c_style & ENGLISH_BIT ~= 0) print " (";
  281.                   if (c_style & INDENT_BIT ~= 0) print ":^";
  282.               }
  283.               q=c_style; l=0;
  284.               if (k2~=3)
  285.               {   inventory_stage=1;
  286.                   parser_one=j; parser_two=depth+wlf_indent;
  287.                   sp=RunRoutines(j,list_together);
  288.                   if (c_style & NEWLINE_BIT == 0 && q & NEWLINE_BIT ~= 0) l=1;
  289.                   if (sp==1) jump Omit__Sublist2;
  290.               }
  291.               lt_value=j.list_together; listing_together=j; wlf_indent++;
  292.               WriteListR(j,depth,stack_pointer); wlf_indent--;
  293.               lt_value=0; listing_together=0;
  294.               if (k2==3)
  295.               {   if (q & ENGLISH_BIT ~= 0) print ")";
  296.               }
  297.               else
  298.               {   inventory_stage=2;
  299.                   parser_one=j; parser_two=depth+wlf_indent;
  300.                   RunRoutines(j,list_together);
  301.               }
  302.              .Omit__Sublist2;
  303.               c_style=q; if (l==1) new_line;
  304.               mr=j.list_together;
  305.               jump Omit_EL2;
  306.           }
  307.       }
  308.  
  309.      .Omit_WL2;
  310.       if (WriteBeforeEntry(j,depth)==1) jump Omit_FL2;
  311.       if (sizes_p->i == 1)
  312.       {   if (c_style & NOARTICLE_BIT ~= 0) PrintShortName(j);
  313.           else
  314.           {   if (c_style & DEFART_BIT ~= 0) DefArt(j); else InDefArt(j);
  315.           }
  316.       }
  317.       else
  318.       {   if (c_style & DEFART_BIT ~= 0) print "the ";
  319.           EnglishNumber(sizes_p->i); print " ";
  320.           PrintOrRun(j,plural,1);
  321.       }
  322.       WriteAfterEntry(j,depth,stack_pointer);
  323.  
  324.      .Omit_EL2;
  325.       if (c_style & ENGLISH_BIT ~= 0)
  326.       {   if (senc==1) print " and ";
  327.           if (senc>1) print ", ";
  328.       }
  329.      .Omit_FL2;
  330.   }
  331.   rtrue;
  332.  
  333.   .EconomyVersion;
  334.  
  335.   n=j;
  336.  
  337.   for (i=1, j=o: i<=n: j=NextEntry(j,depth), i++, senc++)
  338.   {   if (j.list_together~=0 or lt_value
  339.           && ZRegion(j.list_together)==2 or 3
  340.           && j.list_together==mr) senc--;
  341.       mr=j.list_together;
  342.   }
  343.  
  344.   for (i=1, j=o, mr=0: i<=senc: j=NextEntry(j,depth), i++)
  345.   {   if (j.list_together~=0 or lt_value)
  346.       {   if (j.list_together==mr) { i--; jump Omit_FL; }
  347.           k=NextEntry(j,depth);
  348.           if (k==0 || k.list_together~=j.list_together) jump Omit_WL;
  349.           k=ZRegion(j.list_together);
  350.           if (k==2 or 3)
  351.           {   if (c_style & INDENT_BIT ~= 0) spaces 2*(depth+wlf_indent);
  352.               if (k==3)
  353.               {   q=j; l=0;
  354.                   do
  355.                   {   q=NextEntry(q,depth); l++;
  356.                   } until (q.list_together~=j.list_together);
  357.                   EnglishNumber(l); print " ";
  358.                   print_paddr j.list_together;
  359.                   if (c_style & ENGLISH_BIT ~= 0) print " (";
  360.                   if (c_style & INDENT_BIT ~= 0) print ":^";
  361.               }
  362.               q=c_style; l=0;
  363.               if (k~=3)
  364.               {   inventory_stage=1;
  365.                   parser_one=j; parser_two=depth+wlf_indent;
  366.                   sp = RunRoutines(j,list_together);
  367.                   if (c_style & NEWLINE_BIT == 0 && q & NEWLINE_BIT ~= 0) l=1;
  368.                   if (sp==1) jump Omit__Sublist;
  369.               }
  370.               lt_value=j.list_together; listing_together=j; wlf_indent++;
  371.               WriteListR(j,depth,stack_pointer); wlf_indent--;
  372.               lt_value=0; listing_together=0;
  373.               if (k==3)
  374.               {   if (c_style & ENGLISH_BIT ~= 0) print ")";
  375.               }
  376.               else
  377.               {   inventory_stage=2;
  378.                   parser_one=j; parser_two=depth+wlf_indent;
  379.                   RunRoutines(j,list_together);
  380.               }
  381.              .Omit__Sublist;
  382.               if (l==1) new_line;
  383.               c_style=q;
  384.               mr=j.list_together;
  385.               jump Omit_EL;
  386.           }
  387.       }
  388.      .Omit_WL;
  389.       if (WriteBeforeEntry(j,depth)==1) jump Omit_FL;
  390.       if (c_style & NOARTICLE_BIT ~= 0) PrintShortName(j);
  391.       else
  392.       {   if (c_style & DEFART_BIT ~= 0) DefArt(j); else InDefArt(j);
  393.       }
  394.       WriteAfterEntry(j,depth,stack_pointer);
  395.  
  396.      .Omit_EL;
  397.       if (c_style & ENGLISH_BIT ~= 0)
  398.       {   if (i==senc-1) print " and ";
  399.           if (i<senc-1) print ", ";
  400.       }
  401.      .Omit_FL;
  402.   }
  403. ];
  404.  
  405. [ WriteBeforeEntry o depth  flag;
  406.   if (c_style & INDENT_BIT ~= 0) spaces 2*(depth+wlf_indent);
  407.  
  408.   if (c_style & FULLINV_BIT ~= 0)
  409.   {   if (o.invent~=0)
  410.       {   inventory_stage=1;
  411.           flag=PrintOrRun(o,invent,1);
  412.           if (flag==1 && c_style & NEWLINE_BIT ~= 0) new_line;
  413.       }
  414.   }
  415.   return flag;
  416. ];
  417.  
  418. [ WriteAfterEntry o depth stack_p  flag flag2 flag3 p comb;
  419.  
  420.   if (c_style & PARTINV_BIT ~= 0)
  421.   {   comb=0;
  422.       if (o has light && location hasnt light) comb=comb+1;
  423.       if (o has container && o hasnt open)     comb=comb+2;
  424.       if ((o has container && (o has open || o has transparent))
  425.           && (child(o)==0)) comb=comb+4;
  426.       if (comb==1) print " (providing light)";
  427.       if (comb==2) print " (which is closed)";
  428.       if (comb==3) print " (closed and providing light)";
  429.       if (comb==4) print " (which is empty)";
  430.       if (comb==5) print " (empty and providing light)";
  431.       if (comb==6) print " (which is closed and empty)";
  432.       if (comb==7) print " (closed, empty and providing light)";
  433.   }
  434.  
  435.   if (c_style & FULLINV_BIT ~= 0)
  436.   {   if (o.invent ~= 0)
  437.       {   inventory_stage=2;
  438.           if (RunRoutines(o,invent)~=0)
  439.           {   if (c_style & NEWLINE_BIT ~= 0) new_line;
  440.               rtrue;
  441.           }
  442.       }
  443.       if (o has light && o has worn)
  444.       {   print " (providing light and being worn"; flag2=1; }
  445.       else
  446.       {   if (o has light) { print " (providing light"; flag2=1; }
  447.           if (o has worn)  { print " (being worn"; flag2=1; }
  448.       }
  449.       if (o has container)
  450.       {   if (o has openable)
  451.           {   if (flag2==1) print " and ";
  452.               else print " (which is ";
  453.               if (o has open)
  454.               {   print "open";
  455.                   if (child(o)==0) print " but empty";
  456.               }
  457.               else print "closed";
  458.               if (o has lockable && o has locked) print " and locked";
  459.               flag2=1;
  460.           }
  461.           else
  462.               if (child(o)==0)
  463.               {   if (flag2==1) print " and empty";
  464.                   else print " (which is empty)";
  465.               }
  466.       }
  467.       if (flag2==1) print ")";
  468.   }
  469.  
  470.   if (c_style & CONCEAL_BIT == 0)
  471.   {   if (child(o)~=0) flag3=children(o);
  472.   }
  473.   else
  474.   {   objectloop (p in o)
  475.           if (p hasnt concealed) flag3++;
  476.   }
  477.  
  478.   if (c_style & ALWAYS_BIT ~= 0 && flag3>0)
  479.   {   if (c_style & ENGLISH_BIT ~= 0) print " containing ";
  480.       flag=1;
  481.   }
  482.  
  483.   if (c_style & RECURSE_BIT ~= 0 && flag3>0)
  484.   {   if (o has supporter)
  485.       {   if (c_style & ENGLISH_BIT ~= 0)
  486.           {   if (c_style & TERSE_BIT ~= 0)
  487.               print " (on "; else print ", on top of ";
  488.               if (o has animate) print "whom "; else print "which ";
  489.           }
  490.           flag=1;
  491.       }
  492.       if (o has container && (o has open || o has transparent))
  493.       {   if (c_style & ENGLISH_BIT ~= 0)
  494.           {   if (c_style & TERSE_BIT ~= 0)
  495.                   print " (in "; else print ", inside ";
  496.               if (o has animate) print "whom "; else print "which ";
  497.           }
  498.           flag=1;
  499.       }
  500.   }
  501.  
  502.   if (flag==1 && c_style & ENGLISH_BIT ~= 0)
  503.   {   if (flag3 > 1) print "are "; else print "is ";
  504.   }
  505.  
  506.   if (c_style & NEWLINE_BIT ~= 0) new_line;
  507.  
  508.   if (flag==1) WriteListR(child(o),depth+1,stack_p);
  509.  
  510.   if (flag==1 && c_style & TERSE_BIT ~= 0) print ")";
  511. ];
  512.  
  513. ! ----------------------------------------------------------------------------
  514. !   A cunning routine (which could have been a daemon, but isn't, for the
  515. !   sake of efficiency) to move objects which could be in many rooms about
  516. !   so that the player never catches one not in place
  517. ! ----------------------------------------------------------------------------
  518.  
  519. [ MoveFloatingObjects i k l m address;
  520.   for (i=selfobj+1: i<=top_object: i++)
  521.   {   address=i.&found_in;
  522.       if (address~=0 && i hasnt absent)
  523.       {   if (ZRegion(address-->0)==2)
  524.           {   if (indirect(address-->0) ~= 0) move i to location;
  525.           }
  526.           else
  527.           {   k=i.#found_in;
  528.               for (l=0: l<k/2: l++)
  529.               {   m=address-->l;
  530.                   if (m==location || m in location) move i to location;
  531.               }
  532.           }
  533.       }
  534.   }
  535. ];
  536.  
  537. ! ----------------------------------------------------------------------------
  538. !   Two little routines for moving the player safely.
  539. ! ----------------------------------------------------------------------------
  540.  
  541. [ PlayerTo newplace flag;
  542.   move player to newplace;
  543.   while (parent(newplace)~=0) newplace=parent(newplace);
  544.   location=newplace;
  545.   real_location=location;
  546.   AdjustLight(1);
  547.   if (flag==0) <Look>;
  548.   if (flag==1) { NoteArrival(); ScoreArrival(); }
  549.   if (flag==2) LookSub(1);
  550. ];
  551.  
  552. [ MovePlayer direc; <Go direc>; <Look>; ];
  553.  
  554. ! ----------------------------------------------------------------------------
  555. !   The handy YesOrNo routine, and some "meta" verbs
  556. ! ----------------------------------------------------------------------------
  557.  
  558. [ YesOrNo i;
  559.   for (::)
  560.   {
  561.    #IFV3; read buffer parse; #ENDIF;
  562.    #IFV5; read buffer parse DrawStatusLine; #ENDIF;
  563.       i=parse-->1;
  564.       if (i=='yes' or #n$y) rtrue;
  565.       if (i=='no' or #n$n) rfalse;
  566.       L__M(##Quit,1); print "> ";
  567.   }
  568. ];
  569.  
  570. [ QuitSub; L__M(##Quit,2); if (YesOrNo()~=0) quit; ];
  571.  
  572. [ RestartSub; L__M(##Restart,1);
  573.   if (YesOrNo()~=0) { @restart; L__M(##Restart,2); }
  574. ];
  575.  
  576. [ RestoreSub;
  577.   restore Rmaybe;
  578.   return L__M(##Restore,1);
  579.   .RMaybe; L__M(##Restore,2);
  580. ];
  581.  
  582. [ SaveSub;
  583.   save Smaybe;
  584.   return L__M(##Save,1);
  585.   .SMaybe; L__M(##Save,2);
  586. ];
  587.  
  588. [ VerifySub;
  589.   @verify Vmaybe;
  590.   jump Vwrong;
  591.   .Vmaybe; return L__M(##Verify,1);
  592.   .Vwrong;
  593.   L__M(##Verify,2);
  594. ];
  595.  
  596. [ ScriptOnSub;
  597.   if (transcript_mode==1) return L__M(##ScriptOn,1);
  598.   transcript_mode=1;
  599.   0-->8 = (0-->8)|1;
  600.   L__M(##ScriptOn,2); VersionSub();
  601. ];
  602.  
  603. [ ScriptOffSub;
  604.   if (transcript_mode==0) return L__M(##ScriptOff,1);
  605.   L__M(##ScriptOff,2);
  606.   transcript_mode=0;
  607.   0-->8 = (0-->8)&$fffe;
  608. ];
  609.  
  610. [ NotifyOnSub; notify_mode=1; L__M(##NotifyOn); ];
  611. [ NotifyOffSub; notify_mode=0; L__M(##NotifyOff); ];
  612.  
  613. #IFNDEF NO_PLACES;
  614. [ PlacesSub i j k;
  615.   L__M(##Places);
  616.   for (i=selfobj:i<=top_object:i++)
  617.       if (i has visited) j++;
  618.  
  619.   for (i=selfobj:i<=top_object:i++)
  620.   {   if (i has visited)
  621.       {   PrintShortName(i); k++;
  622.           if (k==j) ".";
  623.           if (k==j-1) print " and "; else print ", ";
  624.       }
  625.   }
  626. ];
  627. [ ObjectsSub i j f;
  628.   L__M(##Objects,1);
  629.   for (i=selfobj:i<=top_object:i++)
  630.   {   if (i has moved)
  631.       {   f=1; DefArt(i); j=parent(i);
  632.           if (j==player)
  633.           {   if (i has worn) print "   (worn)";
  634.               else print "   (held)";
  635.               jump obj__ptd;
  636.           }
  637.           if (j has animate) { print "   (given away)"; jump obj__ptd; }
  638.           if (j has visited) { print "   (in "; PrintShortName(j);
  639.                                print ")"; jump obj__ptd; }
  640.           if (j has enterable) { print "   (in "; DefArt(j); print ")";
  641.                                  jump obj__ptd; }
  642.           if (j has container) { print "   (inside "; PrintShortName(j);
  643.                                  print ")"; jump obj__ptd; }
  644.           if (j has supporter) { print "   (on "; PrintShortName(j);
  645.                                  print ")"; jump obj__ptd; }
  646.           print "   (lost)";
  647.           .obj__ptd; new_line;
  648.       }
  649.   }
  650.   if (f==0) L__M(##Objects,2);
  651. ];
  652. #ENDIF;
  653.  
  654. ! ----------------------------------------------------------------------------
  655. !   The scoring system
  656. ! ----------------------------------------------------------------------------
  657.  
  658. [ ScoreSub;
  659.   L__M(##Score);
  660.   PrintRank();
  661. ];
  662.  
  663. [ Achieved num;
  664.   if (task_done->num==0)
  665.   {   task_done->num=1; score=score+task_scores->num;
  666.   }
  667. ];
  668.  
  669. [ PANum m n;
  670.   print "  ";
  671.   n=m;
  672.   if (n<0)    { n=-m; n=n*10; }
  673.   if (n<10)   { print "   "; jump panuml; }
  674.   if (n<100)  { print "  "; jump panuml; }
  675.   if (n<1000) { print " "; }
  676. .panuml;
  677.   print m, " ";
  678. ];
  679.  
  680. [ FullScoreSub i;
  681.   ScoreSub();
  682.   if (score==0 || TASKS_PROVIDED==1) rfalse;
  683.   new_line;
  684.   L__M(##FullScore,1);
  685.  
  686.   for (i=0:i<NUMBER_TASKS:i++)
  687.       if (task_done->i==1)
  688.       {   PANum(task_scores->i);
  689.           PrintTaskName(i);
  690.       }
  691.   
  692.   if (things_score~=0)
  693.   {   PANum(things_score); L__M(##FullScore,2); }
  694.   if (places_score~=0)
  695.   {   PANum(places_score); L__M(##FullScore,3); }
  696.   new_line; PANum(score); L__M(##FullScore,4);
  697. ];
  698.  
  699. ! ----------------------------------------------------------------------------
  700. !   Real verbs start here: Inventory
  701. ! ----------------------------------------------------------------------------
  702.  
  703. [ InvWideSub;
  704.   inventory_style = FULLINV_BIT + ENGLISH_BIT + RECURSE_BIT;
  705.   <Inv>;
  706. ];
  707.  
  708. [ InvTallSub;
  709.   inventory_style = FULLINV_BIT + INDENT_BIT + NEWLINE_BIT + RECURSE_BIT;
  710.   <Inv>;
  711. ];
  712.  
  713. [ InvSub;
  714.   if (child(player)==0) return L__M(##Inv,1);
  715.   if (inventory_style==0) <<InvTall>>;
  716.  
  717.   L__M(##Inv,2);
  718.   if (inventory_style & NEWLINE_BIT ~= 0) print ":^"; else print " ";
  719.  
  720.   WriteListFrom(child(player), inventory_style, 1);
  721.   if (inventory_style & ENGLISH_BIT ~= 0) print ".^";
  722.  
  723.   AfterRoutines();
  724. ];
  725.  
  726. ! ----------------------------------------------------------------------------
  727. !   Object movement verbs
  728. ! ----------------------------------------------------------------------------
  729.  
  730. [ TakeSub;
  731.   if (onotheld_mode==0 || parent(noun)~=player)
  732.   {   if (location==thedark)
  733.       {   if (RTakeSub(real_location)~=0) rtrue;
  734.       }
  735.       else
  736.       {   if (RTakeSub(location)~=0) rtrue;
  737.       }
  738.   }
  739.   if (AfterRoutines()==1) rtrue;
  740.   notheld_mode=onotheld_mode;
  741.   if (notheld_mode==1 || keep_silent==1) rtrue;
  742.   L__M(##Take,1);
  743. ];
  744.  
  745. [ RTakeSub fromobj i j k postonobj;
  746.   if (noun==player) return L__M(##Take,2);
  747.  
  748.   if (noun has animate) return L__M(##Take,3,noun);
  749.  
  750.   if (parent(player)==noun) return L__M(##Take,4,noun);
  751.  
  752.   i=parent(noun);
  753.   if (i==player) return L__M(##Take,5);
  754.  
  755.   if (i has container || i has supporter)
  756.   {   postonobj=i;
  757.       k=action; action=##LetGo;
  758.       if (RunRoutines(i,before)~=0) { action=k; rtrue; }
  759.       action=k;
  760.   }
  761.  
  762.   while (i~=fromobj && i~=0)
  763.   {   if (i hasnt container && i hasnt supporter)
  764.       {   if (i has animate) return L__M(##Take,6,i);
  765.           if (i has transparent) return L__M(##Take,7,i);
  766.           return L__M(##Take,8);
  767.       }
  768.       if (i has container && i hasnt open)
  769.           return L__M(##Take,9,i);
  770.       i=parent(i);
  771.       if (i==player) i=fromobj;
  772.   }
  773.   if (noun has scenery) return L__M(##Take,10);
  774.   if (noun has static)  return L__M(##Take,11);
  775.  
  776.   k=0; objectloop (j in player) if (j hasnt worn) k++;
  777.  
  778.   if (k >= ValueOrRun(player,capacity))
  779.   {   if (SACK_OBJECT~=0)
  780.       {   if (parent(SACK_OBJECT)~=player)
  781.               return L__M(##Take,12);
  782.           j=0;
  783.           objectloop (k in player) 
  784.               if (k~=SACK_OBJECT && k hasnt worn && k hasnt light) j=k;
  785.  
  786.           if (j~=0)
  787.           {   L__M(##Take,13,j);
  788.               keep_silent = 1; <Insert j SACK_OBJECT>; keep_silent = 0;
  789.               if (j notin SACK_OBJECT) rtrue;
  790.           }
  791.           else return L__M(##Take,12);
  792.       }
  793.       else return L__M(##Take,12);
  794.   }
  795.   move noun to player;
  796.  
  797.   if (postonobj~=0)
  798.   {   k=action; action=##LetGo;
  799.       if (RunRoutines(postonobj,after)~=0) { action=k; rtrue; }
  800.       action=k;
  801.   }
  802.   rfalse;
  803. ];
  804.  
  805. [ DropSub i;
  806.   i=parent(noun);
  807.   if (i==location) return L__M(##Drop,1);
  808.   if (i~=player) return L__M(##Drop,2);
  809.   if (noun has worn)
  810.   {   L__M(##Drop,3,noun);
  811.       <Disrobe noun>;
  812.       if (noun has worn) rtrue;
  813.   }
  814.   move noun to parent(player);
  815.   if (AfterRoutines()==1) rtrue;
  816.   if (keep_silent==1) rtrue;
  817.   return L__M(##Drop,4);
  818. ];
  819.  
  820. [ RemoveSub i;
  821.   i=parent(noun);
  822.   if (i has container && i hasnt open) return L__M(##Remove,1);
  823.   if (i~=second) return L__M(##Remove,2);
  824.   if (i has animate) return L__M(##Take,6,i);
  825.   if (RTakeSub(second)~=0) rtrue;
  826.   action=##Take;   if (AfterRoutines()==1) rtrue;
  827.   action=##Remove; if (AfterRoutines()==1) rtrue;
  828.  
  829.   if (keep_silent==1) rtrue;
  830.   return L__M(##Remove,4);
  831. ];
  832.  
  833. [ IndirectlyContains o1 o2;  ! Does o1 already (ultimately) have o2?
  834.   while (o2~=0)
  835.   {   if (o1==o2) rtrue;
  836.       o2=parent(o2);
  837.   }
  838.   rfalse;
  839. ];
  840.  
  841. [ PutOnSub;
  842.   receive_action=##PutOn; 
  843.   if (second==d_obj) { <Drop noun>; rfalse; }
  844.   if (parent(noun)~=player) return L__M(##PutOn,1,noun);
  845.  
  846.   if (second>1)
  847.   {   action=##Receive;
  848.       if (RunRoutines(second,before)~=0) { action=##PutOn; rtrue; }
  849.       action=##PutOn;
  850.   }
  851.  
  852.   if (IndirectlyContains(noun,second)==1) return L__M(##PutOn,2);
  853.   if (second hasnt supporter) return L__M(##PutOn,3,second);
  854.   if (parent(second)==player) return L__M(##PutOn,4);
  855.   if (noun has worn)
  856.   {   L__M(##PutOn,5);
  857.       <Disrobe noun>;
  858.       if (noun has worn) rtrue;
  859.   }
  860.   if (children(second)>=ValueOrRun(second,capacity))
  861.       return L__M(##PutOn,6,second);
  862.   move noun to second;
  863.  
  864.   if (AfterRoutines()==1) rtrue;
  865.  
  866.   if (second>1)
  867.   {   action=##Receive;
  868.       if (RunRoutines(second,after)~=0) { action=##PutOn; rtrue; }
  869.       action=##PutOn;
  870.   }
  871.  
  872.   if (keep_silent==1) rtrue;
  873.   if (multiflag==1) return L__M(##PutOn,7);
  874.   L__M(##PutOn,8,noun);
  875. ];
  876.  
  877. [ InsertSub;
  878.   receive_action = ##Insert;
  879.   if (second==d_obj ) <<Drop noun>>;
  880.   if (parent(noun)~=player) return L__M(##Insert,1);
  881.  
  882.   if (second>1)
  883.   {   action=##Receive;
  884.       if (RunRoutines(second,before)~=0) { action=##Insert; rtrue; }
  885.       action=##Insert;
  886.   }
  887.   if (second hasnt container) return L__M(##Insert,2);
  888.   if (second hasnt open)      return L__M(##Insert,3);
  889.   if (IndirectlyContains(noun,second)==1) return L__M(##Insert,5);
  890.   if (noun has worn)
  891.   {   L__M(##Insert,6);
  892.       <Disrobe noun>; if (noun has worn) rtrue;
  893.   }
  894.  
  895.   if (children(second)>=ValueOrRun(second,capacity))
  896.       return L__M(##Insert,7,second);
  897.  
  898.   move noun to second;
  899.  
  900.   if (AfterRoutines()==1) rtrue;
  901.  
  902.   if (second>1)
  903.   {   action=##Receive;
  904.       if (RunRoutines(second,after)~=0) { action=##Insert; rtrue; }
  905.       action=##Insert;
  906.   }
  907.   if (keep_silent==1) rtrue;
  908.   if (multiflag==1) return L__M(##Insert,8);
  909.   L__M(##Insert,9,noun);
  910. ];
  911.  
  912. [ TransferSub i act_needed k postonobj par;
  913.   act_needed=##Drop;
  914.   if (second has container) act_needed=##Insert;
  915.   else
  916.       if (second has supporter) act_needed=##PutOn;
  917.  
  918.   i=parent(noun);
  919.   if (i~=player)
  920.   {   while (i~=0)
  921.       {   if (i hasnt open) return L__M(##Transfer,1);
  922.           i=parent(i);
  923.           if (i==player) jump DoTransfer;
  924.       }
  925.       return L__M(##Transfer,2);
  926.   }
  927.   .DoTransfer;
  928.   if (noun notin player)
  929.   {   par = parent(noun);
  930.       if (par has container || par has supporter)
  931.       {   postonobj=par;
  932.           k=action; action=##LetGo;
  933.           if (RunRoutines(par,before)~=0) { action=k; rtrue; }
  934.           action=k;
  935.       }
  936.       move noun to player;
  937.       if (postonobj~=0)
  938.       {   k=action; action=##LetGo;
  939.           if (RunRoutines(postonobj,after)~=0) { action=k; rtrue; }
  940.           action=k;
  941.       }
  942.   }
  943.   if (act_needed==##Drop)   <<Drop noun>>;
  944.   if (act_needed==##Insert) <<Insert noun second>>;
  945.   if (act_needed==##PutOn)  <<PutOn noun second>>;
  946.  
  947. ];
  948.  
  949. [ EmptySub;
  950.   second=d_obj; EmptyTSub();
  951. ];
  952.  
  953. [ EmptyTSub i j;
  954.   if (noun hasnt container) return L__M(##EmptyT,1,noun);
  955.   if (noun hasnt open) return L__M(##EmptyT,2,noun);
  956.   if (second~=d_obj)
  957.   {   if (second hasnt container) return L__M(##EmptyT,1,second);
  958.       if (second hasnt open) return L__M(##EmptyT,2,second);
  959.   }
  960.   i=child(noun);
  961.   if (i==0) return L__M(##EmptyT,3,noun);
  962.   while (i~=0)
  963.   {   j=sibling(i);
  964.       PrintShortName(i); print ": ";
  965.       <Transfer i second>;
  966.       i=j;
  967.   }
  968. ];
  969.  
  970. [ GiveSub;
  971.   if (parent(noun)~=player) return L__M(##Give,1,noun);
  972.   if (second==player)  return L__M(##Give,2,noun);
  973.   if (RunLife(second,##Give)~=0) rfalse;
  974.   L__M(##Give,3,second);
  975. ];
  976.  
  977. [ GiveRSub; <Give second noun>; ];
  978.  
  979. [ ShowSub;
  980.   if (parent(noun)~=player) return L__M(##Show,1,noun);
  981.   if (second==player) <<Examine noun>>;
  982.   if (RunLife(second,##Show)~=0) rfalse;
  983.   L__M(##Show,2,second);
  984. ];
  985.  
  986. [ ShowRSub; <Show second noun>; ];
  987.  
  988. ! ----------------------------------------------------------------------------
  989. !   Travelling around verbs
  990. ! ----------------------------------------------------------------------------
  991.  
  992. [ EnterSub i;
  993.   if (noun has door) <<Go noun>>;
  994.   i=parent(player);
  995.   if (i~=location) return L__M(##Enter,1,i);
  996.   i=parent(noun);
  997.   if (i==compass) <<Go noun>>;
  998.   if (noun hasnt enterable) return L__M(##Enter,2);
  999.   if (noun has container && noun hasnt open) return L__M(##Enter,3,noun);
  1000.   if (i~=location)  return L__M(##Enter,4);
  1001.   move player to noun;
  1002.   if (AfterRoutines()==1) rtrue;
  1003.   if (keep_silent==1) rtrue;
  1004.   L__M(##Enter,5,noun);
  1005.   Locale(noun);
  1006. ];
  1007.  
  1008. [ GetOffSub;
  1009.   if (parent(player)==noun) <<Exit>>;
  1010.   L__M(##GetOff,1,noun);
  1011. ];
  1012.  
  1013. [ ExitSub p;
  1014.   p=parent(player);
  1015.   if (p==location || (location==thedark && p==real_location))
  1016.   {   if ((location.out_to~=0)
  1017.           || (location==thedark && real_location.out_to~=0)) <<Go out_obj>>;
  1018.       return L__M(##Exit,1);
  1019.   }
  1020.   if (p has container && p hasnt open)
  1021.       return L__M(##Exit,2,p);
  1022.   if (location == thedark) move player to real_location;
  1023.   else move player to location;
  1024.   if (AfterRoutines()==1) rtrue;
  1025.   if (keep_silent==1) rtrue;
  1026.   L__M(##Exit,3,p); LookSub(1);
  1027. ];
  1028.  
  1029. [ VagueGoSub; L__M(##VagueGo); ];
  1030.  
  1031. [ GoInSub;
  1032.   <<Go in_obj>>;
  1033. ];
  1034.  
  1035. [ GoSub i j k df movewith thedir;
  1036.  
  1037.   movewith=0;
  1038.   i=parent(player);
  1039.   if ((location~=thedark && i~=location)
  1040.       || (location==thedark && i~=real_location))
  1041.   {   j=location;
  1042.       if (location==thedark) location=real_location;
  1043.       k=RunRoutines(i,before); if (k~=3) location=j;
  1044.       if (k==1)
  1045.       {   movewith=i; i=parent(i); jump gotroom; }
  1046.       if (k==0) L__M(##Go,1,i); rtrue;
  1047.   }
  1048.   .gotroom;
  1049.   thedir=noun.door_dir;
  1050.   if (ZRegion(thedir)==2) thedir=RunRoutines(noun,door_dir);
  1051.   
  1052.   j=i.thedir; k=ZRegion(j);
  1053.   if (k==3) { print_paddr j; new_line; rfalse; }
  1054.   if (k==2) { j=RunRoutines(i,thedir);
  1055.               if (j==1) rtrue;
  1056.             }
  1057.  
  1058.   if (k==0 || j==0)
  1059.   {   if (i.cant_go ~= 0) PrintOrRun(i, cant_go);
  1060.       rfalse;
  1061.   }
  1062.  
  1063.   if (j has door)
  1064.   {   if (j has concealed) return L__M(##Go,2);
  1065.       if (j hasnt open)
  1066.       {   if (noun==u_obj) return L__M(##Go,3,j);
  1067.           if (noun==d_obj) return L__M(##Go,4,j);
  1068.           return L__M(##Go,5,j);
  1069.       }
  1070.       if (ZRegion(j.door_to)==2) j=RunRoutines(j,door_to);
  1071.       else j=j.door_to;
  1072.       if (j==0) return L__M(##Go,6,j);
  1073.       if (j==1) rtrue;
  1074.   }
  1075.   if (movewith==0) move player to j; else move movewith to j;
  1076.  
  1077.   df=OffersLight(j);
  1078.   if (df~=0) { location=j; lightflag=1; }
  1079.   else
  1080.   {   if (location==thedark) DarkToDark();
  1081.       real_location=j;
  1082.       location=thedark; lightflag=0;
  1083.   }
  1084.   if (AfterRoutines()==1) rtrue;
  1085.   if (keep_silent==1) rtrue;
  1086.   LookSub(1);
  1087. ];
  1088.  
  1089. ! ----------------------------------------------------------------------------
  1090. !   Describing the world.  SayWhatsOn(object) does just that (producing
  1091. !   no text if nothing except possibly "scenery" and "concealed" items are).
  1092. !   Locale(object) runs through the "tail end" of a Look-style room
  1093. !   description for the contents of the object, printing up suitable
  1094. !   descriptions as it goes.
  1095. ! ----------------------------------------------------------------------------
  1096.  
  1097. [ SayWhatsOn descon j f;
  1098.   if (descon==parent(player)) rfalse;
  1099.   objectloop (j in descon)
  1100.       if (j hasnt concealed && j hasnt scenery) f=1;
  1101.   if (f==0) rfalse;
  1102.   L__M(##Look, 4, descon); rtrue;
  1103. ];
  1104.  
  1105. [ Locale descin text1 text2  o p k j flag f2;
  1106.  
  1107.   objectloop (o in descin) give o ~workflag;
  1108.  
  1109.   k=0;
  1110.   objectloop (o in descin)
  1111.       if (o hasnt concealed && o~=parent(player))
  1112.       {  if (o hasnt scenery)
  1113.          {   give o workflag; k++;
  1114.              p=initial; f2=0;
  1115.              if (o has door && o hasnt open) { p=when_closed; f2=1; }
  1116.              if (o has switchable && o hasnt on) { p=when_off; f2=1; }
  1117.              if (o has container && o hasnt open && o.&when_closed~=0)
  1118.              {   p=when_closed; f2=1; }
  1119.              if (o hasnt moved || o.describe~=NULL || f2==1)
  1120.              {   if (o.describe~=NULL && RunRoutines(o,describe)~=0)
  1121.                  {   flag=1;
  1122.                      give o ~workflag; k--;
  1123.                  }    
  1124.                  else
  1125.                  {   j=o.p;
  1126.                      if (j~=0)
  1127.                      {   new_line;
  1128.                          PrintOrRun(o,p);
  1129.                          flag=1;
  1130.                          give o ~workflag; k--;
  1131.                          if (o has supporter && child(o)~=0) SayWhatsOn(o);
  1132.                      }
  1133.                  }
  1134.              }
  1135.          }
  1136.          else
  1137.              if (o has supporter && child(o)~=0) SayWhatsOn(o);
  1138.       }
  1139.  
  1140.   if (k==0) return 0;
  1141.  
  1142.   if (text1~=0)
  1143.   {   new_line;
  1144.       if (flag==1) text1=text2;
  1145.       print (string) text1, " ";
  1146.       WriteListFrom(child(descin),
  1147.           ENGLISH_BIT + WORKFLAG_BIT + RECURSE_BIT
  1148.           + PARTINV_BIT + TERSE_BIT + CONCEAL_BIT);
  1149.       return k;
  1150.   }
  1151.            
  1152.   if (flag==1) L__M(##Look,5,descin); else L__M(##Look,6,descin);
  1153. ];
  1154.  
  1155. ! ----------------------------------------------------------------------------
  1156. !   Looking.  LookSub(1) is allowed to abbreviate long descriptions, but
  1157. !     LookSub(0) (which is what happens when the Look action is generated)
  1158. !     isn't.  (Except that these are over-ridden by the player-set lookmode.)
  1159. ! ----------------------------------------------------------------------------
  1160.  
  1161. [ LMode1Sub; lookmode=1; print_paddr #Story; L__M(##LMode1); ];  ! Brief
  1162.  
  1163. [ LMode2Sub; lookmode=2; print_paddr #Story; L__M(##LMode2); ];  ! Verbose
  1164.  
  1165. [ LMode3Sub; lookmode=3; print_paddr #Story; L__M(##LMode3); ];  ! Superbrief
  1166.  
  1167. [ NoteArrival descin;
  1168.   descin=location;
  1169.   if (descin~=lastdesc)
  1170.   {   if (descin.initial~=0) PrintOrRun(descin, initial);
  1171.       NewRoom();
  1172.       MoveFloatingObjects();
  1173.       lastdesc=descin;
  1174.   }
  1175. ];
  1176.  
  1177. [ ScoreArrival;
  1178.   if (location hasnt visited)
  1179.   {   give location visited;
  1180.       if (location has scored)
  1181.       {   score=score+ROOM_SCORE;
  1182.           places_score=places_score+ROOM_SCORE;
  1183.       }
  1184.   }
  1185. ];
  1186.  
  1187. [ LookSub allow_abbrev  i descin;
  1188.   if (parent(player)==0) "** Error: player has no location **";
  1189.   NoteArrival();
  1190.   new_line;
  1191. #IFV5; style bold; #ENDIF;
  1192.   PrintShortName(location);
  1193. #IFV5; style roman; #ENDIF;
  1194.   i=parent(player);
  1195.   if (location~=thedark && i~=location)
  1196.   {   if (i has supporter) { print " ("; L__M(##Look,1); print " "; }
  1197.       else { print " ("; L__M(##Look,2); print " "; }
  1198.       DefArt(i); print ")"; descin=i;
  1199.   }
  1200.   if (print_player_flag==1) { print " ("; L__M(##Look,3);
  1201.       print " "; print object player, ")"; }
  1202.   new_line;
  1203.  
  1204.   if (lookmode<3)
  1205.   {   if ((allow_abbrev~=1) || (lookmode==2) || (location hasnt visited))
  1206.       {   if (location.describe~=NULL) RunRoutines(location,describe);
  1207.           else
  1208.           {   if (location.description==0) print "** Room undescribed! **^";
  1209.               else PrintOrRun(location,description);
  1210.           }
  1211.       }
  1212.   }
  1213.  
  1214.   if (descin~=location) Locale(location);
  1215.   Locale(descin);
  1216.  
  1217.   LookRoutine();
  1218.   ScoreArrival();
  1219.  
  1220.   action=##Look;
  1221.   if (AfterRoutines()==1) rtrue;
  1222. ];
  1223.  
  1224. [ ExamineSub i;
  1225.   if (location==thedark) return L__M(##Examine,1);
  1226.   i=noun.description;
  1227.   if (i==0)
  1228.   {   if (noun has container) <<Search noun>>;
  1229.       if (noun has switchable) { L__M(##Examine,3,noun); rfalse; }
  1230.       return L__M(##Examine,2,noun);
  1231.   }
  1232.   PrintOrRun(noun, description);
  1233.   if (noun has switchable) L__M(##Examine,3,noun);
  1234.   if (AfterRoutines()==1) rtrue;
  1235. ];
  1236.  
  1237. [ LookUnderSub;
  1238.   if (location==thedark) return L__M(##LookUnder,1);
  1239.   L__M(##LookUnder,2);
  1240. ];
  1241.  
  1242. [ SearchSub i f;
  1243.   if (location==thedark) return L__M(##Search,1);
  1244.   objectloop (i in noun) if (i hasnt concealed) f=1;
  1245.   if (noun has supporter)
  1246.   {   if (f==0) return L__M(##Search,2,noun);
  1247.       return L__M(##Search,3,noun);
  1248.   }
  1249.   if (noun hasnt container) return L__M(##Search,4);
  1250.   if (noun hasnt transparent && noun hasnt open)
  1251.       return L__M(##Search,5);
  1252.   if (AfterRoutines()==1) rtrue;
  1253.  
  1254.   i=children(noun);
  1255.   if (f==0) return L__M(##Search,6,noun);
  1256.   L__M(##Search,7,noun);
  1257. ];
  1258.  
  1259. ! ----------------------------------------------------------------------------
  1260. !   Verbs which change the state of objects without moving them
  1261. ! ----------------------------------------------------------------------------
  1262.  
  1263. [ UnlockSub;
  1264.   if (noun hasnt lockable) return L__M(##Unlock,1);
  1265.   if (noun hasnt locked)   return L__M(##Unlock,2);
  1266.   if (noun.with_key~=second) return L__M(##Unlock,3);
  1267.   give noun ~locked;
  1268.   if (AfterRoutines()==1) rtrue;
  1269.   if (keep_silent==1) rtrue;
  1270.   L__M(##Unlock,4,noun);
  1271. ];
  1272.  
  1273. [ LockSub;
  1274.   if (noun hasnt lockable) return L__M(##Lock,1);
  1275.   if (noun has locked)     return L__M(##Lock,2);
  1276.   if (noun has open)       return L__M(##Lock,3);
  1277.   if (noun.with_key~=second) return L__M(##Lock,4);
  1278.   give noun locked;
  1279.   if (AfterRoutines()==1) rtrue;
  1280.   if (keep_silent==1) rtrue;
  1281.   L__M(##Lock,5,noun);
  1282. ];
  1283.  
  1284. [ SwitchonSub;
  1285.   if (noun hasnt switchable) return L__M(##SwitchOn,1);
  1286.   if (noun has on) return L__M(##SwitchOn,2);
  1287.   give noun on;
  1288.   if (AfterRoutines()==1) rtrue;
  1289.   if (keep_silent==1) rtrue;
  1290.   L__M(##SwitchOn,3,noun);
  1291. ];
  1292.  
  1293. [ SwitchoffSub;
  1294.   if (noun hasnt switchable) return L__M(##SwitchOff,1);
  1295.   if (noun hasnt on) return L__M(##SwitchOff,2);
  1296.   give noun ~on;
  1297.   if (AfterRoutines()==1) rtrue;
  1298.   if (keep_silent==1) rtrue;
  1299.   L__M(##SwitchOff,3,noun);
  1300. ];
  1301.  
  1302. [ OpenSub;
  1303.   if (noun hasnt openable) return L__M(##Open,1);
  1304.   if (noun has locked)     return L__M(##Open,2);
  1305.   if (noun has open)       return L__M(##Open,3);
  1306.   give noun open;
  1307.   if (AfterRoutines()==1) rtrue;
  1308.   if (keep_silent==1) rtrue;
  1309.   if (noun has container && noun hasnt transparent && child(noun)~=0)
  1310.       return L__M(##Open,4,noun);
  1311.   L__M(##Open,5,noun);
  1312. ];
  1313.  
  1314. [ CloseSub;
  1315.   if (noun hasnt openable) return L__M(##Close,1);
  1316.   if (noun hasnt open)     return L__M(##Close,2);
  1317.   give noun ~open;
  1318.   if (AfterRoutines()==1) rtrue;
  1319.   if (keep_silent==1) rtrue;
  1320.   L__M(##Close,3,noun);
  1321. ];
  1322.  
  1323. [ DisrobeSub;
  1324.   if (noun hasnt worn) return L__M(##Disrobe,1);
  1325.   give noun ~worn;
  1326.   if (AfterRoutines()==1) rtrue;
  1327.   if (keep_silent==1) rtrue;
  1328.   L__M(##Disrobe,2,noun);
  1329. ];
  1330.  
  1331. [ WearSub;
  1332.   if (noun hasnt clothing)  return L__M(##Wear,1);
  1333.   if (parent(noun)~=player) return L__M(##Wear,2);
  1334.   if (noun has worn)        return L__M(##Wear,3);
  1335.   give noun worn;
  1336.   if (AfterRoutines()==1) rtrue;
  1337.   if (keep_silent==1) rtrue;
  1338.   L__M(##Wear,4,noun);
  1339. ];
  1340.  
  1341. [ EatSub;
  1342.   if (noun hasnt edible) return L__M(##Eat,1);
  1343.   remove noun;
  1344.   if (AfterRoutines()==1) rtrue;
  1345.   if (keep_silent==1) rtrue;
  1346.   L__M(##Eat,2,noun);
  1347. ];
  1348.  
  1349. ! ----------------------------------------------------------------------------
  1350. !   Verbs which are really just stubs (anything which happens for these
  1351. !   actions must happen in before rules)
  1352. ! ----------------------------------------------------------------------------
  1353.  
  1354. [ YesSub; L__M(##Yes); ];
  1355. [ NoSub; L__M(##No); ];
  1356. [ BurnSub; L__M(##Burn); ];
  1357. [ PraySub; L__M(##Pray); ];
  1358. [ WakeSub; L__M(##Wake); ];
  1359. [ WakeOtherSub;
  1360.   if (RunLife(noun,##WakeOther)~=0) rfalse;
  1361.   L__M(##WakeOther);
  1362. ];
  1363. [ ThinkSub; L__M(##Think); ];
  1364. [ SmellSub; L__M(##Smell); ];
  1365. [ ListenSub; L__M(##Listen); ];
  1366. [ TasteSub; L__M(##Taste); ];
  1367. [ DigSub; L__M(##Dig); ];
  1368. [ CutSub; L__M(##Cut); ];
  1369. [ JumpSub; L__M(##Jump); ];
  1370. [ JumpOverSub; L__M(##JumpOver); ];
  1371. [ TieSub; L__M(##Tie); ];
  1372. [ DrinkSub; L__M(##Drink); ];
  1373. [ FillSub; L__M(##Fill); ];
  1374. [ SorrySub; L__M(##Sorry); ];
  1375. [ StrongSub; L__M(##Strong); ];
  1376. [ MildSub; L__M(##Mild); ];
  1377. [ SwimSub; L__M(##Swim); ];
  1378. [ SwingSub; L__M(##Swing); ];
  1379. [ BlowSub; L__M(##Blow); ];
  1380. [ RubSub; L__M(##Rub); ];
  1381. [ SetSub; L__M(##Set); ];
  1382. [ SetToSub; L__M(##SetTo); ];
  1383. [ WaveHandsSub; L__M(##WaveHands); ];
  1384. [ BuySub; L__M(##Buy); ];
  1385. [ SingSub; L__M(##Sing); ];
  1386. [ ClimbSub; L__M(##Climb); ];
  1387. [ SleepSub; L__M(##Sleep); ];
  1388. [ ConsultSub; L__M(##Consult,1,noun); ];
  1389. [ TouchSub;
  1390.   if (noun==player) return L__M(##Touch,3);
  1391.   if (noun has animate) return L__M(##Touch,1);
  1392.   L__M(##Touch,2); ];
  1393. [ WaveSub;
  1394.   if (parent(noun)~=player) return L__M(##Wave,1);
  1395.   L__M(##Wave,2,noun); ];
  1396. [ PullSub;
  1397.   if (noun has static)   return L__M(##Pull,1);
  1398.   if (noun has scenery)  return L__M(##Pull,2);
  1399.   if (noun has animate)  return L__M(##Pull,4);
  1400.   L__M(##Pull,3);
  1401. ];
  1402. [ PushSub;
  1403.   if (noun has static)   return L__M(##Push,1);
  1404.   if (noun has scenery)  return L__M(##Push,2);
  1405.   if (noun has animate)  return L__M(##Pull,4);
  1406.   L__M(##Push,3);
  1407. ];
  1408. [ TurnSub;
  1409.   if (noun has static)   return L__M(##Turn,1);
  1410.   if (noun has scenery)  return L__M(##Turn,2);
  1411.   if (noun has animate)  return L__M(##Pull,4);
  1412.   L__M(##Turn,3);
  1413. ];
  1414.  
  1415. [ WaitSub;
  1416.   if (AfterRoutines()==1) rtrue;
  1417.   L__M(##Wait);
  1418. ];
  1419.  
  1420. [ PushDirSub; L__M(##PushDir,1); ];
  1421. [ AllowPushDir i;
  1422.   if (parent(second)~=compass) return L__M(##PushDir,2);
  1423.   if (second==u_obj or d_obj)  return L__M(##PushDir,3);
  1424.   AfterRoutines(); i=noun; move i to player;
  1425.   <Go second>;
  1426.   if (location==thedark) move i to real_location;
  1427.   else move i to location;
  1428. ];
  1429.  
  1430. [ SqueezeSub;
  1431.   if (noun has animate) return L__M(##Squeeze,1);
  1432.   L__M(##Squeeze,2);
  1433. ];
  1434.  
  1435. [ ThrowAtSub;
  1436.   if (second>1)
  1437.   {   action=##ThrownAt;
  1438.       if (RunRoutines(second,before)~=0) { action=##ThrowAt; rtrue; }
  1439.       action=##ThrowAt;
  1440.   }
  1441.   if (second hasnt animate) return L__M(##ThrowAt,1);
  1442.   if (RunLife(second,##ThrowAt)~=0) rfalse;
  1443.   L__M(##ThrowAt,2);
  1444. ];
  1445.  
  1446. [ AttackSub;
  1447.   if (noun has animate && RunLife(noun,##Attack)~=0) rfalse;
  1448.   L__M(##Attack); ];
  1449.  
  1450. [ KissSub;
  1451.   if (RunLife(noun,##Kiss)~=0) rfalse;
  1452.   if (noun==player) return L__M(##Touch,3);
  1453.   L__M(##Kiss);
  1454. ];
  1455.  
  1456. [ AnswerSub;
  1457.   inp1=special_word; noun=inp1;
  1458.   if (RunLife(second,##Answer)~=0) rfalse;
  1459.   L__M(##Answer);
  1460. ];  
  1461.  
  1462. [ TellSub;
  1463.   inp2=special_word; second=inp2;
  1464.   if (noun==player) return L__M(##Tell);
  1465.   if (RunLife(noun,##Tell)~=0) rfalse;
  1466.   L__M(##Tell,2);
  1467. ];  
  1468.   
  1469. [ AskSub;
  1470.   inp2=special_word; second=inp2;
  1471.   if (RunLife(noun,##Ask)~=0) rfalse;
  1472.   L__M(##Ask);
  1473. ];  
  1474.  
  1475. [ AskForSub i;
  1476.   if (noun==player) <<Inv>>;
  1477.   i=noun;
  1478.   action=##Give; inp1=second; inp2=player;
  1479.   if (RunLife(noun,##Order)~=0) rfalse;
  1480.   L__M(##Order,1,i);
  1481. ];
  1482.  
  1483. ! ----------------------------------------------------------------------------
  1484. !   Debugging verbs
  1485. ! ----------------------------------------------------------------------------
  1486.  
  1487. #IFDEF DEBUG;
  1488. [ TraceOnSub; parser_trace=1; "[Trace on.]"; ];
  1489. [ TraceLevelSub; parser_trace=noun;
  1490.   print "[Parser tracing set to level ", parser_trace, ".]^"; ];
  1491. [ TraceOffSub; parser_trace=0; "Trace off."; ];
  1492. [ RoutinesOnSub;  debug_flag=debug_flag | 1; "[Routine listing on.]"; ];
  1493. [ RoutinesOffSub; debug_flag=debug_flag & 6; "[Routine listing off.]"; ];
  1494. [ ActionsOnSub;  debug_flag=debug_flag | 2; "[Action listing on.]"; ];
  1495. [ ActionsOffSub; debug_flag=debug_flag & 5; "[Action listing off.]"; ];
  1496. [ TimersOnSub;  debug_flag=debug_flag | 4; "[Timers listing on.]"; ];
  1497. [ TimersOffSub; debug_flag=debug_flag & 3; "[Timers listing off.]"; ];
  1498. [ CommandsOnSub;
  1499.   @output_stream 4; xcommsdir=1; "[Command recording on.]"; ];
  1500. [ CommandsOffSub;
  1501.   if (xcommsdir==1) @output_stream -4;
  1502.   xcommsdir=0;
  1503.   "[Command recording off.]"; ];
  1504. [ CommandsReadSub;
  1505.   @input_stream 1; xcommsdir=2; "[Replaying commands.]"; ];
  1506. [ PredictableSub i; i=random(-100);
  1507.   "[Random number generator now predictable.]"; ];
  1508. [ XPurloinSub; move noun to player; give noun moved ~concealed; "[Purloined.]"; ];
  1509. [ XAbstractSub; move noun to second; "[Abstracted.]"; ];
  1510. [ XObj obj f;
  1511.   if (parent(obj)==0) PrintShortName(obj); else InDefArt(obj);
  1512.   print " (", obj, ") ";
  1513.   if (f==1) { print "(in "; PrintShortName(parent(obj));
  1514.               print " ", parent(obj), ")"; }
  1515.   new_line;
  1516.   if (child(obj)==0) rtrue;
  1517.   WriteListFrom(child(obj),
  1518.       FULLINV_BIT + INDENT_BIT + NEWLINE_BIT + ALWAYS_BIT, 1);
  1519. ];
  1520. [ XTreeSub i;
  1521.   if (noun==0)
  1522.   {   for (i=selfobj+1:i<=top_object:i++)
  1523.       {   if (parent(i)==0) XObj(i);
  1524.       }
  1525.       rfalse;
  1526.   }
  1527.   XObj(noun,1);
  1528. ];
  1529. [ GotoSub;
  1530.   if (noun>top_object || noun<=selfobj || parent(noun)~=0)
  1531.       "[Not a safe place.]";
  1532.   PlayerTo(noun);
  1533. ];
  1534. [ GonearSub x; x=noun; while (parent(x)~=0) x=parent(x); PlayerTo(x); ];
  1535. [ Print_ScL obj; print_ret ++x_scope_count, ": ", (a) obj, " (", obj, ")"; ];
  1536. [ ScopeSub; x_scope_count=0; LoopOverScope(#r$Print_ScL, noun);
  1537.   if (x_scope_count==0) "Nothing is in scope.";
  1538. ];
  1539. #ENDIF;
  1540.  
  1541. ! ----------------------------------------------------------------------------
  1542. !   Finally: virtually all the text produced by library routines, except for
  1543. !   some parser errors (which are indirected through ParserError).
  1544. ! ----------------------------------------------------------------------------
  1545.  
  1546. [ L__M act n x1 s;
  1547.   s=sw__var; sw__var=act; if (n==0) n=1;
  1548.   L___M(n,x1);
  1549.   sw__var=s;
  1550. ];
  1551.  
  1552. [ L___M n x1 s;
  1553.   s=action;
  1554. #IFDEF LibraryMessages;
  1555.   lm_n=n; lm_o=x1;
  1556.   action=sw__var;
  1557.   if (RunRoutines(LibraryMessages,before)~=0) { action=s; rfalse; }
  1558.   action=s;
  1559. #ENDIF;
  1560.   Prompt:  print "^>"; rtrue;
  1561.   Miscellany: if (n==1) "(considering the first sixteen objects only)^";
  1562.            if (n==2) "Nothing to do!";
  1563.            if (n==3) { print " You have died "; rtrue; }
  1564.            if (n==4) { print " You have won "; rtrue; }
  1565.            if (n==5)
  1566.            {   print "^Would you like to RESTART, RESTORE a saved game";
  1567.                if (TASKS_PROVIDED==0)
  1568.                    print ", give the FULL score for that game";
  1569.                if (deadflag==2 && AMUSING_PROVIDED==0)
  1570.                    print ", see some suggestions for AMUSING things to do";
  1571.                " or QUIT?"; }
  1572.            if (n==6) "[Your interpreter does not provide ~undo~.  Sorry!]";
  1573.            if (n==7) "~Undo~ failed.  [Not all interpreters provide it.]";
  1574.            if (n==8) "Please give one of the answers above.";
  1575.            if (n==9) "^It is now pitch dark in here!";
  1576.            if (n==10) "I beg your pardon?";
  1577.            if (n==11) "[You can't ~undo~ what hasn't been done!]";
  1578.            if (n==12) "[Can't ~undo~ twice in succession. Sorry!]";
  1579.            if (n==13) "[Previous turn undone.]";
  1580.            if (n==14) "Sorry, that can't be corrected.";
  1581.            if (n==15) "Think nothing of it.";
  1582.            if (n==16) "~Oops~ can only correct a single word.";
  1583.   Order:   CDefArt(x1); " has better things to do.";
  1584.   Quit:    if (n==1) { print "Please answer yes or no."; rtrue; }
  1585.            print "Are you sure you want to quit? "; rtrue;
  1586.   Restart: if (n==1) { print "Are you sure you want to restart? "; rtrue; }
  1587.            "Failed.";
  1588.   Restore: if (n==1) "Restore failed.";
  1589.            "Ok.";
  1590.   Save:    if (n==1) "Save failed.";
  1591.            "Ok.";
  1592.   Verify:  if (n==1) "The game file has verified as intact.";
  1593.            "The game file did not verify properly, and may be corrupted \
  1594.            (or you may be running it on a very primitive interpreter which \
  1595.            is unable properly to perform the test).";
  1596.   ScriptOn: if (n==1) "Transcripting is already on.";
  1597.            "Start of a transcript of";
  1598.   ScriptOff: if (n==1) "Transcripting is already off.";
  1599.            "^End of transcript.";
  1600.   NotifyOn: "Score notification on.";
  1601.   NotifyOff: "Score notification off.";
  1602.   Places:  print "You have visited: "; rtrue;
  1603.   Objects: if (n==1) "Objects you have handled:^";
  1604.            "None.";
  1605.   Score:   if (deadflag==0) print "You have so far scored ";
  1606.            else print "In that game you scored ";
  1607.            print score, " out of a possible ", MAX_SCORE,
  1608.                  ", in ", turns, " turn";
  1609.            if (turns>1) print "s"; rtrue;
  1610.   FullScore: if (n==1)
  1611.            {   if (deadflag==0) print "The score is ";
  1612.                else             print "The score was ";
  1613.                "made up as follows:^"; }
  1614.            if (n==2) "finding sundry items";
  1615.            if (n==3) "visiting various places";
  1616.            print "total (out of ", MAX_SCORE; ")";
  1617.   Inv:     if (n==1) "You are carrying nothing.";
  1618.            print "You are carrying"; rtrue;
  1619.   Take:    if (n==1) "Taken.";
  1620.            if (n==2) "You are always self-possessed.";
  1621.            if (n==3) { print "I don't suppose "; DefArt(x1);
  1622.                        " would care for that."; }
  1623.            if (n==4) { print "You'd have to get ";
  1624.                        if (x1 has supporter) print "off "; else print "out of ";
  1625.                        DefArt(x1); " first."; }
  1626.            if (n==5) "You already have that.";
  1627.            if (n==6) { print "That seems to belong to "; DefArt(x1); "."; }
  1628.            if (n==7) { print "That seems to be a part of "; DefArt(x1); "."; }
  1629.            if (n==8) "That isn't available.";
  1630.            if (n==9) { CDefArt(x1); " is not open."; }
  1631.            if (n==10) "That's hardly portable.";
  1632.            if (n==11) "That's fixed in place.";
  1633.            if (n==12) "You're carrying too many things already.";
  1634.            print "(putting "; DefArt(x1); print " into ";
  1635.            DefArt(SACK_OBJECT); " to make room)";
  1636.   Drop:    if (n==1) "Already on the floor.";
  1637.            if (n==2) "You haven't got that.";
  1638.            if (n==3) { print "(first taking "; DefArt(x1); " off)"; }
  1639.            "Dropped.";
  1640.   Remove:  if (n==1) "It is unfortunately closed.";
  1641.            if (n==2) "But it isn't there now.";
  1642.            "Removed.";
  1643.   PutOn:   if (n==1) { print "You need to be holding ";
  1644.                        DefArt(x1); " before you can put it on top \
  1645.                       of something else."; }
  1646.            if (n==2) "You can't put something on top of itself.";
  1647.            if (n==3) { print "Putting things on "; DefArt(x1);
  1648.                        " would achieve nothing."; }
  1649.            if (n==4) "You lack the dexterity.";
  1650.            if (n==5) "(first taking it off)^";
  1651.            if (n==6) { print "There is no more room on "; DefArt(x1); "."; }
  1652.            if (n==7) "Done.";
  1653.            print "You put "; DefArt(x1); print " on "; DefArt(second); ".";
  1654.   Insert:  if (n==1) "You need to be holding it before you can put it into \
  1655.                       something else.";
  1656.            if (n==2) "That can't contain things.";
  1657.            if (n==3) "Alas, it is closed.";
  1658.            if (n==4) "You'll need to take it off first.";
  1659.            if (n==5) "You can't put something inside itself.";
  1660.            if (n==6) "(first taking it off)^";
  1661.            if (n==7) { print "There is no more room in "; DefArt(x1); "."; }
  1662.            if (n==8) "Done.";
  1663.            print "You put "; DefArt(x1); print " into "; DefArt(second); ".";
  1664.   Transfer: if (n==1) "That isn't in your possession.";
  1665.            "First pick that up.";
  1666.   EmptyT:  if (n==1) { CDefArt(x1); " can't contain things."; }
  1667.            if (n==2) { CDefArt(x1); " is closed."; }
  1668.            CDefArt(x1); " is empty already.";
  1669.   Give:    if (n==1) { print "You aren't holding "; DefArt(x1); "."; }
  1670.            if (n==2) { print "You juggle "; DefArt(x1);
  1671.                        " for a while, but don't achieve much."; }
  1672.            CDefArt(x1); " doesn't seem interested.";
  1673.   Show:    if (n==1) { print "You aren't holding "; DefArt(x1); "."; }
  1674.            CDefArt(x1); " is unimpressed.";
  1675.   Enter:   if (n==1) { print "But you're already ";
  1676.                        if (x1 has supporter) print "on ";
  1677.                        else print "in "; DefArt(x1); "."; }
  1678.            if (n==2) "That's not something you can enter.";
  1679.            if (n==3) { print "You can't get into the closed ";
  1680.                        PrintShortName(x1); "."; }
  1681.            if (n==4) "You can only get into something on the floor.";
  1682.            print "You get "; if (x1 has supporter) print "onto ";
  1683.            else print "into "; DefArt(x1); ".";
  1684.   GetOff:  print "But you aren't on "; DefArt(x1); " at the moment.";
  1685.   Exit:    if (n==1) "But you aren't in anything at the moment.";
  1686.            if (n==2) { print "You can't get out of the closed ";
  1687.                        PrintShortName(x1); "."; }
  1688.            print "You get "; if (x1 has supporter) print "off ";
  1689.            else print "out of "; DefArt(x1); ".";
  1690.   VagueGo: "You'll have to say which compass direction to go in.";
  1691.   Go:      if (n==1)
  1692.            {   print "You'll have to get ";
  1693.                if (x1 has supporter) print "off "; else print "out of ";
  1694.                DefArt(x1); " first.";
  1695.            }
  1696.            if (n==2) "You can't go that way.";
  1697.            if (n==3) { print "You are unable to climb "; Defart(x1); "."; }
  1698.            if (n==4) { print "You are unable to descend "; Defart(x1); "."; }
  1699.            if (n==5) { print "You can't, since "; Defart(x1);
  1700.                        " is in the way."; }
  1701.            print "You can't, since "; DefArt(x1); " leads nowhere.";
  1702.   LMode1:  " is now in its normal ~brief~ printing mode, which gives \
  1703.            long descriptions of places never before visited and short \
  1704.            descriptions otherwise.";
  1705.   LMode2:  " is now in its ~verbose~ mode, which always gives long \
  1706.            descriptions of locations (even if you've been there before).";
  1707.   LMode3:  " is now in its ~superbrief~ mode, which always gives short \
  1708.            descriptions of locations (even if you haven't been there before).";
  1709.   Look:    if (n==1) { print "on"; rfalse; }
  1710.            if (n==2) { print "in"; rfalse; }
  1711.            if (n==3) { print "as"; rfalse; }
  1712.            if (n==4)
  1713.            {   print "^On "; DefArt(x1);
  1714.                WriteListFrom(child(x1),
  1715.                    ENGLISH_BIT + RECURSE_BIT + PARTINV_BIT
  1716.                    + TERSE_BIT + ISARE_BIT + CONCEAL_BIT);
  1717.                ".";
  1718.            }
  1719.            if (x1~=location)
  1720.            {   if (x1 has supporter) print "^On "; else print "^In ";
  1721.                DefArt(x1); print " you";
  1722.            }
  1723.            else print "^You";
  1724.            print " can "; if (n==5) print "also "; print "see ";
  1725.            WriteListFrom(child(x1),
  1726.                 ENGLISH_BIT + WORKFLAG_BIT + RECURSE_BIT
  1727.                 + PARTINV_BIT + TERSE_BIT + CONCEAL_BIT);
  1728.            if (x1~=location) ".";
  1729.            " here.";
  1730.   Examine: if (n==1) "Darkness, noun.  An absence of light to see by.";
  1731.            if (n==2) { print "You see nothing special about ";
  1732.                        Defart(x1); "."; }
  1733.            CDefArt(x1); print " is currently switched ";
  1734.            if (x1 has on) "on."; else "off.";
  1735.   LookUnder: if (n==1) "But it's dark.";
  1736.            "You find nothing of interest.";
  1737.   Search:  if (n==1) "But it's dark.";
  1738.            if (n==2) { print "There is nothing on "; DefArt(x1); "."; }
  1739.            if (n==3)
  1740.            {   print "On "; DefArt(x1);
  1741.                WriteListFrom(child(x1),
  1742.                    TERSE_BIT + ENGLISH_BIT + ISARE_BIT + CONCEAL_BIT);
  1743.                ".";
  1744.            }
  1745.            if (n==4) "You find nothing of interest.";
  1746.            if (n==5) "You can't see inside, since it is closed.";
  1747.            if (n==6) { CDefArt(x1); " is empty."; }
  1748.            print "In "; DefArt(x1);
  1749.            WriteListFrom(child(x1),
  1750.                TERSE_BIT + ENGLISH_BIT + ISARE_BIT + CONCEAL_BIT);
  1751.            ".";
  1752.   Unlock:  if (n==1) "That doesn't seem to be something you can unlock.";
  1753.            if (n==2) "It's unlocked at the moment.";
  1754.            if (n==3) "That doesn't seem to fit the lock.";
  1755.            print "You unlock "; DefArt(x1); ".";
  1756.   Lock:    if (n==1) "That doesn't seem to be something you can lock.";
  1757.            if (n==2) "It's locked at the moment.";
  1758.            if (n==3) "First you'll have to close it.";
  1759.            if (n==4) "That doesn't seem to fit the lock.";
  1760.            print "You lock "; DefArt(x1); ".";
  1761.   SwitchOn: if (n==1) "That's not something you can switch.";
  1762.            if (n==2) "That's already on.";
  1763.            print "You switch "; DefArt(x1); " on.";
  1764.   SwitchOff: if (n==1) "That's not something you can switch.";
  1765.            if (n==2) "That's already off.";
  1766.            print "You switch "; DefArt(x1); " off.";
  1767.   Open:    if (n==1) "That's not something you can open.";
  1768.            if (n==2) "It seems to be locked.";
  1769.            if (n==3) "It's already open.";
  1770.            if (n==4)
  1771.            {   print "You open "; DefArt(x1); print ", revealing ";
  1772.                if (WriteListFrom(child(x1),
  1773.                    ENGLISH_BIT + TERSE_BIT + CONCEAL_BIT)==0) "nothing.";
  1774.                ".";
  1775.            }
  1776.            print "You open "; DefArt(x1); ".";
  1777.   Close:   if (n==1) "That's not something you can close.";
  1778.            if (n==2) "It's already closed.";
  1779.            print "You close "; DefArt(x1); ".";
  1780.   Disrobe: if (n==1) "You're not wearing that.";
  1781.            print "You take off "; DefArt(x1); ".";
  1782.   Wear:    if (n==1) "You can't wear that!";
  1783.            if (n==2) "You're not holding that!";
  1784.            if (n==3) "You're already wearing that!";
  1785.            print "You put on "; DefArt(x1); ".";
  1786.   Eat:     if (n==1) "That's plainly inedible.";
  1787.            print "You eat "; DefArt(x1); ".  Not bad.";
  1788.   Yes, No: "That was a rhetorical question.";
  1789.   Burn:    "This dangerous act would achieve little.";
  1790.   Pray:    "Nothing practical results from your prayer.";
  1791.   Wake:    "The dreadful truth is, this is not a dream.";
  1792.   WakeOther: "That seems unnecessary.";
  1793.   Kiss:    "Keep your mind on the game.";
  1794.   Think:   "What a good idea.";
  1795.   Smell:   "You smell nothing unexpected.";
  1796.   Listen:  "You hear nothing unexpected.";
  1797.   Taste:   "You taste nothing unexpected.";
  1798.   Touch:   if (n==1) "Keep your hands to yourself!";
  1799.            if (n==3) "If you think that'll help.";
  1800.            "You feel nothing unexpected.";
  1801.   Dig:     "Digging would achieve nothing here.";
  1802.   Cut:     "Cutting that up would achieve little.";
  1803.   Jump:    "You jump on the spot, fruitlessly.";
  1804.   JumpOver, Tie: "You would achieve nothing by this.";
  1805.   Drink:   "There's nothing suitable to drink here.";
  1806.   Fill:    "But there's no water here to carry.";
  1807.   Sorry:   "Oh, don't apologise.";
  1808.   Strong:  "Real adventurers do not use such language.";
  1809.   Mild:    "Quite.";
  1810.   Attack:  "Violence isn't the answer to this one.";
  1811.   Swim:    "There's not enough water to swim in.";
  1812.   Swing:   "There's nothing sensible to swing here.";
  1813.   Blow:    "You can't usefully blow that.";
  1814.   Rub:     "You achieve nothing by this.";
  1815.   Set:     "No, you can't set that.";
  1816.   SetTo:   "No, you can't set that to anything.";
  1817.   WaveHands: "You wave, feeling foolish.";
  1818.   Wave:    if (n==1) "But you aren't holding that.";
  1819.            print "You look ridiculous waving "; DefArt(x1); ".";
  1820.   Pull, Push, Turn: if (n==1) "It is fixed in place.";
  1821.            if (n==2) "You are unable to.";
  1822.            if (n==4) "That would be less than courteous.";
  1823.            "Nothing obvious happens.";
  1824.   PushDir: if (n==1) "Is that the best you can think of?";
  1825.            if (n==2) "That's not a direction.";
  1826.            "Not that way you can't.";
  1827.   Squeeze: if (n==1) "Keep your hands to yourself.";
  1828.            "You achieve nothing by this.";
  1829.   ThrowAt: if (n==1) "Futile.";
  1830.            "You lack the nerve when it comes to the crucial moment.";
  1831.   Tell:    if (n==1) "You talk to yourself a while.";
  1832.            "This provokes no reaction.";
  1833.   Answer, Ask:  "There is no reply.";
  1834.   Buy:     "Nothing is on sale.";
  1835.   Sing:    "Your singing is abominable.";
  1836.   Climb:   "I don't think much is to be achieved by that.";
  1837.   Wait:    "Time passes.";
  1838.   Sleep:   "You aren't feeling especially drowsy.";
  1839.   Consult: print "You discover nothing of interest in "; DefArt(x1); ".";
  1840. ];
  1841.  
  1842. ! ----------------------------------------------------------------------------
  1843.  
  1844.