00010	!

	! ADVENT -- Game of adventures
00020	!

	! Translated into BASIC-PLUS from the FORTRAN IV program

	! developed by Willie Crowther and modified by Don Woods

	!
00030	! Keith Barnett   Alexis I. duPont High School  12/24/77

	!
01000	!

	! Set-up; create coded data file if necessary
01010	EXTEND
01020	ON ERROR GOTO 32000
01030	TRVSIZ%=750% \

	TABSIZ%=300% \

	LOCSIZ%=150% \

	VRBSIZ%=35% \

	RTXSIZ%=205% \

	CLSMAX%=12% \

	HNTSIZ%=20% \

	MAGSIZ%=35%
01040	RANDOMIZE
01050	DIM HATH%(12%), TK(22%) \

	MAT READ HATH%
01060	OPEN "KB:" AS FILE 3%
01100	LDN$="GAME:"
01110	OPEN LDN$+"ADVENT.DAT" FOR INPUT AS FILE 1%
01120	DIM #1%, TRAVEL(750%), KTAB%(300%), ATAB$(300%)=8%, LTEXT%(150%),

		STEXT%(150%), KEYW%(150%), COND0%(150%), PLAC%(100%),

		FIXD%(100%), PTEXT%(700%), ACTSPK%(35%), RTEXT%(205%),

		CTEXT%(12%), CVAL%(12%), HINTS%(20%,4%), MTEXT%(35%),

		WKDAY(0%), WKEND(0%), HOLID(0%), HBEGIN%(0%), HEND%(0%),

		HNAME$(0%), SHORT%(0%), MAGIC$(0%)=8%, MAGNM%(0%),

		LATNCY%(0%), MSG%(1%), HANDY%(55%), LINES$(32767%)
01130	OPEN "ADVENT.ADV" FOR INPUT AS FILE 4% \

	IF OTHER%(27%)=1% THEN OTHER%(27%)=FNVARSET% + FNSTART% \

		DUM%=FNCHAIN%(11000%)
01135	IF OTHER%(27%)<>2% THEN KILL "ADVENT.ADV" \

		GOTO 1130
01140	DIM #4%, ABB%(150%), ATLOC%(150%), PLACE%(100%), FIXED%(100%),

		COND%(150%), LINK%(200%), PROP%(100%), HINTLC%(20%),

		HINTED%(20%), DSEEN%(6%), DLOC%(6%), ODLOC%(6%),

		HNAME%(4%), OTHER%(35%)
01150	OTHER%(27%)=FNSTART%
01160	CLOSE 1%,4% \

	DUM%=FNVARSET% \

	GOTO 10000
01198	!

	! Set up changeable database (forced motion, ATLOC, LINK)

	!
01200	OPEN LDN$+"ADVENT.CPY<40>" FOR OUTPUT AS FILE 4% \

	FOR I%=1% TO LTEXT%(0%) \

		COND%(I%)=COND0%(I%) \

		COND%(I%)=2% IF LTEXT%(I%)-LTEXT%(I%-1%)>0% AND KEYW%(I%)

			AND FNMOD%(ABS(TRAVEL(KEYW%(I%))),1000%)=1% \

	NEXT I%
01205	HINTED%(I%), HINTLC%(I%)=0% FOR I%=1% TO HINTS%(0%,0%) \

	ABB%(I%), ATLOC%(I%)=0% FOR I%=1% TO LTEXT%(0%) \

	PLACE%(I%), PROP%(I%), LINK%(I%), LINK%(I%+100%)=0% FOR I%=0% TO 100%
01210	FOR I%=100% TO 1% STEP -1% \

		IF FIXD%(I%)>0% THEN

			DUM%=FNDROP%(I%+100%,FIXD%(I%)) + FNDROP%(I%,PLAC%(I%))
01220	NEXT I% \

	FOR I%=100% TO 1% STEP -1% \

		FIXED%(I%)=FIXD%(I%) \

		DUM%=FNDROP%(I%,PLAC%(I%)) IF PLAC%(I%)<>0% AND FIXD%(I%)<=0% \

	NEXT I%
01228	! TALLY keeps track of how many treasures (50 through MAXTRS) have

	! not been found, TALLY2 how many can never be found.
01230	MAXTRS%=64% \

	TALLY%, TALLY2%=0%
01240	FOR I%=50% TO MAXTRS% \

		PROP%(I%)=-1% IF PTEXT%(I%*7%)-PTEXT%(I%*7%-7%)>0% \

		TALLY%=TALLY%-PROP%(I%) \

	NEXT I%
01400	OTHER%(0%)=114% \

	OTHER%(1%)=140% \

	DSEEN%(I%),ODLOC%(I%)=0% FOR I%=1% TO 6% \

	OTHER%(2%)=0%
01410	DLOC%(1%)=19% \

	DLOC%(2%)=27% \

	DLOC%(3%)=33% \

	DLOC%(4%)=44% \

	DLOC%(5%)=64% \

	DLOC%(6%)=OTHER%(0%) \

	OTHER%(3%)=18%
01420	OTHER%(I%)=0% FOR I%=4% TO 20%
01430	OTHER%(21%)=5% \

	OTHER%(22%)=30% \

	OTHER%(23%)=50%
01440	OTHER%(24%)=TALLY% \

	OTHER%(25%)=TALLY2% \

	OTHER%(26%), OTHER%(27%)=2% \

	OTHER%(I%)=0% FOR I%=28% TO 35% \

	OTHER%(33%)=-1%
1450	CLOSE 4%
01500	! Transfer sample
01510	OPEN LDN$+"ADVENT.CPY" FOR INPUT AS FILE 5% \

	OPEN "ADVENT.ADV" FOR OUTPUT AS FILE 4% \

	FIELD #5%, 512% AS S1$ \

	FIELD #4%, 512% AS S2$ \

	FOR I%=1% TO 5% \

		GET #5%, RECORD I% \

		LSET S2$=S1$ \

		PUT #4%, RECORD I% \

	NEXT I% \

	CLOSE 4%,5% \

	GOTO 1130
02000	!

	! Initialize basic data base

	!

	! The text file contains several sections the first line of which

	! is the section number and the last "-1" (and "End")

	! Section 1: Long form descriptions.  Each line begins with the

	!	location number.

	! Section 2: Short form descriptions.

	! Section 3: Travel table.  Each line consists of a location number,

	!	a location number to go to, and a list of verbs that will

	!	cause the travel.  If Y is the resultant location, M=Y/1000

	!	and N=Y MOD 1000. If N<=300 it's the location, if 300<N<=500

	!	N-300 is used for a GOTO to special code, and if N>500

	!	message N-500 from section 6 is printed and he stays where

	!	he is.  If M=0 the motion is unconditional, 0<M<100 it's

	!	done with M% probability, M=100 it's forbidden to dwarves,

	!	100<M<=200 he must be carrying object M, 200<M<=300 he must

	!	be in same place as M (M-200), 300<M<=400 PROP(M MOD 100)

	!	can't be 0, 400<M<=500 PROP(M MOD 100) can't be 1, etc.

	! Section 4: Vocabulary.  If number is <1000, it's a motion verb,

	!	if <2000 an object, <3000 an action verb, <4000 special.

	! Section 5: Object descriptions (for different PROP's).

	! Section 6: Arbitrary messages.

	! Section 7: Initial object locations.  If third number is -1, it's

	!	fixed (it's also fixed if in two locations).

	! Section 8: Action verb default messages.

	! Section 9: Location conditions.  Bit 0 is for light, bits 1 and 2

	!	for liquid info, 3 for pirate, rest for hints.

	! Section 10: Class messages.

	! Section 11: Hints.  Number of turns to trigger hint, points taken

	!	off, and messages.

	! Section 12: Magic messages

	!
02010	OPEN LDN$+"ADVENT.TXT" FOR INPUT AS FILE 2%
02020	PRINT "Initializing..." \

	LINUSE%, TRVS%, CLSSES%=0% \

	R$=CHR$(13%)+CHR$(10%)
02030	OPEN LDN$+"ADVENT.DAT<40>" FOR OUTPUT AS FILE 1%
02040	INPUT #2%, SECT% \

	PRINT "Now loading section";SECT% \

	ON SECT%+1% GOTO 9000, 2100, 2100, 3000, 4000, 2100,

		2100, 5000, 6000, 7000, 2100, 8000, 2100
02100	! Sections 1, 2, 5, 6, 10, 12
02110	LINES$="" \

	OLDLOC%=0%
02120	INPUT LINE #2%, LIN$ \

	I%=INSTR(1%,LIN$,",") \

	LOC%=VAL(LEFT(LIN$,I%-1%)) \

	LIN$=RIGHT(LIN$,I%+1%) \

	LIN$=LEFT(LIN$,LEN(LIN$)-2%)+" " IF MID(LIN$,LEN(LIN$)-2%,1%)="?" \

	IF LOC%=OLDLOC% THEN LINES$=LINES$+LIN$ \

		GOTO 2120
02130	IF OLDLOC%=0% THEN OLDLOC%=LOC% \

		LINES$=LIN$ \

		GOTO 2120
02140	X%=(LEN(LINES$)+15%)/16% \

	LINES$(KK%+LINUSE%)=MID(LINES$,KK%*16%-15%,16%)

		FOR KK%=1% TO X%
02150	LINUSE%=LINUSE%+X% \

	FOR KK%=OLDLOC% TO LOC%-1%-(2%+OLDLOC%)*(LOC%=-1%) \

		IF SECT%=1% THEN LTEXT%(KK%)=LINUSE% ELSE

		IF SECT%=2% THEN STEXT%(KK%)=LINUSE% ELSE

		IF SECT%=6% THEN RTEXT%(KK%)=LINUSE% ELSE

		IF SECT%=12% THEN MTEXT%(KK%)=LINUSE%
02160	NEXT KK% \

	IF SECT%=10% THEN CLSSES%=CLSSES%+1% \

		CTEXT%(CLSSES%)=LINUSE% \

		CVAL%(CLSSES%)=OLDLOC%
02170	GOTO 2190 IF SECT%=5% \

	IF LOC%=-1% THEN

		LTEXT%(0%)=OLDLOC% IF SECT%=1% \

		STEXT%(X%)=LINUSE% FOR X%=OLDLOC% TO LTEXT%(0%) IF SECT%=2% \

		RTEXT%(0%)=OLDLOC% IF SECT%=6% \

		CTEXT%(0%)=CLSSES% IF SECT%=10% \

		MTEXT%(0%)=OLDLOC% IF SECT%=12% \

		GOTO 2040
02180	LINES$=LIN$ \

	OLDLOC%=LOC% \

	GOTO 2120
02190	X%=(OLDLOC%-OLDLOC%/100%*100%)*7%+OLDLOC%/100% \

	PTEXT%(KK%)=LINUSE% FOR KK%=X%-6% TO X%-OLDLOC%/100% \

	LINES$=LIN$ \

	IF LOC%>0% AND LOC%<100% THEN PTEXT%(KK%)=LINUSE%

		FOR KK%=(OLDLOC%-OLDLOC%/100%*100%)*7%+1% TO LOC%*7%-7% \

		OLDLOC%=LOC% \

		GOTO 2120
02200	OLDLOC%=OLDLOC%-OLDLOC%/100%*100%+100%+LOC% \

	IF LOC%=-1% THEN PTEXT%(0%)=OLDLOC%-99% \

		GOTO 2040
02210	INPUT LINE #2%, LIN$ \

	I%=INSTR(1%,LIN$,",") \

	LOC%=VAL(LEFT(LIN$,I%-1%)) \

	LIN$=RIGHT(LIN$,I%+1%) \

	IF OLDLOC%/100%*100%-100%=LOC% THEN LINES$=LINES$+LIN$ \

		GOTO 2210
02220	X%=(LEN(LINES$)+15%)/16% \

	LINES$(KK%+LINUSE%)=MID(LINES$,KK%*16%-15%,16%)

		FOR KK%=1% TO X% \

	LINUSE%=LINUSE%+X% \

	GOTO 2190
03000	! Section 3
03010	KEYW%(I%)=0% FOR I%=0% TO 150%
03020	MAT INPUT #2%, TK \

	LOC%=TK(1%) \

	NEWLOC=TK(2%) \

	IF LOC%=-1% THEN TRAVEL(0%)=TRVS% \

		GOTO 2040
03030	IF KEYW%(LOC%) THEN TRAVEL(TRVS%)=-TRAVEL(TRVS%) ELSE

	KEYW%(LOC%)=TRVS%+1%
03040	FOR L%=3% TO NUM \

		TRVS%=TRVS%+1% \

		TRAVEL(TRVS%)=NEWLOC*1000+TK(L%) \

	NEXT L% \

	TRAVEL(TRVS%)=-TRAVEL(TRVS%) \

	GOTO 3020
04000	! Section 4
04010	TABNDX%=1%
04020	INPUT #2%, KTAB%(TABNDX%), ATAB$(TABNDX%) \

	IF KTAB%(TABNDX%)=-1% THEN KTAB%(0%)=TABNDX% \

		GOTO 2040
04030	TABNDX%=TABNDX%+1% \

	GOTO 4020
05000	! Section 7
05010	PLAC%(I%), FIXD%(I%)=0% FOR I%=0% TO 100%
05020	TK(3%)=0% \

	MAT INPUT #2%, TK \

	OBJ%=TK(1%) \

	J%=TK(2%) \

	K%=TK(3%) \

	IF OBJ%=-1% THEN STEXT%(0%)=OLDOBJ% \

		GOTO 2040
05030	PLAC%(OBJ%)=J% \

	FIXD%(OBJ%)=K% \

	OLDOBJ%=OBJ% \

	GOTO 5020
06000	! Section 8
06010	ACTSPK%(I%)=0% FOR I%=0% TO 35%
06020	INPUT #2%, VERB%, J% \

	GOTO 2040 IF VERB%=-1% \

	ACTSPK%(VERB%)=J% \

	GOTO 6020
07000	! Section 9
07010	COND0%(I%)=0% FOR I%=0% TO 150%
07020	MAT INPUT #2%, TK \

	K%=TK(1%) \

	GOTO 2040 IF K%=-1% \

	FOR I%=2% TO NUM \

	LOC%=TK(I%) \

	DUM%=FNBUG%(8%) IF (COND0%(LOC%) AND 2%^K%)<>0% \

	COND0%(LOC%)=COND0%(LOC%)+2%^K% \

	NEXT I% \

	GOTO 7020
08000	! Section 11
08010	HINTS%(I%,X%)=0% FOR I%=0% TO 20% FOR X%=0% TO 4% \

	HNTMAX%=0%
08020	MAT INPUT #2%, TK \

	K%=TK(1%) \

	IF K%=-1% THEN

		HINTS%(0%,0%)=HNTMAX% \

		GOTO 2040
08030	HINTS%(K%,I%)=TK(I%+1%) FOR I%=1% TO 4% \

	HNTMAX%=K% IF K%>HNTMAX% \

	GOTO 8020
09000	! Section 0
09005	VERB%=0% \

	VERB%=VERB%+1% UNTIL KTAB%(VERB%)/1000%=3% \

	VERB%=KTAB%(VERB%-1%)-2000%
09010	PRINT "Table space used:"
09020	PRINT USING " ##### of 32767 words of messages",LINUSE%
09030	PRINT USING " ##### of ##### travel options",TRAVEL(0%),TRVSIZ%
09040	PRINT USING " ##### of ##### vocabulary words",KTAB%(0%),TABSIZ%
09050	PRINT USING " ##### of ##### locations",LTEXT%(0%),LOCSIZ%
09060	PRINT USING " ##### of ##### objects",STEXT%(0%),100%
09070	PRINT USING " ##### of ##### action verbs",VERB%,VRBSIZ%
09080	PRINT USING " ##### of ##### RTEXT messages",RTEXT%(0%),RTXSIZ%
09090	PRINT USING " ##### of ##### class messages",CTEXT%(0%),CLSMAX%
09100	PRINT USING " ##### of ##### hints",HINTS%(0%,0%),HNTSIZ%
09110	PRINT USING " ##### of ##### magic messages",MTEXT%(0%),MAGSIZ%
09120	HANDY$="BACKLOOKCAVENULLENTRDEPRKEYSLAMPGRATCAGEROD STEPBIRDDOOR"+

		"PILLSNAKFISSTABLCLAMOYSTMAGADWARKNIFFOODBOTTWATEOIL PLAN"+

		"AXE MIRRDRAGCHASTROLBEARMESSVENDBATTGOLDCOINCHESEGGSTRID"+

		"VASEEMERPYRAPEARRUG SPICCHAISAY LOCKTHROFINDINVE"
09130	HANDY%(X%)=FNVOCAB%(CVT$$(MID(HANDY$,X%*4%-3%,4%),-1%),(X%+36%)/43%)

		FOR X%=1% TO LEN(HANDY$)/4%
09140	DUM%=FNPOOF% \

	CLOSE 1%,2% \

	GOTO 1110
10000	!

	! Now start

	!

	! DFLAG is set to 1 when he reaches hall of mists, to 2 when he meets

	! a dwarf, to 3 when a knife is thrown, and to more than 3 if the

	! dwarves are mad (increases accuracy).  The pirate is dwarf #6.

	!
10010	DUM%=FNMOTD%(0%) \

	HINTED%(3%)=FNYES%(65%,1%,0%) \

	NEWLOC%=1% \

	SETUP%=3% \

	LIMIT%=330% \

	LIMIT%=1000% IF HINTED%(3%)
10020	GOTO 10030 IF NEWLOC%>8% OR NEWLOC%=0% OR NOT CLOSNG% \

	DUM%=FNRSPEAK%(130%) \

	NEWLOC%=LOC% \

	CLOCK2%=15% IF NOT PANIC% \

	PANIC%=-1%
10030	GOTO 10050 IF NEWLOC%=LOC% OR FNFORCED%(LOC%) OR FNBITSET%(LOC%,3%) \

	FOR I%=1% TO 5% \

		GOTO 10040 IF ODLOC%(I%)<>NEWLOC% OR NOT DSEEN%(I%) \

		NEWLOC%=LOC% \

		DUM%=FNRSPEAK%(2%) \

		GOTO 10050
10040	NEXT I%
10050	LOC%=NEWLOC% \

	GOTO 11000 IF LOC%=0% OR FNFORCED%(LOC%) OR FNBITSET%(NEWLOC%,3%) \

	GOTO 10100 IF DFLAG% \

	DFLAG%=1% IF LOC%>14% \

	GOTO 11000
10100	GOTO 10120 IF DFLAG%<>1% \

	GOTO 11000 IF LOC%<15% OR FNPCT%(95%) \

	DFLAG%=2% \

	FOR I%=1% TO 2% \

		J%=1%+5%*RND \

		DLOC%(J%)=0% IF FNPCT%(50%) AND SAVED%=-1% \

	NEXT I%
10110	FOR I%=1% TO 5% \

		DLOC%(I%)=DALTLC% IF DLOC%(I%)=LOC% \

		ODLOC%(I%)=DLOC%(I%) \

	NEXT I% \

	DUM%=FNRSPEAK%(3%) + FNDROP%(AXE%,LOC%) \

	GOTO 11000
10120	DTOTAL%, ATTACK%, STICK%=0% \

	FOR I%=1% TO 6% \

		GOTO 10220 IF DLOC%(I%)=0% \

		J%=1% \

		KK%=KEYW%(DLOC%(I%)) \

		GOTO 10150 IF KK%=0%
10130		NEWLOC%=FNMOD%(ABS(TRAVEL(KK%))/1000%,1000%) \

		GOTO 10140 IF NEWLOC%>300% OR NEWLOC%<15% OR NEWLOC%=ODLOC%(I%)

			OR J%>1% AND NEWLOC%=TK(J%-1%) OR J%>19% OR NEWLOC%=

			DLOC%(I%) OR ABS(TRAVEL(KK%))/1000000=100 \

		GOTO 10140 IF FNFORCED%(NEWLOC%) OR FNBITSET%(NEWLOC%,3%)

			AND I%=6% \

		TK(J%)=NEWLOC% \

		J%=J%+1%
10140		KK%=KK%+1% \

		GOTO 10130 IF TRAVEL(KK%-1%)>=0%
10150		TK(J%)=ODLOC%(I%) \

		J%=J%-1% IF J%>1% \

		J%=1%+J%*RND \

		ODLOC%(I%)=DLOC%(I%) \

		DLOC%(I%)=TK(J%) \

		DSEEN%(I%)=DSEEN%(I%) AND LOC%>14% OR (DLOC%(I%)=LOC% OR

			ODLOC%(I%)=LOC%) \

		GOTO 10220 IF NOT DSEEN%(I%) \

		DLOC%(I%)=LOC% \

		GOTO 10210 IF I%<>6% \

		GOTO 10220 IF LOC%=CHLOC% OR PROP%(CHEST%)>=0% \

		K%=0% \

		FOR J%=50% TO MAXTRS% \

			GOTO 10160 IF J%=PYRAM% AND (LOC%=PLAC%(PYRAM%) OR

				LOC%=PLAC%(EMRALD%)) \

			GOTO 10170 IF FNTOTING%(J%)
10160		K%=1% IF FNHERE%(J%) \

		NEXT J% \

		GOTO 10200 IF TALLY%=TALLY2%+1% AND PLACE%(CHEST%)=0% AND

			K%=0% AND FNHERE%(LAMP%) AND PROP%(LAMP%)=1% \

		DUM%=FNRSPEAK%(127%) IF ODLOC%(6%)<>DLOC%(6%) AND FNPCT%(20%) \

		GOTO 10220
10170		DUM%=FNRSPEAK%(128%) \

		DUM%=FNMOVE%(CHEST%,CHLOC%) IF PLACE%(MESSAG%)=0% \

		DUM%=FNMOVE%(MESSAG%,CHLOC2%) \

		FOR J%=50% TO MAXTRS% \

			GOTO 10180 IF J%=PYRAM% AND (LOC%=PLAC%(PYRAM%) OR

				LOC%=PLAC%(EMRALD%)) \

			DUM%=FNCARRY%(J%,LOC%) IF FNAT%(J%) AND FIXED%(J%)=0% \

			DUM%=FNDROP%(J%,CHLOC%) IF FNTOTING%(J%)
10180		NEXT J%
10190		DLOC%(6%), ODLOC%(6%)=CHLOC% \

		DSEEN%(6%)=0% \

		GOTO 10220
10200		DUM%=FNRSPEAK%(186%)+FNMOVE%(CHEST%,CHLOC%)+

			FNMOVE%(MESSAG%,CHLOC2%) \

		GOTO 10190
10210		DTOTAL%=DTOTAL%+1% \

		GOTO 10220 IF ODLOC%(I%)<>DLOC%(I%) \

		ATTACK%=ATTACK%+1% \

		KNFLOC%=LOC% IF KNFLOC%>=0% \

		STICK%=STICK%+1% IF 1000%*RND<95%*(DFLAG%-2%)
10220	NEXT I%
10500	! Dwarves have moved; tell about it
10510	GOTO 11000 IF DTOTAL%=0% \

	IF DTOTAL%=1% THEN DUM%=FNRSPEAK%(4%) ELSE

		PRINT "There are";DTOTAL%;"threatening little dwarves in ";

			"the room with you."
10520	GOTO 11000 IF ATTACK%=0% \

	DFLAG%=3% IF DFLAG%=2% \

	DFLAG%=20% IF SAVED%<>-1% \

	K%=52% \

	IF ATTACK%=1% THEN DUM%=FNRSPEAK%(5%) ELSE

		PRINT ATTACK%;"of them throw knives at you!" \

		K%=6%
10530	IF STICK%>1% THEN PRINT STICK%;"of them get you!" ELSE

		DUM%=FNRSPEAK%(K%+STICK%) \

		GOTO 11000 IF STICK%=0%
10540	OLDLC2%=LOC% \

	GOTO 14020
11000	DUM%=FNCHAIN%(11000%)
14020	DUM%=FNCHAIN%(14020%)
19000	!

	! Chain entries

	!
19020	DUM%=FNVARSET% \

	GOTO 10020
19100	! Magic mode
19110	DUM%=FNVARSET% + FNMAINT% + FNCHAIN%(11000%)
20000	!

	! Functions

	!

	! I/O functions (SPEAK, GETIN, YES)
20100	! Speak -- print message
20110	DEF FNSPEAK%(SUBSC%,LNGTH%) \

	IF SUBSC%>0% THEN IF LEFT(LINES$(SUBSC%-LNGTH%+1%),3%)<>">$<" THEN

		PRINT IF BLKLIN% \

		PRINT LINES$(F0%); FOR F0%=SUBSC%-LNGTH%+1% TO SUBSC%
20120	FNEND
20300	! Rspeak -- random messages
20310	DEF FNRSPEAK%(I%) \

	FDUM%=FNSPEAK%(RTEXT%(I%),RTEXT%(I%)+(RTEXT%(I%-1%)*(I%>1%)+

		PTEXT%(PTEXT%(0%)*7%)*(I%=1%))) IF I%>0% \

	FNEND
20400	! Mspeak -- magic messages
20410	DEF FNMSPEAK%(I%) \

	FDUM%=FNSPEAK%(MTEXT%(I%),MTEXT%(I%)+(MTEXT%(I%-1%)*(I%>1%)+

		CTEXT%(CTEXT%(0%))*(I%=1%))) IF I%>0% \

	FNEND
20500	! Getin -- input word(s)
20510	DEF FNGETIN% \

	INPUT #3%, IN$ \

	IN$=CVT$$(IN$,252%) \

	SPAC%=INSTR(1%,IN$+" "," ") \

	WD1$=LEFT(IN$,SPAC%-1%) \

	WD2$=RIGHT(IN$,SPAC%+1%) \

	FNEND
20600	! Yes -- Random question
20610	DEF FNYES%(X%,Y%,Z%) \

	FDUM%=FNRSPEAK%(X%) \

	ANSWER%=FNYESX% \

	FDUM%=FNRSPEAK%(Y%) IF ANSWER% \

	FDUM%=FNRSPEAK%(Z%) IF NOT ANSWER% \

	FNYES%=ANSWER% \

	FNEND
20700	! Yesm -- Magic question
20710	DEF FNYESM%(X%,Y%,Z%) \

	FDUM%=FNMSPEAK%(X%) \

	ANSWER%=FNYESX% \

	FDUM%=FNMSPEAK%(Y%) IF ANSWER% \

	FDUM%=FNMSPEAK%(Z%) IF NOT ANSWER% \

	FNYESM%=ANSWER% \

	FNEND
20800	! Yesx -- print and input for questions
20810	DEF FNYESX%
20820	FDUM%=FNGETIN% \

	IF LEFT(WD1$,1%)="Y" THEN FNYESX%=-1% ELSE

	IF LEFT(WD1$,1%)="N" THEN FNYESX%=0% ELSE

	PRINT "Please answer the question." \

		GOTO 20820
20830	FNEND
21000	!

	! Data structure functions (VOCAB, DSTROY, JUGGLE, MOVE,

	!				PUT, CARRY, DROP)
21100	! Vocab -- look up value for word (return -1 if not found)
21110	DEF FNVOCAB%(ID$,INIT%) \

	LNGTH%=LEN(ID$) \

	FOR I%=1% TO KTAB%(0%) \

		IF INIT%<0% OR KTAB%(I%)/1000%=INIT% THEN

			IF LEFT(ATAB$(I%),LNGTH%)=ID$ THEN

				FNVOCAB%=KTAB%(I%)+INIT%*1000%*(INIT%>=0%) \

				GOTO 21140
21130	NEXT I% \

	IF INIT%>=0% THEN FDUM%=FNBUG%(5%) ELSE FNVOCAB%=-1%
21140	FNEND
21400	! Move -- Pick up and drop object
21410	DEF FNMOVE%(OBJECT%,WHERE%) \

	IF OBJECT%>100% THEN FROM%=FIXED%(OBJECT%-100%) ELSE

		FROM%=PLACE%(OBJECT%)
21420	FDUM%=FNCARRY%(OBJECT%,FROM%) IF FROM%>0% AND FROM%<301% \

	FDUM%=FNDROP%(OBJECT%,WHERE%) \

	FNEND
21600	! Carry -- start toting object
21610	DEF FNCARRY%(OBJECT%,WHERE%) \

	IF OBJECT%<101% THEN

		GOTO 21660 IF PLACE%(OBJECT%)=-1% \

		PLACE%(OBJECT%)=-1% \

		HOLDNG%=HOLDNG%+1%
21620	IF ATLOC%(WHERE%)=OBJECT% THEN

		ATLOC%(WHERE%)=LINK%(OBJECT%) \

		GOTO 21660
21630	TEMP%=ATLOC%(WHERE%)
21640	IF LINK%(TEMP%)<>OBJECT% THEN

		TEMP%=LINK%(TEMP%) \

		GOTO 21640
21650	LINK%(TEMP%)=LINK%(OBJECT%)
21660	FNEND
21700	! Drop -- Place object at location
21710	DEF FNDROP%(OBJECT%,WHERE%) \

	IF OBJECT%>100% THEN FIXED%(OBJECT%-100%)=WHERE% ELSE

		HOLDNG%=HOLDNG%-1% IF PLACE%(OBJECT%)=-1% \

		PLACE%(OBJECT%)=WHERE%
21720	IF WHERE%>0% THEN

		LINK%(OBJECT%)=ATLOC%(WHERE%) \

		ATLOC%(WHERE%)=OBJECT%
21730	FNEND
22000	!

	! Wizardry functions (START, MAINT, WIZARD, HOURS, NEWHRS, MOTD, POOF)
22100	! Start -- Check for prime time or suspended game
22110	DEF FNSTART% \

	TIM%=FNDATIME% \

	PRIMTM=WKDAY(0%) \

	PRIMTM=WKEND(0%) IF FNWEEK.END% \

	PRIMTM=HOLID(0%) IF DAY%>=HBEGIN%(0%) AND DAY%<=HEND%(0%) \

	PTIME%=NOT FNSHIFT%(PRIMTM,TIM%/60%) \

	SOON%=0%
22120	IF OTHER%(26%)<0% THEN

		DELAY=(DAY%-OTHER%(14%))*1440%+(TIM%-OTHER%(20%)) \

		IF DELAY<LATNCY%(0%) THEN

			PRINT "This adventure was suspended a mere";

				DELAY;"minutes ago." \

			SOON%=-1% \

			IF DELAY<LATNCY%(0%)/3% THEN

				FDUM%=FNMSPEAK%(2%) \

				GOTO 32720
22130	START%=0% \

	GOTO 22160 IF SOON% \

	GOTO 22150 IF PTIME%
22140	SAVED%,OTHER%(14%)=-1% \

	GOTO 22180
22150	FDUM%=FNMSPEAK%(3%) + FNHOURS% + FNMSPEAK%(4%) \

	IF FNWIZARD% THEN 22140 ELSE

	IF OTHER%(26%)<0% THEN 22170 ELSE

	START%=FNYESM%(5%,7%,7%) \

	IF START% THEN 22140 ELSE KILL "ADVENT.ADV" \

		GOTO 32700
22160	FDUM%=FNMSPEAK%(8%) \

	GOTO 22140 IF FNWIZARD%
22170	FDUM%=FNMSPEAK%(9%) \

	GOTO 32720
22180	IF PTIME%=0% AND DAY%>=HBEGIN%(0%) AND DAY%<=HEND%(0%) THEN &
	PRINT &
	\PRINT "Today is a hoilday, namely ";HNAME$(0%) &
	\PRINT &

22182	FNSTART%=START% &
	\FNEND &

22200	! Maint -- Change various things if wizard
22210	DEF FNMAINT% \

	GOTO 22240 IF NOT FNWIZARD% \

	BLKLIN%=0% \

	FDUM%=FNHOURS% IF FNYESM%(10%,0%,0%) \

	FDUM%=FNNEWHRS% IF FNYESM%(11%,0%,0%) \

	IF FNYESM%(26%,0%,0%) THEN

		FDUM%=FNMSPEAK%(27%) \

		INPUT #3%, HBEGIN%(0%) \

		FDUM%=FNMSPEAK%(28%) \

		INPUT #3%, HEND%(0%) \

		TIM%=FNDATIME% \

		HBEGIN%(0%)=HBEGIN%(0%)+DAY% \

		HEND%(0%)=HBEGIN%(0%)+HEND%(0%)-1% \

		FDUM%=FNMSPEAK%(29%) \

		INPUT #3%, HNAME$(0%)
22220	PRINT "Length of short game (null to leave at ";

		NUM1$(SHORT%(0%));")? "; \

	INPUT #3%, X% \

	SHORT%(0%)=X% IF X%>0% \

	FDUM%=FNMSPEAK%(12%) \

	FDUM%=FNGETIN% \

	MAGIC$(0%)=WD1$ IF WD1$<>"" \

	FDUM%=FNMSPEAK%(13%) \

	INPUT #3%, X% \

	MAGNM%(0%)=X% IF X%>0%
22230	PRINT "Latency for restart (null to leave at ";

		NUM1$(LATNCY%(0%));")? "; \

	INPUT #3%, X% \

	FDUM%=FNMSPEAK%(30%) IF X%>0% AND X%<45% \

	X%=45% IF X%>0% AND X%<45% \

	LATNCY%(0%)=X% IF X%>0% \

	FDUM%=FNMOTD%(-1%) IF FNYESM%(14%,0%,0%) \

	OTHER%(14%)=0% \

	OTHER%(26%)=2% \

	KILL "ADVENT.ADV" \

	GOTO 32700
22240	FNEND
22300	! Wizard -- Verify if he's a wizard
22310	DEF FNWIZARD% \

	WIZARD%=FNYESM%(16%,0%,7%) \

	GOTO 22340 IF NOT WIZARD% \

	FDUM%=FNMSPEAK%(17%) + FNGETIN% \

	GOTO 22330 IF WD1$<>MAGIC$(0%)
22320	FDUM%=FNMSPEAK%(18%) + FNGETIN% \

	MGCNV$="" \

	MGCNV$=CHR$(ASCII(RIGHT(MAGIC$(0%),LEN(MAGIC$(0%))-F0%))-

		FNMOD%(MAGNM%(0%)/10^F0%,10%))+MGCNV$

			FOR F0%=0% TO LEN(MAGIC$(0%))-1% \

	IF MGCNV$=WD1$ THEN FDUM%=FNMSPEAK%(19%) \

		GOTO 22340
22330	FDUM%=FNMSPEAK%(20%) \

	WIZARD%=0%
22340	FNWIZARD%=WIZARD% \

	FNEND
22400	! Hours -- Print hours the cave is open and next holiday
22410	DEF FNHOURS% \

	FDUM%=FNHOURSX%(WKDAY(0%),"MON - FRI:")+

		FNHOURSX%(WKEND(0%),"SAT - SUN:")+

		FNHOURSX%(HOLID(0%),"Holidays:") + FNDATIME% \

	GOTO 22420 IF HEND%(0%)<DAY% OR HEND%(0%)<HBEGIN%(0%) \

	IF HBEGIN%(0%)<=DAY% THEN

		PRINT "Today is a holiday, namely ";HNAME$(0%) ELSE

		DAY%=HBEGIN%(0%)-DAY% \

		PRINT "The next holiday will be in";DAY%;"day";

			CHR$(115%*-(DAY%<>1%));", namely ";HNAME$(0%)
22420	FNEND
22500	! Hoursx -- used by hours
22510	DEF FNHOURSX%(H,DAY$) \

	FIRST%=-1% \

	FROM%=0% \

	IF H=0% THEN PRINT "          ";DAY$;" Open all day" \

		GOTO 22550
22520	FROM%=FROM%+1% UNTIL FNSHIFT%(H,FROM%) \

	GOTO 22530 IF FROM%>23% AND FIRST% \

	GOTO 22550 IF FROM%>23% \

	TILL%=FROM% \

	TILL%=TILL%+1% UNTIL NOT FNSHIFT%(H,TILL%) OR TILL%>23% \

	PRINT USING "          \        \ ##:00 TO ##:00",

		DAY$,FROM%,TILL% IF FIRST% \

	PRINT USING "                     ##:00 TO ##:00",

		FROM%,TILL% IF NOT FIRST% \

	FIRST%=0% \

	FROM%=TILL% \

	GOTO 22550 IF TILL%>23% \

	GOTO 22520
22530	PRINT "          ";DAY$;" Closed all day"
22550	FNEND
22600	! Newhrs -- Change cave hours
22610	DEF FNNEWHRS% \

	FDUM%=FNMSPEAK%(21%) \

	WKDAY(0%)=FNNEWHRX("Weekdays:") \

	WKEND(0%)=FNNEWHRX("Weekends:") \

	HOLID(0%)=FNNEWHRX("Holidays:") \

	FDUM%=FNMSPEAK%(22%) + FNHOURS% \

	FNEND
22700	! Newhrx -- used by newhrs
22710	DEF FNNEWHRX(DAY$) \

	NEWHRX=0% \

	PRINT "Prime time on ";DAY$ \

	INPUT #3%, "From: ";FROM% \

	GOTO 22720 IF FROM%<0% OR FROM%>23% \

	INPUT #3%, "Till: ";TILL% \

	IF TILL%>0% AND TILL%<25% THEN

		NEWHRX=NEWHRX+2^I% FOR I%=FROM% TO TILL%-1%
22720	FNNEWHRX=NEWHRX \

	FNEND
22800	! Motd -- Message of the day
22810	DEF FNMOTD%(ALTER%) \

	MOTD$="" \

	IF ALTER% THEN FDUM%=FNMSPEAK%(23%) ELSE

		FDUM%=FNSPEAK%(MTEXT%(MTEXT%(0%))+MSG%(1%),MSG%(1%)) \

		GOTO 22830
22820	INPUT LINE #3%, LIN$ \

	MOTD$=MOTD$+LIN$ \

	GOTO 22820 IF LEN(LIN$)>2% \

	F0%=(LEN(MOTD$)+15%)/16% \

	LINES$(F1%+MTEXT%(MTEXT%(0%)))=MID(MOTD$,F1%*16%-15%,16%)

		FOR F1%=1% TO F0% \

	MSG%(1%)=F0%
22830	FNEND
22900	! Poof -- start up for database initialization
22910	DEF FNPOOF% \

	WKDAY(0%)=32512 \

	WKEND(0%), HOLID(0%), HBEGIN%(0%), MSG%(1%)=0% \

	HEND%(0%)=-1% \

	SHORT%(0%)=30% \

	MAGIC$(0%)="DWARF" \

	MAGNM%(0%)=11111% \

	LATNCY%(0%)=90% \

	MSG%(0%)=LINUSE%+1% \

	FNEND
23000	!

	! Utility functions (SHIFT, DATIME, CIAO, BUG)
23100	! Shift -- check if bit is set (for hours)
23110	DEF FNSHIFT%(VALUE,BIT%) \

	FDUM=INT(VALUE/2^BIT%) \

	FNSHIFT%=-1-INT(VALUE/2^(BIT%+1%))*2%+FDUM \

	FNEND
23200	! Datime -- get date and time
23210	DEF FNDATIME% \

	D0$=DATE$(0%) \

	MON%=INSTR(1%,"  JanFebMarAprMayJunJulAugSepOctNovDec",

		MID(D0$,4%,3%))/3% \

	YEAR%=VAL(RIGHT(D0$,8%))-77% \

	DAY%=-(YEAR%=(YEAR%+1%)/4%*4%-1% AND MON%>2%) \

	DAY%=DAY%+HATH%(I%) FOR I%=1% TO MON%-1% \

	DAY%=DAY%+VAL(LEFT(D0$,2%)) \

	DAY%=DAY%+YEAR%*365%+YEAR%/4%
23220	FNDATIME%=TIME(0%)/60% \

	FNEND
23230	! FNWEEK.END%=-1% IF IT IS SATURDAY OR SUNDAY &
	 DEF FNWEEK.END% &
	\WEEK.1%=SWAP%(CVT$%(RIGHT(SYS(CHR$(6%)+CHR$(-3%)),27%))) &
	\WEEK.2%=WEEK.1%/1000% &
	\WEEK.3%=WEEK.1%-WEEK.2%*1000% &
	\WEEK.3%=(WEEK.2%-7%)/4%+(365%*(WEEK.2%-8%))+WEEK.3% &
	\WEEK.3%=WEEK.3%-(WEEK.3%/7%*7%) &
	\FNWEEK.END%=(WEEK.3%<2%) &
	\FNEND &

23300	! Ciao -- get out
23310	DEF FNCIAO% \

	DUM%=FNSETVAR% \

	GOTO 32700 \

	FNEND
23400	! Bug -- fatal errors

	!  3	Too many travel options

	!  4	Too many vocabulary words

	!  5	Can't find required vocabulary word

	!  6	Too many RTEXT or MTEXT messages

	!  7	Too many hints

	!  8	Location has COND bit being set twice

	!  9	Invalid section number in database

	! 10	Who knows
23410	DEF FNBUG%(NUMB%) \

	PRINT "Fatal error";NUMB%; \

	PRINT "(";NUM1$(ERR);",";NUM1$(ERL);")"; IF NUMB%=10% \

	PRINT \

	KILL LDN$+"ADVENT.DAT" IF NUMB%<10% \

	GOTO 32700 \

	FNEND
24000	!

	! Other functions (TOTING, HERE, AT, LIQ2, LIQ, LIQLOC,

	!			BITSET, FORCED, DARK, PCT)
24100	! Toting -- True if object is being carried
24110	DEF FNTOTING%(OBJ%)=PLACE%(OBJ%)=-1%
24200	! Here -- Ture if object is at same location
24210	DEF FNHERE%(OBJ%)=PLACE%(OBJ%)=LOC% OR FNTOTING%(OBJ%)
24300	! At -- True if on either side of two-placed object
24310	DEF FNAT%(OBJ%)=PLACE%(OBJ%)=LOC% OR FIXED%(OBJ%)=LOC%
24600	! Bitset -- True if COND bit is set
24610	DEF FNBITSET%(L%,N%)=(COND%(L%) AND 2%^N%)<>0%
24700	! Forced -- True if location moves without input
24710	DEF FNFORCED%(LOC%)=COND%(LOC%)=2%
24800	! Dark -- True if it's dark
24810	DEF FNDARK% \

	FNDARK%=COND%(LOC%)-COND%(LOC%)/2%*2%=0% AND (PROP%(LAMP%)=0%

		OR NOT FNHERE%(LAMP%)) \

	FNEND
24900	! Pct -- True N% of the time
24910	DEF FNPCT%(N%)=100%*RND<N%
25000	!

	! Additional functions (MOD, CHAIN, VARSET)
25100	! Mod (not reserved in BASIC-PLUS)
25110	DEF FNMOD%(VALUE,CHOP%)=VALUE-INT(VALUE/CHOP%)*CHOP%
25200	! Chain between ADVENT and ADVNTR.  This is not too efficient, but

	! unfortunately there's no way to fit it all in 16K.
25210	DEF FNCHAIN%(LIN%) \

	DUM%=FNSETVAR% \

	CHAIN LDN$+"ADVNTR" LIN%/100%+19000% \

	FNEND
25300	! Varset -- reset variables after chain
25310	DEF FNVARSET% \

	LDN$="GAME:" \

	RANDOMIZE \

	FDUM%=1%*RND \

	ON ERROR GOTO 32000
25315	OPEN LDN$+"ADVENT.DAT" FOR INPUT AS FILE 1% \

	OPEN "ADVENT.ADV" FOR INPUT AS FILE 4% \

	OPEN "KB:" AS FILE 3% \

	RESTORE \

	MAT READ HATH%
25320	LAMP%=HANDY%(8%) \

	AXE%=HANDY%(29%) \

	MESSAG%=HANDY%(35%)
25330	CHEST%=HANDY%(40%) \

	EMRALD%=HANDY%(44%) \

	PYRAM%=HANDY%(45%)
25360	CHLOC%=OTHER%(0%) \

	CHLOC2%=OTHER%(1%) \

	DFLAG%=OTHER%(2%) \

	DALTLC%=OTHER%(3%) \

	KNFLOC%=OTHER%(7%) \

	SAVED%=OTHER%(14%) \

	PANIC%=OTHER%(16%)
25370	CLOCK2%=OTHER%(23%) \

	TALLY%=OTHER%(24%) \

	TALLY2%=OTHER%(25%) \

	SETUP%=OTHER%(26%) \

	LOC%=OTHER%(28%) \

	OLDLOC%=OTHER%(29%) \

	OLDLC2%=OTHER%(30%) \

	NEWLOC%=OTHER%(31%) \

	LIMIT%=OTHER%(32%) \

	BLKLIN%=OTHER%(33%)
25380	MAXTRS%=64%
25390	FNEND
25400	! Setvar -- set variables for chain
25410	DEF FNSETVAR%
25420	OTHER%(2%)=DFLAG% \

	OTHER%(7%)=KNFLOC% \

	OTHER%(14%)=SAVED% \

	OTHER%(16%)=PANIC%
25430	OTHER%(23%)=CLOCK2% \

	OTHER%(26%)=SETUP% \

	OTHER%(28%)=LOC% \

	OTHER%(30%)=OLDLC2% \

	OTHER%(31%)=NEWLOC% \

	OTHER%(32%)=LIMIT% \

	OTHER%(33%)=BLKLIN%
25440	CLOSE 1%,4% \

	FNEND
31000	!

	! Data

	!
31100	! Date
31110	DATA 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
32000	!

	! Error routine

	!
32010	IF ERR=5% AND ERL=1110% THEN RESUME 2000
32020	IF ERR=5% AND ERL=2010% OR ERR=10% THEN

		PRINT "Sorry, no adventures now." \

		RESUME 32700
32030	IF ERR=5% AND ERL=1130% THEN RESUME 1500
32040	IF ERR=5% AND ERL=1510% THEN RESUME 1200
32050	IF ERR=58% AND ERL=2040% THEN DUM%=FNBUG%(9%)
32060	IF ERR=55% THEN

		IF ERL=2150% THEN DUM%=FNBUG%(6%) ELSE

		IF ERL=3040% THEN DUM%=FNBUG%(3%) ELSE

		IF ERL=4020% THEN DUM%=FNBUG%(4%) ELSE

		IF ERL=8030% THEN DUM%=FNBUG%(7%)
32070	DUM%=FNBUG%(10%)
32700	! Finish up
32710	CLOSE 1%,2%,3%,4%
32720	END
