REM Traffic Simulation
REM By qwe
 
REM Ini
sync on
sync rate 45
set display mode 1024, 768, 32
set window on
autocam off
 
REM Set
global maxcars as integer : maxcars = 200
global gridsize as integer : gridsize = 8
global car_speed as float : car_speed = 0.1
set camera range 1.0, 500.0
 
REM Typ
type cars
	x as float
	z as float
	a as float
	v as float
	to_x as float
	to_z as float
	to as integer
	zone as integer
	o as integer
	xlane as integer
	zlane as integer
	mode as integer
	spot as integer
	light_x as integer
	light_z as integer
endtype
 
type zones
	enter_x as float
	enter_y as float
	to as integer
	stop as boolean
endtype
 
type stoplights
	to as integer
	i as integer
	ra as integer
	rb as integer
	rc as integer
	g as integer
	y as integer
	spots_a
	spots_b
	spots_c
	spots_d
 
endtype
 
type clouds
	offx as float
	offz as float
	o as integer
endtype
 
REM Var
global stoplight_green_time as integer : stoplight_green_time = 300
global stoplight_yellow_time as integer : stoplight_yellow_time = 60
global character_height as float : character_height = 1.5
global cam_mode : cam_mode = 1
global obj_sidewalkgrass
global img_road
global mc
global oldmc
global keytab
global oldkeytab
global obj_sun
global low_bound as float : low_bound = 100.0-5.0
global high_bound as float : high_bound = ((gridsize-1)*100.0) + 5.0
global maxclouds as integer : maxclouds = 5
 
REM Arr
DIM s(gridsize, gridsize) as stoplights
DIM c(maxcars) as cars
DIM cloud(maxclouds) as clouds
DIM l(4) as string
 
REM Load
loading(0, "Initializing")
load_sidewalkgrass()
loading(1, "Loading Roads")
place_roads()
loading(2, "Loading Stoplights and Buildings")
place_stoplights()
loading(3, "Loading Cars")
place_cars()
loading(4, "Loading environment")
place_clouds()
 
color backdrop rgb(128, 255, 255)
position camera ((gridsize/2.0) * 100.0)-50.0, character_height, ((gridsize/2.0) * 100.0)-50.0
 
REM Main
do
	set cursor 0,0
	print "FPS: "; screen fps()
	print "Press tab to toggle WALK / ZOOM"
	print "Press enter/+ on numpad to toggle FPS"
	print "WASD moves, Right-Click Looks"
 
	mouse_control()
	run_stoplights()
	run_cars()
	run_clouds()
	if cam_mode = 1 then run_collision()
 
	sync
loop
 
function run_collision()
	local dist2 as float
	local dx as float
	local dz as float
	local cx as float
	local cz as float
	local ox as float
	local oz as float
 
	REM Var
	cx = camera position x()
	cz = camera position z()
 
	REM Box collision with buildings
	for x = 0 to gridsize
		for y = 0 to gridsize
 
			ox = x*100-50
			oz = y*100-50
 
			dx = cx - ox
			dz = cz - oz
 
			dist2 = dx*dx + dz*dz
 
			`do collision if distance is less than 100 units
			if dist2 < 10000 then boxcol(cx, cz, ox, oz, 42, 42)
 
		next y
	next x
 
	REM Box collision with cars
	for i = 0 to maxcars
 
		ox = object position x(c(i).o)
		oz = object position z(c(i).o)
 
		dx = cx - ox
		dz = cz - oz
 
		dist2 = dx*dx + dz*dz
 
		if dist2 < 100 ` if distance to car is less than 10
 
			if c(i).to = 0 or c(i).to = 2
				`facing z directoin
				boxcol(cx, cz, ox, oz, 2.0, 3.0)
			endif
			if c(i).to = 1 or c(i).to = 3
				`facing x direction
				boxcol(cx, cz, ox, oz, 3.0, 2.0)
			endif
 
		endif
 
	next i
 
endfunction
 
function boxcol(cx as float, cz as float, ox as float, oz as float, xr as float, zr as float)			
	if cx > ox - xr
		if cx < ox + xr
			if cz > oz - zr
				if cz < oz + zr
 
					za# = abs(cz - oz+zr)
					zc# = abs(cz - oz-zr)
 
					xb# = abs(cx - ox+xr)
					xd# = abs(cx - ox-xr)
 
					a = get_smallest_of_4_floats(za#, zc#, xb#, xd#)
 
					if a = 0
						position camera camera position x(), camera position y(), oz - zr
					endif
					if a = 1
						position camera camera position x(), camera position y(), oz + zr
					endif
					if a = 2
						position camera ox - xr, camera position y(), camera position z()
					endif
					if a = 3
						position camera ox + xr, camera position y(), camera position z()
					endif
 
				endif
			endif
		endif
	endif
endfunction
 
function get_smallest_of_4_floats(a as float, b as float, c as float, d as float)
 
	if a < b and a < c and a < d then e = 0
	if b < a and b < c and b < d then e = 1
	if c < a and c < b and c < d then e = 2
	if d < a and d < b and d < c then e = 3
 
endfunction e
 
function run_stoplights()
	for a = 0 to gridsize
		for b = 0 to gridsize
 
			dec s(a, b).i
 
			if s(a, b).i = stoplight_yellow_time
				show object s(a, b).y
				hide object s(a, b).g
			endif
 
			if s(a, b).i = 0
				s(a, b).i = stoplight_green_time
				inc s(a, b).to
				if s(a, b).to = 4 then s(a, b).to = 0
				hide object s(a, b).y
				show object s(a, b).g
				set_stoplight_object(a, b)
			endif
 
		next b
	next a
endfunction
 
function place_roads()
	local x as float
	local y as float
 
	REM Load source objects
 
	`texture
	img_road = free_img()
	texture(0, 0, 64, 64, 128, 128, 128)
	get image img_road, 0, 0, 64, 64
 
	` Road to right
	obj_right = free_obj()
	make object plain obj_right, 90, 10
	set object cull obj_right, 1
	hide object obj_right
	texture object obj_right, img_road
	scale object texture obj_right, 9, 1
 
	` Road to bottom
	obj_bottom = free_obj()
	make object plain obj_bottom, 10, 90
	set object cull obj_bottom, 1
	hide object obj_bottom
	texture object obj_bottom, img_road
	scale object texture obj_bottom, 1, 9
 
	` streetlight
	o = free_obj()
	make object box o, 0.4, 10, 0.4
	position object o, 0, 5, 0
	inc o
	make object box o, 0.4, 0.4, 2.0
	position object o, 0, 9.8, 1.2
	inc o
	make object box o, 1.0, 0.4, 1.0
	position object o, 0, 9.8, 2.7
	inc o
	make object box o, 90, 0.05, 0.05
	position object o, 0, 9.8, 1.5
 
	obj_streetlight = free_obj()
	merge_objects(o-3, o, obj_streetlight)
	hide object obj_streetlight
	color object obj_streetlight, rgb(192,192,192)
 
 
 
	REM Load instances
 
	for a = 0 to gridsize-1
		for b = 0 to gridsize-1
 
			x = a * 100
			y = b * 100
 
			` Road to right
			o = free_obj()
			instance object o, obj_right
			position object o, x+50, 0, y
			rotate object o, 90, 0, 0
 
			` Road to bottom
			o = free_obj()
			instance object o, obj_bottom
			position object o, x, 0, y+50
			rotate object o, 90, 0, 0
 
			`Streetlight right
			o = free_obj()
			instance object o, obj_streetlight
			position object o, x+33, 0, y-6.0
 
			`Streetlight right
			o = free_obj()
			instance object o, obj_streetlight
			position object o, x+66, 0, y-6.0
 
			`Streetlight bottom
			o = free_obj()
			instance object o, obj_streetlight
			position object o, x-6.0, 0, y+33
			rotate object o, 0, 90, 0
 
			`Streetlight bottom
			o = free_obj()
			instance object o, obj_streetlight
			position object o, x-6.0, 0, y+66
			rotate object o, 0, 90, 0
 
			if a = gridsize-1
				` Road to bottom bottom
				o = free_obj()
				instance object o, obj_bottom
				position object o, x+100, 0, y+50
				rotate object o, 90, 0, 0
			endif
 
			if b = gridsize-1
				` Road to right right
				o = free_obj()
				instance object o, obj_right
				position object o, x+50, 0, y+100
				rotate object o, 90, 0, 0
			endif
 
		next b
	next a
endfunction
 
function place_stoplights()
	local x as float
	local y as float
 
	REM Load source objects
 
	`intersection road
	obj_intersection_road = free_obj()
	make object plain obj_intersection_road, 10, 10
	set object cull obj_intersection_road, 1
	hide object obj_intersection_road
	texture object obj_intersection_road, img_road
 
	`intersection structure that holds stoplights
	o = free_obj()
	make object box o, 0.4, 10, 0.4
	position object o, -5.2, 5, -5.2
	inc o
	make object box o, 1.5, 2, 1.5
	position object o, -5, 10.2, -5
	inc o
	make object box o, 0.2, 0.2, 6.0
	position object o, 0, 11, 0
	inc o
	make object box o, 0.2, 0.2, 10.0
	position object o, -1.5, 11, -1.5
	obj_structure = free_obj()
	merge_objects(o-3, o, obj_structure)
	rotate limb obj_structure, 3, 0, 135, 0
	rotate limb obj_structure, 4, 0, 45, 0
	color object obj_structure, rgb(192,192,192)
	hide object obj_structure
 
	`stoplight boxes
	obj_stoplight_box = free_obj()
	make object box obj_stoplight_box, 0.4, 1.5, 0.4
	hide object obj_stoplight_box
	color object obj_stoplight_box, rgb(255,255,0)
	obj_stoplight_red = free_obj()
	make object sphere obj_stoplight_red, 0.35, 4, 4
	hide object obj_stoplight_red
	color object obj_stoplight_red, rgb(128,0,0)
	obj_stoplight_yellow = free_obj()
	make object sphere obj_stoplight_yellow, 0.35, 4, 4
	hide object obj_stoplight_yellow
	color object obj_stoplight_yellow, rgb(128,128,0)
	obj_stoplight_green = free_obj()
	make object sphere obj_stoplight_green, 0.35, 4, 4
	hide object obj_stoplight_green
	color object obj_stoplight_green, rgb(0,128,0)
	obj_red = free_obj()
	make object sphere obj_red, 0.45, 4, 4
	hide object obj_red
	color object obj_red, rgb(255,0,0)
	set object emissive obj_red, rgb(255,0,0)
	ghost object on obj_red
	obj_yellow = free_obj()
	make object sphere obj_yellow, 0.45, 4, 4
	hide object obj_yellow
	color object obj_yellow, rgb(255,255,0)
	set object emissive obj_yellow, rgb(255,255,0)
	ghost object on obj_yellow
	obj_green = free_obj()
	make object sphere obj_green, 0.45, 4, 4
	hide object obj_green
	color object obj_green, rgb(0,255,0)
	set object emissive obj_green, rgb(0,255,0)
	ghost object on obj_green
 
 
	REM Load instances
 
	for a = 0 to gridsize
		for b = 0 to gridsize
 
			x = a * 100
			y = b * 100
 
			REM Intersection ground/road object
			o = free_obj()
			instance object o, obj_intersection_road
			position object o, x, 0, y
			rotate object o, 90, 0, 0
 
			REM Building
			if a = gridsize/2 and b = gridsize/2
			else
				place_random_building(x-50, y-50)
			endif
 
			REM sidewalk and grass model
			o = free_obj()
			instance object o, obj_sidewalkgrass
			position object o, x-50, 0, y-50
			rotate object o, 90, 0, 0
 
			REM Stoplight system (var)
			s(a, b).to = rnd(3)
			s(a, b).i = rnd(stoplight_green_time) + 1
 
			REM Stoplight structure model
			o = free_obj()
			instance object o, obj_structure
			position object o, a*100, 0, b*100
 
			REM Stoplights (model)
			o = free_obj()
			instance object o, obj_stoplight_box
			position object o, a*100+2, 10, b*100+2
			inc o
			instance object o, obj_stoplight_box
			position object o, a*100+2, 10, b*100-2
			inc o
			instance object o, obj_stoplight_box
			position object o, a*100-2, 10, b*100+2
			inc o
			instance object o, obj_stoplight_box
			position object o, a*100-2, 10, b*100-2
			inc o
			instance object o, obj_stoplight_red
			position object o, a*100+2.2, 10.375, b*100+2
			inc o
			instance object o, obj_stoplight_red
			position object o, a*100+2, 10.375, b*100-2.2
			inc o
			instance object o, obj_stoplight_red
			position object o, a*100-2, 10.375, b*100+2.2
			inc o
			instance object o, obj_stoplight_red
			position object o, a*100-2.2, 10.375, b*100-2
			inc o
			instance object o, obj_stoplight_yellow
			position object o, a*100+2.2, 10, b*100+2
			inc o
			instance object o, obj_stoplight_yellow
			position object o, a*100+2, 10, b*100-2.2
			inc o
			instance object o, obj_stoplight_yellow
			position object o, a*100-2, 10, b*100+2.2
			inc o
			instance object o, obj_stoplight_yellow
			position object o, a*100-2.2, 10, b*100-2
			inc o
			instance object o, obj_stoplight_green
			position object o, a*100+2.2, 9.625, b*100+2
			inc o
			instance object o, obj_stoplight_green
			position object o, a*100+2, 9.625, b*100-2.2
			inc o
			instance object o, obj_stoplight_green
			position object o, a*100-2, 9.625, b*100+2.2
			inc o
			instance object o, obj_stoplight_green
			position object o, a*100-2.2, 9.625, b*100-2
 
			REM Load brightened circles (reds)
			s(a, b).ra = free_obj()
			instance object s(a, b).ra, obj_red
			s(a, b).rb = free_obj()
			instance object s(a, b).rb, obj_red
			s(a, b).rc = free_obj()
			instance object s(a, b).rc, obj_red
 
			REM Load brightened circles (green and yellow)
			s(a, b).g = free_obj()
			instance object s(a, b).g, obj_green
			s(a, b).y = free_obj()
			instance object s(a, b).y, obj_yellow
 
			REM Set lightened circles to correspond with which direction stoplight is allowing cars to pass
			set_stoplight_object(a, b)
 
		next b
	next a
endfunction
 
function set_stoplight_object(a, b)
	REM Replace object with correct direction object
	if s(a, b).to = 0 `pos z
		position object s(a, b).g, a*100+2, 9.625, b*100-2.2
		position object s(a, b).y, a*100+2, 10, b*100-2.2
		position object s(a, b).ra, a*100-2.2, 10.375, b*100-2
		position object s(a, b).rb, a*100-2, 10.375, b*100+2.2
		position object s(a, b).rc, a*100+2.2, 10.375, b*100+2
	endif
	if s(a, b).to = 1 `neg x
		position object s(a, b).g, a*100-2.2, 9.625, b*100-2
		position object s(a, b).y, a*100-2.2, 10, b*100-2
		position object s(a, b).ra, a*100+2, 10.375, b*100-2.2
		position object s(a, b).rb, a*100-2, 10.375, b*100+2.2
		position object s(a, b).rc, a*100+2.2, 10.375, b*100+2
	endif
	if s(a, b).to = 2 `neg z
		position object s(a, b).g, a*100-2, 9.625, b*100+2.2
		position object s(a, b).y, a*100-2, 10, b*100+2.2
		position object s(a, b).ra, a*100-2.2, 10.375, b*100-2
		position object s(a, b).rb, a*100+2, 10.375, b*100-2.2
		position object s(a, b).rc, a*100+2.2, 10.375, b*100+2
	endif
	if s(a, b).to = 3 `pos x
		position object s(a, b).g, a*100+2.2, 9.625, b*100+2
		position object s(a, b).y, a*100+2.2, 10, b*100+2
		position object s(a, b).ra, a*100-2.2, 10.375, b*100-2
		position object s(a, b).rb, a*100-2, 10.375, b*100+2.2
		position object s(a, b).rc, a*100+2, 10.375, b*100-2.2
	endif
endfunction
 
function load_sidewalkgrass()
	`texture
	texture(0, 0, 512, 512, 0, 192, 0)
	texture(4, 0, 20, 512, 192, 192, 192)
	texture(0, 4, 512, 20, 192, 192, 192)
	texture(512-20, 0, 512-4, 512, 192, 192, 192)
	texture(0, 512-20, 512, 512-4, 192, 192, 192)
	img_sidewalkgrass = free_img()
	get image img_sidewalkgrass, 0, 0, 512, 512
	`model
	obj_sidewalkgrass = free_obj()
	make object plain obj_sidewalkgrass, 90, 90
	set object cull obj_sidewalkgrass, 0
	hide object obj_sidewalkgrass
	texture object obj_sidewalkgrass, img_sidewalkgrass
endfunction
 
function place_random_building(pos_x as float, pos_z as float)
	local height as float
 
		`building var
		height = (rnd(15)+1) * 10.0
		`building texture
		r=rnd(255)
		g=rnd(255)
		b=rnd(255)
		if r > 128
			r = r - abs(r - 128)/2
		else
			r = r + abs(r - 128)/2
		endif
		if g > 128
			g = g - abs(g - 128)/2
		else
			g = g + abs(g - 128)/2
		endif
		if b > 128
			b = b - abs(b - 128)/2
		else
			b = b + abs(b - 128)/2
		endif
		lock pixels
		ink rgb(r, g, b), 0
		box 0, 0, 256, 512
		for x = 1 to 16
			for y = 1 to 32
				if rnd(1) = 1
					ink rgb(255,255,0),0
				else
					ink rgb(0,0,0),0
				endif
				box x*16, y*16, x*16+8, y*16+8
			next y
		next x
		i = free_img()
		unlock pixels
		get image i, 0, 0, 256, height*3.2
		`building model
		o = free_obj()
		make object box o, 80, height, 80
		offset limb o, 0, 0, height/2, 0
		texture object o, i
		position object o, pos_x, 0, pos_z
		`ceiling
		inc o
		make object box o, 80, 1, 80
		color object o, rgb(r,g,b)
		position object o, pos_x, height+0.5, pos_z
 
endfunction
 
function mouse_control()
	local mmy as float
	local mmx as float
	local spd as float
 
	REM Var
	spd = 0.1
	oldmc = mc
	mc = mouseclick()
	mmy = mousemovey() / 5.0
	mmx = mousemovex() / 5.0
	oldkeytab = keytab
	keytab = keystate(15)
 
	REM Toggle camera mode
	if keytab = 1 and oldkeytab = 0
		if cam_mode = 0
			cam_mode = 1
		else
			cam_mode = 0
		endif
	endif
 
	REM Toggle FPS
	if keystate(78) then sync rate 0
	if keystate(156) then sync rate 45
 
	REM Look
	if mc = 2 and oldmc = 2
		`hide moues while looking around
		hide mouse
		position mouse 512, 384
		`turn camera
		xrotate camera wrapvalue(camera angle x() + mmy)
		yrotate camera wrapvalue(camera angle y() + mmx)
		`bound camera angle
		if camera angle x()>89 and camera angle x()<180 then xrotate camera 89
		if camera angle x()<271 and camera angle x()>180 then xrotate camera 271
	else
		show mouse
	endif
 
	if cam_mode = 1
		REM Move (walk)
		if keystate(42)
			spd = spd * 4
		endif
		if keystate(17)
			position camera newxvalue(camera position x(), camera angle y(), spd), character_height, newzvalue(camera position z(), camera angle y(), spd)
		endif
		if keystate(31)
			position camera newxvalue(camera position x(), camera angle y()-180.0, spd), character_height, newzvalue(camera position z(), camera angle y()-180.0, spd)
		endif          
		if keystate(30)
			position camera newxvalue(camera position x(), camera angle y()-90.0, spd), character_height, newzvalue(camera position z(), camera angle y()-90.0, spd)
		endif
		if keystate(32)
			position camera newxvalue(camera position x(), camera angle y()+90.0, spd), character_height, newzvalue(camera position z(), camera angle y()+90.0, spd)
		endif
	else
		REM Move (zoom)
		spd = spd * 5.0
		if keystate(42)
			spd = spd * 10
		endif
		if keystate(17)
			move camera spd
		endif
		if keystate(31)
			move camera -spd
		endif          
		if keystate(30)
			position camera newxvalue(camera position x(), camera angle y()-90.0, spd), camera position y(), newzvalue(camera position z(), camera angle y()-90.0, spd)
		endif
		if keystate(32)
			position camera newxvalue(camera position x(), camera angle y()+90.0, spd), camera position y(), newzvalue(camera position z(), camera angle y()+90.0, spd)
		endif          
		if keystate(16)
			position camera camera position x(), camera position y() - spd, camera position z()
		endif
		if keystate(18)
			position camera camera position x(), camera position y() + spd, camera position z()
		endif
		if camera position y() < 1.0 then position camera camera position x(), 1.0, camera position z()
	endif
 
endfunction
 
function place_clouds()
 
	for i = 0 to maxclouds
		REM Make cloud object
		o = 1000
		make object sphere o, 100, 6, 6
		inc o
		make object sphere o, 100, 6, 6
		inc o
		make object sphere o, 100, 6, 6
		inc o
		make object sphere o, 100, 6, 6
		inc o
		make object sphere o, 100, 6, 6
		inc o
		make object sphere o, 100, 6, 6
 
		for j = o-5 to o
			position object j, rnd(100), rnd(50), rnd(100)
		next j
 
		obj = free_obj()
		merge_objects(o-5, o, obj)
 
		set object emissive obj, rgb(255, 255, 255)
		cloud(i).o = obj
		cloud(i).offx = rnd(600)-300
		cloud(i).offz = rnd(600)-300
 
		inc o
	next i
 
	obj_sun = free_obj()
	make object sphere obj_sun, 25, 12, 12
	set object emissive obj_sun, rgb(255,255,64)
endfunction
 
function run_clouds()
	for i = 0 to maxclouds
 
		position object cloud(i).o, camera position x() + cloud(i).offx, 200, camera position z() + cloud(i).offz
		inc cloud(i).offx, 0.1
		if cloud(i).offx > 300 then cloud(i).offx = -300.0
 
		position object obj_sun, camera position x(), 400, camera position z()
 
	next i
endfunction
 
function free_obj()
	repeat
		inc i
		if object exist(i)=0 then found=1
	until found
endfunction i
 
function free_img()
	repeat
		inc i
		if image exist(i)=0 then found=1
	until found
endfunction i
 
function merge_objects(SObj,EObj,TOBj)
	Limb=1
 
	make object cube TObj,0.1
 
	for m = SOBj to EObj
		make mesh from object m,m
		add limb TObj,Limb,m
		offset Limb TObj,Limb,Object Position x(m),Object Position y(m),Object Position z(m)
		rotate limb TObj,Limb,Object angle x(m),Object angle y(m),Object angle z(m)
		inc Limb
		delete object m
		delete mesh m
	next m
 
	hide limb TObj, 0
endfunction
 
function texture(xa, ya, xb, yb, r, g, b)
	lock pixels
 
	ink rgb(r, g, b), 0
	box xa, ya, xb, yb
 
 
	ink rgb(tinc(r), tinc(g), tinc(b)), 0
	for x = xa to xb
		for y = ya to yb
			if rnd(3)
				box x, y, x+1, y+1
			endif
		next y
	next x
	ink rgb(tdec(r), tdec(g), tdec(b)), 0
	for x = xa to xb
		for y = ya to yb
			if rnd(3)
				box x, y, x+1, y+1
			endif
		next y
	next x
 
	unlock pixels
endfunction           
 
function tinc(a)
	inc a, 8
	if a > 255 then a = 255
endfunction a
 
function tdec(a)
	dec a, 8
	if a < 0 then a = 0
endfunction a
 
function loading(i as integer, msg as string)
	l(i) = msg
	cls
	ink rgb(255, 255, 0), 0
	for i = 0 to 4
		print l(i)
	next i
	sync
endfunction
 
function place_cars()
	local rndxpos as float
	local rndzpos as float
 
	for i = 0 to maxcars
		REM Make car object
		o = create_car()
		c(i).o = o
 
		REM Get random direction and position
		rndpos = rnd(gridsize * 100)
		rndlane = rnd(gridsize)
 
		face = rnd(3)
		if face = 0`posz
			yrotate object o, 0
			rndxpos = rndlane*100+2.5
			rndzpos = rndpos
			c(i).xlane = rndlane
		endif
		if face = 1`negx
			yrotate object o, 90
			rndxpos = rndpos
			rndzpos = rndlane*100+2.5
			c(i).zlane = rndlane
		endif
		if face = 2`negz
			yrotate object o, 180
			rndxpos = rndlane*100-2.5
			rndzpos = rndpos
			c(i).xlane = rndlane
		endif
		if face = 3`posx
			yrotate object o, 270
			rndxpos = rndpos
			rndzpos = rndlane*100-2.5
			c(i).zlane = rndlane
		endif
 
		position object o, rndxpos, 0.00, rndzpos
		c(i).x = object position x(o)
		c(i).z = object position z(o)
		c(i).a = object angle y(o)
		c(i).to = face
	next i
endfunction
 
function run_cars()
 
	for i = 0 to maxcars
 
		if c(i).mode = 0
			if c(i).to = 0	`if going up
 
				`check to see if near stoplight, if so then goto wait for stoplight mode
				for z = 0 to gridsize
 
					if c(i).z < z*100 - 5 and c(i).z > z*100 - 40
 
						c(i).mode = 1
						c(i).light_x = c(i).xlane
						c(i).light_z = z
						c(i).spot = get_spot_in_line(c(i).light_x, c(i).light_z, c(i).to)
						c(i).to_x = c(i).x
						c(i).to_z = z*100 -  7.5 - c(i).spot * 5
						c(i).v = car_speed
 
					endif
 
				next z
 
				`move along
				inc c(i).z, car_speed
 
			endif
			if c(i).to = 1	`if going left
 
				`check to see if near stoplight, if so then goto wait for stoplight mode
				for x = 0 to gridsize
 
					if c(i).x > x*100 + 5 and c(i).x < x*100 + 40
 
						c(i).mode = 1
						c(i).light_x = x
						c(i).light_z = c(i).zlane
						c(i).spot = get_spot_in_line(c(i).light_x, c(i).light_z, c(i).to)
						c(i).to_x = x*100 +  7.5 + c(i).spot * 5
						c(i).to_z = c(i).z
						c(i).v = car_speed
 
					endif
 
				next z
 
				`move along
				dec c(i).x, car_speed
 
			endif
			if c(i).to = 2	`if going down
 
				`check to see if near stoplight, if so then goto wait for stoplight mode
				for z = 0 to gridsize
 
					if c(i).z < z*100 + 40 and c(i).z > z*100 + 5
 
						c(i).mode = 1
						c(i).light_x = c(i).xlane
						c(i).light_z = z
						c(i).spot = get_spot_in_line(c(i).light_x, c(i).light_z, c(i).to)
						c(i).to_x = c(i).x
						c(i).to_z = z*100 +  7.5 + c(i).spot * 5
						c(i).v = car_speed
 
					endif
 
				next z
 
				`move along
				dec c(i).z, car_speed
 
			endif
			if c(i).to = 3	`if going right
 
				`check to see if near stoplight, if so then goto wait for stoplight mode
				for x = 0 to gridsize
 
					if c(i).x > x*100 - 40 and c(i).x < x*100 - 5
 
						c(i).mode = 1
						c(i).light_x = x
						c(i).light_z = c(i).zlane
						c(i).spot = get_spot_in_line(c(i).light_x, c(i).light_z, c(i).to)
						c(i).to_x = x*100 - 7.5 - c(i).spot * 5
						c(i).to_z = c(i).z
						c(i).v = car_speed
 
					endif
 
				next z
 
				`move along
				inc c(i).x, car_speed
 
			endif
		endif
 
		if c(i).mode = 1
			green = is_stoplight_green(c(i).light_x, c(i).light_z, c(i).to)
 
			if green = 1
				REM If stoplight is GREEN then accelerate and see when enters intersection
 
				inc c(i).v, 0.001
				if c(i).v > car_speed then c(i).v = car_speed
 
				if c(i).to = 0
					inc c(i).z, car_speed
				endif
				if c(i).to = 1
					dec c(i).x, car_speed
				endif
				if c(i).to = 2
					dec c(i).z, car_speed
				endif
				if c(i).to = 3
					inc c(i).x, car_speed
				endif
 
 
				if c(i).x < c(i).light_x*100+4
					if c(i).x > c(i).light_x*100-4
						if c(i).z < c(i).light_z*100+4
							if c(i).z > c(i).light_z*100-4
								REM if car is in intersection
 
								`subtract from slots in line
								erase_slot_in_line(c(i).light_x, c(i).light_z, c(i).to)
								`get new random direction
								c(i).to = get_direction(c(i).light_x, c(i).light_z, c(i).to)
								`set speed
								c(i).v = car_speed
								`new mode: car is now turning towards new lane
								c(i).mode = 2
 
							endif
						endif
					endif
				endif
 
			else
				REM If stoplight is red then stop at place in line
 
				dec c(i).v, 0.0001
				if c(i).v < 0.0 then c(i).v = 0.0
				if c(i).x < c(i).to_x then inc c(i).x, c(i).v
				if c(i).x > c(i).to_x then dec c(i).x, c(i).v
				if c(i).z < c(i).to_z then inc c(i).z, c(i).v
				if c(i).z > c(i).to_z then dec c(i).z, c(i).v
 
			endif
 
		endif
 
		if c(i).mode = 2
 
			x# = c(i).light_x*100
			z# = c(i).light_z*100
 
			if c(i).to = 0
				tox# = x#+2.5
				toz# = z#+5
			endif
			if c(i).to = 1
				tox# = x#-5
				toz# = z#+2.5
			endif
			if c(i).to = 2
				tox# = x#-2.5
				toz# = z#-5
			endif
			if c(i).to = 3
				tox# = x#+5
				toz# = z#-2.5
			endif
 
			point object c(i).o, tox#, 0.00, toz#
			c(i).a = object angle y(c(i).o)
			move object c(i).o, c(i).v
			c(i).x = object position x(c(i).o)
			c(i).z = object position z(c(i).o)
 
			if c(i).x < c(i).light_x*100+5 and c(i).x > c(i).light_x*100-5 and c(i).z < c(i).light_z*100+5 and c(i).z > c(i).light_z*100-5
			else
				REM if car is out of intersection
				`rotate car correctly
				if c(i).to = 0
					c(i).a = 0
				endif
				if c(i).to = 1
					c(i).a = 90
				endif
				if c(i).to = 2
					c(i).a = 180
				endif
				if c(i).to = 3
					c(i).a = 270
				endif
				`set variables
				c(i).mode = 0
				c(i).xlane = c(i).light_x
				c(i).zlane = c(i).light_z
				`place correctly
				c(i).x = tox#
				c(i).z = toz#
			endif
 
		endif
 
 
 
		position object c(i).o, c(i).x, 0.00, c(i).z
		rotate object c(i).o, 0, c(i).a, 0
 
	next i
endfunction
 
function get_direction(x, z, orig)
	repeat
 
		face = rnd(3)
		found = 1
 
		if x = 0
			if face = 1 then found = 0
		endif
		if x = gridsize
			if face = 3 then found = 0
		endif
		if z = 0
			if face = 2 then found = 0
		endif
		if z = gridsize
			if face = 0 then found = 0
		endif
 
		if face = orig+2 then found = 0
		if face = orig-2 then found = 0
 
	until found = 1
endfunction face
 
function get_spot_in_line(x, z, face)
	if face = 0
		inc s(x, z).spots_a
		ret = s(x, z).spots_a
	endif
	if face = 1
		inc s(x, z).spots_b
		ret = s(x, z).spots_b
	endif
	if face = 2
		inc s(x, z).spots_c
		ret = s(x, z).spots_c
	endif
	if face = 3
		inc s(x, z).spots_d
		ret = s(x, z).spots_d
	endif
endfunction ret
 
function erase_slot_in_line(x, z, face)
	if face = 0
		dec s(x, z).spots_a
	endif
	if face = 1
		dec s(x, z).spots_b
	endif
	if face = 2
		dec s(x, z).spots_c
	endif
	if face = 3
		dec s(x, z).spots_d
	endif
endfunction
 
function is_stoplight_green(x, z, face)
	if face = 0
		if s(x, z).to = 0 then ret = 1
	endif
	if face = 1
		if s(x, z).to = 3 then ret = 1
	endif
	if face = 2
		if s(x, z).to = 2 then ret = 1
	endif
	if face = 3
		if s(x, z).to = 1 then ret = 1
	endif
endfunction ret
 
function create_car()
 
	o = 1000
	make object box o, 1.5, 1, 3
	position object o, 0, 0.5, 0
	inc o
	make object cylinder o, 0.5
	position object o, 0.75, 0.25, 1
	rotate object o, 90, 0, 90
	inc o
	make object cylinder o, 0.5
	position object o, -0.75, 0.25, 1
	rotate object o, 90, 0, 90
	inc o
	make object cylinder o, 0.5
	position object o, 0.75, 0.25, -1
	rotate object o, 90, 0, 90
	inc o
	make object cylinder o, 0.5
	position object o, -0.75, 0.25, -1
	rotate object o, 90, 0, 90
	inc o
	make object box o, 1.5, 0.66, 1
	position object o, 0, 1.333, 0
 
	ret_obj = free_obj()
	merge_objects(o-5, o, ret_obj)
 
	color object ret_obj, rgb(rnd(255), rnd(255), rnd(255))
 
endfunction ret_obj