DECLARE FUNCTION ExplodeColour! () DECLARE FUNCTION WurbilMips! () DECLARE SUB RealDelay (x!) DECLARE FUNCTION CheckDead! () DECLARE SUB ExplodeWurbil (w!) DECLARE SUB TitleScreen () DECLARE SUB JumpWurbil (w!, j!) DECLARE SUB Centre (y!, a$) DECLARE FUNCTION Comment$ () DECLARE SUB Explode (x!, y!) DECLARE SUB MoveWurbil (w!, d!) DECLARE SUB FillLand () DECLARE SUB DrawLand () DECLARE SUB DrawWurbil (x!, c!) DECLARE SUB FillWurbils () DECLARE SUB StatusReport (x$) DECLARE SUB WurbilTurn (w!) DECLARE SUB AimWurbil (w!) DECLARE SUB ShootWurbil (w!) DECLARE SUB WurbilArrow (w!, col!) DECLARE SUB StatusBar () DECLARE SUB SetupDisplay () DECLARE FUNCTION Num$ (x!) ' Wurbils ... a sort of Worms clone thingy, by Adam Sampson. ' """"""""" Dedicated to the WIPES development team! CONST SPACING = 300 ' wurbil spacing CONST STARTENERGY = 100 ' energy at start CONST HITEFFECT = 10 ' hit power; 5=scratch 20=dead in one shot CONST MAXHIT = 50 ' maximum hit effect CONST CONV = 3.1415927# / 180 CONST DELAY = 800 ' 50 for a 80386 CONST DATASIZE = 10 CONST NUMPLAYERS = 2 CONST TURN = 5 CONST RADIUS = 30 CONST AGILITY = 2 CONST BUMPY = .02 CONST MOVING = 1 ' 0 for moving off CONST TIMEBOMB = 5 ' time in ticks before bomb is armed CONST MOVEENERGY = 0 ' energy for each move COMMON SHARED numcomments, die, ShotDelay DIM SHARED comm$(100) RESTORE comments numcomments = 0 DO numcomments = numcomments + 1 READ comm$(numcomments) LOOP UNTIL comm$(numcomments) = "*" numcomments = numcomments - 1 ' 1=xpos 2=player 3=energy 4=angle 5=shotpower DIM SHARED wurbil(NUMPLAYERS, DATASIZE) CONST LANDWIDTH = 639 DIM SHARED land(LANDWIDTH) CLS PRINT "WurbilOS 1.0.10 Intel/i386 azz@kanzler.morpork.de" PRINT "Calibrating delay loop..."; r = (WurbilMips + WurbilMips + WurbilMips) / 3 PRINT INT(r * 100) / 100; "WurbilMips." ShotDelay = r * 13.9 RESTORE speednotes delta = 100000: c$ = "" DO READ x, y$ IF ABS(r - x) < delta THEN delta = ABS(r - x) c$ = y$ END IF LOOP UNTIL y$ = "*" PRINT "Adam says " + CHR$(34) + c$ + CHR$(34) RealDelay 1 DO TitleScreen SCREEN 12: CLS RANDOMIZE TIMER StatusReport "Generating land...": FillLand StatusReport "Drawing land...": DrawLand StatusReport "Generating wurbils...": FillWurbils StatusReport "Drawing wurbils..." FOR k = 1 TO NUMPLAYERS DrawWurbil wurbil(k, 1), 15 NEXT k die = 0 DO FOR p = 1 TO NUMPLAYERS FOR k = 1 TO NUMPLAYERS DrawWurbil wurbil(k, 1), 15 NEXT k WurbilTurn p IF CheckDead > 0 THEN EXIT FOR NEXT p LOOP UNTIL CheckDead > 0 p = CheckDead StatusReport "And the final score:" Centre 12, "Wurbil " + Num$(p) + " is dead." Centre 16, "-Press a key-" ExplodeWurbil p DO: LOOP UNTIL INKEY$ <> "" DO: LOOP UNTIL INKEY$ = "" LOOP END comments: ' Adam's comments DATA "Ouch!","That hurt!","Leave me alone!","Aaarrggghhh!" DATA "Yeeooooww!","Schweinehund!","Pig dog rabbit PELICAN!" DATA "[Consult Ali Clarkson for this comment]","Ook." DATA "I thought Helge Schneider was bad, but you're WORSE!" DATA "Good shot, bad luck.","Uh-oh...","DIE IN PAIN!","Go away!" DATA "Hahahaha!","You'll regret that.","I'll get YOU!","Amigas RULE! :)" DATA "Go shoot Adam Sampson, not me! He wrote this game!" DATA "SchweinehundkaninchenPELICAN!","[boom]","I never wanted to do this!" DATA "Hey, you're a good target!","My next bullet has YOUR name on it!" DATA "Maenner sind Schweine!","'Nuts to you.'" ' Chris' comments DATA "Sauhund!","Go to hell!" ' Comment delimiter DATA "*" speednotes: DATA 0,"Like a pig in treacle." DATA 10,"Pretty slow." DATA 20,"Slowish." DATA 55,"Midrange Pentium?" DATA 100,"Fast." DATA 200,"Very fast." DATA 1000,"I didn't know the Met Office used Wurbils." DATA -500,"*" SUB AimWurbil (w) ox1 = 0: ox2 = 0 DO x1 = SIN(wurbil(w, 4) * CONV) * 5 y1 = COS(wurbil(w, 4) * CONV) * 5 LINE (580 + x1, 60 + y1)-(580 + (x1 * 5), 60 + (y1 * 5)) IF ox1 <> x1 AND oy1 <> y1 THEN LINE (580 + ox1, 60 + oy1)-(580 + (ox1 * 5), 60 + (oy1 * 5)), 0 ox1 = x1: oy1 = y1 LOCATE 5, 19: PRINT STRING$(30, " "); LOCATE 5, 19: PRINT STRING$(wurbil(w, 5) / 2, "°"); DO: LOOP UNTIL INKEY$ = "" DO: i$ = INKEY$: LOOP UNTIL i$ <> "" SELECT CASE i$ CASE "z", "y" MoveWurbil w, -1 CASE "x" MoveWurbil w, 1 CASE "Z", "Y" MoveWurbil w, -5 wurbil(w, 3) = wurbil(w, 3) - 5 CASE "X" MoveWurbil w, 5 wurbil(w, 3) = wurbil(w, 3) - 5 CASE "o" wurbil(w, 4) = wurbil(w, 4) + TURN CASE "p" wurbil(w, 4) = wurbil(w, 4) - TURN CASE "," IF wurbil(w, 5) > 0 THEN wurbil(w, 5) = wurbil(w, 5) - 1 CASE "." IF wurbil(w, 5) < 60 THEN wurbil(w, 5) = wurbil(w, 5) + 1 CASE "k" wurbil((1 - (w - 1)) + 1, 3) = 0 END SELECT LOOP UNTIL i$ = CHR$(13) LOCATE 2, 1: PRINT STRING$(20, " "); CHR$(13); STRING$(20, " "); END SUB SUB Centre (y, a$) LOCATE y, 40 - LEN(a$) / 2: PRINT a$; END SUB FUNCTION CheckDead d = 0 FOR k = 1 TO NUMPLAYERS IF wurbil(k, 3) < 1 THEN d = k NEXT k CheckDead = d END FUNCTION FUNCTION Comment$ Comment$ = comm$(INT(RND(1) * numcomments)) END FUNCTION SUB DrawLand FOR k = 150 TO 480 FOR j = 1 TO (230 - (k - 150)) IF RND(1) > .8 THEN PSET (640 * RND(1), k), 9 PSET (640 * RND(1), 480 - (k - 150)), 1 NEXT j NEXT k FOR k = 1 TO LANDWIDTH LINE (k - 1, land(k - 1))-(k, land(k)) LINE (k, land(k))-(k, 480), 2 FOR j = 1 TO INT(RND(1) * 10) + 1 PSET (k, 480 - (480 - land(k)) * RND(1)), 10 NEXT j NEXT k CIRCLE (640 * RND(1), 220), 40, 12 END SUB SUB DrawWurbil (x, c) ' Improve this at some point! y = land(x) LINE (x - 5, y - 20)-(x + 5, y), c LINE (x, y - 10)-(x - 5, y), c CIRCLE (x, y - 10), 5, c END SUB SUB Explode (x, y) FOR k = 1 TO 8 CIRCLE (x, y), k, ExplodeColour RealDelay .01 NEXT k FOR k = 8 TO 1 STEP -1 CIRCLE (x, y), k, 0 RealDelay .01 NEXT k END SUB FUNCTION ExplodeColour SELECT CASE INT(RND(1) * 6) + 1 CASE 1 ExplodeColour = 7 CASE 2 ExplodeColour = 15 CASE 3 ExplodeColour = 4 CASE 4 ExplodeColour = 12 CASE 5 ExplodeColour = 6 CASE 6 ExplodeColour = 14 END SELECT END FUNCTION SUB ExplodeWurbil (w) x = wurbil(w, 1) y = land(x) - 10 FOR k = 1 TO 20 xx = INT(RND(1) * 10) + 1 + x - 10 yy = INT(RND(1) * 10) + 1 + y - 10 FOR kk = 1 TO 8 CIRCLE (xx, yy), kk, ExplodeColour FOR dummy = 1 TO ShotDelay: NEXT NEXT kk FOR kk = 8 TO 1 STEP -1 CIRCLE (xx, yy), kk, 0 FOR dummy = 1 TO ShotDelay: NEXT NEXT kk NEXT END SUB SUB FillLand h = INT(RND(1) * 100) + 1 + 300 FOR k = 0 TO LANDWIDTH land(k) = h r = RND(1) IF r < BUMPY THEN h = h - 4 ELSEIF r < .1 THEN h = h - 2 ELSEIF r < .2 THEN h = h - 1 ELSEIF r < .7 THEN ' nothing ELSEIF r < .9 THEN h = h + 1 ELSEIF r < 1 - BUMPY THEN h = h + 2 ELSE h = h + 4 END IF NEXT k END SUB SUB FillWurbils FOR k = 1 TO NUMPLAYERS ok = 0 WHILE ok = 0 ok = 1 wurbil(k, 1) = INT(RND(1) * LANDWIDTH) + 1 FOR j = 1 TO k - 1 IF ABS(wurbil(k, 1) - wurbil(j, 1)) < SPACING AND j <> k THEN ok = 0 NEXT j wurbil(k, 2) = k wurbil(k, 3) = STARTENERGY wurbil(k, 4) = 250 wurbil(k, 5) = 10 WEND NEXT k END SUB SUB JumpWurbil (w, j) DrawWurbil wurbil(w, 1), 0 DO j = INT(RND(1) * j) + 1 j = j * ((INT(RND(1) * 2) * 2) - 1) wu = wurbil(w, 1) + j LOOP UNTIL wu > 0 AND wu < LANDWIDTH wurbil(w, 1) = wu DrawWurbil wurbil(w, 1), 15 END SUB SUB MoveWurbil (w, d) IF MOVING = 0 THEN EXIT SUB WurbilArrow w, 0 y = land(wurbil(w, 1)) IF wurbil(w, 1) + d < 0 OR wurbil(w, 1) + d > LANDWIDTH THEN EXIT SUB IF ABS(land(wurbil(w, 1) + d) - y) > AGILITY AND ABS(d) = 1 THEN 'BEEP ELSE DrawWurbil wurbil(w, 1), 0 wurbil(w, 1) = wurbil(w, 1) + d DrawWurbil wurbil(w, 1), 15 END IF WurbilArrow w, 15 wurbil(w, 3) = wurbil(w, 3) - MOVEENERGY StatusBar END SUB FUNCTION Num$ (x) a$ = STR$(x) Num$ = RIGHT$(a$, LEN(a$) - 1) END FUNCTION SUB RealDelay (x) t = TIMER: DO: LOOP UNTIL TIMER > t + x END SUB SUB SetupDisplay LOCATE 1, 1: PRINT STRING$(80, "°"); LOCATE 5, 10: PRINT "Power"; LOCATE 5, 18: PRINT "["; STRING$(30, " "); "]" LOCATE 7, 71: PRINT "Angle"; CIRCLE (580, 60), 2 CIRCLE (580, 60), 30 LOCATE 11, 1: PRINT "-Wurbils!--Wurbils!--Wurbils!--Wurbils!--Wurbils!--Wurbils!--Wurbils!--Wurbils!-"; END SUB SUB ShootWurbil (w) ' This is the mathmatical bit. t = 0 ' arbitrary units. ix = wurbil(w, 1) iy = land(ix) - 10 ax = 0 ' wind ay = -2 ' gravity vx = SIN(wurbil(w, 4) * CONV) * wurbil(w, 5) vy = -COS(wurbil(w, 4) * CONV) * wurbil(w, 5) ox = 100: oy = 100 hit = 0 DO t = t + .25 x = (vx * t) + (.5 * ax * t * t) + ix y = iy - ((vy * t) + (.5 * ay * t * t)) CIRCLE (x, y), 2 CIRCLE (ox, oy), 2, 0 ox = x: oy = y IF x < 0 OR x > LANDWIDTH THEN hit = 1 ELSE IF land(INT(x)) <= INT(y) THEN hit = 1 END IF FOR k = 1 TO NUMPLAYERS d = SQR(((wurbil(k, 1) - x) ^ 2) + ((land(wurbil(k, 1)) - y) ^ 2)) IF d < RADIUS AND (k <> w OR t > TIMEBOMB) THEN v = ABS(INT((RADIUS - d) * HITEFFECT)) IF v > MAXHIT THEN v = MAXHIT wurbil(k, 3) = wurbil(k, 3) - v IF wurbil(k, 3) < 0 THEN wurbil(k, 3) = 0 StatusReport "Hit wurbil " + STR$(k) + " for " + STR$(v) + "!" JumpWurbil k, 200 IF wurbil(k, 3) > 0 THEN Centre 2, Comment$ ELSE SELECT CASE INT(RND(1) * 2) + 1 CASE 1 Centre 2, "Bye bye..." CASE 2 Centre 2, "Oh dear." CASE ELSE Centre 2, "Aaarrrgggh!" END SELECT END IF Explode x, y RealDelay .5 hit = 1 END IF NEXT k FOR dummy = 1 TO ShotDelay: NEXT LOOP UNTIL hit = 1 Explode x, y END SUB SUB StatusBar p$ = "Wurbils! by Adam Sampson " FOR k = 1 TO NUMPLAYERS p$ = p$ + Num$(k) + ": " + Num$(wurbil(k, 3)) + " " NEXT k StatusReport p$ END SUB SUB StatusReport (x$) LOCATE 1, 1 PRINT STRING$(80, " "); LOCATE 1, 1 PRINT x$; END SUB SUB TitleScreen SCREEN 0 COLOR 6: CLS FOR k = 1 TO 50: LOCATE INT(RND(1) * 25) + 1, INT(RND(1) * 80) + 1: PRINT "."; : NEXT COLOR 14, 1: Centre 3, " \/\/uRbIlS Pro '98 ": COLOR 14, 0 Centre 6, "by Adam Sampson and Chris Verlage" COLOR 12: Centre 10, "Keys:" COLOR 4 Centre 12, "z x (or y x) = move left or right" Centre 13, "Z X (or Y X) = jump left or right (-5 energy)" Centre 14, ", . = power up or down" Centre 15, "o p = change angle up or down" Centre 16, "Enter = fire your Wuzi" COLOR 13: Centre 18, "= DO NOT HIT THE KEYS HARD; IT DOESN'T MAKE THE SHOT FASTER! =" Centre 20, "Press any key to start the fun..." Centre 21, "Press 'q' to quit" COLOR 4: Centre 24, "Caution: this game contains scenes of graphic humour and amusing comments." DO: LOOP UNTIL INKEY$ = "" DO: i$ = INKEY$: LOOP UNTIL i$ <> "" IF i$ = "q" OR i$ = "Q" THEN END SCREEN 12: CLS END SUB SUB WurbilArrow (w, col) x = wurbil(w, 1) y = land(x) LINE (x - 10, y - 50)-(x, y - 40), col LINE (x, y - 40)-(x + 10, y - 50), col END SUB FUNCTION WurbilMips r = 0: t = TIMER: DO: r = r + 1: LOOP UNTIL TIMER > t + .5 WurbilMips = r / 100 END FUNCTION SUB WurbilTurn (w) FOR k = 1 TO 10: LOCATE k, 1: PRINT STRING$(80, " "); : NEXT IF wurbil(w, 3) = 0 THEN die = 1: EXIT SUB SetupDisplay StatusReport "OK, Wurbil " + Num$(w) + ", it's your turn!" WurbilArrow w, 7 AimWurbil w StatusBar ShootWurbil w StatusBar WurbilArrow w, 0 END SUB