`Challenge Compo - Asteroids Game
`by Bill Robinson
`due: 2-25-06
 
`@Kimosabi - you do NOT have rights to use this program as your own.
`And you never should have used Ric's pong game as your own, on your web sight!
`
`Use 'Z' and 'X' to rotate ship, leftarrow and rightarrow work too
`Use comma ',' to fire, period '.' to thrust
`Use 'Space' to Hyperspace to a new position
`Use 'Shift' for shields, you have a limited number of shields per level
`You only get 5 shots on the screen at a time
`
`Using Hyperspace FREEZES TIME while your ship is in hyperspace traveling to new location.
`If ship traveling through Hyperspace lands on an asteroid,
`you have a brief moment to engage Hyperspace again to save your ship
`Hyperspace will also bring your moving ship to a stop
`
set display mode 1024,768,32
autocam off
sync on
sync rate 60
Hide Mouse
Backdrop on
Color Backdrop 0
set ambient light 15
set camera range 1,5000
randomize timer()
 
`--- Game Setup ---
#constant MAX_ASTEROIDS 199
global GREEN
GREEN=rgb(0,255,0)
global RED
RED=rgb(255,0,0)
global level
global newlevel
global score
global targetsleft
global numasteroids
global lives
global playersafetime
global shields
global syncrate=60
 
`--- Player ---
global ship_x#
global ship_y#
global ship_z#=0
global shipangle#
global shipthrust#
global shipmass#
global explode_object=0
global expdone=0
global exparrayindex=1
global expparticleindex=1
global numhits
global playerdeadtime
global velx#=0
global vely#=0
global shipincx#=0
global shipincy#=0
 
`--- enemy ---
`1=active, 2=size, 3=x, 4=y, 5=z, 6=xinc, 7=yinc, 8=zinc, 9=color
dim enemy#(10)
dim eshots#(10)
 
`--- asteroids ---
`1=active, 2=size, 3=x, 4=y, 5=z, 6=xinc, 7=yinc, 8=zinc, 9=xrot,10=yrot, 11=zrot, 12=color
dim ast_info#(MAX_ASTEROIDS,15)
` highest number of vertexes = 200 for now
global vcount=200
dim vertex_count(199)
dim v_pos_x#(199,vcount)
dim v_pos_y#(199,vcount)
dim v_pos_z#(199,vcount)
 
`--- explosion particles ---
rem Arrays for position, velocity and life of each explosion particle
dim partx#(300)
dim party#(300)
dim partz#(300)
dim partxvel#(300)
dim partyvel#(300)
dim partzvel#(300)
dim partlife(300)
dim explosion(10,10)
global start_time=0
global inten#=60.0
global max=200
 
`--- ship thrust ---
dim thrust#(50,10)
global thrustptr
 
`--- Shots Fired ---
dim shots(100,4)
global shotptr
global shotspeed#
global lastshot
global shottime
global shotpause
global hitnum
global maxshots
global numshots
 
`--- Players shots getting made ---
for i=400 to 410
   make object sphere i,30,3,3
   xrotate object i,90
   color object i,rgb(255,255,255)
   scale object i,20,20,100
   set object collision off i
   hide object i
next i
 
`--- hyperspace ships ---
global numhyper=5
dim hyperinfo#(numhyper,6)
color=GREEN
for i=1 to numhyper
   obnum=1020+i
   make object cone obnum, 20
 
   color object obnum,color
   ghost object on obnum
   hide object obnum
next i
 
`------------------------
screen_xmax=screen width()
screen_ymax=screen height()
screen_center=screen_xmax/2
 
`--- make cone for ship ---
make object cone 1000,20
color object 1000,rgb(0,255,0)
set object collision on 1000
set object collision to spheres 1000
fix object pivot 1000
 
make object sphere 1001,50
color object 1001,rgb(0,255,255)
set object collision off 1001
ghost object on 1001
`set object wireframe 1001,1
set object ambient 1001,0
position object 1001,-2700,-2700,-2700
 
make object cone 4000,50
scale object 4000,100,50,100
color object 4000,rgb(255,0,0)
set object collision on 4000
set object collision to spheres 4000
position object 4000,-2600,-2600,-2600
 
`--- make exhaust particles ---
for i=1 to 40
   color=rgb(rnd(55)+200,rnd(55)+200,0)
   obnum=600+i
   make object plain obnum,2,2
   color object obnum,color
   hide object obnum
next i
 
`--- make explosion pieces ---
color=rgb(255,255,255)
for i=1 to max
   obnum=199+i
   make object plain obnum,6,6
   color object obnum,color
   hide object obnum
next i
 
_reset_vars()
_make_stars()
 
`--- setup starfield in background ---
make object plain 998,1300,1000
texture object 998, 1
position object 998,0,0,200
 
`--- debug limits of screen, for wrap-around of objects ---
global lwall=-480
global rwall=480
global twall=360
global bwall=-360
 
position object 1000, 0,0,0
position camera 0,0,-600
point camera 0,0,0
 
do
   set object collision on 1000
 
   if newlevel=1
      _new_level()
   endif
   if targetsleft=0 then newlevel=1
 
   `explosion 1=active flag, 2=object, 3=#particles, 4=intensity, 5=particle life, 6=particle start num, 7=color
   if keystate(48)=1                            :`b key - self destruct
      _set_explosion(1000,50,30,100,GREEN)
      playerdeadtime=200
   endif
 
   if leftkey()=1 then inc shipangle#,3         :`left arrow key
   if rightkey()=1 then dec shipangle#,3        :`right arrow key
   if keystate(44)=1 then inc shipangle#,3      :`z key
   if keystate(45)=1 then dec shipangle#,3      :`x key
   if keystate(29)=1 then _fire_missle()        :`ctrl key
   if keystate(42)=1 or keystate(54)=1 then _raise_shields()
   if keystate(57)=1                            :`space key
      _hyperspace(1)
      velx#=0:vely#=0:shipincx#=0:shipincy#=0
   endif
 
   if keystate(51)=1 and numshots<maxshots then _shoot()
   if keystate(52)=1
      shipincx#=-sin(shipangle#)*shipthrust#
      shipincy#=cos(shipangle#)*shipthrust#
      _start_thrust()
   else
      shipincx#=0
      shipincy#=0
   endif
 
   `calc ship velocity
   deltax#=shipincx#/shipmass#
   deltay#=shipincy#/shipmass#
   inc velx#,deltax#
   inc vely#,deltay#
 
   inc ship_x#,velx#
   inc ship_y#,vely#
 
   _show_thrust()
 
   shipangle#=wrapvalue(shipangle#)
   ship_x#=_ship_screen_wrapx(ship_x#)             :`wrap players ship around screen if needed
   ship_y#=_ship_screen_wrapy(ship_y#)
 
   zrotate object 1000,shipangle#                  :`rotate players ship
   position object 1000,ship_x#,ship_y#,ship_z#    :`position ship on screen
   if playersafetime>0 and playerdeadtime=0
      position object 1001,ship_x#,ship_y#-5,ship_z#    :`safety shield
   else
      position object 1001,-2500,-2500,-2500
   endif
 
   _check_newexplosions()
   _check_asthits()           :`check for player hits from shots
   _move_shots()              :`move player shots
   _continue_explosion()      :`continue to explode pieces
   _move_asteroids()
   if lives=0 then _game_over()
 
   if playersafetime>0
      dec playersafetime
   else
      _check_playerhit()
   endif
 
   if level>1
      if enemy#(1)=0
         _start_enemy()
      else
         _move_enemy()
      endif
   endif
 
`   _check_enemyhit()
 
   if playerdeadtime>0
      dec playerdeadtime
      if playerdeadtime<200 then center text screen width()/2,300,"GET READY! - For Next Ship"
      if playerdeadtime=0
         velx#=0:vely#=0:shipincx#=0:shipincy#=0
         _hyperspace(2)
         set object collision on 1000
         playersafetime=120
      endif
   endif
 
   if expdone=1
      explode_object=0
      start_time=0
      expdone=0
   endif
 
   if numshots<=0 then numshots=0      :`just correcting for a bug I haven't figured out yet
 
   set cursor 1,1
   print screen fps()
   center text screen_center,10,"Level: "+str$(level)+"      Lives: "+str$(lives)+"      Targets Left: "+str$(targetsleft)+"      Shields: "+str$(shields)+"      Score: "+str$(score)
   sync
loop
 
 
function _start_thrust()
thrustlife=10
i=thrustptr
if thrust#(i,1)=0
   thrust#(i,1)=1
   thrust#(i,2)=ship_x#
   thrust#(i,3)=ship_y#
   thrust#(i,4)=-shipincx#-(rnd(3)/4.0)
   thrust#(i,5)=-shipincy#-(rnd(3)/4.0)
   thrust#(i,6)=thrustlife
   inc thrustptr
   if thrustptr>40 then thrustptr=1
   show object 600+i
endif
endfunction
 
 
function _show_thrust()
for i=1 to 40
   if thrust#(i,6)>0
      position object 600+i,thrust#(i,2),thrust#(i,3),0
      dec thrust#(i,6)
      inc thrust#(i,2),thrust#(i,4)
      inc thrust#(i,3),thrust#(i,5)
   else
      thrust#(i,1)=0
      hide object 600+i
   endif
next i
endfunction
 
 
function _start_enemy()
`1=active, 2=size, 3=x, 4=y, 5=z, 6=xinc, 7=yinc, 8=yloc_change, 9=vis_counter
if enemy#(1)=0
   if enemy#(9)>0
      dec enemy#(9)
   else
      enemy#(1)=1
      enemy#(3)=-500.0
      enemy#(4)=rnd(320)-100
      enemy#(5)=0
      enemy#(6)=(rnd(120)+60)/60.0
      enemy#(7)=0
      enemy#(8)=rnd(100)+50
`      enemy#(9)=rnd(1000)+2000
      position object 4000,enemy#(3),enemy#(4),enemy#(5)
      show object 4000
   endif
endif
endfunction
 
 
function _move_enemy()
`1=active, 2=size, 3=x, 4=y, 5=z, 6=xinc, 7=yinc, 8=yloc_change, 9=vis_counter
if enemy#(1)=1
   dec enemy#(8)
   inc enemy#(3),enemy#(6)
   if enemy#(4)<300 and enemy#(4)>-300 then inc enemy#(4),enemy#(7)
   position object 4000,enemy#(3),enemy#(4),enemy#(5)
   if enemy#(8)<0
      enemy#(8)=rnd(50)+50
      enemy#(7)=(rnd(360)-180)/60.0
   endif
   if enemy#(3)>500
      enemy#(1)=0
      position object 4000,-2700,-2700,-2700
      enemy#(8)=rnd(50)+50
      enemy#(9)=rnd(1000)+2000
   endif
endif
endfunction
 
 
function _enemy_shots()
 
endfunction
 
 
function _raise_shields()
if shields>=200 and playersafetime=0
   playersafetime=200
   dec shields,200
endif
endfunction
 
 
function _check_newexplosions()
  for ex=1 to 10
      if explosion(ex,1)=1
         ex#=object position x(explosion(ex,2))
         ey#=object position y(explosion(ex,2))
         ez#=object position z(explosion(ex,2))
         if expparticleindex+explosion(ex,3)>=200
            expparticleindex=1
         endif
         explosion(ex,6)=expparticleindex
         inc expparticleindex,explosion(ex,3)
   `explosion() 1=active flag, 2=object, 3=#particles, 4=intensity, 5=particle life, 6=particle start num, 7=color
         _request_explosion(ex#,ey#,ez#,explosion(ex,3),explosion(ex,4),explosion(ex,5),explosion(ex,6),explosion(ex,7))
         start_time=1
 
         hide object explosion(ex,2)               :`was explode_object
         set object collision off explosion(ex,2)  :`was explode_object
         explosion(ex,1)=2
      endif
   next ex
endfunction
 
 
`--- move asteroids ---
function _move_asteroids()
for i=1 to numasteroids
   pitch object down i,ast_info#(i,9)           :`tumble asteroids in all three axis
   turn object right i,ast_info#(i,10)
   roll object right i,ast_info#(i,11)
 
   inc ast_info#(i,3),ast_info#(i,6)
   inc ast_info#(i,4),ast_info#(i,7)
      `--- wrap asteroids around screen if needed -----
   ast_info#(i,3)=_asteroid_screen_wrapx(ast_info#(i,3),ast_info#(i,2))    :`returns a screen wrap coord if object x-value went off screen
   ast_info#(i,4)=_asteroid_screen_wrapy(ast_info#(i,4),ast_info#(i,2))    :`returns a screen wrap coord if object y-value went off screen
   position object i,ast_info#(i,3),ast_info#(i,4),ast_info#(i,5)          :`position asteroid in new location
next i
endfunction
 
 
`--- array entry for another explosion ---
function _set_explosion(object,numparticles,intensity,particlelife,color)
explosion(exparrayindex,1)=1                 :`explosion flag 1=on 0=off
explosion(exparrayindex,2)=object            :`object to explode
explosion(exparrayindex,3)=numparticles      :`number of particles
explosion(exparrayindex,4)=intensity         :`intensity
explosion(exparrayindex,5)=particlelife      :`particle life
explosion(exparrayindex,7)=color             :`color of particles
inc exparrayindex
if exparrayindex>10 then exparrayindex=1
endfunction
 
 
function _game_over()
do
   center text screen width()/2,10,"Level: "+str$(level)+"     Lives: "+str$(lives)+"    Targets Left: "+str$(targetsleft)+"     Score: "+str$(score)
   center text screen width()/2,300,"GAME OVER - Thanks For Playing!"
   center text screen width()/2,350,"Press escape key to exit"
   _check_newexplosions()
   _continue_explosion()
   _move_asteroids()
   sync
loop
endfunction
 
 
`--- builds new level ---
function _new_level()
inc level
set text font "Arial"
set text size 18
sync
center text screen width()/2,300,"Get Ready - For Level "+str$(level)
sync
wait 1000
numasteroids=0
newasteroids=7+level
for i=1 to 199
   if object exist(i)=1
      delete object i
   endif
next i
 
size=3
_add_asteroids(newasteroids,size,0)
newlevel=0
 
ship_x#=0
ship_y#=0
playersafetime=200
numshots=0
shields=1000
if level>1 then enemy#(9)=2000          :`reset enemy visible counter
endfunction
 
 
function _check_playerhit()
hnum=object collision(1000,0)
   if hnum>0
      if hnum<=199
         inc numhits
         if numhits>50
            hide object 1000                           :`hide player ship
            set object collision off 1000
            position object 1000,-2000,-2000,-2000     :`just move offscreen
            _set_explosion(1000,50,30,100,GREEN)
            numhits=0
            playerdeadtime=400
            playersafetime=450
            dec lives
         endif
      endif
   endif
endfunction
 
 
function _check_enemyhit()
sync rate 0
for i=1 to 10
   if shots(i,1)=1
      objnum=shots(i,2)
      hitnum=object collision(objnum,0)
      if hitnum>0
         if hitnum=4000
            hide object objnum                           :`hide shot
            set object collision off objnum
            position object objnum,-3000,-3000,-3000     :`just move offscreen
 
            hide object hitnum                           :`hide asteroid
            set object collision off hitnum
            position object hitnum,-2000,-2000,-2000     :`just move offscreen
 
            inc score,200
            _remove_shot(objnum)
            shots(i,1)=0
            _set_explosion(hitnum,10,10,20,RED)
         endif
      endif
   endif
next i
sync rate syncrate
endfunction
 
 
function _check_asthits()
sync rate 0
for i=1 to 10
   if shots(i,1)=1
      objnum=shots(i,2)
      hitnum=object collision(objnum,0)
      if hitnum>0
         if hitnum<199
            hide object objnum                           :`hide shot
            set object collision off objnum
            position object objnum,-3000,-3000,-3000     :`just move offscreen
 
            hide object hitnum                           :`hide asteroid
            set object collision off hitnum
            position object hitnum,-2000,-2000,-2000     :`just move offscreen
 
            inc score,10
            dec targetsleft
            _remove_shot(objnum)
            shots(i,1)=0
            size=ast_info#(hitnum,2)                     :`size of the hit asteroid
            if size>1
               _add_asteroids(2,size-1,hitnum)
            endif
            _set_explosion(hitnum,10,3*size,20,ast_info#(hitnum,12))
         endif
      endif
   endif
next i
sync rate syncrate
endfunction
 
 
`--- Player Shots - 1=active, 2=obnum, 3=shotlife, ---
function _shoot()
shottime=timer()-lastshot
if shottime<shotpause then exitfunction
   position object shotptr,ship_x#,ship_y#,0
   show object shotptr
   zrotate object shotptr,shipangle#
   set object collision on shotptr
   set object collision to spheres shotptr
   shots(shotptr-399,1)=1
   shots(shotptr-399,2)=shotptr
   shots(shotptr-399,3)=500
   inc shotptr
   if shotptr>=410 then shotptr=400
   lastshot=timer()
   inc numshots
endfunction
 
 
function _move_shots()
   for i=1 to 10
      if shots(i,1)=1
         obnum=shots(i,2)
         move object obnum,-shotspeed#
         posx#=object position x(obnum)
         posy#=object position y(obnum)
         posx#=_ship_screen_wrapx(posx#)
         posy#=_ship_screen_wrapy(posy#)
         position object obnum,posx#,posy#,0
         dec shots(i,3),shotspeed#
         if shots(i,3)<=0
            _remove_shot(obnum)
            shots(i,1)=0
         endif
      endif
   next i
endfunction
 
 
function _remove_shot(obnum)
set object collision off obnum
position object shotptr,-2000,-2000,-2000    :`just move offscreen
hide object obnum
dec numshots
endfunction
 
 
function _fire_missle()
 
endfunction
 
 
function _asteroid_screen_wrapx(x#,size#)
limit#=490+size#*15.0
if x#>limit# then x#=-limit#
if x#<-limit# then x#=limit#
endfunction x#
 
 
function _asteroid_screen_wrapy(y#,size#)
limit#=380+size#*15.0
if y#>limit# then y#=-limit#
if y#<-limit# then y#=limit#
endfunction y#
 
 
function _ship_screen_wrapx(x#)
if x#>500 then x#=-500
if x#<-500 then x#=500
endfunction x#
 
 
function _ship_screen_wrapy(y#)
if y#>380 then y#=-380
if y#<-380 then y#=380
endfunction y#
 
 
function _make_stars()
ink rgb(255,255,255),0
for x=1 to 250
   dot rnd(1024),rnd(768)
next x
get image 1,0,0,1024,768,1
endfunction
 
 
function _reset_vars()
   level=0
   newlevel=1
   targetsleft=0
   numasteroids=0
   lives=5
   playersafetime=100
 
   ship_y#=0
   ship_x#=0
   shipthrust#=3.0
   shipmass#=50.0
 
   expdone=0
   exparrayindex=1
   expparticleindex=1
   shotptr=400
   shotspeed#=4
   shotpause=150
   maxshots=5
   numshots=0
 
   fusetime#=1
   fuselength=1
   boomflag=0
 
   thrustptr=1
endfunction
 
 
`--------DB demo routines for explosions--------
function _request_explosion(ex#,ey#,ez#,particles,intensity#,life,partindex,color)
for i=partindex to partindex+particles
   partlife(i)=life + rnd(life/5)
   partx#(i)=ex#
   party#(i)=ey#
   partz#(i)=ez#
   partyvel#(i)=rnd(intensity#)-(intensity#/2)
   partxvel#(i)=rnd(intensity#)-(intensity#/2)
   partzvel#(i)=rnd(intensity#)-(intensity#/2)
   show object 199+i
   color object 199+i,color
next i
endfunction
 
 
`explosion 1=active flag, 2=object, 3=#particles, 4=intensity, 5=particle life, 6=particle start num, 7=
function _continue_explosion()
for ex=1 to 10
   if explosion(ex,1)=2
      for t=explosion(ex,6) to explosion(ex,6)+explosion(ex,3)
         if partlife(t)>1
            dec partlife(t)
            position object 199+t,partx#(t),party#(t),partz#(t)
            partxvel#(t)=partxvel#(t)*0.98                 :`was 0.95
            partyvel#(t)=partyvel#(t)*0.98
`           partzvel#(t)=partzvel#(t)*0.95                 :`particles slow down from air friction
            partzvel#(t)=0.0
`           partyvel#(t)=partyvel#(t)-0.5                  :`particles effected by gravity
            inc partx#(t),partxvel#(t)
            inc party#(t),partyvel#(t)
            inc partz#(t),partzvel#(t)
`           if party#(t)<=0 then partyvel#(t)=partyvel#(t)*-0.7     :`particles bounce on the ground
            rotate object t+199,wrapvalue(object angle x(t+199)+rnd(50)),wrapvalue(object angle y(t+199)+rnd(100)),0
         endif
         if partlife(t)=1
            partlife(t)=0
            hide object 199+t
            start_time=0
            expdone=1
`            explosion(ex,1)=0
         endif
      next t
   endif
next ex
endfunction
 
 
function _add_asteroids(num,size,hitnum)
sync rate 0
for i=1 to num
   astnum=numasteroids+1
   _make_asteroids(astnum,size)
 
   set object smoothing astnum,0
   set object collision on astnum
   set object collision to spheres astnum
`1=active, 2=size, 3=x, 4=y, 5=z, 6=xinc, 7=yinc, 8=zinc, 9=xrot,10=yrot, 11=zrot, 12=color
   ast_info#(astnum,1)=1
   ast_info#(astnum,2)=size
   if hitnum>0
      ast_info#(astnum,3)=ast_info#(hitnum,3)     :`use larger asteroid location
      ast_info#(astnum,4)=ast_info#(hitnum,4)
   else
      ast_info#(astnum,3)=rnd(1200)-600           :`random location
      ast_info#(astnum,4)=rnd(1200)-600
   endif
   ast_info#(astnum,5)=0
 
   v#=(rnd(3)+0.8)/(rnd(8)+size)       :`generate a motion value
   d=rnd(10):if d>5 then v#=v#*-1.0    :`decide whether a positive or negative motion
   ast_info#(astnum,6)=v#
 
   v#=(rnd(3)+0.8)/(rnd(8)+size)       :`generate a motion value
   d=rnd(10):if d>5 then v#=v#*-1.0    :`decide whether a positive or negative motion
   ast_info#(astnum,7)=v#
 
   ast_info#(astnum,8)=0
 
   v#=rnd(3)/(rnd(10)+1.0)             :`generate a rotation value
   d=rnd(10):if d>5 then v#=v#*-1.0    :`decide whether a positive or negative rotation
   ast_info#(astnum,9)=v#
 
   v#=rnd(3)/(rnd(10)+1.0)
   d=rnd(10):if d>5 then v#=v#*-1.0
   ast_info#(astnum,10)=v#
 
   v#=rnd(3)/(rnd(10)+1.0)
   d=rnd(10):if d>5 then v#=v#*-1.0
   ast_info#(astnum,11)=v#
 
   if hitnum>0
      color=ast_info#(hitnum,12)     :`use larger asteroid color
   else
      color=rgb(rnd(255),rnd(255),rnd(255))  :`use random color
   endif
   ast_info#(astnum,12)=color
   color object astnum,ast_info#(astnum,12)
   position object astnum,ast_info#(astnum,3),ast_info#(astnum,4),ast_info#(astnum,5)
   show object astnum
 
   inc numasteroids
   inc targetsleft
next i
sync rate syncrate
endfunction
 
 
` ----- Make Asteroids --- Trying vertex commands for the first time! -----
function _make_asteroids(num,size)
objs=num
make object sphere objs,60
if size=2 then scale object objs,70,70,70
if size=1 then scale object objs,30,30,30
 
` get vertex data
ob=objs
make mesh from object 1,ob
lock vertexdata for mesh  1
vertex_count(ob)=(GET VERTEXDATA VERTEX COUNT()-1)
for v=0 to vertex_count(ob)
   v_pos_x#(ob,v)=GET VERTEXDATA POSITION X(v)+object position x(ob)
   v_pos_y#(ob,v)=GET VERTEXDATA POSITION y(v)+object position y(ob)
   v_pos_z#(ob,v)=GET VERTEXDATA POSITION z(v)+object position z(ob)
next v
unlock vertexdata
delete mesh 1
 
` deform vertices 4-10 times for jagged look
for deftimes=1 to (rnd(6)+4)
   make mesh from object 1,ob
   lock vertexdata for mesh  1
   for i=0 to vertex_count(ob)
      xdir=rnd(10):if xdir>5 then xdir=1 else xdir=-1
      ydir=rnd(10):if ydir>5 then ydir=1 else ydir=-1
      zdir=rnd(10):if zdir>5 then zdir=1 else zdir=-1
      inc v_pos_x#(ob,i),rnd(5)*xdir
      inc v_pos_y#(ob,i),rnd(5)*ydir
      inc v_pos_z#(ob,i),rnd(5)*zdir
      SET VERTEXDATA POSITION i, v_pos_x#(ob,i),v_pos_y#(ob,i),v_pos_z#(ob,i)
   next i
   unlock vertexdata
   make object 5000,1,0
   delete mesh 1
   delete object ob
   clone object ob,5000
   delete object 5000
next deftimes
endfunction
 
 
` ----- Hyperspace ship to new location --- This was interesting to work out -----
function _hyperspace(source)
sync rate 0
hyperflag=1
numslices=3
destx#=rnd(850)-425
desty#=rnd(650)-325
hide object 1000
 
for i=1 to numhyper
   if source=2
      ship_x#=1500
      ship_y#=400
   endif
   hyperinfo#(i,1)=ship_x#
   hyperinfo#(i,2)=ship_y#
 
   obnum=1020+i
   xrotate object obnum,object angle x(1000)
   yrotate object obnum,object angle y(1000)
   zrotate object obnum,object angle z(1000)
   position object obnum,hyperinfo#(i,1), hyperinfo#(i,2), 0
   show object obnum
next i
 
hyperinfo#(1,1)=destx#
hyperinfo#(1,2)=desty#
position object 1021,hyperinfo#(1,1), hyperinfo#(1,2), 0
 
count=0
while hyperflag=1
   for i=2 to numhyper
      hyperinfo#(i,3)=(hyperinfo#(i-1,1)-hyperinfo#(i,1))/numslices
      hyperinfo#(i,4)=(hyperinfo#(i-1,2)-hyperinfo#(i,2))/numslices
      inc hyperinfo#(i,1),hyperinfo#(i,3)
      inc hyperinfo#(i,2),hyperinfo#(i,4)
      position object 1020+i,hyperinfo#(i,1), hyperinfo#(i,2), 0
      sync
   next i
   inc count
   if count>=numhyper*numslices*2 then hyperflag=0
endwhile
ship_x#=destx#
ship_y#=desty#
box_xdir#=0
box_ydir#=0
position object 1000,ship_x#,ship_y#,ship_z#
show object 1000
 
for i=1 to numhyper
   hide object 1020+i
next i
sync
sync rate syncrate
endfunction