Challenge: 
Winner?: 
Yes
Code Snippet: 
`Trench Runner
`======================
`? CPU
`======================
`Main Source File

#constant trenchLength = 20
#constant crossBridgeObjQty = 3
#constant crossBridgeChance = 5
#constant maxBlastObjects = 200
#constant bumpMappingOn = 0
#constant turretMax = 25
#constant turretProb = 10
#constant maxShips = 10
#constant maxActionKeys = 30
#constant maxBooms = 27
#constant trenchCeil = 20
#constant maxMessages = 20
#constant hasMessagePanel = 1
#constant winDistance = 5000

#constant pitchSpeed = 1.0
#constant turnSpeed = 1.0
#constant rollSpeed = 0.7

#constant moveSpeed = 0.75
#constant accSpeed = 0.1
#constant fireRate = 90
#constant pathChangeChance = 30
#constant lookAheadDist = 70
#constant randBurstChance = 10
#constant underFireEvadeChance = 50
#constant EvadeAmnt = 1.0
#constant blastDamage = 20
#constant StartSepDist = 20

#constant AutoBReloadTime = 1000

#constant empireShipSize = 0.50
#constant rebelShipSize = 1.0
#constant pathFuzzy = 0.1

#constant cSize = 0.50

#constant turretLead = 25

#constant rayLen = 10000

`helpfull constants
#constant EmpireShip = 2
#constant RebelShip = 1

#constant AIcontrol = 1
#constant playerControl = 2

#constant keyHoldUp = 1
#constant keyJustPressed = 2
#constant keyHoldDown = 3
#constant keyJustReleased = 4

#constant keyPitchUp = 1
#constant keyPitchDown = 2
#constant keyRollLeft = 3
#constant keyRollRight = 4
#constant keyFire = 5
#constant keySlideLeft = 6
#constant keySlideRight = 7
#constant keySlideUp = 8
#constant keySlideDown = 9
#constant keyForward = 10
#constant keyAutoToggle = 11

#constant keyCamRotUp = 12
#constant keyCamRotDown = 13
#constant keyCamRotRight = 14
#constant keyCamRotLeft = 15
#constant keyCamRotRollR = 16
#constant keyCamRotRollL = 17

#constant keyCamMovUp = 18
#constant keyCamMovDown = 19
#constant keyCamMovRight = 20
#constant keyCamMovLeft = 21
#constant keyCamMovFwd = 22
#constant keyCamMovBak = 23

#constant keyToggleFreeRot = 24
#constant keyToggleMsgPan = 25

#constant keyPhotonTorpedo = 26
#constant keySwitchShips = 27
#constant keyPauseKey = 28

sync on
sync rate 0
autocam off
set camera range 0.001,1000
disable escapekey
fog on
fog distance trenchLength*10

color backdrop rgb(0,0,0)

make light 1
point light 1,25,100,0

randomize timer()

position camera 1,5,-10
`position camera 25,25,25
point camera 1,5,0

global trenchObj as integer
global trenchTexture as integer
global trenchBumpmap as integer
global curblock as integer
global endTarget as integer

global greenLaserImg as integer
global redLaserImg as integer
global gridImg as integer
global XwingImg as integer
global bladeImg as integer
global explodeImg as integer
global sWaveImg as integer
global msgPanImg as integer
global msgUpImg as integer
global msgDownImg as integer

global SkyBoxNum as integer
global StarsTexture as integer
global DSTexture as integer

global turretFireRate as integer = 300
global messagesLastUpdate as integer
global msgPanalVisible as integer = 1

global playerShip as integer

global camRotX as float
global camRotY as float
global camRotZ as float
global freeRotToggle as integer

global camOffVert as float = 0.6
global camOffHorz as float
global camOffZ as float = -1.2

global rebelVictory as integer
global empireVictory as integer
global EmpireRecreate as integer
global timeLeft as integer
global prgEnd as integer = 0
global gamePaused as integer
global timeStoped as integer
global stopTime as integer

`FPS independent stuff
`variables for FPS independent
 global FPS as integer
 global GameSpeed as integer
 global LoopConstant as double float
 global LoopTime as integer
 global LastLoopTime as integer
 global LoopSpeed as double float
 global FPSISmoothing as integer
 global MaxLoopTime as integer



 MaxLoopTime = 100
 GameSpeed = 60
 LoopSpeed = 1.0
 FPSISmoothing = 25
 LastLoopTime = timer()

type xyzfloat
   x as float
   y as float
   z as float
endtype

type tsqrType
   objnum as integer
endtype

type colBox
   objNum as integer
   xsize as integer
   ysize as integer
   zsize as integer
endtype

type blastType
   color as integer
   vel as float
   traveledDist as float
   maxDist as float
   objnum as integer
   exist as integer
   startTime as integer
   life as integer
   dynColCheck as float
   live as integer
   BType as integer
endtype

type turretType
   exist as integer
   objNum as integer
   objNumBox as integer
   objNumStand as integer
   reload as integer
   orient as integer
   target as integer
endtype

type autoShip
   controlType as integer
   exist as integer
   side as integer
   objnum as integer
   reload as integer
   intersectUpdate as integer
   roll as float
   vel as float
   newPathOverride as integer
   autoPathX as float
   autoPathY as float
   autoBurst as integer
   autoBreload as integer
   target as integer
   engageTime as integer
   underFire as integer
   health as integer
   incoming as integer
   numTorpedos as integer
endtype

type BoomType
   exist as integer
   boomObj as integer
   shockObj as integer
   scale as float
   scale2 as float
   vanishSize as float
endtype

type keyType
   keycode as integer
   lastState as integer
   currentState as integer
endtype

global dim trenchSqr(trenchLength) as tsqrType
global dim crossBridges(trenchLength,crossBridgeObjQty) as colBox

global dim blast(maxBlastObjects) as blastType
global dim turrets(turretMax) as turretType
global dim autoShips(maxShips) as autoShip
global dim booms(maxBooms) as BoomType

global dim actionKeys(maxActionKeys) as keyType

global dim messages(maxMessages) as string



bladeImg = freeImage()
Blades2Texture(bladeImg)
XwingImg = freeImage()
WhiteStainedTexture(XwingImg)
gridImg = freeImage()
SolarGridTexture(gridImg)
gridImg = freeImage()
SolarGridTexture(gridImg)
greenLaserImg = freeImage()
greenLaserTexture(greenLaserImg)
redLaserImg = freeImage()
redLaserTexture(redLaserImg)
StarsTexture = freeImage()
StarsTexture(StarsTexture)
explodeImg = freeImage()
ExplodeTexture(explodeImg)
sWaveImg = freeImage()
ShockWaveTexture(sWaveImg)
msgPanImg = freeImage()
MessagePanalImg(msgPanImg)

DSTexture = freeImage()
BlockEndTexture(DSTexture)

gosub makeTrenchObj

`cool backround pannel for messages
if hasMessagePanel = 1
   sprite msgPanImg, 0,0,msgPanImg
   set sprite alpha msgPanImg, 125
   hide sprite msgPanImg
endif


`skybox creation
SkyBoxNum = freeObject()
createSkyBox(SkyBoxNum, 1000)

for n = 1 to 6
   texture limb SkyBoxNum, n, StarsTexture
   scale limb texture SkyBoxNum, n, 5,5
next n



for n = 1 to maxBlastObjects
   constructBlast(n)
next n

for n = 1 to turretMax
   buildTurret(n)
next n

`auto ships!!
createAutoShips()

`Kerblooom!!!
makeBooms()

`action keys, change to change controls...
actionKeys(keyPitchUp).keycode = 200
actionKeys(keyPitchDown).keycode = 208
actionKeys(keyRollLeft).keycode = 203
actionKeys(keyRollRight).keycode = 205
actionKeys(keyFire).keycode = 157 `control key
actionKeys(keySlideUp).keycode = 72
actionKeys(keySlideDown).keycode = 80
actionKeys(keySlideLeft).keycode = 75
actionKeys(keySlideRight).keycode = 77
actionKeys(keyForward).keycode = 184 `alt key

actionKeys(keyAutoToggle).keycode = 30 `'a' key

`Extended camera control keys...
actionKeys(keyCamRotUp).keycode = 23
actionKeys(keyCamRotDown).keycode = 37
actionKeys(keyCamRotRight).keycode = 38
actionKeys(keyCamRotLeft).keycode = 36
actionKeys(keyCamRotRollR).keycode = 26
actionKeys(keyCamRotRollL).keycode = 27

actionKeys(keyCamMovUp).keycode = 210
actionKeys(keyCamMovDown).keycode = 211
actionKeys(keyCamMovRight).keycode = 199
actionKeys(keyCamMovLeft).keycode = 207
actionKeys(keyCamMovFwd).keycode = 201
actionKeys(keyCamMovBak).keycode = 209

actionKeys(keyToggleFreeRot).keycode = 46
actionKeys(keyToggleMsgPan).keycode = 50

actionKeys(keyPhotonTorpedo).keycode = 28
actionKeys(keySwitchShips).keycode = 31

actionKeys(keyPauseKey).keycode = 25

remstart
createsound("sparkle1",10,8000,3000,500,30,0.01,10,5,0,0,0.05)
createsound("sparkle2",11,6200,5000,300,30,0.01,10,5,0,0,0.05)
createsound("sparkle3",12,4000,5000,800,30,0.01,10,5,0,0,0.05)
createsound("rocket1",4,1600,1000,4000,0.005,0.2,0,0,0,0,10)
createsound("rocket2",5,1800,1500,8000,0.008,0.2,0,0,0,0,10)
createsound("rocket3",7,2200,2500,500,0.003,0.2,0,0,0,0,10)
createsound("deep explosion",9,30,100,16000,0.00,1.5,.0,0,0,0,100)

soundPlay(10)
soundPlay(11)
soundPlay(12)
soundPlay(4)
soundPlay(5)
soundPlay(7)
soundPlay(9)
remend


`createXwingfighter(1000, 0.5)
`createTIEfighter(1000,0.5)
remstart
make object box 1000,0.25,0.25,0.25
set object collision off 1000
hide object 1000
remend

intro()

do

   resetBullets()
   resetTurrets()
   resetBooms()
   resetShips()
   clearMsgs()

   menu()

   rebelVictory = 0
   empireVictory = 0
   `threee minuts before rebel base ceases to exist...
   timeLeft = getTime() + 180000
   `AddRebelShip(15.0, AIcontrol)

   `createTurret(0, 1.25, 0, 1)

   `make object box 201,2,2,2
   `point object 201,0,0,10
   `tmpFireTime = timer()

   `explode(1000)

   `-------------------------------------------------
   `#################  Enter Main loop  #############
   `-------------------------------------------------

   repeat
      updateKeys()
      updateMessages()

      if wrapvalue(camera angle y()) > 270 or wrapvalue(camera angle y()) < 90
         updateTrench(camera position z(), 10.0, 1)
      else
         updateTrench(camera position z(), 10.0, 0)
      endif

      `Skybox Update
      position object SkyBoxNum, camera position x(), camera position y(), camera position z()

      if gamePaused = 0
         updateExplode()


         `recreate empire ships, the rebels are limited, but harder to hit =)
         if getTime() - EmpireRecreate > 10000
            AddEmpireShip(0, AIcontrol)
            EmpireRecreate = getTime()
         endif

         `ok i relent, a few extra rebel ships come in every now and again as well =)
         if rnd(4000) = 1
            tmp = AddRebelShip(0, AIcontrol)
            newMsg(tmp, "Little recon reo commin in...")
         endif



         updateAutoShips()
         updateTurrets(camera position z(), 10.0)
         updateBlasts()

         if timeLeft - getTime() <= 0 and rebelVictory = 0 then empireVictory = 1
         if countAutoShips(RebelShip) <= 0 then empireVictory = 1

      else
         `so da game is paused...
         ink RGB(0,128,192),0
         center text screen width()/2, screen height()/2,"Game Paused"
      endif

      updateExtendedKeyControls()

      FPS_UpdateIndependent()

      ink rgb(200,140,0),0
      text 5,screen height() - 35, "Rebel Ships: " + str$(countAutoShips(RebelShip))
      text 5,screen height() - 20, "Empire Ships: " + str$(countAutoShips(EmpireShip))
      center text screen width()/2,screen height() - 35, str$(int((timeLeft - getTime())/600)) + "Seconds Remaining"
      center text screen width()/2,screen height() - 20, str$(int(winDistance - camera position z())) + "m Remaining"
      sync

      `loop until exscapekey = 1
   until escapekey() = 1 or rebelVictory = 1 or empireVictory = 1

   if escapekey() = 1
      repeat
         sync
         `anti word blocking
      until escapekey() = 0
   endif

   if rebelVictory = 1
      rebelWinVid()
   endif

   if empireVictory = 1
      EmpireWinVid()
   endif

   `so somebody one eh? play me a video =)
   if rebelVictory = 1 or empireVictory = 1
   endif
loop

function getTime()
   local rtrn as integer
   if timeStoped
      rtrn = stopTime
   else
      rtrn = timer() - stopTime
   endif

endfunction rtrn

function startTime()
   timeStoped = 0
   stopTime = timer() - stopTime
endfunction

function stopTime()
   timeStoped = 1
   stopTime = timer() - stopTime
endfunction

function updateExtendedKeyControls()
   `engage/disengage autopilot
   if codeState(keyAutoToggle) = keyJustPressed
      if autoShips(playerShip).controlType = AIcontrol
         autoShips(playerShip).controlType = playerControl
         newMsg(playerShip, "Auto Pilot Disengaged")
      else
         autoShips(playerShip).controlType = AIcontrol
         newMsg(playerShip, "Auto Pilot Engaged - Enjoy the flight.")
      endif
   endif

   `Extended camera control keys...
   if codeState(keyCamRotUp) = keyHoldDown then camRotX = camRotX - timeValue(1.5)
   if codeState(keyCamRotDown) = keyHoldDown then camRotX = camRotX + timeValue(1.5)
   if codeState(keyCamRotRight) = keyHoldDown then camRotY = camRotY + timeValue(1.5)
   if codeState(keyCamRotLeft) = keyHoldDown then camRotY = camRotY - timeValue(1.5)
   if codeState(keyCamRotRollR) = keyHoldDown then camRotZ = camRotZ + timeValue(1.5)
   if codeState(keyCamRotRollL) = keyHoldDown then camRotZ = camRotZ - timeValue(1.5)

   if codeState(keyCamMovUp) = keyHoldDown then camOffVert = camOffVert + timeValue(0.0125)
   if codeState(keyCamMovDown) = keyHoldDown then camOffVert = camOffVert - timeValue(0.0125)
   if codeState(keyCamMovRight) = keyHoldDown then camOffHorz = camOffHorz + timeValue(0.0125)
   if codeState(keyCamMovLeft) = keyHoldDown then camOffHorz = camOffHorz - timeValue(0.0125)
   if codeState(keyCamMovFwd) = keyHoldDown then camOffZ = camOffZ + timeValue(0.025)
   if codeState(keyCamMovBak) = keyHoldDown then camOffZ = camOffZ - timeValue(0.025)

   if codeState(keyToggleFreeRot) = keyJustPressed
      if freeRotToggle = 0
         freeRotToggle = 1
         newMsg(99, "Free Camera Rotate Engaged")
      else
         freeRotToggle = 0
         newMsg(99, "Constrained Camera Rotate Engaged")
      endif
   endif

   if codeState(keyToggleMsgPan) = keyJustPressed
      if msgPanalVisible = 0
         msgPanalVisible = 1
         newMsg(99, "Message Pannel Displayed")
      else
         msgPanalVisible = 0
         newMsg(99, "Message Pannel Hidden")
      endif
   endif

   if codeState(keyPauseKey) = keyJustPressed
      if gamePaused = 0
         gamePaused = 1
         newMsg(99, "Game Paused")
         stopTime()
      else
         gamePaused = 0
         newMsg(99, "Game Continued")
         startTime()
      endif
   endif

   if codeState(keyPhotonTorpedo) = keyJustPressed
      if autoShips(playerShip).side = RebelShip and autoShips(playerShip).numTorpedos > 0
         fireBlast(autoShips(playerShip).objnum, RebelShip, 0,-0.1, 1.5,2)
         fireBlast(autoShips(playerShip).objnum, RebelShip, 0, 0.1, 1.5,2)
         autoShips(playerShip).numTorpedos = autoShips(playerShip).numTorpedos - 2
         newMsg(ship, "Torpedos away!")
      endif
   endif

   if codeState(keySwitchShips) = keyJustReleased
      tmp = playerChange(autoShips(playerShip).side)
      if tmp <> -1
         playerShip = tmp
      endif
   endif

   `player re-enter if passing exaust port...
   if object position z(autoShips(playerShip).objnum) >= winDistance
      position object autoShips(playerShip).objnum, 0, 20, winDistance - 1000
      autoShips(playerShip).incoming = 1
      newMsg(playerShip, "Goin again...")
   endif

   `now update camera
   autoCamera(playerShip)
endfunction

function FPS_UpdateIndependent()
   `update FPS independent code
     LoopTime = timer() - LastLoopTime
     LastLoopTime = timer()

     if LoopTime > MaxLoopTime then LoopTime = MaxLoopTime

     LoopConstant = GameSpeed/1000.0
     LoopSpeed = (LoopSpeed*(FPSISmoothing-1.0) + (LoopTime * LoopConstant * 1.0)) / FPSISmoothing*1.0
     FPS = screen fps()
      `done with FPS independent part
endfunction

function timeValue(value as float)
   local rtrn as float
   rtrn = value * LoopSpeed
endfunction rtrn

function MouseControl(Speed as float)

   xrotate camera wrapvalue(camera angle x()+mousemovey()/3.0)
   yrotate camera wrapvalue(camera angle y()+mousemovex()/3.0)
   if mouseclick()=1 then move camera timeValue(Speed)
   if mouseclick()=2 then move camera timeValue((0-Speed))

   if camera position y() > 10 then position camera camera position x(), 10, camera position z()
   if camera position y() < 1 then position camera camera position x(), 1, camera position z()

   if camera position x() > 4.9 then position camera 4.9, camera position y(), camera position z()
   if camera position x() < -4.9 then position camera -4.9, camera position y(), camera position z()

endfunction

function updateKeys()
   for n = 1 to maxActionKeys
      if actionKeys(n).keycode > 0
         actionKeys(n).lastState = actionKeys(n).currentState
         actionKeys(n).currentState = keystate(actionKeys(n).keycode)
      endif
   next n
endfunction

function codeState(actionKey as integer)
   local rtrn as integer = -1
   if actionKeys(actionKey).keycode > 0
      if actionKeys(actionKey).currentState = 0 and actionKeys(actionKey).lastState = 0
         rtrn = keyHoldUp
      endif

      if actionKeys(actionKey).currentState = 1 and  actionKeys(actionKey).lastState = 0
         rtrn = keyJustPressed
      endif

      if actionKeys(actionKey).currentState = 1 and  actionKeys(actionKey).lastState = 1
         rtrn = keyHoldDown
      endif

      if actionKeys(actionKey).currentState = 0 and  actionKeys(actionKey).lastState = 1
         rtrn = keyJustReleased
      endif

   endif
endfunction rtrn



makeTrenchObj:

   local tmpMesh as integer
   local tmpObj as integer

   trenchObj = FreeObject()
   tmpMesh = FreeMesh()

   trenchTexture = FreeImage()
   BlockTexture(trenchTexture)
   if bumpMappingOn = 1
      trenchBumpmap = FreeImage()
      BWBlockTexture(trenchBumpmap)
   endif

   make object plain trenchObj, 10,10

   tmpObj = FreeObject()

   make object plain tmpObj, 10,10
   make mesh from object tmpMesh,tmpObj
   delete object tmpObj

   add limb trenchObj,1,tmpMesh

   offset limb trenchObj,1,5,0,-5
   rotate limb trenchObj,1,0,-90,0

   delete mesh tmpMesh

   make object plain tmpObj, 10,10
   make mesh from object tmpMesh,tmpObj
   delete object tmpObj

   add limb trenchObj,2,tmpMesh

   offset limb trenchObj,2,-5,0,-5
   rotate limb trenchObj,2,0,90,0

   add limb trenchObj,3,tmpMesh
   offset limb trenchObj,3,105,0,-10
   scale limb trenchObj,3,2000,100,100
   scale limb texture trenchObj,3, 20, 1

   add limb trenchObj,4,tmpMesh
   offset limb trenchObj,4,-105,0,-10
   scale limb trenchObj,4,2000,100,100
   scale limb texture trenchObj,4, 20, 1

   delete mesh tmpMesh

   texture object trenchObj,trenchTexture
   if bumpMappingOn = 1
      set bump mapping on trenchObj,trenchBumpmap
   else
      set object emissive trenchObj, rgb(150,150,150)
   endif
   set object cull trenchObj, 0

   position object trenchObj,0,0,0
   rotate object trenchObj,90,0,0

   hide object trenchObj

   buildTrench(trenchObj, 10)
return

function buildTrench(obj as integer, spacing as float)
   for n = 1 to trenchLength
      trenchSqr(n).objnum = FreeObject()
      instance object trenchSqr(n).objnum, obj
      `texture object trenchSqr(n).objnum,trenchTexture
      `set bump mapping on trenchSqr(n).objnum,trenchBumpmap
      position object trenchSqr(n).objnum,0,0,(n-2)*spacing
      rotate object  trenchSqr(n).objnum,90,0,0
      `show object trenchSqr(n).objnum
   next n

   `end target
   endTarget = freeObject()
   make object plain endTarget,10,10
   tmp = freeObject()
   make object box tmp, 10,10,100
   position object tmp,0, 5, winDistance+51
   texture object tmp,trenchTexture

   texture object endTarget, DSTexture
   position object endTarget,0,5,winDistance
   set object cull endTarget, 0
   point object endTarget,0,5,0
endfunction

function updateTrench(cameraZ as float, spacing as float, direction as integer)
   local updateBridges as integer
   if curBlock <> int(cameraZ/spacing) then updateBridges = 1 : curBlock = int(cameraZ/spacing)
   if direction = 1
      for n = 1 to trenchLength
         position object trenchSqr(n).objnum,0,0,(n-2)*spacing+int(cameraZ/spacing)*spacing
      next n
   else
      for n = 1 to trenchLength
         position object trenchSqr(n).objnum,0,0,(n+2-trenchLength)*spacing+int(cameraZ/spacing)*spacing
      next n
   endif

   `position object

   `I still want to update bridges and turrets, even if looking backwards, but I just need to update the
   `side walls
      if rnd(crossBridgeChance) = 1 and updateBridges = 1 then buildBridge((curBlock mod trenchLength), (n-2)*spacing+int(cameraZ/spacing)*spacing, spacing)
      `turret time!
      if rnd(turretProb) = 1 and updateBridges = 1
         tmp = rnd(10)
         select tmp
            case 0
               `bottom
               createTurret(-4+rnd(8), 1.25, (n-2)*spacing+int(cameraZ/spacing)*spacing, 1)
            endcase
            case 1
               `left
               createTurret(3.25, rnd(6)+2, (n-2)*spacing+int(cameraZ/spacing)*spacing, 0)
            endcase
            case 2
               `right
               createTurret(-3.25, rnd(6)+2, (n-2)*spacing+int(cameraZ/spacing)*spacing, 0)
            endcase
            case default
               `this way there is more pedistal turrets than trench turrets
               if rnd(1) = 1
                  `pedistal turret on the right
                  createTurret(15, 25, (n-2)*spacing+int(cameraZ/spacing)*spacing, 2)
               else
                  `pedistal turret on the left
                  createTurret(-15, 25, (n-2)*spacing+int(cameraZ/spacing)*spacing, 2)
               endif
            endcase
         endselect
      endif

endfunction

function buildBridge(tsqr, zPos as float, sqrSize)
   local posy as float
   local posz as float

   posy = rnd(sqrSize)
   posz = zPos - sqrSize/2 + rnd(sqrSize)

   for n = 1 to crossBridgeObjQty
      if crossBridges(tsqr,n).objNum > 0
         if object exist(crossBridges(tsqr,n).objNum) = 1 then delete object crossBridges(tsqr,n).objNum
      endif
      crossBridges(tsqr,n).objNum = FreeObject()
      make object box crossBridges(tsqr,n).objNum, 100,100,100
      texture object crossBridges(tsqr,n).objNum,trenchTexture
      `set bump mapping on crossBridges(tsqr,n).objNum,trenchBumpmap
      position object crossBridges(tsqr,n).objNum,(sqrSize/3.0)*(n-2), posy, posz

      crossBridges(tsqr,n).xsize = (sqrSize/3.0) + 1.0
      crossBridges(tsqr,n).ysize = rnd(sqrSize/5.0) + 1.0
      crossBridges(tsqr,n).zsize = rnd(sqrSize/5.0) + 1.0
      scale object crossBridges(tsqr,n).objNum, crossBridges(tsqr,n).xsize, crossBridges(tsqr,n).ysize, crossBridges(tsqr,n).zsize

      set object collision to boxes crossBridges(tsqr,n).objNum
      `set object collision on crossBridges(tsqr,n).objNum
   next n
endfunction

function createsound(name$,soundnumber,frequency#,length#,loudness#,bend#,decay#,vibratospeed#,vibratodepth#,tremelospeed#,tremelodepth#,attack#)

outWord as word
dword1 as dword: dword2 as dword: dword3 as dword: dword4 as dword
dword5 as dword: dword6 as dword: dword7 as dword

samples=int((length#/1000)*44100)

if memblock exist(1) then delete memblock 1
make memblock 1,samples*2+28

` write 28 memblock header bytes
dword1=1      ` gg query: is this the number of channels?
dword2=2      ` gg query: is this the number of bytes per sample?
dword3=22050  ` gg query: seems to be half the number of samples per second - why?
dword4=88200  ` gg query: is this the number of bytes per second?
dword5=4      ` gg query: what does this represent?
dword6=16     ` gg query:     (ditto)            ?
dword7=0      ` gg query:     (ditto)            ?

position=0
write memblock dword 1, position, dword1 : inc position,4
write memblock dword 1, position, dword2 : inc position,4
write memblock dword 1, position, dword3 : inc position,4
write memblock dword 1, position, dword4 : inc position,4
write memblock dword 1, position, dword5 : inc position,4
write memblock dword 1, position, dword6 : inc position,4
write memblock dword 1, position, dword7 : inc position,4

rem generate and write wave
riseinloudness#=loudness#
for x=1 to samples
  outInteger=int(sin((x/122.5)*(frequency#+vibratodepth#*sin(theta#)))*(loudness#-fallinloudness#-riseinloudness#+tremelodepth#*sin(phi#)))*3.0
  if outInteger <-32767 then outInteger=-32767  ` gg query: is this the valid range?
  if outInteger>32767 then outInteger=32767     ` gg query:       (ditto)          ?
  outWord=outInteger
  inc theta#,vibratospeed#
  inc phi#,tremelospeed#
  dec frequency#,bend#

  if fallinloudness#<loudness#
    inc fallinloudness#,decay#
  endif

  if riseinloudness#>0
    dec riseinloudness#,attack#
  endif

  write memblock word 1, position, outWord : inc position,2
next x

if sound exist(soundnumber)=1 then delete sound soundnumber

make sound from memblock 999, 1 ` assumes you won't need sound number 999!
clone sound soundnumber, 999
delete sound 999

` memblock no longer required
delete memblock 1

endfunction

function FreeMesh()
   repeat
      inc i
      if mesh exist(i)=0 then found=1
   until found
endfunction i

function FreeObject()
   repeat
      inc i
      if object exist(i)=0 then found=1
   until found
endfunction i

function FreeImage()
   repeat
      inc i
      if image exist(i)=0 then found=1
   until found
endfunction i


function FreeMemblock()
   repeat
      inc i
      if memblock exist(i)=0 then found=1
   until found
endfunction i

function constructBlast(index)
   local tmp as integer
   local tmp2 as integer

   blast(index).objNum = freeObject()

   make object plain blast(index).objNum, 0, 0

   tmp = freeObject()
   tmp2 = freeMesh()

   make object plain tmp, 0.125, 3
   make mesh from object tmp2, tmp
   delete object tmp

   add limb blast(index).objNum, 1, tmp2
   rotate limb blast(index).objNum, 1,90,0,90
   add limb blast(index).objNum, 2, tmp2
   rotate limb blast(index).objNum, 2,90,0,0

   show limb blast(index).objNum, 1
   show limb blast(index).objNum, 2

   set object cull blast(index).objNum,0

   rotate object blast(index).objNum, 0,0,0
   position object blast(index).objNum, 0,0,0

   ghost object on blast(index).objNum,0
   `set object light blast(index).objNum, 0

   set object emissive blast(index).objNum, rgb(255,255,0)

   set object collision off blast(index).objNum

   hide object blast(index).objNum
endfunction

function updateBlasts()
   for n = 1 to maxBlastObjects
      if blast(n).exist = 1
         move object blast(n).objNum, timeValue(blast(n).vel)
         inc blast(n).traveledDist, timeValue(blast(n).vel)
         inc blast(n).dynColCheck, timeValue(blast(n).vel)
         `timer kill
         if getTime() - blast(n).startTime > blast(n).life
            blast(n).exist = 0
            hide object blast(n).objNum
         endif

         if blast(n).dynColCheck > 2.0 and blast(n).live = 1


            tmpx# = object position x(blast(n).objNum)
            tmpy# = object position y(blast(n).objNum)
            tmpz# = object position z(blast(n).objNum)
            move object blast(n).objNum, blast(n).dynColCheck + 2.0

            turret = intesectTurret(tmpx#, tmpy#, tmpz#, object position x(blast(n).objNum), object position y(blast(n).objNum), object position z(blast(n).objNum))
            shipHit = intesectShip(tmpx#, tmpy#, tmpz#, object position x(blast(n).objNum), object position y(blast(n).objNum), object position z(blast(n).objNum),(empireShipSize+rebelShipSize)/2)

            move object blast(n).objNum, 0 - blast(n).dynColCheck - 2.0

            `collision with turret, life?
            if turret > 0
               hideTurret(turret)
               explode(turrets(turret).objNum)
               newMsg(100, "Turret Scrap heap")
               blast(n).exist = 0
               hide object blast(n).objNum
            endif

            `collision with ship, life?
            if shipHit > 0
               blast(n).exist = 0
               hide object blast(n).objNum

               autoShips(shipHit).health = autoShips(shipHit).health - blastDamage
               if autoShips(shipHit).health <= 0
                  explode(autoShips(shipHit).objNum)
                  newMsg(shipHit, "AHHHHHHHHH!!!!!!!!!")
                  newMsg(shipHit, "Elimiated")
                  killShip(shipHit)
                  if playerShip = shipHit
                     tmp = playerChange(autoShips(shipHit).side)
                     if tmp <> -1
                        playerShip = tmp
                     endif
                  endif
               else
                  if autoShips(shipHit).health > 30
                     newMsg(shipHit, "Ahh!! I'm hit")
                  else
                     newMsg(shipHit, "I'm dead meat...")
                  endif
               endif
            endif

            if blast(n).BType = 2 `photon torpedo...
               if intersectZtarget(object position x(blast(n).objNum),object position y(blast(n).objNum),0, 7.5, 1.25) > 0
                  tmpx# = object position x(blast(n).objNum)
                  tmpy# = object position y(blast(n).objNum)
                  tmpz# = object position z(blast(n).objNum)
                  move object blast(n).objNum, blast(n).dynColCheck + 2.0

                  tmpdist# = intersect object(endTarget, tmpx#, tmpy#, tmpz#, object position x(blast(n).objNum), object position y(blast(n).objNum), object position z(blast(n).objNum))

                  move object blast(n).objNum, 0 - blast(n).dynColCheck - 2.0

                  if tmpdist# > 0.01
                     `yes!!!! rebels win!
                     rebelVictory = 1
                  endif
               endif
            endif



            blast(n).dynColCheck = 0
         else
            if blast(n).dynColCheck > 5.0
               blast(n).live = 1
               blast(n).dynColCheck = 2.0
            endif
         endif

         if blast(n).maxDist > 1 and blast(n).traveledDist > blast(n).maxDist
            blast(n).exist = 0
            hide object blast(n).objNum
         endif
      endif
   next n
endfunction

function resetBullets()
   for n = 1 to maxBlastObjects
      blast(n).exist = 0
      hide object blast(n).objNum
   next n
endfunction

function fireBlast(sourceObj, color, offX as float, offY as float, offZ as float, bType as integer)
   local tmpIdx as integer
   tmpIdx = freeBlast()
   if tmpIdx > 0
      blast(tmpIdx).exist = 1
      blast(tmpIdx).vel = 1.5
      blast(tmpIdx).startTime = getTime()
      blast(tmpIdx).life = 5000
      blast(tmpIdx).traveledDist = 0
      blast(tmpIdx).maxDist = trenchLength * 10.0 * 2
      blast(tmpIdx).live = 0
      blast(tmpIdx).BType = bType

      blast(tmpIdx).dynColCheck = 0

      if color = 1
         colorBlast(blast(tmpIdx).objNum, redLaserImg)
      else
         colorBlast(blast(tmpIdx).objNum, greenLaserImg)
      endif

      position object blast(tmpIdx).objNum, object position x(sourceObj),object position y(sourceObj),object position z(sourceObj)
      rotate object blast(tmpIdx).objNum, object angle x(sourceObj),object angle y(sourceObj),object angle z(sourceObj)

      show object blast(tmpIdx).objNum

      move object up blast(tmpIdx).objNum, offX
      move object right blast(tmpIdx).objNum, offY
      move object blast(tmpIdx).objNum, offZ

      tmpx = object position x(blast(tmpIdx).objNum)
      tmpy = object position y(blast(tmpIdx).objNum)
      tmpz = object position z(blast(tmpIdx).objNum)

      move object blast(tmpIdx).objNum, rayLen

      blast(tmpIdx).maxDist = intersectStatic(tmpx, tmpy, tmpz, object position x(blast(tmpIdx).objNum), object position y(blast(tmpIdx).objNum), object position z(blast(tmpIdx).objNum))

      move object blast(tmpIdx).objNum, 0-rayLen
   endif
endfunction

function colorBlast(obj, img)
   texture limb obj, 1,img
   texture limb obj, 2,img
endfunction

function freeBlast()
   repeat
      inc i
      if blast(i).exist=0 then found=1
   until found = 1 or i >= maxBlastObjects
   if found = 0 then i = -1
endfunction i

function intesectTurret(x#, y#, z#, xto#, yto#, zto#)
   local dist as float = 1000.0
   local tmp as float
   local turret as integer
   for i = 1 to turretMax
      if turrets(i).objNumBox > 0
         if object exist(turrets(i).objNumBox) = 1 and turrets(i).exist = 1
            tmp = intersect object(turrets(i).objNumBox, x#, y#, z#, xto#, yto#, zto#)
            if dist > tmp and tmp > 0.01
               dist = tmp
               turret = i

            endif
         endif
      endif
   next i
endfunction turret

function intersectBridge(x#, y#, z#, xto#, yto#, zto#)
   local dist as float = 1000.0
   local tmp as float
   for i = 1 to trenchLength
      for j = 1 to crossBridgeObjQty
         if crossBridges(i,j).objNum > 0
            if object exist(crossBridges(i,j).objNum) = 1
               tmp = intersect object(crossBridges(i,j).objNum, x#, y#, z#, xto#, yto#, zto#)
               if dist > tmp and tmp > 0.01 then dist = tmp
            endif
         endif
      next j
   next i
endfunction dist

function intersectTrench(x#, y#, z#, xto#, yto#, zto#)
   local dist as float = 1000.0
   local tmp as float
   for i = 1 to trenchLength
      if trenchSqr(i).objNum > 0
         if object exist(trenchSqr(i).objNum) = 1
            tmp = intersect object(trenchSqr(i).objNum, x#, y#, z#, xto#, yto#, zto#)
            if dist > tmp and tmp > 0.01 then dist = tmp
         endif
      endif
   next i
endfunction dist

function intersectStatic(x#, y#, z#, xto#, yto#, zto#)
   local dist as float = 0.0
   local tmp as float

   dist = intersectBridge(x#, y#, z#, xto#, yto#, zto#)
   tmp = intersectTrench(x#, y#, z#, xto#, yto#, zto#)
   if dist < tmp then dist = tmp
endfunction dist

function intesectShip(x#, y#, z#, xto#, yto#, zto#, hitDist#)
   local dist as float = 1000.0
   local tmp as float
   local tmp2 as float
   local ship as integer
   for n = 1 to maxShips
      if autoShips(n).exist = 1
         if object exist(autoShips(n).objNum) = 1 and autoShips(n).exist = 1
            `tmp = intersect object(autoShips(n).objNum, x#, y#, z#, xto#, yto#, zto#)
            tmp = dCheck(x#, y#, z#, autoShips(n).objNum)
            tmp2 = dCheck(xto#, yto#, zto#, autoShips(n).objNum)

            if tmp2 < tmp then tmp = tmp2

            `if the ship is close enough, do an intersect test, else it gets to be to much
            `of a tax on the system and a major slowdown.
            if tmp < hitDist#^2 * 2.0
               tmp = intersect object(autoShips(n).objNum, x#, y#, z#, xto#, yto#, zto#)
               if tmp < dist and tmp > 0.001
                  ship = n
                  dist = tmp
               endif

               `newMsg(99, "Intersect ship performed")
            endif

            `newMsg(99, "Hit Distance: " + str$(hitDist#^2 * 2.0) + " tmp: " + str$(tmp))
         endif
      endif
   next i
endfunction ship

function nearShip(ship,radius as float)
   local tmp as integer
   local tmpobj as integer
   tmp = -1
   for n = 1 to maxShips
      if autoShips(n).exist = 1 and n <> ship and autoships(n).side <> autoships(ship).side
         tmpobj = autoShips(ship).objNum
         if intersectZtarget(object position x(tmpobj),object position y(tmpobj),object position x(autoships(n).objNum), object position y(autoships(n).objNum), radius) = 1
            if object position z(tmpobj) < object position z(autoships(n).objNum)
               tmp = n
            endif
         endif
      endif
   next n
endfunction tmp

function intersectZtarget(x#,y#,cirx#, ciry#, cirr#)
   local rtrn as integer = 0
   local tmp as float
   tmp = (x# - cirx#)*(x# - cirx#) + (y# - ciry#)*(y# - ciry#)

   if tmp < cirr# * cirr#
      rtrn = 1
   endif
endfunction rtrn

function dCheck(x#, y#, z#, object)
   local tmpRtrn as float
   tmpRtrn = ((x# - object position x(object))*(x# - object position x(object)) + (y# - object position y(object))*(y# - object position y(object)) + (z# - object position z(object))*(z# - object position z(object)))
endfunction tmpRtrn



function GreenLaserTexture(imgNum as integer)
   local xSize as integer
   local ySize as integer


   local tmpXa as integer
   local tmpYa as integer
   local tmpXb as integer
   local tmpYb as integer

   cls rgb(0,0,0)

   xSize = 30
   ySize = 90

   create bitmap 1, xSize, ySize
   set current bitmap 1

   cls rgb(0,0,0)

   for n = 0 to xSize
      tmpColor = int(sin((((n*1.0)/(xSize*1.0))*180.0))*255)
      ink rgb(tmpColor, 255, tmpColor),0

      line n, 0, n, ysize
   next n

   get image imgNum,0,0,xSize,ySize,0

   delete bitmap 1
   set current bitmap 0
endfunction

function RedLaserTexture(imgNum as integer)
   local xSize as integer
   local ySize as integer


   local tmpXa as integer
   local tmpYa as integer
   local tmpXb as integer
   local tmpYb as integer

   cls rgb(0,0,0)

   xSize = 30
   ySize = 90

   create bitmap 1, xSize, ySize
   set current bitmap 1

   cls rgb(0,0,0)

   for n = 0 to xSize
      tmpColor = int(sin((((n*1.0)/(xSize*1.0))*180.0))*255)
      ink rgb(255, tmpColor, tmpColor),0

      line n, 0, n, ysize
   next n

   get image imgNum,0,0,xSize,ySize,0

   delete bitmap 1
   set current bitmap 0
endfunction

function BlockTexture(imgNum as integer)
   local xSize as integer
   local ySize as integer

   local colorOff as integer
   local BWScale as integer
   local sqrMaxSize as integer

   local tmpXa as integer
   local tmpYa as integer
   local tmpXb as integer
   local tmpYb as integer

   cls rgb(0,0,0)

   xSize = 255
   ySize = 255
   sqrMaxSize = 100

   BWScale = 100
   colorOff = 5

   create bitmap 1, xSize+40, ySize+40
   set current bitmap 1

   cls rgb(175,175,175)

   for n = 1 to 100
      tmpColor = rnd(BWScale) - BWScale/2 + 200
      ink rgb(tmpColor + rnd(colorOff), tmpColor + rnd(colorOff), tmpColor + rnd(colorOff)),0

      tmpXa = rnd(xSize+40)
      tmpYa = rnd(ySize+40)
      tmpXb = rnd(sqrMaxSize)
      tmpYb = rnd(sqrMaxSize)

      box tmpXa, tmpYa, tmpXa+tmpXb, tmpYa+tmpYb
   next n

   get image imgNum,20,20,xSize+20,ySize+20,0

   delete bitmap 1
   set current bitmap 0
endfunction

function BWBlockTexture(imgNum as integer)
   local xSize as integer
   local ySize as integer

   local BWScale as integer
   local sqrMaxSize as integer

   local tmpXa as integer
   local tmpYa as integer
   local tmpXb as integer
   local tmpYb as integer

   cls rgb(0,0,0)

   xSize = 255
   ySize = 255
   sqrMaxSize = 100

   BWScale = 255

   create bitmap 1, xSize+40, ySize+40
   set current bitmap 1

   cls rgb(0,0,0)

   for n = 1 to 200
      tmpColor = rnd(BWScale)
      ink rgb(tmpColor, tmpColor, tmpColor),0

      tmpXa = rnd(xSize+40)
      tmpYa = rnd(ySize+40)
      tmpXb = rnd(sqrMaxSize)
      tmpYb =