· 7 years ago · Oct 10, 2018, 05:24 PM
1-- Valvates library for cordanite management and stuff.
2-- If you have an idea for feature make an issue or
3-- Create a pull request if you're a coder.
4-- A lot of stuff here is unfinished so
5-- Be careful and tell me how to make it better :DD
6
7-- WARNING!
8-- Since the turtle writes his coordanites to a file you should
9-- run fs.delete(t.cordsfile) when your program finishes!
10
11local t = {}
12
13
14-- Debug level of messages to display. (see log function)
15-- I use level 1 as error 2 as Warning 3 as Info and 4 for debug.
16t.debug_level = 4
17
18-- Files
19t.logfile = 'logfile.log'
20t.cordsfile = 'cords'
21t.posfile = 'savedPosistions'
22
23local file -- Used for file management
24t.saved_positions = {}-- Table for saving posisions
25
26t.blocks_dug = 0 -- Blocks dug
27
28-- Diference in cords with diferent orientations
29local zDiff = {
30 [0] = -1,
31 [1] = 0,
32 [2] = 1,
33 [3] = 0
34}
35
36local xDiff = {
37 [0] = 0,
38 [1] = 1,
39 [2] = 0,
40 [3] = -1
41}
42
43-- Needed for human readable input/output
44t.orientations = {
45 [0] = "north",
46 [1] = "east",
47 [2] = "south",
48 [3] = "west"
49}
50
51-- Unwanted items for clean inventory function.
52t.unWantedItems = {
53 'minecraft:cobblestone',
54 'minecraft:stone',
55 'minecraft:flint',
56 'minecraft:dirt',
57 'minecraft:sandstone',
58 'minecraft:sand'
59}
60
61-- Checks if a value is in a table.
62function t.inTable(value, table)
63 for key, v in ipairs(table) do
64 if value == value then
65 return true
66 end
67 end
68 -- if its not in the table then
69 return false
70end
71
72function t.cleanInventory()
73 local item
74 local prevSlot = turtle.getSelectedSlot()
75
76 for i=1,16 do
77 item = turtle.getItemDetail(i)
78 -- Makes sure item exists to avoid nil errors.
79 if item and t.inTable(item.name, t.unWantedItems) then
80 turtle.select(i)
81 turtle.dropDown(item.count) -- Drops all of the unwanted item
82 end
83 turtle.select(prevSlot) -- Leave no trace!
84 end
85end
86
87function t.writeToFile(msg, file)
88 -- Function used by logging function.
89 -- i felt it was cleaner this way.
90
91 if file == nil then
92 file = 'log' -- default
93 end
94
95 file = fs.open(file, 'a')
96 file.write(msg..'\n') -- Adds newline
97 file.close()
98end
99
100function t.log(msg, msg_debug_level)
101 -- Logging function
102
103 if msg_debug_level == nil then
104 t.writeToFile('[WARNING] msg_debug_level is nil, defaulting to level 3 message info.', t.logfile)
105 -- As a param this is already local.
106 msg_debug_level = 3
107 end
108
109 if msg_debug_level <= t.debug_level then
110 t.writeToFile(msg)
111 end
112end
113
114local function updatePositions()
115 -- Writes saved positions to file.
116 file = fs.open(t.posfile, 'w')
117 file.write(textutils.serialize(t.saved_positions))
118 file.close()
119end
120
121-- Get cords from file
122function t.getCords()
123 local cords
124 local contents
125 if t.cordsfile == nil then
126 t.log('[ERROR] cordsfile is nil', 1)
127 t.log('[WARNING] Without a cords file persistance will fail', 2)
128 return -- Breaks from this function
129 end
130 if not fs.exists(t.cordsfile) then
131 t.log('[WARNING] t.cordsfile does not exist', 2)
132 t.log('[INFO] Creating cordsfile...', 3)
133 -- Creates cords file with 0,0,0,0 as values.
134 t.writeToFile(textutils.serialize({x = 0, y = 0, z = 0, orientation = 0}), t.cordsfile)
135 end
136 file = fs.open(t.cordsfile, 'r') -- Opens cordsfile for reading.
137 contents = file.readAll()
138 cords = textutils.unserialize(contents)
139 -- Sets coordanites
140 t.x = cords.x
141 t.y = cords.y
142 t.z = cords.z
143
144 -- Sets orientation
145 t.orientation = cords.orientation
146
147 -- Not going to return a value since i will just change the varables.
148end
149
150-- Saves coordanites to file
151local function saveCords()
152 local cords = {
153 x = t.x,
154 y = t.y,
155 z = t.z,
156 }
157 -- Testing to see if i need the temporary cords varable.
158 t.log('[DEBUG] Trying to write cords to file.', 4)
159 writeToFile(textutils.serialize({x = t.x,y = t.y, z = t,z}), t.cordsfile)
160end
161
162local function orientationToNumber(orientationStr)
163 -- Turns an orientation string into an Orientation number.
164 for i=0,#t.orientations do
165 if orientationStr == t.orientations[i] then
166 return i
167 end
168 end
169end
170
171-- Turns an orientation number into an t.orientation string.
172local function orientationToString(orientationInt)
173 -- Checks to see if orientationInt is a number
174 if type(orientationInt) ~= 'number' then
175 t.log('[ERROR] orientationInt is not a number', 1)
176 error('[ERROR] OrientationInt is not a number')
177 end
178 if orientations[orientationInt] then
179 return t.orientations[orientationInt]
180 else
181 print('[ERROR] Orientation is invalid', 1)
182 print('orientationInt = '..orientationInt)
183 error()
184 end
185end
186
187-- Turning functions
188function t.turnRight()
189 turtle.turnRight()
190 -- This "magic" math adds one to t.orientation unless t.orientation is 3, then it moves to 0.
191 -- This could also be done with an if statement but this is cleaner imo
192 t.orientation = (t.orientation + 1) % 4
193end
194
195function t.turnLeft()
196 turtle.turnLeft()
197 t.orientation = (t.orientation - 1) % 4
198end
199
200-- Looks to a direction, can be passed a string or a number
201function t.look(direction)
202 -- makes sure the value passed is valid.
203 if type(direction) == 'string' then
204 direction = orientationToNumber(direction)
205 elseif type(direction) ~= 'number' then
206 error('Direction is not a number')
207 end
208
209 -- Thanks to Incin for this bit of code :)
210 if direction == t.orientation then return end
211
212 if (direction - t.orientation) % 2 == 0 then
213 t.turnLeft()
214 t.turnLeft()
215 elseif (direction - t.orientation) % 4 == 1 then
216 t.turnRight()
217 else
218 t.turnLeft()
219 end
220end
221
222function t.forward()
223 log('[DEBUG] t.forward called', 4)
224
225 if turtle.forward() then
226 log('[DEBUG] turtle.forward() returned true, changing cords...', 4)
227 -- Change t.x and t.z cords
228 t.x = t.x + xDiff[t.orientation]
229 t.z = t.z + zDiff[t.orientation]
230 saveCords()
231 return true
232 else
233 -- If he failed to move return false and don't change the cords.
234 return false
235 end
236end
237
238function t.up()
239 t.log('[DEBUG] t.up function called', 4)
240 if turtle.up() then
241 t.y = t.y + 1
242 t.log('[DEBUG] Trying to save cords to file after going up', 4)
243 saveCords()
244 return true
245 else
246 return false
247 end
248end
249
250function t.down()
251 if turtle.down() then
252 t.y = t.y - 1
253 saveCords()
254 return true
255 else
256 return false
257 end
258end
259
260function t.digDown()
261 if turtle.digDown() then
262 t.blocks_dug = t.blocks_dug + 1
263 return true
264 else
265 return false
266 end
267end
268function t.dig()
269 if turtle.dig() then
270 t.blocks_dug = t.blocks_dug + 1
271 return true
272 else
273 return false
274 end
275end
276function t.digUp()
277 if turtle.digUp() then
278 t.blocks_dug = t.blocks_dug + 1
279 return true
280 else
281 return false
282 end
283end
284
285-- This function saves the turtles posision so it can be returned to later.
286function t.saveCurrentPos(name)
287 if type(name) ~= 'string' then
288 error('Position name must be a string.')
289 end
290
291 -- Creates a new table entry with "name" key
292 t.saved_positions[name] = {
293 x = t.x,
294 y = t.y,
295 z = t.z,
296 orientation = t.orientation
297 }
298end
299
300function t.savePosisionsToFile()
301 file = fs.open(t.savedPositions, 'w')
302 file.write(textutils.serialize(t.saved_positions))
303 file.close()
304end
305
306function t.getPos()
307 if fs.exists(t.savedPositions) then
308 file = fs.open(t.savedPositions, 'r')
309 t.saved_positions = textutils.unserialize(file.readAll())
310 file.close()
311 else
312 error('No file to get positions from.')
313 end
314end
315
316function t.gotoPos(name)
317 t.goto(t.saved_positions[name].x, t.saved_posisions[name].y, t.saved_posisions[name].z, t.saved_posisions[name].orientation)
318end
319
320-- Careful this breaks blocks.
321function t.goto(xTarget, yTarget, zTarget, orientationTarget)
322 if not xTarget or not yTarget or not zTarget or not orientationTarget then
323 t.log('Here are all the params for the goto function:', 1)
324 t.log(xTarget, yTarget, zTarget, orientationTarget, 1)
325 error('Invalid params, read log for more info.')
326 end
327 -- Moves to t.y
328 while yTarget < t.y do
329 t.digDown()
330 t.down()
331 end
332
333 while yTarget > t.y do
334 t.digUp()
335 t.up()
336 end
337
338 -- Turns to correct t.orientation then moves forward until its at the right t.x cord
339 if xTarget < t.x then
340 t.look('west')
341 while xTarget < t.x do
342 t.dig()
343 t.forward()
344 end
345 end
346
347 if xTarget > t.x then
348 t.look('east')
349 while xTarget > t.x do
350 t.dig()
351 t.forward()
352 end
353 end
354
355 -- Turns to correct t.orientation then moves forward until its at the right t.z cord
356 if zTarget < t.z then
357 t.look('north')
358 while zTarget < t.z do
359 t.dig()
360 t.forward()
361 end
362 end
363 if zTarget > t.z then
364 t.look('south')
365 while zTarget > t.z do
366 t.dig()
367 t.forward()
368 end
369 end
370 -- Look to correct orientation
371 t.look(orientationTarget)
372end
373-- Because its not defined at the top
374t.getCords()
375return t