· 4 years ago · Sep 06, 2021, 03:16 PM
1-- Misc Useful Functions
2-- Required by most other programs
3-- <Flexico64@gmail.com>
4
5-------------------------------------------
6-- |¯¯] || |¯¯] \\// /\ |¯\ [¯¯] --
7-- | ] ||_ | ] >< | | | / ][ --
8-- || |__] |__] //\\ |||| || [__] --
9-------------------------------------------
10
11local log_file = "log.txt"
12local options_file = "flex_options.cfg"
13
14-- Defaults; can be changed in config file
15local modem_channel = 6464
16local name_color
17if term.isColor() then
18 name_color = "yellow"
19else
20 name_color = "lightGray"
21end --if/else
22
23
24function getPeripheral(name)
25 local x,sides
26 sides = { "top", "bottom", "left",
27 "right", "front", "back" }
28 local periph = {}
29 for x=1,#sides do
30 if peripheral.getType(sides[x]) == name then
31 periph[#periph+1] = sides[x]
32 end --if
33 end --for
34 return periph
35end --function
36
37
38local modem
39local hasModem = false
40local x = getPeripheral("modem")
41if #x > 0 then
42 hasModem = true
43 modem = peripheral.wrap(x[1])
44 --modem.open(modem_channel)
45end --if
46
47function modemOff()
48 if hasModem then
49 modem.close(modem_channel)
50 end --if
51end --function
52
53
54local file
55if not fs.exists(log_file) then
56 file = fs.open(log_file,"w")
57 file.close()
58end --if
59
60
61
62function optionsExport()
63 if fs.exists(options_file) then
64 fs.delete(options_file)
65 end
66 local file
67 while file == nil do
68 file = fs.open(options_file,"w")
69 end
70 file.writeLine("# Flex API Options File #\n")
71 file.writeLine("modem_channel="
72 ..tostring(modem_channel))
73 file.writeLine("name_color="..name_color.."\n")
74 file.close()
75 return true
76end --function
77
78
79function optionsImport()
80 if not fs.exists(options_file) then
81 return false
82 end
83 local file
84 while file == nil do
85 file = fs.open(options_file, "r")
86 end
87
88 local x = file.readLine()
89 while x ~= nil do
90 if string.find(x,"modem_channel")==1 then
91 modem_channel = tonumber(string.sub(x,15))
92 elseif string.find(x,"name_color")==1 then
93 name_color = string.sub(x,12)
94 end --if/else
95 x = file.readLine()
96 end --while
97
98 file.close()
99 return true
100end --function
101
102
103if not optionsImport() then
104 optionsExport()
105end --if
106
107
108
109--==============================--
110
111
112-- Inventory Condense
113function condense(n)
114 if n == nil then n = 1 end
115 n = math.floor(n)
116 if n < 1 or n > 16 then
117 n = 1
118 end --if
119
120 local x,y,slot
121 slot = turtle.getSelectedSlot()
122 for x=n+1,16 do
123 if turtle.getItemCount(x) > 0 then
124
125 for y=n,x-1 do
126 if turtle.getItemCount(y) == 0 or
127 turtle.getItemDetail(x)["name"] ==
128 turtle.getItemDetail(y)["name"] and
129 turtle.getItemSpace(y) > 0 then
130 turtle.select(x)
131 turtle.transferTo(y)
132 end --if
133 if turtle.getItemCount(x) == 0 then
134 break
135 end --if
136 end --for
137
138 end --if
139 end --for
140 turtle.select(slot)
141end --function
142
143
144-- Round n to p decimal places
145function round(n,p)
146 if p == nil then p = 0 end
147 n = n*math.pow(10,p)
148 local m = n - math.floor(n)
149 if m < 0.5 then
150 return math.floor(n) / math.pow(10,p)
151 else
152 return math.ceil(n) / math.pow(10,p)
153 end --if/else
154end --function
155
156
157-- Number to String
158-- Optionally a max length if not an integer
159function tostr(num,len)
160 num = tostring(num)
161 local sci = ""
162
163 local e = string.find(num,"e")
164 if e ~= nil then
165 -- Separate exponent from number
166 sci = string.sub(num,e,-1)
167 num = string.sub(num,1,e-1)
168 end --if
169
170 if string.find(num,"%.") ~= nil then
171 -- Remove extra zeroes from decimal
172 while string.sub(num,string.len(num)) == "0" do
173 num = string.sub(num,1,string.len(num)-1)..""
174 end --while
175 end --if
176
177 if string.sub(num,-1) == "." then
178 -- If all trailing zeroes are gone, erase decimal point
179 num = string.sub(num,1,-2)..""
180 end --if
181
182 if len == nil then
183 -- If no max length specified
184 return num..sci..""
185 end --if
186
187 while string.len(num) + string.len(sci) > len do
188 -- If too long, cut off a decimal digit
189 num = string.sub(num,1,-2)..""
190 end --while
191
192 return num..sci..""
193
194end --function
195
196
197-- Evaluate Expression
198function eval(expression)
199 local solution, err = loadstring(
200 "return "..expression)
201 if err then error(err,2) end
202 local sol = pcall(solution)
203 if not sol then
204 error("Invalid Expression",2)
205 end
206 return solution()
207end --function
208
209
210-- Press any Key
211function getKey()
212 local event, key_code = os.pullEvent("key")
213 return key_code
214end --function
215function keyPress() return getKey() end
216
217
218
219
220-------------------------------
221-- [¯¯] |¯¯] \\// [¯¯] --
222-- || | ] >< || --
223-- || |__] //\\ || --
224-------------------------------
225-- /¯] /¯\ || /¯\ |¯\ --
226-- | [ | O | ||_ | O | | / --
227-- \_] \_/ |__] \_/ | \ --
228-------------------------------
229
230hexchars = "0123456789ABCDEF"
231
232-- Start with named value, get hex char
233function getHex(x)
234 if x == nil then
235 error("Number expected, got nil", 2)
236 end
237 x = round(math.log(x)/math.log(2))
238 if x < 0 or x > 15 then
239 error("Invalid color number", 2)
240 end --if
241 return string.sub(hexchars,x+1,x+1)
242end --function
243
244-- Start with hex char, get named value
245function getVal(x)
246 local z = string.find(hexchars,x)
247 if z == nil then return nil end
248 return math.pow(2,z-1)
249end --function
250
251local send_depth, print_depth = 0, 0
252
253
254
255-------------------------------
256-- Multicolor Print Function --
257-------------------------------
258
259function printColors(message,textColor)
260 local x,y,z,t,skip,margin
261 local xmax,ymax = term.getSize()
262 local oldColor = term.getTextColor()
263 if message == nil then
264 message = "nil"
265 end --if
266 if textColor == nil then
267 textColor = oldColor
268 end --if
269
270 margin = ""
271 for x=1,print_depth do
272 margin = margin.." "
273 end --for
274
275 if type(message) == "table" then
276 if print_depth == 0 then
277 printColors("#0{")
278 end --if
279 print_depth = print_depth + 1
280
281 for x,y in pairs(message) do
282 if type(y) == "table" then
283 printColors(margin.." "..tostring(x).." #0= {",textColor)
284 printColors(y,textColor)
285 else
286 printColors(margin.." "..tostring(x).." #0= #"..
287 getHex(textColor)..tostring(y),textColor)
288 end --if/else
289 end --for
290
291 print_depth = print_depth - 1
292 printColors(margin.."#0}")
293 return
294
295 end --if
296
297 if type(textColor) == "number" then
298 message = "#"..getHex(textColor)
299 ..tostring(message)
300 end --if
301
302 for t=1,string.len(message) do
303
304 skip = false
305 while string.sub(message,t,t) == "#" and
306 not skip do
307
308 -- Found legit "#"
309 if string.sub(message,t+1,t+1) == "#" then
310 message = string.sub(message,1,t)..
311 string.sub(message,t+2)..""
312 skip = true
313
314 else
315 textColor = getVal(string.sub(message,t+1,t+1))
316
317 if textColor == nil then
318 textColor = colors.white
319 end --if
320
321 -- This bit clears out # escapes
322 if t == 1 then
323 message = string.sub(message,3)..""
324 elseif t < string.len(message) then
325 message = string.sub(message,1,t-1)..
326 string.sub(message,t+2)..""
327 elseif t == string.len(message) then
328 message = string.sub(message,1,t-1)..""
329 end --if/else
330
331 end --if
332
333 if t > string.len(message) then
334 break
335 end --if
336
337 end --while (is escape char)
338
339 if t > string.len(message) then
340 break
341 end --if
342
343 -- Actually Print Character
344 x,y = term.getCursorPos()
345 term.setTextColor(textColor)
346
347 if textColor == colors.gray then
348 --term.setBackgroundColor(colors.lightGray)
349
350 elseif textColor == colors.black then
351 term.setBackgroundColor(colors.lightGray)
352
353 end --if/else
354 term.write(string.sub(message,t,t))
355 term.setBackgroundColor(colors.black)
356
357 if t >= string.len(message) then
358 break
359 end --if
360
361 -- Loop Around to Next Row
362 xmax,ymax = term.getSize()
363 if string.sub(message,t,t) == "\n" or x >= xmax then
364 x = 1
365 if y < ymax-1 then
366 y = y + 1
367 else
368 print("")
369 end --if/else
370 else
371 x = x + 1
372 end --if/else
373 term.setCursorPos(x,y)
374
375 end --for
376
377 term.setTextColor(oldColor)
378 print("")
379
380end --function
381
382
383
384------------------------------
385-- Print/Broadcast Function --
386------------------------------
387
388function send(message,textColor)
389 local x,y,z,id,nameColor
390 local oldColor = term.getTextColor()
391
392 local margin = ""
393 for x=1,send_depth do
394 margin = margin.." "
395 end --for
396
397 if type(message) == "table" then
398 if send_depth == 0 then
399 send("#0{")
400 end --if
401 send_depth = send_depth + 1
402
403 for x,y in pairs(message) do
404 if type(y) == "table" then
405 send(margin.." "..tostring(x).." #0= {",textColor)
406 send(y,textColor)
407 else
408 send(margin.." "..tostring(x).." #0= #"
409 ..getHex(textColor)..tostring(y),textColor)
410 end --if/else
411 end --for
412
413 send_depth = send_depth - 1
414 send(margin.."#0}")
415 return
416
417 end --if
418
419
420 if message == nil then
421 message = "nil"
422 end --if
423
424 message = tostring(message)
425 if textColor == nil then
426 textColor = colors.white
427 end --if
428 nameColor = eval("colors."..name_color)
429
430 printColors(message,textColor)
431
432 file = fs.open(log_file,"a")
433 file.writeLine(message)
434 file.close()
435
436 if hasModem then
437 id = "#"..getHex(nameColor)..
438 tostring(os.getComputerID()).."#0"
439
440 if os.getComputerLabel() ~= nil then
441 id = id.."|#"..getHex(nameColor)..
442 os.getComputerLabel().."#0"
443 end --if
444
445 id = id..": #"..getHex(textColor)..
446 message..""
447
448 modem.transmit(modem_channel,
449 modem_channel+1,id)
450 sleep(0.1)
451 end --if (hasModem)
452
453 term.setTextColor(oldColor)
454 sleep(0.05)
455end --function (print/broadcast)
456
457
458--================================--
459
460
461args = {...}
462
463if args[1]=="color" or args[1]=="colors" then
464 z = ""
465 for x=0,15 do
466 y = string.sub(hexchars,x+1,x+1)..""
467 z = z.."#"..y..y.."#0 "
468 end --for
469 printColors(z)
470 return
471
472elseif args[1] == "edit" then
473 shell.run("edit "..options_file)
474 optionsImport()
475
476end --if/else
477
478
479
480-------------------------------------------
481-- /¯¯] |¯¯] [¯¯] |¯\ /\ [¯¯] /\ --
482--| [¯| | ] || | | | | || | | --
483-- \__| |__] || |_/ |||| || |||| --
484-------------------------------------------
485
486
487function getBlock(dir)
488 dir = dir or "fwd"
489 local block,meta
490
491 if dir=="fwd" then
492 block,meta = turtle.inspect()
493 elseif dir=="up" then
494 block,meta = turtle.inspectUp()
495 elseif dir=="down" then
496 block,meta = turtle.inspectDown()
497 end
498
499 if block then
500 block = meta["name"]
501 meta = meta["metadata"]
502 return block,meta
503 else
504 return "minecraft:air",nil
505 end --if
506
507end --function
508
509function getBlockUp()
510 return getBlock("up")
511end
512
513function getBlockDown()
514 return getBlock("down")
515end
516
517
518function isBlock(key,dir)
519 if type(key) == "string" then
520 key = { key }
521 end --if
522 if type(key) ~= "table" then
523 error("Expected string or table, got "
524 ..type(key), 2)
525 return false
526 end --if
527
528 local block = getBlock(dir)
529 local x
530 for x=1,#key do
531
532 if string.find(key[x],":") ~= nil then
533 if block == key[x] then
534 return true
535 end --if
536
537 else
538 if string.find(block,key[x]) ~= nil then
539 return true
540 end --if
541
542 end --if/else
543 end --for
544
545 return false
546end --function
547
548function isBlockUp(key)
549 return isBlock(key, "up")
550end
551
552function isBlockDown(key)
553 return isBlock(key, "down")
554end
555
556
557
558local fluid = { "air", "water", "lava",
559 "acid", "blood", "poison" }
560
561function isFluid(dir)
562 return isBlock(fluid, "fwd")
563end
564
565function isFluidUp()
566 return isBlock(fluid, "up")
567end
568
569function isFluidDown()
570 return isBlock(fluid, "down")
571end
572
573
574
575function isItem(key,slot)
576 if key == nil then return false end
577
578 local slot_old = turtle.getSelectedSlot()
579 if type(slot) ~= "number" then
580 slot = slot_old
581 end --if
582
583 if type(key) == "table" then
584 local x
585 for x=1,#key do
586 if isItem(key[x],slot) then
587 return true
588 end --if
589 end --for
590 return false
591 end --if
592
593 if turtle.getItemCount(slot) == 0 then
594 return false
595 end --if
596
597 local name = turtle.getItemDetail(slot)["name"]
598
599 return ( string.find(name,key) ~= nil )
600end --function
601
602
603