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