DigsoftFixes/flex.lua
2024-09-14 16:14:19 -04:00

603 lines
12 KiB
Lua
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- Misc Useful Functions
-- Required by most other programs
-- <Flexico64@gmail.com>
-------------------------------------------
-- |¯¯] ||   |¯¯] \\//     /\  |¯\ [¯¯]  --
-- | ]  ||_  | ]   ><     |  | | /  ][   --
-- ||   |__] |__] //\\    |||| ||  [__]  --
-------------------------------------------
local log_file = "log.txt"
local options_file = "flex_options.cfg"
-- Defaults; can be changed in config file
local modem_channel = 6464
local name_color
if term.isColor() then
name_color = "yellow"
else
name_color = "lightGray"
end --if/else
function getPeripheral(name)
local x,sides
sides = { "top", "bottom", "left",
"right", "front", "back" }
local periph = {}
for x=1,#sides do
if peripheral.getType(sides[x]) == name then
periph[#periph+1] = sides[x]
end --if
end --for
return periph
end --function
local modem
local hasModem = false
local x = getPeripheral("modem")
if #x > 0 then
hasModem = true
modem = peripheral.wrap(x[1])
modem.open(modem_channel)
end --if
function modemOff()
local x = getPeripheral("modem")
if #x > 0 then
modem.close(modem_channel)
end --if
end --function
local file
if not fs.exists(log_file) then
file = fs.open(log_file,"w")
file.close()
end --if
function optionsExport()
if fs.exists(options_file) then
fs.delete(options_file)
end
local file
while file == nil do
file = fs.open(options_file,"w")
end
file.writeLine("# Flex API Options File #\n")
file.writeLine("modem_channel="
..tostring(modem_channel))
file.writeLine("name_color="..name_color.."\n")
file.close()
return true
end --function
function optionsImport()
if not fs.exists(options_file) then
return false
end
local file
while file == nil do
file = fs.open(options_file, "r")
end
local x = file.readLine()
while x ~= nil do
if string.find(x,"modem_channel")==1 then
modem_channel = tonumber(string.sub(x,15))
elseif string.find(x,"name_color")==1 then
name_color = string.sub(x,12)
end --if/else
x = file.readLine()
end --while
file.close()
return true
end --function
if not optionsImport() then
optionsExport()
end --if
--==============================--
-- Inventory Condense
function condense(n)
if n == nil then n = 1 end
n = math.floor(n)
if n < 1 or n > 16 then
n = 1
end --if
local x,y,slot
slot = turtle.getSelectedSlot()
for x=n+1,16 do
if turtle.getItemCount(x) > 0 then
for y=n,x-1 do
if turtle.getItemCount(y) == 0 or
turtle.getItemDetail(x)["name"] ==
turtle.getItemDetail(y)["name"] and
turtle.getItemSpace(y) > 0 then
turtle.select(x)
turtle.transferTo(y)
end --if
if turtle.getItemCount(x) == 0 then
break
end --if
end --for
end --if
end --for
turtle.select(slot)
end --function
-- Round n to p decimal places
function round(n,p)
if p == nil then p = 0 end
n = n*math.pow(10,p)
local m = n - math.floor(n)
if m < 0.5 then
return math.floor(n) / math.pow(10,p)
else
return math.ceil(n) / math.pow(10,p)
end --if/else
end --function
-- Number to String
-- Optionally a max length if not an integer
function tostr(num,len)
num = tostring(num)
local sci = ""
local e = string.find(num,"e")
if e ~= nil then
-- Separate exponent from number
sci = string.sub(num,e,-1)
num = string.sub(num,1,e-1)
end --if
if string.find(num,"%.") ~= nil then
-- Remove extra zeroes from decimal
while string.sub(num,string.len(num)) == "0" do
num = string.sub(num,1,string.len(num)-1)..""
end --while
end --if
if string.sub(num,-1) == "." then
-- If all trailing zeroes are gone, erase decimal point
num = string.sub(num,1,-2)..""
end --if
if len == nil then
-- If no max length specified
return num..sci..""
end --if
while string.len(num) + string.len(sci) > len do
-- If too long, cut off a decimal digit
num = string.sub(num,1,-2)..""
end --while
return num..sci..""
end --function
-- Evaluate Expression
function eval(expression)
local solution, err = loadstring(
"return "..expression)
if err then error(err,2) end
local sol = pcall(solution)
if not sol then
error("Invalid Expression",2)
end
return solution()
end --function
-- Press any Key
function getKey()
local event, key_code = os.pullEvent("key")
return key_code
end --function
function keyPress() return getKey() end
-------------------------------
--    [¯¯] |¯¯] \\// [¯¯]  --
--     ||  | ]   ><   ||   --
--     ||  |__] //\\  ||   --
-------------------------------
--  /¯]  /¯\  ||    /¯\  |¯\ --
-- | [  | O | ||_  | O | | / --
--  \_]  \_/  |__]  \_/  | \ --
-------------------------------
hexchars = "0123456789ABCDEF"
-- Start with named value, get hex char
function getHex(x)
if x == nil then
error("Number expected, got nil", 2)
end
x = round(math.log(x)/math.log(2))
if x < 0 or x > 15 then
error("Invalid color number", 2)
end --if
return string.sub(hexchars,x+1,x+1)
end --function
-- Start with hex char, get named value
function getVal(x)
local z = string.find(hexchars,x)
if z == nil then return nil end
return math.pow(2,z-1)
end --function
local send_depth, print_depth = 0, 0
-------------------------------
-- Multicolor Print Function --
-------------------------------
function printColors(message,textColor)
local x,y,z,t,skip,margin
local xmax,ymax = term.getSize()
local oldColor = term.getTextColor()
if textColor == nil then
textColor = oldColor
else
end --if
margin = ""
for x=1,print_depth do
margin = margin.." "
end --for
if type(message) == "table" then
if print_depth == 0 then
printColors("#0{")
end --if
print_depth = print_depth + 1
for x,y in pairs(message) do
if type(y) == "table" then
printColors(margin.." "..tostring(x).." #0= {",textColor)
printColors(y,textColor)
else
printColors(margin.." "..tostring(x).." #0= #"..
getHex(textColor)..tostring(y),textColor)
end --if/else
end --for
print_depth = print_depth - 1
printColors(margin.."#0}")
return
end --if
if type(textColor) == "number" then
message = "#"..getHex(textColor)
..tostring(message)
end --if
for t=1,string.len(message) do
skip = false
while string.sub(message,t,t) == "#" and
not skip do
-- Found legit "#"
if string.sub(message,t+1,t+1) == "#" then
message = string.sub(message,1,t)..
string.sub(message,t+2)..""
skip = true
else
textColor = getVal(string.sub(message,t+1,t+1))
if textColor == nil then
textColor = colors.white
end --if
-- This bit clears out # escapes
if t == 1 then
message = string.sub(message,3)..""
elseif t < string.len(message) then
message = string.sub(message,1,t-1)..
string.sub(message,t+2)..""
elseif t == string.len(message) then
message = string.sub(message,1,t-1)..""
end --if/else
end --if
if t > string.len(message) then
break
end --if
end --while (is escape char)
if t > string.len(message) then
break
end --if
-- Actually Print Character
x,y = term.getCursorPos()
term.setTextColor(textColor)
if textColor == colors.gray then
--term.setBackgroundColor(colors.lightGray)
elseif textColor == colors.black then
term.setBackgroundColor(colors.lightGray)
end --if/else
term.write(string.sub(message,t,t))
term.setBackgroundColor(colors.black)
if t >= string.len(message) then
break
end --if
-- Loop Around to Next Row
xmax,ymax = term.getSize()
if string.sub(message,t,t) == "\n" or x >= xmax then
x = 1
if y < ymax-1 then
y = y + 1
else
print("")
end --if/else
else
x = x + 1
end --if/else
term.setCursorPos(x,y)
end --for
term.setTextColor(oldColor)
print("")
end --function
------------------------------
-- Print/Broadcast Function --
------------------------------
function send(message,textColor)
local x,y,z,id,nameColor
local oldColor = term.getTextColor()
local margin = ""
for x=1,send_depth do
margin = margin.." "
end --for
if type(message) == "table" then
if send_depth == 0 then
send("#0{")
end --if
send_depth = send_depth + 1
for x,y in pairs(message) do
if type(y) == "table" then
send(margin.." "..tostring(x).." #0= {",textColor)
send(y,textColor)
else
send(margin.." "..tostring(x).." #0= #"
..getHex(textColor)..tostring(y),textColor)
end --if/else
end --for
send_depth = send_depth - 1
send(margin.."#0}")
return
end --if
if message == nil then
message = "nil"
end --if
message = tostring(message)
if textColor == nil then
textColor = colors.white
end --if
nameColor = eval("colors."..name_color)
printColors(message)
file = fs.open(log_file,"a")
file.writeLine(message)
file.close()
if hasModem then
id = "#"..getHex(nameColor)..
tostring(os.getComputerID()).."#0"
if os.getComputerLabel() ~= nil then
id = id.."|#"..getHex(nameColor)..
os.getComputerLabel().."#0"
end --if
id = id..": #"..getHex(textColor)..
message..""
modem.transmit(modem_channel,
modem_channel+1,id)
sleep(0.1)
end --if (hasModem)
term.setTextColor(oldColor)
sleep(0.02)
end --function (print/broadcast)
--================================--
args = {...}
if args[1]=="color" or args[1]=="colors" then
z = ""
for x=0,15 do
y = string.sub(hexchars,x+1,x+1)..""
z = z.."#"..y..y.."#0 "
end --for
printColors(z)
return
elseif args[1] == "edit" then
shell.run("edit "..options_file)
optionsImport()
end --if/else
-------------------------------------------
-- /¯¯] |¯¯] [¯¯]    |¯\   /\  [¯¯]  /\  --
--| [¯| | ]   ||     |  | |  |  ||  |  | --
-- \__| |__]  ||     |_/  ||||  ||  |||| --
-------------------------------------------
function getBlock(dir)
dir = dir or "fwd"
local block,meta
if dir=="fwd" then
block,meta = turtle.inspect()
elseif dir=="up" then
block,meta = turtle.inspectUp()
elseif dir=="down" then
block,meta = turtle.inspectDown()
end
if block then
block = meta["name"]
meta = meta["metadata"]
return block,meta
else
return "minecraft:air",nil
end --if
end --function
function getBlockUp()
return getBlock("up")
end
function getBlockDown()
return getBlock("down")
end
function isBlock(key,dir)
if type(key) == "string" then
key = { key }
end --if
if type(key) ~= "table" then
error("Expected string or table, got "
..type(key), 2)
return false
end --if
local block = getBlock(dir)
local x
for x=1,#key do
if string.find(key[x],":") ~= nil then
if block == key[x] then
return true
end --if
else
if string.find(block,key[x]) ~= nil then
return true
end --if
end --if/else
end --for
return false
end --function
function isBlockUp(key)
return isBlock(key, "up")
end
function isBlockDown(key)
return isBlock(key, "down")
end
local fluid = { "air", "water", "lava",
"acid", "blood", "poison" }
function isFluid(dir)
return isBlock(fluid, "fwd")
end
function isFluidUp()
return isBlock(fluid, "up")
end
function isFluidDown()
return isBlock(fluid, "down")
end
function isItem(key,slot)
if key == nil then return false end
local slot_old = turtle.getSelectedSlot()
if type(slot) ~= "number" then
slot = slot_old
end --if
if type(key) == "table" then
local x
for x=1,#key do
if isItem(key[x],slot) then
return true
end --if
end --for
return false
end --if
if turtle.getItemCount(slot) == 0 then
return false
end --if
local name = turtle.getItemDetail(slot)["name"]
return ( string.find(name,key) ~= nil )
end --function