Inventory This is the complete source code of the example game verblibm.inf.
Back to List
Complete
Browsing verblibm.h
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.