00001
00002
00003
00004 #include <stdio.h>
00005 #include <stdlib.h>
00006 #include "advent.h"
00007 #include "advdec.h"
00008
00009 _PROTOTYPE(void descitem, (void));
00010 _PROTOTYPE(void domove, (void));
00011 _PROTOTYPE(void goback, (void));
00012 _PROTOTYPE(void copytrv, (struct trav *, struct trav *));
00013 _PROTOTYPE(void dotrav, (void));
00014 _PROTOTYPE(void badmove, (void));
00015 _PROTOTYPE(void spcmove, (int));
00016 _PROTOTYPE(void death, (void));
00017 _PROTOTYPE(void dwarves, (void));
00018 _PROTOTYPE(void dopirate, (void));
00019 _PROTOTYPE(int stimer, (void));
00020 _PROTOTYPE(void do_hint, (int));
00021
00022
00023
00024
00025
00026 void turn()
00027 {
00028 int i, hint;
00029 static int waste = 0;
00030
00031 if (newtravel) {
00032
00033 if (outside(g.newloc) && g.newloc != 0 && g.closing) {
00034 rspeak(130);
00035 g.newloc = g.loc;
00036 if (!g.panic)
00037 g.clock2 = 15;
00038 g.panic = TRUE;
00039 }
00040
00041
00042 if (g.newloc != g.loc && !forced(g.loc) && g.loc_attrib[g.loc] & NOPIRAT == 0)
00043 for (i = 1; i < (DWARFMAX - 1); ++i)
00044 if (g.odloc[i] == g.newloc && g.dseen[i]) {
00045 g.newloc = g.loc;
00046 rspeak(2);
00047 break;
00048 }
00049
00050 g.loc = g.newloc;
00051 dwarves();
00052
00053
00054
00055 if (g.loc == 0) {
00056 death();
00057 return;
00058 }
00059
00060 if (forced(g.loc)) {
00061 desclg(g.loc);
00062 ++g.visited[g.loc];
00063 domove();
00064 return;
00065 }
00066
00067 if (g.wzdark && dark() && pct(35)) {
00068 rspeak(23);
00069 g.oldloc2 = g.loc;
00070 death();
00071 return;
00072 }
00073
00074 if (outside(g.loc) && g.prop[LAMP]) {
00075 waste++;
00076 if (waste > 11) {
00077 rspeak(324);
00078 waste = 0;
00079 }
00080 } else
00081 waste = 0;
00082
00083
00084 if (g.chase) {
00085 g.chase++;
00086 g.prop[WUMPUS] = g.chase / 2;
00087 move(WUMPUS, g.loc);
00088 if (g.chase >= 10) {
00089 if (dark())
00090 rspeak(270);
00091 pspeak(WUMPUS, 5);
00092 death();
00093 return;
00094 }
00095 }
00096
00097 g.health += (outside(g.loc)) ? 3 : 1;
00098 if (g.health > 100)
00099 g.health = 100;
00100 if (here(RADIUM) && (g.place[RADIUM] != -SHIELD || ajar(SHIELD)))
00101 g.health -= 7;
00102 if (g.health < 60) {
00103 rspeak(391 + (60 - g.health) / 10);
00104 if (g.health < 0) {
00105 death();
00106 return;
00107 }
00108 }
00109 if ((g.oldloc == 188) && (g.loc != 188 && g.loc != 189)
00110 && (g.prop[BOOTH] == 1)) {
00111 move(GNOME, 0);
00112 g.prop[BOOTH] = 0;
00113 }
00114
00115 describe();
00116 if (!blind()) {
00117 ++g.visited[g.loc];
00118 descitem();
00119 }
00120 }
00121
00122
00123
00124
00125 for (hint = HNTMIN; hint <= HNTMAX; hint++) {
00126 if (g.hinted[hint])
00127 continue;
00128 if (g.loc_attrib[g.loc] / 256 != hint - 6)
00129 g.hintlc[hint] = -1;
00130 g.hintlc[hint]++;
00131 if (g.hintlc[hint] >= g.hints[hint][1])
00132 do_hint(hint);
00133 }
00134
00135 if (g.closed) {
00136 if (g.prop[OYSTER] < 0 && toting(OYSTER))
00137 pspeak(OYSTER, 1);
00138 for (i = 1; i < MAXOBJ; ++i)
00139 if (toting(i) && g.prop[i] < 0)
00140 g.prop[i] = -1 - g.prop[i];
00141 }
00142 g.wzdark = dark();
00143 if (g.knfloc > 0 && g.knfloc != g.loc)
00144 g.knfloc = 0;
00145 ++g.turns;
00146 i = rand();
00147
00148 if (stimer())
00149
00150 return;
00151
00152 while (!english())
00153 ;
00154
00155 vrbx = 1;
00156 objx = objs[1] ? 1 : 0;
00157 iobx = iobjs[1] ? 1 : 0;
00158 verb = VAL(verbs[vrbx]);
00159 do {
00160 object = objx ? objs[objx] : 0;
00161 iobj = iobx ? iobjs[iobx] : 0;
00162 if (object && (objs[2] || iobjs[2])) {
00163 pspeak(object, -1);
00164 printf(" ");
00165 }
00166 switch (CLASS(verbs[vrbx])) {
00167 case MOTION:
00168 motion = verb;
00169 domove();
00170 break;
00171 case NOUN:
00172 bug(22);
00173 case ACTION:
00174 if (object || iobj)
00175 trverb();
00176 else
00177 itverb();
00178 break;
00179 case MISC:
00180 rspeak(verb);
00181 if (verb == 51)
00182 g.hinted[1] = TRUE;
00183 break;
00184 default:
00185 bug(22);
00186 }
00187 if (objx) {
00188 objx++;
00189 if (objs[objx] == 0)
00190 objx = 0;
00191 }
00192 if ((!objx || !objs[objx]) && iobx) {
00193 iobx++;
00194 if (iobjs[iobx] == 0)
00195 iobx = 0;
00196 if (iobx && iobjs[1])
00197 objx = 1;
00198 }
00199 } while (objx || iobx);
00200 return;
00201 }
00202
00203
00204
00205
00206 void describe()
00207 {
00208 if (toting(BEAR))
00209 rspeak(141);
00210 if (dark())
00211 rspeak(16);
00212 else if ((g.terse && verb != LOOK) || g.visited[g.loc] % g.abbnum)
00213 descsh(g.loc);
00214 else
00215 desclg(g.loc);
00216 if (g.loc == 33 && pct(25) && !g.closing)
00217 rspeak(8);
00218 if (g.loc == 147 && !g.visited[g.loc])
00219 rspeak(216);
00220 return;
00221 }
00222
00223
00224
00225
00226 void descitem()
00227 {
00228 int i, state;
00229
00230 for (i = 1; i < MAXOBJ; ++i) {
00231 if (at(i)) {
00232 if (i == STEPS && toting(NUGGET))
00233 continue;
00234 if (g.prop[i] < 0) {
00235 if (g.closed)
00236 continue;
00237 else {
00238 g.prop[i] = 0;
00239 if (i == RUG || i == CHAIN
00240 || i == SWORD || i == CASK)
00241 g.prop[i] = 1;
00242 if (i == CLOAK || i == RING)
00243 g.prop[i] = 2;
00244 --g.tally;
00245 }
00246 }
00247 if (i == STEPS && g.loc == g.fixed[STEPS])
00248 state = 1;
00249 else
00250 state = g.prop[i] % 8;
00251 pspeak(i, state);
00252 lookin(i);
00253 }
00254 }
00255
00256 if (g.tally == g.tally2 && g.tally != 0 && g.limit > 35)
00257 g.limit = 35;
00258 return;
00259 }
00260
00261
00262
00263
00264
00265 void dwarfend()
00266 {
00267 rspeak(136);
00268 normend();
00269 return;
00270 }
00271
00272
00273
00274
00275 void normend()
00276 {
00277 score(FALSE);
00278 gaveup = TRUE;
00279 return;
00280 }
00281
00282
00283
00284
00285
00286 void death()
00287 {
00288 int yea, j;
00289
00290 if (!g.closing) {
00291 if (g.limit < 0) {
00292 rspeak(185);
00293 normend();
00294 return;
00295 }
00296 yea = yes(81 + g.numdie * 2, 82 + g.numdie * 2, 54);
00297 if (++g.numdie >= MAXDIE || !yea)
00298 normend();
00299 if (g.chase) {
00300 g.chase = FALSE;
00301 g.prop[WUMPUS] = 0;
00302 move(WUMPUS, 174);
00303 }
00304 if (toting(LAMP))
00305 g.prop[LAMP] = 0;
00306 for (j = 1; j < MAXOBJ; ++j) {
00307 if (toting(j))
00308 drop(j, j == LAMP ? 1 : g.oldloc2);
00309 if (wearng(j)) {
00310 g.prop[j] = 0;
00311 bitoff(j, WEARBT);
00312 }
00313 }
00314 g.newloc = 3;
00315 g.oldloc = g.loc;
00316 g.health = 100;
00317 return;
00318 }
00319
00320 rspeak(131);
00321 ++g.numdie;
00322 normend();
00323 return;
00324 }
00325
00326
00327
00328
00329 void dwarves()
00330 {
00331 int i, j, k, attack, stick, dtotal;
00332
00333
00334 if (g.newloc == 0 || forced(g.newloc) || g.loc_attrib[g.newloc] & NOPIRAT)
00335 return;
00336
00337
00338 if (!g.dflag) {
00339 if (inside(g.newloc))
00340 ++g.dflag;
00341 return;
00342 }
00343
00344 if (g.dflag == 1) {
00345 if (!inside(g.newloc) || pct(85))
00346 return;
00347 ++g.dflag;
00348
00349
00350 for (i = 1; i < 3; ++i)
00351 if (pct(50))
00352 g.dloc[(ranz(DWARFMAX - 1)) + 1] = 0;
00353
00354
00355 for (i = 1; i <= DWARFMAX; ++i) {
00356 if (g.dloc[i] == g.newloc)
00357 g.dloc[i] = g.daltloc;
00358 g.odloc[i] = g.dloc[i];
00359 }
00360 rspeak(3);
00361 drop(AXE, g.newloc);
00362 return;
00363 }
00364
00365
00366
00367
00368
00369
00370 dtotal = attack = stick = 0;
00371 for (i = 1; i <= DWARFMAX; ++i) {
00372 if (g.dloc[i] == 0)
00373 continue;
00374
00375
00376 do
00377 j = ranz(106) + 15;
00378
00379 while (j == g.odloc[i] || j == g.dloc[i]
00380 || g.loc_attrib[j] & NOPIRAT);
00381
00382 if (j == 0)
00383 bug(36);
00384 g.odloc[i] = g.dloc[i];
00385 g.dloc[i] = j;
00386
00387 g.dseen[i] = ((g.dseen[i] && inside(g.newloc))
00388 || g.dloc[i] == g.newloc
00389 || g.odloc[i] == g.newloc);
00390
00391 if (g.dseen[i]) {
00392 g.dloc[i] = g.newloc;
00393 if (i == DWARFMAX)
00394 dopirate();
00395 else {
00396 ++dtotal;
00397 if (g.odloc[i] == g.dloc[i]) {
00398 ++attack;
00399 if (g.knfloc >= 0)
00400 g.knfloc = g.newloc;
00401 if (ranz(1000) < (45 * (g.dflag - 2)))
00402 ++stick;
00403 }
00404 }
00405 }
00406 }
00407
00408
00409 if (dtotal == 0)
00410 return;
00411 if (dtotal > 1)
00412 printf("There are %d threatening little dwarves in the room with you!\n", dtotal);
00413 else
00414 rspeak(4);
00415 if (attack == 0)
00416 return;
00417 if (g.dflag == 2)
00418 ++g.dflag;
00419 if (attack > 1) {
00420 printf("%d of them throw knives at you!!\n", attack);
00421 k = 6;
00422 } else {
00423 rspeak(5);
00424 k = 52;
00425 }
00426 if (stick <= 1) {
00427 rspeak(stick + k);
00428 if (stick == 0)
00429 return;
00430 } else
00431 printf("%d of them get you !!!\n", stick);
00432 g.oldloc2 = g.newloc;
00433 death();
00434 return;
00435 }
00436
00437
00438
00439
00440 void dopirate()
00441 {
00442 int j;
00443 boolean k;
00444
00445 if (g.newloc == g.chloc || g.prop[CHEST] >= 0)
00446 return;
00447 k = FALSE;
00448
00449
00450 for (j = 1; j < MAXOBJ; ++j)
00451 if (treasr(j) && !(j == CASK && liq(CASK) == WINE)
00452 && !(j == PYRAMID && (g.newloc == g.place[PYRAMID]
00453 || g.newloc == g.place[EMERALD]))) {
00454 if (toting(j) && athand(j))
00455 goto stealit;
00456 if (here(j))
00457 k = TRUE;
00458 }
00459 if (g.tally == g.tally2 + 1 && k == FALSE && g.place[CHEST] == 0 &&
00460 athand(LAMP) && g.prop[LAMP] == 1) {
00461 rspeak(186);
00462 move(CHEST, g.chloc);
00463 move(MESSAGE, g.chloc2);
00464 g.dloc[DWARFMAX] = g.chloc;
00465 g.odloc[DWARFMAX] = g.chloc;
00466 g.dseen[DWARFMAX] = 0;
00467 return;
00468 }
00469 if (g.odloc[DWARFMAX] != g.dloc[DWARFMAX] && pct(30))
00470 rspeak(127);
00471 return;
00472
00473 stealit:
00474
00475 rspeak(128);
00476
00477 if (g.place[MESSAGE] == 0)
00478 move(CHEST, g.chloc);
00479 move(MESSAGE, g.chloc2);
00480 for (j = 1; j < MAXOBJ; ++j) {
00481 if (!treasr(j) || !athand(j)
00482 || (j == PYRAMID &&
00483 (g.newloc == plac[PYRAMID] || g.newloc == plac[EMERALD]))
00484 || (j == CASK && (liq(CASK) != WINE)))
00485 continue;
00486 if (enclosed(j))
00487 extract(j);
00488 if (wearng(j)) {
00489 g.prop[j] = 0;
00490 bitoff(j, WEARBT);
00491 }
00492 insert(j, CHEST);
00493 }
00494 g.dloc[DWARFMAX] = g.chloc;
00495 g.odloc[DWARFMAX] = g.chloc;
00496 g.dseen[DWARFMAX] = FALSE;
00497 return;
00498 }
00499
00500
00501
00502
00503 int stimer()
00504 {
00505 int i, spk;
00506 static int clock3;
00507
00508 g.foobar = g.foobar > 0 ? -g.foobar : 0;
00509 g.combo = g.combo > 0 ? -g.combo : 0;
00510 if (g.turns > 310 && g.abbnum != 10000 && !g.terse)
00511 rspeak(273);
00512
00513
00514 if (g.closed) {
00515 clock3--;
00516 if (clock3 == 0) {
00517 g.prop[PHONE] = 0;
00518 g.prop[BOOTH] = 0;
00519 rspeak(284);
00520 } else if (clock3 < -7) {
00521 rspeak(254);
00522 normend();
00523 return (TRUE);
00524 }
00525 }
00526 if (g.tally == 0 && inside(g.loc) && g.loc != Y2)
00527 --g.clock;
00528 if (g.clock == 0) {
00529
00530 g.prop[GRATE] = 0;
00531 biton(GRATE, LOCKBT);
00532 bitoff(GRATE, OPENBT);
00533 g.prop[FISSURE] = 0;
00534 g.prop[TDOOR] = 0;
00535 biton(TDOOR, LOCKBT);
00536 bitoff(TDOOR, OPENBT);
00537 g.prop[TDOOR2] = 0;
00538 biton(TDOOR2, LOCKBT);
00539 bitoff(TDOOR2, OPENBT);
00540 for (i = 1; i <= DWARFMAX; ++i) {
00541 g.dseen[i] = FALSE;
00542 g.dloc[i] = 0;
00543 }
00544 move(TROLL, 0);
00545 move((TROLL + MAXOBJ), 0);
00546 move(TROLL2, plac[TROLL]);
00547 move((TROLL2 + MAXOBJ), fixd[TROLL]);
00548 juggle(CHASM);
00549 if (g.prop[BEAR] != 3)
00550 destroy(BEAR);
00551 g.prop[CHAIN] = 0;
00552 g.fixed[CHAIN] = 0;
00553 g.prop[AXE] = 0;
00554 g.fixed[AXE] = 0;
00555 rspeak(129);
00556 g.clock = -1;
00557 g.closing = TRUE;
00558 return (FALSE);
00559 }
00560 if (g.clock < 0)
00561 --g.clock2;
00562 if (g.clock2 == 0) {
00563
00564 g.prop[BOTTLE] = put(BOTTLE, 115, 8);
00565 g.holder[BOTTLE] = WATER;
00566 g.place[WATER] = -BOTTLE;
00567 g.hlink[WATER] = 0;
00568 bitoff(BOTTLE, OPENBT);
00569 g.prop[PLANT] = put(PLANT, 115, 0);
00570 g.prop[OYSTER] = put(OYSTER, 115, 0);
00571 g.prop[LAMP] = put(LAMP, 115, 0);
00572 g.prop[ROD] = put(ROD, 115, 0);
00573 g.prop[DWARF] = put(DWARF, 115, 0);
00574 g.loc = 115;
00575 g.oldloc = 115;
00576 g.newloc = 115;
00577
00578 put(GRATE, 116, 0);
00579 biton(GRATE, LOCKBT);
00580 bitoff(GRATE, OPENBT);
00581 g.prop[SNAKE] = put(SNAKE, 116, 1);
00582 g.prop[BIRD] = put(BIRD, 116, 1);
00583 g.prop[CAGE] = put(CAGE, 116, 0);
00584 g.prop[ROD2] = put(ROD2, 116, 0);
00585 g.prop[PILLOW] = put(PILLOW, 116, 0);
00586
00587 g.prop[BOOTH] = put(BOOTH, 116, -3);
00588 g.fixed[BOOTH] = 115;
00589 g.prop[PHONE] = put(PHONE, 212, -4);
00590
00591 g.prop[MIRROR] = put(MIRROR, 115, 0);
00592 g.fixed[MIRROR] = 116;
00593 g.prop[BOOK2] = put(BOOK2, 115, 0);
00594
00595 for (i = 1; i < MAXOBJ; ++i) {
00596 if (toting(i) && enclosed(i))
00597 extract(i);
00598 if (toting(i))
00599 destroy(i);
00600 }
00601 rspeak(132);
00602 g.closed = TRUE;
00603 clock3 = 20 + ranz(20);
00604 newtravel = TRUE;
00605 return (TRUE);
00606 }
00607 if (g.prop[LAMP] == 1)
00608 --g.limit;
00609 if (g.limit == 0) {
00610 --g.limit;
00611 g.prop[LAMP] = 0;
00612 if (here(LAMP))
00613 rspeak(184);
00614 return (FALSE);
00615 }
00616 if (g.limit < 0 && outside(g.loc)) {
00617 rspeak(185);
00618 normend();
00619 return (TRUE);
00620 }
00621 if (g.limit <= 40) {
00622 if (g.lmwarn || !here(LAMP))
00623 return (FALSE);
00624 g.lmwarn = TRUE;
00625 spk = 187;
00626 if (g.prop[BATTERIES] == 1)
00627 spk = 323;
00628 if (g.place[BATTERIES] == 0)
00629 spk = 183;
00630 if (g.prop[VEND] == 1)
00631 spk = 189;
00632 rspeak(spk);
00633 return (FALSE);
00634 }
00635 return (FALSE);
00636 }
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646 #define MASE 1
00647 #define DARK 2
00648 #define WITT 3
00649 #define H_SWORD 4
00650 #define SLIDE 5
00651 #define H_GRATE 6
00652 #define H_BIRD 7
00653 #define H_ELFIN 8
00654 #define RNBOW 9
00655 #define STYX 10
00656 #define H_SNAKE 11
00657 #define CASTLE 12
00658
00659 void do_hint(hint)
00660 int hint;
00661 {
00662 g.hintlc[hint] = 0;
00663 switch (hint + 1 - HNTMIN) {
00664 case MASE:
00665 if (!at(g.loc) && !at(g.oldloc)
00666 && !at(g.loc) && burden(0) > 1)
00667 break;
00668 else
00669 return;
00670 case DARK:
00671 if (g.prop[EMERALD] != -1 && g.prop[PYRAMID] == -1)
00672 break;
00673 else
00674 return;
00675 case WITT:
00676 break;
00677 case H_SWORD:
00678 if ((g.prop[SWORD] == 1 || g.prop[SWORD] == 5)
00679 && !toting(CROWN))
00680 break;
00681 else
00682 return;
00683 case SLIDE:
00684 break;
00685 case H_GRATE:
00686 if (g.prop[GRATE] == 0 && !athand(KEYS))
00687 break;
00688 else
00689 return;
00690 case H_BIRD:
00691 if (here(BIRD) && athand(ROD) && object == BIRD)
00692 break;
00693 else
00694 return;
00695 case H_ELFIN:
00696 if (!g.visited[159])
00697 break;
00698 else
00699 return;
00700 case RNBOW:
00701 if (!toting(SHOES) || g.visited[205])
00702 break;
00703 else
00704 return;
00705 case STYX:
00706 if (!athand(LYRE) && g.prop[DOG] != 1)
00707 break;
00708 else
00709 return;
00710 case H_SNAKE:
00711 if (here(SNAKE) && !here(BIRD))
00712 break;
00713 else
00714 return;
00715 case CASTLE:
00716 break;
00717 default:
00718 printf(" TRYING TO PRINT HINT # %d\n", hint);
00719 bug(27);
00720 }
00721 if (!yes(g.hints[hint][3], 0, 54))
00722 return;
00723 printf("\nI am prepared to give you a hint,");
00724 printf(" but it will cost you %2d points\n", g.hints[hint][2]);
00725 g.hinted[hint] = yes(175, g.hints[hint][4], 54);
00726 if (g.hinted[hint] && g.limit > 30)
00727 g.limit += 30 * g.hints[hint][2];
00728 return;
00729 }