4.4BSD/usr/src/contrib/dungeon/dverb1.F
C TAKE-- BASIC TAKE SEQUENCE
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 TAKE AN OBJECT (FOR VERBS TAKE, PUT, DROP, READ, ETC.)
C
LOGICAL FUNCTION TAKE(FLG)
C
C DECLARATIONS
C
IMPLICIT INTEGER (A-Z)
LOGICAL FLG,OBJACT,OAPPLI,QOPEN,QHERE
#include "parser.h"
#include "gamestate.h"
#include "state.h"
COMMON /STAR/ MBASE,STRBIT
#include "objects.h"
#include "oflags.h"
C
#include "advers.h"
C
C FUNCTIONS AND DATA
C
QOPEN(O)=(and(OFLAG2(O),OPENBT).NE.0)
C TAKE, PAGE 2
C
TAKE=.FALSE.
C !ASSUME LOSES.
OA=OACTIO(PRSO)
C !GET OBJECT ACTION.
IF(PRSO.LE.STRBIT) GO TO 100
C !STAR?
TAKE=OBJACT(X)
C !YES, LET IT HANDLE.
RETURN
C
100 X=OCAN(PRSO)
C !INSIDE?
IF(PRSO.NE.AVEHIC(WINNER)) GO TO 400
C !HIS VEHICLE?
CALL RSPEAK(672)
C !DUMMY.
RETURN
C
400 IF(and(OFLAG1(PRSO),TAKEBT).NE.0) GO TO 500
IF(.NOT.OAPPLI(OA,0)) CALL RSPEAK(552+RND(5))
RETURN
C
C OBJECT IS TAKEABLE AND IN POSITION TO BE TAKEN.
C
500 IF((X.NE.0).OR. QHERE(PRSO,HERE)) GO TO 600
IF(OADV(PRSO).EQ.WINNER) CALL RSPEAK(557)
C !ALREADY GOT IT?
RETURN
C
600 IF(((X.NE.0).AND.(OADV(X).EQ.WINNER)).OR.
& ((WEIGHT(0,PRSO,WINNER)+OSIZE(PRSO)).LE.MXLOAD))
& GO TO 700
CALL RSPEAK(558)
C !TOO MUCH WEIGHT.
RETURN
C
700 TAKE=.TRUE.
C !AT LAST.
IF(OAPPLI(OA,0)) RETURN
C !DID IT HANDLE?
CALL NEWSTA(PRSO,0,0,0,WINNER)
C !TAKE OBJECT FOR WINNER.
OFLAG2(PRSO)=or(OFLAG2(PRSO),TCHBT)
CALL SCRUPD(OFVAL(PRSO))
C !UPDATE SCORE.
OFVAL(PRSO)=0
C !CANT BE SCORED AGAIN.
IF(FLG) CALL RSPEAK(559)
C !TELL TAKEN.
RETURN
C
END
C DROP- DROP VERB PROCESSOR
C
C DECLARATIONS
C
LOGICAL FUNCTION DROP(Z)
IMPLICIT INTEGER (A-Z)
LOGICAL F,PUT,OBJACT
#include "parser.h"
#include "gamestate.h"
C
C ROOMS
#include "rindex.h"
#include "objects.h"
#include "oflags.h"
C
#include "advers.h"
#include "verbs.h"
C DROP, PAGE 2
C
DROP=.TRUE.
C !ASSUME WINS.
X=OCAN(PRSO)
C !GET CONTAINER.
IF(X.EQ.0) GO TO 200
C !IS IT INSIDE?
IF(OADV(X).NE.WINNER) GO TO 1000
C !IS HE CARRYING CON?
IF(and(OFLAG2(X),OPENBT).NE.0) GO TO 300
CALL RSPSUB(525,ODESC2(X))
C !CANT REACH.
RETURN
C
200 IF(OADV(PRSO).NE.WINNER) GO TO 1000
C !IS HE CARRYING OBJ?
300 IF(AVEHIC(WINNER).EQ.0) GO TO 400
C !IS HE IN VEHICLE?
PRSI=AVEHIC(WINNER)
C !YES,
F=PUT(.TRUE.)
C !DROP INTO VEHICLE.
PRSI=0
C !DISARM PARSER.
RETURN
C !DONE.
C
400 CALL NEWSTA(PRSO,0,HERE,0,0)
C !DROP INTO ROOM.
IF(HERE.EQ.MTREE) CALL NEWSTA(PRSO,0,FORE3,0,0)
CALL SCRUPD(OFVAL(PRSO))
C !SCORE OBJECT.
OFVAL(PRSO)=0
C !CANT BE SCORED AGAIN.
OFLAG2(PRSO)=or(OFLAG2(PRSO),TCHBT)
C
IF(OBJACT(X)) RETURN
C !DID IT HANDLE?
I=0
C !ASSUME NOTHING TO SAY.
IF(PRSA.EQ.DROPW) I=528
IF(PRSA.EQ.THROWW) I=529
IF((I.NE.0).AND.(HERE.EQ.MTREE)) I=659
CALL RSPSUB(I,ODESC2(PRSO))
RETURN
C
1000 CALL RSPEAK(527)
C !DONT HAVE IT.
RETURN
C
END
C PUT- PUT VERB PROCESSOR
C
C DECLARATIONS
C
LOGICAL FUNCTION PUT(FLG)
IMPLICIT INTEGER (A-Z)
LOGICAL TAKE,QOPEN,QHERE,OBJACT,FLG
#include "parser.h"
#include "gamestate.h"
C
C MISCELLANEOUS VARIABLES
C
COMMON /STAR/ MBASE,STRBIT
#include "objects.h"
#include "oflags.h"
#include "advers.h"
#include "verbs.h"
C
C FUNCTIONS AND DATA
C
QOPEN(R)=((and(OFLAG2(R),OPENBT)).NE.0)
C PUT, PAGE 2
C
PUT=.FALSE.
IF((PRSO.LE.STRBIT).AND.(PRSI.LE.STRBIT)) GO TO 200
IF(.NOT.OBJACT(X)) CALL RSPEAK(560)
C !STAR
PUT=.TRUE.
RETURN
C
200 IF((QOPEN(PRSI))
& .OR.(and(OFLAG1(PRSI),(DOORBT+CONTBT)).NE.0)
& .OR.(and(OFLAG2(PRSI),VEHBT).NE.0)) GO TO 300
CALL RSPEAK(561)
C !CANT PUT IN THAT.
RETURN
C
300 IF(QOPEN(PRSI)) GO TO 400
C !IS IT OPEN?
CALL RSPEAK(562)
C !NO, JOKE
RETURN
C
400 IF(PRSO.NE.PRSI) GO TO 500
C !INTO ITSELF?
CALL RSPEAK(563)
C !YES, JOKE.
RETURN
C
500 IF(OCAN(PRSO).NE.PRSI) GO TO 600
C !ALREADY INSIDE.
CALL RSPSB2(564,ODESC2(PRSO),ODESC2(PRSI))
PUT=.TRUE.
RETURN
C
600 IF((WEIGHT(0,PRSO,0)+WEIGHT(0,PRSI,0)+OSIZE(PRSO))
& .LE.OCAPAC(PRSI)) GO TO 700
CALL RSPEAK(565)
C !THEN CANT DO IT.
RETURN
C
C NOW SEE IF OBJECT (OR ITS CONTAINER) IS IN ROOM
C
700 J=PRSO
C !START SEARCH.
725 IF(QHERE(J,HERE)) GO TO 750
C !IS IT HERE?
J=OCAN(J)
IF(J.NE.0) GO TO 725
C !MORE TO DO?
GO TO 800
C !NO, SCH FAILS.
C
750 SVO=PRSO
C !SAVE PARSER.
SVI=PRSI
PRSA=TAKEW
PRSI=0
IF(.NOT.TAKE(.FALSE.)) RETURN
C !TAKE OBJECT.
PRSA=PUTW
PRSO=SVO
PRSI=SVI
GO TO 1000
C
C NOW SEE IF OBJECT IS ON PERSON.
C
800 IF(OCAN(PRSO).EQ.0) GO TO 1000
C !INSIDE?
IF(QOPEN(OCAN(PRSO))) GO TO 900
C !OPEN?
CALL RSPSUB(566,ODESC2(PRSO))
C !LOSE.
RETURN
C
900 CALL SCRUPD(OFVAL(PRSO))
C !SCORE OBJECT.
OFVAL(PRSO)=0
OFLAG2(PRSO)=or(OFLAG2(PRSO),TCHBT)
CALL NEWSTA(PRSO,0,0,0,WINNER)
C !TEMPORARILY ON WINNER.
C
1000 IF(OBJACT(X)) RETURN
C !NO, GIVE OBJECT A SHOT.
CALL NEWSTA(PRSO,2,0,PRSI,0)
C !CONTAINED INSIDE.
PUT=.TRUE.
RETURN
C
END
C VALUAC- HANDLES VALUABLES/EVERYTHING
C
C DECLARATIONS
C
SUBROUTINE VALUAC(V)
IMPLICIT INTEGER (A-Z)
LOGICAL LIT,F,F1,TAKE,PUT,DROP,NOTVAL,QHERE
#include "parser.h"
#include "gamestate.h"
#include "objects.h"
#include "oflags.h"
#include "verbs.h"
C
C FUNCTIONS AND DATA
C
NOTVAL(R)=(SAVEP.EQ.V).AND.(OTVAL(R).LE.0)
C VALUAC, PAGE 2
C
F=.TRUE.
C !ASSUME NO ACTIONS.
I=579
C !ASSUME NOT LIT.
IF(.NOT.LIT(HERE)) GO TO 4000
C !IF NOT LIT, PUNT.
I=677
C !ASSUME WRONG VERB.
SAVEP=PRSO
C !SAVE PRSO.
SAVEH=HERE
C !SAVE HERE.
C
100 IF(PRSA.NE.TAKEW) GO TO 1000
C !TAKE EVERY/VALUA?
DO 500 PRSO=1,OLNT
C !LOOP THRU OBJECTS.
IF(.NOT.QHERE(PRSO,HERE).OR.
& (and(OFLAG1(PRSO),VISIBT).EQ.0).OR.
& (and(OFLAG2(PRSO),ACTRBT).NE.0).OR.
& NOTVAL(PRSO)) GO TO 500
IF((and(OFLAG1(PRSO),TAKEBT).EQ.0).AND.
& (and(OFLAG2(PRSO),TRYBT).EQ.0)) GO TO 500
F=.FALSE.
CALL RSPSUB(580,ODESC2(PRSO))
F1=TAKE(.TRUE.)
IF(SAVEH.NE.HERE) RETURN
500 CONTINUE
GO TO 3000
C
1000 IF(PRSA.NE.DROPW) GO TO 2000
C !DROP EVERY/VALUA?
DO 1500 PRSO=1,OLNT
IF((OADV(PRSO).NE.WINNER).OR.NOTVAL(PRSO))
& GO TO 1500
F=.FALSE.
CALL RSPSUB(580,ODESC2(PRSO))
F1=DROP(.TRUE.)
IF(SAVEH.NE.HERE) RETURN
1500 CONTINUE
GO TO 3000
C
2000 IF(PRSA.NE.PUTW) GO TO 3000
C !PUT EVERY/VALUA?
DO 2500 PRSO=1,OLNT
C !LOOP THRU OBJECTS.
IF((OADV(PRSO).NE.WINNER)
& .OR.(PRSO.EQ.PRSI).OR.NOTVAL(PRSO).OR.
& (and(OFLAG1(PRSO),VISIBT).EQ.0)) GO TO 2500
F=.FALSE.
CALL RSPSUB(580,ODESC2(PRSO))
F1=PUT(.TRUE.)
IF(SAVEH.NE.HERE) RETURN
2500 CONTINUE
C
3000 I=581
IF(SAVEP.EQ.V) I=582
C !CHOOSE MESSAGE.
4000 IF(F) CALL RSPEAK(I)
C !IF NOTHING, REPORT.
RETURN
END