zork/dverb2.c

689 lines
17 KiB
C

/* SAVE- SAVE GAME STATE */
/*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"
/* DECLARATIONS */
static integer cxappl_ P((integer));
void savegm_()
{
/* Local variables */
integer i;
FILE *e;
prsvec_1.prswon = FALSE_;
/* !DISABLE GAME. */
/* Note: save file format is different for PDP vs. non-PDP versions */
if ((e = fopen("dsave.dat", BINWRITE)) == NULL)
goto L100;
gttime_(&i);
/* !GET TIME. */
#define do_uio(i, zbuf, cbytes) \
(void) fwrite((const char *)(zbuf), (cbytes), (i), e)
do_uio(1, &vers_1.vmaj, sizeof(integer));
do_uio(1, &vers_1.vmin, sizeof(integer));
do_uio(1, &vers_1.vedit, sizeof(integer));
do_uio(1, &play_1.winner, sizeof(integer));
do_uio(1, &play_1.here, sizeof(integer));
do_uio(1, &hack_1.thfpos, sizeof(integer));
do_uio(1, &play_1.telflg, sizeof(logical));
do_uio(1, &hack_1.thfflg, sizeof(logical));
do_uio(1, &hack_1.thfact, sizeof(logical));
do_uio(1, &hack_1.swdact, sizeof(logical));
do_uio(1, &hack_1.swdsta, sizeof(integer));
do_uio(64, &puzzle_1.cpvec[0], sizeof(integer));
do_uio(1, &i, sizeof(integer));
do_uio(1, &state_1.moves, sizeof(integer));
do_uio(1, &state_1.deaths, sizeof(integer));
do_uio(1, &state_1.rwscor, sizeof(integer));
do_uio(1, &state_1.egscor, sizeof(integer));
do_uio(1, &state_1.mxload, sizeof(integer));
do_uio(1, &state_1.ltshft, sizeof(integer));
do_uio(1, &state_1.bloc, sizeof(integer));
do_uio(1, &state_1.mungrm, sizeof(integer));
do_uio(1, &state_1.hs, sizeof(integer));
do_uio(1, &screen_1.fromdr, sizeof(integer));
do_uio(1, &screen_1.scolrm, sizeof(integer));
do_uio(1, &screen_1.scolac, sizeof(integer));
do_uio(220, &objcts_1.odesc1[0], sizeof(integer));
do_uio(220, &objcts_1.odesc2[0], sizeof(integer));
do_uio(220, &objcts_1.oflag1[0], sizeof(integer));
do_uio(220, &objcts_1.oflag2[0], sizeof(integer));
do_uio(220, &objcts_1.ofval[0], sizeof(integer));
do_uio(220, &objcts_1.otval[0], sizeof(integer));
do_uio(220, &objcts_1.osize[0], sizeof(integer));
do_uio(220, &objcts_1.ocapac[0], sizeof(integer));
do_uio(220, &objcts_1.oroom[0], sizeof(integer));
do_uio(220, &objcts_1.oadv[0], sizeof(integer));
do_uio(220, &objcts_1.ocan[0], sizeof(integer));
do_uio(200, &rooms_1.rval[0], sizeof(integer));
do_uio(200, &rooms_1.rflag[0], sizeof(integer));
do_uio(4, &advs_1.aroom[0], sizeof(integer));
do_uio(4, &advs_1.ascore[0], sizeof(integer));
do_uio(4, &advs_1.avehic[0], sizeof(integer));
do_uio(4, &advs_1.astren[0], sizeof(integer));
do_uio(4, &advs_1.aflag[0], sizeof(integer));
do_uio(46, &flags[0], sizeof(logical));
do_uio(22, &switch_[0], sizeof(integer));
do_uio(4, &vill_1.vprob[0], sizeof(integer));
do_uio(25, &cevent_1.cflag[0], sizeof(logical));
do_uio(25, &cevent_1.ctick[0], sizeof(integer));
#undef do_uio
if (fclose(e) == EOF)
goto L100;
rspeak_(597);
return;
L100:
rspeak_(598);
/* !CANT DO IT. */
} /* savegm_ */
/* RESTORE- RESTORE GAME STATE */
/* DECLARATIONS */
void rstrgm_()
{
/* Local variables */
integer i, j, k;
FILE *e;
prsvec_1.prswon = FALSE_;
/* !DISABLE GAME. */
/* Note: save file format is different for PDP vs. non-PDP versions */
if ((e = fopen("dsave.dat", BINREAD)) == NULL)
goto L100;
#define do_uio(i, zbuf, cbytes) \
(void)fread((char *)(zbuf), (cbytes), (i), e)
do_uio(1, &i, sizeof(integer));
do_uio(1, &j, sizeof(integer));
do_uio(1, &k, sizeof(integer));
if (i != vers_1.vmaj | j != vers_1.vmin) {
goto L200;
}
do_uio(1, &play_1.winner, sizeof(integer));
do_uio(1, &play_1.here, sizeof(integer));
do_uio(1, &hack_1.thfpos, sizeof(integer));
do_uio(1, &play_1.telflg, sizeof(logical));
do_uio(1, &hack_1.thfflg, sizeof(logical));
do_uio(1, &hack_1.thfact, sizeof(logical));
do_uio(1, &hack_1.swdact, sizeof(logical));
do_uio(1, &hack_1.swdsta, sizeof(integer));
do_uio(64, &puzzle_1.cpvec[0], sizeof(integer));
do_uio(1, &time_1.pltime, sizeof(integer));
do_uio(1, &state_1.moves, sizeof(integer));
do_uio(1, &state_1.deaths, sizeof(integer));
do_uio(1, &state_1.rwscor, sizeof(integer));
do_uio(1, &state_1.egscor, sizeof(integer));
do_uio(1, &state_1.mxload, sizeof(integer));
do_uio(1, &state_1.ltshft, sizeof(integer));
do_uio(1, &state_1.bloc, sizeof(integer));
do_uio(1, &state_1.mungrm, sizeof(integer));
do_uio(1, &state_1.hs, sizeof(integer));
do_uio(1, &screen_1.fromdr, sizeof(integer));
do_uio(1, &screen_1.scolrm, sizeof(integer));
do_uio(1, &screen_1.scolac, sizeof(integer));
do_uio(220, &objcts_1.odesc1[0], sizeof(integer));
do_uio(220, &objcts_1.odesc2[0], sizeof(integer));
do_uio(220, &objcts_1.oflag1[0], sizeof(integer));
do_uio(220, &objcts_1.oflag2[0], sizeof(integer));
do_uio(220, &objcts_1.ofval[0], sizeof(integer));
do_uio(220, &objcts_1.otval[0], sizeof(integer));
do_uio(220, &objcts_1.osize[0], sizeof(integer));
do_uio(220, &objcts_1.ocapac[0], sizeof(integer));
do_uio(220, &objcts_1.oroom[0], sizeof(integer));
do_uio(220, &objcts_1.oadv[0], sizeof(integer));
do_uio(220, &objcts_1.ocan[0], sizeof(integer));
do_uio(200, &rooms_1.rval[0], sizeof(integer));
do_uio(200, &rooms_1.rflag[0], sizeof(integer));
do_uio(4, &advs_1.aroom[0], sizeof(integer));
do_uio(4, &advs_1.ascore[0], sizeof(integer));
do_uio(4, &advs_1.avehic[0], sizeof(integer));
do_uio(4, &advs_1.astren[0], sizeof(integer));
do_uio(4, &advs_1.aflag[0], sizeof(integer));
do_uio(46, &flags[0], sizeof(logical));
do_uio(22, &switch_[0], sizeof(integer));
do_uio(4, &vill_1.vprob[0], sizeof(integer));
do_uio(25, &cevent_1.cflag[0], sizeof(logical));
do_uio(25, &cevent_1.ctick[0], sizeof(integer));
(void)fclose(e);
rspeak_(599);
return;
L100:
rspeak_(598);
/* !CANT DO IT. */
return;
L200:
rspeak_(600);
/* !OBSOLETE VERSION */
(void)fclose(e);
} /* rstrgm_ */
/* WALK- MOVE IN SPECIFIED DIRECTION */
/* DECLARATIONS */
logical walk_()
{
/* System generated locals */
logical ret_val;
ret_val = TRUE_;
/* !ASSUME WINS. */
if (play_1.winner != aindex_1.player || lit_(play_1.here) || prob_(25,
25)) {
goto L500;
}
if (! findxt_(prsvec_1.prso, play_1.here)) {
goto L450;
}
/* !INVALID EXIT? GRUE */
/* ! */
switch (curxt_1.xtype) {
case 1: goto L400;
case 2: goto L200;
case 3: goto L100;
case 4: goto L300;
}
/* !DECODE EXIT TYPE. */
bug_(9, curxt_1.xtype);
L100:
if (cxappl_(curxt_1.xactio) != 0) {
goto L400;
}
/* !CEXIT... RETURNED ROOM? */
if (flags[*xflag - 1]) {
goto L400;
}
/* !NO, FLAG ON? */
L200:
jigsup_(523);
/* !BAD EXIT, GRUE */
/* ! */
return ret_val;
L300:
if (cxappl_(curxt_1.xactio) != 0) {
goto L400;
}
/* !DOOR... RETURNED ROOM? */
if ((objcts_1.oflag2[curxt_1.xobj - 1] & OPENBT) != 0) {
goto L400;
}
/* !NO, DOOR OPEN? */
jigsup_(523);
/* !BAD EXIT, GRUE */
/* ! */
return ret_val;
L400:
if (lit_(curxt_1.xroom1)) {
goto L900;
}
/* !VALID ROOM, IS IT LIT? */
L450:
jigsup_(522);
/* !NO, GRUE */
/* ! */
return ret_val;
/* ROOM IS LIT, OR WINNER IS NOT PLAYER (NO GRUE). */
L500:
if (findxt_(prsvec_1.prso, play_1.here)) {
goto L550;
}
/* !EXIT EXIST? */
L525:
curxt_1.xstrng = 678;
/* !ASSUME WALL. */
if (prsvec_1.prso == xsrch_1.xup) {
curxt_1.xstrng = 679;
}
/* !IF UP, CANT. */
if (prsvec_1.prso == xsrch_1.xdown) {
curxt_1.xstrng = 680;
}
/* !IF DOWN, CANT. */
if ((rooms_1.rflag[play_1.here - 1] & RNWALL) != 0) {
curxt_1.xstrng = 524;
}
rspeak_(curxt_1.xstrng);
prsvec_1.prscon = 1;
/* !STOP CMD STREAM. */
return ret_val;
L550:
switch (curxt_1.xtype) {
case 1: goto L900;
case 2: goto L600;
case 3: goto L700;
case 4: goto L800;
}
/* !BRANCH ON EXIT TYPE. */
bug_(9, curxt_1.xtype);
L700:
if (cxappl_(curxt_1.xactio) != 0) {
goto L900;
}
/* !CEXIT... RETURNED ROOM? */
if (flags[*xflag - 1]) {
goto L900;
}
/* !NO, FLAG ON? */
L600:
if (curxt_1.xstrng == 0) {
goto L525;
}
/* !IF NO REASON, USE STD. */
rspeak_(curxt_1.xstrng);
/* !DENY EXIT. */
prsvec_1.prscon = 1;
/* !STOP CMD STREAM. */
return ret_val;
L800:
if (cxappl_(curxt_1.xactio) != 0) {
goto L900;
}
/* !DOOR... RETURNED ROOM? */
if ((objcts_1.oflag2[curxt_1.xobj - 1] & OPENBT) != 0) {
goto L900;
}
/* !NO, DOOR OPEN? */
if (curxt_1.xstrng == 0) {
curxt_1.xstrng = 525;
}
/* !IF NO REASON, USE STD. */
rspsub_(curxt_1.xstrng, objcts_1.odesc2[curxt_1.xobj - 1]);
prsvec_1.prscon = 1;
/* !STOP CMD STREAM. */
return ret_val;
L900:
ret_val = moveto_(curxt_1.xroom1, play_1.winner);
/* !MOVE TO ROOM. */
if (ret_val) {
ret_val = rmdesc_(0);
}
/* !DESCRIBE ROOM. */
return ret_val;
} /* walk_ */
/* CXAPPL- CONDITIONAL EXIT PROCESSORS */
/* DECLARATIONS */
static integer cxappl_(ri)
integer ri;
{
/* System generated locals */
integer ret_val, i__1;
/* Local variables */
integer i, j, k;
integer nxt;
integer ldir;
ret_val = 0;
/* !NO RETURN. */
if (ri == 0) {
return ret_val;
}
/* !IF NO ACTION, DONE. */
switch (ri) {
case 1: goto L1000;
case 2: goto L2000;
case 3: goto L3000;
case 4: goto L4000;
case 5: goto L5000;
case 6: goto L6000;
case 7: goto L7000;
case 8: goto L8000;
case 9: goto L9000;
case 10: goto L10000;
case 11: goto L11000;
case 12: goto L12000;
case 13: goto L13000;
case 14: goto L14000;
}
bug_(5, ri);
/* C1- COFFIN-CURE */
L1000:
findex_1.egyptf = objcts_1.oadv[oindex_1.coffi - 1] != play_1.winner;
/* !T IF NO COFFIN. */
return ret_val;
/* C2- CAROUSEL EXIT */
/* C5- CAROUSEL OUT */
L2000:
if (findex_1.caroff) {
return ret_val;
}
/* !IF FLIPPED, NOTHING. */
L2500:
rspeak_(121);
/* !SPIN THE COMPASS. */
L5000:
i = xpars_1.xelnt[xpars_1.xcond - 1] * rnd_(8);
/* !CHOOSE RANDOM EXIT. */
curxt_1.xroom1 = exits_1.travel[rooms_1.rexit[play_1.here - 1] + i - 1] &
xpars_1.xrmask;
ret_val = curxt_1.xroom1;
/* !RETURN EXIT. */
return ret_val;
/* C3- CHIMNEY FUNCTION */
L3000:
findex_1.litldf = FALSE_;
/* !ASSUME HEAVY LOAD. */
j = 0;
i__1 = objcts_1.olnt;
for (i = 1; i <= i__1; ++i) {
/* !COUNT OBJECTS. */
if (objcts_1.oadv[i - 1] == play_1.winner) {
++j;
}
/* L3100: */
}
if (j > 2) {
return ret_val;
}
/* !CARRYING TOO MUCH? */
curxt_1.xstrng = 446;
/* !ASSUME NO LAMP. */
if (objcts_1.oadv[oindex_1.lamp - 1] != play_1.winner) {
return ret_val;
}
/* !NO LAMP? */
findex_1.litldf = TRUE_;
/* !HE CAN DO IT. */
if ((objcts_1.oflag2[oindex_1.door - 1] & OPENBT) == 0) {
objcts_1.oflag2[oindex_1.door - 1] &= ~ TCHBT;
}
return ret_val;
/* C4- FROBOZZ FLAG (MAGNET ROOM, FAKE EXIT) */
/* C6- FROBOZZ FLAG (MAGNET ROOM, REAL EXIT) */
L4000:
if (findex_1.caroff) {
goto L2500;
}
/* !IF FLIPPED, GO SPIN. */
findex_1.frobzf = FALSE_;
/* !OTHERWISE, NOT AN EXIT. */
return ret_val;
L6000:
if (findex_1.caroff) {
goto L2500;
}
/* !IF FLIPPED, GO SPIN. */
findex_1.frobzf = TRUE_;
/* !OTHERWISE, AN EXIT. */
return ret_val;
/* C7- FROBOZZ FLAG (BANK ALARM) */
L7000:
findex_1.frobzf = objcts_1.oroom[oindex_1.bills - 1] != 0 &
objcts_1.oroom[oindex_1.portr - 1] != 0;
return ret_val;
/* CXAPPL, PAGE 3 */
/* C8- FROBOZZ FLAG (MRGO) */
L8000:
findex_1.frobzf = FALSE_;
/* !ASSUME CANT MOVE. */
if (findex_1.mloc != curxt_1.xroom1) {
goto L8100;
}
/* !MIRROR IN WAY? */
if (prsvec_1.prso == xsrch_1.xnorth || prsvec_1.prso == xsrch_1.xsouth) {
goto L8200;
}
if (findex_1.mdir % 180 != 0) {
goto L8300;
}
/* !MIRROR MUST BE N-S. */
curxt_1.xroom1 = (curxt_1.xroom1 - rindex_1.mra << 1) + rindex_1.mrae;
/* !CALC EAST ROOM. */
if (prsvec_1.prso > xsrch_1.xsouth) {
++curxt_1.xroom1;
}
/* !IF SW/NW, CALC WEST. */
L8100:
ret_val = curxt_1.xroom1;
return ret_val;
L8200:
curxt_1.xstrng = 814;
/* !ASSUME STRUC BLOCKS. */
if (findex_1.mdir % 180 == 0) {
return ret_val;
}
/* !IF MIRROR N-S, DONE. */
L8300:
ldir = findex_1.mdir;
/* !SEE WHICH MIRROR. */
if (prsvec_1.prso == xsrch_1.xsouth) {
ldir = 180;
}
curxt_1.xstrng = 815;
/* !MIRROR BLOCKS. */
if (ldir > 180 && ! findex_1.mr1f || ldir < 180 && ! findex_1.mr2f) {
curxt_1.xstrng = 816;
}
return ret_val;
/* C9- FROBOZZ FLAG (MIRIN) */
L9000:
if (mrhere_(play_1.here) != 1) {
goto L9100;
}
/* !MIRROR 1 HERE? */
if (findex_1.mr1f) {
curxt_1.xstrng = 805;
}
/* !SEE IF BROKEN. */
findex_1.frobzf = findex_1.mropnf;
/* !ENTER IF OPEN. */
return ret_val;
L9100:
findex_1.frobzf = FALSE_;
/* !NOT HERE, */
curxt_1.xstrng = 817;
/* !LOSE. */
return ret_val;
/* CXAPPL, PAGE 4 */
/* C10- FROBOZZ FLAG (MIRROR EXIT) */
L10000:
findex_1.frobzf = FALSE_;
/* !ASSUME CANT. */
ldir = (prsvec_1.prso - xsrch_1.xnorth) / xsrch_1.xnorth * 45;
/* !XLATE DIR TO DEGREES. */
if (! findex_1.mropnf || (findex_1.mdir + 270) % 360 != ldir &&
prsvec_1.prso != xsrch_1.xexit) {
goto L10200;
}
curxt_1.xroom1 = (findex_1.mloc - rindex_1.mra << 1) + rindex_1.mrae + 1
- findex_1.mdir / 180;
/* !ASSUME E-W EXIT. */
if (findex_1.mdir % 180 == 0) {
goto L10100;
}
/* !IF N-S, OK. */
curxt_1.xroom1 = findex_1.mloc + 1;
/* !ASSUME N EXIT. */
if (findex_1.mdir > 180) {
curxt_1.xroom1 = findex_1.mloc - 1;
}
/* !IF SOUTH. */
L10100:
ret_val = curxt_1.xroom1;
return ret_val;
L10200:
if (! findex_1.wdopnf || (findex_1.mdir + 180) % 360 != ldir &&
prsvec_1.prso != xsrch_1.xexit) {
return ret_val;
}
curxt_1.xroom1 = findex_1.mloc + 1;
/* !ASSUME N. */
if (findex_1.mdir == 0) {
curxt_1.xroom1 = findex_1.mloc - 1;
}
/* !IF S. */
rspeak_(818);
/* !CLOSE DOOR. */
findex_1.wdopnf = FALSE_;
ret_val = curxt_1.xroom1;
return ret_val;
/* C11- MAYBE DOOR. NORMAL MESSAGE IS THAT DOOR IS CLOSED. */
/* BUT IF LCELL.NE.4, DOOR ISNT THERE. */
L11000:
if (findex_1.lcell != 4) {
curxt_1.xstrng = 678;
}
/* !SET UP MSG. */
return ret_val;
/* C12- FROBZF (PUZZLE ROOM MAIN ENTRANCE) */
L12000:
findex_1.frobzf = TRUE_;
/* !ALWAYS ENTER. */
findex_1.cphere = 10;
/* !SET SUBSTATE. */
return ret_val;
/* C13- CPOUTF (PUZZLE ROOM SIZE ENTRANCE) */
L13000:
findex_1.cphere = 52;
/* !SET SUBSTATE. */
return ret_val;
/* CXAPPL, PAGE 5 */
/* C14- FROBZF (PUZZLE ROOM TRANSITIONS) */
L14000:
findex_1.frobzf = FALSE_;
/* !ASSSUME LOSE. */
if (prsvec_1.prso != xsrch_1.xup) {
goto L14100;
}
/* !UP? */
if (findex_1.cphere != 10) {
return ret_val;
}
/* !AT EXIT? */
curxt_1.xstrng = 881;
/* !ASSUME NO LADDER. */
if (puzzle_1.cpvec[findex_1.cphere] != -2) {
return ret_val;
}
/* !LADDER HERE? */
rspeak_(882);
/* !YOU WIN. */
findex_1.frobzf = TRUE_;
/* !LET HIM OUT. */
return ret_val;
L14100:
if (findex_1.cphere != 52 || prsvec_1.prso != xsrch_1.xwest || !
findex_1.cpoutf) {
goto L14200;
}
findex_1.frobzf = TRUE_;
/* !YES, LET HIM OUT. */
return ret_val;
L14200:
for (i = 1; i <= 16; i += 2) {
/* !LOCATE EXIT. */
if (prsvec_1.prso == puzzle_1.cpdr[i - 1]) {
goto L14400;
}
/* L14300: */
}
return ret_val;
/* !NO SUCH EXIT. */
L14400:
j = puzzle_1.cpdr[i];
/* !GET DIRECTIONAL OFFSET. */
nxt = findex_1.cphere + j;
/* !GET NEXT STATE. */
k = 8;
/* !GET ORTHOGONAL DIR. */
if (j < 0) {
k = -8;
}
if ((abs(j) == 1 || abs(j) == 8 || (puzzle_1.cpvec[findex_1.cphere + k -
1] == 0 || puzzle_1.cpvec[nxt - k - 1] == 0)) && puzzle_1.cpvec[
nxt - 1] == 0) {
goto L14500;
}
return ret_val;
L14500:
cpgoto_(nxt);
/* !MOVE TO STATE. */
curxt_1.xroom1 = rindex_1.cpuzz;
/* !STAY IN ROOM. */
ret_val = curxt_1.xroom1;
return ret_val;
} /* cxappl_ */