Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- hostID = 13
- turtleNum = 1
- channel = "storageSys:1"
- chestSize = 54*64
- chestNum = 10*3
- chestName = "minecraft:chest"
- storage = {}
- turtPos = {turtleNum,0,0}
- que = {}
- APK = "APK"
- function init()
- --open rednet--
- if not rednet.isOpen("right") then
- rednet.open("right")
- end
- --get storage--
- fs.delete("storage")
- if fs.exists("storage") then
- local f = fs.open("storage","r")
- storage = textutils.unserialize(f.readAll())
- f.close()
- else
- save("storage",storage)
- end
- storage = {}
- --get que--
- if fs.exists("que") then
- local f = fs.open("que","r")
- que = textutils.unserialize(f.readAll())
- f.close()
- else
- save("que",que)
- end
- que = {}
- --get location--
- fs.delete("location")
- if fs.exists("location") then
- local data = {}
- local f = fs.open("location","r")
- data = textutils.unserialize(f.readAll())
- f.close()
- if data[1] == true then
- turtPos = data[2]
- print("my pos is: ".. turtPos[2].. " " .. turtPos[3])
- else
- findLocation()
- end
- else
- save("location",{false,turtPos})
- findLocation()
- end
- end
- function getTableSize(t)
- local count = 0
- for k in pairs(t) do
- for b in pairs(t[k].pos) do
- count = count + 1
- end
- end
- return count
- end
- function waitForResponse(id,tries)
- if not tries then tries = 3 end
- local sndr,msg,m,nTry = nil,nil,nil,0
- while nTry < tries 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
- return true
- end
- end
- function findLocation()
- print("Finding Location")
- save("location",{false,turtPos})
- repeat turtle.up() until turtle.detectUp()
- for i=1,4 do
- local e, data = turtle.inspect()
- if data then
- print(data.name)
- if data.name ~= chestName then
- turtPos = {turtleNum,0,4}
- break
- end
- end
- turtle.turnRight()
- end
- save("location",{true,turtPos})
- print("location is: ".. turtPos[1].. " "..turtPos[2].." ".. turtPos[3])
- end
- function save(path,data)
- f = fs.open(path,"w")
- f.write(textutils.serialize(data))
- f.close()
- end
- function down()
- while not turtle.down() do end
- end
- function up()
- while not turtle.up() do end
- end
- function goto(start,dest)
- save("location",{false,turtPos})
- local dif = dest[2] - start[2]
- while dif ~= 0 do
- if dif > 0 then
- down()
- dif = dif - 1
- else
- up()
- dif = dif + 1
- end
- end
- while start[3] > dest[3] do
- turtle.turnLeft()
- start[3] = start[3] - 1
- end
- while start[3] < dest[3] do
- turtle.turnRight()
- start[3] = start[3] + 1
- end
- print("at: "..dest[2].. " ".. dest[3])
- turtPos = dest
- save("location",{true,turtPos})
- end
- function listen()
- while true do
- local e = { os.pullEvent() }
- if e[1] == "rednet_message" then
- if e[3] then
- local msg = textutils.unserialize(e[3])
- if msg[1] ~= APK then
- if msg[1] == "request" then
- print("[MSG] "..e[2].. " " ..e[3])
- rednet.send(hostID,textutils.serialize({APK,storage}),channel)
- print("[SNT] ".. e[3].. " " .. "storage")
- else
- rednet.send(e[2],textutils.serialize({APK}),channel)
- table.insert(que,msg)
- end
- end
- end
- elseif e[1] == "timer" then
- if e[2] == "waitForEmpty" then
- waitForEmpty = false
- end
- end
- end
- end
- function pullItems(name,count,b)
- local r = count%64
- local f = math.floor(count/64)
- for i=1,16 do
- if turtle.getItemCount(i) < 1 then
- turtle.select(i)
- break
- end
- end
- for i=1,f do
- turtle.suck(64)
- storage[name].pos[b][4] = storage[name].pos[b][4] - turtle.getItemCount()
- save("storage",storage)
- turtle.dropDown()
- end
- turtle.suck(r)
- storage[name].pos[b][4] = storage[name].pos[b][4] - turtle.getItemCount()
- save("storage",storage)
- turtle.dropDown(r)
- if storage[name].pos[b][4] == 0 then
- table.remove(storage[name].pos,b)
- end
- if storage[name].pos == {} then
- table.remove(storage, name)
- end
- end
- function dropItems(n,c,b)
- print("Dropping: " .. n .. ": "..c)
- for i=1,16 do
- if c <= 0 then break end
- local data = turtle.getItemDetail(i)
- if data then
- if data.name == n then
- turtle.select(i)
- if c > data.count then
- turtle.drop()
- storage[n].pos[b][4] = storage[n].pos[b][4] + data.count
- save("storage",storage)
- c = c - data.count
- else
- turtle.drop(c)
- storage[n].pos[b][4] = storage[n].pos[b][4] + c
- save("storage",storage)
- c = 0
- end
- end
- end
- end
- for l,g in pairs(storage[n].pos) do
- print(l.. " ".. g[3].." ".. g[4])
- end
- end
- function retrieveItems(tbl)
- local count = tbl[2]
- local list = {}
- local pullList = {}
- for k,v in pairs(storage) do
- if storage[tbl[1]] then
- for b in pairs(storage[tbl[1]].pos) do
- table.insert(list,{storage[tbl[1]].pos[b],b})
- end
- end
- end
- table.sort(list, function(a,b) return a[4] < b[4] end)
- for k,v in pairs(list) do
- if count <= 0 then break end
- if v[1][4] - count > 0 then
- table.insert(pullList,{v,count})
- count = count - count
- else
- table.insert(pullList,{v,v[4]})
- count = count - v[1][4]
- end
- end
- for k,v in pairs(pullList) do
- goto(turtPos,pullList[k][1][1])
- pullItems(tbl[1],pullList[k][2],pullList[k][1][2])
- end
- updateHost()
- end
- function checkForItems()
- local trys = 0
- while true do
- if trys > 10 then break end
- while turtle.suckUp() do
- trys = 10 - 2
- end
- sleep(0.2)
- trys = trys + 1
- end
- storeItems()
- end
- function awaitItems(tbl)
- print(tbl[1].. ": "..tbl[2])
- local msg = textutils.serialize({"s",{turtPos[1],tbl[1],tbl[2]}})
- repeat rednet.send(hostID,msg,channel) until waitForResponse(hostID, 3)
- local trys = 0
- while true do
- if trys > 10 then break end
- while turtle.suckUp() do
- trys = 10 - 2
- end
- sleep(0.2)
- trys = trys + 1
- end
- storeItems()
- end
- function findChest()
- local list = {}
- local aList = {}
- for k,v in pairs(storage) do
- for b in pairs(storage[k].pos) do
- table.insert(list,{storage[k].pos[b][1],storage[k].pos[b][2],storage[k].pos[b][3]})
- end
- end
- for i=1,chestNum do
- local p = {turtPos[1],math.floor(i/3),(i%3)+1}
- table.insert(aList,p)
- end
- local space = false
- for k,v in pairs(aList) do
- space = false
- for b,c in pairs(list) do
- if c == v then
- space = true
- break
- end
- end
- if not space then
- print("Free Chest: "..v[2].. " ".. v[3])
- table.insert(v,0)
- return v
- end
- end
- return false
- end
- function storeItems()
- for i=1,16 do
- local chestList = {}
- local data,dt = nil
- local c = 0
- data = turtle.getItemDetail(i)
- if data then
- c = c + data.count
- --check to see if there are more like items--
- for b=i,16 do
- dt = turtle.getItemDetail(b)
- if dt then
- if dt.name == data.name then
- c = c + dt.count
- end
- end
- end
- --find a chest for items--
- local nm = data.name
- if storage[nm] then
- for v in pairs(storage[nm].pos) do
- print(nm.. ": ".. storage[nm].pos[v][2].. " ".. storage[nm].pos[v][3])
- if storage[nm].pos[v][4] + c <= chestSize then
- table.insert(chestList,{nm,storage[nm].pos[v],c,v})
- c = 0
- else
- local tmpA = chestSize - storage[nm].pos[v][4]
- table.insert(chestList, {nm,storage[nm].pos[v],tmpA,v})
- c = c - tmpA
- end
- end
- end
- --generate new chest--
- if c > 0 then
- print("Gen Chest: " .. nm .. " "..c)
- local nxtChest = findChest()
- if nxtChest then
- if storage[nm] then
- storage[nm].pos[#storage[nm].pos + 1] = nxtChest
- else
- storage[nm] = {pos={}}
- storage[nm].pos[1] = nxtChest
- end
- table.insert(chestList,{nm,nxtChest,c,#storage[nm].pos})
- else
- print("No Chest Found")
- table.insert(chestList,{nm,{-1},c,0})
- end
- end
- --move to all chest--
- for k,v in pairs(chestList) do
- if chestList[k][2][1] >= 0 then
- goto(turtPos,chestList[k][2])
- dropItems(chestList[k][1],chestList[k][3],chestList[k][4])
- else
- local amt = chestList[k][3]
- for i=1,16 do
- local d = turtle.getItemDetail(i)
- if d then
- if d.name == chestList[k][1] then
- turtle.select(i)
- if amt > 63 then
- turtle.dropDown()
- amt = amt - d.count
- else
- turtle.dropDown(amt)
- amt = amt - d.count
- end
- end
- end
- end
- end
- end
- updateHost()
- end
- end
- end
- function updateHost()
- local msg = textutils.serialize({"u",{turtPos[1],storage}})
- repeat rednet.send(hostID,msg,channel) until waitForResponse(hostID,3)
- 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] == "a" then
- print("await items")
- awaitItems(que[1][2])
- elseif que[1][1] == "s" then
- print("store items")
- storeItems(que[1][2])
- end
- table.remove(que,1)
- print("que: " .. #que)
- end
- sleep(1)
- checkForItems()
- end
- end
- init()
- parallel.waitForAll(listen,taskManager)
Add Comment
Please, Sign In to add comment