C SAVE- SAVE GAME STATE C C COPYRIGHT 1980, INFOCOM COMPUTERS AND COMMUNICATIONS, CAMBRIDGE MA. 02142 C ALL RIGHTS RESERVED, COMMERCIAL USAGE STRICTLY PROHIBITED C WRITTEN BY R. M. SUPNIK C C DECLARATIONS C SUBROUTINE SAVEGM IMPLICIT INTEGER (A-Z) #include "parser.h" #include "gamestate.h" #include "state.h" #include "screen.h" #include "puzzle.h" #include "rooms.h" #include "exits.h" #include "objects.h" #include "clock.h" #include "villians.h" #include "advers.h" #include "flags.h" C C MISCELLANEOUS VARIABLES C COMMON /VERS/ VMAJ,VMIN,VEDIT COMMON /TIME/ PLTIME,SHOUR,SMIN,SSEC C PRSWON=.FALSE. C !DISABLE GAME. C Note: save file format is different for PDP vs. non-PDP versions C #ifdef PDP C C send restore data flag down pipe C call outstr(stchr,1) C write out necessary common blocks C C /play/ call arywt(4,winner) C C /state/ call arywt(11,moves) C C /screen/ call arywt(3,formdr) C C /puzzle/ call arywt(64,cpvec) C C /vers/ call arywt(3,vmaj) C C /rooms/ call arywt(400,rval) C C /objects/ call arywt(2860,odesc1) C C /cevent/ call arywt(100,ctick) C C /hack/ call arywt(8,thfpos) C C /vill/ call arywt(4,vprob) C C /advs/ call arywt(28,aroom) C C /findex/ call arywt(114,flags) C C send end of data flag down pipe C call outstr(endchr,1) CALL RSPEAK(597) RETURN #else OPEN (UNIT=1,file='dsave.dat',ACCESS='SEQUENTIAL', & status='UNKNOWN',FORM='UNFORMATTED',ERR=100) rewind (unit=1, err=100) C CALL GTTIME(I) C !GET TIME. WRITE(1) VMAJ,VMIN,VEDIT WRITE(1) WINNER,HERE,THFPOS,TELFLG,THFFLG,THFACT, & SWDACT,SWDSTA,CPVEC WRITE(1) I,MOVES,DEATHS,RWSCOR,EGSCOR,MXLOAD, & LTSHFT,BLOC,MUNGRM,HS,FROMDR,SCOLRM,SCOLAC WRITE(1) ODESC1,ODESC2,OFLAG1,OFLAG2,OFVAL,OTVAL, & OSIZE,OCAPAC,OROOM,OADV,OCAN WRITE(1) RVAL,RFLAG WRITE(1) AROOM,ASCORE,AVEHIC,ASTREN,AFLAG WRITE(1) FLAGS,SWITCH,VPROB,CFLAG,CTICK C CLOSE(UNIT=1) CALL RSPEAK(597) RETURN C 100 CALL RSPEAK(598) C !CANT DO IT. RETURN #endif PDP END C RESTORE- RESTORE GAME STATE C C DECLARATIONS C SUBROUTINE RSTRGM IMPLICIT INTEGER (A-Z) #include "parser.h" #include "gamestate.h" #include "state.h" #include "screen.h" #include "puzzle.h" #include "rooms.h" #include "exits.h" #include "objects.h" #include "clock.h" #include "villians.h" #include "advers.h" #include "flags.h" C C MISCELLANEOUS VARIABLES C COMMON /VERS/ VMAJ,VMIN,VEDIT COMMON /TIME/ PLTIME,SHOUR,SMIN,SSEC C PRSWON=.FALSE. C !DISABLE GAME. C Note: save file format is different for PDP vs. non-PDP versions C #ifdef PDP C C read in necessary common blocks C C /play/ call aryrd(4,winner) C C /state/ call aryrd(11,moves) C C /screen/ call aryrd(3,formdr) C C /puzzle/ call aryrd(64,cpvec) C C /vers/ call intrd(i) call intrd(j) call intrd(k) C C /rooms/ call aryrd(400,rval) C C /objects/ call aryrd(2860,odesc1) C C /cevent/ call aryrd(100,ctick) C C /hack/ call aryrd(8,thfpos) C C /vill/ call aryrd(4,vprob) C C /advs/ call aryrd(28,aroom) C C /findex/ call aryrd(114,flags) C C IF(or((I.NE.VMAJ),(J.NE.VMIN))) GO TO 200 CALL RSPEAK(599) RETURN C 200 CALL RSPEAK(600) C !OBSOLETE VERSION RETURN #else OPEN (UNIT=1,file='dsave.dat',ACCESS='SEQUENTIAL', #ifdef XELOS & status='OLD',FORM='UNFORMATTED',ERR=100,recl=1) #else & status='OLD',FORM='UNFORMATTED',ERR=100) #endif rewind (unit=1, err=100) C READ(1) I,J,K IF(or((I.NE.VMAJ),(J.NE.VMIN))) GO TO 200 C READ(1) WINNER,HERE,THFPOS,TELFLG,THFFLG,THFACT, & SWDACT,SWDSTA,CPVEC READ(1) PLTIME,MOVES,DEATHS,RWSCOR,EGSCOR,MXLOAD, & LTSHFT,BLOC,MUNGRM,HS,FROMDR,SCOLRM,SCOLAC READ(1) ODESC1,ODESC2,OFLAG1,OFLAG2,OFVAL,OTVAL, & OSIZE,OCAPAC,OROOM,OADV,OCAN READ(1) RVAL,RFLAG READ(1) AROOM,ASCORE,AVEHIC,ASTREN,AFLAG READ(1) FLAGS,SWITCH,VPROB,CFLAG,CTICK C CLOSE(UNIT=1) CALL RSPEAK(599) RETURN C 100 CALL RSPEAK(598) C !CANT DO IT. RETURN C 200 CALL RSPEAK(600) C !OBSOLETE VERSION CLOSE (UNIT=1) RETURN #endif PDP END C WALK- MOVE IN SPECIFIED DIRECTION C C DECLARATIONS C LOGICAL FUNCTION WALK(X) IMPLICIT INTEGER(A-Z) LOGICAL FINDXT,QOPEN,LIT,PROB,MOVETO,RMDESC #include "parser.h" #include "gamestate.h" #include "rooms.h" #include "rflag.h" #include "curxt.h" #include "xsrch.h" #include "objects.h" #include "oflags.h" #include "clock.h" #include "villians.h" #include "advers.h" #include "flags.h" C C FUNCTIONS AND DATA C QOPEN(O)=and(OFLAG2(O),OPENBT).NE.0 C WALK, PAGE 2 C WALK=.TRUE. C !ASSUME WINS. IF((WINNER.NE.PLAYER).OR.LIT(HERE).OR.PROB(25,25)) & GO TO 500 IF(.NOT.FINDXT(PRSO,HERE)) GO TO 450 C !INVALID EXIT? GRUE C ! GO TO (400,200,100,300),XTYPE C !DECODE EXIT TYPE. CALL BUG(9,XTYPE) C 100 IF(CXAPPL(XACTIO).NE.0) GO TO 400 C !CEXIT... RETURNED ROOM? IF(FLAGS(XFLAG)) GO TO 400 C !NO, FLAG ON? 200 CALL JIGSUP(523) C !BAD EXIT, GRUE C ! RETURN C 300 IF(CXAPPL(XACTIO).NE.0) GO TO 400 C !DOOR... RETURNED ROOM? IF(QOPEN(XOBJ)) GO TO 400 C !NO, DOOR OPEN? CALL JIGSUP(523) C !BAD EXIT, GRUE C ! RETURN C 400 IF(LIT(XROOM1)) GO TO 900 C !VALID ROOM, IS IT LIT? 450 CALL JIGSUP(522) C !NO, GRUE C ! RETURN C C ROOM IS LIT, OR WINNER IS NOT PLAYER (NO GRUE). C 500 IF(FINDXT(PRSO,HERE)) GO TO 550 C !EXIT EXIST? 525 XSTRNG=678 C !ASSUME WALL. IF(PRSO.EQ.XUP) XSTRNG=679 C !IF UP, CANT. IF(PRSO.EQ.XDOWN) XSTRNG=680 C !IF DOWN, CANT. IF(and(RFLAG(HERE),RNWALL).NE.0) XSTRNG=524 CALL RSPEAK(XSTRNG) PRSCON=1 C !STOP CMD STREAM. RETURN C 550 GO TO (900,600,700,800),XTYPE C !BRANCH ON EXIT TYPE. CALL BUG(9,XTYPE) C 700 IF(CXAPPL(XACTIO).NE.0) GO TO 900 C !CEXIT... RETURNED ROOM? IF(FLAGS(XFLAG)) GO TO 900 C !NO, FLAG ON? 600 IF(XSTRNG.EQ.0) GO TO 525 C !IF NO REASON, USE STD. CALL RSPEAK(XSTRNG) C !DENY EXIT. PRSCON=1 C !STOP CMD STREAM. RETURN C 800 IF(CXAPPL(XACTIO).NE.0) GO TO 900 C !DOOR... RETURNED ROOM? IF(QOPEN(XOBJ)) GO TO 900 C !NO, DOOR OPEN? IF(XSTRNG.EQ.0) XSTRNG=525 C !IF NO REASON, USE STD. CALL RSPSUB(XSTRNG,ODESC2(XOBJ)) PRSCON=1 C !STOP CMD STREAM. RETURN C 900 WALK=MOVETO(XROOM1,WINNER) C !MOVE TO ROOM. IF(WALK) WALK=RMDESC(0) C !DESCRIBE ROOM. RETURN END C CXAPPL- CONDITIONAL EXIT PROCESSORS C C DECLARATIONS C INTEGER FUNCTION CXAPPL(RI) IMPLICIT INTEGER (A-Z) #include "gamestate.h" #include "parser.h" #include "puzzle.h" #include "rooms.h" #include "rindex.h" #include "exits.h" #include "curxt.h" #include "xpars.h" #include "xsrch.h" #include "objects.h" #include "oflags.h" #include "oindex.h" #include "advers.h" #include "flags.h" C CXAPPL, PAGE 2 C CXAPPL=0 C !NO RETURN. IF(RI.EQ.0) RETURN C !IF NO ACTION, DONE. GO TO (1000,2000,3000,4000,5000,6000,7000, & 8000,9000,10000,11000,12000,13000,14000),RI CALL BUG(5,RI) C C C1- COFFIN-CURE C 1000 EGYPTF=OADV(COFFI).NE.WINNER C !T IF NO COFFIN. RETURN C C C2- CAROUSEL EXIT C C5- CAROUSEL OUT C 2000 IF(CAROFF) RETURN C !IF FLIPPED, NOTHING. 2500 CALL RSPEAK(121) C !SPIN THE COMPASS. 5000 I=XELNT(XCOND)*RND(8) C !CHOOSE RANDOM EXIT. XROOM1=and(TRAVEL(REXIT(HERE)+I),XRMASK) CXAPPL=XROOM1 C !RETURN EXIT. RETURN C C C3- CHIMNEY FUNCTION C 3000 LITLDF=.FALSE. C !ASSUME HEAVY LOAD. J=0 DO 3100 I=1,OLNT C !COUNT OBJECTS. IF(OADV(I).EQ.WINNER) J=J+1 3100 CONTINUE C IF(J.GT.2) RETURN C !CARRYING TOO MUCH? XSTRNG=446 C !ASSUME NO LAMP. IF(OADV(LAMP).NE.WINNER) RETURN C !NO LAMP? LITLDF=.TRUE. C !HE CAN DO IT. IF(and(OFLAG2(DOOR),OPENBT).EQ.0) & OFLAG2(DOOR)=and(OFLAG2(DOOR), not(TCHBT)) RETURN C C C4- FROBOZZ FLAG (MAGNET ROOM, FAKE EXIT) C C6- FROBOZZ FLAG (MAGNET ROOM, REAL EXIT) C 4000 IF(CAROFF) GO TO 2500 C !IF FLIPPED, GO SPIN. FROBZF=.FALSE. C !OTHERWISE, NOT AN EXIT. RETURN C 6000 IF(CAROFF) GO TO 2500 C !IF FLIPPED, GO SPIN. FROBZF=.TRUE. C !OTHERWISE, AN EXIT. RETURN C C C7- FROBOZZ FLAG (BANK ALARM) C 7000 FROBZF=and((OROOM(BILLS).NE.0),(OROOM(PORTR).NE.0)) RETURN C CXAPPL, PAGE 3 C C C8- FROBOZZ FLAG (MRGO) C 8000 FROBZF=.FALSE. C !ASSUME CANT MOVE. IF(MLOC.NE.XROOM1) GO TO 8100 C !MIRROR IN WAY? IF((PRSO.EQ.XNORTH).OR.(PRSO.EQ.XSOUTH)) GO TO 8200 IF(MOD(MDIR,180).NE.0) GO TO 8300 C !MIRROR MUST BE N-S. XROOM1=((XROOM1-MRA)*2)+MRAE C !CALC EAST ROOM. IF(PRSO.GT.XSOUTH) XROOM1=XROOM1+1 C !IF SW/NW, CALC WEST. 8100 CXAPPL=XROOM1 RETURN C 8200 XSTRNG=814 C !ASSUME STRUC BLOCKS. IF(MOD(MDIR,180).EQ.0) RETURN C !IF MIRROR N-S, DONE. 8300 LDIR=MDIR C !SEE WHICH MIRROR. IF(PRSO.EQ.XSOUTH) LDIR=180 XSTRNG=815 C !MIRROR BLOCKS. IF(((LDIR.GT.180).AND..NOT.MR1F).OR. & ((LDIR.LT.180).AND..NOT.MR2F)) XSTRNG=816 RETURN C C C9- FROBOZZ FLAG (MIRIN) C 9000 IF(MRHERE(HERE).NE.1) GO TO 9100 C !MIRROR 1 HERE? IF(MR1F) XSTRNG=805 C !SEE IF BROKEN. FROBZF=MROPNF C !ENTER IF OPEN. RETURN C 9100 FROBZF=.FALSE. C !NOT HERE, XSTRNG=817 C !LOSE. RETURN C CXAPPL, PAGE 4 C C C10- FROBOZZ FLAG (MIRROR EXIT) C 10000 FROBZF=.FALSE. C !ASSUME CANT. LDIR=((PRSO-XNORTH)/XNORTH)*45 C !XLATE DIR TO DEGREES. IF(.NOT.MROPNF .OR. & ((MOD(MDIR+270,360).NE.LDIR).AND.(PRSO.NE.XEXIT))) & GO TO 10200 XROOM1=((MLOC-MRA)*2)+MRAE+1-(MDIR/180) C !ASSUME E-W EXIT. IF(MOD(MDIR,180).EQ.0) GO TO 10100 C !IF N-S, OK. XROOM1=MLOC+1 C !ASSUME N EXIT. IF(MDIR.GT.180) XROOM1=MLOC-1 C !IF SOUTH. 10100 CXAPPL=XROOM1 RETURN C 10200 IF(.NOT.WDOPNF .OR. & ((MOD(MDIR+180,360).NE.LDIR).AND.(PRSO.NE.XEXIT))) & RETURN XROOM1=MLOC+1 C !ASSUME N. IF(MDIR.EQ.0) XROOM1=MLOC-1 C !IF S. CALL RSPEAK(818) C !CLOSE DOOR. WDOPNF=.FALSE. CXAPPL=XROOM1 RETURN C C C11- MAYBE DOOR. NORMAL MESSAGE IS THAT DOOR IS CLOSED. C BUT IF LCELL.NE.4, DOOR ISNT THERE. C 11000 IF(LCELL.NE.4) XSTRNG=678 C !SET UP MSG. RETURN C C C12- FROBZF (PUZZLE ROOM MAIN ENTRANCE) C 12000 FROBZF=.TRUE. C !ALWAYS ENTER. CPHERE=10 C !SET SUBSTATE. RETURN C C C13- CPOUTF (PUZZLE ROOM SIZE ENTRANCE) C 13000 CPHERE=52 C !SET SUBSTATE. RETURN C CXAPPL, PAGE 5 C C C14- FROBZF (PUZZLE ROOM TRANSITIONS) C 14000 FROBZF=.FALSE. C !ASSSUME LOSE. IF(PRSO.NE.XUP) GO TO 14100 C !UP? IF(CPHERE.NE.10) RETURN C !AT EXIT? XSTRNG=881 C !ASSUME NO LADDER. IF(CPVEC(CPHERE+1).NE.-2) RETURN C !LADDER HERE? CALL RSPEAK(882) C !YOU WIN. FROBZF=.TRUE. C !LET HIM OUT. RETURN C 14100 IF((CPHERE.NE.52).OR.(PRSO.NE.XWEST).OR..NOT.CPOUTF) & GO TO 14200 FROBZF=.TRUE. C !YES, LET HIM OUT. RETURN C 14200 DO 14300 I=1,16,2 C !LOCATE EXIT. IF(PRSO.EQ.CPDR(I)) GO TO 14400 14300 CONTINUE RETURN C !NO SUCH EXIT. C 14400 J=CPDR(I+1) C !GET DIRECTIONAL OFFSET. NXT=CPHERE+J C !GET NEXT STATE. K=8 C !GET ORTHOGONAL DIR. IF(J.LT.0) K=-8 IF((((IABS(J).EQ.1).OR.(IABS(J).EQ.8)).OR. & ((CPVEC(CPHERE+K).EQ.0).OR.(CPVEC(NXT-K).EQ.0))).AND. & (CPVEC(NXT).EQ.0)) GO TO 14500 RETURN C 14500 CALL CPGOTO(NXT) C !MOVE TO STATE. XROOM1=CPUZZ C !STAY IN ROOM. CXAPPL=XROOM1 RETURN C END