'
'	GAME > LEVELS > LAYERS > LEGO
'

' size of a world chunk (= max area)
?zone = 16

' maximum size of a lego brick 3x3
?max = 3

' city sub divisions
?sub = 5

' style
?render_color = 41
?render_roof = 31
?chunk_ground_color = #332


'

goto "scene init"

'goto "new game"

goto "intro init"

goto "main"

'


label "intro init"
	
	select screen "front"
	mix screen "screen"
	fill screen #0005
	
	color 1
	font size 10
	trace text "A R C H I T E C T" center 0, 10
	
	font size 5
	color 3
	trace text "Press SPACE to start" center 0, 0
	
	font size 2
	color 1
	trace text "2026 by Dozzen" center 0, 90
	
	'
	'goto "level_start"
	?level = 3
	goto "level_next"
	
	'delete "lego"
	'hide "lego"
	
	?play = 0
	?intro_mode = 1
	?intro_anim = 60
	
return

'

label "intro anim"
	
	' Title effect
	color #fff0
	?x = random -7 to 6
	?y = random -5 to 4
	?d = (abs ?x) + (abs ?y)
	if (random 1 to 12) > ?d
		trace frame ?x * 10, ?y * 10 to (?x + 1) * 10, (?y + 1) * 10
		trace fill #0482
	end
	
	' Auto build / demo
	?intro_anim - 1
	if ?intro_anim = 0
		
		for 1 to 12
			?x1 = random ?base_start to ?base_end
			?z = random ?base_start to ?base_end
			?x2 = ?x1 + (random 1 to ?base)
			limit ?x2 max ?base_end
			
			for ?x1 to ?x2 as ?x
				if (cell "helper" to ?x, 1, ?z) <> 0
					add "layer" dot ?x, 1, ?z
					?intro_anim = 60
				end
			next
		next
		
		goto "layer end"
	end
	
	
	if (press "space") = 1
		
		?intro_mode = 0
		?play = 1
		goto "new game"
		goto "level_start"
	end
	
return




'

label "new game"
	
	clear screen
	
	?score = 0
	?old_score = 0
	?level = 1
	?tutorial = 1
	
	goto "level_start"
	
return

'

label "main"
	' main loop
	do
		
		goto "score anim"
		
		if ?play = 0
			goto "final camera anim"
			
			if ?intro_mode = 1
				goto "intro anim"
			else if (press once "space") = 1
				goto "level_next"
			end
			
		else
			
			' move first (!)
			goto "player move"
			goto "lego_drop"
			
			?cx = ?zone / 2
			?cy = (?zone + ?layer) * 1.25
			?cz = (?zone - ?layer) / 2
			?cz = 0' -?zone / 4
			
			if ?flag_locked > 0
				?flag_locked - 1
				
				if ?flag_locked <= 0
					if ?flag_start = 0
						goto "layer end"
					else
						goto "level end"
					end
				end
			end
			
		end
		
		' smooth camera
		?cam_x + (?cx - ?cam_x) / 20
		?cam_y + (?cy - ?cam_y) / 60
		?cam_z + (?cz - ?cam_z) / 20
		
		move "camera" to ?cam_x, ?cam_y, ?cam_z
		target "camera" to ?zone / 2, 1, ?zone / 2
		
		update
		
	loop
return

'

label "scene init"
	
	' setup scene ONCE
	fov 50
	background 3
	pen 0
	show fog #08f to 200
	
	delete "light"' default
	
	create orb as "sun"
	color "sun" to #8cf
	move "sun" to ?zone * 2, ?zone / 2, ?zone
	
	power "glow" to 50
	
	create shadow as "shadow"
	'?sx = ?zone
	move "shadow" to ?zone, ?zone, ?zone
	target "shadow" to ?zone * 1.2, ?zone / 4, ?zone / 2
	power "shadow" to 50
	color "shadow" to #fed
	shadow "shadow" to ?zone * 1.5
return

'

label "score anim"
	
	if (mod (frame), 3) = 1
		if ?score_display <> ?score
			?score_display + 1
		end
		
		if ?score >= ?score_old
			color 1
		else
			color #fb4
		end
		
		create text ?score_display as "score"
		center "score" to 1, 1, 1
		'paint "score" to "neon"
		turn x "score" to -90
		zoom "score" to .2, .2, 0
		move "score" to 1, 1, 14
	end
return

'

label "level_start"
	
	color 1
	font size 3
	
	?base = 3 + ?level' initial play area 4 x 4
	?play = 1
	?layer = 0
	?lego = 0
	
	' play area min/max coords
	?base_start = round (?zone - ?base) / 2 + 1
	?base_end = ?zone - ?base_start + 1
	?base_end = ?base_start + ?base - 1
	
	'
	create text "LEVEL ?level" as "text_level"
	'center "text_level" to 1, 1, 1
	paint "text_level" to "neon"
	turn x "text_level" to -90
	zoom "text_level" to .1, .1, 0
	move "text_level" to 8.5, 1, 1
	
	'
	goto "chunk init"
	
	'
	'
	'
	?sub = 5
	?c = ?sub + 3' milieu second
	create sprite ?zone * ?sub as "render"
	zoom "render" to 1 / ?sub
	center "render" to ?c, ?c, ?c' ?sub * 2, ?sub * 2, ?sub * 2
	move "render" to 1, 1, 1
	paint "render" to "metal"
	
	'
	copy "render" as "render-neon"
	paint "render-neon" to "neon"
	
	'
	build manual "render"
	build manual "render-neon"
	
	'
	goto "layer start"
	
	'
	?px = (round ?zone / 2)
	?pz = (round ?zone / 2)
	
return

'

label "level end"
	
	?play = 0
	?score_old = ?score
	
	'
	delete "helper"
	delete "layer"
	hide "lego"
	
	?angle = 180
	
return

'

label "level_next"
	'	construction is over - start a new one
	
	'	cleanup
	delete "render"
	
	for 1 to ?layer as ?y
		delete "render-?y"
	next
	
	'
	color 1
	?old_score = ?score
	if ?old_score > 0
		create text ?old_score as "old_score"
		center "old_score" to 1, 1, 1
		paint "old_score" to "neon"
		turn x "old_score" to -90
		zoom "old_score" to .1, .1, 0
		move "old_score" to 1, 1, 13
	end
	
	
	'	restart
	?score = 0
	?score_display = 0
	?base + 1
	?level + 1
	goto "level_start"
	
	
return

'

label "chunk init"
	
	' Create ground & sky
	' chunk resolution x 2
	?z2 = ?zone * 2
	
	'
	' ground
	'
	create sprite ?z2 as "chunk"
	center "chunk" to 1.5, 1, 1.5
	zoom "chunk" to .5
	move "chunk" to 1, -1, 1
	
	color #805020
	for 1 to ?z2 as ?x
		for 1 to ?z2 as ?z
			if (coin) = 1
				add "chunk" dot ?x, 1, ?z
			end
		next
	next
	
	color #805020
	add "chunk" box 1, 2, 1 to ?z2, 2, ?z2
	
	color #409811
	add "chunk" box 1, 3, 1 to ?z2, 3, ?z2
	
	color #805020
	for 1 to ?z2 as ?x
		for 1 to ?z2 as ?z
			if (coin) = 1
				add "chunk" dot ?x, 3, ?z
			end
		next
	next
	
	color #409811
	add "chunk" box 1, 4, 1 to ?z2, 4, ?z2
	
	'
	color #44a011
	for 1 to ?z2 as ?x
		for 1 to ?z2 as ?z
			if (coin) = 1
				add "chunk" dot ?x, 4, ?z
			end
		next
	next
	
	' play area
	color ?chunk_ground_color
	?o = ?base_start * 2 - 2
	?p = ?base_end * 2 + 1
	add "chunk" frame ?o, 4, ?o to ?p, 4, ?p
	
	' optimisation cleanup
	color 0
	add "chunk" box 3, 1, 3 to ?z2 - 2, 3, ?z2 - 2
	
	
	'
	'	skybox
	'
	create sprite 32 as "skybox"
	center "skybox" to 16, 16, 16
	zoom "skybox" to 4, 2, 4
	paint "skybox" to "neon"
	?blue = 100
	for 1 to 32 as ?y
		color ?blue, ?blue * 2, ?blue * 4
		?blue - 4
		add "skybox" frame 1, ?y, 1 to 32, ?y, 32
	next
	
	' close
	color 99
	add "skybox" box 1, 32, 1 to 32, 32, 32
	
	color 1
	add "skybox" box 1, 1, 1 to 32, 1, 32
	
	color 90, 90, 90
	for 1 to 512
		add "skybox" dot (random 1 to 32), 1, (random 1 to 32)
	next
	
	move "skybox" to 8, 8, 8
	
return

'

label "layer start"
	
	?layer + 1
	?flag_start = 1
	?layer_blocs = 0
	?flag_locked = 0
	
	
	' helper = drop area
	create sprite ?zone as "helper"
	move "helper" to 1, (?layer - 1) + .5, 1
	zoom "helper" to 1, .01, 1
	'hide "helper"
	paint "helper" to "neon"
	center "helper" to 1, 1, 1
	'hide "helper"
	
	
	?c = #444
	color ?c
	if ?layer = 1
		add "helper" box ?base_start, 1, ?base_start to ?base_end, 1, ?base_end
		hide "helper"
		' NOTHING
	else
		' display drop area
		?prev = "layer-" + (?layer - 1)
		for 1 to ?zone as ?x
			for 1 to ?zone as ?z
				if (cell ?prev to ?x, 1, ?z) <> 0
					cell "helper" to ?x, 1, ?z = ?c
				end
			next
		next
	end
	
	'
	create sprite ?zone as "layer"
	center "layer" to 1, 1, 1
	move "layer" to 1, ?layer, 1
	
	'
	goto "lego new"
	
return

'

label "lego new"
	
	?flag_drop = 1
	?lego_size = 1
	
	if ?lego <> 0
		'	keep the previous one
	else
		'
		?last = 4 + ?level
		limit ?last max 10
		
		' piece de tetris
		if ?lego = 0
			?lego = random 1 to ?last
		else
			' keep the previous one
		end
		
		color 1
		create sprite ?max as "lego"
		
		if ?lego = 1
			' L
			add "lego" dot 1, 1, 1
			add "lego" dot 2, 1, 1
			add "lego" dot 1, 1, 2
		else if ?lego = 2
			' carré
			add "lego" frame 1, 1, 1 to 2, 1, 2
		else if ?lego = 3
			' T
			add "lego" dot 1, 1, 1
			add "lego" dot 2, 1, 1
			add "lego" dot 3, 1, 1
			add "lego" dot 2, 1, 2
		else if ?lego = 4
			' +
			add "lego" dot 2, 1, 1
			add "lego" dot 2, 1, 2
			add "lego" dot 2, 1, 3
			add "lego" dot 1, 1, 2
			add "lego" dot 3, 1, 2
		else if ?lego = 5
			'U
			add "lego" dot 1, 1, 1
			add "lego" dot 2, 1, 1
			'add "piece" dot to 3,1,1
			add "lego" dot 2, 1, 2
		else if ?lego = 6
			' . de Paul
			add "lego" dot 1, 1, 1
		else if ?lego = 7
			' -|
			add "lego" dot 3, 1, 1
			add "lego" dot 3, 1, 2
			add "lego" dot 2, 1, 2
			add "lego" dot 3, 1, 3
		else if ?lego = 8
			' -|
			add "lego" dot 2, 1, 1
			add "lego" dot 2, 1, 2
		else if ?lego = 9
			' ^
			add "lego" dot 1, 1, 1
			add "lego" dot 2, 1, 2
			add "lego" dot 3, 1, 2
			add "lego" dot 1, 1, 2
			add "lego" dot 3, 1, 2
		else if ?lego = 10
			' 4
			add "lego" dot 1, 1, 1
			add "lego" dot 1, 1, 2
			add "lego" dot 2, 1, 2
			add "lego" dot 3, 1, 2
			add "lego" dot 3, 1, 3
		end
		
		center "lego" to 1, 1, 1
		?lego_zoom = 0
	end
	
	' pos "pas possible
	?py = ?layer + 1
	
	?vpx = ?px
	?vpz = ?pz
	' pas vy
	
	if (goto "test locked") = 0
		'	no room to drop lego
		?flag_locked = 60
	else
		?flag_start = 0
	end
	
	goto "lego color"
	
return

'

label "test locked"
	
	' is there room left for the current lego ?
	?possible = 0
	
	for 1 to ?zone as ?x
		for 1 to ?zone as ?z
			?valide = goto "test drop", ?x, ?z
			?possible + ?valide
		next
	next
	
return ?possible

'


label "test drop"
	param ?vx
	param ?vz
	
	' may the player drop the lego here ?
	
	?valide = 1
	
	for 1 to ?max as ?mx
		for 1 to ?max as ?mz
			?dx = ?vx + (?mx - 1)
			?dz = ?vz + (?mz - 1)
			if (cell "lego" to ?mx, 1, ?mz) <> 0' and (peek "layer" to ?dx,?dy,1) <> 0
				if (cell "helper" to ?dx, 1, ?dz) < 1
					'	not allowed
					exit 0
				else if (cell "layer" to ?dx, 1, ?dz) <> 0
					'	not available
					exit 0
				end
			end
		next
	next
	
return 1' ?valide

'

label "lego color"
	
	' default
	color 1' + text
	
	' change lego color based on the current state
	if ?flag_locked > 0
		if ?flag_start = 1
			' no room on new layer = level over
			?message = "No room available... next level!"
			color #808
			?lego_size = 0
		else
			' no room left = layer over
			?message = "No room available... going up!"
			color #f42
		end
	else if ?flag_drop = 0
		' Can't drop here
		color #ff8
	else
		' Can drop, ok
		color 1
	end
	
	fill "lego"
	
	if ?tutorial = 1
		color 1
		trace text ?message center 0, -50
	end
	
return

'

label "player move"
	
	?futur_x = ?px
	?futur_z = ?pz
	
	if (press "left") = 1
		?futur_x - 1
	else if (press "right") = 1
		?futur_x + 1
	else if (press "up") = 1
		?futur_z + 1
	else if (press "down") = 1
		?futur_z - 1
	end
	
	if ?px <> ?futur_x or ?pz <> ?futur_z
		
		if (goto "test deplace", ?futur_x, ?futur_z) = 1
			?px = ?futur_x
			?pz = ?futur_z
			
			if (goto "test drop", ?px, ?pz) = 1
				?flag_drop = 1
				?py = ?layer
			else
				?flag_drop = 0
				?py = ?layer + 2
			end
			
			goto "lego color"
		end
	end
	
	?vpx + (?px - ?vpx) / 3
	?vpz + (?pz - ?vpz) / 3
	?vpy + (?py - ?vpy) / 15
	
	' anim et place
	?lego_zoom + (?lego_size - ?lego_zoom) / 20
	zoom "lego" to ?lego_zoom
	move "lego" to ?vpx, ?vpy, ?vpz
	
return

'

label "test deplace"
	param ?vx
	param ?vz
	
	' ok pour déplacer la pièce ici ?
	' ne doit pas sortir de la zone définie
	?valide = 1
	for 1 to ?max as ?mx
		for 1 to ?max as ?mz
			?dx = ?vx + (?mx - 1)
			?dz = ?vz + (?mz - 1)
			if (cell "lego" to ?mx, 1, ?mz) <> 0
				'if (peek "helper" to ?dx,1,?dy) < 0
				if ?dx < 1 or ?dz < 1 or ?dx > ?zone or ?dz > ?zone
					' en dehors de la plage
					?valide = 0
				end
			end
		next
	next
	
return ?valide

'

label "lego_drop"
	
	if (press once "space") = 1
		if (goto "test drop", ?px, ?pz) = 1
			
			color ?render_color
			for 1 to ?max as ?mx
				for 1 to ?max as ?mz
					if (cell "lego" to ?mx, 1, ?mz) <> 0
						?dx = ?px + (?mx - 1)
						?dz = ?pz + (?mz - 1)
						add "layer" dot ?dx, 1, ?dz
						?score + 3
					end
				next
			next
			
			' move "layer" to 1, ?layer, 1
			
			?lego = 0
			goto "lego new"
		end
	end
	
return

'

label "layer end"
	
	'	transform layer -> city
	'clear screen
	goto "layer render"
	
	' 	keep a copy for helper
	copy "layer" as "layer-?layer"
	hide "layer-?layer"
	delete "layer"
	delete "helper"
	'delete "lego"
	
	'	next layer
	goto "layer start"
	
return


'

label "layer render"
	
	
	'	transform layer -> city
	for 1 to ?zone as ?x
		for 1 to ?zone as ?z
			if (cell "layer" to ?x, 1, ?z) <> 0
				
				for 1 to ?sub as ?xx
					for 1 to ?sub as ?zz
						for 1 to ?sub as ?yy
							
							?xxx = ?x * ?sub + ?xx
							?zzz = ?z * ?sub + ?zz
							?yyy = ?layer * ?sub + ?yy
							
							color ?render_color
							?voxel_part = "render"
							
							if ?yy = ?sub
								color ?render_roof
							end
							
							if ?yy = 3 and ?xx <> 3
								' windows
								color ?layer + 1
								?voxel_part = "render-neon"
								' extrusion x 4
								if ?xx = 1 and (cell "layer" to ?x - 1, 1, ?z) = 0
									color 0
								end
								if ?xx = ?sub and (cell "layer" to ?x + 1, 1, ?z) = 0
									color 0
								end
								if ?zz = 1 and (cell "layer" to ?x, 1, ?z - 1) = 0
									color 0
								end
								if ?zz = ?sub and (cell "layer" to ?x, 1, ?z + 1) = 0
									color 0
								end
							end
							
							add ?voxel_part dot ?xxx, ?yyy, ?zzz
						next
					next
				next
				
			end
		next
	next
	
	update
	build "render"
	build "render-neon"
	
return

'

label "final camera anim"
	
	'	move the camera around the city
	?m = ?zone / 2
	?n = 2 + ?layer * .75
	?angle + .5
	
	?rad = ?n * 2 - ?n * (cos ?angle / 2)
	
	?cx = ?m + ?rad * (sin ?angle)
	?cy = ?n + ?n * .5 * (sin ?angle / 2)
	?cz = ?m + ?rad * (cos ?angle)
	
return




'
x