Guest User

Untitled

a guest
Dec 15th, 2012
336
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 8.10 KB | None | 0 0
  1. local sensor = peripheral.wrap("left")
  2. rednet.open("right")
  3. local config = dofile("elevator.config")
  4. local floors = {}
  5. local selectedFloor = 1
  6. local cartDispenserId = nil
  7. local lastError = nil
  8. local expectingCart = false
  9. local expectingArrival = false
  10. local needCart = true
  11. local gotCartResponse = false
  12. local inUse = false
  13. local inventorySlot = 1
  14. local proximitySlot = 2
  15.  
  16. local function switchToInventorySensor()
  17.     if turtle.getItemCount(inventorySlot) > 0 then
  18.         turtle.select(16)
  19.         turtle.transferTo(proximitySlot)
  20.         turtle.select(inventorySlot)
  21.         turtle.transferTo(16)
  22.     end
  23. end
  24.  
  25. local function switchToProximitySensor()
  26.     if turtle.getItemCount(proximitySlot) > 0 then
  27.         turtle.select(16)
  28.         turtle.transferTo(inventorySlot)
  29.         turtle.select(proximitySlot)
  30.         turtle.transferTo(16)
  31.     end
  32. end
  33.  
  34. local function checkIfCart()
  35.     local rtn = false
  36.     local targetName = nil
  37.     switchToInventorySensor()
  38.     for name,target in pairs(sensor.getTargets()) do
  39.         if target.type == "railcraft.common.blocks.machine.gamma.TileDispenserCart" then
  40.             targetName = name
  41.             break
  42.         end
  43.     end
  44.     if targetName then
  45.         local inventoryData = sensor.getTargetDetails(targetName)
  46.         for slot, item in pairs(inventoryData) do
  47.             if item.Size > 0 then
  48.                 rtn = true
  49.                 break
  50.             end
  51.         end
  52.     end
  53.     return rtn
  54. end
  55. local function dispenseCart(floor)
  56.     if checkIfCart() then
  57.         expectingCart = true
  58.         rednet.send(cartDispenserId, textutils.serialize{type="elevator", sender="main", id=config.id, command="dispense"})
  59.     else
  60.         rednet.broadcast(textutils.serialize{type="elevator", sender="main", id=config.id, command="needCart"})
  61.         needCart = true
  62.     end
  63. end
  64.  
  65. local function handleCancel()
  66.     inUse = false
  67.     needCart = false
  68.     gotCartResponse = false
  69.     expectingCart = false
  70.     expectingArrival = false
  71.     rs.setOutput("front", false)
  72.     lastError = nil
  73. end
  74.  
  75. local function chooseFloor()
  76.     lastError = nil
  77.     if cartDispenserId then
  78.         if not expectingCart then
  79.             local floor = floors[selectedFloor]
  80.             dispenseCart(floor)
  81.         end
  82.     else
  83.         lastError = "Cannot find the cart dispenser!"
  84.     end
  85. end
  86.  
  87. local function addFloor(message)
  88.     local found = false
  89.     for index, floor in ipairs(floors) do
  90.         if floor.id == message.id then
  91.             floors[index] = { id=message.id, shortcut = message.shortcut, description = message.description }
  92.             found = true
  93.             break
  94.         end
  95.     end
  96.     if not found then      
  97.         table.insert(floors, { id=message.id, shortcut = message.shortcut, description = message.description })
  98.     end
  99.     table.sort(floors, function(a,b) return tonumber(a.id) < tonumber(b.id) end)   
  100. end
  101.  
  102. local function handleMain(senderId, message)
  103.     if message.command == "announce" then
  104.         rednet.send(senderId, textutils.serialize{type="elevator", sender = "main", id=config.id, command="ack", shortcut=config.shortcut, description=config.description})
  105.         addFloor(message)
  106.     elseif message.command == "ack" then
  107.         addFloor(message)
  108.     elseif message.command == "floorSelect" then
  109.         inUse = true
  110.         if message.floorId == config.id then
  111.             rs.setOutput("front", true)
  112.             expectingArrival = true
  113.         end
  114.     elseif message.command == "cancel" then
  115.         handleCancel()
  116.     elseif message.command == "gotCart" then
  117.         if needCart and not gotCartResponse then
  118.             gotCartResponse = true
  119.             expectingCart = true
  120.             rs.setOutput("front", true)
  121.             rednet.send(senderId, textutils.serialize{type="elevator", sender="main", id = config.id, command="sendCart"})
  122.         end        
  123.     elseif message.command == "sendCart" then
  124.         rednet.send(cartDispenserId, textutils.serialize{type="elevator", sender="main", id=config.id, command="sendCart"})
  125.     elseif message.command == "needCart" then
  126.         if checkIfCart() then
  127.             rednet.send(senderId, textutils.serialize{type="elevator", sender="main", id=config.id, command="gotCart"})
  128.         end
  129.     end
  130. end
  131.  
  132. local function handleDispenser(senderId, message)
  133.     if message.command == "announce" then
  134.         if message.id == config.id then
  135.             rednet.send(senderId, textutils.serialize{type="elevator", sender = "main", id=config.id, command="ack", shortcut=config.shortcut, description=config.description})
  136.             cartDispenserId = senderId
  137.         end
  138.     elseif message.command == "ack" then
  139.         cartDispenserId = senderId
  140.     end
  141. end
  142.  
  143. local function doScan()
  144.     while true do
  145.         if expectingCart or expectingArrival then
  146.             switchToProximitySensor()
  147.             local targets = sensor.getTargets()
  148.             for name, target in pairs(targets) do
  149.                 if (target.Position.X == config.embarkedCoords.x) and (target.Position.Y == config.embarkedCoords.y) and (target.Position.Z == config.embarkedCoords.z) then
  150.                     rs.setOutput("front", false)
  151.                     if expectingCart then
  152.                         inUse = true
  153.                         rednet.broadcast(textutils.serialize{type="elevator", sender="main", id=config.id, command="floorSelect", floorId=floors[selectedFloor].id})
  154.                         sleep(.5)
  155.                         rednet.send(cartDispenserId, textutils.serialize{type="elevator", sender="main", id=config.id, command="launch"})
  156.                     elseif expectingArrival then
  157.                         inUse = false
  158.                         rednet.broadcast(textutils.serialize{type="elevator", sender="main", id=config.id, command="cancel"})
  159.                         rednet.send(cartDispenserId, textutils.serialize{type="elevator", sender="main", id=config.id, command="dispense"})                    
  160.                         handleCancel()
  161.                     end
  162.                     expectingArrival = false                   
  163.                     expectingCart = false
  164.                 end
  165.             end
  166.         end    
  167.         sleep(.1)
  168.     end
  169. end
  170.  
  171. local function doNetwork()
  172.     print("Starting network...")
  173.     rednet.broadcast(textutils.serialize{type="elevator", sender = "main", id=config.id, command="announce", shortcut = config.shortcut, description=config.description })
  174.     while true do
  175.         local event, senderId, data, distance = os.pullEvent("rednet_message")
  176.         local message = textutils.unserialize(data)
  177.         if message and message.type == "elevator" then
  178.             if message.sender == "main" then
  179.                 handleMain(senderId, message)          
  180.             elseif message.sender == "dispenser" then
  181.                 handleDispenser(senderId, message)
  182.             end
  183.         end
  184.     end
  185. end
  186.  
  187. local function displayFloorSelection()
  188.     print("Floors available: ")
  189.     for index, floor in ipairs(floors) do
  190.         if index == selectedFloor then
  191.             print(string.format("[ %s: %s ]", floor.shortcut, floor.description))
  192.         else
  193.             print(string.format("  %s: %s  ", floor.shortcut, floor.description))
  194.         end
  195.     end
  196. end
  197.  
  198. local function displayCart()
  199.     if not needCart then
  200.         print("Your cart is ready!")
  201.     else
  202.         print("Use cart when arrives.")
  203.     end
  204. end
  205.  
  206. local function displayInUse()
  207.     print("Cart system in use!")
  208. end
  209.  
  210. local function displayNeedCart()
  211.     print("Waiting for cart...")
  212. end
  213.  
  214. local function displayMenu()
  215.     term.clear()
  216.     term.setCursorPos(1,1)
  217.     if expectingCart then
  218.         displayCart()
  219.     elseif inUse then
  220.         displayInUse()
  221.     else
  222.         displayFloorSelection()
  223.     end
  224.     if lastError then print(lastError) end
  225.     print("Press Q to exit C to Cancel Request")
  226. end
  227.  
  228. local function doMenu()
  229.     print("Displaying menu...")
  230.     while true do
  231.         sleep(1)
  232.         displayMenu()
  233.     end
  234. end
  235.  
  236. local function doKeyboard()
  237.     print("Starting keyboard handler...")
  238.     while true do
  239.         local event, key = os.pullEvent()
  240.         if event == "char" then
  241.             if string.lower(key) == "q" then
  242.                 break
  243.             elseif string.lower(key) == "c" then
  244.                 rednet.broadcast(textutils.serialize{type="elevator", sender="main", id=config.id, command="cancel"})
  245.                 handleCancel()
  246.             else
  247.                 local keyToCompare = string.lower(key)
  248.                 for index, floor in ipairs(floors) do
  249.                     if keyToCompare == floor.shortcut then
  250.                         selectedFloor = index
  251.                         displayMenu()
  252.                         chooseFloor()
  253.                         break
  254.                     end
  255.                 end
  256.             end
  257.         elseif event == "key" then
  258.             if key == 200 then
  259.                 if selectedFloor > 1 then -- up arrow
  260.                     selectedFloor = selectedFloor - 1
  261.                     displayMenu()
  262.                 end
  263.             elseif key == 208 then
  264.                 if selectedFloor < #floors then -- down arrow
  265.                     selectedFloor = selectedFloor + 1
  266.                     displayMenu()
  267.                 end
  268.             elseif key == 28 then -- enter
  269.                 chooseFloor()
  270.             end
  271.         end
  272.     end
  273. end
  274.  
  275.  
  276. local function startup()
  277.     term.clear()
  278.     term.setCursorPos(1,1)
  279.     return parallel.waitForAny(doNetwork, doKeyboard, doMenu, doScan)
  280. end
  281.  
  282.  
  283. local rtn, error = pcall(startup)
  284. if not rtn then
  285.     print("Elevator failed: " .. error)
  286. end
  287. print("Exiting.")
Advertisement
Add Comment
Please, Sign In to add comment