source: trunk/minix/commands/advent/turn.c@ 9

Last change on this file since 9 was 9, checked in by Mattia Monga, 13 years ago

Minix 3.1.2a

File size: 15.0 KB
Line 
1/* program TURN.C */
2
3
4#include <stdio.h>
5#include <stdlib.h>
6#include "advent.h"
7#include "advdec.h"
8
9_PROTOTYPE(void descitem, (void));
10_PROTOTYPE(void domove, (void));
11_PROTOTYPE(void goback, (void));
12_PROTOTYPE(void copytrv, (struct trav *, struct trav *));
13_PROTOTYPE(void dotrav, (void));
14_PROTOTYPE(void badmove, (void));
15_PROTOTYPE(void spcmove, (int));
16_PROTOTYPE(void death, (void));
17_PROTOTYPE(void dwarves, (void));
18_PROTOTYPE(void dopirate, (void));
19_PROTOTYPE(int stimer, (void));
20_PROTOTYPE(void do_hint, (int));
21
22
23/*
24 Routine to take 1 turn
25*/
26void turn()
27{
28 int i, hint;
29 static int waste = 0;
30
31 if (newtravel) {
32 /* If closing, then he can't leave except via the main office. */
33 if (outside(g.newloc) && g.newloc != 0 && g.closing) {
34 rspeak(130);
35 g.newloc = g.loc;
36 if (!g.panic)
37 g.clock2 = 15;
38 g.panic = TRUE;
39 }
40 /* See if a dwarf has seen him and has come from where he wants
41 to go. */
42 if (g.newloc != g.loc && !forced(g.loc) && g.loc_attrib[g.loc] & NOPIRAT == 0)
43 for (i = 1; i < (DWARFMAX - 1); ++i)
44 if (g.odloc[i] == g.newloc && g.dseen[i]) {
45 g.newloc = g.loc;
46 rspeak(2);
47 break;
48 }
49
50 g.loc = g.newloc;
51 dwarves(); /* & special dwarf(pirate who
52 steals) */
53
54 /* Check for death */
55 if (g.loc == 0) {
56 death();
57 return;
58 }
59 /* Check for forced move */
60 if (forced(g.loc)) {
61 desclg(g.loc);
62 ++g.visited[g.loc];
63 domove();
64 return;
65 }
66 /* Check for wandering in dark */
67 if (g.wzdark && dark() && pct(35)) {
68 rspeak(23);
69 g.oldloc2 = g.loc;
70 death();
71 return;
72 }
73 /* see if he is wasting his batteies out in the open */
74 if (outside(g.loc) && g.prop[LAMP]) {
75 waste++;
76 if (waste > 11) {
77 rspeak(324);
78 waste = 0;
79 }
80 } else
81 waste = 0;
82
83 /* If wumpus is chasing stooge, see if wumpus gets him */
84 if (g.chase) {
85 g.chase++;
86 g.prop[WUMPUS] = g.chase / 2;
87 move(WUMPUS, g.loc);
88 if (g.chase >= 10) {
89 if (dark())
90 rspeak(270);
91 pspeak(WUMPUS, 5);
92 death();
93 return;
94 }
95 }
96 /* check for radiation poisoning. */
97 g.health += (outside(g.loc)) ? 3 : 1;
98 if (g.health > 100)
99 g.health = 100;
100 if (here(RADIUM) && (g.place[RADIUM] != -SHIELD || ajar(SHIELD)))
101 g.health -= 7;
102 if (g.health < 60) {
103 rspeak(391 + (60 - g.health) / 10);
104 if (g.health < 0) {
105 death();
106 return;
107 }
108 }
109 if ((g.oldloc == 188) && (g.loc != 188 && g.loc != 189)
110 && (g.prop[BOOTH] == 1)) {
111 move(GNOME, 0);
112 g.prop[BOOTH] = 0;
113 }
114 /* Describe his situation */
115 describe();
116 if (!blind()) {
117 ++g.visited[g.loc];
118 descitem();
119 }
120 } /* end of newtravel start for
121 second entry point */
122 /* Check if this location is eligible for any hints. If been here
123 long enough, branch to help section. Ignore "hints" < HNTMIN
124 (special stuff, see database notes. */
125 for (hint = HNTMIN; hint <= HNTMAX; hint++) {
126 if (g.hinted[hint])
127 continue;
128 if (g.loc_attrib[g.loc] / 256 != hint - 6)
129 g.hintlc[hint] = -1;
130 g.hintlc[hint]++;
131 if (g.hintlc[hint] >= g.hints[hint][1])
132 do_hint(hint);
133 }
134
135 if (g.closed) {
136 if (g.prop[OYSTER] < 0 && toting(OYSTER))
137 pspeak(OYSTER, 1);
138 for (i = 1; i < MAXOBJ; ++i)
139 if (toting(i) && g.prop[i] < 0)
140 g.prop[i] = -1 - g.prop[i];
141 }
142 g.wzdark = dark();
143 if (g.knfloc > 0 && g.knfloc != g.loc)
144 g.knfloc = 0;
145 ++g.turns;
146 i = rand();
147
148 if (stimer()) /* as the grains of sand slip
149 by */
150 return;
151
152 while (!english()) /* retrieve player instructions */
153 ;
154
155 vrbx = 1;
156 objx = objs[1] ? 1 : 0;
157 iobx = iobjs[1] ? 1 : 0;
158 verb = VAL(verbs[vrbx]);
159 do {
160 object = objx ? objs[objx] : 0;
161 iobj = iobx ? iobjs[iobx] : 0;
162 if (object && (objs[2] || iobjs[2])) {
163 pspeak(object, -1);
164 printf(" ");
165 }
166 switch (CLASS(verbs[vrbx])) {
167 case MOTION:
168 motion = verb;
169 domove();
170 break;
171 case NOUN:
172 bug(22);
173 case ACTION:
174 if (object || iobj)
175 trverb();
176 else
177 itverb();
178 break;
179 case MISC:
180 rspeak(verb);
181 if (verb == 51)
182 g.hinted[1] = TRUE;
183 break;
184 default:
185 bug(22);
186 }
187 if (objx) {
188 objx++;
189 if (objs[objx] == 0)
190 objx = 0;
191 }
192 if ((!objx || !objs[objx]) && iobx) {
193 iobx++;
194 if (iobjs[iobx] == 0)
195 iobx = 0;
196 if (iobx && iobjs[1])
197 objx = 1;
198 }
199 } while (objx || iobx);
200 return;
201}
202
203/*
204 Routine to describe current location
205*/
206void describe()
207{
208 if (toting(BEAR))
209 rspeak(141);
210 if (dark())
211 rspeak(16);
212 else if ((g.terse && verb != LOOK) || g.visited[g.loc] % g.abbnum)
213 descsh(g.loc);
214 else
215 desclg(g.loc);
216 if (g.loc == 33 && pct(25) && !g.closing)
217 rspeak(8);
218 if (g.loc == 147 && !g.visited[g.loc])
219 rspeak(216);
220 return;
221}
222
223/*
224 Routine to describe visible items
225*/
226void descitem()
227{
228 int i, state;
229
230 for (i = 1; i < MAXOBJ; ++i) {
231 if (at(i)) {
232 if (i == STEPS && toting(NUGGET))
233 continue;
234 if (g.prop[i] < 0) {
235 if (g.closed)
236 continue;
237 else {
238 g.prop[i] = 0;
239 if (i == RUG || i == CHAIN
240 || i == SWORD || i == CASK)
241 g.prop[i] = 1;
242 if (i == CLOAK || i == RING)
243 g.prop[i] = 2;
244 --g.tally;
245 }
246 }
247 if (i == STEPS && g.loc == g.fixed[STEPS])
248 state = 1;
249 else
250 state = g.prop[i] % 8;
251 pspeak(i, state);
252 lookin(i);
253 }
254 }
255 /* If remaining treasures too elusive, zap his lamp */
256 if (g.tally == g.tally2 && g.tally != 0 && g.limit > 35)
257 g.limit = 35;
258 return;
259}
260
261/*
262 Routine to handle player's demise via
263 waking up the dwarves...
264*/
265void dwarfend()
266{
267 rspeak(136);
268 normend();
269 return;
270}
271
272/*
273 normal end of game
274*/
275void normend()
276{
277 score(FALSE);
278 gaveup = TRUE;
279 return;
280}
281
282/*
283 Routine to handle the passing on of one
284 of the player's incarnations...
285*/
286void death()
287{
288 int yea, j;
289
290 if (!g.closing) {
291 if (g.limit < 0) {
292 rspeak(185);
293 normend();
294 return;
295 }
296 yea = yes(81 + g.numdie * 2, 82 + g.numdie * 2, 54);
297 if (++g.numdie >= MAXDIE || !yea)
298 normend();
299 if (g.chase) {
300 g.chase = FALSE;
301 g.prop[WUMPUS] = 0;
302 move(WUMPUS, 174);
303 }
304 if (toting(LAMP))
305 g.prop[LAMP] = 0;
306 for (j = 1; j < MAXOBJ; ++j) {
307 if (toting(j))
308 drop(j, j == LAMP ? 1 : g.oldloc2);
309 if (wearng(j)) {
310 g.prop[j] = 0;
311 bitoff(j, WEARBT);
312 }
313 }
314 g.newloc = 3;
315 g.oldloc = g.loc;
316 g.health = 100;
317 return;
318 }
319 /* Closing -- no resurrection... */
320 rspeak(131);
321 ++g.numdie;
322 normend();
323 return;
324}
325
326/*
327 dwarf stuff.
328*/
329void dwarves()
330{
331 int i, j, k, attack, stick, dtotal;
332
333 /* See if dwarves allowed here */
334 if (g.newloc == 0 || forced(g.newloc) || g.loc_attrib[g.newloc] & NOPIRAT)
335 return;
336
337 /* See if dwarves are active. */
338 if (!g.dflag) {
339 if (inside(g.newloc))
340 ++g.dflag;
341 return;
342 }
343 /* If first close encounter (of 3rd kind) */
344 if (g.dflag == 1) {
345 if (!inside(g.newloc) || pct(85))
346 return;
347 ++g.dflag;
348
349 /* kill 0, 1 or 2 of the dwarfs */
350 for (i = 1; i < 3; ++i)
351 if (pct(50))
352 g.dloc[(ranz(DWARFMAX - 1)) + 1] = 0;
353
354 /* If any of the survivors is at location, use alternate choise */
355 for (i = 1; i <= DWARFMAX; ++i) {
356 if (g.dloc[i] == g.newloc)
357 g.dloc[i] = g.daltloc;
358 g.odloc[i] = g.dloc[i];
359 }
360 rspeak(3);
361 drop(AXE, g.newloc);
362 return;
363 }
364 /* Things are in full swing. Move each dwarf at random, except if
365 he's seen us then he sticks with us. Dwarfs never go to
366 locations outside or meet the bear or following him into dead
367 end in maze. And of couse, dead dwarves don't do much of
368 anything. */
369
370 dtotal = attack = stick = 0;
371 for (i = 1; i <= DWARFMAX; ++i) {
372 if (g.dloc[i] == 0)
373 continue;
374 /* Move a dwarf at random. we don't have a matrix around to do
375 it as in the original version... */
376 do
377 j = ranz(106) + 15;
378 /* allowed area */
379 while (j == g.odloc[i] || j == g.dloc[i]
380 || g.loc_attrib[j] & NOPIRAT);
381
382 if (j == 0)
383 bug(36);
384 g.odloc[i] = g.dloc[i];
385 g.dloc[i] = j;
386
387 g.dseen[i] = ((g.dseen[i] && inside(g.newloc))
388 || g.dloc[i] == g.newloc
389 || g.odloc[i] == g.newloc);
390
391 if (g.dseen[i]) {
392 g.dloc[i] = g.newloc;
393 if (i == DWARFMAX)
394 dopirate();
395 else {
396 ++dtotal;
397 if (g.odloc[i] == g.dloc[i]) {
398 ++attack;
399 if (g.knfloc >= 0)
400 g.knfloc = g.newloc;
401 if (ranz(1000) < (45 * (g.dflag - 2)))
402 ++stick;
403 }
404 }
405 }
406 }
407
408 /* Now we know shat's happing, let's tell the poor sucker about it */
409 if (dtotal == 0)
410 return;
411 if (dtotal > 1)
412 printf("There are %d threatening little dwarves in the room with you!\n", dtotal);
413 else
414 rspeak(4);
415 if (attack == 0)
416 return;
417 if (g.dflag == 2)
418 ++g.dflag;
419 if (attack > 1) {
420 printf("%d of them throw knives at you!!\n", attack);
421 k = 6;
422 } else {
423 rspeak(5);
424 k = 52;
425 }
426 if (stick <= 1) {
427 rspeak(stick + k);
428 if (stick == 0)
429 return;
430 } else
431 printf("%d of them get you !!!\n", stick);
432 g.oldloc2 = g.newloc;
433 death();
434 return;
435}
436
437/*
438 pirate stuff
439*/
440void dopirate()
441{
442 int j;
443 boolean k;
444
445 if (g.newloc == g.chloc || g.prop[CHEST] >= 0)
446 return;
447 k = FALSE;
448 /* Pirate won't take pyramid from plover room or dark room (too
449 easy! ) */
450 for (j = 1; j < MAXOBJ; ++j)
451 if (treasr(j) && !(j == CASK && liq(CASK) == WINE)
452 && !(j == PYRAMID && (g.newloc == g.place[PYRAMID]
453 || g.newloc == g.place[EMERALD]))) {
454 if (toting(j) && athand(j))
455 goto stealit;
456 if (here(j))
457 k = TRUE;
458 }
459 if (g.tally == g.tally2 + 1 && k == FALSE && g.place[CHEST] == 0 &&
460 athand(LAMP) && g.prop[LAMP] == 1) {
461 rspeak(186);
462 move(CHEST, g.chloc);
463 move(MESSAGE, g.chloc2);
464 g.dloc[DWARFMAX] = g.chloc;
465 g.odloc[DWARFMAX] = g.chloc;
466 g.dseen[DWARFMAX] = 0;
467 return;
468 }
469 if (g.odloc[DWARFMAX] != g.dloc[DWARFMAX] && pct(30))
470 rspeak(127);
471 return;
472
473stealit:
474
475 rspeak(128);
476 /* don't steal chest back from troll! */
477 if (g.place[MESSAGE] == 0)
478 move(CHEST, g.chloc);
479 move(MESSAGE, g.chloc2);
480 for (j = 1; j < MAXOBJ; ++j) {
481 if (!treasr(j) || !athand(j)
482 || (j == PYRAMID &&
483 (g.newloc == plac[PYRAMID] || g.newloc == plac[EMERALD]))
484 || (j == CASK && (liq(CASK) != WINE)))
485 continue;
486 if (enclosed(j))
487 extract(j);
488 if (wearng(j)) {
489 g.prop[j] = 0;
490 bitoff(j, WEARBT);
491 }
492 insert(j, CHEST);
493 }
494 g.dloc[DWARFMAX] = g.chloc;
495 g.odloc[DWARFMAX] = g.chloc;
496 g.dseen[DWARFMAX] = FALSE;
497 return;
498}
499
500/*
501 special time limit stuff...
502*/
503int stimer()
504{
505 int i, spk;
506 static int clock3;
507
508 g.foobar = g.foobar > 0 ? -g.foobar : 0;
509 g.combo = g.combo > 0 ? -g.combo : 0;
510 if (g.turns > 310 && g.abbnum != 10000 && !g.terse)
511 rspeak(273);
512
513 /* Bump all the right clocks for reconning battery life and closing */
514 if (g.closed) {
515 clock3--;
516 if (clock3 == 0) {
517 g.prop[PHONE] = 0;
518 g.prop[BOOTH] = 0;
519 rspeak(284);
520 } else if (clock3 < -7) {
521 rspeak(254);
522 normend();
523 return (TRUE);
524 }
525 }
526 if (g.tally == 0 && inside(g.loc) && g.loc != Y2)
527 --g.clock;
528 if (g.clock == 0) {
529 /* Start closing the cave */
530 g.prop[GRATE] = 0;
531 biton(GRATE, LOCKBT);
532 bitoff(GRATE, OPENBT);
533 g.prop[FISSURE] = 0;
534 g.prop[TDOOR] = 0;
535 biton(TDOOR, LOCKBT);
536 bitoff(TDOOR, OPENBT);
537 g.prop[TDOOR2] = 0;
538 biton(TDOOR2, LOCKBT);
539 bitoff(TDOOR2, OPENBT);
540 for (i = 1; i <= DWARFMAX; ++i) {
541 g.dseen[i] = FALSE;
542 g.dloc[i] = 0;
543 }
544 move(TROLL, 0);
545 move((TROLL + MAXOBJ), 0);
546 move(TROLL2, plac[TROLL]);
547 move((TROLL2 + MAXOBJ), fixd[TROLL]);
548 juggle(CHASM);
549 if (g.prop[BEAR] != 3)
550 destroy(BEAR);
551 g.prop[CHAIN] = 0;
552 g.fixed[CHAIN] = 0;
553 g.prop[AXE] = 0;
554 g.fixed[AXE] = 0;
555 rspeak(129);
556 g.clock = -1;
557 g.closing = TRUE;
558 return (FALSE);
559 }
560 if (g.clock < 0)
561 --g.clock2;
562 if (g.clock2 == 0) {
563 /* Set up storage room... and close the cave... */
564 g.prop[BOTTLE] = put(BOTTLE, 115, 8);
565 g.holder[BOTTLE] = WATER;
566 g.place[WATER] = -BOTTLE;
567 g.hlink[WATER] = 0;
568 bitoff(BOTTLE, OPENBT);
569 g.prop[PLANT] = put(PLANT, 115, 0);
570 g.prop[OYSTER] = put(OYSTER, 115, 0);
571 g.prop[LAMP] = put(LAMP, 115, 0);
572 g.prop[ROD] = put(ROD, 115, 0);
573 g.prop[DWARF] = put(DWARF, 115, 0);
574 g.loc = 115;
575 g.oldloc = 115;
576 g.newloc = 115;
577 /* Leave the grate with normal (non-negative property). */
578 put(GRATE, 116, 0);
579 biton(GRATE, LOCKBT);
580 bitoff(GRATE, OPENBT);
581 g.prop[SNAKE] = put(SNAKE, 116, 1);
582 g.prop[BIRD] = put(BIRD, 116, 1);
583 g.prop[CAGE] = put(CAGE, 116, 0);
584 g.prop[ROD2] = put(ROD2, 116, 0);
585 g.prop[PILLOW] = put(PILLOW, 116, 0);
586
587 g.prop[BOOTH] = put(BOOTH, 116, -3);
588 g.fixed[BOOTH] = 115;
589 g.prop[PHONE] = put(PHONE, 212, -4);
590
591 g.prop[MIRROR] = put(MIRROR, 115, 0);
592 g.fixed[MIRROR] = 116;
593 g.prop[BOOK2] = put(BOOK2, 115, 0);
594
595 for (i = 1; i < MAXOBJ; ++i) {
596 if (toting(i) && enclosed(i))
597 extract(i);
598 if (toting(i))
599 destroy(i);
600 }
601 rspeak(132);
602 g.closed = TRUE;
603 clock3 = 20 + ranz(20);
604 newtravel = TRUE;
605 return (TRUE);
606 }
607 if (g.prop[LAMP] == 1)
608 --g.limit;
609 if (g.limit == 0) {
610 --g.limit;
611 g.prop[LAMP] = 0;
612 if (here(LAMP))
613 rspeak(184);
614 return (FALSE);
615 }
616 if (g.limit < 0 && outside(g.loc)) {
617 rspeak(185);
618 normend();
619 return (TRUE);
620 }
621 if (g.limit <= 40) {
622 if (g.lmwarn || !here(LAMP))
623 return (FALSE);
624 g.lmwarn = TRUE;
625 spk = 187;
626 if (g.prop[BATTERIES] == 1)
627 spk = 323;
628 if (g.place[BATTERIES] == 0)
629 spk = 183;
630 if (g.prop[VEND] == 1)
631 spk = 189;
632 rspeak(spk);
633 return (FALSE);
634 }
635 return (FALSE);
636}
637
638/* HINTS
639 come here if he's been long enough at required location(s)
640 for some unused hint, hint number is in variable "hint".
641 Branch to quick test for additional conditions, then
642 do neet stuff. If conditions are met and we want to offer
643 hint. Clear hintlc if no action is taken.
644 */
645
646#define MASE 1
647#define DARK 2
648#define WITT 3
649#define H_SWORD 4
650#define SLIDE 5
651#define H_GRATE 6
652#define H_BIRD 7
653#define H_ELFIN 8
654#define RNBOW 9
655#define STYX 10
656#define H_SNAKE 11
657#define CASTLE 12
658
659void do_hint(hint)
660int hint;
661{
662 g.hintlc[hint] = 0;
663 switch (hint + 1 - HNTMIN) {
664 case MASE:
665 if (!at(g.loc) && !at(g.oldloc)
666 && !at(g.loc) && burden(0) > 1)
667 break;
668 else
669 return;
670 case DARK:
671 if (g.prop[EMERALD] != -1 && g.prop[PYRAMID] == -1)
672 break;
673 else
674 return;
675 case WITT:
676 break;
677 case H_SWORD:
678 if ((g.prop[SWORD] == 1 || g.prop[SWORD] == 5)
679 && !toting(CROWN))
680 break;
681 else
682 return;
683 case SLIDE:
684 break;
685 case H_GRATE:
686 if (g.prop[GRATE] == 0 && !athand(KEYS))
687 break;
688 else
689 return;
690 case H_BIRD:
691 if (here(BIRD) && athand(ROD) && object == BIRD)
692 break;
693 else
694 return;
695 case H_ELFIN:
696 if (!g.visited[159])
697 break;
698 else
699 return;
700 case RNBOW:
701 if (!toting(SHOES) || g.visited[205])
702 break;
703 else
704 return;
705 case STYX:
706 if (!athand(LYRE) && g.prop[DOG] != 1)
707 break;
708 else
709 return;
710 case H_SNAKE:
711 if (here(SNAKE) && !here(BIRD))
712 break;
713 else
714 return;
715 case CASTLE:
716 break;
717 default:
718 printf(" TRYING TO PRINT HINT # %d\n", hint);
719 bug(27);
720 }
721 if (!yes(g.hints[hint][3], 0, 54))
722 return;
723 printf("\nI am prepared to give you a hint,");
724 printf(" but it will cost you %2d points\n", g.hints[hint][2]);
725 g.hinted[hint] = yes(175, g.hints[hint][4], 54);
726 if (g.hinted[hint] && g.limit > 30)
727 g.limit += 30 * g.hints[hint][2];
728 return;
729}
Note: See TracBrowser for help on using the repository browser.