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