1020 !************************************************************ & ! & ! * M O N S T A * & ! Action-packed adventure game & ! & ! By Mark Buxbaum & John S. Montrym & ! & ! Amended by Mark Bramhall 16-Dec-1981 & ! Modified by Dan O'Reilly 1-Apr-1983 & ! & !************************************************************ & 1040 !--------------------------------------------------------- & ! & ! Keyboard keys: & ! & ! 8 Up & ! 2/5 Down & ! 4 Left & ! 6 Right & ! 0 Drop bomb & ! ^W Refresh display & ! & !---------------------------------------------------------- & ! & ! Present values of A%(X%,Y%) and their meanings: & ! & ! -2 Printed wall & ! -1 Unprinted wall & ! 0 Empty square & ! 1 Monsta & ! 2 Human & ! 3 Footprint (place where human has been) & ! 4 Target & ! 5 Printed randomizer & ! 6 Unprinted randomizer & ! 7 UNUSED & ! 8 Club 1060 ! 9 Inactive bomb & ! 10 Active bomb & ! & !--------------------------------------------------------- & ! & ! PR.TYPE - GLOBAL current status of print attributes: & ! & ! Bit Meaning (when set) & ! 0 Bold & ! 1 Underline & ! 2 Blinking & ! 3 Reverse background & ! & ! & !--------------------------------------------------------- & 1080 RANDOMIZE 1100 OPEN "TI:" AS FILE #2% ! For setting up the game parameters 1110 OPEN "TI:" AS FILE #1% ! For getting game moves 1115 CALL GETCHR ! Attach lun 1 for unsolicited input 1120 ON ERROR GOTO 19000 1140 Q% = NOECHO(1%) ! Disable echo 1150 Q% = NOECHO(2%) ! Disable echo on this channel too 1180 WAIT 0% ! Make sure no keyboard wait enabled 1200 N.RAND% = INT(RND*15%) + 11% & \ N.CLUB% = INT(RND*5%) + 3% & \ N.BOMB% = INT(RND*4%) + 3% & \ FIRST.TIME% = -1% 1220 !--------FNS$, FNLINE$ CONSTANTS----------------------------- 1240 CTRLW% = -1% ! Prints printed; doesn't print unprinted & \ CTRLY% = 1% ! Prints printed and unprinted & \ CHASE% = 0% ! Prints unprinted; doesn't print printed 1260 !--------ESCAPE SEQUENCE CONSTANTS--------------------------- 1280 E$ = CHR$(155%) \ CHEAT$ = CHR$(25%) 1300 CSI$ = E$ + "[" & \ ANSI$ = E$ + "<" & \ KEYPAD.OFF$ = E$ + ">" & \ BELL$ = CHR$(7%) & \ SCREEN.BK.BLACK$ = CSI$ + "?5l" & \ SCREEN.BK.WHITE$ = CSI$ + "?5h" & \ W132$ = CSI$ + "?3h" & \ W80$ = CSI$ + "?3l" & \ GR.MODE$ = CHR$(142%) ! Shift out - G1 set. & \ TX.MODE$ = CHR$(143%) ! Shift in - G0 set. & \ INIT.GR.MODE$ = E$ + ")0" ! Set G1 set to special graphics characters. & \ SET.TAB$ = E$ + "H" & \ CLR.TABS$ = CSI$ + "3g" & \ CLS$ = CSI$ + "2J" & \ DOUBLE.WIDTH$ = E$ + "#6" 1320 K.DROP$ = "0" & \ KEY.STROKES$ = "62485" & ! Position in KEY.STROKES$ - UP = 4, DOWN = 2/5, LEFT = 3, RIGHT = 1 1340 !------ TEXT MESSAGE CONSTANTS --------------------------------------- 1360 BOING$(0%) = " B O I N G ! " & \ BOING$(1%) = " S P R O I N G ! " & \ BOING$(2%) = " O O P S ! " & \ BOING$(3%) = " Z A P " & \ BOING$(4%) = " W H O O P S ! " 1380 SURPR$(0%) = " S U R P R I S E ! " & \ SURPR$(1%) = " H A ! ! " & \ SURPR$(2%) = " U H O H ! ! " 1400 LEVELS$(1%) = TX.MODE$ + "Novice " + GR.MODE$ & \ LEVELS$(2%) = TX.MODE$ + "Beginner " + GR.MODE$ & \ LEVELS$(3%) = TX.MODE$ + "Expert " + GR.MODE$ & \ LEVELS$(4%) = TX.MODE$ + "Superman " + GR.MODE$ & \ LEVELS$(5%) = " W O W ! " & \ LEVELS$(6%) = TX.MODE$ + "Impossible" + GR.MODE$ 1420 CRATER$(0%) = " " & \ CRATER$(1%) = "f" & \ CRATER$(2%) = TX.MODE$ + "o" + GR.MODE$ & \ CRATER$(3%) = " " & \ CRATER$(4%) = TX.MODE$ + "x" + GR.MODE$ 1440 RATS$(0%) = "RATS" & \ RATS$(1%) = "DAMN" & \ RATS$(2%) = "HELL" & \ RATS$(3%) = "SHIT" & \ RATS$(4%) = "DARN" & \ RATS$(5%) = "TURD" 1460 ANGER$(0%) = "(I THINK HE'S UPSET) " & \ ANGER$(1%) = "AW, GIVE HIM A BREAK " & \ ANGER$(2%) = "NOW HE'S REALLY MAD " & \ ANGER$(3%) = " WHAT IS THIS ? ! ? " & \ ANGER$(4%) = " YOU'RE A MANIAC! " & \ ANGER$(5%) = " YOU MONSTA HATER! " & \ MAX.ANGER.COUNT% = 5% 1480 READ XMULT.PROB(I%), & XWAIT.TIME(I%), & XMAX.MONSTA.MOVES%(I%), & XFAST.RAND(I%) FOR I% = 1% TO 6% 1500 DATA .13, 3, 2, 0 1520 DATA .33, 2, 4, 0 1540 DATA .33, 1, 6, 0 1560 DATA .45, 1, 8, 0 1580 DATA 0, 0,99, .4 1600 DATA .80, 0,99, 1 & & & 1620 DIM A%(24%,66%),DIR$(23%),PT$(15%) 1640 READ PT$(I%) FOR I% = 0% TO 15% 1660 DATA '', '1', '4', '4;1', '5', '5;1', '5;4', '5;4;1' 1680 DATA '7','7;1','7;4','7;4;1','7;5','7;5;1','7;5;4','7;5;4;1' 1700 PR.TYPE% = 15% & \ PRINT #2%, ANSI$ + INIT.GR.MODE$ + ! ANSI mode, set G1 graphics & TX.MODE$ + & FNPR.TYPE$(0%) + ! Initialize attributes. & KEYPAD.OFF$ + ! Disable the keypad & CLS$ + CLR.TABS$; ! Clear screen, clear tabs 1720 PRINT #2%, FNM$(5%,10%) + E$ + "#3" + "Welcome to MONSTA" & \ PRINT #2%, FNM$(6%,10%) + E$ + "#4" + "Welcome to MONSTA"; & \ PRINT #2%, FNM$(1%,I%) + SET.TAB$; FOR I% = 1% TO 65% STEP 8% & \ PRINT #2%, FNM$(1%,1%); 1740 FOR I% = 0% TO 23% & \ READ D$ & \ DIR$(I%) = "" & \ DIR$(I%) = DIR$(I%) + CHR$(VAL(MID(D$, J%, 1%))) & FOR J% = 1% TO 4% & \ NEXT I% 1760 DATA '1234','1243','1324','1342','1423','1432' 1780 DATA '2134','2143','2314','2341','2413','2431' 1800 DATA '3124','3142','3214','3241','3412','3421' 1820 DATA '4123','4132','4213','4231','4312','4321' 1840 READ M1%(I%),N1%(I%),M2%(I%),N2%(I%) FOR I% = 1% TO 4% 1860 DATA 0,1,0,2,1,0,2,0,0,-1,0,-2,-1,0,-2,0 1880 A%(X%,Y%) = -1% FOR X% = 0% TO 24% FOR Y% = 0% TO 66% & \ A%(X%,Y%) = 0% FOR X% = 2% TO 22% STEP 2% FOR Y% = 2% TO 64% STEP 2% 1900 !---------------------SET UP MAZE---------------------------- 1920 X% = 2*INT(11*RND+1) \ X1% = X% & \ Y% = 2*INT(32*RND+1) \ Y1% = Y% & \ A%(X%,Y%) = -9% & \ V% = 1% & \ MAX% = 20% & \ FOO% = 1% & ! Select a random start point. The target will go here. & 1940 C% = 1% & 1960 D$ = DIR$(INT(RND*24%)) \ D% = ASCII(D$) & 1980 VX% = X% + M2%(D%) \ VY% = Y% + N2%(D%) & \ GOTO 2060 IF A%(VX%, VY%) <> 0% & ! If we've been here before, try another direction. & 2000 V% = V% + 1% & \ A%(VX%,VY%) = V% & \ FOO% = FOO% + 1% & \ A%(X%+M1%(D%),Y%+N1%(D%)) = 0% & \ C% = 1% & \ X% = VX% & \ Y% = VY% & ! Break another wall down & record our having been here. & 2020 IF V% > MAX% THEN MAX% = V% & \ X9% = X% & \ Y9% = Y% & ! Record maximum distance from start. The human will start here. & 2040 GOTO 1960 & 2060 IF C% < 4% THEN & C% = C% + 1% & \ D% = ASCII(MID(D$,C%,1%)) & \ GOTO 1980 & ! If we haven't tried all directions, try next one. & 2080 GOTO 2120 IF FOO% >= 352% ! Drop out when full & \ V% = V% - 1% & \ FOR I% = 1% TO 4% & \ VX% = X% + M2%(I%) \ VY% = Y% + N2%(I%) ! Watch out - PDP8.. & \ GOTO 2100 IF A%(VX%,VY%) = V% & \ NEXT I% & \ GOTO 32767 & 2100 X% = VX% \ Y% = VY% & \ GOTO 1940 & ! Back out one step - try again. & 2120 !----------------FILL MAZE WITH JUNK------------------------- 2140 A%(X%,Y%) = 0% IF A%(X%,Y%) <> -1% FOR X% = 2% TO 22% FOR Y% = 2% TO 64% & \ A%(X%,65%), A%(X%,1%) = -2% FOR X% = 1% TO 23% & \ A%(23%,Y%), A%(1%,Y%) = -2% FOR Y% = 2% TO 64% 2160 !----------------SET UP HUMAN, TARGET------------------------ 2180 A%(X1%,Y1%) = 4% & \ A%(X9%,Y9%) = 2% & \ HUMAN.SAV% = 3% ! First time he moves leave a footprint. 2200 !----------------SET UP RANDOMIZERS-------------------------- 2220 FOR I% = 1% TO N.RAND% & \ R0% = INT(RND*2%) 2240 X% = 2% * INT(11%*RND+1%) - R0% + 1% \ Y% = 2% * INT(32%*RND+1%) - R0% 2260 IF Y% <> 1% AND X% <> 23% AND A%(X%,Y%) = -1% & THEN A%(X%,Y%) = 6% & ELSE GOTO 2240 2280 NEXT I% 2300 !----------------SET UP CLUBS-------------------------------- 2320 FOR I% = 1% TO N.CLUB% 2340 X% = 2 * INT(11*RND+1) \ Y% = 2 * INT(32*RND+1) & \ IF A%(X%,Y%) = 0% THEN A%(X%,Y%) = 8% ELSE 2340 2360 NEXT I% 2380 !----------------SET UP BOMBS-------------------------------- 2400 FOR I% = 1% TO N.BOMB% 2420 X% = 2 * INT(11*RND+1) \ Y% = 2 * INT(32*RND+1) & \ IF A%(X%,Y%) = 0% THEN A%(X%,Y%) = 9% ELSE 2420 2440 NEXT I% 2460 !----------------SET UP MONSTA------------------------------- 2480 GOSUB 10800 ! Randomly place MONSTA 2500 !----- GET DIFFICULTY LEVEL --------------------------------- 2520 LEVEL.DIFF$ = " " & \ START.TIME = TIME(0) & \ TIME.OUT = 0 & \ GOSUB 10000 ! Print board 2540 PRINT #2%, FNM$(23%,1%) + & FNPR.TYPE$(8%) + & TX.MODE$ + & " Enter difficulty level :" + & SPACE$(18%) + & FNM$(23%,26%) + & GR.MODE$; & \ COL.SAV% = 26% 2560 A$ = FNGET.INPUT$(0%,0%) ! Get some input w/ stall 2580 Q$ = LEFT(A$,1%) \ A$="" ! Only want 1st char 2590 GOTO 2560 IF Q$="" ! Nothing entered 2600 GOTO 32767 IF Q$ = CHR$(3%) ! Trap ^C. 2620 IF Q$ = CHR$(13%) AND LEVEL.DIFF$ <> "" THEN GOTO 7000 ! START. 2640 GOTO 2500 IF Q$ = CHR$(23%) ! ^W 2660 Q$ = EDIT$(Q$,32%) ! Convert to uppercase. & \ IF Q$ = CHR$(21%) OR Q$ = CHR$(127%) THEN & PRINT #2%, FNM$(23%, COL.SAV%)+SPACE$(10%)+FNM$(23%,COL.SAV%); & \ LEVEL.DIFF$ = "" & \ GOTO 2560 2680 LEVEL.DIFF% = INSTR(1%,"NBESWI", Q$) 2700 IF LEVEL.DIFF% <> 0% & THEN MULT.PROB = XMULT.PROB(LEVEL.DIFF%) & \ WAIT.TIME = XWAIT.TIME(LEVEL.DIFF%) & \ MAX.MONSTA.MOVES% = XMAX.MONSTA.MOVES%(LEVEL.DIFF%) & \ FAST.RAND = XFAST.RAND(LEVEL.DIFF%) & \ LEVEL.DIFF$ = LEVELS$(LEVEL.DIFF%) & \ PRINT #2%, FNM$(23%,COL.SAV%) + LEVEL.DIFF$; & \ GOTO 2560 2720 CHEAT$ = Q$ IF CHEAT$ = CHR$(-1%) AND Q$ < CHR$(32%) & \ PRINT #2%, FNM$(23%,1%) + & TX.MODE$ + & "Levels: Novice Beginner Expert Superman Wow Impossible: " + & GR.MODE$ + & FNM$(23%,56%); & \ COL.SAV% = 56% & \ LEVEL.DIFF$ = "" & \ GOTO 2560 7000 !---------------START OF GAME--------------------------------- 7020 PRINT #2%, FNM$(23%,1%) + SPACE$(65%); & \ MONSTA.TIME.SAV = 0 & \ STATUS.TIME.SAV = 0 & \ START.TIME = TIME(0) & \ TIME.OUT = 0 7040 !---------------CONTINUOUS PROCESSING------------------------------ 7060 GOTO 7260 IF TIME(0) < MONSTA.TIME.SAV + WAIT.TIME & ! Only make moves at specified intervals. 7080 MONSTA.TIME.SAV = TIME(0) & \ GOTO 7260 IF WAIT.TIME = 0 AND RND > FAST.RAND & ! Rapid move only some of the time. Otherwise go show the status line 7100 MOVE.CNT% = 0% 7120 PRINT #2%, FNS$(XM%, YM%, MONSTA.SAV%, CTRLY%); & \ DLX% = X9% - XM% \ DLY% = Y9% - YM% 7140 IF DLX% >= 0% THEN IF DLX% = 0% THEN UD% = 0% & ELSE UD% = 2% & ELSE UD% = 4% & 7160 IF DLY% >= 0% THEN IF DLY% = 0% THEN LR% = 0% & ELSE LR% = 1% & ELSE LR% = 3% & ! Choose between Up vs. down & left vs. right. & 7180 GO TO 7220 IF LR% = 0% OR UD% = 0% & \ L1% = FNWALLP%(A%(XM%+M1%(UD%),YM%)) & \ L2% = FNWALLP%(A%(XM%,YM%+N1%(LR%))) & \ IF L1% XOR L2% THEN UD% = 0% IF L1% & \ LR% = 0% IF L2% & \ GOTO 7220 & ! If only one open path, take it & 7200 IF ABS(DLX%) < ABS(DLY%) & THEN UD% = 0% & ELSE IF ABS(DLX%) <> ABS(DLY%) & THEN LR% = 0% & ELSE IF RND > .5 THEN LR% = 0% & ELSE UD% = 0% & ! If one axis longer, take it, otherwise take random & 7220 XM% = XM% + M1%(UD%+LR%) ! One or the other of UD% & LR% = 0% & \ YM% = YM% + N1%(UD%+LR%) & \ MONSTA.SAV% = A%(XM%,YM%) & \ GOSUB 10580 IF MONSTA.SAV% = 10% ! Activated bomb. & \ GOTO 7240 IF XM% <> X9% OR YM% <> Y9% ! MONSTA hits human. & \ GOTO 10740 IF C.CLUB% < 1% ! SCHLOORP if human has no clubs & \ C.CLUB% = C.CLUB% - 1% \ GOSUB 10840 ! Ouch otherwise & \ GOSUB 10800 ! Randomize MONSTA 7240 PRINT #2%, FNS$(XM%,YM%,1%, CHASE%); & \ MOVE.CNT% = MOVE.CNT% + 1% ! Bump MONSTA move counter. & \ GOTO 7120 IF RND < MULT.PROB & UNLESS (FIRST.TIME% OR MOVE.CNT% >= MAX.MONSTA.MOVES%) & ! Multiple moves after FIRST.TIME% zeroed. 7260 !-------------------STATUS LINE----------------------------------- 7280 GOSUB 10120 IF TIME(0) >= STATUS.TIME.SAV + 1 & ! Status line every second. 7300 !-------------------KEYBOARD POLL------------------------------ 7320 CALL INCHR BY REF (ACHAR%) 7325 IF ACHAR% <> 0% THEN GOTO 7380 ! Human is trying to move 7330 IF WAIT.TIME <> 0 THEN SLEEP 1% ! Rest for a second? 7335 GOTO 7040 ! Go make a monsta move 7360 !---------------HUMAN MOVES---------------------------------------- 7380 Q$ = CHR$(ACHAR%) & \ ACHAR% = 0% ! Zero out our character & \ DIR% = INSTR(1%,KEY.STROKES$,Q$) & \ DIR% = 2% IF DIR% = 5% & \ GOTO 7420 IF DIR% <> 0% & \ GOSUB 10060 IF Q$ = CHR$(25%) ! ^Y & \ GOSUB 10000 IF Q$ = CHR$(23%) ! ^W & \ GOTO 32767 IF Q$ = CHR$(3%) ! ^C & \ IF Q$ = K.DROP$ THEN & IF C.BOMB% THEN & C.BOMB% = C.BOMB% - 1% & UNLESS HUMAN.SAV% = 10% & \ HUMAN.SAV% = 10% & \ PRINT #2%, FNMESSAG$(" ... CAREFUL ..."); & \ GOTO 7600 7400 GOTO 7600 ! Unrecognized key. 7420 XD1% = M1%(DIR%) & \ YD1% = N1%(DIR%) & \ M0%(1%) = X9% + FNC%(XD1%) & \ N0%(1%) = Y9% + FNC%(YD1%) & \ M0%(2%) = X9% + XD1% & \ N0%(2%) = Y9% + YD1% & \ M0%(3%) = X9% - FNC%(-XD1%) & \ N0%(3%) = Y9% - FNC%(-YD1%) & \ IF XM% = M0%(2%) AND YM% = N0%(2%) & THEN NEXT.SQUARE% = MONSTA.SAV% & ELSE NEXT.SQUARE% = A%(M0%(2%),N0%(2%)) 7440 IF NEXT.SQUARE% < 0% ! Bump a wall & THEN PRINT #2%, FNS$(M0%(I%),N0%(I%),A%(M0%(I%),N0%(I%)),CHASE%); & FOR I% = 1% TO 3% & \ GOTO 7600 & 7460 VX9% = X9% + M2%(DIR%) \ VY9% = Y9% + N2%(DIR%) & \ GOTO 7500 IF A%(VX9%,VY9%) = 1% ! Go handle MONSTA & \ GOTO 7540 IF NEXT.SQUARE% = 5% OR ! Go handle randomizer & NEXT.SQUARE% = 6% & \ PRINT #2%, FNS$(X9%,Y9%,HUMAN.SAV%,CHASE%); & \ HUMAN.SAV% = 3% ! Human will move - replace what he was standing on & \ IF M0%(2%) = XM% AND N0%(2%) = YM% THEN MONSTA.SAV% = 3% & ELSE PRINT #2%, FNS$(M0%(2%),N0%(2%),HUMAN.SAV%,CHASE%); & 7480 X9% = VX9% \ Y9% = VY9% & \ GOSUB 10480 ! Common human moves code. & \ GOTO 7600 7500 !-----------------BUMP INTO MONSTA-------------------- 7510 GOTO 10620 IF MONSTA.SAV% = 4% ! Target under MONSTA. 7520 GOTO 10740 UNLESS C.CLUB% ! SCHLOORP if human has no clubs & \ C.CLUB% = C.CLUB% - 1% & \ MONSTA.SAV% = 2% & \ PRINT #2%, FNS$(X9%,Y9%,HUMAN.SAV%,CHASE%); & \ X9% = VX9% \ Y9% = VY9% ! Move human to new spot. & \ GOSUB 10840 ! Ouch & \ PRINT #2%, FNS$(XM%,YM%,MONSTA.SAV%,CTRLY%); & \ GOSUB 10800 ! Randomize MONSTA & \ GOSUB 10580 IF MONSTA.SAV% = 10% ! Handle MONSTA lands on bomb & \ PRINT #2%, FNS$(XM%,YM%,1%,CHASE%); & \ GOTO 7600 7540 !-----------------HUMAN GETS RANDOMIZED---------------- 7560 PRINT #2%, FNS$(M0%(I%),N0%(I%),A%(M0%(I%),N0%(I%)),CHASE%); & FOR I% = 1% TO 3% & \ PRINT #2%, FNS$(X9%,Y9%,HUMAN.SAV%,CHASE%); & \ HUMAN.SAV% = 3% & \ MULT.PROB = MULT.PROB + .0008 7580 X9% = 2*INT(11*RND+1) \ Y9% = 2*INT(32*RND+1) & \ GOTO 7580 IF ABS(YM%-Y9%) < 3% OR ABS(XM% - X9%) < 3% & \ GOSUB 10480 ! Common human moves code. & \ PRINT #2%, BELL$; IF NEXT.SQUARE% = 6% ! Bell if newly shown & \ GOSUB 10880 ! Boing message. & \ GOTO 7600 7600 GOTO 7300 10000 !---------------SUBROUTINE TO REPRINT BOARD-------------------- 10020 REF.START = TIME(0) 10040 PRINT #2%, ANSI$ + INIT.GR.MODE$ + GR.MODE$ + & SCREEN.BK.BLACK$ + W132$; & \ SLEEP 1% & \ PRINT #2%, FNPR.TYPE$(8%) + DOUBLE.WIDTH$ + SPACE$(65%) & \ PRINT #2%, FNLINE$(X%,CTRLW%) FOR X% = 2% TO 22% & \ GOTO 10100 ! Clean up, print status line & return & 10060 !---------------------CHEAT MODE-------------------------------- 10080 REF.START = TIME(0) & \ PRINT #2%, CLS$ + FNM$(1%,1%) + & DOUBLE.WIDTH$ + & FNPR.TYPE$(8%) + & SPACE$(65%) & \ PRINT #2%, FNLINE$(X%,CTRLY%) FOR X% = 2% TO 22% 10100 \ J% = 1000% ! Invalidate cnt & \ PRINT #2%, DOUBLE.WIDTH$ + SPACE$(65%) & \ PRINT #2%, DOUBLE.WIDTH$ + SPACE$(65%); & \ START.TIME = START.TIME - REF.START + TIME(0) ! No time penalty for & \ TIME.OUT = 0 & \ GOTO 10120 ! Status line, return. 10120 !------- STATUS LINE SUBROUTINE ----------------------------- 10140 JUNK$ = & FNT$(TIME(0)-START.TIME) + ! Elapsed time & " ?:"+NUM$(N.RAND%) + ! Randomizers left & " !:"+NUM$(C.CLUB%)+"/"+NUM$(N.CLUB%) + ! Clubs Carried/Left & " #:"+NUM$(C.BOMB%)+"/"+NUM$(N.BOMB%) + ! Bombs Carried/Left & " P: "+NUM1$(INT(100*MULT.PROB))+"% " ! Multiple move probability & 10160 IF TIME(0) < TIME.OUT & THEN JUNK$ = FNM$(24%,23%) + & JUNK$ & ELSE JUNK$ = FNM$(24%,1%) + & " " + & LEVEL.DIFF$ + & " " + & JUNK$ & \ TIME.OUT = 99999 & ! Only print difficulty level when necessary. & 10180 PRINT #2%, FNPR.TYPE$(8%) + JUNK$ + FNM$(24%,1%); & \ STATUS.TIME.SAV = TIME(0) & \ RETURN & 10200 !------- BOMB EXPLOSION ------------------------------------ & ! Caller must set XB%, YB% = Hitter's coords & ! 10220 PRINT #2%, SCREEN.BK.WHITE$; & \ BLAST.H.RAD% = INT(RND*3.9+1.6) & \ BLAST.V.RAD% = INT(RND*3.9+1.6) & \ SLEEP 1% & \ PRINT #2%, SCREEN.BK.BLACK$; & \ SLEEP 1% & \ PRINT #2%, SCREEN.BK.WHITE$; & \ SLEEP 1% 10240 IF XB% <= 2% + BLAST.V.RAD% & THEN BLAST.TOP% = 2% & ELSE BLAST.TOP% = XB% - BLAST.V.RAD% 10260 IF XB% <= 22% - BLAST.V.RAD% & THEN BLAST.BOT% = XB% + BLAST.V.RAD% & ELSE BLAST.BOT% = 22% 10280 IF YB% <= 2% + BLAST.H.RAD% & THEN BLAST.LEFT% = 2% & ELSE BLAST.LEFT% = YB% - BLAST.H.RAD% 10300 IF YB% <= 64% - BLAST.H.RAD% & THEN BLAST.RIGHT% = YB% + BLAST.H.RAD% & ELSE BLAST.RIGHT% = 64% 10320 PRINT #2%, FNPR.TYPE$(0%); & \ FOR X7% = BLAST.TOP% TO BLAST.BOT% & \ PRINT #2%, FNM$(X7%,BLAST.LEFT%); & \ FOR Y7% = BLAST.LEFT% TO BLAST.RIGHT% & \ HUMAN.BLASTED% = -1% IF X9% = X7% AND Y9% = Y7% & \ MONSTA.BLASTED% = -1% IF XM% = X7% AND YM% = Y7% & \ IF A%(X7%,Y7%) = 4% ! Don't erase target & THEN PRINT #2%, CSI$ + "C"; & \ GO TO 10360 10340 N.RAND% = N.RAND% - 1% IF A%(X7%,Y7%) = 6% ! Unprinted randomizer & \ N.CLUB% = N.CLUB% - 1% IF A%(X7%,Y7%) = 8% ! Club & \ N.BOMB% = N.BOMB% - 1% IF A%(X7%,Y7%) = 9% ! Inactive bomb & \ A%(X7%,Y7%) = 0% & \ PRINT #2%, CRATER$(INT(RND*4.5)); 10360 NEXT Y7% \ NEXT X7% 10380 IF MONSTA.BLASTED% AND NOT(HUMAN.BLASTED%) & THEN CLEAR.LAUGH% = -1% & \ VX% = X9% - 1% & \ VY% = Y9% - 1% & \ PRINT #2%, FNM$(VX%,VY%) + & FNPR.TYPE$(0%) + & TX.MODE$ + & "hee" + & GR.MODE$; ! Human laughs. 10400 SLEEP 1% 10420 PRINT #2%, SCREEN.BK.BLACK$; \ SLEEP 1% & \ GO TO 10680 IF HUMAN.BLASTED% ! Go Boom & \ GO TO 10460 IF NOT(MONSTA.BLASTED%) ! Skip MONSTA blasted. & \ MONSTA.BLASTED% = 0% & \ GOSUB 10800 ! MONSTA gets randomized & \ IF CLEAR.LAUGH% THEN & CLEAR.LAUGH% = 0% & \ PRINT #2%, FNS$(VX%,K%,A%(VX%,K%), CTRLY%); & FOR K% = VY% TO VY% + 2% 10440 GOSUB 10580 IF MONSTA.SAV% = 10% 10460 RETURN 10480 !------------ COMMON HUMAN MOVES SUBROUTINE --------------------- 10500 GOTO 10620 IF A%(X9%,Y9%) = 4% ! Go handle landing on target. & \ IF A%(X9%,Y9%) = 8% THEN ! Pick up a club & N.CLUB% = N.CLUB% - 1% & \ PRINT #2%, FNMESSAG$(" W H E W ! "); & UNLESS C.CLUB% OR FIRST.TIME% ! Whew & \ C.CLUB% = C.CLUB% + 1% & \ FIRST.TIME% = 0% 10520 IF A%(X9%,Y9%) = 9% THEN ! Pick up an inactive bomb & N.BOMB% = N.BOMB% - 1% & \ C.BOMB% = C.BOMB% + 1% & \ FIRST.TIME% = 0% 10540 IF A%(X9%,Y9%) = 10% THEN ! Land on an activated bomb & XB% = X9% & \ YB% = Y9% & \ A%(X9%,Y9%) = 2% & \ GOSUB 10200 ! Boom & \ GOTO 32767 10560 PRINT #2%, FNS$(X9%,Y9%,2%,CHASE%); ! Move human to new spot & \ RETURN & 10580 !-----------------MONSTA GETS BLASTED------------------------------- 10600 XB% = XM% & \ YB% = YM% & \ A%(XB%,YB%) = 0% & \ GOSUB 10200 ! Boom & \ MULT.PROB = MULT.PROB + .02 ! MONSTA wants revenge & \ MAX.MONSTA.MOVES% = MAX.MONSTA.MOVES% + 2% & \ PRINT #2%, FNMESSAG$(ANGER$(ANGER.COUNT%)); & \ ANGER.COUNT% = ANGER.COUNT% + 1% & UNLESS ANGER.COUNT% >= MAX.ANGER.COUNT% & \ RETURN 10620 !--------------------WINNER'S CIRCLE--------------------------- 10640 TIME.OUT = 0 & \ GOSUB 10120 ! Status line & \ PRINT #2%, FNPR.TYPE$(8%) + ! MONSTA is unhappy & FNM$(XM%-1%,YM%-1%) + & RATS$(INT(6%*RND)); & \ PRINT #2%, FNM$(23%,1%) + & SPACE$(19%) + & FNPR.TYPE$(5%) + & "* * * V I C T O R Y * * *" + & FNPR.TYPE$(8%) + & SPACE$(19%) + & FNM$(24%,1%); 10660 SLEEP 15% \ GOTO 32767 10680 !-----------------HUMAN GETS BLASTED--------------------------- 10700 TIME.OUT = 0 & \ GOSUB 10120 ! Status line & \ PRINT #2%, FNPR.TYPE$(8%) + & FNM$(X9%-1%,Y9%-1%) + "RIP" + & FNM$(X9%,Y9%) + "g"; & \ PRINT #2%, FNM$(XM%-1%,YM%-1%) + "HA!"; UNLESS MONSTA.BLASTED% & \ PRINT #2%, FNM$(23%,1%) + & SPACE$(20%) + & FNPR.TYPE$(5%) + & "B L O W N T O B I T S" + & FNPR.TYPE$(8%) + & SPACE$(20%) + & FNM$(24%,1%); 10720 SLEEP 15% \ GO TO 32767 10740 !-----------------S C H L O O R P------------------------------ 10760 TIME.OUT = 0 & \ GOSUB 10120 ! Status line & \ PRINT #2%, FNM$(23%,1%) + & FNPR.TYPE$(8%) + & SPACE$(23%) + & "S C H L O O R P !!!" + & SPACE$(23%) + & FNM$(X9%,Y9%) + & "g" + & FNM$(X9%-1%,Y9%-1%) + & "RIP" + & FNM$(24%,1%); 10780 SLEEP 15% \ GO TO 32767 10800 !----------------- MONSTA GETS RANDOMIZED ---------------------- 10820 XM% = INT(RND*21%) + 2% \ YM% = INT(RND*63%) + 2% & \ GOTO 10820 IF ABS(YM%-Y9%) < 3% OR ABS(XM%-X9%) < 3% & \ MONSTA.SAV% = A%(XM%,YM%) \ A%(XM%,YM%) = 1% \ RETURN & 10840 !-----------------OUCH------------------------------------------- 10860 PRINT #2%, BELL$ + BELL$ + & FNMESSAG$(" O U C H ! "); & \ RETURN 10880 !----------------BOING------------------------------------------- 10900 IF FIRST.TIME% = 0% & THEN PRINT #2%, FNMESSAG$(BOING$(INT(RND*5%))); & ELSE FIRST.TIME% = 0% & \ PRINT #2%, FNMESSAG$(SURPR$(INT(RND*3%))); 10920 RETURN 15000 !---- FNM$(X%,Y%) - MOVE CURSOR TO POSITION X,Y ------------ 15020 DEF* FNM$(X%,Y%) = CSI$ + NUM1$(X%) + ";" + NUM1$(Y%) + "f" 15040 !---- FNPR.TYPE$(ARG%) - SETS PRINT ATTRIBUTES-------------- 15060 DEF* FNPR.TYPE$(ARG%) & \ IF ARG% = PR.TYPE% THEN FNPR.TYPE$ = "" \ GOTO 15100 15080 IF (NOT(ARG%) AND PR.TYPE%) & THEN FNPR.TYPE$ = CSI$ + ";" + PT$(ARG%) + "m" & ELSE FNPR.TYPE$ = CSI$ + PT$(ARG% AND NOT(PR.TYPE%)) + "m" 15100 PR.TYPE% = ARG% & \ FNEND 15120 !------ FNC%(ARG%) ----------------------------------------- 15140 DEF* FNC%(ARG%) & \ FNC% = ARG% & \ FNC% = 1% IF ARG% = 0% & \ FNEND 15160 !------------ FNWALLP% - WALL PREDICATE --------------------- 15180 DEF* FNWALLP%(ARG%) = (ARG% = -2% OR ARG% = -1% OR & ARG% = 5% OR ARG% = 6%) 15200 !-------------FNTAB$(ARG%)----------------------------------- & ! Returns sequence to move cursor from column CCP% to ARG% & ! Assumes tabs are set at columns 1,9,17,25,33,41,49,57,65 & ! 15220 DEF* FNTAB$(ARG%) & \ IF ARG% = CCP% THEN FNTAB$ = "" \ GOTO 15260 15240 IF (ARG% AND 7%) <> 1% & THEN IF ARG% = CCP% + 1% & THEN FNTAB$ = CSI$ + "C" & ELSE FNTAB$ = CSI$ + NUM1$(ARG%-CCP%) + "C" & ELSE FNTAB$ = STRING$((ARG%-CCP%-1%)/8%+1%,9%) 15260 CCP% = ARG% \ FNEND 15280 !-------------- FNLINE$ - Returns printable line of maze---- & ! Called with CTL% = CTRLW% or CTRLY% only & ! FNLINE$ assumes clear screen & ! 15300 DEF* FNLINE$(X5%,CTL%) \ CCP% = 1% \ Q3$ = DOUBLE.WIDTH$ & \ FOR Y5% = 1% TO 65% & \ ON A%(X5%,Y5%) + 3% GOTO & 15320, ! -2 - Printed wall & 15340, ! -1 - Unprinted wall & 15380, ! 0 - Empty square & 15400, ! 1 - MONSTA & 15420, ! 2 - Human & 15440, ! 3 - Footprint & 15460, ! 4 - Target & 15480, ! 5 - Printed randomizer & 15500, ! 6 - Unprinted randomizer & 15620, ! 7 - UNUSED & 15540, ! 8 - Club & 15560, ! 9 - Inactive bomb & 15580 ! 10 - Acitvated bomb 15320 Q3$ = Q3$ + FNTAB$(Y5%) + FNPR.TYPE$(8%) + " " \ GOTO 15600 15340 IF CTL% >= 0% THEN A%(X5%,Y5%) = -2% & \ Q3$ = Q3$ + FNTAB$(Y5%) + FNPR.TYPE$(8%) + " " & \ GOTO 15600 ! Print unprinted wall if ^Y 15360 GOTO 15620 15380 GOTO 15620 ! Empty square - do nothing 15400 Q3$ = Q3$ + FNTAB$(Y5%) + FNPR.TYPE$(5%) + "`" \ GOTO 15600 ! MONSTA 15420 Q3$ = Q3$ + FNTAB$(Y5%) + FNPR.TYPE$(1%) + "O" \ GOTO 15600 ! Human 15440 Q3$ = Q3$ + FNTAB$(Y5%) + FNPR.TYPE$(0%) + "~" \ GOTO 15600 ! Footprint 15460 Q3$ = Q3$ + FNTAB$(Y5%) + FNPR.TYPE$(5%) + "*" \ GOTO 15600 ! Target 15480 Q3$ = Q3$ + FNTAB$(Y5%) + FNPR.TYPE$(8%) + "?" \ GOTO 15600 ! Printed & ! randomizer 15500 IF CTL% >= 0% THEN & A%(X5%,Y5%) = 5% & \ N.RAND% = N.RAND% - 1% & \ Q3$ = Q3$ + FNTAB$(Y5%) + FNPR.TYPE$(8%) + "?" & \ GOTO 15600 ! Print unprinted randomizer if ^Y 15520 GOTO 15620 15540 Q3$ = Q3$ + FNTAB$(Y5%) + FNPR.TYPE$(0%) + "!" \ GOTO 15600 ! Club 15560 Q3$ = Q3$ + FNTAB$(Y5%) + FNPR.TYPE$(0%) + "#" \ GOTO 15600 ! Inact. bomb 15580 Q3$ = Q3$ + FNTAB$(Y5%) + FNPR.TYPE$(13%)+ "#" \ GOTO 15600 ! Active bomb 15600 CCP% = CCP% + 1% ! Bump cursor position 15620 NEXT Y5% & \ FNLINE$ = Q3$ & \ FNEND 15640 ! & ! Define FNS$(X%,Y%,VALUE%,CTL%) - sets A%(X%,Y%) to printed & ! value and returns a printable string based on CTL% & ! 15660 DEF* FNS$(X%,Y%,VALUE%,CTL%) 15680 A%(X%,Y%) = VALUE% 15700 ON VALUE% + 3% GOTO & 15720, ! -2 - Printed wall & 15740, ! -1 - Unprinted wall & 15780, ! 0 - Empty square & 15800, ! 1 - MONSTA & 15820, ! 2 - Human & 15840, ! 3 - Footprint & 15860, ! 4 - Target & 15880, ! 5 - Printed randomizer & 15900, ! 6 - Unprinted randomizer & 16000, ! 7 - UNUSED & 15940, ! 8 - Club & 15960, ! 9 - Inactive bomb & 15980 ! 10 - Acitvated bomb 15720 FNS$ = FNPR.TYPE$(8%) + FNM$(X%,Y%) + " " IF CTL% \ GOTO 16000 & ! Printed wall 15740 IF CTL% >= 0% THEN A%(X%,Y%) = -2% & \ FNS$ = FNM$(X%,Y%) + FNPR.TYPE$(8%) + " " 15760 GOTO 16000 ! Unprinted wall - printed if CHASE% or CTRLY% 15780 FNS$ = FNM$(X%,Y%) + FNPR.TYPE$(0%) + " " & \ GOTO 16000 ! Empty square 15800 FNS$ = FNM$(X%,Y%) + FNPR.TYPE$(12%)+ "`" & \ GOTO 16000 ! MONSTA 15820 FNS$ = FNM$(X%,Y%) + FNPR.TYPE$(1%) + "O" & \ GOTO 16000 ! Human 15840 FNS$ = FNM$(X%,Y%) + FNPR.TYPE$(0%) + "~" & \ MULT.PROB = MULT.PROB + .0002 & \ GOTO 16000 ! Footprint also increases difficulty 15860 FNS$ = FNM$(X%,Y%) + FNPR.TYPE$(5%) + "*" & \ GOTO 16000 ! Target 15880 FNS$ = FNM$(X%,Y%) + FNPR.TYPE$(8%) + "?" IF CTL% & \ GOTO 16000 ! Printed randomizer 15900 IF CTL% >= 0% THEN N.RAND% = N.RAND% - 1% & \ A%(X%,Y%) = 5% & \ FNS$ = FNM$(X%,Y%) + FNPR.TYPE$(8%) + "?" 15920 GOTO 16000 ! Unprinted randomizer - printed if CHASE% & ! or CTRLY% 15940 FNS$ = FNM$(X%,Y%) + FNPR.TYPE$(0%) + "!" & \ GOTO 16000 ! Club 15960 FNS$ = FNM$(X%,Y%) + FNPR.TYPE$(0%) + "#" & \ GOTO 16000 ! Inactive bomb 15980 FNS$ = FNM$(X%,Y%) + FNPR.TYPE$(13%)+ "#" & \ GOTO 16000 ! Activated bomb (flashes bold reverse) 16000 FNEND 16020 !-------------- MM:SS time format function ----------------- 16040 DEF* FNT$(ARG%) & \ Z% = INT(ARG%/60) & \ FNT$ = FNP$(Z%) + ":" + FNP$(ARG%-Z%*60%) & \ FNEND 16060 DEF* FNP$(ARG%)=STRING$(2%-LEN(NUM1$(ARG%)),48%)+NUM1$(ARG%) 16080 !-------------- FNMESSAG$(MSG$) ---------------------------- 16100 DEF* FNMESSAG$(MSG$) & \ TIME.OUT = TIME(0) + 3 & \ FNMESSAG$ = FNM$(24%,1%) + FNPR.TYPE$(8%) + MSG$ & \ FNEND 17200 !-------------- Delimiterless input function --------------- 17220 DEF* FNGET.INPUT$(STALL%,AMOUNT%) 17240 CALL INCHR(III%) ! Get any character that's there & \ A$=CHR$(III%) ! Make it ASCII & \ A$="" IF III%=0% ! If nothing, make sure & \ FNGET.INPUT$ = A$ + "" ! Return the input string & \ SLEEP AMOUNT% IF LEN(A$) = 0% ! Rest a while as needed & \ FNEND 19000 !-------------- ERROR ROUTINE ------------------------------ 19020 RESUME 19040 19040 ON ERROR GOTO 0 19060 GOTO 32767 32766 !-------------- END OF PROGRAM ----------------------------- & ! Return to normal. 32767 PRINT #2%, CLS$ + CLR.TABS$; & \ PRINT #2%, FNM$(1%,I%) + SET.TAB$; FOR I% = 9% TO 129% STEP 8% & \ PRINT #2%, FNPR.TYPE$(0%) + & TX.MODE$ + & SCREEN.BK.BLACK$ + & W80$; & \ SLEEP 1% & \ Q% = ECHO(1%) ! Enable echo & \ Q% = ECHO(2%) ! On this channel also... & \ CLOSE #1% & \ CLOSE #2% & \ END