· 4 years ago · Apr 27, 2021, 08:50 PM
1--- CC
2--- Turtle sorter
3--- Input amount of rows and height of chests
4
5-- User input
6
7-- Initialized settings for the area the turtle while sort
8local chest_width = 5
9local chest_height = 12
10
11-- If the turtles backs up to sort the chests ar to it's "chest_side"
12local chest_side = 'Right'
13
14-- The way the face of the turtle is oriented
15-- N = 0; E = 1; S = 2; W = 3
16local turtle_face = 1
17
18-- vector from 0 to 'home'.
19local home_cords = vector.new(76, 9, 178)
20
21-- Script vars
22
23-- Chest
24local chest = peripheral.wrap('front')
25local copy_side = chest_side
26
27-- Positioning
28local pos = vector.new(gps.locate())
29local diff = pos:sub(home_cords)
30
31-- accepted fuels
32local accepted_fuel = {
33 'minecraft:coal_block',
34 'minecraft:coal',
35}
36
37-- Helper functions
38local function table_to_set(table)
39 --- Converts a table to a set where there are no double keys.
40
41 -- Create the set.
42 local a_set = {}
43
44 -- For each item in the table iterate trough it.
45 for i in ipairs(table) do
46 -- The key is the 'name' and the value, a place holder, is the last
47 -- 'count' value.
48 a_set[table[i]['name']] = table[i]['count']
49 end
50
51 -- Print function remove.
52 for key, value in pairs(a_set) do
53 print( key, value)
54 end
55
56 -- Return the set.
57 return a_set
58end
59
60local function around()
61 turtle.turnLeft()
62 turtle.turnLeft()
63 if turtle_face + 2 == 4 then
64 turtle_face = 0
65 elseif turtle_face + 2 == 5 then
66 turtle_face = 1
67 else
68 turtle_face = turtle_face + 2
69 end
70end
71
72local function Left()
73 turtle.turnLeft()
74 if turtle_face - 1 == -1 then
75 turtle_face = 3
76 else
77 turtle_face = turtle_face - 1
78 end
79end
80
81local function Right()
82 turtle.turnRight()
83 if turtle_face + 1 == 4 then
84 turtle_face = 0
85 else
86 turtle_face = turtle_face + 1
87 end
88end
89
90local function n_forward(n)
91 for x=1,n do
92 turtle.forward()
93 end
94end
95
96local function pick_up()
97 for i in pairs(chest.list()) do
98 turtle.suck()
99 end
100 return true
101end
102
103local function refuel()
104 local current_fuel = turtle.getFuelLevel()
105 if current_fuel <= 0 then
106 while current_fuel <= 0 do
107 turtle.select(1)
108 for x=1, #accepted_fuel do
109 if turtle.getItemDetail().name == accepted_fuel[x] then
110 turtle.refuel()
111 end
112 end
113 end
114 end
115end
116
117local function update(cords)
118 pos = vector.new(gps.locate())
119 diff = pos:sub(cords)
120end
121
122local function go_to(cords)
123 --- Cord is a table, from the vector API, in {x='x', y='y', z='z'}
124 while diff.x ~= 0 or diff.y ~= 0 or diff.z ~= 0 do
125 pos = vector.new(gps.locate())
126
127 -- For the x-field
128 if diff.x < 0 then
129 print('diff x < 0')
130 if turtle_face ~= 1 then
131 while turtle_face ~= 1 do
132 Right()
133 print('face (if) : ', turtle_face)
134 end
135 end
136
137 while not turtle.detect() and diff.x < 0 and turtle_face == 1 do
138 print('diff neg x: ', diff)
139 print('pos: ', pos)
140 print('face: ', turtle_face)
141 turtle.forward()
142 update(cords)
143 end
144
145 elseif diff.x > 0 then
146 print('diff x > 0')
147 if turtle_face ~= 3 then
148 while turtle_face ~= 3 do
149 Right()
150 print('face (if) : ', turtle_face)
151 end
152 end
153
154 while not turtle.detect() and diff.x > 0 and turtle_face == 3 do
155 print('diff pos x: ', diff)
156 print('pos: ', pos)
157 print('face: ', turtle_face)
158 turtle.forward()
159 update(cords)
160 end
161 end
162
163 -- For the y-field
164 if diff.y < 0 then
165 while not turtle.detectUp() and diff.y < 0 do
166 print('diff neg y: ', diff)
167 print('pos: ', pos)
168 print('face: ', turtle_face)
169 turtle.up()
170 update(cords)
171 end
172 elseif diff.y > 0 then
173 while not turtle.detectDown() and diff.y > 0 do
174 print('diff pos y: ', diff)
175 print('pos: ', pos)
176 print('face: ', turtle_face)
177 turtle.down()
178 update(cords)
179 end
180 end
181
182 -- For the z-field
183 if diff.z < 0 then
184 print('diff z < 0')
185 if turtle_face ~= 0 then
186 while turtle_face ~= 0 do
187 Right()
188 print('face (if) : ', turtle_face)
189 end
190 end
191
192 while not turtle.detect() and diff.z < 0 and turtle_face == 0 do
193 print('diff neg y: ', diff)
194 print('pos: ', pos)
195 print('face: ', turtle_face)
196 turtle.forward()
197 update(cords)
198 end
199 elseif diff.z > 0 then
200 print('diff z > 0')
201 if turtle_face ~= 2 then
202 while turtle_face ~= 2 do
203 Right()
204 print('face (if) : ', turtle_face)
205 end
206 end
207
208 while not turtle.detect() and diff.z > 0 and turtle_face == 2 do
209 print('diff neg y: ', diff)
210 print('pos: ', pos)
211 print('face: ', turtle_face)
212 turtle.forward()
213 update(cords)
214 end
215
216 end
217
218 end
219end
220
221-- Main functions
222
223-- Compare function
224local function drop(compare)
225 --- Compare/sort/drop function
226 --- To-do
227 --- Use .getItemDetail(slot) / .size() instead of .list() for the
228 --- display / support of nil slots
229
230 -- If the turtle does not have to check if the current slot item is
231 -- in it's inventory.
232 if compare == false then
233 -- For all the items, except fuel, drop it in the chest infront of it.
234 for x=2,16 do
235 turtle.select(x)
236 turtle.drop()
237 end
238
239 -- The turtle does need to compare.
240 else
241 -- for the amount of unique blocks in the chest.
242 if table_to_set(chest.list()) ~= nil then
243 for i in pairs(table_to_set(chest.list())) do
244 -- For the inventorty of a turtle.
245 for x=2,16 do
246 -- Select the slot
247 turtle.select(x)
248 -- If the slot and the inventory items match, drop the item in
249 -- the chest
250 if i ~= nil and turtle.getItemDetail() ~= nil then
251 if i ==
252 turtle.getItemDetail()['name'] then
253 turtle.drop()
254 end
255 end
256 end
257 end
258 end
259 end
260 turtle.select(1)
261end
262
263local function move()
264 -- Move from 'home' to chests
265 go_to(vector.new(74, 8, 173))
266 if turtle_face ~= 0 then
267 while turtle_face ~= 0 do
268 Right()
269 end
270 end
271
272 -- If the chests are on it's right side, now they will be on the left.n_forward
273 if chest_side == 'Right' then
274 Left()
275 turtle.forward()
276 elseif chest_side == 'Left' then
277 Right()
278 turtle.forward()
279 end
280
281 -- Place the items in the right chests
282 for x=1,chest_height do
283 for y=1,chest_width do
284 refuel()
285 if chest_side == 'Left' then
286 Right()
287 drop(true)
288 Left()
289 elseif chest_side == 'Right' then
290 Left()
291 drop(true)
292 Right()
293 end
294 turtle.forward()
295 end
296 turtle.up()
297 around()
298 if chest_side == 'Left' then
299 chest_side = 'Right'
300 else
301 chest_side = 'Left'
302 end
303 end
304 go_to(home_cords)
305end
306
307local function main()
308 pos = vector.new(gps.locate())
309 diff = pos:sub(home_cords)
310 local inventory_full = true
311
312 -- Check if the turtle is 'Home'
313 if diff.x == 0 and diff.y == 0 and diff.z == 0 then
314 -- Check fuel level and refuel if needed
315 refuel()
316
317 -- Check if the turtle's inventory is full
318 for x=2,16 do
319 turtle.select(x)
320 if turtle.getItemDetail() == nil then
321 inventory_full = false
322 end
323 end
324
325 -- If there is space in the inventory don't sort but wait for a full
326 -- inventory.
327 while not inventory_full do
328 inventory_full = pick_up()
329 end
330 move()
331 end
332
333end
334
335-- Main loop
336while true do
337 main()
338end