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