1 /* RESIDENT SUBROUTINES FOR DUNGEON */
2
3 /*COPYRIGHT 1980, INFOCOM COMPUTERS AND COMMUNICATIONS, CAMBRIDGE MA. 02142*/
4 /* ALL RIGHTS RESERVED, COMMERCIAL USAGE STRICTLY PROHIBITED */
5 /* WRITTEN BY R. M. SUPNIK */
6
7 #include <stdio.h>
8 #include "funcs.h"
9 #include "vars.h"
10
11 #ifndef SEEK_SET
12 #define SEEK_SET (0)
13 #endif
14
15 extern FILE *dbfile;
16
17 static void rspsb2nl_ P((integer, integer, integer, logical));
18
19 /* RSPEAK-- OUTPUT RANDOM MESSAGE ROUTINE */
20
21 /* CALLED BY-- */
22
23 /* CALL RSPEAK(MSGNUM) */
24
rspeak_(n)25 void rspeak_(n)
26 integer n;
27 {
28 rspsb2nl_(n, 0, 0, 1);
29 } /* rspeak_ */
30
31 /* RSPSUB-- OUTPUT RANDOM MESSAGE WITH SUBSTITUTABLE ARGUMENT */
32
33 /* CALLED BY-- */
34
35 /* CALL RSPSUB(MSGNUM,SUBNUM) */
36
rspsub_(n,s1)37 void rspsub_(n, s1)
38 integer n;
39 integer s1;
40 {
41 rspsb2nl_(n, s1, 0, 1);
42 } /* rspsub_ */
43
44 /* RSPSB2-- OUTPUT RANDOM MESSAGE WITH UP TO TWO SUBSTITUTABLE ARGUMENTS */
45
46 /* CALLED BY-- */
47
48 /* CALL RSPSB2(MSGNUM,SUBNUM1,SUBNUM2) */
49
rspsb2_(n,s1,s2)50 void rspsb2_(n, s1, s2)
51 integer n;
52 integer s1;
53 integer s2;
54 {
55 rspsb2nl_(n, s1, s2, 1);
56 } /* rspsb2_ */
57
58 /* rspsb2nl_ Display a substitutable message with an optional newline */
59
rspsb2nl_(n,y,z,nl)60 static void rspsb2nl_(n, y, z, nl)
61 integer n;
62 integer y;
63 integer z;
64 logical nl;
65 {
66 const char *zkey = "IanLanceTaylorJr";
67 long x;
68
69 x = (long)n;
70
71 if (x > 0) {
72 x = rmsg_1.rtext[x - 1];
73 }
74 /* !IF >0, LOOK UP IN RTEXT. */
75 if (x == 0) {
76 return;
77 }
78 /* !ANYTHING TO DO? */
79 play_1.telflg = TRUE_;
80 /* !SAID SOMETHING. */
81
82 x = ((- x) - 1) * 8;
83 if (fseek(dbfile, x + (long)rmsg_1.mrloc, SEEK_SET) == EOF) {
84 fprintf(stderr, "Error seeking database loc %d\n", x);
85 exit_();
86 }
87
88 if (nl)
89 more_output(NULL);
90
91 while (1) {
92 integer i;
93
94 i = getc(dbfile);
95 if (i == EOF) {
96 fprintf(stderr, "Error reading database loc %d\n", x);
97 exit_();
98 }
99 i ^= zkey[x & 0xf] ^ (x & 0xff);
100 x = x + 1;
101 if (i == '\0')
102 break;
103 else if (i == '\n') {
104 putchar('\n');
105 if (nl)
106 more_output(NULL);
107 }
108 else if (i == '#' && y != 0) {
109 long iloc;
110
111 iloc = ftell(dbfile);
112 rspsb2nl_(y, 0, 0, 0);
113 if (fseek(dbfile, iloc, SEEK_SET) == EOF) {
114 fprintf(stderr, "Error seeking database loc %d\n", iloc);
115 exit_();
116 }
117 y = z;
118 z = 0;
119 }
120 else
121 putchar(i);
122 }
123
124 if (nl)
125 putchar('\n');
126 }
127
128 /* OBJACT-- APPLY OBJECTS FROM PARSE VECTOR */
129
130 /* DECLARATIONS */
131
objact_()132 logical objact_()
133 {
134 /* System generated locals */
135 logical ret_val;
136
137 ret_val = TRUE_;
138 /* !ASSUME WINS. */
139 if (prsvec_1.prsi == 0) {
140 goto L100;
141 }
142 /* !IND OBJECT? */
143 if (oappli_(objcts_1.oactio[prsvec_1.prsi - 1], 0)) {
144 return ret_val;
145 }
146 /* !YES, LET IT HANDLE. */
147
148 L100:
149 if (prsvec_1.prso == 0) {
150 goto L200;
151 }
152 /* !DIR OBJECT? */
153 if (oappli_(objcts_1.oactio[prsvec_1.prso - 1], 0)) {
154 return ret_val;
155 }
156 /* !YES, LET IT HANDLE. */
157
158 L200:
159 ret_val = FALSE_;
160 /* !LOSES. */
161 return ret_val;
162 } /* objact_ */
163
164 /* BUG-- REPORT FATAL SYSTEM ERROR */
165
166 /* CALLED BY-- */
167
168 /* CALL BUG(NO,PAR) */
169
bug_(a,b)170 void bug_(a, b)
171 integer a;
172 integer b;
173 {
174 /* Local variables */
175
176 more_output(NULL);
177 printf("PROGRAM ERROR %d, PARAMETER=%d\n", a, b);
178
179 if (debug_1.dbgflg != 0) {
180 return;
181 }
182 exit_();
183
184 } /* bug_ */
185
186 /* NEWSTA-- SET NEW STATUS FOR OBJECT */
187
188 /* CALLED BY-- */
189
190 /* CALL NEWSTA(OBJECT,STRING,NEWROOM,NEWCON,NEWADV) */
191
newsta_(o,r,rm,cn,ad)192 void newsta_(o, r, rm, cn, ad)
193 integer o;
194 integer r;
195 integer rm;
196 integer cn;
197 integer ad;
198 {
199 rspeak_(r);
200 objcts_1.oroom[o - 1] = rm;
201 objcts_1.ocan[o - 1] = cn;
202 objcts_1.oadv[o - 1] = ad;
203 } /* newsta_ */
204
205 /* QHERE-- TEST FOR OBJECT IN ROOM */
206
207 /* DECLARATIONS */
208
qhere_(obj,rm)209 logical qhere_(obj, rm)
210 integer obj;
211 integer rm;
212 {
213 /* System generated locals */
214 integer i__1;
215 logical ret_val;
216
217 /* Local variables */
218 integer i;
219
220 ret_val = TRUE_;
221 if (objcts_1.oroom[obj - 1] == rm) {
222 return ret_val;
223 }
224 /* !IN ROOM? */
225 i__1 = oroom2_1.r2lnt;
226 for (i = 1; i <= i__1; ++i) {
227 /* !NO, SCH ROOM2. */
228 if (oroom2_1.oroom2[i - 1] == obj && oroom2_1.rroom2[i - 1] == rm) {
229
230 return ret_val;
231 }
232 /* L100: */
233 }
234 ret_val = FALSE_;
235 /* !NOT PRESENT. */
236 return ret_val;
237 } /* qhere_ */
238
239 /* QEMPTY-- TEST FOR OBJECT EMPTY */
240
241 /* DECLARATIONS */
242
qempty_(obj)243 logical qempty_(obj)
244 integer obj;
245 {
246 /* System generated locals */
247 integer i__1;
248 logical ret_val;
249
250 /* Local variables */
251 integer i;
252
253 ret_val = FALSE_;
254 /* !ASSUME LOSE. */
255 i__1 = objcts_1.olnt;
256 for (i = 1; i <= i__1; ++i) {
257 if (objcts_1.ocan[i - 1] == obj) {
258 return ret_val;
259 }
260 /* !INSIDE TARGET? */
261 /* L100: */
262 }
263 ret_val = TRUE_;
264 return ret_val;
265 } /* qempty_ */
266
267 /* JIGSUP- YOU ARE DEAD */
268
269 /* DECLARATIONS */
270
jigsup_(desc)271 void jigsup_(desc)
272 integer desc;
273 {
274 /* Initialized data */
275
276 static const integer rlist[9] = { 8,6,36,35,34,4,34,6,5 };
277
278 /* System generated locals */
279 integer i__1;
280
281 /* Local variables */
282 integer nonofl;
283 logical f;
284 integer i, j;
285
286 rspeak_(desc);
287 /* !DESCRIBE SAD STATE. */
288 prsvec_1.prscon = 1;
289 /* !STOP PARSER. */
290 if (debug_1.dbgflg != 0) {
291 return;
292 }
293 /* !IF DBG, EXIT. */
294 advs_1.avehic[play_1.winner - 1] = 0;
295 /* !GET RID OF VEHICLE. */
296 if (play_1.winner == aindex_1.player) {
297 goto L100;
298 }
299 /* !HIMSELF? */
300 rspsub_(432, objcts_1.odesc2[advs_1.aobj[play_1.winner - 1] - 1]);
301 /* !NO, SAY WHO DIED. */
302 newsta_(advs_1.aobj[play_1.winner - 1], 0, 0, 0, 0);
303 /* !SEND TO HYPER SPACE. */
304 return;
305
306 L100:
307 if (findex_1.endgmf) {
308 goto L900;
309 }
310 /* !NO RECOVERY IN END GAME. */
311 if (state_1.deaths >= 2) {
312 goto L1000;
313 }
314 /* !DEAD TWICE? KICK HIM OFF. */
315 if (! yesno_(10, 9, 8)) {
316 goto L1100;
317 }
318 /* !CONTINUE? */
319
320 i__1 = objcts_1.olnt;
321 for (j = 1; j <= i__1; ++j) {
322 /* !TURN OFF FIGHTING. */
323 if (qhere_(j, play_1.here)) {
324 objcts_1.oflag2[j - 1] &= ~ FITEBT;
325 }
326 /* L50: */
327 }
328
329 ++state_1.deaths;
330 scrupd_(- 10);
331 /* !CHARGE TEN POINTS. */
332 f = moveto_(rindex_1.fore1, play_1.winner);
333 /* !REPOSITION HIM. */
334 findex_1.egyptf = TRUE_;
335 /* !RESTORE COFFIN. */
336 if (objcts_1.oadv[oindex_1.coffi - 1] == play_1.winner) {
337 newsta_(oindex_1.coffi, 0, rindex_1.egypt, 0, 0);
338 }
339 objcts_1.oflag2[oindex_1.door - 1] &= ~ TCHBT;
340 objcts_1.oflag1[oindex_1.robot - 1] = (objcts_1.oflag1[oindex_1.robot - 1]
341 | VISIBT) & ~ NDSCBT;
342 if (objcts_1.oroom[oindex_1.lamp - 1] != 0 || objcts_1.oadv[oindex_1.lamp
343 - 1] == play_1.winner) {
344 newsta_(oindex_1.lamp, 0, rindex_1.lroom, 0, 0);
345 }
346
347 /* NOW REDISTRIBUTE HIS VALUABLES AND OTHER BELONGINGS. */
348
349 /* THE LAMP HAS BEEN PLACED IN THE LIVING ROOM. */
350 /* THE FIRST 8 NON-VALUABLES ARE PLACED IN LOCATIONS AROUND THE HOUSE. */
351 /* HIS VALUABLES ARE PLACED AT THE END OF THE MAZE. */
352 /* REMAINING NON-VALUABLES ARE PLACED AT THE END OF THE MAZE. */
353
354 i = 1;
355 i__1 = objcts_1.olnt;
356 for (j = 1; j <= i__1; ++j) {
357 /* !LOOP THRU OBJECTS. */
358 if (objcts_1.oadv[j - 1] != play_1.winner || objcts_1.otval[j - 1] !=
359 0) {
360 goto L200;
361 }
362 ++i;
363 if (i > 9) {
364 goto L400;
365 }
366 /* !MOVE TO RANDOM LOCATIONS. */
367 newsta_(j, 0, rlist[i - 1], 0, 0);
368 L200:
369 ;
370 }
371
372 L400:
373 i = rooms_1.rlnt + 1;
374 /* !NOW MOVE VALUABLES. */
375 nonofl = RAIR + RWATER + RSACRD + REND;
376 /* !DONT MOVE HERE. */
377 i__1 = objcts_1.olnt;
378 for (j = 1; j <= i__1; ++j) {
379 if (objcts_1.oadv[j - 1] != play_1.winner || objcts_1.otval[j - 1] ==
380 0) {
381 goto L300;
382 }
383 L250:
384 --i;
385 /* !FIND NEXT ROOM. */
386 if ((rooms_1.rflag[i - 1] & nonofl) != 0) {
387 goto L250;
388 }
389 newsta_(j, 0, i, 0, 0);
390 /* !YES, MOVE. */
391 L300:
392 ;
393 }
394
395 i__1 = objcts_1.olnt;
396 for (j = 1; j <= i__1; ++j) {
397 /* !NOW GET RID OF REMAINDER. */
398 if (objcts_1.oadv[j - 1] != play_1.winner) {
399 goto L500;
400 }
401 L450:
402 --i;
403 /* !FIND NEXT ROOM. */
404 if ((rooms_1.rflag[i - 1] & nonofl) != 0) {
405 goto L450;
406 }
407 newsta_(j, 0, i, 0, 0);
408 L500:
409 ;
410 }
411 return;
412
413 /* CAN'T OR WON'T CONTINUE, CLEAN UP AND EXIT. */
414
415 L900:
416 rspeak_(625);
417 /* !IN ENDGAME, LOSE. */
418 goto L1100;
419
420 L1000:
421 rspeak_(7);
422 /* !INVOLUNTARY EXIT. */
423 L1100:
424 score_(0);
425 /* !TELL SCORE. */
426 (void) fclose(dbfile);
427 exit_();
428
429 } /* jigsup_ */
430
431 /* OACTOR- GET ACTOR ASSOCIATED WITH OBJECT */
432
433 /* DECLARATIONS */
434
oactor_(obj)435 integer oactor_(obj)
436 integer obj;
437 {
438 /* System generated locals */
439 integer ret_val = 1, i__1;
440
441 /* Local variables */
442 integer i;
443
444 i__1 = advs_1.alnt;
445 for (i = 1; i <= i__1; ++i) {
446 /* !LOOP THRU ACTORS. */
447 ret_val = i;
448 /* !ASSUME FOUND. */
449 if (advs_1.aobj[i - 1] == obj) {
450 return ret_val;
451 }
452 /* !FOUND IT? */
453 /* L100: */
454 }
455 bug_(40, obj);
456 /* !NO, DIE. */
457 return ret_val;
458 } /* oactor_ */
459
460 /* PROB- COMPUTE PROBABILITY */
461
462 /* DECLARATIONS */
463
prob_(g,b)464 logical prob_(g, b)
465 integer g;
466 integer b;
467 {
468 /* System generated locals */
469 logical ret_val;
470
471 /* Local variables */
472 integer i;
473
474 i = g;
475 /* !ASSUME GOOD LUCK. */
476 if (findex_1.badlkf) {
477 i = b;
478 }
479 /* !IF BAD, TOO BAD. */
480 ret_val = rnd_(100) < i;
481 /* !COMPUTE. */
482 return ret_val;
483 } /* prob_ */
484
485 /* RMDESC-- PRINT ROOM DESCRIPTION */
486
487 /* RMDESC PRINTS A DESCRIPTION OF THE CURRENT ROOM. */
488 /* IT IS ALSO THE PROCESSOR FOR VERBS 'LOOK' AND 'EXAMINE'. */
489
rmdesc_(full)490 logical rmdesc_(full)
491 integer full;
492 {
493 /* System generated locals */
494 logical ret_val, L__1;
495
496 /* Local variables */
497 integer i, ra;
498
499 /* FULL= 0/1/2/3= SHORT/OBJ/ROOM/FULL */
500
501 ret_val = TRUE_;
502 /* !ASSUME WINS. */
503 if (prsvec_1.prso < xsrch_1.xmin) {
504 goto L50;
505 }
506 /* !IF DIRECTION, */
507 screen_1.fromdr = prsvec_1.prso;
508 /* !SAVE AND */
509 prsvec_1.prso = 0;
510 /* !CLEAR. */
511 L50:
512 if (play_1.here == advs_1.aroom[aindex_1.player - 1]) {
513 goto L100;
514 }
515 /* !PLAYER JUST MOVE? */
516 rspeak_(2);
517 /* !NO, JUST SAY DONE. */
518 prsvec_1.prsa = vindex_1.walkiw;
519 /* !SET UP WALK IN ACTION. */
520 return ret_val;
521
522 L100:
523 if (lit_(play_1.here)) {
524 goto L300;
525 }
526 /* !LIT? */
527 rspeak_(430);
528 /* !WARN OF GRUE. */
529 ret_val = FALSE_;
530 return ret_val;
531
532 L300:
533 ra = rooms_1.ractio[play_1.here - 1];
534 /* !GET ROOM ACTION. */
535 if (full == 1) {
536 goto L600;
537 }
538 /* !OBJ ONLY? */
539 i = rooms_1.rdesc2[play_1.here - 1];
540 /* !ASSUME SHORT DESC. */
541 if (full == 0 && (findex_1.superf || (rooms_1.rflag[play_1.here - 1] &
542 RSEEN) != 0 && findex_1.brieff)) {
543 goto L400;
544 }
545
546 /* The next line means that when you request VERBOSE mode, you */
547 /* only get long room descriptions 20% of the time. I don't either */
548 /* like or understand this, so the mod. ensures VERBOSE works */
549 /* all the time. jmh@ukc.ac.uk 22/10/87 */
550
551 /* & .AND.(BRIEFF.OR.PROB(80,80))))) GO TO 400 */
552 i = rooms_1.rdesc1[play_1.here - 1];
553 /* !USE LONG. */
554 if (i != 0 || ra == 0) {
555 goto L400;
556 }
557 /* !IF GOT DESC, SKIP. */
558 prsvec_1.prsa = vindex_1.lookw;
559 /* !PRETEND LOOK AROUND. */
560 if (! rappli_(ra)) {
561 goto L100;
562 }
563 /* !ROOM HANDLES, NEW DESC? */
564 prsvec_1.prsa = vindex_1.foow;
565 /* !NOP PARSER. */
566 goto L500;
567
568 L400:
569 rspeak_(i);
570 /* !OUTPUT DESCRIPTION. */
571 L500:
572 if (advs_1.avehic[play_1.winner - 1] != 0) {
573 rspsub_(431, objcts_1.odesc2[advs_1.avehic[play_1.winner - 1] -
574 1]);
575 }
576
577 L600:
578 if (full != 2) {
579 L__1 = full != 0;
580 princr_(L__1, play_1.here);
581 }
582 rooms_1.rflag[play_1.here - 1] |= RSEEN;
583 if (full != 0 || ra == 0) {
584 return ret_val;
585 }
586 /* !ANYTHING MORE? */
587 prsvec_1.prsa = vindex_1.walkiw;
588 /* !GIVE HIM A SURPISE. */
589 if (! rappli_(ra)) {
590 goto L100;
591 }
592 /* !ROOM HANDLES, NEW DESC? */
593 prsvec_1.prsa = vindex_1.foow;
594 return ret_val;
595
596 } /* rmdesc_ */
597
598 /* RAPPLI- ROUTING ROUTINE FOR ROOM APPLICABLES */
599
600 /* DECLARATIONS */
601
rappli_(ri)602 logical rappli_(ri)
603 integer ri;
604 {
605 /* Initialized data */
606
607 const integer newrms = 38;
608
609 /* System generated locals */
610 logical ret_val;
611
612
613 ret_val = TRUE_;
614 /* !ASSUME WINS. */
615 if (ri == 0) {
616 return ret_val;
617 }
618 /* !IF ZERO, WIN. */
619 if (ri < newrms) {
620 ret_val = rappl1_(ri);
621 }
622 /* !IF OLD, PROCESSOR 1. */
623 if (ri >= newrms) {
624 ret_val = rappl2_(ri);
625 }
626 /* !IF NEW, PROCESSOR 2. */
627 return ret_val;
628 } /* rappli_ */
629