REM Project: AGH
REM Created: 5/3/2007 2:54:16 PM
REM
REM ***** Main Source File *****
REM
 
SET DISPLAY MODE 1024, 768, 32
 
INK RGB(50, 50, 0), 0
BOX 1, 1, 65, 65
GET IMAGE 1, 1, 1, 65, 65, 1
CLS 0
INK RGB(255, 255, 0), 0
FOR i = 0 to 6
   LINE 1, 15+i, 9, 1+i
   LINE 9, 1+i, 17, 15+i
   INK RGB(255-(30*i), 255-(30*i), 0), 0
NEXT i
GET IMAGE 2, 1, 1, 17, 20, 1
CLS 0
INK RGB(255, 255, 255), 0
FOR i = 1 to 5
   ELLIPSE 5, 5, i, i
   INK RGB(255-(30*i), 255-(30*i), 255-(30*i)), 0
NEXT i
GET IMAGE 3, 1, 1, 11, 11, 1
CLS 0
INK RGB(255, 0, 0), 0
FOR i = 1 to 5
   ELLIPSE 5, 5, i, i
   INK RGB(255-(30*i), 0, 0), 0
NEXT i
GET IMAGE 4, 1, 1, 11, 11, 1
CLS 0
INK RGB(255, 255, 255), 0
LINE 8,1,8,17
LINE 9,1,9,17
LINE 1,8,17,8
LINE 1,9,17,9
GET IMAGE 5, 1, 1, 17, 17, 1
CLS 0
INK RGB(255, 0, 0), 0
LINE 8,1,8,17
LINE 9,1,9,17
LINE 1,8,17,8
LINE 1,9,17,9
GET IMAGE 6, 1, 1, 17, 17, 6
CLS 0
INK RGB(255, 255, 255), 0
 
SYNC ON : HIDE MOUSE : AUTOCAM OFF : SYNC RATE 60
 
REPEAT
   CENTER TEXT SCREEN WIDTH()/2, 150, "Holy BANANANAS. You are Ron Gollinplecker and you have been appointed"
   CENTER TEXT SCREEN WIDTH()/2, 165, "this team's Sphere Exterminator. Your Extermispheretron 6816 vaporiz-"
   CENTER TEXT SCREEN WIDTH()/2, 180, "zles spheres into next Christmas. It has a varying range based on the"
   CENTER TEXT SCREEN WIDTH()/2, 195, "intensity of the targeted sphere's longing and desire for an end to -"
   CENTER TEXT SCREEN WIDTH()/2, 210, "its misphery. Shoot quickly, dear Gollinplecker, for the window is a-"
   CENTER TEXT SCREEN WIDTH()/2, 225, "ll too short, and you wouldn't want to be gobbled and.. spheregested."
   CENTER TEXT SCREEN WIDTH()/2, 275, "PRESS ENTER TO CONTINUE. MOOSE."
   CENTER TEXT SCREEN WIDTH()/2, 325, "Oh yeah, and if you misfire, you lose your weapon for some seconds..."
   SYNC
UNTIL RETURNKEY() = 1
 
GLOBAL dTimer
GLOBAL loopTime
GLOBAL lastTime
GLOBAL grav#
GLOBAL mouseSens#
GLOBAL jumpVel#
GLOBAL jump
GLOBAL jumpFwd
GLOBAL jumpBack
GLOBAL jumpLeft
GLOBAL jumpRight
GLOBAL moving
GLOBAL hp
 
TYPE killBall
   dist AS FLOAT
   startDist AS FLOAT
   up AS INTEGER
   spr AS INTEGER
   redSpr AS INTEGER
   obj AS INTEGER
   speed AS FLOAT
   killMin AS FLOAT
   killMax AS FLOAT
   KILL as INTEGER
ENDTYPE
 
DIM killBalls(20) AS killball
 
FOR i = 1 TO 20
   killBalls(i).up = 0
   killBalls(i).spr = 0
   killBalls(i).redSpr = 0
   killBalls(i).obj = 0
   killBalls(i).KILL = 0
NEXT i
 
UpdateDelta()
 
COLOR BACKDROP RGB(150, 150, 255)
MAKE OBJECT SPHERE 1000, 1
HIDE OBJECT 1000
 
MAKE OBJECT BOX 999, 500, 1, 500
COLOR OBJECT 999, RGB(50, 50, 0)
MAKE OBJECT BOX 998, 500, 1, 500
POSITION OBJECT 998, 0, 300, 0
GHOST OBJECT ON 998
 
`MAKE-A DA GUN
MAKE OBJECT CYLINDER 1001, 5
MAKE OBJECT BOX 1002, 1, 0.1, 2
MAKE MESH FROM OBJECT 1, 1002
ADD LIMB 1001, 1, 1
OFFSET LIMB 1001, 1, 0, 2, -3
SCALE OBJECT 1001, 20, 100, 20
COLOR OBJECT 1001, 0
COLOR LIMB 1001, 1, RGB(50, 50, 50)
XROTATE OBJECT 1001, 90
LOCK OBJECT ON 1001
POSITION OBJECT 1001, 1, -2, 2
DELETE OBJECT 1002
SET AMBIENT LIGHT 20
 
 
FOR i = 1 TO 20
   MAKE OBJECT BOX i, 5, 500, 5
   COLOR OBJECT i, RGB(255, 0, 0)
   GHOST OBJECT ON i
NEXT i
 
FOR i = 1 TO 5
   POSITION OBJECT i, -250, 50, -250+(i-1)*100
NEXT i
 
FOR i = 6 TO 10
   POSITION OBJECT i, 250, 50, 250-(i-6)*100
NEXT i
 
FOR i = 11 TO 15
   POSITION OBJECT i, -250+(i-11)*100, 50, 250
NEXT i
 
FOR i = 16 TO 20
   POSITION OBJECT i, 250-(i-16)*100, 50, -250
NEXT i
 
 
POSITION CAMERA 0, 15, 0
 
grav# = 0.1
mouseSens# = 0.2
killInterval = 3000
gunInterval = 5000
gunTimer = 0
hp = 5
score = 0
SPRITE 1, SCREEN WIDTH()-100, SCREEN HEIGHT()-100, 1
SPRITE 2, SCREEN WIDTH()-100, SCREEN HEIGHT()-100, 2
SPRITE 3, -30, -30, 3
SPRITE 4, -40, -40, 4
SPRITE 5, SCREEN WIDTH()/2-8, SCREEN HEIGHT()/2-8, 5
SPRITE 6, SCREEN WIDTH()/2-8, SCREEN HEIGHT()/2-8, 6
HIDE SPRITE 6
 
 
killTime = TIMER()
 
REPEAT
   UpdateDelta()
   MouseMove()
   PlayerMove()
   TEXT 5, 5, "LIFE FORCE:"
   BOX 100, 5, 200, 20, RGB(110, 0, 0), RGB(110, 0, 0), RGB(110, 0, 0), RGB(110, 0, 0)
   BOX 100, 5, 100+(hp*20), 20, RGB(255, 0, 0), RGB(255, 0, 0), RGB(255, 0, 0), RGB(255, 0, 0)
   TEXT 5, 20, "SCORE: "+STR$(score)
   IF (TIMER() - killTime) > killInterval
      MakeKillBall(1.0, 200.0, 30.0)
      killTime = TIMER()
   ENDIF
   IF gunTimer = 1
      IF (TIMER() - gunTime) > gunInterval
         SHOW OBJECT 1001
         SHOW SPRITE 5
         gunTimer = 0
      ENDIF
   ELSE
      pick = PICK OBJECT(SCREEN WIDTH()/2, SCREEN HEIGHT()/2, 21, 40)
      kb = 0
      HIDE SPRITE 6
      SHOW SPRITE 5
      onTarget = 0
      IF pick <> 0
         kb = GetKillBallByObj(pick)
         IF killBalls(kb).KILL = 1
            HIDE SPRITE 5
            SHOW SPRITE 6
            onTarget = 1
         ENDIF
      ENDIF
      IF MOUSECLICK() = 1 AND clicked = 0
         IF onTarget = 1
            DestroyKillBall(kb)
            INC score
         ELSE
            HIDE OBJECT 1001
            HIDE SPRITE 5
            HIDE SPRITE 6
            gunTimer = 1
            gunTime = TIMER()
         ENDIF
      ENDIF
      clicked = MOUSECLICK()
   ENDIF
   IF moving = 1
      POSITION OBJECT 1001, 2, -2, 2+SIN(TIMER())*0.2
   ELSE
      POSITION OBJECT 1001, 2, -2, 2
   ENDIF
   `TEXT 5, 5, "FPS: "+STR$(SCREEN FPS())
   SYNC
UNTIL hp <= 0
 
COLOR BACKDROP 0
REPEAT
   CENTER TEXT SCREEN WIDTH()/2, 150, "BOOOOO!"
   CENTER TEXT SCREEN WIDTH()/2, 250, "SCORE: "+STR$(score)
   CENTER TEXT SCREEN WIDTH()/2, 350, "PRESS ENTER"
   SYNC
UNTIL RETURNKEY()=1
 
END
 
FUNCTION MakeKillBall(spd#, startD#, kdist#)
   nextBall = NextKillBall()
   IF nextBall <> -1
      killBalls(nextBall).up = 1
      killBalls(nextBall).dist = 1.0
      killBalls(nextBall).spr = NextSprite()
      CLONE SPRITE 3, killBalls(nextBall).spr
      killBalls(nextBall).redSpr = NextSprite()
      CLONE SPRITE 4, killBalls(nextBall).redSpr
      killBalls(nextBall).obj = NextObj()
      MAKE OBJECT SPHERE killBalls(nextBall).obj, 10
      SET OBJECT SPECULAR killBalls(nextBall).obj, RGB(200, 200, 200)
      killBalls(nextBall).speed = spd#
      kmax# = RND(30.0)+30.0
      killBalls(nextBall).killMin = kmax# - kdist#
      killBalls(nextBall).killMax = kmax#
      killBalls(nextBall).startDist = startD#
      ROTATE OBJECT killBalls(nextBall).obj, WRAPVALUE(RND(80)+270), WRAPVALUE(RND(360)), 0.0
      MOVE OBJECT killBalls(nextBall).obj, startD#
   ENDIF
ENDFUNCTION
 
FUNCTION DestroyKillBall(b)
   IF killBalls(b).up = 1
      killBalls(b).up = 0
      DELETE SPRITE killBalls(b).spr
      DELETE SPRITE killBalls(b).redSpr
      DELETE OBJECT killBalls(b).obj
      killBalls(b).spr = 0
      killBalls(b).redSpr = 0
      killBalls(b).obj = 0
      killBalls(b).KILL = 0
   ENDIF
ENDFUNCTION
 
FUNCTION MouseMove()
   XROTATE CAMERA CAMERA ANGLE X()+MOUSEMOVEY()*mouseSens#
   YROTATE CAMERA WRAPVALUE(CAMERA ANGLE Y()+MOUSEMOVEX()*mouseSens#)
   IF CAMERA ANGLE X() > 25.0 THEN XROTATE CAMERA 25.0
   IF CAMERA ANGLE X() < -90.0 THEN XROTATE CAMERA -90.0
ENDFUNCTION
 
FUNCTION PlayerMove()
   plSpeed# = 2.0
   xAng# = CAMERA ANGLE X()
   yAng# = CAMERA ANGLE Y()
   zAng# = 0.0
   tplPosX# = CAMERA POSITION X()
   tplPosY# = CAMERA POSITION Y()
   tplPosZ# = CAMERA POSITION Z()
   IF jump = 0
      ROTATE CAMERA 0, YAng#, 0
      IF KEYSTATE(17) = 1 THEN MOVE CAMERA Delta(plSpeed#)
      IF KEYSTATE(31) = 1 THEN MOVE CAMERA Delta((plSpeed#/2)*-1)
      IF KEYSTATE(30) = 1
         YROTATE CAMERA yAng#-90
         tSpd# = plSpeed#
         IF KEYSTATE(17) = 1 THEN tSpd# = tSpd#/2
         MOVE CAMERA Delta(tSpd#)
         YROTATE CAMERA yAng#+90
      ENDIF
      IF KEYSTATE(32) = 1
         YROTATE CAMERA yAng#-90
         tSpd# = plSpeed#
         IF KEYSTATE(17) = 1 THEN tSpd# = tSpd#/2
         MOVE CAMERA Delta(tSpd#*-1)
         YROTATE CAMERA yAng#+90
      ENDIF
      ROTATE CAMERA xAng#, yAng#, zAng#
   ELSE
      IF jumpFwd = 1 THEN MOVE OBJECT 1000, Delta(plSpeed#)
      IF jumpBack = 1 THEN MOVE OBJECT 1000, Delta((plSpeed#/2)*-1)
      IF jumpLeft = 1
         YROTATE OBJECT 1000, OBJECT ANGLE Y(1000)-90
         tSpd# = plSpeed#
         IF jumpFwd = 1 THEN tSpd# = plSpeed#/2
         MOVE OBJECT 1000, Delta(tSpd#)
         YROTATE OBJECT 1000, OBJECT ANGLE Y(1000)+90
      ENDIF
      IF jumpRight = 1
         YROTATE OBJECT 1000, OBJECT ANGLE Y(1000)-90
         tSpd# = plSpeed#
         IF jumpFwd = 1 THEN tSpd# = plSpeed#/2
         MOVE OBJECT 1000, Delta(tSpd#*-1)
         YROTATE OBJECT 1000, OBJECT ANGLE Y(1000)+90
      ENDIF
      POSITION CAMERA OBJECT POSITION X(1000), CAMERA POSITION Y(), OBJECT POSITION Z(1000)
   ENDIF
   plPosX# = CAMERA POSITION X()
   plPosY# = CAMERA POSITION Y()
   plPosZ# = CAMERA POSITION Z()
   moving = 0
   IF (tplPosX#+tplPosY#+tplPosZ#) <> (plPosX#+plPosY#+plPosZ#) THEN moving = 1
   IF KEYSTATE(57) = 1 AND jump = 0
      jump = 1
      jumpVel# = 2.5
      jumpFwd = KEYSTATE(17)
      jumpBack = KEYSTATE(31)
      jumpLeft = KEYSTATE(30)
      jumpRight = KEYSTATE(32)
      ROTATE OBJECT 1000, xAng#, yAng#, zAng#
   ENDIF
 
 
   DEC jumpVel#, Delta(grav#)
   INC plPosY#, Delta(jumpVel#)
   IF plPosY# < 15 THEN plPosY# = 15 : jump = 0 : jumpFwd = 0 : jumpBack = 0 : jumpLeft = 0 : jumpRight = 0
 
   IF plPosX# < -250 THEN plPosX# = -250
   IF plPosX# > 250 THEN plPosX# = 250
   IF plPosZ# < -250 THEN plPosZ# = -250
   IF plPosZ# > 250 THEN plPosZ# = 250
 
   POSITION CAMERA plPosX#, plPosY#, plPosZ#
   POSITION OBJECT 1000, plPosX#, plPosY#, plPosZ#
   FOR i = 1 to 20
      IF killBalls(i).up = 1
         POINT OBJECT killBalls(i).obj, plPosX#, plPosY#, plPosZ#
         killBalls(i).dist = ObjectXYZDistance(1000, killBalls(i).obj)
         tKBSpd# = (killBalls(i).startDist - killBalls(i).dist)*0.011
         `TEXT 5, 25, "SPD: "+STR$(tKBSpd#)+" "+STR$(killBalls(i).speed)
         IF tKBSpd# < killBalls(i).speed THEN tKBSpd# = killBalls(i).speed
         `TEXT 5, 45, "SPD: "+STR$(tKBSpd#)+" "+STR$(killBalls(i).speed)
         MOVE OBJECT killBalls(i).obj, Delta(tKBSpd#)
         IF killBalls(i).dist <= killBalls(i).killMax AND killBalls(i).dist >= killBalls(i).killMin
            IF killBalls(i).KILL = 0
               HIDE SPRITE killBalls(i).spr
               SHOW SPRITE killBalls(i).redSpr
               COLOR OBJECT killBalls(i).obj, RGB(255, 0, 0)
            ENDIF
            CENTER TEXT OBJECT SCREEN X(killBalls(i).obj), OBJECT SCREEN Y(killBalls(i).obj), "KILL ME!!"
            gooSpr = 4
            killBalls(i).KILL = 1
            tSpr = killBalls(i).redSpr
         ELSE
            IF killBalls(i).KILL = 1
               SHOW SPRITE killBalls(i).spr
               HIDE SPRITE killBalls(i).redSpr
               COLOR OBJECT killBalls(i).obj, RGB(255, 255, 255)
            ENDIF
            gooSpr = 3
            killBalls(i).KILL = 0
            tSpr = killBalls(i).spr
         ENDIF
         SPRITE tSpr, SPRITE X(2), SPRITE Y(2), gooSpr
         ROTATE SPRITE tSpr, WRAPVALUE(yAng# - OBJECT ANGLE Y(killBalls(i).obj))*-1
         MOVE SPRITE tSpr, INT(ObjectXZDistance(1000, killBalls(i).obj)/7.8125)*-1
         OFFSET SPRITE tSpr, 5, 5
         IF killBalls(i).dist <= 1.0 THEN DestroyKillBall(i) : DEC hp
      ENDIF
   NEXT i
   `TEXT 5, 65, STR$(WRAPVALUE(xAng#))
   mapOffsetX = 32+INT(plPosX#/8)
   mapOffsetY = 32-INT(plPosZ#/8)
   OFFSET SPRITE 2, 8, 10
   OFFSET SPRITE 1, mapOffsetX, mapOffsetY
   ROTATE SPRITE 1, yAng#*-1
ENDFUNCTION
 
FUNCTION UpdateDelta()
   dTimer = TIMER()
   loopTime = dTimer-lastTime
   lastTime= dTimer
ENDFUNCTION
 
FUNCTION Delta(val#)
   res# = val#*0.060*loopTime
ENDFUNCTION res#
 
FUNCTION ObjectXZDistance(obj1, obj2)
   dx# = OBJECT POSITION X(obj2)-OBJECT POSITION X(obj1)
   dz# = OBJECT POSITION Z(obj2)-OBJECT POSITION Z(obj1)
   res# = SQRT(dx#*dx# + dz#*dz#)
ENDFUNCTION res#
 
FUNCTION ObjectXYZDistance(obj1, obj2)
   dx# = OBJECT POSITION X(obj2)-OBJECT POSITION X(obj1)
   dy# = OBJECT POSITION Y(obj2)-OBJECT POSITION Y(obj1)
   dz# = OBJECT POSITION Z(obj2)-OBJECT POSITION Z(obj1)
   res# = SQRT(dx#*dx# + dy#*dy# + dz#*dz#)
ENDFUNCTION res#
 
FUNCTION NextSprite()
   FOR i = 1 TO 65535
      IF SPRITE EXIST(i) = 0 THEN res = i : EXIT
   NEXT i
ENDFUNCTION res
 
FUNCTION NextObj()
   FOR i = 1 TO 65535
      IF OBJECT EXIST(i) = 0 THEN res = i : EXIT
   NEXT i
ENDFUNCTION res
 
FUNCTION NextKillBall()
   res = -1
   FOR i = 1 TO 20
      IF killBalls(i).up = 0 THEN res = i : EXIT
   NEXT i
ENDFUNCTION res
 
FUNCTION GetKillBallByObj(obj)
   res = 0
   FOR i = 1 TO 20
      IF killBalls(i).obj = obj THEN res = i : EXIT
   NEXT i
ENDFUNCTION res