Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local sensor = peripheral.wrap("left")
- rednet.open("right")
- local config = dofile("elevator.config")
- local floors = {}
- local selectedFloor = 1
- local cartDispenserId = nil
- local lastError = nil
- local expectingCart = false
- local expectingArrival = false
- local needCart = true
- local gotCartResponse = false
- local inUse = false
- local inventorySlot = 1
- local proximitySlot = 2
- local function switchToInventorySensor()
- if turtle.getItemCount(inventorySlot) > 0 then
- turtle.select(16)
- turtle.transferTo(proximitySlot)
- turtle.select(inventorySlot)
- turtle.transferTo(16)
- end
- end
- local function switchToProximitySensor()
- if turtle.getItemCount(proximitySlot) > 0 then
- turtle.select(16)
- turtle.transferTo(inventorySlot)
- turtle.select(proximitySlot)
- turtle.transferTo(16)
- end
- end
- local function checkIfCart()
- local rtn = false
- local targetName = nil
- switchToInventorySensor()
- for name,target in pairs(sensor.getTargets()) do
- if target.type == "railcraft.common.blocks.machine.gamma.TileDispenserCart" then
- targetName = name
- break
- end
- end
- if targetName then
- local inventoryData = sensor.getTargetDetails(targetName)
- for slot, item in pairs(inventoryData) do
- if item.Size > 0 then
- rtn = true
- break
- end
- end
- end
- return rtn
- end
- local function dispenseCart(floor)
- if checkIfCart() then
- expectingCart = true
- rednet.send(cartDispenserId, textutils.serialize{type="elevator", sender="main", id=config.id, command="dispense"})
- else
- rednet.broadcast(textutils.serialize{type="elevator", sender="main", id=config.id, command="needCart"})
- needCart = true
- end
- end
- local function handleCancel()
- inUse = false
- needCart = false
- gotCartResponse = false
- expectingCart = false
- expectingArrival = false
- rs.setOutput("front", false)
- lastError = nil
- end
- local function chooseFloor()
- lastError = nil
- if cartDispenserId then
- if not expectingCart then
- local floor = floors[selectedFloor]
- dispenseCart(floor)
- end
- else
- lastError = "Cannot find the cart dispenser!"
- end
- end
- local function addFloor(message)
- local found = false
- for index, floor in ipairs(floors) do
- if floor.id == message.id then
- floors[index] = { id=message.id, shortcut = message.shortcut, description = message.description }
- found = true
- break
- end
- end
- if not found then
- table.insert(floors, { id=message.id, shortcut = message.shortcut, description = message.description })
- end
- table.sort(floors, function(a,b) return tonumber(a.id) < tonumber(b.id) end)
- end
- local function handleMain(senderId, message)
- if message.command == "announce" then
- rednet.send(senderId, textutils.serialize{type="elevator", sender = "main", id=config.id, command="ack", shortcut=config.shortcut, description=config.description})
- addFloor(message)
- elseif message.command == "ack" then
- addFloor(message)
- elseif message.command == "floorSelect" then
- inUse = true
- if message.floorId == config.id then
- rs.setOutput("front", true)
- expectingArrival = true
- end
- elseif message.command == "cancel" then
- handleCancel()
- elseif message.command == "gotCart" then
- if needCart and not gotCartResponse then
- gotCartResponse = true
- expectingCart = true
- rs.setOutput("front", true)
- rednet.send(senderId, textutils.serialize{type="elevator", sender="main", id = config.id, command="sendCart"})
- end
- elseif message.command == "sendCart" then
- rednet.send(cartDispenserId, textutils.serialize{type="elevator", sender="main", id=config.id, command="sendCart"})
- elseif message.command == "needCart" then
- if checkIfCart() then
- rednet.send(senderId, textutils.serialize{type="elevator", sender="main", id=config.id, command="gotCart"})
- end
- end
- end
- local function handleDispenser(senderId, message)
- if message.command == "announce" then
- if message.id == config.id then
- rednet.send(senderId, textutils.serialize{type="elevator", sender = "main", id=config.id, command="ack", shortcut=config.shortcut, description=config.description})
- cartDispenserId = senderId
- end
- elseif message.command == "ack" then
- cartDispenserId = senderId
- end
- end
- local function doScan()
- while true do
- if expectingCart or expectingArrival then
- switchToProximitySensor()
- local targets = sensor.getTargets()
- for name, target in pairs(targets) do
- if (target.Position.X == config.embarkedCoords.x) and (target.Position.Y == config.embarkedCoords.y) and (target.Position.Z == config.embarkedCoords.z) then
- rs.setOutput("front", false)
- if expectingCart then
- inUse = true
- rednet.broadcast(textutils.serialize{type="elevator", sender="main", id=config.id, command="floorSelect", floorId=floors[selectedFloor].id})
- sleep(.5)
- rednet.send(cartDispenserId, textutils.serialize{type="elevator", sender="main", id=config.id, command="launch"})
- elseif expectingArrival then
- inUse = false
- rednet.broadcast(textutils.serialize{type="elevator", sender="main", id=config.id, command="cancel"})
- rednet.send(cartDispenserId, textutils.serialize{type="elevator", sender="main", id=config.id, command="dispense"})
- handleCancel()
- end
- expectingArrival = false
- expectingCart = false
- end
- end
- end
- sleep(.1)
- end
- end
- local function doNetwork()
- print("Starting network...")
- rednet.broadcast(textutils.serialize{type="elevator", sender = "main", id=config.id, command="announce", shortcut = config.shortcut, description=config.description })
- while true do
- local event, senderId, data, distance = os.pullEvent("rednet_message")
- local message = textutils.unserialize(data)
- if message and message.type == "elevator" then
- if message.sender == "main" then
- handleMain(senderId, message)
- elseif message.sender == "dispenser" then
- handleDispenser(senderId, message)
- end
- end
- end
- end
- local function displayFloorSelection()
- print("Floors available: ")
- for index, floor in ipairs(floors) do
- if index == selectedFloor then
- print(string.format("[ %s: %s ]", floor.shortcut, floor.description))
- else
- print(string.format(" %s: %s ", floor.shortcut, floor.description))
- end
- end
- end
- local function displayCart()
- if not needCart then
- print("Your cart is ready!")
- else
- print("Use cart when arrives.")
- end
- end
- local function displayInUse()
- print("Cart system in use!")
- end
- local function displayNeedCart()
- print("Waiting for cart...")
- end
- local function displayMenu()
- term.clear()
- term.setCursorPos(1,1)
- if expectingCart then
- displayCart()
- elseif inUse then
- displayInUse()
- else
- displayFloorSelection()
- end
- if lastError then print(lastError) end
- print("Press Q to exit C to Cancel Request")
- end
- local function doMenu()
- print("Displaying menu...")
- while true do
- sleep(1)
- displayMenu()
- end
- end
- local function doKeyboard()
- print("Starting keyboard handler...")
- while true do
- local event, key = os.pullEvent()
- if event == "char" then
- if string.lower(key) == "q" then
- break
- elseif string.lower(key) == "c" then
- rednet.broadcast(textutils.serialize{type="elevator", sender="main", id=config.id, command="cancel"})
- handleCancel()
- else
- local keyToCompare = string.lower(key)
- for index, floor in ipairs(floors) do
- if keyToCompare == floor.shortcut then
- selectedFloor = index
- displayMenu()
- chooseFloor()
- break
- end
- end
- end
- elseif event == "key" then
- if key == 200 then
- if selectedFloor > 1 then -- up arrow
- selectedFloor = selectedFloor - 1
- displayMenu()
- end
- elseif key == 208 then
- if selectedFloor < #floors then -- down arrow
- selectedFloor = selectedFloor + 1
- displayMenu()
- end
- elseif key == 28 then -- enter
- chooseFloor()
- end
- end
- end
- end
- local function startup()
- term.clear()
- term.setCursorPos(1,1)
- return parallel.waitForAny(doNetwork, doKeyboard, doMenu, doScan)
- end
- local rtn, error = pcall(startup)
- if not rtn then
- print("Elevator failed: " .. error)
- end
- print("Exiting.")
Advertisement
Add Comment
Please, Sign In to add comment