summaryrefslogtreecommitdiff
path: root/cactus.lua
blob: 65ebf4e48ec3322fa9b03d196d389de83053c3c4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
local numutil = require 'numutil'

local function ensure_equipped(ptype, item)
	local cur = peripheral.getType"left"
	print(cur)
	if cur == ptype then return true end
	for i = 1,16 do
		local det = turtle.getItemDetail(i)
		if det and det.name == item then
			turtle.select(i)
			return turtle.equipLeft()
		end
	end
	return false, "couldn't find "..item
end

local function ensure_modem() return ensure_equipped("modem","computercraft:wireless_modem_normal") end
local function ensure_scanner() return error("aaa") end

local function turte_pos_init()
	assert(ensure_modem())

	local POS = vector.new(gps.locate())

	while turtle.detect() do turtle.turnRight() end
	turtle.forward()
	local newpos = vector.new(gps.locate())
	turtle.back()
	local FACING = newpos - POS

	return POS, FACING
end

local POS, FACING = turte_pos_init()

local function moveby_y(delta)
	local fn = turtle.up
	if delta < 0 then fn = turtle.down  delta = -delta  end
	for i=1,delta do fn() end
	POS.y = POS.y + delta
end

local function rotatev(v,nq)
	-- rotates v by n quarters, clockwise (rightwards)
	nq = nq%4
	if nq == 0     then return vector.new( v.x,  v.y,  v.z)
	elseif nq == 1 then return vector.new(-v.z,  v.y,  v.x)
	elseif nq == 2 then return vector.new(-v.x,  v.y, -v.z)
	elseif nq == 3 then return vector.new( v.z,  v.y, -v.x)
	end
end

local function turn_right()
	FACING = rotatev(FACING,1)
	turtle.turnRight()
end
local function turn_left()
	FACING = rotatev(FACING,-1)
	turtle.turnLeft()
end

local function turn_to_face(newfacing)
	if newfacing == FACING then return
	elseif newfacing == -FACING then turn_right() turn_right()
	elseif newfacing == rotatev(FACING,1) then turn_right()
	elseif newfacing == rotatev(FACING,-1) then turn_left()
	else error("invalid facing "..tostring(newfacing),2)
	end
end

local function move_linear(n)
	local dir = turtle.forward
	if n < 0 then dir = turtle.back end
	for i = 1,math.abs(n) do dir() end
	print(POS,n,FACING)
	POS = POS + FACING*n
end

local function moveby_xz(dv)
	if FACING.x ~= 0 then
		move_linear(dv:dot(FACING))
		if dv.z ~= 0 then
			turn_to_face(vector.new(0,0,numutil.sign(dv.z)))
			move_linear(dv:dot(FACING))
		end
	elseif FACING.z ~= 0 then
		move_linear(dv:dot(FACING))
		if dv.x ~= 0 then
			turn_to_face(vector.new(numutil.sign(dv.x),0,0))
			move_linear(dv:dot(FACING))
		end
	end
end

local function moveby(delta)
	moveby_y(delta.y)
	moveby_xz(delta)
end
local function moveto(target)
	moveby(target - POS)
end


local datum = vector.new(-18, 128, -1837)

moveto(datum)
turn_to_face(vector.new(0,0,1))

local function do_column()
	if turtle.detectDown() then
		turtle.digDown()
		turtle.down()
		turtle.digDown()
		turtle.up()
	end
end

repeat
	repeat
		do_column()
		move_linear(1)
	until POS.z == -1826
	do_column()
	turn_right()
	move_linear(1)
	turn_right()

	repeat
		do_column()
		move_linear(1)
	until POS.z == datum.z
	do_column()
	turn_left()
	move_linear(1)
	turn_left()

until POS.x <= -29