set display mode 1024,768,32
backdrop on
color backdrop 0
sync on
hide mouse
set image colorkey 0,0,0
set camera range 1,20000
 
global shots
shots=20
firespeed=20
 
rem Objects
global oPlanet=1
global oShip=2
global oAlienS=3
global oAlienF=13
global oSky=14
global oShotS=15
global oShotF=35
global oAtmosphere=36
global oExplosion=37
global oHud=38
global oDir=39
rem Images
global iPlanet=1
global iEngine=2
global iAlien=3
global iSky=4
global iShip=5
global iShot=6
global iTitle=7
global iHud=8
rem Meshes
global mShip=1
 
global xvship as float
global yvShip as float
global zvShip as float
mass as float
global velocity as float
xvShip=0.0
yvShip=0.0
zvShip=0.64
mass=250.0
global fire=1
global dim afire(shots) as integer
global dim xfire(shots) as float
global dim yfire(shots) as float
global dim zfire(shots) as float
global dim xvfire(shots) as float
global dim yvfire(shots) as float
global dim zvfire(shots) as float
 
aliens=oAlienF-oAlienS
dim xvAlien(aliens) as float
dim yvAlien(aliens) as float
dim zvAlien(aliens) as float
dim exAlien(aliens) as integer
global radar as integer
radar=0
 
dist_vector=1
i=make vector3(dist_vector)
title()
make_planet()
make_ship()
make_aliens()
make_stars()
make_shots()
make_explosion()
make_hud()
for i=oAlienS to oAlienF
  angle=(i-oAlienS)*9
  position object i,cos(angle)*650,(i-aliens/2)*20,sin(angle)*650
  angle=wrapvalue(90-angle)
  xvAlien(i-oAlienS)=cos(angle)*0.64
  yvAlien(i-oAlienS)=0.0
  zvAlien(i-oAlienS)=sin(angle)*0.64
next i
position object oShip,750,-50,100
position camera 1200,0,0
point camera 0,0,0
trigger=0
press=0
set text font "courier new"
set text size 16
text 350,450,"Press any key to start"
sync
while inkey$()<>""
endwhile
wait key
while not escapekey()
  move object oShip,-25
  pitch object up oShip,90
  move object oShip,2
  xobtain#=object position x(oShip)
  yobtain#=object position y(oShip)
  zobtain#=object position z(oShip)
  xcam#=camera position x()
  ycam#=camera position y()
  zcam#=camera position z()
  set vector3 dist_vector,(xcam#-xobtain#),(ycam#-yobtain#),(zcam#-zobtain#)
  dist#=length vector3(dist_vector)/20
  if dist#>2.0 then dist#=2.0
  point camera xobtain#,yobtain#,zobtain#
  move camera dist#
  move object oShip,-2
  pitch object down oShip,90
  move object oShip,25
  point camera object position x(oShip),object position y(oShip),object position z(oShip)
  if leftkey()
    turn object left oShip,0.5
  endif
  if rightkey()
    turn object right oShip,0.5
  endif
  if upkey()
    pitch object down oShip,0.5
  endif
  if downkey()
    pitch object up oShip,0.5
  endif
  if not shiftkey()
    hide limb oShip,7
    hide limb oShip,8
    hide limb oShip,9
  endif
  if shiftkey()
    cx#=object position x(oShip)
    cy#=object position y(oShip)
    cz#=object position z(oShip)
    move object oShip,0.001
    nx#=object position x(oShip)
    ny#=object position y(oShip)
    nz#=object position z(oShip)
    position object oShip,cx#,cy#,cz#
    xvShip=xvShip+nx#-cx#
    yvShip=yvShip+ny#-cy#
    zvShip=zvShip+nz#-cz#
    show limb oShip,7
    show limb oShip,8
    show limb oShip,9
  endif
  if not spacekey() then trigger=0
  if spacekey() and trigger=0
    trigger=1
    inc fire
    if fire>shots then fire=1
    afire(fire)=1
    xfire(fire)=object position x(oShip)
    yfire(fire)=object position y(oShip)
    zfire(fire)=object position z(oShip)
    cx#=object position x(oShip)
    cy#=object position y(oShip)
    cz#=object position z(oShip)
    move object oShip,firespeed
    nx#=object position x(oShip)
    ny#=object position y(oShip)
    nz#=object position z(oShip)
    move object oShip,-firespeed
    xvfire(fire)=nx#-cx#
    yvfire(fire)=ny#-cy#
    zvfire(fire)=nz#-cz#
    show object fire+oShotS-1
  endif
  set cursor 0,100
  if not keystate(19) then press=0
  if keystate(19) and press=0
    press=1
    radar=1-radar
  endif
  if radar
    ink rgb(255,0,0),0
    set text transparent
    for i=oAlienS to oAlienF
      if object visible(i)
        if object in screen(i)
          if not intersect object(oPlanet,camera position x(),camera position y(),camera position z(),object position x(i),object position y(i),object position z(i))
            xRad=object screen x(i)
            yRad=object screen y(i)
            oRad=pick object(xRad,yRad,i,i)
            dRad=get pick distance()
            line xRad,yRad-10,xRad-10,yRad+5
            line xRad-10,yRad+5,xRad+10,yRad+5
            line xRad+10,yRad+5,xRad,yRad-10
            set cursor xRad-10,yRad+10
            print dRad
          endif
        endif
      endif
    next i
  endif
  set vector3 dist_vector,object position x(oShip),object position y(oShip),object position z(oShip)
  height#=length vector3(dist_vector)
  if height#<550
    set object ambience oShip,rgb(255,0,0)
    if height#<520
      crash()
      end
    endif
  else
    set object ambience oShip,rgb(64,64,192)
  endif
  attract#=mass/height#^2
  deltaxv#=attract#*object position x(oShip)/height#
  deltayv#=attract#*object position y(oShip)/height#
  deltazv#=attract#*object position z(oShip)/height#
  xvShip=xvShip-deltaxv#
  yvShip=yvShip-deltayv#
  zvShip=zvShip-deltazv#
  set vector3 dist_vector,xvShip,yvShip,zvShip
  velocity=length vector3(dist_vector)
  position object oShip,object position x(oShip)+xvShip,object position y(oShip)+yvShip,object position z(oShip)+zvShip
  for i=oAlienS to oAlienF
    if exAlien(i-oAlienS)<100
      position object i,object position x(i)+xvAlien(i-oAlienS),object position y(i)+yvAlien(i-oAlienS),object position z(i)+zvAlien(i-oAlienS)
      set vector3 dist_vector,object position x(i)+xvAlien(i-oAlienS),object position y(i)+yvAlien(i-oAlienS),object position z(i)+zvAlien(i-oAlienS)
      distance#=length vector3(dist_vector)
      attract#=mass/distance#^2
      deltaxv#=attract#*object position x(i)/distance#
      deltayv#=attract#*object position y(i)/distance#
      deltazv#=attract#*object position z(i)/distance#
      xvAlien(i-oAliens)=xvAlien(i-oAliens)-deltaxv#
      yvAlien(i-oAliens)=yvAlien(i-oAliens)-deltayv#
      zvAlien(i-oAliens)=zvAlien(i-oAliens)-deltazv#
      if exAlien(i-oAlienS)>0
        ghost object on i
        show object oExplosion
        position object oExplosion,object position x(i),object position y(i),object position z(i)
        scale object oExplosion,exAlien(i-oAlienS),exAlien(i-oAlienS),exAlien(i-oAlienS)
        fade object oExplosion,150-exAlien(i-oAlienS)
        fade object i,100-exAlien(i-oAlienS)
        inc exAlien(i-oAlienS)
        if exAlien(i-oAlienS)=100
          hide object oExplosion
          hide object i
        endif
      endif
    endif
  next i
  for i=1 to shots
    if afire(i)>0
      position object i+oShotS-1,xfire(i),yfire(i),zfire(i)
      nx#=xfire(i)+xvfire(i)
      ny#=yfire(i)+yvfire(i)
      nz#=zfire(i)+zvfire(i)
      for j=oAlienS to oAlienF
        if exAlien(j-oAlienS)=0
          hit=intersect object(j,xfire(i),yfire(i),zfire(i),nx#,ny#,nz#)
          if hit>0
            afire(i)=0
            hide object i+oShotS-1
            exAlien(j-oAlienS)=1
          endif
        endif
      next j
      if afire(i)>0
        inc afire(i)
        if afire(i)>100
          afire(i)=0
          hide object i+oShotS-1
        else
          xfire(i)=nx#
          yfire(i)=ny#
          zfire(i)=nz#
        endif
      endif
    endif
  next i
  position object oSky,object position x(oShip),object position y(oShip),object position z(oShip)
  hud()
  ink rgb(0,0,255),64
  set cursor 430,725
  set text opaque
  print " Ship velocity:";int(velocity*1000)
  set cursor 430,745
  print "Orbital height:";int(height#);
  instructions()
  sync
endwhile
end
 
function make_ship()
  make object box oShip,20,75,20
rem  color object oShip,rgb(128,128,128)
  make object cylinder oShip+1,20
  make mesh from object mShip+1,oShip+1
  delete object oShip+1
  add limb oShip,1,mShip+1
  add limb oShip,2,mShip+1
  add limb oShip,3,mShip+1
  delete mesh mShip+1
  offset limb oShip,1,-10,30.5,-5
  offset limb oShip,2,10,30.5,-5
  offset limb oShip,3,0,31.5,10
rem  color limb oShip,1,rgb(128,128,128)
rem  color limb oShip,2,rgb(128,128,128)
rem  color limb oShip,3,rgb(128,128,128)
  make object sphere oShip+1,20,20,20
  scale object oShip+1,100,10,100
  make mesh from object mShip+1,oShip+1
  delete object oShip+1
  add limb oShip,4,mShip+1
  add limb oShip,5,mShip+1
  add limb oShip,6,mShip+1
  add limb oShip,7,mShip+1
  add limb oShip,8,mShip+1
  add limb oShip,9,mShip+1
  delete mesh mShip+1
  offset limb oShip,4,-10,39.5,-5
  offset limb oShip,5,10,39.5,-5
  offset limb oShip,6,0,40.5,10
  offset limb oShip,7,-10,40,-5
  offset limb oShip,8,10,40,-5
  offset limb oShip,9,0,41,10
rem  color limb oShip,7,rgb(255,0,0)
rem  color limb oShip,8,rgb(255,0,0)
rem  color limb oShip,9,rgb(255,0,0)
  make object box oShip+1,20,20,5
  make mesh from object mShip+1,oShip+1
  delete object oShip+1
  add limb oShip,10,mShip+1
  add limb oShip,11,mShip+1
  add limb oShip,12,mShip+1
  delete mesh mShip+1
  offset limb oShip,10,-29,30,-10
  offset limb oShip,11,29,30,-10
  offset limb oShip,12,0,30,29.5
  rotate limb oShip,10,0,-15,0
  rotate limb oShip,11,0,15,0
  rotate limb oShip,12,0,90,0
rem  color limb oShip,10,rgb(128,128,128)
rem  color limb oShip,11,rgb(128,128,128)
rem  color limb oShip,12,rgb(128,128,128)
  hide limb oShip,7
  hide limb oShip,8
  hide limb oShip,9
  xrotate object oShip,-90
  fix object pivot oShip
  create bitmap 1,64,64
  ink rgb(64,64,64),0
  box 0,0,63,63
  ink rgb(128,128,128),0
  for i=0 to 63 step 2
    for j=0 to 63 step 2
      dot i,j
    next j
  next i
  get image iShip,0,0,63,63
  delete bitmap 1
  set current bitmap 0
  create bitmap 1,64,64
  ink rgb(255,0,0),0
  box 0,0,63,63
  for i= 1 to 62
    ink rgb(255-(i*3),0,0),0
    circle 32,32,i
  next i
  get image iEngine,0,0,63,63
  delete bitmap 1
  set current bitmap 0
  texture object oShip,iShip
  texture limb oShip,7,iEngine
  texture limb oShip,8,iEngine
  texture limb oShip,9,iEngine
  scale object oShip,10,10,10
  set object diffuse oShip,rgb(128,128,128)
  set object specular oShip,rgb(128,128,128)
  set object emissive oShip,rgb(64,64,64)
  set object specular power oShip,90
  set object ambient oShip,0
  set object light oShip,1
endfunction
 
function make_planet()
  make object sphere oPlanet,1000,30,30
  make object sphere oAtmosphere,1040,30,30
  create bitmap 1,2048,2048
  ink rgb(0,128,255),0
  box 0,0,2047,2047
  ink rgb(128,128,0),0
  dim x(8)
  dim y(8)
  for i=1 to 800
    x=rnd(2047)
    y=rnd(2047)
    for j=1 to 80
      ink rgb(255-j*2,255-j*2,255),0
      angle=j*9
      x1=cos(angle)*j
      y1=sin(angle)*j
      circle x+x1,y+y1,j/2
      circle x-x1,y-y1,j/2
    next j
  next i
  get image iPlanet,0,0,2047,2047
  delete bitmap 1
  set current bitmap 0
  texture object oPlanet,iPlanet
  set object ambient oPlanet,0
  set object light oPlanet,1
  set object filter oPlanet,2
  texture object oAtmosphere,iPlanet
  ghost object on oAtmosphere
  set object ambient oAtmosphere,1
  fade object oAtmosphere,120
endfunction
function make_aliens()
  make object cube oAlienS,20
  create bitmap 1,256,256
  for i=0 to 255 step 8
    g=rnd(10)
    l=rnd(5)
    ink rgb(g*25,g*25,g*25),0
    box i+j,0,i+j+3,255
    ink 0,0
    box i+j+1,l*15,i+j+2,255-l*15
  next i
  for i=0 to 255 step 8
    g=rnd(10)
    l=rnd(5)
    ink rgb(g*25,g*25,g*25),0
    box 0,i+j,255,i+j+3
    ink 0,0
    box l*15,i+j+1,255-l*15,i+j+2
  next i
  get image iAlien,0,0,255,255
  delete bitmap 1
  set current bitmap 0
  texture object oAlienS,iAlien
  scale object oAlienS,30,30,30
  for i=oAlienS+1 to oAlienF
    clone object i,oAlienS
  next i
endfunction
function make_stars()
  make object sphere oSky,19900
  set object cull oSky,0
  create bitmap 1,2048,2048
  ink rgb(255,255,255),0
  for i=1 to 2048
    x=rnd(2048)
    y=rnd(2048)
    dot x,y
  next i
  get image iSky,0,0,2047,2047
  delete bitmap 1
  set current bitmap 0
  texture object oSky,iSky
  set object ambient oSky,0
endfunction
function make_shots()
  make object sphere oShotS,2
  color object oShotS,rgb(255,128,128)
  set object ambience oShotS,rgb(255,0,0)
  set object emissive oShotS,rgb(255,0,0)
  for i=1 to shots
    clone object oShotS+i,oShotS
  next i
endfunction
function make_explosion()
  make object sphere oExplosion,100
  texture object oExplosion,iAlien
  ghost object on oExplosion
  set object emissive oExplosion,rgb(255,0,0)
  set object ambience oExplosion,rgb(255,0,0)
  set object diffuse oExplosion,rgb(255,0,0)
  hide object oExplosion
endfunction
function crash()
  set text size 20
  ink rgb(192,192,192),0
  box 300,200,700,400
  ink rgb(64,64,64),0
  box 310,210,690,390
  ink rgb(255,255,255),0
  text 320,240,"Spacecraft burned up in atmosphere"
  sync
  wait key
endfunction
function title()
  set current bitmap 0
  sync
  ink rgb(255,255,255),0
  set text size 20
  text 350,300,"You are in orbit around a planet."
  text 350,320,"You must shoot down the alien satellites that are"
  text 350,340,"also in orbit around the planet."
  text 350,360,"Watch your orbital height. Do not degrade your orbit"
  text 350,380,"too much or you will enter the atmosphere."
  sync
endfunction
function instructions()
  set cursor 0,700
  print "Arrows = rotate ship"
  print "Shift  = thrust"
  print "Space  = fire"
  print "R      = radar (on/off)";
endfunction
function make_hud()
  make object plain oHud,10,10
  create bitmap 1,100,100
  ink 0,0
  box 0,0,99,99
  ink rgb(0,0,255),0
  set text font "arial"
  set text size 16
  text 0,20,"Ship direction"
  line 0,10,0,15
  line 0,15,98,15
  line 99,15,98,10
  get image iHud,0,0,99,99,1
  delete bitmap 1
  set current bitmap 0
  set object transparency oHud,1
  texture object oHud,iHud
  yrotate object oHud,180
  fix object pivot oHud
  disable object zdepth oHud
  make object cone oDir,5
  scale object oDir,15,100,15
  ghost object on oDir
  color object oDir,rgb(0,0,255)
  set object ambience oDir,rgb(0,0,255)
  disable object zdepth oDir
  xrotate object oDir,90
  fix object pivot oDir
endfunction
function hud()
  move camera 50
  position object oHud,camera position x(),camera position y()-28,camera position z()
  set object to camera orientation oHud
  position object oDir,camera position x(),camera position y()-23,camera position z()
  point object oDir,object position x(oDir)+xvShip,object position y(oDir)+yvShip,object position z(oDir)+zvShip
  move camera -50
endfunction