Just mucking around with some rendering in blitz3d

Started by Matty, July 14, 2024, 17:22:09

Previous topic - Next topic

Matty

I made this today (well yesterday, it's 1am now that I'm posting this!) in Blitz3d. The rendering was reasonably quick on my old PC, but it's not realtime rendering.

The code is shown below as well:




Code: BASIC
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Renderer for 3d Scenes
;
;Non Realtime
;
;Matt Lloyd 2024
;
;
Global rtxti = 0
Global renderfileprefix$ = ""
global scriptfolder$ = "scripts\"
global renderquality = 5;;0-10, or higher than 10 to record as well...
global worldtex$ = "deserttex.jpg"
global worldmap$ = "desertmap.png"
Global fogr,fogg,fogb
Global clsr,clsg,clsb
Global cloudtexfile$ = "cloudtex.png"
global treedensity = 0
global rockdensity = 0
global bushdensity = 0
fogr = 100
fogg = 140
fogb = 180
clsr = fogr
clsg = fogg
clsb = fogb
Global fogmin = 10
Global fogmax = 180
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Global debugging = 0

debugging = 1
scg# = 0.175
global record = 0
startframe = 0
Global renderfrom = 0
skipframe = 0
skipped = 0
global maxframe = 50
;;;;;;;;;;;;;;;;;;
doclouds = 0
dorocks = 0
dobushes = 0
Global doshadows = 0
dotrees = 0
grasson = 0
spedup = 0
;renderquality = 10
.setuprenderer
checkinginput = 0;change this later...to either 0,1 or 2 to check the values...
If CommandLine$()<>"" Then 
	txt$ = CommandLine$()
	If Instr(txt,"-start:")>0 Then
		renderfrom = Int(Mid(txt,Instr(txt,"-start:")+7,8)) ;check this works
		If checkinginput=1 Then RuntimeError("startframe is:"+renderfrom)
		startframe = 0;
		spedup = 0;
	EndIf
	If Instr(txt,"-end:")>0 Then
		;maybe it's maxframe, not maxframes, I cannot remember off the top of my head
		maxframes = Int(Mid(txt,Instr(txt,"-end:")+5,8))
		maxframe = maxframes ;just in case I've got it wrong...doesn't hurt to do this if I'm wrong.
		If checkinginput=2 Then RuntimeError("endframe is:"+maxframes)
	EndIf
	If Instr(txt,"-record:1")>0 Then 
		record = 1
	Else
		record = 0
	EndIf
	If Instr(txt,"-quality:")>0 Then
		renderquality = Int(Mid(txt,Instr(txt,"-quality:")+9,8))
	EndIf 
	if instr(txt,".txt")>0 then
		;a config file is passed, no other parameters
		configfile(commandline$())
	endif
	
Else
	;the old input boxes go here.....simply put them in here when you get home.....
	renderfrom = Abs(Int(Input("Render From This Frame:")))
	maxframe = Abs(Int(Input("Render To This Frame:")))
	record = Int(Input("Type '1' to Record Frames To Disk"))
	renderquality = Int(Input("Quality Setting:"))
EndIf 

Select renderquality
Case -1
	spedup = 4
Case 0
	;default
Case 1
	dotrees = 1
Case 2
	doclouds = 1
Case 3
	dotrees = 1
	doclouds = 1
Case 4
	dotrees = 1
	doshadows = 0
	dorocks = 1
	doclouds = 1
Case 5
	dotrees = 1
	doshadows = 0
	dobushes = 1
	dorocks = 1
	doclouds = 1
Case 6
	dotrees = 1
	doshadows = 1
	dobushes = 1
	dorocks = 1
	doclouds = 1
Case 7
	grasson = 1
	dotrees = 1
	doshadows = 2
	dobushes = 1
	dorocks = 1
	doclouds = 1
Case 8
	grasson = 1
	dotrees = 1
	doshadows = 0
	dobushes = 1
	dorocks = 1
	doclouds = 1
Case 9
	grasson = 1
	dotrees = 1
	doshadows = 1
	dobushes = 1
	dorocks = 1
	doclouds = 1
Case 10
	grasson = 1
	dotrees = 1
	doshadows = 2
	dobushes = 1
	dorocks = 1
	doclouds = 1
End Select
If renderquality > 10 Then
	grasson = 1
	dotrees = 1
	doshadows = 2
	dobushes = 1
	dorocks = 1
	doclouds = 1
	record = 1
EndIf




Global frame# = -3
Const debugginglights = 0
Global worldscale# = 4.0
windowed = 2
dim explosiontex(8) ;7aug2024
global explosionsprite
type explosionstruct
	field frame# ;0-63
	Field x#,y#,z#
	Field vx#,vy#,vz#
	Field sc#
	Field index ;0-8
end type
Global bloode# = 0.88
Global blooda# = -0.02
Global bloodv# = 0.065
Type bloodexplosion ;this is for when a unit dies...we'll add camera shake as well....
	Field x#,y#,z#
	Field vx#,vy#,vz#
	Field life
	Field fiery
End Type

SeedRnd 3

Global bullet1,bullet2,bullet3

Type bullet
	Field x#,y#,z#,vx#,vy#,vz#
	Field life
	field flamer ;7aug2024
	Field rocket ;7aug2024
	Field blue
End Type

;load level mesh stuff
;load/generate map however we end up doing it....


Global camshake#,camshakex#,camshakey#,delta#


If record<>1 Then record = 0
Graphics3D 1920,1080,0,2
pleasewait("Loading explosions")
loadexplosions()
pleasewait("Loading scripts")
loadscripts()
pleasewait("Setting up Part 1")
AntiAlias True 
Global camera = CreateCamera()
AlignToVector camera,0,-1,1.5,3,1
MoveEntity camera,0,0,-100
Global gplane = CreatePlane()
EntityColor gplane,40,40,40
EntityPickMode gplane,2
;;;;;
;Lighting
;
AmbientLight 0,0,0
lp = CreatePivot()
light1 = CreateLight(1)
LightColor light1,240,200,150
EntityParent light1,lp
AlignToVector light1,1,-1,1,3,1
light2 = CreateLight(1)
LightColor light2,240,200,150
AlignToVector light2,-1,-1,1,3,1
EntityParent light2,lp
light3 = CreateLight(1)
LightColor light3,240,200,150
AlignToVector light3,1,-1,-1,3,1
EntityParent light3,lp
light4 = CreateLight(1)
LightColor light4,240,200,150
AlignToVector light4,-1,-1,-1,3,1
EntityParent light4,lp
;;;;;
For c = 1 To CountChildren(lp)
	LightColor GetChild(lp,c),240,200,150
Next
Global bloodcube = CreateCube()
ScaleEntity bloodcube,0.05,0.05,0.05
HideEntity bloodcube

Dim mesh(200)
Dim meshsc#(200)



Global grassid = 0
Global bushid = 0
Global rockid = 0
pleasewait("Loading meshes")
loadmeshes()



	cube = CreateCube() ;for reference purposes only...
	EntityAlpha cube,0.8
	EntityColor cube,255,0,255
	
	PositionEntity camera,0,1.75,0
	AlignToVector camera,0,1,0,2,1
	AlignToVector camera,0,0,1,3,1
	TranslateEntity camera,0,0,-50
	
	gcube = CreateCube()
	FitMesh gcube,-100,-1,-100,200,1,200,False
	
	gtex0 = LoadTexture(worldtex$,1)
	SetBuffer BackBuffer()
	Global map = LoadTerrain(worldmap$)
	TerrainDetail map,30000
	TerrainShading map,True
	ScaleTexture gtex0,1,1
	ScaleEntity map,5,150,5
	PositionEntity map,-512.0*2.5,0,-512.0*2.5
	SetBuffer BackBuffer()
	EntityTexture map,gtex0,0,0;desert
	TranslateEntity gplane,0,-0.5,0
	CameraClsColor camera,clsr,clsg,clsb
	PositionEntity map,-1024,0,-1024
	pleasewait("Executing initial scripts")
	scriptplace()
	pleasewait("Entering loop")
Repeat ;MAIN LOOP
	;;;;;;;;;;;;;;;;;;;;;
	;;;;;;;;;;;;;;;;;;;;;
	delta = 1.0
	camshakex = 0
	camshakey = 0
	If camshake > 0 Then 
		camshake = camshake - delta
		camshakex = Rnd(-1,1) * camshake * 0.0135
		camshakey = Rnd(-1,1) * camshake * 0.0135
	EndIf
	tris = 0
	frame = frame + 1

	;;;;;;;;;;;;;;;; Handle All Object Motion In This Segment ;;;;;;;;;;;;;;;;;;
	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	animscript()
	bulletscript()
	explosionscript()
	updateexplosions() ;7aug2024
	updatebullets()
	;;;;;;;;;;;;;;;; Handle Camera Motion Immediately Below Here;;;;;;;;;;;;;;;;	
	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	

	camerascript()
	
	;;;;;;;;;;;;;;;; Handle Camera Motion Above This Line ;;;;;;;;;;;;;;;;;;;;;;	
	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
	
	;;;;;;;;;;;;;;;; Rendering Takes Place In This Next Section ;;;;;;;;;;;;;;;;
	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
	
	If (frame Mod (spedup+1) = 0 And spedup >= 1) Or spedup = 0 Then 
		If skipframe > 0 Then 
			If skipped = 1 Then startframe = frame + (frame Mod skipframe) - 3
		EndIf 	
		If frame >= startframe And (record = 0 Or (record<>0 And frame Mod 2 = 0)) Then 
			skipped = 1
			CameraClsMode camera,True,True
			ShowEntity gplane
			For id = 0 To 200
				If mesh(id)<>0 Then HideEntity mesh(id)
			Next
			ShowEntity cube
			HideEntity cube
			HideEntity gcube
			ShowEntity map
			renderworld3
			HideEntity gcube
			HideEntity gplane
			HideEntity cube
			HideEntity map
			CameraClsMode camera,False,False
			CameraFogMode camera,False
			ShowEntity map
			If renderquality > 15 Then 
				For ix# = 0.1 To 1.0 Step 0.1
					TranslateEntity map,Rnd(-0.25,0.25),Rnd(0.1,0.15),Rnd(-0.25,0.25)
					EntityAlpha map,0.1
					renderworld3
				Next
			EndIf 
			EntityAlpha map,1
			PositionEntity map,-1024,0,-1024
			HideEntity map
			If doclouds = 1 Then 
				If cloudtex = 0 Then
					 cloudtex = LoadTexture(cloudtexfile$,1+2)
				EndIf
				
				If cloud = 0 Then
					cloud = CreateSphere()
					EntityTexture cloud,cloudtex
					EntityAlpha cloud,0.6
					EntityFX cloud,1
					ScaleMesh cloud,10,4,7
				EndIf
				ShowEntity cloud
				SeedRnd 893483
				gcloud# = gcloud# + 1.0
				If gcloud > 2048 Then gcloud = 0
				For i = 1 To 250
					gx# = Rnd(-1024,1024) + gcloud
					gz# = Rnd(-1024,1024) + gcloud
					If gx > 1024 Then gx = gx - 2048
					If gz > 1024 Then gz = gz - 2048
					For j = 1 To 30
						xt# = gx + Rnd(-100,100)
						zt# = gz + Rnd(-100,100)
						gy# = ym(xt,zt)+Rnd(-30,70);Rnd(50,250)
						
						PositionEntity cloud,xt+zcloud,gy,zt+zcloud
						scx# = Rnd(10,30)*0.66
						scy# = Rnd(4,15)*0.5
						scz# = Rnd(10,30)*0.66
						EntityAlpha cloud,Rnd(0.05,0.35)*0.2*1.0
						ScaleEntity cloud,scx,scy,scz			
						CameraProject camera,xt,gy,zt
						If ProjectedZ()>0 And ProjectedX()>-200 And ProjectedX()<2120 And ProjectedY()>-400 And ProjectedY()<1400 Then 
							renderworld3
							tris = tris + TrisRendered
						EndIf 
					Next
				Next
				HideEntity cloud		
			EndIf 
			CameraFogMode camera,True
			CameraFogRange camera,fogmin,fogmax
			
			CameraFogColor camera,fogr,fogg,fogb

			If frame < renderfrom Then Goto skipzone2
			CameraFogMode camera,1
			;script instances.......
			drawalienplants()
			drawstatics()
			drawanims()
			drawbullets()
			drawexplosions() 
			HideEntity mesh(grassid)
			HideEntity mesh(grassid+1)
			If zonepivot=0 Then zonepivot = CreatePivot()
			For zonex# = -128 * 20 To 128 * 20 Step 128
				For zonez# = -128 * 20 To 128 * 20 Step 128
					PositionEntity zonepivot,zonex,EntityY(camera),zonez
					If EntityDistance(zonepivot,camera)>512 Then Goto skipzone
					If dotrees = 1 And frame >= renderfrom And frame>=startframe Then
						dda = 90
						If grasson = 0 Then dda = 0 
						grass = mesh(grassid)
						ShowEntity mesh(grassid)
						ScaleEntity grass,scx*0.2,scy*0.2,scz*0.2
						grasspivot = CreatePivot()
						mmn = 0
						j = 0
						jx# = 0
						jz# = 0
						yaw# = 0
						x = 0
						z = 0
						xx4# = 2.5
						seedrnd abs(zonex+zonez+8383)
						For i = 1 To dda
							x = x + 3
							If x > 80 Then x = -80
							For x3# = -9  To 9 Step 0.5
								yaw# = yaw# + 33.0
								z = z + 3
								If z > 80 Then z = -80
								For z3# = -9 To 9 Step 0.5
									r3 = z3*z3 + x3*x3
									xx4# = Rnd(0.2,2.5)
									If xx4 > 2.5 Then xx4 = 0.5
									ScaleEntity grass,scx*0.2*xx4,scy*0.2*xx4,scz*0.2*xx4
									j = j + 1
									jx# = jx# + 0.2
									If jx > 2.0 Then jx = -2
									jz# = jz# + 0.2
									If jz > 2.0 Then jz = -2
									xt# = Float(zonex+x+x3)+jx#+Rnd(-2,2)
									zt# = Float(zonez+z+z3)+jz#+Rnd(-2,2)
									if scripterase(cat_grass,xt,zt) then goto erasegrass
									yt# = ym(xt,zt)
									pitch# = 0
									PositionEntity grass,xt,yt,zt
									RotateEntity grass,pitch,yaw,0
									scx# =1; Rnd(0.5,1.5)*0.3
									scy# = 1;Rnd(0.75,2.25)*0.25
									scz# = 1;Rnd(0.5,1.5)*0.3
									PositionEntity grasspivot,xt,yt,zt
									If EntityDistance(camera,grasspivot)<200
										CameraProject camera,xt,yt,zt
										If ProjectedZ()>-100 And ProjectedY()>-100 And ProjectedY()<1180 And ProjectedX()>-100 And ProjectedX()<2020 Then 
											If r3 < 64 Then 
												renderworld3
												If EntityDistance(camera,grasspivot)<40 Then doshadow(grass)
											EndIf 
										EndIf 
									EndIf 
									.erasegrass
								Next
								;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
								;;;;;;;;;;;;;;;;;; This Is Needed So Program Runs In Background ;;
								;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
								If KeyHit(1) Then End
								If Abs(MilliSecs()-grasstime)>500 Then Delay 5:grasstime = MilliSecs()
							Next
						Next
						FreeEntity grasspivot:grasspivot = 0
						HideEntity mesh(grassid)
						SeedRnd 883411 
						For i = 1 To 189 + treedensity
							xx0# = zonex+Rnd(-64,64)
							zz0# = zonez+Rnd(-64,64)
							qqq = Rand(0,3)
							For j = 1 To qqq
								;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
								;;;;;;;;;;;;;;;;;; This Is Needed So Program Runs In Background ;;
								;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
								If KeyHit(1) Then End 
								If Abs(MilliSecs()-grasstime)>500 Then Delay 5:grasstime = MilliSecs()
								qq = Rand(0,4);3;Rand(0,1)+ rockid
								;0 is not fine because of alpha (should be fixed now)
								;3 is fine
								;4 is fine
								;2 is not fine, 1 is not fine
								qq = Rand(2,4)
								if qq = 2 then qq = 0
								xx# = xx0 + Rnd(-30,30)
								zz# = zz0 + Rnd(-30,30)
								en = mesh(qq)
								ShowEntity en
								PositionEntity en,xx,ym(xx,zz),zz
								RotateEntity en,0,Rnd(360),0
								meshsc(qq)=0.03
								If qq < 3 Then meshsc(qq) = 0.6
								If qq = 4 Then meshsc(qq) = 0.25
								If qq = 0 Then meshsc(qq) = 1.0
								xx4# = Rnd(0.8,1.4)
								ScaleEntity en,meshsc(qq)*xx4,meshsc(qq)*xx4,meshsc(qq)*xx4
								if scripterase(cat_tree,xx,zz) then 
									For j = 1 To 3
										Rnd(-3,3)
										Rnd(-3,3)
										Rand(360)
										Rnd(0.5,1.5)
									next						
									goto erasetree
								endif 
								
								If EntityDistance(camera,en)<600 Then 
									CameraProject camera,xx,ym(xx,zz),zz
									If ProjectedZ()>0 And ProjectedX()>-200 And ProjectedX()<2120 And ProjectedY()>-200 And ProjectedY()<1200 Then
										If EntityDistance(en,camera)<250 Then
											renderworld3
										Else
											If (i+j) Mod 3 = 0 Then renderworld3
										EndIf 
										odoshadows = doshadows
										doshadows = 1
										doshadow(en)
										doshadows = odoshadows
									EndIf 
								EndIf 
								HideEntity en
								en = mesh(grassid)
								ShowEntity en
								For j = 1 To 3
									xx1# = xx + Rnd(-3,3)
									zz1# = zz + Rnd(-3,3)
									PositionEntity en,xx1,ym(xx1,zz1),zz1
									RotateEntity en,0,Rand(360),0
									sc# = Rnd(0.5,1.5)*0.2
									ScaleEntity en,sc,sc,sc
									If EntityDistance(camera,en)<600 Then 
										CameraProject camera,xx1,ym(xx1,zz1),zz1
											If ProjectedZ()>0 And ProjectedX()>-200 And ProjectedX()<2120 And ProjectedY()>-200 And ProjectedY()<1200 Then
											If False Then
											Else
											renderworld3
											doshadow(en)
											EndIf
										EndIf 
									EndIf 
								Next
								.erasetree ;fixed where this was located
								HideEntity en
							next
						Next
					EndIf 
					If dorocks = 1 Then 
						SeedRnd 3411 ; Abs(zonex)+ Abs(zonez)
						For i = 1 To 600 + rockdensity
							xx0# = zonex+Rnd(-64,64)
							zz0# = zonez+Rnd(-64,64)
							qqq = Rand(3,6)
							For j = 1 To qqq
								qq = Rand(0,1)+ rockid
								xx# = xx0 + Rnd(-3,3)
								zz# = zz0 + Rnd(-3,3)
								en = mesh(qq)
								if scripterase(cat_rock,xx,zz) then
									rnd(360)
									rnd(-0.004,0.003)
									for j = 1 to 16
										rnd(-2,2)
										rnd(-2,2)
										rand(360)
										rnd(0.5,1.5)
									next
									goto eraserock
								endif
								ShowEntity en
								PositionEntity en,xx,ym(xx,zz),zz
								RotateEntity en,0,Rnd(360),0
								meshsc(qq)=0.008+Rnd(-0.004,0.003)
								ScaleEntity en,meshsc(qq),meshsc(qq),meshsc(qq)
								If EntityDistance(camera,en)<256 Then 
									CameraProject camera,xx,ym(xx,zz),zz
									If ProjectedZ()>0 And ProjectedX()>-200 And ProjectedX()<2120 And ProjectedY()>-200 And ProjectedY()<1200 Then
										renderworld3
									EndIf 
								EndIf 
								HideEntity en
								en = mesh(grassid)
								ShowEntity en
								For j = 1 To 16
									xx1# = xx + Rnd(-2,2)
									zz1# = zz + Rnd(-2,2)
									PositionEntity en,xx1,ym(xx1,zz1),zz1
									RotateEntity en,0,Rand(360),0
									sc# = Rnd(0.5,1.5)*0.2
									ScaleEntity en,sc,sc,sc
									If EntityDistance(camera,en)<256 Then 
										CameraProject camera,xx1,ym(xx1,zz1),zz1
											If ProjectedZ()>0 And ProjectedX()>-200 And ProjectedX()<2120 And ProjectedY()>-200 And ProjectedY()<1200 Then
											renderworld3
											doshadow(en)
										EndIf 
									EndIf 
								Next
								.eraserock
								HideEntity en
							Next
						Next
					EndIf
					SeedRnd 38231 ; Abs(zonex)+Abs(zonez)
					If dobushes = 1 Then 
						If grasspivot = 0 Then grasspivot = CreatePivot()
						For i = 1 To 2000 + bushdensity
							xx# = Rnd(-64,64)+zonex
							zz# = Rnd(-64,64)+zonez
							qqq = Rand(2,10)
							PositionEntity grasspivot,xx,EntityY(camera),zz
							If EntityDistance(grasspivot,camera) > 250 Then qqq = qqq / 3
							For j = 1 To qqq
								xx = xx + Rnd(-10,10)
								zz = zz + Rnd(-10,10)
								qq = Rand(0,11)+bushid
								en = mesh(qq)
								if scripterase(cat_bush,xx,zz) then
									rnd(360)
									for j = 1 to 25
										rnd(-2,2)
										rnd(-2,2)
										rand(360)
										rnd(0.5,1.5)
									next
									goto erasebush
								endif 
								ShowEntity en
								PositionEntity en,xx,ym(xx,zz),zz
								RotateEntity en,0,Rnd(360),0
								meshsc(qq)=0.65*0.75
								ScaleEntity en,meshsc(qq),meshsc(qq),meshsc(qq)
								If EntityDistance(camera,en)<512 Then 
									CameraProject camera,xx,ym(xx,zz),zz
									If ProjectedZ()>0 And ProjectedX()>-200 And ProjectedX()<2120 And ProjectedY()>-200 And ProjectedY()<1200 Then
										renderworld3
									EndIf 
								EndIf
								HideEntity en
								en = mesh(grassid)
								ShowEntity en
								For j = 1 To 25
									xx1# = xx + Rnd(-2,2)
									zz1# = zz + Rnd(-2,2)
									PositionEntity en,xx1,ym(xx1,zz1),zz1
									RotateEntity en,0,Rand(360),0
									sc# = Rnd(0.5,1.5)*0.2
									ScaleEntity en,sc,sc,sc
									If EntityDistance(camera,en)<512 Then 
										CameraProject camera,xx1,ym(xx1,zz1),zz1
										If ProjectedZ()>0 And ProjectedX()>-200 And ProjectedX()<2120 And ProjectedY()>-200 And ProjectedY()<1200 Then
											renderworld3
											doshadow(en)
										EndIf 
									EndIf 
								Next
								.erasebush
								HideEntity en
							Next
						Next
						if grasspivot<>0 then freeentity grasspivot:grasspivot = 0
					EndIf 
			.skipzone
			Next ;zonez
			Next ;zonex
			.skipzone2
			SeedRnd 48383
		EndIf ;startframe
		ShowEntity gplane
		ShowEntity cube
		
		;;;;;;;;;;;;;;;; 3d Rendering Took Place Above In BackBuffer ;;;;;;;;;;;;;;;
		;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
		;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	

		;;;;;;;;;;;;;;;; Save Output To Disk, If Required To ;;;;;;;;;;;;;;;;;;;;;;;
		;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
		;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	

		If record<>0 And frame Mod 2 = 0 And frame>=startframe Then
			sframe$ = Str(Int(frame/2))
			While Len(sframe)<6
				sframe = "0" + sframe
			Wend 
			If Instr(sframe,".") Then
				sframe = Left(sframe,Instr(sframe,".") - 1)
			EndIf 
			If frame >= renderfrom Then SaveBuffer BackBuffer(),"..\screenshots\render_"+renderfileprefix$+"_"+sframe+".bmp"
			If frame >= maxframe Then End 
		EndIf 

		;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Output Saved To Disk ;;;;;;;;;;;;;;;;;;;;;;;
		;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
		;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	

		;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Debugging And Status Info;;;;;;;;;;;;;;;;;;;
		;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
		;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
		;;
		If frame < startframe Or frame < renderfrom Then Cls
		If font = 0 Then font = LoadFont("Arial",30)
		If font<>0 Then SetFont font
		;;
		;;
		If frame >= renderfrom Then 
			Text 0,0,"F:"+frame+" FTIME:"+dtime+ " CAMERAMODE:"+cameramode+ " camxyz:"+EntityX(camera)+","+EntityY(camera)+","+EntityZ(camera)
			Text 0,40,CurrentTime()
			Text 0,80,"Press ESCAPE to Stop Rendering"
			If record = 0 Or (record<>0 And frame Mod 2 = 0) Then 
				If skipframe > 0 Then
					If frame = startframe + 1 Then Flip True: Delay 2
				Else
					If frame < startframe Then 
						Flip False
					Else
						Flip True
						Delay 2
					EndIf 
				EndIf
			EndIf
		Else
			If Int(frame) Mod 100 = 0 Then 
				Text 0,0,"F:"+frame+" FTIME:"+dtime+ " CAMERAMODE:"+cameramode+ " camxyz:"+EntityX(camera)+","+EntityY(camera)+","+EntityZ(camera)
				Text 0,40,CurrentTime()
				Flip True 
				Delay 2
			EndIf 
		EndIf
		dtime = Abs(MilliSecs()-ftime)
		ftime = MilliSecs()
		If dtime < 20  And frame >=startframe And frame >= renderfrom And record = 0 Then Delay 20 - dtime
		
	EndIf ;frame mod spedup
	
Until KeyHit(1)
	;savedata()
End

Function loadmeshes()
	id = 0
	ClearTextureFilters
	dir = ReadDir("..\environment\extras\")
	Repeat
		dirfile$ = NextFile(dir)
		If dirfile="" Then Exit
		If Right(dirfile,3) = "tga" Or Right(dirfile,3) = "png" Then 
			bark = 0
			if dirfile = "birch_DF.tga" or dirfile = "bjork_DF.tga" or dirfile = "treebark1.dds" or dirfile = "treebark1.jpg" then bark = 1	
			if bark = 0 then 
				TextureFilter dirfile,1+2
			else
				texturefilter dirfile,1
			endif
		EndIf 
	Forever
	CloseDir dir
	For j = 1 To 4
		mesh(id) = LoadMesh("..\environment\extras\tree0"+j+".b3d")
		HideEntity mesh(id)
		id = id + 1
	Next
	TextureFilter "elmleaves_DF.tga",1+2
	mesh(id) = LoadMesh("..\environment\elm.b3d")
	id = id + 1
	bushid = id
	For i = 1 To 12
		mesh(id) = LoadMesh("..\environment\extras\bush0"+i+".b3d")
		id = id + 1
	Next
	mesh(id) = LoadMesh("..\environment\rivergrass.b3d")
	ScaleMesh mesh(id),0.75,0.75,0.75
	grassid = id
	id = id + 1
	mesh(id) = LoadMesh("..\environment\grasstall.b3d")
	ScaleMesh mesh(id),0.75,0.75,0.75
	id = id + 1
	rockid = id
	mesh(id) = LoadMesh("..\environment\rock01.b3d")
	EntityShininess mesh(id),0
	id = id + 1
	mesh(id) = LoadMesh("..\environment\rock02.b3d")
	EntityShininess mesh(id),0
	id = id + 1
	For i = 0 To id
		If mesh(i)<>0 Then HideEntity mesh(i)
	Next
End Function 

Function shadows(en)
	shade = CreateMesh()
	shadesurf = CreateSurface(shade)
	meshx# = EntityX(en)
	meshy# = EntityY(en)
	meshz# = EntityZ(en)
	yaw# = EntityYaw(en)
	RotateEntity en,0,0,0
	PositionEntity en,0,0,0
	ScaleEntity en,1,1,1
	mm = CopyMesh(en)
	RotateMesh mm,0,yaw,0
	
	aa# = 0.5
	For s = 1 To CountSurfaces(mm)
		surf = GetSurface(mm,s)
		For t = 0 To CountTriangles(surf) - 1
			v0 = TriangleVertex(surf,t,0)
			v1 = TriangleVertex(surf,t,1)
			v2 = TriangleVertex(surf,t,2)
			v0x# = VertexX(surf,v0)
			v0y# = VertexY(surf,v0)
			v0z# = VertexZ(surf,v0)
			TFormPoint v0x,v0y,v0z,en,0
			v00 = AddVertex( shadesurf,TFormedX()-(TFormedY())*aa ,0.0,TFormedZ()-(TFormedY())*aa)
			v1x# = VertexX(surf,v1)
			v1y# = VertexY(surf,v1)
			v1z# = VertexZ(surf,v1)
			TFormPoint v1x,v1y,v1z,en,0
			v11 = AddVertex (shadesurf,TFormedX()-(TFormedY())*aa ,0.0,TFormedZ()-(TFormedY())*aa)
			v2x# = VertexX(surf,v2)
			v2y# = VertexY(surf,v2)
			v2z# = VertexZ(surf,v2)
			TFormPoint v2x,v2y,v2z,en,0
			v22 = AddVertex (shadesurf,TFormedX()-(TFormedY())*aa ,0.0,TFormedZ()-(TFormedY())*aa)
			AddTriangle shadesurf,v00,v11,v22
		Next
	Next
	FreeEntity mm
	ScaleEntity en,0.022,0.022,0.022
	EntityFX shade,1+16
	EntityShininess shade,0
	EntityColor shade,0,0,0
	EntityAlpha shade,1
	PositionEntity en,meshx,meshy,meshz
	RotateEntity en,0,yaw,0

	Return shade
End Function 

Function ym#(xt#,zt#)
	Return TerrainY(map,xt,0,zt)
End Function 

Function doshadow(en)
doshadows = 2
If EntityDistance(en,camera)>145 Then Return 
EntityAlpha en,0.0
If EntityDistance(en,camera)>50 Then 
shade = CreateCylinder(8,1,en)
Else
shade = CopyEntity(en,en)
EndIf
ShowEntity shade
ScaleEntity shade,1,0.001,1
PositionEntity shade,0,0.1,0,False
RotateEntity shade,0,0,0,False
EntityColor shade,0,0,0
EntityAlpha shade,0.25
camx# = EntityX(camera)
camy# = EntityY(camera)
camz# = EntityZ(camera)
If doshadows >= 1 Then 
If doshadows = 1 Or doshadows = 3 Then 
	EntityAlpha shade,0.65
	If doshadows = 3 Then EntityAlpha shade,0.2
	renderworld3
Else
For cx# = -0.25 To 0.25 Step 0.25
	For cz# = -0.25 To 0.25 Step 0.25
		PositionEntity camera,camx+cx,camy,camz+cz,True
		renderworld3	
	Next
Next
EndIf 
EndIf 
PositionEntity camera,camx,camy,camz
FreeEntity shade
EntityAlpha en,1.0

End Function 

Function doanimshadow(en,qanim)
doshadows = 2
EntityAlpha en,0.0
shade = CopyEntity(en,en)
ShowEntity shade
ScaleEntity shade,1,0.001,1
PositionEntity shade,0,0,0,False
RotateEntity shade,0,0,0,False
EntityColor shade,0,0,0
EntityAlpha shade,0.15
camx# = EntityX(camera)
camy# = EntityY(camera)
camz# = EntityZ(camera)
SetAnimTime shade,qanim
If doshadows >= 1 Then 
If doshadows = 1 Then 
	EntityAlpha shade,0.65
	renderworld3
Else
For cx# = -0.25 To 0.25 Step 0.25
	For cz# = -0.25 To 0.25 Step 0.25
		PositionEntity camera,camx+cx,camy,camz+cz,True
		renderworld3	
	Next
Next
EndIf 
EndIf 
PositionEntity camera,camx,camy,camz
FreeEntity shade
EntityAlpha en,1.0

End Function 

Function renderworld3()
If frame < renderfrom Then Return
RenderWorld2
End Function 


Function createbloodexplosion(ent,x#,y#,z#,vx#=0,vy#=0,vz#=0,fiery = 0)

	SeedRnd abs(int(frame)+int(x)+int(y)+int(z))
	If ent = 0 Then 
		freeit = 1
		ent = CreateSphere()
		ScaleMesh ent,2,4,2
		PositionMesh ent,0,10,0
		HideEntity ent
	EndIf 
	sc# = 1.0
	For s = 1 To CountSurfaces(ent)
		surf = GetSurface(ent,s)
		sc = 1.0
		PositionEntity ent,0,0,0
		For v = 0 To CountVertices(surf) - 1 Step 5
			If Rand(0,100)<14 Then 
			TFormPoint VertexX(surf,v),VertexY(surf,v),VertexZ(surf,v),ent,0
			b.bloodexplosion = New bloodexplosion
			b\x = x + TFormedX()*sc*0.15
			b\y = y + TFormedY()*sc*0.15
			b\z = z + TFormedZ()*sc*0.15
			b\vx = Rnd(-3.0,3.0)*bloodv + vx# * 0.25
			b\vy = Rnd(-0.25,3.25)*bloodv 
			b\vz = Rnd(-3.0,3.0)*bloodv + vz# * 0.25
			b\life = 100 - Rand(0,45)
			b\fiery = fiery
			EndIf 
		Next
	Next
	If freeit Then FreeEntity ent
End Function

Function updatebloodexplosion()
delta# = delta1*5.0
	For b.bloodexplosion = Each bloodexplosion
		b\life = b\life - 1
		b\x = b\x + b\vx * delta
		b\y = b\y + b\vy * delta
		b\z = b\z + b\vz * delta
		b\vy = b\vy + blooda
		If b\y < 0 Then 
			b\vy = b\vy * bloode
			b\y = 0.001
			
		EndIf 
		If b\life < 0 Then
			Delete b
			
		EndIf 
	Next
delta# = 1.0
End Function

Function drawbloodexplosion()
	If bloodcube = 0 Then Return 
	ShowEntity bloodcube
	For b.bloodexplosion = Each bloodexplosion
		CameraProject camera,b\x,ym(b\x,b\z)+1.0,b\z
		if projectedz()>0 and projectedx()>-100 and projectedy()>-100 and projectedx()<graphicswidth()+100 and projectedy()<graphicsheight()+100 then 
			PositionEntity bloodcube,b\x,b\y+ym(b\x,b\z),b\z
			RotateEntity bloodcube,Rnd(360),Rnd(360),Rnd(360)
			EntityColor bloodcube,Rand(150,250)/3,Rand(50,100)/3,Rand(70,120)/3
			If b\fiery>0 Then 
				EntityColor bloodcube,Rand(200,255),Rand(200,255),Rand(100,250)
				EntityFX bloodcube,1
				bsc# = 1.0*0.025
			Else
				EntityFX bloodcube,0
				bsc# = 3.5*0.025
			EndIf 
			ScaleEntity bloodcube,Rnd(0.1,0.5)*bsc,Rnd(0.1,0.5)*bsc,Rnd(0.1,0.5)*bsc
			If b\life < 50 Then
				EntityAlpha bloodcube,Float(b\life*2)/100.0
			Else
				EntityAlpha bloodcube,1
			EndIf
			renderworld2
		endif 
	Next
	HideEntity bloodcube
End Function 


Function renderworld2()
	If camshake>0 Then 
		MoveEntity camera,camshakex,camshakey,0
	EndIf 
	RenderWorld
	If camshake>0 Then
		MoveEntity camera,-camshakex,-camshakey,0
	EndIf 
End Function 

Function createbullet(x#,y#,z#,vx#,vy#,vz#,onground=0,life=0,weapontype=0);7aug2024 added weapontype
	weapontype = 0
	b.bullet = New bullet
	b\x = x
	b\y = y
	b\z = z
	If onground<>0 Then b\y = ym(x,z)+y
	b\vx = vx
	b\vy = vy
	b\vz = vz
	b\life = 100
	If life>0 Then b\life = life
End Function 

Function updatebullets()
	For b.bullet = Each bullet
		ox# = b\x 
		oz# = b\z 
		b\x = b\x + b\vx * delta
		b\y = b\y + b\vy * delta
		b\z = b\z + b\vz * delta
		b\life = b\life - 1
		If b\life <0 Then Delete b
	Next
End Function 

Function drawbullets()
	If bullet1 = 0 Then 
		bullet1 = CreateCylinder(8,True)
		ScaleMesh bullet1,0.1,6,0.1
		RotateMesh bullet1,90,0,0
		PositionMesh bullet1,0,0,3
		EntityColor bullet1,250,170,50
		EntityAlpha bullet1,0.65
		EntityBlend bullet1,3
		HideEntity bullet1
		
	EndIf
	If bullet2 = 0 Then
		bullet2 = CreateCylinder(8,True)
		ScaleMesh bullet2,0.12,6.3,0.12
		RotateMesh bullet2,90,0,0
		PositionMesh bullet2,0,0,3.15
		EntityColor bullet2,255,190,100
		EntityAlpha bullet2,0.35
		EntityBlend bullet2,3
		HideEntity bullet2
	EndIf
	ScaleEntity bullet1,0.25,0.25,0.25
	ScaleEntity bullet2,0.25,0.25,0.25
	For b.bullet = Each bullet
		CameraProject camera,b\x,b\y,b\z
		If ProjectedZ()<0 Or ProjectedX()<-100 Or ProjectedX()>GraphicsWidth()+100 Or ProjectedY()<-100 Or ProjectedY()>GraphicsHeight()+100 Then 
		Else
			PositionEntity bullet1,b\x,b\y,b\z
			AlignToVector bullet1,b\vx,b\vy,b\vz,3,1
			PositionEntity bullet2,b\x,b\y,b\z
			AlignToVector bullet2,b\vx,b\vy,b\vz,3,1
			EntityColor bullet2,100,190,255
			EntityColor bullet1,50,170,250
			ShowEntity bullet1
			ShowEntity bullet2
			renderworld2
			HideEntity bullet1
			HideEntity bullet2
		EndIf
	Next
End Function 







Function updateexplosions() ;7aug2024
	for e.explosionstruct = each explosionstruct
		e\x = e\x + e\vx
		e\y = e\y + e\vy
		e\z = e\z + e\vz
		e\frame = e\frame + 1
		If Int(e\frame) > 63 Then 
			delete e
		endif 
	Next
End Function 


Function createexplosion(x#,y#,z#,sc#=1.0,vx#=0,vy#=0,vz#=0)
	if explosiontex(0)=0 then return 
	e.explosionstruct = New explosionstruct
	e\x = x#
	e\y = y#
	e\z = z#
	e\vx = vx
	e\vy = vy
	e\vz = vz
	e\sc = sc
	e\frame = 0
	i = Rand(0,8) + Abs(Handle(e)*123) Mod 8
	i = i Mod 8
	while explosiontex(i)=0 
		i = i + 1
		if i > 8 then i = 0
	wend
	e\index = i
End Function 


Function drawexplosions() ;7aug2024 ;done
	If explosionsprite = 0 Then Return 
	showentity explosionsprite
	for e.explosionstruct = each explosionstruct
		CameraProject camera,e\x,e\y,e\z
		if projectedz()>0 and projectedx()>-100 and projectedy()>-100 and projectedx()<graphicswidth()+100 and projectedy()<graphicsheight()+100 then 
			PositionEntity explosionsprite,e\x,e\y,e\z
			ScaleSprite explosionsprite,e\sc,e\sc
			if e\frame >=0 and int(e\frame) < 64 then 
				EntityTexture explosionsprite,explosiontex(e\index),Int(e\frame)
				renderworld2
			endif 
		endif 
	next
	hideentity explosionsprite
End Function 


;script handling functions
;General Environment File Format Structure
;
;That's basically it....
;Pretty simple
;we 'carve' out regions to remove vegetation from the landscape
;and we 'fill' regions with buildings etc..man-made stuff - the seed determines how they're placed randomly within the region that is specified....
;there's a few more rules that get applied automatically in the code sections itself.
;
;folder structure:
;
;environment\grasses <--- put grass vegetation models and textures in here
;environment\bushes  <--- bush models and textures
;environment\rocks   <--- rock models
;environment\trees   <--- tree models files
;environment\static1 <--- a bunch of buildings or statues etc
;environment\static2 <--- same as above but if you want to have different 'categories' of buildings that get randomly placed in clusters, this is how you do it.
;environment\static3
;environment\static4
;semirandom...as well.
;

const cat_grass=0
const cat_bush=1
const cat_rock=2
const cat_tree=3
const shape_circle=0
const shape_rect=1
global staticid = 0
;

type statics
	field sc#
	field category$
	field modeldir$
	field modeltype$
	field modeltex$ ;for files that you have to specify it, some you do, some you don't
	field ent
	field mw#,md#,mh# ;width,depth,height
	field tex
	field staticindex
end type

type static_fill
	field seed
	field category$
	field shapecategory$
	field x#,z#,w#,h#,r#
end type

type static_instance
	field ent
	field yaw#
	field x#,z#
	field y#
	field size#
end type

Global animid = 0
Global instanceid = 0

type anim
	field sc#
	field category$
	field model$
	field ent
	field animindex
	Field walk
	Field static
end type

type anim_instance
	field ent
	field x#,y#,z#
	field yaw#
	field anim_category$
	field category$
	field startframe#
	field endframe#
	field posx#,posy#,posz#
	field sx#,sy#,sz#,fx#,fy#,fz#
	field spointzx#,spointzy#,spointzz#
	field spointzfraction#
	field spointyx#,spointyy#,spointyz#
	field spointyfraction#
	field fpointzx#,fpointzy#,fpointzz#
	field fpointzfraction#
	field fpointyx#,fpointyy#,fpointyz#
	field fpointyfraction#
	;;;animation parameters
	field sframe#,fframe#,aspeed#,curframe#
	field loop
	Field walk
	Field instanceid
	Field static
end type

Function drawanims()

	For si.anim_instance = Each anim_instance

		If si\category = "NEW" Then 
			ent = 0
			cat$ = si\anim_category
			yaw# = 0
			x# = 0
			y# = 0
			z# = 0
			curframe# = 0
			walk = 0
			static = 0
			For si2.anim_instance = Each anim_instance
				If si2\anim_category = si\anim_category And Handle(si2) = Handle(si) Then
					While si2\category<>"END"
					If frame >= si2\startframe - 0.5 ;And frame < si2\endframe + 0.5 Then
						s.anim_instance = si2.anim_instance
						If s\walk > 0 Then walk = s\walk
						If s\static > 0 Then static = s\static
						iframe = frame
						If iframe > s\endframe Then iframe = s\endframe
						Select si2\category				
						Case "PLACE"
							ent = s\ent
							x = s\x
							y = s\y
							z = s\z
							If walk Then y = ym(x,z)
						
						Case "SETYAW"
							yaw = s\yaw
							ent = s\ent
						Case "MOVETO"
							ent = s\ent
							x# = s\sx + (s\fx - s\sx) * ((iframe - s\startframe) / (s\endframe - s\startframe))
							y# = s\sy + (s\fy - s\sy) * ((iframe - s\startframe) / (s\endframe - s\startframe))
							z# = s\sz + (s\fz - s\sz) * ((iframe - s\startframe) / (s\endframe - s\startframe))
							If walk Then y = ym(x,z)
						Case "TURNYAWTO"
							ent = s\ent
							yaw = s\sy + (s\fy - s\sy) * ((iframe - s\startframe) / (s\endframe - s\startframe))
						Case "ANIM-LOOP"
							ent = s\ent
							curframe = s\curframe
						Case "ANIM-ONCE"
							ent = s\ent
							curframe = s\curframe
						End Select
					EndIf 
						si2 = After si2
					Wend			
					Exit
				EndIf
			Next

			If ent<>0 Then 
				CameraProject camera,x,y,z
				If ProjectedZ()>0 And ProjectedX()>-1920 And ProjectedX()<3840 And ProjectedY()>-1080 And ProjectedY()<2160 Then
					;we're in view
					RotateEntity ent,0,yaw,0
					PositionEntity ent,x,y,z
					
					If static = 1 Then
					Else
						SetAnimTime ent,curframe
					EndIf 
					ShowEntity ent
					renderworld2
					If static = 1 Then 
						doshadow(ent)
					Else
						doanimshadow(ent,curframe)
					EndIf 
					HideEntity ent
				EndIf		
			EndIf
		EndIf
	
	Next
end function 

function animscript()
	for s.anim_instance = each anim_instance
		if s\endframe = s\startframe then
			;it's a 'do once' script
			if frame - 0.5 < s\startframe and frame + 0.5 > s\startframe
				select s\category
				case "PLACE"
					positionentity s\ent,s\posx,s\posy,s\posz
					if s\walk<>0 then
						positionentity s\ent,s\posx,ym(s\posx,s\posz),s\posz
					EndIf
					s\x = EntityX(s\ent)
					s\y = EntityY(s\ent)
					s\z = EntityZ(s\ent)
					;s\endframe = frame + 10000000
					minframe = 999999999
					For s2.anim_instance = Each anim_instance
						If s2\instanceid = s\instanceid Then
							If s2\category = "PLACE" Or s2\category = "MOVETO" Then
								If s2\startframe > s\endframe And s2\startframe < minframe Then
									minframe = s2\startframe - 1
									s\endframe = minframe
								EndIf 
							EndIf
						EndIf 
					Next
					Case "POINT"
					aligntovector s\ent,s\sx,s\sy,s\sz,2,1
					aligntovector s\ent,s\fx,s\fy,s\fz,3,1
				case "SETYAW"
					RotateEntity s\ent,0,s\yaw,0
					minframe = 999999999
					For s2.anim_instance = Each anim_instance
						If s2\instanceid = s\instanceid Then
							If s2\category = "SETYAW" Or s2\category = "TURNYAWTO" Then
								If s2\startframe > s\endframe And s2\startframe < minframe Then
									minframe = s2\startframe - 1
									s\endframe = minframe
								EndIf 
							EndIf
						EndIf 
					Next
				End Select
			endif 
		else
			if frame >= s\startframe and frame < s\endframe then
				select s\category
				case "ALIGNY"
					vx# = s\spointyx + (s\fpointyx - s\spointyx) * ((frame - s\startframe) / (s\endframe - s\startframe))
					vy# = s\spointyy + (s\fpointyy - s\spointyy) * ((frame - s\startframe) / (s\endframe - s\startframe))
					vz# = s\spointyz + (s\fpointyz - s\spointyz) * ((frame - s\startframe) / (s\endframe - s\startframe))
					vf# = s\spointyfraction# + (s\fpointyfraction# - s\spointyfraction#) * ((frame - s\startframe) / (s\endframe - s\startframe))
					aligntovector s\ent,vx,vy,vz,2,vf
				case "ALIGNZ"
					vx# = s\spointzx + (s\fpointzx - s\spointzx) * ((frame - s\startframe) / (s\endframe - s\startframe))
					vy# = s\spointzy + (s\fpointzy - s\spointzy) * ((frame - s\startframe) / (s\endframe - s\startframe))
					vz# = s\spointzz + (s\fpointzz - s\spointzz) * ((frame - s\startframe) / (s\endframe - s\startframe))
					vf# = s\spointzfraction# + (s\fpointzfraction# - s\spointzfraction#) * ((frame - s\startframe) / (s\endframe - s\startframe))
					aligntovector s\ent,vx,vy,vz,2,vf
				case "MOVETO"
					vx# = s\sx + (s\fx - s\sx) * ((frame - s\startframe) / (s\endframe - s\startframe))
					vy# = s\sy + (s\fy - s\sy) * ((frame - s\startframe) / (s\endframe - s\startframe))
					vz# = s\sz + (s\fz - s\sz) * ((frame - s\startframe) / (s\endframe - s\startframe))
					positionentity s\ent,vx,vy,vz
					if s\walk<>0 then
						positionentity s\ent,vx,ym(vx,vz),vz
					endif
					s\x = entityx(s\ent)
					s\y = entityy(s\ent)
					s\z = entityz(s\ent)
					
				case "TURNTO"
					vx# = s\sx + (s\fx - s\sx) * ((frame - s\startframe) / (s\endframe - s\startframe))
					vy# = s\sy + (s\fy - s\sy) * ((frame - s\startframe) / (s\endframe - s\startframe))
					vz# = s\sz + (s\fz - s\sz) * ((frame - s\startframe) / (s\endframe - s\startframe))
					tmppivot = createpivot()
					positionentity tmppivot,vx,vy,vz
					pointentity s\ent,tmppivot
					freeentity tmppivot
					tmppivot = 0
				case "TURNYAWTO"
					vy# = s\sy + (s\fy - s\sy) * ((frame - s\startframe) / (s\endframe - s\startframe))
					rotateentity s\ent,0,vy,0
				case "ANIM-LOOP"
					s\curframe = s\curframe + s\aspeed
					if s\curframe > s\fframe then s\curframe = s\sframe
					If s\curframe < s\sframe Then s\curframe = s\sframe
					
				case "ANIM-ONCE"
					s\curframe = s\curframe + s\aspeed
					if s\curframe > s\fframe then s\curframe = s\fframe
					if s\curframe < s\sframe then s\curframe = s\sframe
				End Select
			endif 
		endif 
	next
end function 

type explosionlist
	field startframe#
	field x#,y#,z#,sc#,vx#,vy#,vz#
	field placeonground
end type

Type bulletlist
	Field startframe#
	Field x#,y#,z#,sc#,vx#,vy#,vz#
	Field placeonground
	Field repeats
End Type

Function bulletscript()
	For e.bulletlist = Each bulletlist
		If frame + e\repeats * 4 > e\startframe - 0.5 And frame < e\startframe + 0.5 Then
			y# = e\y
			If e\repeats > 0 And Int(frame) Mod 4 = 0 Then 
				createbullet(e\x,e\y,e\z,e\vx+e\vx*Rnd(-0.1,0.1),e\vy+e\vy*Rnd(-0.1,0.1),e\vz+e\vz*Rnd(-0.1,0.1),e\placeonground)
			Else
				If e\repeats = 0 Then createbullet(e\x,e\y,e\z,e\vx,e\vy,e\vz,e\placeonground)
			EndIf 
		EndIf 
	Next

End Function

Function explosionscript()
	for e.explosionlist = each explosionlist
		if frame > e\startframe - 0.5 and frame < e\startframe + 0.5 then
			y# = e\y
			if e\placeonground<>0 then 
				y = ym(e\x,e\z)+e\sc
			endif 
			createexplosion(e\x,y,e\z,e\sc,e\vx,e\vy,e\vz)
		endif 
	next
end function 

Function readexplosionfile(file$,clearprevious=0)
	infile = readfile(file)
	if infile<>0 then 
		if clearprevious<>0 then 
			Delete Each explosionlist
		endif
		while(not(eof(infile)))
			txt$ = readline(infile)
			if txt = "BEGIN-BASIC"
				e.explosionlist = new explosionlist
				e\startframe = readline(infile)
				e\x = readline(infile)
				e\y = readline(infile)
				e\z = readline(infile)
				e\sc = readline(infile)
			endif
			if txt = "BEGIN-BASIC-GROUND"
				e.explosionlist = new explosionlist
				e\startframe = readline(infile)
				e\placeonground = 1
				e\x = readline(infile)
				e\y = readline(infile)
				e\z = readline(infile)
				e\sc = readline(infile)
			endif
			if txt = "BEGIN"
				e.explosionlist = new explosionlist
				e\startframe = readline(infile)
				e\x = readline(infile)
				e\y = readline(infile)
				e\z = readline(infile)
				e\sc = readline(infile)
				e\vx = readline(infile)
				e\vy = readline(infile)
				e\vz = readline(infile)
			endif
			if txt = "BEGIN-GROUND"
				e.explosionlist = new explosionlist
				e\startframe = readline(infile)
				e\placeonground = 1
				e\x = readline(infile)
				e\y = readline(infile)
				e\z = readline(infile)
				e\sc = readline(infile)
				e\vx = readline(infile)
				e\vy = readline(infile)
				e\vz = readline(infile)
			endif
		wend 
		closefile infile
	endif 
End Function 

Function readbulletfile(file$,clearprevious=0)
	infile = ReadFile(file)
	If infile<>0 Then 
		If clearprevious<>0 Then 
			Delete Each bulletlist
		EndIf
		While(Not(Eof(infile)))
			txt$ = ReadLine(infile)
			If txt = "BEGIN"
				e.bulletlist = New bulletlist
				e\startframe = ReadLine(infile)
				e\x = ReadLine(infile)
				e\y = ReadLine(infile)
				e\z = ReadLine(infile)
				e\sc = ReadLine(infile)
				e\vx = ReadLine(infile)
				e\vy = ReadLine(infile)
				e\vz = ReadLine(infile)
				e\repeats = ReadLine(infile)
			EndIf
			If txt = "BEGIN-GROUND"
				e.bulletlist = New bulletlist
				e\startframe = ReadLine(infile)
				e\placeonground = 1
				e\x = ReadLine(infile)
				e\y = ReadLine(infile)
				e\z = ReadLine(infile)
				e\sc = ReadLine(infile)
				e\vx = ReadLine(infile)
				e\vy = ReadLine(infile)
				e\vz = ReadLine(infile)
				e\repeats = ReadLine(infile)
			EndIf
		Wend 
		CloseFile infile
	EndIf 
End Function 



Function readanimfile(file$,clearprevious=0)
	instanceid = 0
	infile = readfile(file)
	if infile<>0 then
		if clearprevious<>0 then
			delete each anim_instance
			for a.anim = each anim
				freeentity a\ent
				delete a
			next
		endif
		while(not(eof(infile)))
			txt$ = readline(infile)
			if txt = "BEGIN-DEFINE"
				animid = animid + 1
				a.anim = new anim
				a\category = readline(infile)
				a\sc = readline(infile)
				a\model = readline(infile)
				If ReadLine(infile) = "walk" Then a\walk = 1
				If ReadLine(infile) = "static" Then a\static = 1
				a\animindex = animid
				If a\static = 1 Then
					a\ent = LoadMesh(a\model)
				Else
					a\ent = LoadAnimMesh(a\model)
				EndIf
				If a\ent<>0 Then 
					HideEntity a\ent
					ScaleEntity a\ent,a\sc,a\sc,a\sc
				else
					animid = animid - 1
					delete a
				endif 
			endif
			If txt = "NEW-INSTANCE"
				instanceid = instanceid + 1
				s.anim_instance = New anim_instance
				s\anim_category = ReadLine(infile)
				s\category = "NEW"
				s\instanceid = instanceid
			EndIf
			If txt = "END-INSTANCE"
				s.anim_instance = New anim_instance
				s\anim_category = ReadLine(infile)
				s\instanceid = instanceid
				s\category = "END"
			EndIf
			if txt = "ANIM-LOOP"
				s.anim_instance = new anim_instance
				s\anim_category$ = readline(infile)
				s\category = "ANIM-LOOP"
				s\startframe = readline(infile)
				s\endframe = readline(infile)
				s\sframe = readline(infile)
				s\fframe = readline(infile)
				s\aspeed = ReadLine(infile)
				s\instanceid = instanceid
				s\loop = true
			endif
			if txt = "ANIM-ONCE"
				s.anim_instance = new anim_instance
				s\anim_category$ = readline(infile)
				s\category = "ANIM-ONCE"
				s\startframe = readline(infile)
				s\endframe = readline(infile)
				s\sframe = readline(infile)
				s\fframe = readline(infile)
				s\aspeed = ReadLine(infile)
				s\instanceid = instanceid
				s\loop = false
			endif
			if txt = "BEGIN-PLACE"
				s.anim_instance = new anim_instance
				s\anim_category$ = readline(infile)
				s\category = "PLACE"
				s\instanceid = instanceid
				s\startframe = readline(infile)
				s\endframe = s\startframe
				s\posx = readline(infile)
				s\posy = readline(infile)
				s\posz = readline(infile)
			endif
			if txt = "BEGIN-POINT"
				s.anim_instance = new anim_instance
				s\anim_category$ = readline(infile)
				s\category = "POINT"
				s\instanceid = instanceid
				s\startframe = readline(infile)
				s\endframe = s\startframe
				s\sx = readline(infile) ;y vector
				s\sy = readline(infile)
				s\sz = readline(infile)
				s\fx = readline(infile) ;z vector
				s\fy = readline(infile)
				s\fz = readline(infile)
			endif
			if txt = "BEGIN-SETYAW"
				s.anim_instance = new anim_instance
				s\anim_category$ = readline(infile)
				s\category = "SETYAW"
				s\instanceid = instanceid
				s\startframe = readline(infile)
				s\endframe = s\startframe
				s\yaw = readline(infile)
			endif
			if txt = "BEGIN-TURNYAWTO"
				s.anim_instance = new anim_instance
				s\anim_category$ = readline(infile)
				s\category = "TURNYAWTO"
				s\instanceid = instanceid
				s\startframe = readline(infile)
				s\endframe = readline(infile)
				s\sy = readline(infile)
				s\fy = readline(infile)
			endif
			
			if txt = "BEGIN-MOVETO"
				s.anim_instance = new anim_instance
				s\anim_category$ = readline(infile)
				s\category = "MOVETO"
				s\startframe = readline(infile)
				s\endframe = readline(infile)
				s\sx = ReadLine(infile)
				s\instanceid = instanceid
				s\sy = readline(infile)
				s\sz = readline(infile)
				s\fx = readline(infile)
				s\fy = readline(infile)
				s\fz = readline(infile)

			endif
			if txt = "BEGIN-TURNTO"
				s.anim_instance = new anim_instance
				s\anim_category$ = readline(infile)
				s\instanceid = instanceid
				s\category = "TURNTO"
				s\startframe = readline(infile)
				s\endframe = readline(infile)
				s\sx = readline(infile)
				s\sy = readline(infile)
				s\sz = readline(infile)
				s\fx = readline(infile)
				s\fy = readline(infile)
				s\fz = readline(infile)
			endif
		wend
		closefile infile
		for s.anim_instance = each anim_instance
			for a.anim = each anim
				If a\category = s\anim_category Then s\ent = a\ent:s\walk = a\walk:s\static = a\static
			next
		Next
;		outfile = WriteFile("scripts\dump.txt")
;		For s.anim_instance = Each anim_instance
;			txt$ = ""
;			txt = txt + s\x+","
;			txt = txt + s\y+","
;			txt = txt + s\z+","
;			txt = txt + s\yaw+","
;			txt = txt + s\anim_category+","
;			txt = txt + s\category+","
;			txt = txt + s\startframe+","
;			txt = txt + s\endframe+","
;			txt = txt + s\posx+","
;			txt = txt + s\posy+","
;			txt = txt + s\posz+","
;			txt = txt + s\curframe+","
;			txt = txt + s\sframe+","
;			txt = txt + s\fframe+","
;			txt = txt + s\aspeed+","
;			txt = txt + s\walk
;			WriteLine outfile,txt
;		Next
;		CloseFile outfile
	endif
End Function

type alienplant
	field ent
	field index
end type

type alienplantinstance
	field ent
	field x#,z#,sc#,yaw#
end type

function drawalienplants()
	for a.alienplantinstance = each alienplantinstance
		y# = ym(a\x,a\z)
		cameraproject camera,a\x,y,a\z#
		if projectedz()>0 and projectedx()>-100 and projectedy()>-100 and projectedx()<graphicswidth()+100 and projectedy()<graphicsheight()+100 then
			showentity a\ent
			positionentity a\ent,a\x,y,a\z
			rotateentity a\ent,0,a\yaw,0
			scaleentity a\ent,a\sc,a\sc,a\sc
			renderworld2
			HideEntity a\ent
		endif
	next
end function

Function readalienplantfile(file$,clearprevious=0)
	infile = readfile(file)
	if infile<>0 then
		if clearprevious<>0 then
			delete each alienplant
			delete each alienplantinstance
		endif
		while(not(eof(infile)))
			txt$ = readline(infile)
			if txt = "BEGIN-DEFINE"
				a.alienplant = new alienplant
				index = index + 1
				a\index = index
				filename$ = readline(infile)
				a\ent = loadmesh(filename)
				texname$ = readline(infile)
				tex = loadtexture(texname,1+2)
				if tex<>0 and a\ent<>0 then entitytexture a\ent,tex
				if a\ent = 0 then
					delete a
				else
					sc# = readline(infile)
					scalemesh a\ent,sc,sc,sc
					hideentity a\ent
				endif
			endif
			if txt = "BEGIN-PLACE"
				x# = readline(infile)
				z# = readline(infile)
				yaw# = yaw# + 3
				ap.alienplantinstance = new alienplantinstance
				ap\x = x
				ap\z = z
				ap\yaw = yaw 
				ap\sc = rnd(0.5,2.0)
				if index>0 then 
					ii = rand(1,index)
					for a.alienplant = each alienplant
						if ii = a\index then ap\ent = a\ent
					next
				endif
			endif 
		wend 
		closefile infile
	endif
end function

Function readstaticfile(file$,clearprevious=0)

	infile = readfile(file)
	if infile<>0 then
		if clearprevious<>0 then
			delete each static_fill
			delete each static_instance
			for s.statics = each statics
				if s\ent<>0 then freeentity s\ent
				delete s
			next
		endif
		
		while(not(eof(infile)))
			txt$ = readline(infile)
			If txt = "BEGIN-DEFINE" Then

				sc# = readline(infile)
				category$ = readline(infile)
				modeldir$ = readline(infile)
				modeltype$ = ReadLine(infile)
				modeltex$ = ReadLine(infile)
				dir2 = ReadDir(modeldir)
				tex = 0
				If dir2<>0 Then
					Repeat
						file2$ = nextfile(dir2)
						if file2 = "" then exit
						If Right(file2,3) = modeltype Then
							ent = LoadMesh(modeldir+file2)
							if ent<>0 then
								HideEntity ent
								ScaleMesh ent,sc,sc,sc
								if modeltex = "blank" or modeltex = "none" then
								else
									if modeltex<>"" then
										If Instr(modeltex,".png") Then 
											tex = LoadTexture(modeltex,1+2)
										Else
											tex = LoadTexture(modeltex,1)
										EndIf 
										if tex<>0 then 
											entitytexture ent,tex
										endif 
									endif 
								endif
								mw# = meshwidth(ent)
								mh# = meshheight(ent)
								md# = meshdepth(ent)
								staticid = staticid + 1
								s.statics = new statics
								s\sc# = sc
								s\category$ = category
								s\modeldir$ = modeldir
								s\modeltype$ = modeltype
								s\modeltex = modeltex
								s\ent = ent
								s\mw# = mw
								s\mh# = mh
								s\md# = md
								s\tex = tex
								s\staticindex = staticid

							endif 
						endif
					forever
					closedir dir2
				endif
			endif
			if txt = "BEGIN-PLACE" then
				v.static_fill = new static_fill
				v\seed = readline(infile)
				v\category = readline(infile)
				v\shapecategory = readline(infile)
				v\x = readline(infile)
				v\z = readline(infile)
				v\w = readline(infile)
				v\h = readline(infile)
				v\r = readline(infile)
			endif 
		wend
		closefile infile
	endif
end function 


type veg_erase
	field category ;grass etc
	Field shape ;circular, rectangular
	field x#,z#,w#,h#,r#
end type

type camera_script
	
	field category$
	field startframe#
	field endframe#
	field posx#,posy#,posz#
	field sx#,sy#,sz#,fx#,fy#,fz#
	field spointzx#,spointzy#,spointzz#
	field spointzfraction#
	field spointyx#,spointyy#,spointyz#
	field spointyfraction#
	field fpointzx#,fpointzy#,fpointzz#
	field fpointzfraction#
	field fpointyx#,fpointyy#,fpointyz#
	field fpointyfraction#
	
end type

function camerascript()
	for s.camera_script = each camera_script
		if s\endframe = s\startframe then
			;it's a 'do once' script
			if frame - 0.5 < s\startframe and frame + 0.5 > s\startframe
				select s\category
				case "PLACE"
					positionentity camera,s\posx,s\posy,s\posz
				case "POINT"
					aligntovector camera,s\sx,s\sy,s\sz,2,1
					aligntovector camera,s\fx,s\fy,s\fz,3,1
				end select
			endif 
		else
			if frame >= s\startframe and frame < s\endframe then
				select s\category
				case "ALIGNY"
					vx# = s\spointyx + (s\fpointyx - s\spointyx) * ((frame - s\startframe) / (s\endframe - s\startframe))
					vy# = s\spointyy + (s\fpointyy - s\spointyy) * ((frame - s\startframe) / (s\endframe - s\startframe))
					vz# = s\spointyz + (s\fpointyz - s\spointyz) * ((frame - s\startframe) / (s\endframe - s\startframe))
					vf# = s\spointyfraction# + (s\fpointyfraction# - s\spointyfraction#) * ((frame - s\startframe) / (s\endframe - s\startframe))
					aligntovector camera,vx,vy,vz,2,vf
				case "ALIGNZ"
					vx# = s\spointzx + (s\fpointzx - s\spointzx) * ((frame - s\startframe) / (s\endframe - s\startframe))
					vy# = s\spointzy + (s\fpointzy - s\spointzy) * ((frame - s\startframe) / (s\endframe - s\startframe))
					vz# = s\spointzz + (s\fpointzz - s\spointzz) * ((frame - s\startframe) / (s\endframe - s\startframe))
					vf# = s\spointzfraction# + (s\fpointzfraction# - s\spointzfraction#) * ((frame - s\startframe) / (s\endframe - s\startframe))
					aligntovector camera,vx,vy,vz,2,vf
				case "MOVETO"
					vx# = s\sx + (s\fx - s\sx) * ((frame - s\startframe) / (s\endframe - s\startframe))
					vy# = s\sy + (s\fy - s\sy) * ((frame - s\startframe) / (s\endframe - s\startframe))
					vz# = s\sz + (s\fz - s\sz) * ((frame - s\startframe) / (s\endframe - s\startframe))
					positionentity camera,vx,vy,vz
			    case "ZOOMTO"
					vz# = abs(s\sz + (s\fz - s\sz) * ((frame - s\startframe) / (s\endframe - s\startframe)))
					if vz<>0 then 
						camerazoom camera,vz
					endif 
				case "TURNTO"
					vx# = s\sx + (s\fx - s\sx) * ((frame - s\startframe) / (s\endframe - s\startframe))
					vy# = s\sy + (s\fy - s\sy) * ((frame - s\startframe) / (s\endframe - s\startframe))
					vz# = s\sz + (s\fz - s\sz) * ((frame - s\startframe) / (s\endframe - s\startframe))
					tmppivot = createpivot()
					positionentity tmppivot,vx,vy,vz
					pointentity camera,tmppivot
					freeentity tmppivot
					tmppivot = 0
				end select
			endif 
		endif 
	next
end function 

function readcamerafile(file$,clearprevious=0)
	infile = readfile(file)
	if infile<>0 then
		if clearprevious<>0 then delete each camera_script
		while(not(eof(infile)))
			txt$ = readline(infile)
			if txt = "BEGIN-ALIGNY"
				s.camera_script = new camera_script
				s\category = "ALIGNY"
				s\startframe = readline(infile)
				s\endframe = readline(infile)
				s\spointyx = readline(infile)
				s\spointyy = readline(infile)
				s\spointyz = readline(infile)
				s\spointyfraction# = readline(infile)
				s\fpointyx = readline(infile)
				s\fpointyy = readline(infile)
				s\fpointyz = readline(infile)
				s\fpointyfraction# = readline(infile)
			endif
			if txt = "BEGIN-ALIGNZ"
				s.camera_script = new camera_script
				s\category = "ALIGNZ"
				s\startframe = readline(infile)
				s\endframe = readline(infile)
				s\spointzx = readline(infile)
				s\spointzy = readline(infile)
				s\spointzz = readline(infile)
				s\spointzfraction# = readline(infile)
				s\fpointzx = readline(infile)
				s\fpointzy = readline(infile)
				s\fpointzz = readline(infile)
				s\fpointzfraction# = readline(infile)
			endif
			if txt = "BEGIN-PLACE"
				s.camera_script = new camera_script
				s\category = "PLACE"
				s\startframe = readline(infile)
				s\endframe = s\startframe
				s\posx = readline(infile)
				s\posy = readline(infile)
				s\posz = readline(infile)
			endif
			if txt = "BEGIN-POINT"
				s.camera_script = new camera_script
				s\category = "POINT"
				s\startframe = readline(infile)
				s\endframe = s\startframe
				s\sx = readline(infile) ;y vector
				s\sy = readline(infile)
				s\sz = readline(infile)
				s\fx = readline(infile) ;z vector
				s\fy = readline(infile)
				s\fz = readline(infile)
			endif
			if txt = "BEGIN-MOVETO"
				s.camera_script = new camera_script
				s\category = "MOVETO"
				s\startframe = readline(infile)
				s\endframe = readline(infile)
				s\sx = readline(infile)
				s\sy = readline(infile)
				s\sz = readline(infile)
				s\fx = readline(infile)
				s\fy = readline(infile)
				s\fz = readline(infile)
				
			endif
			if txt = "BEGIN-ZOOMTO"
				s.camera_script = new camera_script
				s\category = "ZOOMTO"
				s\startframe = readline(infile)
				s\endframe = readline(infile)
				s\sz = readline(infile)
				s\fz = readline(infile)
			endif
			if txt = "BEGIN-TURNTO"
				s.camera_script = new camera_script
				s\category = "TURNTO"
				s\startframe = readline(infile)
				s\endframe = readline(infile)
				s\sx = readline(infile)
				s\sy = readline(infile)
				s\sz = readline(infile)
				s\fx = readline(infile)
				s\fy = readline(infile)
				s\fz = readline(infile)
			endif
		wend
		closefile infile
	endif
end function 
	
function readvegfile(file$,clearprevious=0)
	infile = readfile(file)
	if infile<>0 then
		if clearprevious<>0 then delete each veg_erase
		while(not(eof(infile)))
			txt$ = readline(infile)
			if txt = "BEGIN" then 
				v.veg_erase = new veg_erase
				txtcategory$ = readline(infile)
				txtshape$ = readline(infile)
				if txtcategory = "grass" then category = cat_grass
				if txtcategory = "bush" then category = cat_bush
				if txtcategory = "rock" then category = cat_rock
				if txtcategory = "tree" then category = cat_tree
				if category = 0 then category = int(txtcategory)
				v\category = category
				if txtshape = "circle" then shape = shape_circle
				if txtshape = "rect" or txtshape = "rectangle" then shape = shape_rect
				if shape = 0 then shape = int(txtshape)
				v\shape = shape
				v\x = readline(infile)
				v\z = readline(infile)
				v\w = readline(infile)
				v\h = readline(infile)
				v\r = readline(infile)
			endif 
		wend
		closefile infile
	endif
end function 

function loadscripts()
	dir = readdir(currentdir()+"\"+scriptfolder$)
	if dir<>0 then
		repeat	
			file$ = nextfile(dir)
			if file="" then exit
			if lower(left(file,5)) = "erase" and lower(right(file,4)) = ".txt" then
				i = i + 1
				if i = 1 then j = 1 else j = 0
				readvegfile(scriptfolder$+file,j)
			endif
			if lower(left(file,10)) = "explosions" and lower(right(file,4)) = ".txt" then
				k3 = k3 + 1
				if k3 = 1 then m3 = 1 else m3 = 0
				readexplosionfile(scriptfolder$+file,m3)
			EndIf 
			If Lower(Left(file,7)) = "bullets" And Lower(Right(file,4)) = ".txt" Then
				k5 = k5 + 1
				If k5 = 1 Then m5 = 1 Else m5 = 0
				readbulletfile(scriptfolder$+file,m5)
			EndIf 
			

			if lower(left(file,7)) = "statics" and lower(right(file,4)) = ".txt" then
				k = k + 1
				if k = 1 then m = 1 else m = 0
				readstaticfile(scriptfolder$+file,m)
			EndIf 
			
			if lower(left(file,11)) = "alienplants" and lower(right(file,4)) = ".txt" then
				k77 = k77 + 1
				if k77 = 1 then m77 = 1 else m77 = 0
				readalienplantfile(scriptfolder$+file,m77)
			EndIf 
			
			
			if lower(left(file,6)) = "camera" and lower(right(file,4)) = ".txt" then
				u = u + 1
				if u = 1 then pp = 1 else pp = 0
				readcamerafile(scriptfolder$+file,pp)
			endif 
			if lower(left(file,5)) = "anims" and lower(right(file,4)) = ".txt" then
				sk = sk + 1
				if sk = 1 then sm = 1 else sm = 0
				readanimfile(scriptfolder$+file,sm)
			EndIf 
			
		forever
		closedir dir
	endif
end function 

function scripterase(category,x#,z#)
	for v.veg_erase = each veg_erase
		if v\category = category then
			if v\shape = shape_circle then
				dx# = x - v\x
				dz# = z - v\z
				if dx*dx + dz*dz < v\r * v\r then return true
			else
				if x > v\x and x < v\x + v\w and z > v\z and z < v\z + v\h then return true
			endif
		endif 
	next
	return false
end function 

function scriptplace()
	for v.static_fill = each static_fill
		seedrnd v\seed
		index = 0
		count = 0
		for s.statics = each statics
			if s\category = v\category then
				count = count + 1
			endif
		next
		if count > 0 then 
					If v\shapecategory = "circle" Then
							
					endif
					if v\shapecategory = "rect" or v\shapecategory = "rectangle" then
						sx# = v\x
						sz# = v\z
						fx# = v\x + v\w
						fz# = v\z + v\h
						
						While sx < fx 
							sz = v\z
							While sz < fz 
								index = Rand(1,count)
								For s.statics = Each statics
									If s\category = v\category Then index = index - 1
									If index <= 0 Then
										mw# = s\mw
										mh# = s\mh
										md# = s\md
										ent = s\ent
										yaw# = Rand(0,3)*90.0
										size# = mw
										If size < md Then size = md
										donotplace = False
										For si.static_instance = Each static_instance
											If si\x  + si\size > sx - size * 0.5 And si\x - si\size < sx + size * 0.5 Then
												If si\z + si\size> sz - size * 0.5 And si\z - si\size < sz + size * 0.5 Then
													donotplace = True
													Exit
												EndIf 
											EndIf
										Next
										If donotplace = False Then 
											si.static_instance = New static_instance
											si\size = size
											si\x = sx
											si\z = sz
											si\yaw = yaw
											si\ent = ent
										EndIf 
										Exit
									EndIf
								Next
								sz = sz + size * 0.5
							Wend
							
							sx = sx + size * 0.5
						Wend
				EndIf
			EndIf
		Next						
End Function 



function drawstatics()
	for si.static_instance = each static_instance
		if si\ent<>0 then 
			y# = ym(si\x,si\z)
			CameraProject camera,si\x,y,si\z
			if projectedz()>0 and projectedx()>-1920 and projectedx()<3840 and projectedy()>-1080 and projectedy()<2160 then
				;we're in view
				rotateentity si\ent,0,si\yaw,0
				positionentity si\ent,si\x,y,si\z#
				
				ShowEntity si\ent
				renderworld2
				;doshadow(si\ent)
				hideentity si\ent
			endif
		endif 
	next
end function 

function loadexplosions()
	if explosiontex(0) = 0 then 
		i = 0
		dir = readdir("..\fx\")
		if dir<>0 then
			repeat
				file$ = nextfile(dir)
				if file = "" then exit
				if left(file,4) = "etex" and right(file,3) = "png" then 
					explosiontex(i) = LoadAnimTexture("..\fx\"+file,1+2,128,128,0,64) ;I think this is right...
					i = i + 1
				endif 
			forever
			closedir dir
		endif 
	endif
	If explosiontex(0) = 0 Then Return
	If explosionsprite = 0 Then
		explosionsprite = createsprite()
		entityfx explosionsprite,1+8
		hideentity explosionsprite
	endif 

end function 

function configfile(file$)
	infile = readfile(file)
	if infile<>0 then
		while(not(eof(infile)))
			txt$ = readline(infile)
			If txt = "BEGIN-ATMOSPHERE"
				fogr = ReadLine(infile)
				fogg = ReadLine(infile)
				fogb = ReadLine(infile)
				clsr = ReadLine(infile)
				clsg = ReadLine(infile)
				clsb = ReadLine(infile)
				fogmin = ReadLine(infile)
				fogmax = ReadLine(infile)
			EndIf	
			if txt = "BEGIN-VEG"
				treedensity = readline(infile)
				rockdensity = readline(infile)
				bushdensity = readline(infile)
			endif 
			If txt = "BEGIN-MAPSTUFF" Then
				worldtex = ReadLine(infile)
				worldmap = readline(infile)
				cloudtexfile = ReadLine(infile)
			EndIf
			if txt = "BEGIN-CONFIG" then 
				;default file layout
				;BEGIN-CONFIG
				;scripts\
				;myrender
				;0
				;1600
				;10
				;1
				;worldtex
				;worldmap
				;cloudtex
				scriptfolder$ = readline(infile) ;must have trailing slash
				renderfileprefix$ = readline(infile);no special characters
				renderfrom = readline(infile)
				maxframe = readline(infile)
				renderquality = readline(infile)
				record = ReadLine(infile)
		EndIf 
		wend
		closefile infile
	endif
End Function 

Function pleasewait(txt$)
	Local rtxt$[4]
	rtxt
="\"
	rtxt[1]="-"
	rtxt[2]="/"
	rtxt[3]="|"
	If txt = "" Then txt = "Please Wait...."
	If rtxti<0 Then rtxti = 0
	If rtxti>3 Then rtxti = 3
	txt = txt + "..."+rtxt[rtxti Mod 4]
	rtxti = rtxti + 1
	Cls
	Text GraphicsWidth()/2,GraphicsHeight()/2,txt,1,1
	Flip
End Function 

Baggey

#16
Hi @Matty thats an amazing share of code. There is a mistake towards the end :-X

Code: BASIC
rtxt[0]="\"

Is there a way to get the png's. I suppose if i know the recommend scale i could try anything really ::)

Ive always wondered how games like this work. Youve got me downloading Blitz3d. 8)

Kind Regards Baggey
Running a PC that just Aint fast enough!? i7 4Ghz Quad core 32GB ram  2x1TB SSD and NVIDIA Quadro K1200 on 2 x HP Z24's . DID Technology stop! Or have we been assimulated!

Windows10, Parrot OS, Raspberry Pi Black Edition! , ZX Spectrum 48k, C64, Enterprise 128K, The SID chip. Im Misunderstood!

Matty

Re that 'error' - it's not an error, it's just a piece of text displayed during the 'pleasewait loading' screen that has a little ascii character spinning around.

Matty

Productive during the month of August 


3DzForMe

BLitz3D, IDEal, AGK Studio, BMax, Java Code, Cerberus
Recent Hardware: Lenovo Re-furb'd Laptop
Oldest Hardware: Commodore Amiga 1200 with 1084S Monitor & Blitz Basic 2.1