`Standard setup
sync on
sync rate 60
hide mouse
if check display mode(1024,768,32)
	set display mode 1024,768,32
endif
set text font "Arial"
set text size 20
ink -1,0
randomize timer()
set camera range 1,10000
autocam off
 
`Declare variables
dim options(-1) as string
#Constant sw screen width()
#Constant sh screen height()
 
repeat
	`Choose Mode
	text_menu_add("Level Editor")
	text_menu_add("Play Game")
	text_menu_add("Exit")
	choice=text_menu_run()
 
	`Level Editor
	if choice=0
	   repeat
	  	   filehandle=3
			input "Level Name: ",fname$
			fname$=fname$+".dat"
			if file exist(fname$)=1
			   text_menu_add("Work from previous")
			   text_menu_add("Overwrite previous")
			   text_menu_add("Choose different name")
				filehandle=text_menu_run()
			endif
		until filehandle<>2
		highestobject=2
		startobject=0
		if filehandle=0
		   open to read 1,fname$
		   read float 1,a#
		   read float 1,b#
			make object sphere 2,10,3,5
			color object 2,rgb(0, 64, 128)
		   position object 2,a#,6,b#
			cobj=2
			while file end(1)=0
				inc cobj
				read float 1,objtype#
				if objtype#=0.0
				   make object box cobj,100,10,100
				   color object cobj,rgb(0,128,0)
					read float 1,a#
					read float 1,b#
					position object cobj,a#,6,b#
					read float 1,a#
					read float 1,b#
					scale object cobj,a#,100,b#
				else
				   make object sphere cobj,10,3,5
				   xrotate object cobj,180
				   color object cobj,rgb(255, 255, 128)
					read float 1,a#
					read float 1,b#
					position object cobj,a#,6,b#
				endif
			endwhile
			close file 1
			highestobject=cobj
			startobj=2
		endif
		if filehandle=1
			delete file fname$
		endif
		editorchoice=0
		mode=0
		make object box 1,1000,2,1000
		position camera 0,150,-1000
		xrotate camera 20
		backdrop on
		color backdrop rgb(128,0,0)
		repeat
		   if escapekey()=1
		      end
			endif
			sync
			ink 0,0
			box sw/2-10,sh/2-1,sw/2+10,sh/2+1
			box sw/2-1,sh/2-10,sw/2+1,sh/2+10
			select mode
				case 0
	   			modestring$="Create Walls"
				endcase
				case 1
	   			modestring$="Set player starting point"
				endcase
				case 2
					modestring$="Add powerups"
				endcase
				case 3
					modestring$="Delete items"
				endcase
			endselect
			set cursor 0,0
			print "Action: "+modestring$
			print "Press Space for options"
			free_flight(0,3)
			if spacekey()=1
			   text_menu_add("Continue")
			   text_menu_add("Create Walls")
			   text_menu_add("Set player starting point")
			   text_menu_add("Add powerups")
			   text_menu_add("Delete items")
			   text_menu_add("Save")
			   text_menu_add("Exit")
			   editorchoice=text_menu_run()
			   if editorchoice>0 and editorchoice<5
				   mode=editorchoice-1
				endif
				if editorchoice=5
				   if startobject=0
						print "You must choose a starting position before saving."
						sync
						wait key
				   else
					   if file exist(fname$)=1
					      delete file fname$
						endif
						open to write 1,fname$
						a#=object position x(startobject)
						b#=object position z(startobject)
						write float 1,a#
						write float 1,b#
						for i=2 to highestobject
						   if object exist(i)=1 and i<>startobject
								if object angle x(i)=0
								   write float 1,0.0
								   a#=object position x(i)
								   b#=object position z(i)
								   write float 1,a#
									write float 1,b#
									a#=object size x(i,1)
									b#=object size z(i,1)
									write float 1,a#
									write float 1,b#
								else
								   write float 1,1.0
								   a#=object position x(i)
								   b#=object position z(i)
								   write float 1,a#
								   write float 1,b#
								endif
						   endif
						next i
						close file 1
					endif
				   while spacekey()=1
				   endwhile
				endif
			endif
			mc=mouseclick()
			if mc=0
			   hold=0
			endif
			if mc=1
			   if mode=0
			      if hold=0
			         collide=pick object(sw/2,sh/2,1,1)
						if collide=1
						   bx=get pick vector x()+camera position x()
						   bz=get pick vector z()+camera position z()
						   cobj=free_object()
						   make object box cobj,100,10,100
						   position object cobj,bx,6,bz
						   color object cobj,rgb(0,128,0)
						   if cobj>highestobject
						      highestobject=cobj
							endif
						else
						   cobj=0
						endif
					endif
					if hold=1
					   if cobj>0
				         collide=pick object(sw/2,sh/2,1,1)
							if collide=1
							   cx=get pick vector x()+camera position x()
							   cz=get pick vector z()+camera position z()
								scale object cobj,abs(cx-bx),100,abs(cz-bz)
							   position object cobj,(cx+bx)/2.0,6,(cz+bz)/2.0
							endif
					   endif
					endif
			   endif
				if mode=1
		         collide=pick object(sw/2,sh/2,1,1)
					if collide=1
					   bx=get pick vector x()+camera position x()
					   bz=get pick vector z()+camera position z()
					   if startobject=0
					      startobject=free_object()
							make object sphere startobject,10,3,5
							position object startobject,bx,6,bz
							color object startobject,rgb(0, 64, 128)
							if startobject>highestobject
							   highestobject=startobject
							endif
						else
							position object startobject,bx,6,bz
						endif
					endif
				endif
				if mode=2 and hold=0
		         collide=pick object(sw/2,sh/2,1,1)
					if collide=1
					   bx=get pick vector x()+camera position x()
					   bz=get pick vector z()+camera position z()
					   cobj=free_object()
					   make object sphere cobj,10,3,5
					   position object cobj,bx,6,bz
					   xrotate object cobj,180
					   color object cobj,rgb(255, 255, 128)
					   if cobj>highestobject
                     highestobject=cobj
						endif
					endif
				endif
				if mode=3 and hold=0
		         collide=pick object(sw/2,sh/2,2,highestobject)
					if collide>0
						delete object collide
					endif
				endif
			   hold=1
			endif
		until editorchoice=6
		for i=1 to highestobject
			if object exist(i)=1
			   delete object i
			endif
		next i
		backdrop off
	endif
 
	`Game
	if choice=1
 		color backdrop rgb(128,0,0)
	   leave=0
	   repeat
		   input "Level name: ",fname$
		   fname$=fname$+".dat"
			if file exist(fname$)=0
				text_menu_add("Oops a typo in my level name.")
				text_menu_add("Let me out of here.")
				leave=text_menu_run()
			endif
		until file exist(fname$)=1 or leave=1
		backdrop on
		if leave=0
		   make object box 1,1000,2,1000
		   open to read 1,fname$
		   read float 1,a#
		   read float 1,b#
		   position camera a#,3,b#
		   rotate camera 0,0,0
		   make object cube 2,3
		   position object 2,a#,3,b#
			cobj=2
			while file end(1)=0
				inc cobj
				read float 1,objtype#
				if objtype#=0.0
				   make object box cobj,100,10,100
				   color object cobj,rgb(0,128,0)
					read float 1,a#
					read float 1,b#
					position object cobj,a#,6,b#
					read float 1,a#
					read float 1,b#
					scale object cobj,a#,100,b#
				else
				   make object sphere cobj,10,3,5
				   xrotate object cobj,180
				   color object cobj,rgb(255, 255, 128)
					read float 1,a#
					read float 1,b#
					position object cobj,a#,6,b#
				endif
			endwhile
			gun=free_object()
			make object cone gun,100
			scale object gun,1,25,1
			show object bounds gun
			disable object zdepth gun
			color object gun,rgb(255,255,0)
			set object emissive gun,rgb(255,0,0)
			global firstenemy
			firstenemy=gun+1
			numenemies=50
			for i=firstenemy to firstenemy+numenemies
			   make object cube i,6
			   color object i,rgb(128, 255, 255)
			   set object emissive i,rgb(128,255,128)
			   repeat
				   position object i,rnd(1000)-500,5.5,rnd(1000)-500
				until object collision(i,0)=0
				rotate object i,rnd(360),rnd(360),0
			next i
			gundelay=0
			global health=50
			global speed as float
			global gundelayinc
			gundelayinc=50
			speed=0.5
 
			`Main Loop
			do
				sync
				ink 0,0
				text 0,0,"Health: "+str$(health)
				text 0,30,"Gun Recharge: "+str$(gundelay)
				box sw/2-10,sh/2-1,sw/2+10,sh/2+1
				box sw/2-1,sh/2-10,sw/2+1,sh/2+10
				fps_camera(0,speed)
				cx#=camera position x()
				cz#=camera position z()
				position object gun,cx#,3,cz#
				rotate object gun,camera angle x()+90,camera angle y(),camera angle z()
				move object right gun,4
				move object up gun,10
				if mouseclick()=1
					if gundelay=0
					   gundelay=gundelayinc
						shoot=pick object(sw/2,sh/2,firstenemy,firstenemy+numenemies)
					   if shoot>0
					      delete object shoot
						endif
					endif
				endif
				if gundelay>0
				   dec gundelay
				endif
				eleft=0
				for i=firstenemy to firstenemy+numenemies
				   if object exist(i)=1
				      eleft=1
				      px#=object position x(i)
				      pz#=object position z(i)
						x#=object angle x(i)
						xrotate object i,0
				      move object i,0.2
				      xrotate object i,x#+1
				      yrotate object i,object angle y(i)+rnd(8)-4
				      if object collision(i,0)>0
							position object i,px#,5.5,pz#
							yrotate object i,object angle y(i)+180
						endif
				   endif
				next i
				if health<=0
					text 0,60,"You were killed"
					sync
					wait key
					end
				endif
				if eleft=0
					text 0,60,"You have killed everything"
					sync
					wait key
					end
				endif
			loop
 
		endif
	endif
until choice=2
end
 
`Functions
function text_menu_add(option as string)
array insert at bottom options(0)
options(array count(options(0)))=option
endfunction
 
function text_menu_clear()
undim options(0)
global dim options(-1) as string
endfunction
 
function text_menu_run()
repeat
until returnkey()=0
choice=0
lastmove=0
repeat
if escapekey()=1
	end
endif
sync
cls
set cursor 0,0
for i=0 to array count(options(0))
	if choice=i
	   ink rgb(255,0,0),0
	else
	   ink -1,0
	endif
	print options(i)
next i
move=downkey()-upkey()
if move=0
	lastmove=0
endif
if lastmove=0
	inc choice,move
	lastmove=move
endif
if choice<0
	choice=0
endif
if choice>array count(options(0))
	choice=array count(options(0))
endif
until returnkey()=1
text_menu_clear()
while returnkey()=1
endwhile
ink -1,0
endfunction choice
 
function free_flight(cam,speed#)
move camera cam,speed#*(upkey()-downkey())
x#=camera angle x(cam)
rotate camera cam,0,camera angle y(cam)+90,0
move camera cam,speed#*(rightkey()-leftkey())
rotate camera cam,x#+mousemovey()/2.0,camera angle y(cam)-90+mousemovex()/2.0,0
if camera angle x(cam)>90 then xrotate camera cam,90
if camera angle x(cam)<-90 then xrotate camera cam,-90
endfunction
 
function free_object()
repeat
	inc i
until object exist(i)=0
endfunction i
 
function fps_camera(cam,speed#)
px#=camera position x()
pz#=camera position z()
x#=camera angle x(cam)
xrotate camera cam,0
move camera cam,speed#*(upkey()-downkey())
yrotate camera cam,camera angle y(cam)+90
move camera cam,speed#*(rightkey()-leftkey())
position object 2,camera position x(),3,camera position z()
collide=object collision(2,0)
if collide>0
	position camera px#,3,pz#
	position object 2,px#,3,pz#
	if collide>firstenemy
		dec health
	else
	   if object angle x(collide)=180
	      `give power up
			up=rnd(2)
			select up
			   case 0
			      speed=speed*2
				endcase
				case 1
				   gundelayinc=gundelayinc/2
				endcase
				case 2
				   inc health,10
				endcase
			endselect
	      move object down collide,15
		endif
	endif
endif
rotate camera cam,x#+mousemovey()/2.0,camera angle y(cam)-90+mousemovex()/2.0,0
if camera angle x(cam)>90 then xrotate camera cam,90
if camera angle x(cam)<-90 then xrotate camera cam,-90
endfunction