View difference between Paste ID: UYR6MHTp and zkb4FY4L
SHOW: | | - or go back to the newest paste.
1
cost_only = false
2
blocks = 0
3
fuel = 0
4
5
positionx = 0
6
positiony = 0
7
facing = 0
8
9
function writeOut(message)
10
	print(message)
11
end
12
function checkResources()
13
	while turtle.getItemCount(activeslot) <= 0 do
14
		if activeslot == 16 then
15
			writeOut("Turtle is empty, please put building block in slots and press enter to continue")
16
			io.read()
17
			activeslot = 1
18
			turtle.select(activeslot)
19
		else
20
			activeslot = activeslot+1
21
			writeOut("Turtle slot empty, trying slot "..activeslot)
22
			turtle.select(activeslot)
23
		end
24
		os.sleep(0.2)
25
	end
26
end
27
function checkFuel()
28
	while turtle.getFuelLevel() < 50 do
29
		writeOut("Turtle almost out of fuel, pausing. Please drop fuel in inventory. And press enter.")
30
		io.read()
31
		turtle.refuel()
32
	end
33
end
34
function placeBlock()
35
	-- Cost calculation mode - don't move
36
	blocks = blocks + 1
37
	if cost_only then
38
		return
39
	end
40
41
	if turtle.detectDown() and not turtle.compareDown() then
42
		turtle.digDown()
43
	end
44
45
	checkResources()
46
47
	turtle.placeDown()
48
end
49
-- Navigation features
50
-- allow the turtle to move while tracking its position
51
-- this allows us to just give a destination point and have it go there
52
53
function turnRightTrack()
54
	if cost_only then
55
		return
56
	end
57
58
	turtle.turnRight()
59
	facing = facing + 1
60
	if facing >= 4 then
61
		facing = 0
62
	end
63
end
64
65
function turnLeftTrack()
66
	if cost_only then
67
		return
68
	end
69
70
	turtle.turnLeft()
71
	facing = facing - 1
72
	if facing < 0 then
73
		facing = 3
74
	end
75
end
76
function turnAroundTrack()
77
	turnLeftTrack()
78
	turnLeftTrack()
79
end
80
function safeForward()
81
	fuel = fuel + 1
82
	if cost_only then
83
		return
84
	end
85
86
	checkFuel()
87
	success = false
88
	while not success do
89
		success = turtle.forward()
90
		if not success then
91
			while turtle.detect() do
92
				if not turtle.dig() then
93
					print("Blocked attempting to move forward.")
94
					print("Please clear and press enter to continue.")
95
					io.read()
96
				end
97
			end
98
		end
99
	end
100
end
101
102
function safeBack()
103
	fuel = fuel + 1
104
	if cost_only then
105
		return
106
	end
107
108
	checkFuel()
109
	success = false
110
	while not success do
111
		success = turtle.back()
112
		if not success then
113
			turnAroundTrack();
114
			while turtle.detect() do
115
				if not turtle.dig() then
116
					break;
117
				end
118
			end
119
			turnAroundTrack()
120
			success = turtle.back()
121
			if not success then
122
				print("Blocked attempting to move back.")
123
				print("Please clear and press enter to continue.")
124
				io.read()
125
			end
126
		end
127
	end
128
end
129
130
function safeUp()
131
	fuel = fuel + 1
132
	if cost_only then
133
		return
134
	end
135
136
	checkFuel()
137
	success = false
138
	while not success do
139
		success = turtle.up()
140
		if not success then
141
			while turtle.detectUp() do
142
				if not turtle.digUp() then
143
					print("Blocked attempting to move up.")
144
					print("Please clear and press enter to continue.")
145
					io.read()
146
				end
147
			end
148
		end
149
	end
150
end
151
152
function safeDown()
153
	fuel = fuel + 1
154
	if cost_only then
155
		return
156
	end
157
158
	checkFuel()
159
	success = false
160
	while not success do
161
		success = turtle.down()
162
		if not success then
163
			while turtle.detectDown() do
164
				if not turtle.digDown() then
165
					print("Blocked attempting to move down.")
166
					print("Please clear and press enter to continue.")
167
					io.read()
168
				end
169
			end
170
		end
171
	end
172
end
173
174
function moveY(targety)
175
	if targety == positiony then
176
		return
177
	end
178
179
	if (facing ~= 0 and facing ~= 2) then -- check axis
180
		turnRightTrack()
181
	end
182
183
	while targety > positiony do
184
		if facing == 0 then
185
			safeForward()
186
		else
187
			safeBack()
188
		end
189
		positiony = positiony + 1
190
	end
191
192
	while targety < positiony do
193
		if facing == 2 then
194
			safeForward()
195
		else
196
			safeBack()
197
		end
198
		positiony = positiony - 1
199
	end
200
end
201
202
function moveX(targetx)
203
	if targetx == positionx then
204
		return
205
	end
206
207
	if (facing ~= 1 and facing ~= 3) then -- check axis
208
		turnRightTrack()
209
	end
210
211
	while targetx > positionx do
212
		if facing == 1 then
213
			safeForward()
214
		else
215
			safeBack()
216
		end
217
		positionx = positionx + 1
218
	end
219
220
	while targetx < positionx do
221
		if facing == 3 then
222
			safeForward()
223
		else
224
			safeBack()
225
		end
226
		positionx = positionx - 1
227
	end
228
end
229
230
function navigateTo(targetx, targety)
231
	if facing == 0 or facing == 2 then -- Y axis
232
		moveY(targety)
233
		moveX(targetx)
234
	else
235
		moveX(targetx)
236
		moveY(targety)
237
	end
238
end
239
function line(length)
240
	if length <= 0 then
241
		error("Error, length can not be 0")
242
	end
243
	local i
244
	for i=1, length do
245
		placeBlock()
246
		if i ~= length then
247
			safeForward()
248
		end
249
	end
250
end
251
function rectangle(depth, width)
252
	if depth <= 0 then
253
		error("Error, depth can not be 0")
254
	end
255
	if width <= 0 then
256
		error("Error, width can not be 0")
257
	end
258
	local lengths = {depth, width, depth, width }
259
	local j
260
	for j=1,4 do
261
		line(lengths[j])
262
		turnRightTrack()
263
	end
264
end
265
function square(width)
266
	rectangle(width, width)
267
end
268
function wall(length, height)
269
	turnRightTrack()
270
	local i
271
	local j
272
	for i = 1, length do
273
		for j = 1, height do
274
			placeBlock()
275
			if j < height then
276
				safeUp()
277
			end
278
		end
279
		safeForward()
280
		for j = 1, height-1 do
281
			safeDown()
282
		end
283
	end
284
	turnLeftTrack()
285
end
286
function platform(x, y)
287
	local forward = true
288
	for cy = 0, y-1 do
289
		for cx = 0, x-1 do
290
			if forward then
291
				navigateTo(cx, cy)
292
			else
293
				navigateTo(x - cx - 1, cy)
294
			end
295
			placeBlock()
296
		end
297
		if forward then
298
			forward = false
299
		else
300
			forward = true
301
		end
302
	end
303
end
304
function stair(width, height)
305
	turnRightTrack()
306
	local cx=1
307
	local cy=0
308
	local goforward=0
309
	while cy < height do
310
		while cx < width do
311
			placeBlock()
312
			safeForward()
313
			cx = cx + 1
314
		end
315
		placeBlock()
316
		cx = 1
317
		cy = cy + 1
318
		if cy < height then
319
			if goforward == 1 then
320
				turnRightTrack()
321
				safeUp()
322
				safeForward()
323
				turnRightTrack()
324
				goforward = 0
325
			else
326
				turnLeftTrack()
327
				safeUp()
328
				safeForward()
329
				turnLeftTrack()
330
				goforward = 1
331
			end
332
		end
333
	end
334
end
335
function circle(radius)
336
	radius = tonumber(radius)
337
338
	-- Main dome and sphere building routine
339
340
	width = radius * 2 + 1
341
	sqrt3 = 3 ^ 0.5
342
	boundary_radius = radius + 1.0
343
	boundary2 = boundary_radius ^ 2
344
345
	zstart = radius
346
347
	-- This loop is for each vertical layer through the sphere or dome.
348
	for z = zstart,zstart do
349
		--writeOut("Layer " .. z)
350
		cz2 = (radius - z) ^ 2
351
352
		limit_offset_y = (boundary2 - cz2) ^ 0.5
353
		max_offset_y = math.ceil(limit_offset_y)
354
355
		-- We do first the +x side, then the -x side to make movement efficient
356
		for side = 0,1 do
357
			-- On the right we go from small y to large y, on the left reversed
358
			-- This makes us travel clockwise around each layer
359
			if (side == 0) then
360
				ystart = radius - max_offset_y
361
				yend = radius + max_offset_y
362
				ystep = 1
363
			else
364
				ystart = radius + max_offset_y
365
				yend = radius - max_offset_y
366
				ystep = -1
367
			end
368
369
			for y = ystart,yend,ystep do
370
				cy2 = (radius - y) ^ 2
371
372
				remainder2 = (boundary2 - cz2 - cy2)
373
374
375
				if remainder2 >= 0 then
376
					-- This is the maximum difference in x from the centre we can be without definitely being outside the radius
377
					max_offset_x = math.ceil((boundary2 - cz2 - cy2) ^ 0.5)
378
379
					-- Only do either the +x or -x side
380
					if (side == 0) then
381
						-- +x side
382
						xstart = radius
383
						xend = radius + max_offset_x
384
					else
385
						-- -x side
386
						xstart = radius - max_offset_x
387
						xend = radius - 1
388
					end
389
390
					-- Reverse direction we traverse xs when in -y side
391
					if y > radius then
392
						temp = xstart
393
						xstart = xend
394
						xend = temp
395
						xstep = -1
396
					else
397
						xstep = 1
398
					end
399
400
					for x = xstart,xend,xstep do
401
						cx2 = (radius - x) ^ 2
402
						distance_to_centre = (cx2 + cy2 + cz2) ^ 0.5
403
						-- Only blocks within the radius but still within 1 3d-diagonal block of the edge are eligible
404
						if distance_to_centre < boundary_radius and distance_to_centre + sqrt3 >= boundary_radius then
405
							offsets = {{0, 1, 0}, {0, -1, 0}, {1, 0, 0}, {-1, 0, 0}, {0, 0, 1}, {0, 0, -1}}
406
							for i=1,6 do
407
								offset = offsets[i]
408
								dx = offset[1]
409
								dy = offset[2]
410
								dz = offset[3]
411
								if ((radius - (x + dx)) ^ 2 + (radius - (y + dy)) ^ 2 + (radius - (z + dz)) ^ 2) ^ 0.5 >= boundary_radius then
412
									-- This is a point to use
413
									navigateTo(x, y)
414
									placeBlock()
415
									break
416
								end
417
							end
418
						end
419
					end
420
				end
421
			end
422
		end
423
	end
424
425
	-- Return to where we started in x,y place and turn to face original direction
426
	-- Don't change vertical place though - should be solid under us!
427
	navigateTo(0, 0)
428
	while (facing > 0) do
429
		turnLeftTrack()
430
	end
431
end
432
function dome(type, radius)
433
	type = type
434
	radius = tonumber(radius)
435
436
	-- Main dome and sphere building routine
437
438
	width = radius * 2 + 1
439
	sqrt3 = 3 ^ 0.5
440
	boundary_radius = radius + 1.0
441
	boundary2 = boundary_radius ^ 2
442
443
	if type == "dome" then
444
		zstart = radius
445
	elseif type == "sphere" then
446
		zstart = 0
447
	else
448
		print("Usage: sdbuild <shape> <radius> [-c]")
449
		os.exit(1)
450
	end
451
	zend = width - 1
452
453
	-- This loop is for each vertical layer through the sphere or dome.
454
	for z = zstart,zend do
455
		if not cost_only and z ~= zstart then
456
			safeUp()
457
		end
458
		--writeOut("Layer " .. z)
459
		cz2 = (radius - z) ^ 2
460
461
		limit_offset_y = (boundary2 - cz2) ^ 0.5
462
		max_offset_y = math.ceil(limit_offset_y)
463
464
		-- We do first the +x side, then the -x side to make movement efficient
465
		for side = 0,1 do
466
			-- On the right we go from small y to large y, on the left reversed
467
			-- This makes us travel clockwise around each layer
468
			if (side == 0) then
469
				ystart = radius - max_offset_y
470
				yend = radius + max_offset_y
471
				ystep = 1
472
			else
473
				ystart = radius + max_offset_y
474
				yend = radius - max_offset_y
475
				ystep = -1
476
			end
477
478
			for y = ystart,yend,ystep do
479
				cy2 = (radius - y) ^ 2
480
481
				remainder2 = (boundary2 - cz2 - cy2)
482
483
484
				if remainder2 >= 0 then
485
					-- This is the maximum difference in x from the centre we can be without definitely being outside the radius
486
					max_offset_x = math.ceil((boundary2 - cz2 - cy2) ^ 0.5)
487
488
					-- Only do either the +x or -x side
489
					if (side == 0) then
490
						-- +x side
491
						xstart = radius
492
						xend = radius + max_offset_x
493
					else
494
						-- -x side
495
						xstart = radius - max_offset_x
496
						xend = radius - 1
497
					end
498
499
					-- Reverse direction we traverse xs when in -y side
500
					if y > radius then
501
						temp = xstart
502
						xstart = xend
503
						xend = temp
504
						xstep = -1
505
					else
506
						xstep = 1
507
					end
508
509
					for x = xstart,xend,xstep do
510
						cx2 = (radius - x) ^ 2
511
						distance_to_centre = (cx2 + cy2 + cz2) ^ 0.5
512
						-- Only blocks within the radius but still within 1 3d-diagonal block of the edge are eligible
513
						if distance_to_centre < boundary_radius and distance_to_centre + sqrt3 >= boundary_radius then
514
							offsets = {{0, 1, 0}, {0, -1, 0}, {1, 0, 0}, {-1, 0, 0}, {0, 0, 1}, {0, 0, -1}}
515
							for i=1,6 do
516
								offset = offsets[i]
517
								dx = offset[1]
518
								dy = offset[2]
519
								dz = offset[3]
520
								if ((radius - (x + dx)) ^ 2 + (radius - (y + dy)) ^ 2 + (radius - (z + dz)) ^ 2) ^ 0.5 >= boundary_radius then
521
									-- This is a point to use
522
									navigateTo(x, y)
523
									placeBlock()
524
									break
525
								end
526
							end
527
						end
528
					end
529
				end
530
			end
531
		end
532
	end
533
534
	-- Return to where we started in x,y place and turn to face original direction
535
	-- Don't change vertical place though - should be solid under us!
536
	navigateTo(0, 0)
537
	while (facing > 0) do
538
		turnLeftTrack()
539
	end
540
541
end
542
writeOut("Shape Maker 1.1. Created by Michiel using a bit of Vliekkie's code")
543
writeOut("Fixed and made readable by Aeolun ;)")
544
writeOut("");
545
writeOut("What should be built?")
546
writeOut("+---------+-----------+-------+-------+")
547
writeOut("| line    | rectangle | wall  | room  |")
548
writeOut("| square  | platform  | stair | dome  |")
549
writeOut("| pyramid | cylinder  | circle|       |")
550
writeOut("+---------+-----------+-------+-------+")
551
writeOut("")
552
553
local choice = io.read()
554
writeOut("Building a "..choice)
555
writeOut("Want to just calculate the cost? [y/n]")
556
local yes = io.read()
557
if yes == 'y' then
558
	cost_only = true
559
end
560
561
if not cost_only then
562
	turtle.select(1)
563
	activeslot = 1
564
	if turtle.getItemCount(activeslot) == 0 then
565
		writeOut("Please put building blocks in the first slot (and more if you need them)")
566
		while turtle.getItemCount(activeslot) == 0 do
567
			os.sleep(2)
568
		end
569
	end
570
end
571
if choice == "rectangle" then -- fixed
572
	writeOut("How deep do you want it to be?")
573
	h = io.read()
574
	h = tonumber(h)
575
	writeOut("How wide do you want it to be?")
576
	v = io.read()
577
	v = tonumber(v)
578
	rectangle(h, v)
579
end
580
if choice == "square" then --fixed
581
	writeOut("How long does it need to be?")
582
	local s = io.read()
583
	s = tonumber(s)
584
	square(s)
585
end
586
if choice == "line" then --fixed
587
	writeOut("How long does the line need to be?")
588
	local ll = io.read()
589
	ll = tonumber(ll)
590
	line(ll)
591
end
592
if choice == "wall" then --fixed
593
	writeOut("How long does it need to be?")
594
	local wl = io.read()
595
	wl = tonumber(wl)
596
	writeOut("How high does it need to be?")
597
	local wh = io.read()
598
	wh = tonumber(wh)
599
	if  wh <= 0 then
600
		error("Error, the height can not be zero")
601
	end
602
	if wl <= 0 then
603
		error("Error, the length can not be 0")
604
	end
605
	wall(wl, wh)
606
end
607
if choice == "platform" then
608
	writeOut("How long do you want it to be?")
609
	x = io.read()
610
	x = tonumber(x)
611
	writeOut("How wide do you want it to be?")
612
	y = io.read()
613
	y = tonumber(y)
614
	platform(x, y)
615
	writeOut("Done")
616
end
617
if choice == "stair" then --fixed
618
	writeOut("How wide do you want it to be?")
619
	x = io.read()
620
	x = tonumber(x)
621
	writeOut("How high do you want it to be?")
622
	y = io.read()
623
	y = tonumber(y)
624
	stair(x, y)
625
	writeOut("Done")
626
end
627
if choice == "room" then
628
	writeOut("How deep does it need to be?")
629
	local cl = io.read()
630
	cl = tonumber(cl)
631
	writeOut("How wide does it need to be?")
632
	local ch = io.read()
633
	ch = tonumber(ch)
634
	writeOut("How high does it need to be?")
635
	local hi = io.read()
636
	hi = tonumber(hi)
637
	if hi < 3 then
638
		hi = 3
639
	end
640
	if cl < 3 then
641
		cl = 3
642
	end
643
	if ch < 3 then
644
		ch = 3
645
	end
646
647
	platform(cl, ch)
648
	while (facing > 0) do
649
		turnLeftTrack()
650
	end
651
	turnAroundTrack()
652
	for i = 1, hi-2 do
653
		safeUp()
654
		rectangle(cl, ch)
655
	end
656
	safeUp()
657
	platform(cl, ch)
658
end
659
if choice == "dome" then
660
	writeOut("What radius do you need it to be?")
661
	local rad = io.read()
662
	rad = tonumber(rad)
663
	dome("dome", rad)
664
end
665
if choice == "sphere" then
666
	writeOut("What radius do you need it to be?")
667
	local rad = io.read()
668
	rad = tonumber(rad)
669
	dome("sphere", rad)
670
end
671
if choice == "circle" then
672
	writeOut("What radius do you need it to be?")
673
	local rad = io.read()
674
	rad = tonumber(rad)
675
	circle(rad)
676
end
677
if choice == "cone" then
678
	writeOut("What radius do you need it to be?")
679
	local rad = io.read()
680
	rad = tonumber(rad)
681
	for radi=rad,1,-1 do
682
    	  circle(radi)
683
          turtle.up()
684
          turtle.forward()
685
          turtle.turnRight()
686
          turtle.forward()
687
          turtle.turnLeft()
688
        end
689
end
690
if choice == "cylinder" then
691
	writeOut("What radius do you need it to be?")
692
	local rad = io.read()
693
	rad = tonumber(rad)
694
	writeOut("What height do you need it to be?")
695
	local height = io.read()
696
	height = tonumber(height)
697
698
	for i = 1, height do
699
		circle(rad)
700
		safeUp()
701
	end
702
	for i = 1, height do
703
		safeDown()
704
	end
705
end
706
if choice == "pyramid" then
707
	writeOut("What width/depth do you need it to be?")
708
	local width = io.read()
709
	width = tonumber(width)
710
	writeOut("Do you want it to be hollow [y/n]?")
711
	local hollow = io.read()
712
	if hollow == 'y' then
713
		hollow = true
714
	else
715
		hollow = false
716
	end
717
718
719
	height = math.ceil(width / 2)
720
	for i = 1, height do
721
		if hollow then
722
			rectangle(width, width)
723
		else
724
			platform(width, width)
725
			navigateTo(0,0)
726
			while facing ~= 0 do
727
				turnRightTrack()
728
			end
729
		end
730
		if i ~= height then
731
			safeUp()
732
			safeForward()
733
			turnRightTrack()
734
			safeForward()
735
			turnLeftTrack()
736
			width = width - 2
737
		end
738
	end
739
end
740
741
print("Blocks used: " .. blocks)
742
print("Fuel used: " .. fuel)