Advertisement
theTANCO

LibAppend.lua

Jun 27th, 2022 (edited)
996
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 21.76 KB | None | 0 0
  1. -- This is an API to add much needed functions to the global libraries in
  2. --   ComputerCraft Lua. This code will only work in ComputerCraft.
  3. -- To get this program, run the following command:
  4. --   pastebin get Rac6Jxjg "/API/LibAppend.lua"
  5. -- This file must be saved in "/API/" in order for programs that use it to
  6. --   function properly.
  7. -- Add it to your program by including 'dofile("/API/LibAppend.lua")' or
  8. --   'require("/API/LibAppend")' at the top of your code.
  9.  
  10. -- This is so 'require' can be used, even if APIs are loaded with 'dofile'.
  11. require = dofile("/rom/modules/main/cc/require.lua").make(
  12.     setmetatable({}, {__index = _ENV}),
  13.     "/"
  14. )
  15.  
  16. -- This loads the expect module into your program. I don't know why this isn't
  17. --   loaded into the global table by default.
  18. -- expect.expect(arg, value, ...) -> Throws an error if the 'value' isn't any of
  19. --   the given types. You can enter multiple type arguments after 'value'.
  20. -- expect.field(table, index, ...) -> Throws an error a property of a table
  21. --   isn't any of the given types. 'index' must be a key string and not an index
  22. --   number. You can enter multiple type arguments after 'index'.
  23. -- expect.range(num, min, max) -> Thrown an error if a number is not between two
  24. --   values, inclusive.
  25. expect = require("cc.expect")
  26.  
  27. -- Gets the "name" of the specified color.
  28. colors.name = function(color)
  29.     local colorList = {
  30.         ["0"] = "white",
  31.         ["1"] = "orange",
  32.         ["2"] = "magenta",
  33.         ["3"] = "lightBlue",
  34.         ["4"] = "yellow",
  35.         ["5"] = "lime",
  36.         ["6"] = "pink",
  37.         ["7"] = "gray",
  38.         ["8"] = "lightGray",
  39.         ["9"] = "cyan",
  40.         ["a"] = "purple",
  41.         ["b"] = "blue",
  42.         ["c"] = "brown",
  43.         ["d"] = "green",
  44.         ["e"] = "red",
  45.         ["f"] = "black"
  46.     }
  47.     return colorList[colors.toBlit(expect.expect(1, color, "number"))]
  48. end
  49.  
  50. -- Non-American version of colors.name().
  51. colours.name = function(colour)
  52.     local name = colors.name(colour)
  53.     if name == "gray" or name == "lightGray" then name = name:gsub("ray", "rey") end
  54.     return name
  55. end
  56.  
  57. math.round = function(n)
  58.     return math.floor(n+0.5)
  59. end
  60.  
  61. -- Correctly capitalize the first letter in each sentence in a string.
  62. string.cap = function(s)
  63.     for a = 1, s:len() do
  64.         if a == 1 or s:sub(a-2, a-1) == ". " or s:sub(a-2, a-1) == "? " or s:sub(a-2, a-1) == "! " then
  65.             s = s:sub(1, a-1)..s:sub(a, a):upper()..s:sub(a+1, s:len())
  66.         end
  67.     end
  68.     return s
  69. end
  70.  
  71. -- Capitalizes the first letter in all words.
  72. string.capAll = function(s)
  73.     for a = 1, s:len() do
  74.         if a == 1 or s:sub(a-1, a-1) == " " then
  75.             s = s:sub(1, a-1)..s:sub(a, a):upper()..s:sub(a+1, s:len())
  76.         end
  77.     end
  78.     return s
  79. end
  80.  
  81. string.concat = function(...)
  82.     str = ""
  83.     for _, v in ipairs({...}) do
  84.         str = str .. tostring(v)
  85.     end
  86.     return str
  87. end
  88.  
  89. -- Easily add padding to a string.
  90. -- 'str' is the string to add padding to.
  91. -- 'pad' is the string to use as padding.
  92. -- 's' adds padding to the start of str if the length of str is less than s.
  93. -- 'e' adds padding to the end of str if the length of str is less than e after adding s padding.
  94. string.pad = function(str, pad, s, e)
  95.     str, pad = tostring(str), tostring(pad)
  96.     s, e = tonumber(s) or 0, tonumber(e) or 0
  97.     str = pad:rep(s-str:len()) .. str
  98.     str = str .. pad:rep(e-str:len())
  99.     return str
  100. end
  101.  
  102. -- A single function option for swapping the values of two elements in a table.
  103. -- 't' is the table you want to change.
  104. -- 'i1' and 'i2' are the keys for the elements being swapped.
  105. -- The value of 't[i1]' is set to 't[i2]'.
  106. -- The value of 't[i2]' is set to 't[i1]'.
  107. table.swap = function(t, i1, i2)
  108.     expect.expect(1, t, "table")
  109.     expect.expect(2, i1, "number", "string")
  110.     expect.expect(3, i2, "number", "string")
  111.     e = t[i1]
  112.     t[i1] = t[i2]
  113.     t[i2] = e
  114. end
  115.  
  116. -- Moves elements up or down through an ordered list.
  117. -- 't' is the table you want to change.
  118. -- 'i' is the index of the element being moved.
  119. -- 'n' is how many places the element will move.
  120. -- Only index numbers can be used for i. Strings will not work.
  121. -- To move elements with strings as keys, use 'table.swap'.
  122. table.shift = function(t, i, n)
  123.     expect.expect(1, t, "table")
  124.     expect.expect(2, i, "number")
  125.     expect.expect(3, n, "number")
  126.     repeat
  127.         if n < 0 then
  128.             table.swap(t, i, i-1)
  129.             i = i - 1
  130.         elseif n > 0 then
  131.             table.swap(t, i, i+1)
  132.             i = i + 1
  133.         end
  134.     until i == n
  135.     return i
  136. end
  137.  
  138. -- A combination of term.blit and print.
  139. term.printBlit = function(s, t, b)
  140.     expect.expect(1, s, "string")
  141.     expect.expect(2, t, "string")
  142.     expect.expect(3, b, "string")
  143.     if s:len() ~= t:len() or s:len() ~= b:len() then
  144.         error("Arguments must be the same length", 2)
  145.     end
  146.     term.blit(s, t, b)
  147.     print()
  148. end
  149.  
  150. -- A combination of texutils.slowWrite and term.blit.
  151. textutils.slowBlit = function(s, t, b, d)
  152.     d = d or 20
  153.     expect.expect(1, s, "string")
  154.     expect.expect(2, t, "string")
  155.     expect.expect(3, b, "string")
  156.     if string.len(s) ~= string.len(t) or string.len(s) ~= string.len(b) or string.len(t) ~= string.len(b) then
  157.         error("Arguments #1-3 must be the same length ("..string.len(s)..", "..string.len(t)..", "..string.len(b)..")", 2)
  158.     end
  159.     expect.expect(4, d, "number")
  160.     if d <= 0 then
  161.         error("Text speed must be greater than 0", 2)
  162.     end
  163.  
  164.     local lastSpace = 0
  165.     local lastNL = 0
  166.     local xPos, yPos = term.getCursorPos()
  167.     local xSize, ySize = term.getSize()
  168.     for i = 1, s:len() do
  169.         if s:sub(i, i) == " " then
  170.             lastSpace = i
  171.         end
  172.         if s:sub(i, i) == "\n" then
  173.             lastNL = i
  174.             lastSpace = i
  175.         end
  176.         if xPos+i-lastNL-1 > xSize then
  177.             s = s:sub(1, lastSpace-1).."\n"..s:sub(lastSpace+1, s:len())
  178.             lastNL = lastSpace
  179.             xPos = 1
  180.         end
  181.     end
  182.  
  183.     local currentTextColor = term.getTextColor()
  184.     local currentBackgroundColor = term.getBackgroundColor()
  185.  
  186.     for i = 1, s:len() do
  187.         sleep(1/d)
  188.         term.setTextColor(2^tonumber(t:sub(i, i), 16))
  189.         term.setBackgroundColor(2^tonumber(b:sub(i, i), 16))
  190.         write(s:sub(i, i))
  191.     end
  192.     term.setTextColor(currentTextColor)
  193.     term.setBackgroundColor(currentBackgroundColor)
  194. end
  195.  
  196. -- 'buffer = doubleBuffer.new()' creates double frame buffers and redirects the
  197. --   term to the first buffer.
  198. -- 'buffer.swap()' redirects the from the current buffer to the other.
  199. -- 'buffer.resize()' resizes the buffers if the parent term size has changed.
  200. -- 'buffer.parent()' returns the parent term.
  201. -- 'buffer.reset()' redirects back to the parent term.
  202. doubleBuffer = {}
  203. doubleBuffer.new = function(parent)
  204.     local oldTerm = expect.expect(1, parent, "table", "nil") or term.current()
  205.     for k, v in pairs(term.native()) do
  206.         if type(k) == "string" and type(v) == "function"
  207.         and type(oldTerm[k]) ~= "function" then
  208.             error("Redirect object is missing method " .. k .. ".", 2)
  209.         end
  210.     end
  211.     local buffer = {
  212.         [0] = window.create(oldTerm, 1, 1, 1, 1),
  213.         [1] = window.create(oldTerm, 1, 1, 1, 1)
  214.     }
  215.     local win = 1
  216.  
  217.     swap = function()
  218.         buffer[win].setVisible(true)
  219.         win = 1 - win
  220.         buffer[win].setVisible(false)
  221.         return term.redirect(buffer[win])
  222.     end
  223.  
  224.     resize = function()
  225.         local xSize, ySize = term.getSize()
  226.         buffer[0].reposition(1, 1, xSize, ySize)
  227.         buffer[1].reposition(1, 1, xSize, ySize)
  228.         return xSize, ySize
  229.     end
  230.  
  231.     parent = function()
  232.         return oldTerm
  233.     end
  234.  
  235.     reset = function()
  236.         return term.redirect(oldTerm)
  237.     end
  238.  
  239.     resize()
  240.     swap()
  241.     return {
  242.         swap = swap,
  243.         resize = resize,
  244.         parent = parent,
  245.         reset = reset
  246.     }
  247. end
  248.  
  249. -- Converts decimial number to another base (binary, hexadecimal, etc.)
  250. tobase = function(n, b)
  251.     local code = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" -- 2 - 36 values per digit
  252.     local v = ""
  253.     expect.expect(1, n, "number")
  254.     expect.expect(2, b, "number")
  255.     repeat
  256.         v = code:sub(n%b+1, n%b+1) .. v
  257.         n = math.floor(n/b)
  258.     until n <= 0
  259.     return v
  260. end
  261.  
  262. -- This is the vector api completely rewritten to include 2D and 4D vectors, as
  263. -- well as error messages that make it easier to debug.
  264. -- A 2-dimensional vector with 'x' and 'y' values.
  265. -- A 3-dimensional vector with 'x', 'y' and 'z' values.
  266. -- A 4-dimensional vector with 'x', 'y', 'z', and 'w' values.
  267. vector = (function()
  268.     local vect = {}
  269.     local vectors = {[2] = {}, [3] = {}, [4] = {}}
  270.     local checkValue = {}
  271.  
  272.     local err = function(v, t, e)
  273.         if type(v) ~= t then error(e, 5) end
  274.     end
  275.     local checkVector = function(o, d)
  276.         err(o, "table", "expected second operand to be a table (" .. d .. "D vector), got " .. type(o))
  277.     end
  278.     local checkField = function(n, m)
  279.         err(n, "number", "expected '" .. m .. "' of second operand to be a number, got " .. type(n))
  280.     end
  281.     local checkNumber = function(n)
  282.         err(n, "number", "expected second operand to be a number, got " .. type(n))
  283.     end
  284.  
  285.     -- Checks operand values for errors.
  286.     checkValue[2] = function(o)
  287.         checkVector(o, 2)
  288.         checkField(o.x, 'x')
  289.         checkField(o.y, 'y')
  290.     end
  291.     checkValue[3] = function(o)
  292.         checkVector(o, 3)
  293.         checkField(o.x, 'x')
  294.         checkField(o.y, 'y')
  295.         checkField(o.z, 'z')
  296.     end
  297.     checkValue[4] = function(o)
  298.         checkVector(o, 4)
  299.         checkField(o.x, 'x')
  300.         checkField(o.y, 'y')
  301.         checkField(o.z, 'z')
  302.         checkField(o.w, 'w')
  303.     end
  304.  
  305.     -- Adds two vectors together.
  306.     vectors[2].add = function(self, o)
  307.         checkValue[2](o)
  308.         return vect.new(
  309.             self.x + o.x,
  310.             self.y + o.y
  311.         )
  312.     end
  313.     vectors[3].add = function(self, o)
  314.         checkValue[3](o)
  315.         return vect.new(
  316.             self.x + o.x,
  317.             self.y + o.y,
  318.             self.z + o.z
  319.         )
  320.     end
  321.     vectors[4].add = function(self, o)
  322.         checkValue[4](o)
  323.         return vect.new(
  324.             self.x + o.x,
  325.             self.y + o.y,
  326.             self.z + o.z,
  327.             self.w + o.w
  328.         )
  329.     end
  330.  
  331.     -- Subtracts one vector from another.
  332.     vectors[2].sub = function(self, o)
  333.         checkValue[2](o)
  334.         return vect.new(
  335.             self.x - o.x,
  336.             self.y - o.y
  337.         )
  338.     end
  339.     vectors[3].sub = function(self, o)
  340.         checkValue[3](o)
  341.         return vect.new(
  342.             self.x - o.x,
  343.             self.y - o.y,
  344.             self.z - o.z
  345.         )
  346.     end
  347.     vectors[4].sub = function(self, o)
  348.         checkValue[4](o)
  349.         return vect.new(
  350.             self.x - o.x,
  351.             self.y - o.y,
  352.             self.z - o.z,
  353.             self.w - o.w
  354.         )
  355.     end
  356.  
  357.     -- Multiplies a vector by a scalar value.
  358.     vectors[2].mul = function(self, n)
  359.         checkNumber(n)
  360.         return vect.new(
  361.             self.x * n,
  362.             self.y * n
  363.         )
  364.     end
  365.     vectors[3].mul = function(self, n)
  366.         checkNumber(n)
  367.         return vect.new(
  368.             self.x * n,
  369.             self.y * n,
  370.             self.z * n
  371.         )
  372.     end
  373.     vectors[4].mul = function(self, n)
  374.         checkNumber(n)
  375.         return vect.new(
  376.             self.x * n,
  377.             self.y * n,
  378.             self.z * n,
  379.             self.w * n
  380.         )
  381.     end
  382.  
  383.     -- Divides a vector by a scalar value.
  384.     vectors[2].div = function(self, n)
  385.         checkNumber(n)
  386.         return vect.new(
  387.             self.x / n,
  388.             self.y / n
  389.         )
  390.     end
  391.     vectors[3].div = function(self, n)
  392.         checkNumber(n)
  393.         return vect.new(
  394.             self.x / n,
  395.             self.y / n,
  396.             self.z / n
  397.         )
  398.     end
  399.     vectors[4].div = function(self, n)
  400.         checkNumber(n)
  401.         return vect.new(
  402.             self.x / n,
  403.             self.y / n,
  404.             self.z / n,
  405.             self.w / n
  406.         )
  407.     end
  408.  
  409.     -- Negates a vector.
  410.     vectors[2].unm = function(self)
  411.         return vect.new(
  412.             -self.x,
  413.             -self.y
  414.         )
  415.     end
  416.     vectors[3].unm = function(self)
  417.         return vect.new(
  418.             -self.x,
  419.             -self.y,
  420.             -self.z
  421.         )
  422.     end
  423.     vectors[4].unm = function(self)
  424.         return vect.new(
  425.             -self.x,
  426.             -self.y,
  427.             -self.z,
  428.             -self.w
  429.         )
  430.     end
  431.  
  432.     -- Computes the dot product of two vectors.
  433.     vectors[2].dot = function(self, o)
  434.         checkValue[2](o)
  435.         return self.x * o.x + self.y * o.y
  436.     end
  437.     vectors[3].dot = function(self, o)
  438.         checkValue[3](o)
  439.         return self.x * o.x + self.y * o.y + self.z * o.z
  440.     end
  441.     vectors[4].dot = function(self, o)
  442.         checkValue[4](o)
  443.         return self.x * o.x + self.y * o.y + self.z * o.z + self.w * o.w
  444.     end
  445.  
  446.     -- Computes the cross product of two vectors.
  447.     vectors[2].cross = function(self, o)
  448.         checkValue[2](o)
  449.         return vect.new(0, 0)
  450.     end
  451.     vectors[3].cross = function(self, o)
  452.         checkValue[3](o)
  453.         return vect.new(
  454.             self.y * o.z - self.z * o.y,
  455.             self.z * o.x - self.x * o.z,
  456.             self.x * o.y - self.y * o.x
  457.         )
  458.     end
  459.     vectors[4].cross = function(self, o)
  460.         checkValue[4](o)
  461.         local v = vectors[3].cross(self, o)
  462.         return vect.new(v.x, v.y, v.z, 0)
  463.     end
  464.  
  465.     -- Get the length (also called magnitude) of a vector.
  466.     vectors[2].length = function(self)
  467.         return math.sqrt(self.x ^ 2 + self.y ^ 2)
  468.     end
  469.     vectors[3].length = function(self)
  470.         return math.sqrt(self.x ^ 2 + self.y ^ 2 + self.z ^ 2)
  471.     end
  472.     vectors[4].length = function(self)
  473.         return math.sqrt(self.x ^ 2 + self.y ^ 2 + self.z ^ 2 + self.w ^ 2)
  474.     end
  475.  
  476.     -- Computes a vector with the same direction, but of length 1.
  477.     vectors[2].normalize = function(self) return self:mul(1 / self:length()) end
  478.     vectors[3].normalize = function(self) return self:mul(1 / self:length()) end
  479.     vectors[4].normalize = function(self) return self:mul(1 / self:length()) end
  480.  
  481.     -- Construct a vector with each dimension rounded to the nearest value.
  482.     vectors[2].round = function(self, t)
  483.         t = tonumber(t) or 1
  484.         return vect.new(
  485.             math.floor((self.x + t * 0.5) / t) * t,
  486.             math.floor((self.y + t * 0.5) / t) * t
  487.         )
  488.     end
  489.     vectors[3].round = function(self, t)
  490.         t = tonumber(t) or 1
  491.         return vect.new(
  492.             math.floor((self.x + t * 0.5) / t) * t,
  493.             math.floor((self.y + t * 0.5) / t) * t,
  494.             math.floor((self.z + t * 0.5) / t) * t
  495.         )
  496.     end
  497.     vectors[4].round = function(self, t)
  498.         t = tonumber(t) or 1
  499.         return vect.new(
  500.             math.floor((self.x + t * 0.5) / t) * t,
  501.             math.floor((self.y + t * 0.5) / t) * t,
  502.             math.floor((self.z + t * 0.5) / t) * t,
  503.             math.floor((self.w + t * 0.5) / t) * t
  504.         )
  505.     end
  506.  
  507.     -- Converts a vector into a string, for pretty printing.
  508.     vectors[2].tostring = function(self)
  509.         return self.x .. "," .. self.y
  510.     end
  511.     vectors[3].tostring = function(self)
  512.         return self.x .. "," .. self.y .. "," .. self.z
  513.     end
  514.     vectors[4].tostring = function(self)
  515.         return self.x .. "," .. self.y .. "," .. self.z .. "," .. self.w
  516.     end
  517.  
  518.     -- Checks for equality between two vectors.
  519.     vectors[2].eq = function(self, o)
  520.         checkValue[2](o)
  521.         return self.x == o.x and self.y == o.y
  522.     end
  523.     vectors[3].eq = function(self, o)
  524.         checkValue[3](o)
  525.         return self.x == o.x and self.y == o.y and self.z == o.z
  526.     end
  527.     vectors[4].eq = function(self, o)
  528.         checkValue[4](o)
  529.         return self.x == o.x and self.y == o.y and self.z == o.z and self.w == o.w
  530.     end
  531.  
  532.     vect.new = function(x, y, z, w)
  533.         x, y, z, w = tonumber(x) or 0, tonumber(y) or 0, tonumber(z), tonumber(w)
  534.         local dim = 3
  535.  
  536.         if z == nil then dim = dim - 1
  537.         elseif w ~= nil then dim = dim + 1
  538.         end
  539.  
  540.         local main = vectors[dim]
  541.  
  542.         return setmetatable({x = x, y = y, z = z, w = w}, {
  543.             __index = main,
  544.             __add = main.add,
  545.             __sub = main.sub,
  546.             __mul = main.mul,
  547.             __div = main.div,
  548.             __unm = main.unm,
  549.             __tostring = main.tostring,
  550.             __eq = main.eq
  551.         })
  552.     end
  553.  
  554.     return {
  555.         new = vect.new
  556.     }
  557. end)()
  558.  
  559. --[[ The smallest time that the 'sleep' function works is 1/20th of a second.
  560. That means programs can technically only work in 20 frames per second.
  561. However, stuff can be printed to the screen faster than that if the 'sleep'
  562. function is removed, but ComputerCraft programs can only go a little over 6
  563. seconds without sleeping before it throws the 'Too long without yielding' error.
  564. This 'wait' function is my first solution to that problem.
  565.  
  566. This works like the sleep function, but instead of time, it counts ticks. It can
  567. even output a frame rate higher than what you would naturally see on your real
  568. world monitor, but it's not really meant to do that. Setting a tick rate that's
  569. too high will result in errors as detailed below.
  570.  
  571. Use 'wait(n)' with a number argument to loop 'n' ticks per second.
  572. • This function will calculate and return the 'fps' value.
  573. • 20 is the default value for 'n' if no argument is given.
  574. • Enter 1-20 to sleep for '1/n' amount of time. You can also enter decimals
  575.   between 0 and 1 or fractions to sleep for longer than 1 second.
  576. • Enter a number above 20 to set a tick rate faster than 20. Currently this is
  577.   restricted to multiples of 20. This may be fixed in a future update.
  578. • Entering 0 will throw an out of range error.
  579. • Entering a value that is too high may result in the following:
  580.   • You will get the 'Too long without yielding' error.
  581.   • You will get calculation errors with 'fps' and 'frameTime'.
  582.   • Your tick rate will become extremely unstable.
  583.   • You will experience input lag.
  584.   • Peformance varies depending on the speed of your real world CPU.
  585.  
  586. Additional values can also be returned from this function's methods.
  587. • 'wait(n)' or 'wait.fps()' will return the current ticks per second.
  588. • 'wait.ticks()' will return the total number of ticks counted by the function.
  589. • 'wait.startTime()' will return the 'os.clock()' time that the program started.
  590. • 'wait.programClock()' will return the time since the program started.
  591. • 'wait.frameTime(real)' will return one of two values:
  592.   • If 'real' is true or not nil, it will return the average time for 1 tick.
  593.   • If 'real' is false or nil, it will return the same average time rounded to
  594.     the nearest 1/20th of a second to adhere to ComputerCraft's timing system.
  595.  
  596. The best way to use this function is with the parallel API.
  597. • Put 'wait(n)' and whatever else you want to run with it inside an infinite
  598.   loop inside a function.
  599. • Add your created function to 'parallel.waitForAny' with another function
  600.   that's taking user input and/or any other function you want to run with set
  601.   tick rates.
  602.  
  603. Run either of these programs for a proof of concept:
  604. https://pastebin.com/5pgLdX2D
  605. https://pastebin.com/U8DGAmie
  606. ]]
  607. wait = (function()
  608.     local ticks = 0
  609.     local startTime = os.clock()
  610.     local frames = {os.clock()}
  611.     local fps = 0
  612.  
  613.     return setmetatable({
  614.         ticks = function() return ticks end,
  615.         frameTime = function(real)
  616.             local time = os.clock()-frames[1]
  617.             if real then return time / fps
  618.             else return math.round(time / fps * 20) / 20 end
  619.         end,
  620.         startTime = function() return startTime end,
  621.         programClock = function() return os.clock() - startTime end,
  622.         fps = function() return fps end
  623.     }, {
  624.         __call = function(self, n)
  625.             n = tonumber(n) or 20
  626.             if n <= 0 then error("Value out of range, must be greater than 0", 2) end
  627.             ticks = ticks + 1
  628.             frames[#frames+1] = os.clock()
  629.             if n <= 20 then
  630.                 sleep(1/n)
  631.             elseif ticks%math.round(n/20) == 0 then
  632.                 sleep(0.05)
  633.             end
  634.             while os.clock()-frames[1] > 1 and #frames > 1 do
  635.                 table.remove(frames, 1)
  636.             end
  637.             fps =  #frames / (os.clock() - frames[1]) - (math.floor(n/20)-1)
  638.             return fps
  639.         end
  640.     })
  641. end)()
  642.  
  643. -- Check if a specific value is equal to any of multile values.
  644. OR = function(val, ...)
  645.     local returnCode = false
  646.     for _, v in ipairs({...}) do
  647.         returnCode = returnCode or v == val
  648.     end
  649.     return returnCode
  650. end
  651.  
  652. -- Check if a specific value is equal to all of multiple values.
  653. AND = function(val, ...)
  654.     local returnCode = true
  655.     for _, v in ipairs({...}) do
  656.         returnCode = returnCode and v == val
  657.     end
  658.     return returnCode
  659. end
  660.  
  661. -- Check if a number is between two numbers, inclusive or non-inclusive.
  662. isBetween = function(val, low, high, inclusive)
  663.     if inclusive then return val >= low and val <= high
  664.     else return val > low and val < high end
  665. end
  666.  
  667. -- Freezes the program to check values for bug testing.
  668. -- The program will resume when any key is pressed.
  669. bugCheck = function(x, y, s)
  670.     local oldX, oldY = term.getCursorPos()
  671.     term.setCursorPos(x, y)
  672.     term.setBackgroundColor(colors.black)
  673.     term.setTextColor(colors.red)
  674.     write(s)
  675.     os.pullEvent("key")
  676.     term.setCursorPos(oldX, oldY)
  677. end
  678.  
  679. --[[ Changelog
  680.     The changelog has been moved to its own file: https://pastebin.com/2cK0DcBk
  681. ]]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement