IronicPickle

elevator.lua

Feb 27th, 2020
972
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.19 KB | None | 0 0
  1. -- Args
  2. local args = { ... }
  3. local floorNum = tonumber(args[1]) or 1
  4. local floorName = args[2] or "Unnamed"
  5. local redstoneOutput = args[3] or "right"
  6. local channel = tonumber(args[4]) or 10
  7.  
  8. -- Libraries
  9. local setup = require("/lua/lib/setupUtils")
  10. local monUtils = require("/lua/lib/monitorUtils")
  11. local write = monUtils.write
  12. local drawBox = monUtils.drawBox
  13. local stateHandler = require("/lua/lib/stateHandler")
  14.  
  15. -- Peripherals
  16. local wrappedPers = setup.getPers({
  17.     "monitor",
  18.     "modem"
  19. })
  20. local monitor = setup.setupMonitor(
  21.     wrappedPers.monitor[1], 0.5
  22. )
  23. local modem = wrappedPers.modem[1]
  24. local speaker = peripheral.find("speaker")
  25.  
  26. -- Setup
  27. local devices = {}
  28. local floors = {}
  29. local moving = false
  30. local direction = 0
  31.  
  32. local stateData = stateHandler.getState("elevator")
  33. local defaultData = 1
  34. local currentFloorIndex = stateData or defaultData
  35.  
  36. -- Windows
  37. local winHeader = setup.setupWindow(
  38.     monitor, 1, 1, monitor.x, 6
  39. )
  40. local winFooter = setup.setupWindow(
  41.     monitor, 1, (monitor.y - 3), monitor.x, 4
  42. )
  43. local winMain = setup.setupWindow(
  44.     monitor, 1, 7, monitor.x, (monitor.y - (6 + 4))
  45. )
  46.  
  47. -- Main
  48.  
  49. function start()
  50.     print("# Program Started")
  51.    
  52.     local deviceData = {
  53.         floorNum = floorNum,
  54.         floorName = floorName
  55.     }
  56.     devices = setup.setupNetwork(
  57.         modem, channel, deviceData, monitor
  58.     )
  59.     local map = {}
  60.     for i, device in ipairs(devices) do
  61.         if(not map[device.floorNum]) then
  62.             table.insert(floors, device)
  63.             map[device.floorNum] = true
  64.         end
  65.     end
  66.    
  67.     table.sort(floors,
  68.         function(a, b) return a.floorNum > b.floorNum end
  69.     )
  70.     drawHeader()
  71.     drawFooter()
  72.     drawMain()
  73.    
  74.     await()
  75. end
  76.  
  77. function await()
  78.     while(true) do
  79.         local event, p1, p2, p3, p4, p5 = os.pullEvent()
  80.        
  81.         local isTouch = (event == "monitor_touch")
  82.        
  83.         local isModemMessage = (event == "modem_message")
  84.        
  85.         if(isTouch) then
  86.             local x = p2
  87.             local y = p3 - winHeader.y
  88.            
  89.             local floorIndex = y - 4
  90.             local floor = floors[floorIndex]
  91.             if(floor and (floorIndex) ~= currentFloorIndex) then
  92.                 modem.transmit(channel, channel,
  93.                     {
  94.                          type = "floorChange",
  95.                          floorIndex = floorIndex  
  96.                     }
  97.                 )
  98.                 moveTo(floorIndex)
  99.                 break
  100.             end
  101.         elseif(isModemMessage) then
  102.             local body = p4
  103.             if(body.type == "floorChange") then
  104.                 moveTo(body.floorIndex)
  105.                 break
  106.             end
  107.         end
  108.     end
  109. end
  110.  
  111. function moveTo(floorIndex)
  112.     local floor = floors[floorIndex]
  113.     direction = currentFloorIndex - floorIndex
  114.     currentFloorIndex = floorIndex
  115.     moving = true
  116.     updateState()
  117.    
  118.     if(speaker) then
  119.         speaker.playSound(
  120.             "minecraft:entity.experience_orb.pickup",
  121.             1, 0.5
  122.         )
  123.     end
  124.    
  125.     sendSignal(floor.floorNum)
  126.    
  127.     drawMain()
  128.    
  129.     sendSignal(floor.floorNum)
  130.    
  131.     if(speaker) then
  132.         speaker.playSound(
  133.             "minecraft:entity.player.levelup",
  134.             1, 0.5
  135.         )
  136.     end
  137.    
  138.     await()
  139. end
  140.  
  141. function sendSignal(floorNum)
  142.     local colorDecimal = 1
  143.     for i = 1, floorNum - 1, 1 do
  144.         colorDecimal = colorDecimal + colorDecimal
  145.     end
  146.    
  147.     if(colorDecimal >= 32768) then return end
  148.     if(moving) then colorDecimal = colorDecimal + 32768 end
  149.    
  150.     redstone.setBundledOutput(
  151.         redstoneOutput, colorDecimal
  152.     )
  153.    
  154. end
  155.  
  156. function updateState()
  157.     stateHandler.updateState("elevator", currentFloorIndex)
  158. end
  159.  
  160. function drawHeader()
  161.     winHeader.bg = colors.blue
  162.     winHeader.setBackgroundColor(winHeader.bg)
  163.    
  164.     drawBox(winHeader,
  165.         1, 1, winHeader.x, winHeader.y,
  166.         true
  167.     )
  168.     drawBox(winHeader,
  169.         1, winHeader.y, winHeader.x, winHeader.y,
  170.         true, colors.white
  171.     )
  172.    
  173.     write(winHeader, "Elevator", 0, 2, "centre")
  174.     write(winHeader, "This Floor: " .. floorName, 0, 4, "centre")
  175. end
  176.  
  177. function drawFooter()
  178.     winFooter.bg = colors.blue
  179.     winFooter.setBackgroundColor(winFooter.bg)
  180.    
  181.     drawBox(winFooter,
  182.         1, 1, winFooter.x, winFooter.y,
  183.         true
  184.     )
  185.     drawBox(winFooter,
  186.         1, 1, winFooter.x, 1,
  187.         true, colors.white
  188.     )
  189.    
  190.     write(winFooter, "Select a floor", 2, 3, "left")
  191.     write(winFooter, "Channel: " .. channel, 2, 3, "right" )
  192. end
  193.  
  194. function drawMain()
  195.     winMain.bg = colors.cyan
  196.     winMain.setBackgroundColor(winMain.bg)
  197.    
  198.     drawBox(winMain,
  199.         1, 1, winMain.x, winMain.y,
  200.         true
  201.     )
  202.    
  203.     if(moving) then
  204.         parallel.waitForAny(
  205.             drawMoving, awaitFinish,
  206.             function() sleep(30) end
  207.         )
  208.         moving = false
  209.         drawMain()
  210.     else
  211.         drawFloors()
  212.     end
  213. end
  214.  
  215. function drawMoving()
  216.     local i = 1
  217.     local max = winMain.y - 4
  218.     while(true) do
  219.         i = i + 1
  220.         if(i > max) then i = 1 end
  221.        
  222.         local dirStr = "\\/"
  223.         if(direction > 0) then
  224.             dirStr = "/\\"
  225.         end
  226.        
  227.         winMain.clear()
  228.         local floor = floors[currentFloorIndex]
  229.        
  230.         write(winMain,
  231.             "Moving to: " .. floor.floorName,
  232.             0, 2, "centre"
  233.         )
  234.        
  235.         for ii = 1, 5, 1 do
  236.             local y = i + ii - 1
  237.             if(y > max) then y = y % max end
  238.             if(direction > 0) then
  239.                 y = (y - max - 1) * -1
  240.             end
  241.            
  242.             write(winMain,
  243.                 dirStr,
  244.                 0, (y + 3), "centre"
  245.             )
  246.         end
  247.        
  248.         os.sleep(0.1)
  249.     end
  250. end
  251.  
  252. function awaitFinish()
  253.     sleep(1)
  254.     while(true) do
  255.         local event, p1, p2, p3, p4, p5 = os.pullEvent()
  256.        
  257.         local isRedstone = (event == "redstone")
  258.        
  259.         local isModemMessage = (event == "modem_message")
  260.        
  261.         if(isRedstone) then
  262.             modem.transmit(channel, channel,
  263.                 {
  264.                     type = "floorChanged"
  265.                 }
  266.             )
  267.             return
  268.         elseif(isModemMessage) then
  269.             local body = p4
  270.             if(body.type == "floorChanged") then
  271.                 return
  272.             end
  273.         end
  274.        
  275.     end
  276. end
  277.    
  278. function drawFloors()
  279.     if(currentFloorIndex > #floors) then
  280.         currentFloorIndex = 1
  281.     end
  282.     write(winMain,
  283.         "Floor: " .. floors[currentFloorIndex].floorName,
  284.         2, 2, "right"
  285.     )
  286.     write(winMain,
  287.         "# Floors",
  288.         2, 2, "left"
  289.     )
  290.    
  291.     for i, floor in ipairs(floors) do
  292.         local y = 4 + i
  293.         if(i == currentFloorIndex) then
  294.             drawBox(winMain,
  295.                 1, y, winMain.x, y,
  296.                 true, colors.blue
  297.             )
  298.             winMain.setBackgroundColor(colors.blue)
  299.         end
  300.         write(winMain,
  301.             " > " .. floor.floorName .. " ",
  302.             2, y, "left"
  303.         )
  304.         winMain.setBackgroundColor(winMain.bg)
  305.     end
  306. end
  307.  
  308. setup.utilsWrapper(start, modem, channel)
Add Comment
Please, Sign In to add comment