C RESIDENT SUBROUTINES FOR DUNGEON
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 RSPEAK-- OUTPUT RANDOM MESSAGE ROUTINE
C RSPSUB-- OUTPUT RANDOM MESSAGE WITH SUBSTITUTABLE ARGUMENT
C CALL RSPSUB(MSGNUM,SUBNUM)
C RSPSB2-- OUTPUT RANDOM MESSAGE WITH UP TO TWO SUBSTITUTABLE ARGUMENTS
C CALL RSPSB2(MSGNUM,SUBNUM1,SUBNUM2)
SUBROUTINE RSPSB2(N,S1,S2)
INTEGER*2 OLDREC,NEWREC,JREC
C use C routine to access data base
C CONVERT ALL ARGUMENTS FROM DICTIONARY NUMBERS (IF POSITIVE)
C TO ABSOLUTE RECORD NUMBERS.
C !SET UP WORK VARIABLES.
C !IF >0, LOOK UP IN RTEXT.
READ(UNIT=DBCH,REC=X) OLDREC,B1
B1(I:I)=char(xor(ichar(B1(I:I)),X1))
IF(B1(I:I).EQ.'#') GO TO 1000
IF(B1(I:I).NE.' ') GO TO 600
600 WRITE(OUTCH,650) (B1(J:J),J=1,I)
READ(UNIT=DBCH,REC=X) NEWREC,B1
IF(OLDREC.EQ.NEWREC) GO TO 100
C SUBSTITUTION WITH SUBSTITUTABLE AVAILABLE.
C Y IS NUMBER OF RECORD TO SUBSTITUTE.
C 1) COPY REST OF B1 TO B2
C 2) READ SUBSTITUTABLE OVER B1
C 3) RESTORE TAIL OF ORIGINAL B1
C THE IMPLICIT ASSUMPTION HERE IS THAT THE SUBSTITUTABLE STRING
C IS VERY SHORT (i.e. MUCH LESS THAN ONE RECORD).
C READ SUBSTITUTE STRING INTO B3, AND DECRYPT IT:
READ(UNIT=DBCH,REC=Y) JREC,B3
B3(K1:K1)=char(xor(ICHAR(B3(K1:K1)),X1))
C FILL REMAINDER OF B1 WITH CHARACTERS FROM B3:
C FIND END OF SUBSTITUTE STRING IN B1:
IF(B1(J:J).NE.' ') GO TO 1300
C PUT TAIL END OF B1 (NOW IN B2) BACK INTO B1 AFTER SUBSTITUTE STRING:
C OBJACT-- APPLY OBJECTS FROM PARSE VECTOR
LOGICAL FUNCTION OBJACT(X)
IF(OAPPLI(OACTIO(PRSI),0)) RETURN
100 IF(PRSO.EQ.0) GO TO 200
IF(OAPPLI(OACTIO(PRSO),0)) RETURN
C BUG-- REPORT FATAL SYSTEM ERROR
100 FORMAT('PROGRAM ERROR ',I2,', PARAMETER=',I6)
100 FORMAT(' PROGRAM ERROR ',I2,', PARAMETER=',I6)
C NEWSTA-- SET NEW STATUS FOR OBJECT
C CALL NEWSTA(OBJECT,STRING,NEWROOM,NEWCON,NEWADV)
SUBROUTINE NEWSTA(O,R,RM,CN,AD)
C QHERE-- TEST FOR OBJECT IN ROOM
LOGICAL FUNCTION QHERE(OBJ,RM)
IF(OROOM(OBJ).EQ.RM) RETURN
IF((OROOM2(I).EQ.OBJ).AND.(RROOM2(I).EQ.RM)) RETURN
C QEMPTY-- TEST FOR OBJECT EMPTY
LOGICAL FUNCTION QEMPTY(OBJ)
IF(OCAN(I).EQ.OBJ) RETURN
LOGICAL YESNO,MOVETO,QHERE,F
DATA RLIST/8,6,36,35,34,4,34,6,5/
IF(WINNER.EQ.PLAYER) GO TO 100
CALL RSPSUB(432,ODESC2(AOBJ(WINNER)))
CALL NEWSTA(AOBJ(WINNER),0,0,0,0)
C !NO RECOVERY IN END GAME.
IF(DEATHS.GE.2) GO TO 1000
C !DEAD TWICE? KICK HIM OFF.
IF(.NOT.YESNO(10,9,8)) GO TO 1100
IF(QHERE(J,HERE)) OFLAG2(J)=and(OFLAG2(J),not(FITEBT))
IF(OADV(COFFI).EQ.WINNER) CALL NEWSTA(COFFI,0,EGYPT,0,0)
OFLAG2(DOOR)=and(OFLAG2(DOOR),not(TCHBT))
OFLAG1(ROBOT)=and(or(OFLAG1(ROBOT),VISIBT),not(NDSCBT))
IF((OROOM(LAMP).NE.0).OR.(OADV(LAMP).EQ.WINNER))
& CALL NEWSTA(LAMP,0,LROOM,0,0)
C NOW REDISTRIBUTE HIS VALUABLES AND OTHER BELONGINGS.
C THE LAMP HAS BEEN PLACED IN THE LIVING ROOM.
C THE FIRST 8 NON-VALUABLES ARE PLACED IN LOCATIONS AROUND THE HOUSE.
C HIS VALUABLES ARE PLACED AT THE END OF THE MAZE.
C REMAINING NON-VALUABLES ARE PLACED AT THE END OF THE MAZE.
IF((OADV(J).NE.WINNER).OR.(OTVAL(J).NE.0))
C !MOVE TO RANDOM LOCATIONS.
CALL NEWSTA(J,0,RLIST(I),0,0)
NONOFL=RAIR+RWATER+RSACRD+REND
IF((OADV(J).NE.WINNER).OR.(OTVAL(J).EQ.0))
IF(and(RFLAG(I),NONOFL).NE.0) GO TO 250
C !NOW GET RID OF REMAINDER.
IF(OADV(J).NE.WINNER) GO TO 500
IF(and(RFLAG(I),NONOFL).NE.0) GO TO 450
C CAN'T OR WON'T CONTINUE, CLEAN UP AND EXIT.
C file closed in exit routine
C OACTOR- GET ACTOR ASSOCIATED WITH OBJECT
INTEGER FUNCTION OACTOR(OBJ)
IF(AOBJ(I).EQ.OBJ) RETURN
C PROB- COMPUTE PROBABILITY
LOGICAL FUNCTION PROB(G,B)
C RMDESC-- PRINT ROOM DESCRIPTION
C RMDESC PRINTS A DESCRIPTION OF THE CURRENT ROOM.
C IT IS ALSO THE PROCESSOR FOR VERBS 'LOOK' AND 'EXAMINE'.
LOGICAL FUNCTION RMDESC(FULL)
C FULL= 0/1/2/3= SHORT/OBJ/ROOM/FULL
IF(PRSO.LT.XMIN) GO TO 50
50 IF(HERE.EQ.AROOM(PLAYER)) GO TO 100
C !SET UP WALK IN ACTION.
100 IF(LIT(HERE)) GO TO 300
& .AND.(SUPERF.OR.(((and(RFLAG(HERE),RSEEN)).NE.0)
C The next line means that when you request VERBOSE mode, you
C only get long room descriptions 20% of the time. I don't either
C like or understand this, so the mod. ensures VERBOSE works
C all the time. jmh@ukc.ac.uk 22/10/87
C& .AND.(BRIEFF.OR.PROB(80,80))))) GO TO 400
& .AND.BRIEFF))) GO TO 400
IF((I.NE.0).OR.(RA.EQ.0)) GO TO 400
IF(.NOT.RAPPLI(RA)) GO TO 100
C !ROOM HANDLES, NEW DESC?
500 IF(AVEHIC(WINNER).NE.0) CALL RSPSUB(431,ODESC2(AVEHIC(WINNER)))
600 IF(FULL.NE.2) CALL PRINCR(FULL.NE.0,HERE)
RFLAG(HERE)=or(RFLAG(HERE),RSEEN)
IF((FULL.NE.0).OR.(RA.EQ.0)) RETURN
IF(.NOT.RAPPLI(RA)) GO TO 100
C !ROOM HANDLES, NEW DESC?
C RAPPLI- ROUTING ROUTINE FOR ROOM APPLICABLES
LOGICAL FUNCTION RAPPLI(RI)
IF(RI.LT.NEWRMS) RAPPLI=RAPPL1(RI)
IF(RI.GE.NEWRMS) RAPPLI=RAPPL2(RI)