miniminater

rain

Dec 18th, 2021 (edited)
186
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 9.86 KB | None | 0 0
  1. --[[
  2.     Second attempt at matrix rain.
  3. ]]
  4.  
  5. local component = require("component")
  6. local gpu = component.gpu
  7. local event = require("event")
  8.  
  9. local wid, hig = gpu.getResolution()
  10.  
  11. local delay = 0.035
  12. local frequency = 0
  13. local persistence = {4, math.floor(hig / 2)}
  14. local notontop = 0.33
  15. local maxDrops = 50
  16. local usercolor = "green"
  17. local tails = true
  18. local screenregion = 0.5
  19. local statictails = false
  20.  
  21. local colors = {
  22.     "red",
  23.     "orange",
  24.     "yellow",
  25.     "green",
  26.     "blue",
  27.     "purple",
  28.     "violet",
  29.     "gray",
  30.     "grey",
  31.     "pink",
  32.     "white" --white should always be at the end, to exclude it from the random selection
  33. }
  34.  
  35. local function swap(a, b)
  36.     if a < b then
  37.         return a, b
  38.     else
  39.         return b, a
  40.     end
  41. end
  42.  
  43. local function argError(arg, type, usage)
  44.     print("arg_error: " .. arg .. " requires a " .. type .. " value")
  45.     print("usage: " .. usage)
  46.     os.exit()
  47. end
  48.  
  49. local args = {...}
  50. local ii = 1
  51. for i=1,#args do
  52.     if ii > #args then
  53.         break
  54.     end
  55.     if args[ii] == "-d" or args[ii] == "--delay" then
  56.         ii = ii + 1
  57.         if ii <= #args then
  58.             delay = tonumber(args[ii]) --the time between each raindrop
  59.         else
  60.             argError("delay", "number", "rain [-d|--delay] <delay>")
  61.         end
  62.     elseif args[ii] == "-f" or args[ii] == "--frequency" then
  63.         ii = ii + 1
  64.         if ii <= #args then
  65.             frequency = tonumber(args[ii]) --how many iters between each raindrop
  66.         else
  67.             argError("frequency", "number", "rain [-f|--frequency] <frequency>")
  68.         end
  69.     elseif args[ii] == "-p" or args[ii] == "--persistence" then
  70.         if ii + 2 <= #args then
  71.             local persmin, persmax = swap(tonumber(args[ii+1]), tonumber(args[ii+2]))
  72.             persmin = math.floor(persmin * hig)
  73.             persmax = math.floor(persmax * hig)
  74.             persistence = {persmin, persmax}
  75.         else
  76.             argError("persistence", "number", "rain [-p|--persistence] <persistence>")
  77.         end
  78.         ii = ii + 2
  79.     elseif args[ii] == "-t" or args[ii] == "--notontop" then
  80.         if ii <= #args then
  81.             notontop = tonumber(args[ii+1]) --chance for raindrop to spawn below y=1
  82.         else
  83.             argError("notontop", "number", "rain [-t|--notontop] <notontop>")
  84.         end
  85.         ii = ii + 1
  86.     elseif args[ii] == "-m" or args[ii] == "--maxdrops" then
  87.         if ii <= #args then
  88.             maxDrops = tonumber(args[ii+1]) --max number of raindrops
  89.         else
  90.             argError("maxdrops", "number", "rain [-m|--maxdrops] <maxdrops>")
  91.         end
  92.         ii = ii + 1
  93.     elseif args[ii] == "-c" or args[ii] == "--color" then
  94.         if ii <= #args then
  95.             --make sure the color is valid
  96.             local valid = false
  97.             for i=1,#colors do
  98.                 if args[ii+1] == colors[i] then
  99.                     valid = true
  100.                     break
  101.                 end
  102.             end
  103.             if valid then
  104.                 usercolor = args[ii+1]
  105.             elseif args[ii+1] == "random" then
  106.                 usercolor = colors[math.random(1, #colors - 1)]
  107.             else
  108.                 argError("color", "color", "rain [-c|--color] <color>")
  109.             end
  110.         else
  111.             argError("color", "color", "rain [-c|--color] <color>")
  112.         end
  113.         ii = ii + 1
  114.     elseif args[ii] == "-n" or args[ii] == "--no-tails" then
  115.         tails = false
  116.     elseif args[ii] == "-s" or args[ii] == "--screenregion" then
  117.         if ii <= #args then
  118.             screenregion = tonumber(args[ii+1]) --percentage of the screen the raindrops will spawn in from top
  119.         else
  120.             argError("screenregion", "number", "rain [-s|--screenregion] <screenregion>")
  121.         end
  122.         ii = ii + 1
  123.     elseif args[ii] == "-u" or args[ii] == "--static-tails" then
  124.         statictails = true
  125.     elseif args[ii] == "-v" or args[ii] == "--version" then
  126.         print("Rain v1.0")
  127.         print("By minater247")
  128.         os.exit()
  129.     elseif args[ii] == "-h" or args[ii] == "--help" then
  130.         print("usage: rain [-d|--delay] <delay> [-f|--frequency] <frequency> [-p|--persistence] <persistence> [-t|--notontop] <notontop>\n")
  131.         print("-d|--delay <float>: the time between each raindrop")
  132.         print("-f|--frequency <int>: how many iters between each raindrop")
  133.         print("-p|--persistence <float> <float>: The minimum and maximum length of the raindrops, in percent of the screen height")
  134.         print("-t|--notontop <float>: The chance that a raindrop will not be on the top of the screen")
  135.         print("-m|--maxdrops <int>: The maximum number of raindrops that can be on the screen at once")
  136.         print("-c|--color <string>: The color of the raindrops. Must be either a color name or 'random'")
  137.         print("-n|--no-tails: Whether or not to draw tails on the raindrops")
  138.         print("-s|--screenregion <float>: The percentage of the screen the raindrops will spawn in from top")
  139.         print("-u|--static-tails: Make the bottom character of the raindrop the same")
  140.         os.exit()
  141.     else
  142.         print("arg_error: unknown argument " .. args[ii])
  143.         print("usage: rain [-d|--delay] <delay> [-f|--frequency] <frequency> [-p|--persistence] <persistence> [-t|--notontop] <notontop>")
  144.         os.exit()
  145.     end
  146.     ii = ii + 1
  147. end
  148.  
  149.  
  150.  
  151. local function genchars(len)
  152.     local str = ""
  153.     for i=1, len do
  154.         local s = string.char(math.random(32, 126))
  155.         if s == " " then
  156.             s = "&"
  157.         end
  158.         str = str .. s
  159.     end
  160.     return str
  161. end
  162. local charset = genchars(1000)
  163. local charsetlen = 1000
  164. local currchar = 1
  165.  
  166.  
  167. local Drops = {}
  168. local function createDrop()
  169.     local drop = {}
  170.     drop.x = math.random(1, wid)
  171.     if math.random() < notontop then
  172.         drop.y = math.random(1, math.floor(hig * screenregion))
  173.     else
  174.         drop.y = 1
  175.     end
  176.     drop.char = charset:sub(currchar, currchar)
  177.     currchar = currchar + 1
  178.     if currchar > charsetlen then
  179.         currchar = 1
  180.     end
  181.     drop.persistence = math.random(persistence[1], persistence[2])
  182.     table.insert(Drops, drop)
  183. end
  184.  
  185. local function moveDropsDown()
  186.     for i, drop in ipairs(Drops) do
  187.         drop.y = drop.y + 1
  188.         if drop.y > hig then
  189.             table.remove(Drops, i)
  190.         end
  191.     end
  192. end
  193.  
  194. local Screen = {}
  195. for y=1, hig do
  196.     Screen[y] = {}
  197.     for x=1, wid do
  198.         Screen[y][x] = 0
  199.     end
  200. end
  201.  
  202. local function subtractOne()
  203.     for y=1, hig do
  204.         for x=1, wid do
  205.             if Screen[y][x] > 0 then
  206.                 Screen[y][x] = Screen[y][x] - 1
  207.             end
  208.         end
  209.     end
  210. end
  211.  
  212. local screencolors = {}
  213. screencolors.red = {
  214.     0x000000,
  215.     0x330000,
  216.     0x660000,
  217.     0x990000,
  218.     0xcc0000,
  219.     0xff0000
  220. }
  221. screencolors.orange = {
  222.     0x000000,
  223.     0x330000,
  224.     0xCC4900,
  225.     0xFF4900,
  226.     0xFF6D00
  227. }
  228. screencolors.yellow = {
  229.     0xFFB600,
  230.     0xFFDB00,
  231.     0xFFFF00
  232. }
  233. screencolors.green = {
  234.     0x000000,
  235.     0x002400,
  236.     0x004900,
  237.     0x006d00,
  238.     0x009200,
  239.     0x00b600,
  240.     0x00db00,
  241.     0x00ff00
  242. }
  243. screencolors.blue = {
  244.     0x000000,
  245.     0x000040,
  246.     0x000080,
  247.     0x0000c0,
  248.     0x0000ff,
  249.     0x0024ff,
  250.     0x0049ff,
  251.     0x006dff,
  252.     0x0092ff
  253. }
  254. screencolors.purple = {
  255.     0x000000,
  256.     0x3300C0,
  257.     0x3300FF,
  258.     0x6624FF,
  259.     0x6649FF,
  260.     0x9949FF    
  261. }
  262. screencolors.violet = screencolors.purple
  263. screencolors.white = {
  264.     0xFFFFFF
  265. }
  266. screencolors.gray = {
  267.     0x000000,
  268.     0x0F0F0F,
  269.     0x1E1E1E,
  270.     0x2D2D2D,
  271.     0x3C3C3C,
  272.     0x4B4B4B,
  273.     0x5A5A5A,
  274.     0x696969,
  275.     0x787878,
  276.     0x878787,
  277.     0x969696,
  278.     0xA5A5A5,
  279.     0xB4B4B4,
  280.     0xC3C3C3,
  281.     0xD2D2D2,
  282.     0xE1E1E1,
  283.     0xF0F0F0
  284. }
  285. screencolors.grey = screencolors.gray
  286. screencolors.pink = {
  287.     0x000000,
  288.     0x660080,
  289.     0x9900FF,
  290.     0xCC00FF,
  291.     0xFF00FF,
  292.     0xFF24FF
  293. }
  294.  
  295. local currcolors = screencolors[usercolor]
  296.  
  297. local function drawScreen()
  298.     gpu.setBackground(0x000000)
  299.     gpu.fill(1, 1, wid, hig, " ")
  300.     for y=1, hig do
  301.         for x=1, wid do
  302.             if Screen[y][x] > 0 then
  303.                 if Screen[y][x] > #currcolors then
  304.                     gpu.setForeground(currcolors[#currcolors])
  305.                 else
  306.                     gpu.setForeground(currcolors[Screen[y][x]])
  307.                 end
  308.                 gpu.set(x, y, charset:sub(currchar, currchar))
  309.                 currchar = currchar + 1
  310.                 if currchar > charsetlen then
  311.                     currchar = 1
  312.                 end
  313.             end
  314.         end
  315.     end
  316. end
  317.  
  318.  
  319. local function addDropsToScreen()
  320.     for i, drop in ipairs(Drops) do
  321.         Screen[drop.y][drop.x] = drop.persistence
  322.         if not tails and not statictails then
  323.             drop.char = charset:sub(currchar, currchar)
  324.             currchar = currchar + 1
  325.             if currchar > charsetlen then
  326.                 currchar = 1
  327.             end
  328.         end
  329.     end
  330. end
  331.  
  332. local function drawDrops()
  333.     if tails then
  334.         gpu.setForeground(0xFFFFFF)
  335.     else
  336.         gpu.setForeground(currcolors[#currcolors])
  337.     end
  338.     for i, drop in ipairs(Drops) do
  339.         gpu.set(drop.x, drop.y, drop.char)
  340.     end
  341. end
  342.  
  343. local iter = 0
  344. while true do
  345.     moveDropsDown()
  346.     subtractOne()
  347.     if #Drops < maxDrops then
  348.         if frequency < 1 and frequency > 0 then
  349.             for i=1,math.floor(1 / frequency) do
  350.                 createDrop()
  351.             end
  352.         elseif frequency > 0 then
  353.             if iter % frequency == 0 then
  354.                 createDrop()
  355.             end
  356.         else
  357.             createDrop()
  358.         end
  359.     end
  360.     addDropsToScreen()
  361.     drawScreen()
  362.     drawDrops()
  363.     local ev = event.pull(delay, "key_down")
  364.     if ev then
  365.         gpu.fill(1, 1, wid, hig, " ")
  366.         io.write("\x1b[1;1H") --terminal escape to 1,1
  367.         break
  368.     end
  369.     iter = iter + 1
  370. end
Add Comment
Please, Sign In to add comment