zork/dsub.c

633 lines
12 KiB
C

/* RESIDENT SUBROUTINES FOR DUNGEON */
/*COPYRIGHT 1980, INFOCOM COMPUTERS AND COMMUNICATIONS, CAMBRIDGE MA. 02142*/
/* ALL RIGHTS RESERVED, COMMERCIAL USAGE STRICTLY PROHIBITED */
/* WRITTEN BY R. M. SUPNIK */
#include <stdio.h>
#include "funcs.h"
#include "vars.h"
#ifndef SEEK_SET
#define SEEK_SET (0)
#endif
extern FILE *dbfile;
static void rspsb2nl_ P((integer, integer, integer, logical));
/* RSPEAK-- OUTPUT RANDOM MESSAGE ROUTINE */
/* CALLED BY-- */
/* CALL RSPEAK(MSGNUM) */
void rspeak_(n)
integer n;
{
rspsb2nl_(n, 0, 0, 1);
} /* rspeak_ */
/* RSPSUB-- OUTPUT RANDOM MESSAGE WITH SUBSTITUTABLE ARGUMENT */
/* CALLED BY-- */
/* CALL RSPSUB(MSGNUM,SUBNUM) */
void rspsub_(n, s1)
integer n;
integer s1;
{
rspsb2nl_(n, s1, 0, 1);
} /* rspsub_ */
/* RSPSB2-- OUTPUT RANDOM MESSAGE WITH UP TO TWO SUBSTITUTABLE ARGUMENTS */
/* CALLED BY-- */
/* CALL RSPSB2(MSGNUM,SUBNUM1,SUBNUM2) */
void rspsb2_(n, s1, s2)
integer n;
integer s1;
integer s2;
{
rspsb2nl_(n, s1, s2, 1);
} /* rspsb2_ */
/* rspsb2nl_ Display a substitutable message with an optional newline */
static void rspsb2nl_(n, y, z, nl)
integer n;
integer y;
integer z;
logical nl;
{
const char *zkey = "IanLanceTaylorJr";
long x;
x = (long)n;
if (x > 0) {
x = rmsg_1.rtext[x - 1];
}
/* !IF >0, LOOK UP IN RTEXT. */
if (x == 0) {
return;
}
/* !ANYTHING TO DO? */
play_1.telflg = TRUE_;
/* !SAID SOMETHING. */
x = ((- x) - 1) * 8;
if (fseek(dbfile, x + (long)rmsg_1.mrloc, SEEK_SET) == EOF) {
fprintf(stderr, "Error seeking database loc %d\n", x);
exit_();
}
if (nl)
more_output(NULL);
while (1) {
integer i;
i = getc(dbfile);
if (i == EOF) {
fprintf(stderr, "Error reading database loc %d\n", x);
exit_();
}
i ^= zkey[x & 0xf] ^ (x & 0xff);
x = x + 1;
if (i == '\0')
break;
else if (i == '\n') {
putchar('\n');
if (nl)
more_output(NULL);
}
else if (i == '#' && y != 0) {
long iloc;
iloc = ftell(dbfile);
rspsb2nl_(y, 0, 0, 0);
if (fseek(dbfile, iloc, SEEK_SET) == EOF) {
fprintf(stderr, "Error seeking database loc %d\n", iloc);
exit_();
}
y = z;
z = 0;
}
else
putchar(i);
}
if (nl)
putchar('\n');
}
/* OBJACT-- APPLY OBJECTS FROM PARSE VECTOR */
/* DECLARATIONS */
logical objact_()
{
/* System generated locals */
logical ret_val;
ret_val = TRUE_;
/* !ASSUME WINS. */
if (prsvec_1.prsi == 0) {
goto L100;
}
/* !IND OBJECT? */
if (oappli_(objcts_1.oactio[prsvec_1.prsi - 1], 0)) {
return ret_val;
}
/* !YES, LET IT HANDLE. */
L100:
if (prsvec_1.prso == 0) {
goto L200;
}
/* !DIR OBJECT? */
if (oappli_(objcts_1.oactio[prsvec_1.prso - 1], 0)) {
return ret_val;
}
/* !YES, LET IT HANDLE. */
L200:
ret_val = FALSE_;
/* !LOSES. */
return ret_val;
} /* objact_ */
/* BUG-- REPORT FATAL SYSTEM ERROR */
/* CALLED BY-- */
/* CALL BUG(NO,PAR) */
void bug_(a, b)
integer a;
integer b;
{
/* Local variables */
more_output(NULL);
printf("PROGRAM ERROR %d, PARAMETER=%d\n", a, b);
if (debug_1.dbgflg != 0) {
return;
}
exit_();
} /* bug_ */
/* NEWSTA-- SET NEW STATUS FOR OBJECT */
/* CALLED BY-- */
/* CALL NEWSTA(OBJECT,STRING,NEWROOM,NEWCON,NEWADV) */
void newsta_(o, r, rm, cn, ad)
integer o;
integer r;
integer rm;
integer cn;
integer ad;
{
rspeak_(r);
objcts_1.oroom[o - 1] = rm;
objcts_1.ocan[o - 1] = cn;
objcts_1.oadv[o - 1] = ad;
} /* newsta_ */
/* QHERE-- TEST FOR OBJECT IN ROOM */
/* DECLARATIONS */
logical qhere_(obj, rm)
integer obj;
integer rm;
{
/* System generated locals */
integer i__1;
logical ret_val;
/* Local variables */
integer i;
ret_val = TRUE_;
if (objcts_1.oroom[obj - 1] == rm) {
return ret_val;
}
/* !IN ROOM? */
i__1 = oroom2_1.r2lnt;
for (i = 1; i <= i__1; ++i) {
/* !NO, SCH ROOM2. */
if (oroom2_1.oroom2[i - 1] == obj && oroom2_1.rroom2[i - 1] == rm) {
return ret_val;
}
/* L100: */
}
ret_val = FALSE_;
/* !NOT PRESENT. */
return ret_val;
} /* qhere_ */
/* QEMPTY-- TEST FOR OBJECT EMPTY */
/* DECLARATIONS */
logical qempty_(obj)
integer obj;
{
/* System generated locals */
integer i__1;
logical ret_val;
/* Local variables */
integer i;
ret_val = FALSE_;
/* !ASSUME LOSE. */
i__1 = objcts_1.olnt;
for (i = 1; i <= i__1; ++i) {
if (objcts_1.ocan[i - 1] == obj) {
return ret_val;
}
/* !INSIDE TARGET? */
/* L100: */
}
ret_val = TRUE_;
return ret_val;
} /* qempty_ */
/* JIGSUP- YOU ARE DEAD */
/* DECLARATIONS */
void jigsup_(desc)
integer desc;
{
/* Initialized data */
static const integer rlist[9] = { 8,6,36,35,34,4,34,6,5 };
/* System generated locals */
integer i__1;
/* Local variables */
integer nonofl;
logical f;
integer i, j;
rspeak_(desc);
/* !DESCRIBE SAD STATE. */
prsvec_1.prscon = 1;
/* !STOP PARSER. */
if (debug_1.dbgflg != 0) {
return;
}
/* !IF DBG, EXIT. */
advs_1.avehic[play_1.winner - 1] = 0;
/* !GET RID OF VEHICLE. */
if (play_1.winner == aindex_1.player) {
goto L100;
}
/* !HIMSELF? */
rspsub_(432, objcts_1.odesc2[advs_1.aobj[play_1.winner - 1] - 1]);
/* !NO, SAY WHO DIED. */
newsta_(advs_1.aobj[play_1.winner - 1], 0, 0, 0, 0);
/* !SEND TO HYPER SPACE. */
return;
L100:
if (findex_1.endgmf) {
goto L900;
}
/* !NO RECOVERY IN END GAME. */
// always exit for plopbot's purposes
goto L1000;
// if (state_1.deaths >= 2) {
// goto L1000;
// }
/* !DEAD TWICE? KICK HIM OFF. */
if (! yesno_(10, 9, 8)) {
goto L1100;
}
/* !CONTINUE? */
i__1 = objcts_1.olnt;
for (j = 1; j <= i__1; ++j) {
/* !TURN OFF FIGHTING. */
if (qhere_(j, play_1.here)) {
objcts_1.oflag2[j - 1] &= ~ FITEBT;
}
/* L50: */
}
++state_1.deaths;
scrupd_(- 10);
/* !CHARGE TEN POINTS. */
f = moveto_(rindex_1.fore1, play_1.winner);
/* !REPOSITION HIM. */
findex_1.egyptf = TRUE_;
/* !RESTORE COFFIN. */
if (objcts_1.oadv[oindex_1.coffi - 1] == play_1.winner) {
newsta_(oindex_1.coffi, 0, rindex_1.egypt, 0, 0);
}
objcts_1.oflag2[oindex_1.door - 1] &= ~ TCHBT;
objcts_1.oflag1[oindex_1.robot - 1] = (objcts_1.oflag1[oindex_1.robot - 1]
| VISIBT) & ~ NDSCBT;
if (objcts_1.oroom[oindex_1.lamp - 1] != 0 || objcts_1.oadv[oindex_1.lamp
- 1] == play_1.winner) {
newsta_(oindex_1.lamp, 0, rindex_1.lroom, 0, 0);
}
/* NOW REDISTRIBUTE HIS VALUABLES AND OTHER BELONGINGS. */
/* THE LAMP HAS BEEN PLACED IN THE LIVING ROOM. */
/* THE FIRST 8 NON-VALUABLES ARE PLACED IN LOCATIONS AROUND THE HOUSE. */
/* HIS VALUABLES ARE PLACED AT THE END OF THE MAZE. */
/* REMAINING NON-VALUABLES ARE PLACED AT THE END OF THE MAZE. */
i = 1;
i__1 = objcts_1.olnt;
for (j = 1; j <= i__1; ++j) {
/* !LOOP THRU OBJECTS. */
if (objcts_1.oadv[j - 1] != play_1.winner || objcts_1.otval[j - 1] !=
0) {
goto L200;
}
++i;
if (i > 9) {
goto L400;
}
/* !MOVE TO RANDOM LOCATIONS. */
newsta_(j, 0, rlist[i - 1], 0, 0);
L200:
;
}
L400:
i = rooms_1.rlnt + 1;
/* !NOW MOVE VALUABLES. */
nonofl = RAIR + RWATER + RSACRD + REND;
/* !DONT MOVE HERE. */
i__1 = objcts_1.olnt;
for (j = 1; j <= i__1; ++j) {
if (objcts_1.oadv[j - 1] != play_1.winner || objcts_1.otval[j - 1] ==
0) {
goto L300;
}
L250:
--i;
/* !FIND NEXT ROOM. */
if ((rooms_1.rflag[i - 1] & nonofl) != 0) {
goto L250;
}
newsta_(j, 0, i, 0, 0);
/* !YES, MOVE. */
L300:
;
}
i__1 = objcts_1.olnt;
for (j = 1; j <= i__1; ++j) {
/* !NOW GET RID OF REMAINDER. */
if (objcts_1.oadv[j - 1] != play_1.winner) {
goto L500;
}
L450:
--i;
/* !FIND NEXT ROOM. */
if ((rooms_1.rflag[i - 1] & nonofl) != 0) {
goto L450;
}
newsta_(j, 0, i, 0, 0);
L500:
;
}
return;
/* CAN'T OR WON'T CONTINUE, CLEAN UP AND EXIT. */
L900:
rspeak_(625);
/* !IN ENDGAME, LOSE. */
goto L1100;
L1000:
rspeak_(7);
/* !INVOLUNTARY EXIT. */
L1100:
score_(0);
/* !TELL SCORE. */
(void) fclose(dbfile);
exit_();
} /* jigsup_ */
/* OACTOR- GET ACTOR ASSOCIATED WITH OBJECT */
/* DECLARATIONS */
integer oactor_(obj)
integer obj;
{
/* System generated locals */
integer ret_val = 1, i__1;
/* Local variables */
integer i;
i__1 = advs_1.alnt;
for (i = 1; i <= i__1; ++i) {
/* !LOOP THRU ACTORS. */
ret_val = i;
/* !ASSUME FOUND. */
if (advs_1.aobj[i - 1] == obj) {
return ret_val;
}
/* !FOUND IT? */
/* L100: */
}
bug_(40, obj);
/* !NO, DIE. */
return ret_val;
} /* oactor_ */
/* PROB- COMPUTE PROBABILITY */
/* DECLARATIONS */
logical prob_(g, b)
integer g;
integer b;
{
/* System generated locals */
logical ret_val;
/* Local variables */
integer i;
i = g;
/* !ASSUME GOOD LUCK. */
if (findex_1.badlkf) {
i = b;
}
/* !IF BAD, TOO BAD. */
ret_val = rnd_(100) < i;
/* !COMPUTE. */
return ret_val;
} /* prob_ */
/* RMDESC-- PRINT ROOM DESCRIPTION */
/* RMDESC PRINTS A DESCRIPTION OF THE CURRENT ROOM. */
/* IT IS ALSO THE PROCESSOR FOR VERBS 'LOOK' AND 'EXAMINE'. */
logical rmdesc_(full)
integer full;
{
/* System generated locals */
logical ret_val, L__1;
/* Local variables */
integer i, ra;
/* FULL= 0/1/2/3= SHORT/OBJ/ROOM/FULL */
ret_val = TRUE_;
/* !ASSUME WINS. */
if (prsvec_1.prso < xsrch_1.xmin) {
goto L50;
}
/* !IF DIRECTION, */
screen_1.fromdr = prsvec_1.prso;
/* !SAVE AND */
prsvec_1.prso = 0;
/* !CLEAR. */
L50:
if (play_1.here == advs_1.aroom[aindex_1.player - 1]) {
goto L100;
}
/* !PLAYER JUST MOVE? */
rspeak_(2);
/* !NO, JUST SAY DONE. */
prsvec_1.prsa = vindex_1.walkiw;
/* !SET UP WALK IN ACTION. */
return ret_val;
L100:
if (lit_(play_1.here)) {
goto L300;
}
/* !LIT? */
rspeak_(430);
/* !WARN OF GRUE. */
ret_val = FALSE_;
return ret_val;
L300:
ra = rooms_1.ractio[play_1.here - 1];
/* !GET ROOM ACTION. */
if (full == 1) {
goto L600;
}
/* !OBJ ONLY? */
i = rooms_1.rdesc2[play_1.here - 1];
/* !ASSUME SHORT DESC. */
if (full == 0 && (findex_1.superf || (rooms_1.rflag[play_1.here - 1] &
RSEEN) != 0 && findex_1.brieff)) {
goto L400;
}
/* The next line means that when you request VERBOSE mode, you */
/* only get long room descriptions 20% of the time. I don't either */
/* like or understand this, so the mod. ensures VERBOSE works */
/* all the time. jmh@ukc.ac.uk 22/10/87 */
/* & .AND.(BRIEFF.OR.PROB(80,80))))) GO TO 400 */
i = rooms_1.rdesc1[play_1.here - 1];
/* !USE LONG. */
if (i != 0 || ra == 0) {
goto L400;
}
/* !IF GOT DESC, SKIP. */
prsvec_1.prsa = vindex_1.lookw;
/* !PRETEND LOOK AROUND. */
if (! rappli_(ra)) {
goto L100;
}
/* !ROOM HANDLES, NEW DESC? */
prsvec_1.prsa = vindex_1.foow;
/* !NOP PARSER. */
goto L500;
L400:
rspeak_(i);
/* !OUTPUT DESCRIPTION. */
L500:
if (advs_1.avehic[play_1.winner - 1] != 0) {
rspsub_(431, objcts_1.odesc2[advs_1.avehic[play_1.winner - 1] -
1]);
}
L600:
if (full != 2) {
L__1 = full != 0;
princr_(L__1, play_1.here);
}
rooms_1.rflag[play_1.here - 1] |= RSEEN;
if (full != 0 || ra == 0) {
return ret_val;
}
/* !ANYTHING MORE? */
prsvec_1.prsa = vindex_1.walkiw;
/* !GIVE HIM A SURPISE. */
if (! rappli_(ra)) {
goto L100;
}
/* !ROOM HANDLES, NEW DESC? */
prsvec_1.prsa = vindex_1.foow;
return ret_val;
} /* rmdesc_ */
/* RAPPLI- ROUTING ROUTINE FOR ROOM APPLICABLES */
/* DECLARATIONS */
logical rappli_(ri)
integer ri;
{
/* Initialized data */
const integer newrms = 38;
/* System generated locals */
logical ret_val;
ret_val = TRUE_;
/* !ASSUME WINS. */
if (ri == 0) {
return ret_val;
}
/* !IF ZERO, WIN. */
if (ri < newrms) {
ret_val = rappl1_(ri);
}
/* !IF OLD, PROCESSOR 1. */
if (ri >= newrms) {
ret_val = rappl2_(ri);
}
/* !IF NEW, PROCESSOR 2. */
return ret_val;
} /* rappli_ */