TGC Codebase Backup



unfinished turn based rpg with infinite terrain by Animate Dream

15th Jan 2007 1:53
Summary

This is an unfinished rpg engine with persistent and infinite terrain, the beginnings of a turn based rpg combat system, and more.



Description

This is an unfinished rpg engine with persistent and infinite terrain, and the beginnings of a turn based rpg combat system. At over a thousand lines of code I think it might be a useful resource. Other things I coded include moving clouds, a system for dynamic spawning and unloading of monsters and trees of different dimensions, 3 different types of cameras programmed to avoid clipping the terrain, accurate uphill and downhill movement speeds, some crude but effective sliding collision code, simple wandering/attacking AI, projectiles, and possibly more I don't remember. I couldn't get the hit detection working quite right so I am for the moment abandoning the project to work with an engine coded in C++ which I'm more comfortable with. However, I'm releasing the full source for use for any purpose. I only wish I could have made even more contributions to the darkbasic community. This has been sitting on my hard drive for a while, so I'm not even sure if it runs error free with the current version of darkbasic. The commentation may be lacking but I think the programming is straightforward enough to understand. The images models and sounds were too big to upload here but I used mostly resources that came with darkbasic during development. You will have to include all media yourself or change the media loading in the code. If anyone would like to continue the project or borrow parts of it I might be tempted into helping. I can be contacted at animatedream@gmail.com



Code
                                    ` This code was downloaded from The Game Creators
                                    ` It is reproduced here with full permission
                                    ` http://www.thegamecreators.com
                                    
                                    rem By Stephen Lujan
sync on
backdrop on : hide mouse : color backdrop 0

rem Select font
set text font "arial" : set text size 16
set text to bold : set text transparent

rem Loading prompt
sync
center text screen width()/2,screen height()/2,"LOADING"
center text screen width()/2,screen height()*0.4,"Use arrow keyes to Move. Hit escape to exit."
center text screen width()/2,screen height()*0.3,"Hit c to change from manual to automatic camera."
center text screen width()/2,screen height()*0.2,"Operate the manual camera with the mouse."
center text screen width()/2,screen height()*0.1,"Zoom in and out with the + and - on the number pad."
sync

`don't give same sequence of random numbers each time...
RANDOMIZE timer()

REM DATA SETUP
`counter
global gun#

type bullet
   objnum as integer
   effect as integer
   strength# as float
   particles as integer
   movetype as integer
   velocity# as float
   life# as float
   maxlife# as float
endtype

dim bullets(0) as bullet
global bullets

type creature
   objnum as integer
   ctype as integer
   state as integer
   life# as float
   movetype as integer
   movestate as integer
endtype


global lasttime#
global time#
global fps#

dim creatures(1) as creature
global creatures
global debug

REM LOAD RESOURCES
gosub _load_images

REM IMPORTANT LOAD PROCEDURES
gosub _load_world
gosub _load_player

REM CAMERA SETTINGS
backdrop off
autocam off
set camera range 1,size
`set display mode 800,768,32
camdist#= 250.0
global camdist#
camdist#= 250.0
global view
rem Position camera in center of terrain
position camera 0,size/2-50,size/8,size/2-50
`automatic camera collision 0,20,0

REM FINAL SETUP
desc$="testing"
`test()
desc$="LOD Terrain Ad Infinatum"
 rem Create simple sprite based crosshair
 sprite 1,screen width()/2-16,screen height()/2-16,3
 set sprite 1,0,1
 SET SPRITE ALPHA 1, 100

`initialize time variables
time#= timer()
lasttime#= time#
                        rem MAIN LOOP
         rem MAIN LOOP
rem Main loop
while escapekey()=0
gosub _real_time
World(camera position x(0),camera position z(0))
rem End loop
endwhile
                                          rem END MAIN LOOP
                     rem END MAIN LOOP
`end game
end

`run live objects and update frame
_real_time:
   rem check frame rate
   time#= timer()
   rawfps = screen fps()
   fps#= (rawfps + 1000/(time#- lasttime#))/2

   `user types c to change camera mode
   if ENTRY$() = "c" or ENTRY$() = "C"
      if view < 2
         inc view
      else
         view = 0
      endif
   endif
   CLEAR ENTRY BUFFER

   if (SCANCODE()= 78 and camdist# < 1000.0) then camdist#= camdist#+55.0/fps#
   if (SCANCODE()= 74 and camdist# > 100.0) then camdist#= camdist#-55.0/fps#

   `rem Control player over terrain
   `s#=s#/friction#

   rem Control direction of model
   `if upkey()=1 and s#<100.0 then inc s#,acc#
   `if downkey()=1 and s#>-100.0 then dec s#,acc#
   `if leftkey()=1 then dec a#,1.5
   `if rightkey()=1 then inc a#,1.5

      cx#=object position x(2)
      cz#=object position z(2)

      if shiftkey()=1
         walkv#=600.0
         else walkv#=170.0
      endif

      walk=0
   if leftkey()=1
      yrotate object 2,wrapvalue(object angle y(2)-(110.1/(fps#+3.1)))
      walk=1
   endif
   if rightkey()=1
      yrotate object 2,wrapvalue(object angle y(2)+(110.1/(fps#+3.1)))
      walk=1
   endif
   if upkey()=1
      cx#=newxvalue(object position x(2),object angle y(2),(walkv#/(fps#+3.1)))
      cz#=newzvalue(object position z(2),object angle y(2),(walkv#/(fps#+3.1)))
      walk=1
   endif
   if downkey()=1
      cx#=newxvalue(object position x(2),object angle y(2),(-walkv#/(fps#+3.1)))
      cz#=newzvalue(object position z(2),object angle y(2),(-walkv#/(fps#+3.1)))
      walk=1
   endif

 if walk<>lastwalk then change=1
 if change=1
  if walk=0 then loop object 2,0,12*heroframe#
   if walk=1 then loop object 2,35*heroframe#,41.7*heroframe#
  `if walk=1 then set object speed 2,12000: loop object 2,72.3*heroframe#,76.2*heroframe#
  change=0 : lastwalk=walk
 endif

 if walk=0 then set object speed 2,200000/fps#
 if walk=1 then set object speed 2,480000/fps#

   cy#=get ground height(1,cx#-matrix position x(1),cz#-matrix position z(1))+8.0
   rem inclines effect speed
   incline=0
   if cy#>object position y(2)
      diffx#= cx#-object position x(2)
      diffy#= cy#-object position y(2)
      diffz#= cz#-object position z(2)
      incline# = diffy# / sqrt((diffx#*diffx#)+(diffz#*diffz#))
      inc incline#
      incline#= incline#*sqrt(incline#)
      `strdebug$="x"+str$(diffx#)+"y"+str$(diffy#)+"z"+str$(diffz#)+"i"+str$(incline#)
      `text 20,screen height()-80,strdebug$
      cx#= object position x(2) + (diffx#/incline#)
      `quick sloppy y
      cy#= object position y(2) + (diffy#/incline#)
      cz#= object position z(2) + (diffz#/incline#)
      `slow perfect y
     `cy#=get ground height(1,cx#-matrix position x(1),cz#-matrix position z(1))+10.0
   endif

   position object 2,cx#,cy#,cz#

   `which camera style
   if view = 2 then CameraFirstPerson(2)
   if view = 1 then CameraTrack(1,2)
   if view = 0 then CameraTrack2(1,2)

   rem Position sky at camera and rotate to simulate cloud movement
   position object 1,camera position x(0),camera position y(0)-(O#),camera position z(0)
   zrotate object 1,wrapvalue(object angle z(1)+(0.8/(fps#+3.1)))

   `run all creature protocols
   ai()

   `do projectile protocol
   runplayerguns()
   runbullets()

   rem Show Framerate
   text 20,screen height()-40,desc$
   strfps$="DBPro Fps: "+str$(rawfps)
   text screen width()-20-text width(strfps$),screen height()-40,strfps$

   rem gosub _tdat
   gosub _mdat

   `now that lasttime# isn't needed anymore this frame update it
   lasttime#= time#

   rem Update screen
   sync

return

`initialize world
function editmatrix(MatrixNumber,xpos,zpos)
 ImageNumber=2
 if matrix exist(MatrixNumber) = 0
    make matrix MatrixNumber,size,size,max,max
   prepare matrix texture MatrixNumber,ImageNumber,2,2
 endif
 Height#=0.0
 `get realworld tile
 x2= xpos/tsize#
 z2= zpos/tsize#
 for x=0 to max
  for z=0 to max
   x3= x2 + x
   z3= z2 + z
   rem Height#= cos(x*30+rnd(30)+rnd(30))*30  +  sin(z*30)*30  +  sin((x-z)*12)*60 +  cos((z-x)*50)*15
    Height#= heightmap(x3,z3)
   set matrix height MatrixNumber, x, z, Height#

   if x<max and z<max
    TileID=1+rnd(3)
    set matrix tile MatrixNumber, x, z, TileID
   endif
  next z
 next x
 update matrix MatrixNumber

 position matrix MatrixNumber,xpos,0,zpos

 for x=1 to max-1
  for z=1 to max-1
   normalize(MatrixNumber,x,z)
  next z
 next x
 for x=0 to max
  for z=0 to max
     loadscenery(x,z)
  next z
 next x
 update matrix MatrixNumber

EndFunction

`load scenery for new terrain
function loadscenery(xtile,ztile)
   rem Create trees
   while rnd(118)=77
      tr = rnd(1000)+10000
      if object exist(tr) = 0 and object exist (tr+1) = 0
         h=rnd(120)+180
         w= h+rnd(90)-45
         make object plain tr,w,h
         make object plain tr+1,w,h
         xoff=xtile*tsize#+rnd(tsize#)
         zoff=ztile*tsize#+rnd(tsize#)
         xpos= matrix position x(1)
         zpos= matrix position z(1)
         position object tr,xpos+xoff,get ground height(1,xoff,zoff)+object size(tr)/1.5,zpos+zoff
         position object tr+1,xpos+xoff,get ground height(1,xoff,zoff)+object size(tr)/1.5,zpos+zoff
         r=rnd(90)
         rotate object tr, 0,r,0
         rotate object tr+1, 0,90+r,0
         texture object tr,11
         texture object tr+1,11
         set object tr,0,1,0,2
         set object tr+1,0,1,0,2
         set object specular tr,0
         set object specular tr+1,0
      endif
   endwhile
   `objnum= start + 99
   `clone object 2,objnum
   `xoff=rnd(size)
   `zoff=rnd(size)
   `position object start,xpos*size+xoff,get ground height(MatrixNumber,xoff,zoff)+object size(objnum)/1.5,zpos*size+zoff
   loadcreatures(xtile,ztile)
endfunction

`unload scenery that's too far away
function unloadscenery()
   rem clear scenery from terrain being unloaded
   start= 100
   for tr=10000 to 11000
      if object exist(tr)
         if object position z(tr) < camera position z(0) - size * 0.55
            delete object tr
            else if object position z(tr) > camera position z(0) + size * 0.55
               delete object tr
               else if object position x(tr) < camera position x(0) - size * 0.55
                  delete object tr
                  else if object position x(tr) > camera position x(0) + size * 0.55
                     delete object tr
                  endif
               endif
            endif
         endif
      endif
   next tr
   unloadcreatures()
endfunction

         ` START CREATURE CODE
                              ` START CREATURE CODE
                                                   ` START CREATURE CODE
`load creatures with new terrain
function loadcreatures(xtile,ztile)
   while rnd(399)=77
      `creatures(0) unused
      index = array count(creatures(0)) - 1
      obj = creatures(index).objnum +1
      if obj >= 2000 then obj = 1000
      if obj < 1000 then obj = 1000
      if object exist(obj) = 0
         array insert at bottom creatures(0)
         index= array count(creatures(0)) - 1
         creatures(index).objnum= obj
         creatures(index).movetype= 0
         creatures(index).life#=20.0
         clone object obj, 999
         scale object obj,3500,3500,3500
         `set object specular obj,0
         `set object obj,1,0,0,2,1,1
         loop object obj,0,25
         xoff=xtile*tsize#+rnd(tsize#)
         zoff=ztile*tsize#+rnd(tsize#)
         xpos= matrix position x(1)
         zpos= matrix position z(1)
         position object obj,xpos+xoff,get ground height(1,xoff,zoff)+object size(obj)+20,zpos+zoff
         r=rnd(359)
         rotate object obj, 0,r,0
         set object collision on obj
         set object collision to boxes obj
         `automatic object collision obj,60.0,0
         inc debug
      endif
   endwhile
endfunction

`remove creatures that are too far away
function unloadcreatures()
   x=1
   while x <  array count(creatures(0))
      tr = creatures(x).objnum
      if object exist(tr):`object number not valid errors?
         if object position z(tr) < camera position z(0) - size * 0.55
            delete object tr
            array delete element creatures(x),x
            else if object position z(tr) > camera position z(0) + size * 0.55
               delete object tr
               array delete element creatures(x),x
               else if object position x(tr) < camera position x(0) - size * 0.55
                  delete object tr
                  array delete element creatures(x),x
                  else if object position x(tr) > camera position x(0) + size * 0.55
                     delete object tr
                     array delete element creatures(x),x
                     else inc x
                  endif
               endif
            endif
         endif
         else inc x
      endif
      `inc x :rem if a creature is deleted this skips one?
   endwhile
endfunction

`runs all creature movement etc
function ai()
   x= 1
   while x <  array count(creatures(0))
      obj= creatures(x).objnum
      if obj < 1000 or obj >= 2000
         print "AI ERROR "
         print "index "+str$(x)
         print "object "+str$(obj)
         str1$="numbers"
         for x= 0 to array count(creatures(0)) - 1
            obj= creatures(x).objnum
            str1$=str1$+" "+str$(obj)
         next x
         print str1$
         sync
         sleep 6000
      endif
      if object exist(obj):`object number not valid errors?
         set object speed obj,2000/fps#
         `set creature to dying state as needed
         if creatures(x).life#<= 0 and creatures(x).state > -1 then creatures(x).state = -1
         `default state
         if creatures(x).movetype = 0 and creatures(x).state=0
            if rnd(6 * fps#)= 2 then creatures(x).movestate = rnd(3)
            walkv#= -70
            cx# = object position x(obj)
            cz# = object position z(obj)
            select creatures(x).movestate
               case 1:  cx#=newxvalue(object position x(obj),object angle y(obj),(walkv#/(fps#+3.1)))
                        cz#=newzvalue(object position z(obj),object angle y(obj),(walkv#/(fps#+3.1)))
               endcase
               case 2:  yrotate object obj,wrapvalue(object angle y(obj)-(30.1/(fps#+3.1)))
                        cx#=newxvalue(object position x(obj),object angle y(obj),(walkv#/(fps#+3.1)))
                        cz#=newzvalue(object position z(obj),object angle y(obj),(walkv#/(fps#+3.1)))
               endcase
               case 3:  yrotate object obj,wrapvalue(object angle y(obj)+(30.1/(fps#+3.1)))
                        cx#=newxvalue(object position x(obj),object angle y(obj),(walkv#/(fps#+3.1)))
                        cz#=newzvalue(object position z(obj),object angle y(obj),(walkv#/(fps#+3.1)))
               endcase
            endselect
            cy#=get ground height(1,cx#-matrix position x(1),cz#-matrix position z(1))+object size(obj)+20
            rem inclines effect speed
            if cy#>object position y(obj) and creatures(obj).movestate > 0
               incline=0
               diffx#= cx#-object position x(obj)
               diffy#= cy#-object position y(obj)
               diffz#= cz#-object position z(obj)
               incline# = diffy# / sqrt((diffx#*diffx#)+(diffz#*diffz#))
               inc incline#
               incline#= incline#*sqrt(incline#)
               cx#= object position x(obj) + (diffx#/incline#)
               `quick sloppy y
               cy#= object position y(obj) + (diffy#/incline#)
               cz#= object position z(obj) + (diffz#/incline#)
               `slow perfect y
               `cy#=get ground height(1,cx#-matrix position x(1),cz#-matrix position z(1))+10.0
            endif
            position object obj,cx#,cy#,cz#
         endif
         `dying animations and such
         if creatures(x).state = -1
            print "CREATURE KILLED!"
            sync
            sleep 3000
            delete object obj
            array delete element creatures(x),x
         endif
      endif
      inc x
   endwhile
endfunction
                                    `END CREATURE CODE
                  `END CREATURE CODE
`END CREATURE CODE

function runbullets()
   t#= time#-lasttime#
   x= 0
   while x < array count(bullets(0))
      obj= bullets(x).objnum
      p=bullets(x).particles
      move object obj,(bullets(x).velocity# * t#/1000.0)
      if p > 0
         position particles p, object position x(obj), object position y(obj), object position z(obj)
         set particle emissions p,(1+10*(bullets(x).maxlife#-bullets(x).life#)/bullets(x).maxlife#)
         rotate particles p,90-object angle x(obj),object angle y(obj)+180,0
      endif
      bullets(x).life#= bullets(x).life#+(t#)
      delete = 0
      collider= object collision(obj,0)
      if collider > 0
         `debuggishness
         `print str$(collider)+" object hit!!!!"
         `sync
         `sleep 3000
         delete = 1
         if collider > 1000 and collider < 2000
            y=1
            while y <  array count(creatures(0))-1
               if collider = creatures(y).objnum then creatures(y).life# = creatures(y).life#- 10.0
               inc y
            endwhile
         endif
      endif
      if bullets(x).life# > bullets(x).maxlife# then delete = 1
      if delete = 1
         delete object obj
         if p > 0 then set particle emissions p,0
         array delete element bullets(0),x
      else
         inc x
      endif
   endwhile
endfunction

function runplayerguns()
if gun# > 0
   gun# = gun#- (time#-lasttime#)
else
   if mouseclick()= 1
      gun#=700 `0.7 second refire rate
      bnum= array count(bullets(0))
      obj = 2000
      if bnum > 0 then obj = bullets(bnum-1).objnum+1
      if obj < 2000 then obj = 2000
      if obj > 2100 then obj = 2000
      if object exist(obj)= 0
         array insert at bottom bullets(0)
         bullets(bnum).maxlife# = 3500.0
         bullets(bnum).life# = 0.0
         bullets(bnum).objnum = obj
         bullets(bnum).velocity# = 600.0
         make object cube obj, 0.1
         px#=object position x(2)
         pz#=object position z(2)
         py#=object position y(2) + object size(2)*0.95
         position object obj,px#,py#,pz#
         ROTATE OBJECT obj, 0, object angle y(2), 0
         move object obj, 30
         if view = 2
            ROTATE OBJECT obj, camera angle x(0), camera angle y(0), 0
         endif
         automatic object collision obj,6,0
         set object emissive obj,rgb(255,250,220)
         p= obj
         `if particles exist(p) then p = 2000+rnd(999)
         if particles exist(p)= 1 then delete particles p
         bullets(bnum).particles = p
         ParticleNumber = p
         ImageNumber = 2000
         make particles ParticleNumber, ImageNumber, 50, 60.0
         position particles ParticleNumber, object position x(obj), object position y(obj), object position z(obj)
         color particles ParticleNumber, 255, 128, 0
         set particle emissions ParticleNumber, 10
         set particle velocity ParticleNumber, 10
         set particle speed ParticleNumber, 0.01
         set particle gravity ParticleNumber, 0
         set particle life ParticleNumber, 10
         SET PARTICLE FLOOR ParticleNumber, 0
      endif
   endif
endif
endfunction


`world function updates matrix to reflect player movement
function World (x#, z#)
   MatrixNumber = 1
   if (x# > matrix position x(1) + tsize# * 0.55 * max)
      shift matrix left 1
      shift matrix left 1
      update matrix MatrixNumber
      position matrix 1,matrix position x(1)+2*tsize#,matrix position y(1),matrix position z(1)

      `get realworld tile
      x2= (matrix position x(1)/tsize#)
      z2= (matrix position z(1)/tsize#)
      for x = max-1 to max
         for z=0 to max
            x3= x2 + x
            z3= z2 + z
            Height#= heightmap(x3,z3)
            set matrix height MatrixNumber, x, z, Height#

            if x<max and z<max
               TileID=1+rnd(3)
               set matrix tile MatrixNumber, x, z, TileID
            endif
         next z
      next x
      update matrix MatrixNumber

      for x = max-2 to max-1
         for z=1 to max-1
            normalize(MatrixNumber,x,z)
         next z
      next x
      update matrix MatrixNumber

      unloadscenery()
      for x = max-1 to max
         for z=0 to max
            loadscenery(x,z)
         next z
      next x
   endif


   if (x# < matrix position x(1) + tsize# * 0.45 * max)
      shift matrix right 1
      shift matrix right 1
      update matrix MatrixNumber
      position matrix 1,matrix position x(1)-2*tsize#,matrix position y(1),matrix position z(1)

      `get realworld tile
      x2= (matrix position x(1)/tsize#)
      z2= (matrix position z(1)/tsize#)
      for x = 1 to 0 step -1
         for z=0 to max
            x3= x2 + x
            z3= z2 + z
                Height#= heightmap(x3,z3)
            set matrix height MatrixNumber, x, z, Height#

            if x<max and z<max
               TileID=1+rnd(3)
               set matrix tile MatrixNumber, x, z, TileID
            endif
         next z
      next x
      update matrix MatrixNumber

      for x = 2 to 1 step -1
         for z=1 to max-1
            normalize(MatrixNumber,x,z)
         next z
      next x
      update matrix MatrixNumber

      unloadscenery()
      for x = 1 to 0 step -1
         for z=0 to max
            loadscenery(x,z)
         next z
      next x
   endif


   if (z# > matrix position z(1) + tsize# * 0.55 * max)
      shift matrix up 1
      shift matrix up 1
      update matrix MatrixNumber
      position matrix 1,matrix position x(1),matrix position y(1),matrix position z(1)+2*tsize#

      `get realworld tile
      x2= (matrix position x(1)/tsize#)
      z2= (matrix position z(1)/tsize#)
      for z= max-1 to max
         for x=0 to max
            x3= x2 + x
            z3= z2 + z
            Height#= heightmap(x3,z3)
            set matrix height MatrixNumber, x, z, Height#

            if x<max and z<max
               TileID=1+rnd(3)
               set matrix tile MatrixNumber, x, z, TileID
            endif
         next x
      next z
      update matrix MatrixNumber

      for z= max-2 to max-1
         for x=1 to max-1
            normalize(MatrixNumber,x,z)
         next x
      next z
      update matrix MatrixNumber

      unloadscenery()
      for z= max-1 to max
         for x=0 to max
            loadscenery(x,z)
         next x
      next z
   endif


   if (z# < matrix position z(1) + tsize# * 0.45 * max)
      shift matrix down 1
      shift matrix down 1
      update matrix MatrixNumber
      position matrix 1,matrix position x(1),matrix position y(1),matrix position z(1)-2*tsize#

      `get realworld tile
      x2= matrix position x(1)/tsize#
      z2= (matrix position z(1)/tsize#)
      for z = 1 to 0 step -1
         for x=0 to max
            x3= x2 + x
            z3= z2 + z
             Height#= heightmap(x3,z3)
            set matrix height MatrixNumber, x, z, Height#

            if x<max and z<max
               TileID=1+rnd(3)
               set matrix tile MatrixNumber, x, z, TileID
            endif
         next x
      next z
      update matrix MatrixNumber

      for z = 2 to 1 step -1
         for x=1 to max-1
            normalize(MatrixNumber,x,z)
         next x
      next z
      update matrix MatrixNumber

      unloadscenery()
      for z = 1 to 0 step -1
         for x=0 to max
             loadscenery(x,z)
         next x
      next z
   endif
endfunction

`debugging display
_mdat:
matnum = 1
set cursor 0,0
print "matrix DATA"
 print " matrix number:";matnum
 print " exist:";matrix exist(matnum)
 if matrix exist(matnum)=1
 print " x:";matrix position x(matnum)
 print " y:";matrix position y(matnum)
 print " z:";matrix position z(matnum)
 `print " height:";get ground height(matnum, cx#, cz#)
 rem print " totalheight:";get total terrain height(TerrainNumber)
 endif
print
print "CAMERA DATA"
print " x:";camera position x(0)
print " y:";camera position y(0)
print " z:";camera position z(0)
print " x angle:";camera angle x(0)
print " y angle:";camera angle y(0)
print " z angle:";camera angle z(0)
print "Other DATA"
`print "Incline:";incline
print "Creatures:";array count(creatures(0))
print "Last Creature ObjNum:";creatures(array count(creatures(0))-1).objnum
print "debug: ";debug
   remstart
   str1$="numbers"
   for x= 0 to array count(creatures(0)) - 1
      obj= creatures(x).objnum
      str1$=str1$+" "+str$(obj)
   next x
   print str1$
   remend
return

`camera tracks player
function CameraTrack(matrix,obj):
   camx#= camera position x(0)
   camy#= camera position y(0)
   camz#= camera position z(0)
   rem smooth third person camera
   rotate camera camera angle x(0)+(mousemovey()/2.0),camera angle y(0)+(mousemovex()/2.0),0
   if wrapvalue(camera angle x(0))>90 and wrapvalue(camera angle x(0))<180 then xrotate camera 0,90
   if wrapvalue(camera angle x(0))>180 and wrapvalue(camera angle x(0))<260 then xrotate camera 0,260
   a#= camera angle y(0)
   b#= camera angle x(0)
   pointx#=object position x(obj)
   pointz#=object position z(obj)
   pointy#= object size(obj)+object position y(obj)+25
   cy#=newyvalue(pointy#,b#,-camdist#)
   cx#=newxvalue(pointx#,a#,cos(b#)*-camdist#)
   cz#=newzvalue(pointz#,a#,cos(b#)*-camdist#)

   h#= get ground height(1,cx#-matrix position x(1),cz#-matrix position z(1))+camdist#/8
   if cy# < h#
      diff#= (camdist#-(h#- cy#))/camdist#
      cy#=newyvalue(pointy#,b#,-camdist#*diff#)
      cx#=newxvalue(pointx#,a#,-camdist#*cos(b#)*diff#)
      cz#=newzvalue(pointz#,a#,-camdist#*cos(b#)*diff#)
   endif
   remstart
   h#= get ground height(1,cx#-matrix position x(1),cz#-matrix position z(1))+30
   if cy#<h#
      cy#=h#
      point camera pointx#,pointy#,pointz#
   endif
   remend
   position camera cx#,cy#,cz#
   POSITION LISTENER cx#,cy#,cz#
endfunction

`camera tracks player
function CameraTrack2(matrix,obj):
   camx#= camera position x(0)
   camy#= camera position y(0)
   camz#= camera position z(0)
   rem smooth third person camera
   a#= object angle y(obj)
   cx#=newxvalue(object position x(obj),a#,-camdist#)
   cz#=newzvalue(object position z(obj),a#,-camdist#)
   cy#= get ground height(1,cx#-matrix position x(1),cz#-matrix position z(1))+ 0.4*camdist#
   if object position y(obj)+0.7*camdist# > cy# then cy# =  (cy# + object position y(obj)+0.4*camdist#)/2.0
   camx#=curvevalue(cx#,camx#,25.0)
   camy#=curvevalue(cy#,camy#,70.0)
   camz#=curvevalue(cz#,camz#,25.0)
   position camera camx#,camy#,camz#
   POSITION LISTENER camx#,camy#,camz#

   pointx#=newxvalue(object position x(obj),a#,camdist#/2)
   pointz#=newzvalue(object position z(obj),a#,camdist#/2)
   point camera pointx#,object position y(obj)+ 0.4*camdist#+ object size y(obj),pointz#
endfunction

function CameraFirstPerson(obj):
   rotate camera camera angle x(0)+(mousemovey()/2.0),camera angle y(0)+(mousemovex()/2.0),0
   if wrapvalue(camera angle x(0))>70 and wrapvalue(camera angle x(0))<180 then xrotate camera 0,70
   if wrapvalue(camera angle x(0))>180 and wrapvalue(camera angle x(0))<280 then xrotate camera 0,280
   rotate object obj, object angle x(obj),camera angle y(0),object angle z(obj)
   a#= object angle y(obj)
   camy#= object size(obj)+object position y(obj)
   camx#=newxvalue(object position x(obj),a#,15)
   camz#=newzvalue(object position z(obj),a#,15)
   position camera camx#, camy#, camz#
   POSITION LISTENER camx#, camy#, camz#
endfunction

`used to create heightmap for matrix
function heightmap(x3,z3)
   noise = 1.0
   height = cos(991.0*cos((z3+x3)*noise))*160.0 + sin(951.0*cos((x3)*1.3*noise))*110.0 + cos(971.0*sin((x3-z3)*2*noise))*70.0 + sin(977.0*sin((-z3)*3*noise))*40 + cos(907.0*cos((z3-x3)*5.0*noise))*25.0
   height = height*1.5 :`final modifier to terrain deformation height
endfunction height

`creates matrix normals
function normalize(M,X,Z)
`         Make Vectors
        r=Make Vector3(1)
        r=Make Vector3(2)
        r=Make Vector3(3)

        softness#= 1.5
        tw#= softness# * tsize# : ` need to adjust according to "look"  - heavy/light shadows 0-15

        `Make two vectors at each vertex in same plane
        AX# = X: AZ# = Z:AY# = Get matrix Height(1, AX#, AZ#)
        dzx#=((Get matrix Height(M, AX#-1, AZ#))- (Get matrix Height(M, AX#+1, AZ#)))
        dzy#=((Get matrix Height(M, AX#, AZ#-1))- (Get matrix Height(M, AX#, AZ#+1)))

        ` Set vectors  - based on your axis, might need to change (-) signs
        Set Vector3 1, -tw#,dzx#,0
        Set Vector3 2, 0,-dzy#,tw#

        ` Get cross product of 2 vertex vectors - gives the normal
        Cross Product Vector3 3,1,2

        `Pull out x,y,z of Normal
        nx#=x vector3(3)
        ny#=y vector3(3)
        nz#=z vector3(3)
        set matrix normal M, x,z,nx#,ny#,nz#
endfunction

`for debugging
function test()
   z= size*0.6
   x= size*0.6
   while z > -1000 and mouseclick()=0
   position camera -400,1400,-400
   `world(size/2,z)
   set cursor 0,0
   if upkey()=1
      print " up"
      z=z+20
      world(x,z)
   endif
   if downkey()=1
      print " down"
      z=z-20
      world(x,z)
   endif
   if rightkey()=1
      print " right"
      shift matrix right 1
      shift matrix right 1
      update matrix 1
   endif
   if leftkey()=1
      print " left"
      shift matrix left 1
      shift matrix left 1
      update matrix 1
   endif
   point camera matrix position x(1)+(0.3*size),matrix position y(1),matrix position z(1)+(0.3*size)
   sync
   sleep 80
   endwhile
endfunction

function test2()
   str1$="numbers"
   error= 0
   for x= 0 to array count(creatures(0)) - 1
      obj= creatures(x).objnum
      str1$=str1$+" "+str$(obj)
      if x > 0 and (obj <1000 or obj >= 2000) then error = 1
   next x
   if error then print str1$
endfunction error

_load_world:
      `need to clone objects for speed reasons
   load object "H-Alien Psionic-Idle.x",999
   `append object "H-Alien Psionic-Die.x", 999, total object frames(999)+1
   scale object 999,3500,3500,3500
   set object specular 999,0
   set object 999,1,0,0,2,1,1
   set object collision to boxes 999
   set object collision on 999

   global max
   max = 50
   global size
   size = 15000
   global tsize#
   tsize# = size/max

   editmatrix(1,0,0)
   for x=0 to max
      for z=0 to max
         loadscenery(x,z)
      next z
   next x

   L#= size*0.90 : rem distance to sky at horizon
   O#= 0.75 : rem radii above center camera will appear in sky sphere
   rem calculate radius
   r#= sqrt((L#*L#)/(O#*O#+1))
   O#= r#*O#
   make object sphere 1,2.0*r#,20,20
   texture object 1,1
   scale object texture 1,9.0,9.0
   set object 1,1,0,0,2,0,1
   `fix object pivot 1
   xrotate object 1,90
   `fix object pivot 1
   set object collision off 1

   set camera range 1,size
   `set display mode 800,768,32
   camdist#= 250.0
   global camdist#

   set ambient light 35
   make light 1
   rem Set Default Light As Sun
   set directional light 1,1,-2,2
   `color light 1,220,212,182
   color light 1,150,140,130

   rem Set up Fog
    set normalization on
    fog on
    fog distance size*0.40
    `fog color rgb(245,235,225)
    fog color rgb(210,210,220)
return

_load_player:
   load object "ColZ.x",2
   position object 2,size/2,0,size/2
   xrotate object 2,270
   fix object pivot 2
   rotate object 2,0,180,0
   scale object 2, 60.0,60.0,60.0
   set object specular 2,0
   heroframe#=total object frames(2)/200.0
   set object speed 2,2000
   loop object 2,0,12*heroframe#
   `crazy dba v1.05 commands
   `set object diffuse 2,rgb(255,0,0)
   `set object ambience 2,rgb(0,0,0)
   `set object emissive 2,rgb(0,0,64)
   `set object specular 2,rgb(255,255,255)
   `set object specular power 2,1
   `set object smoothing 2,0
   DELETE OBJECT COLLISION BOX 2
   set object collision to boxes 2
return

_load_images:
   load image "grass.bmp",2
   set image colorkey 0,0,0
   load image "tree.bmp",11
   load image "cloudsTexture.jpg",1
   load image "crosshair.bmp",3
   load image "fire.bmp",2000
return

_load_sounds: