Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- turts = {15}
- redstone = {2}
- chestSize = 54*64
- chestNum = 10*3
- channel = "storageSys:1"
- APK = "APK"
- storage = {}
- que = {}
- waitToEmpty = false
- wait = nil
- function init()
- --open rednet--
- if not rednet.isOpen("right") then
- rednet.open("right")
- end
- sleep(10)
- for k,v in pairs(redstone) do
- rednet.send(v,"off",channel)
- end
- -- call all our turtles and get storage info--
- callTurtles()
- return true
- end
- function waitForResponse(id,tries)
- if not tries then tries = 3 end
- local sndr,msg,nTry = nil,nil,0
- while true do
- if nTry > tries then break end
- sndr,m = rednet.receive(channel,1)
- if m then
- msg = textutils.unserialize(m)
- end
- if sndr == id then
- if msg[1] == APK then
- return msg
- end
- elseif not sndr then
- nTry = nTry + 1
- end
- end
- return true
- end
- function getTableSize(t)
- local count = 0
- for _ in pairs(t) do
- count = count + 1
- end
- return count
- end
- function callTurtles()
- local req = textutils.serialize({"request"})
- print("Pinging Turtles")
- for i=1,#turts do
- rednet.send(turts[i],req,channel)
- local data = waitForResponse(turts[i],3)
- if data ~= true then
- if data[2] then
- storage[i] = data[2]
- print("Recieved Storage from: "..i)
- else
- print("Couldnt get storage: "..i)
- end
- end
- end
- if #storage == #turts then
- return true
- else
- return false
- end
- end
- function sendItems(tbl)
- turtle.select(1)
- local count = tbl[3]
- rednet.send(redstone[tbl[1]],"on",channel)
- for i=1,16 do
- if count <= 0 then break end
- local data = turtle.getItemDetail(i)
- if data then
- if data.name == tbl[2] then
- turtle.select(i)
- if count > 63 then
- turtle.drop()
- count = count - data.count
- else
- turtle.drop(count)
- count = count - data.count
- end
- end
- end
- end
- sleep(3)
- rednet.send(redstone[tbl[1]],"off",channel)
- end
- function retrieveItems(tbl)
- local name,count = tbl[2],tbl[3]
- local sendList = {}
- local list = {}
- for k in pairs(storage) do
- if storage[k][name] then
- for b in pairs(storage[k][name].pos) do
- table.insert(list,storage[k][name].pos[b])
- end
- end
- end
- table.sort(list, function(a,b) return a[4] < b[4] end)
- for k,v in ipairs(list) do
- if count <= 0 then break end
- if v[4] >= count then
- table.insert(sendList,{v[1],count})
- count = 0
- else
- table.insert(sendList,{v[1],v[4]})
- count = count - v[4]
- end
- end
- for k,v in pairs(sendList) do
- local msg = textutils.serialize({"r",{name,v[4]}})
- repeat rednet.send(turts[v[1]],msg,channel) until waitForResponse(turts[v[1]],2)
- end
- end
- function queryItems(tbl)
- if not tbl[2] then
- msg = textutils.serialize(storage)
- else
- local count = 0
- for k in pairs(storage) do
- if storage[k][tbl[2]] then
- for b,c in pairs(storage[k][tbl[2]].pos) do
- count = count + storage[k][tbl[2]].pos[b][4]
- end
- end
- end
- msg = textutils.serialize({tbl[2],count})
- end
- rednet.send(tbl[1],msg,channel)
- end
- function checkForSpace(name,c)
- local list = {}
- for k in pairs(storage) do
- if storage[k][name] then
- for b in pairs(storage[k][name].pos) do
- if c <= 0 then return list end
- if chestSize - storage[k][name].pos[b][4] > c then
- if not list[k] then
- list[k] = c
- else
- list[k] = list[k] + c
- end
- c = 0
- else
- local count = chestSize - storage[k][name].pos[b][4]
- if not list[k] then
- list[k] = count
- else
- list[k] = list[k] + count
- end
- c = c - count
- end
- end
- end
- end
- if c > 0 then
- local small = -1
- local prevSmall = math.huge
- for i,v in pairs(storage) do
- local count = 0
- for k,c in pairs(storage[i]) do
- count = count + getTableSize(storage[i][k].pos)
- end
- if count < prevSmall then
- prevSmall = count
- small = i
- end
- end
- if prevSmall >= chestSize*chestNum then
- list["full"] = c
- else
- if list[small] then
- list[small] = list[small] + c
- else
- list[small] = c
- end
- end
- c = 0
- end
- return list
- end
- function prepareTurtle(tbl)
- local list = {}
- for k,v in pairs(tbl) do
- list[k] = checkForSpace(k,v)
- end
- for k,v in pairs(list) do
- for b in pairs(list[k]) do
- local msg = textutils.serialize({"a",{k,list[k][b]}})
- repeat rednet.send(turts[b],msg,channel) until waitForResponse(turts[b])
- end
- end
- wait = os.startTimer(95)
- waitToEmpty = true
- end
- function checkForItems()
- local list = {}
- if not waitToEmpty then
- if turtle.suckUp() then
- local trys = 0
- while true do
- if trys > 4 then break end
- while turtle.suckUp() do end
- trys = trys + 1
- sleep(0.5)
- end
- end
- for i=1,16 do
- local data = turtle.getItemDetail(i)
- if data then
- if not list[data.name] then
- list[data.name] = data.count
- else
- list[data.name] = list[data.name] + data.count
- end
- end
- end
- prepareTurtle(list)
- else
- for i=1,16 do
- if turtle.getItemCount(i) > 0 then
- break
- end
- waitToEmpty = false
- os.cancelTimer(wait)
- end
- end
- end
- function updateStorage(tbl)
- storage[tbl[1]] = tbl[2]
- end
- function listen()
- while true do
- e = {}
- e = { os.pullEvent() }
- if e[1] == "rednet_message" then
- if e[2] ~= os.getComputerID() then
- if e[3] then
- print(e[2].. ": ".. e[3])
- local msg = textutils.unserialize(e[3])
- print("[MSG] "..e[2].." " ..msg[1])
- print(msg[1])
- if msg[1] ~= APK then
- if msg[1] == "u" then
- updateStorage(msg[2])
- else
- table.insert(que,msg)
- end
- rednet.send(e[2],textutils.serialize({APK}),channel)
- end
- end
- end
- elseif e[1] == "timer" then
- if e[2] == "wait" then
- waitToEmpty = false
- end
- end
- end
- end
- function taskManager()
- while true do
- while que[1] do
- if que[1][1] == "r" then
- print("retrieve items")
- retrieveItems(que[1][2])
- elseif que[1][1] == "s" then
- print("send Items")
- sendItems(que[1][2])
- elseif que[1][1] == "q" then
- print("query items")
- queryItems(que[1][2])
- end
- table.remove(que ,1)
- end
- checkForItems()
- sleep(1)
- end
- end
- init()
- while not storage[1] do
- sleep(5)
- callTurtles()
- end
- parallel.waitForAll(listen,taskManager)
Add Comment
Please, Sign In to add comment