SHOW:
|
|
- or go back to the newest paste.
| 1 | --slots = textutils.unserialize( fs.open("slots","r").readAll() )
| |
| 2 | --nObjective = 1 | |
| 3 | --instructions = textutils.unserialize( fs.open("instructions","r").readAll() )
| |
| 4 | ||
| 5 | ||
| 6 | ||
| 7 | --instructions[n] = {x,y,z,id,data}
| |
| 8 | ||
| 9 | function getLength(checklist) | |
| 10 | local c = 0 | |
| 11 | for i,v in pairs(checklist) do | |
| 12 | for k,l in pairs(v) do | |
| 13 | if l then | |
| 14 | c = c + 1 | |
| 15 | end | |
| 16 | end | |
| 17 | end | |
| 18 | return c | |
| 19 | end | |
| 20 | ||
| 21 | function getSlotsUsed(checklist) | |
| 22 | local c = 0 | |
| 23 | local count = 0 | |
| 24 | for id,table in pairs(checklist) do | |
| 25 | for data,count in pairs(table) do | |
| 26 | c = c + math.ceil(count/64) | |
| 27 | end | |
| 28 | end | |
| 29 | return c | |
| 30 | end | |
| 31 | ||
| 32 | function sort() | |
| 33 | items = {}
| |
| 34 | for i = 1,16 do | |
| 35 | local item = turtle.getItemDetail(i) | |
| 36 | if item then | |
| 37 | local pSlot = nil | |
| 38 | if items[item.name] then | |
| 39 | pSlot = items[item.name][item.damage] | |
| 40 | end | |
| 41 | if pSlot then | |
| 42 | turtle.select(i) | |
| 43 | turtle.transferTo(pSlot) | |
| 44 | if turtle.getItemCount(pSlot) == 64 then | |
| 45 | if turtle.getItemCount(i) > 0 then | |
| 46 | items[item.name][item.damage] = i | |
| 47 | else | |
| 48 | items[item.name][item.damage] = nil | |
| 49 | end | |
| 50 | end | |
| 51 | elseif turtle.getItemCount(i) < 64 then | |
| 52 | if not items[item.name] then | |
| 53 | items[item.name] = {}
| |
| 54 | end | |
| 55 | items[item.name][item.damage] = i | |
| 56 | end | |
| 57 | end | |
| 58 | end | |
| 59 | end | |
| 60 | ||
| 61 | local function add2checklist(checklist,name,damage,slots_available) | |
| 62 | --checklist[id][data] = count version | |
| 63 | --INPUT: item, checklist | |
| 64 | --OUTPUT: added to checklist if there's space | |
| 65 | slots_available = slots_available or 15 | |
| 66 | local numCheckList = getSlotsUsed(checklist) | |
| 67 | ||
| 68 | if name == nil then | |
| 69 | return checklist | |
| 70 | end | |
| 71 | ||
| 72 | if checklist[name] and checklist[name][damage] then | |
| 73 | checklist[name][damage] = checklist[name][damage] + 1 | |
| 74 | if getSlotsUsed(checklist) > slots_available then | |
| 75 | checklist[name][damage] = checklist[name][damage] - 1 | |
| 76 | return checklist,true | |
| 77 | else | |
| 78 | return checklist | |
| 79 | end | |
| 80 | end | |
| 81 | ||
| 82 | if numCheckList < slots_available then | |
| 83 | if checklist[name] then | |
| 84 | checklist[name][damage] = 1 | |
| 85 | else | |
| 86 | checklist[name] = {}
| |
| 87 | checklist[name][damage] = 1 | |
| 88 | end | |
| 89 | else | |
| 90 | --error("checklist full")
| |
| 91 | return checklist,true | |
| 92 | end | |
| 93 | return checklist | |
| 94 | end | |
| 95 | ||
| 96 | function checklistMaker(nObjective,instructions,slots) | |
| 97 | --INPUT: nObjective,instructions,slots | |
| 98 | --OUTPUT: next 15 invo spaces worth of blocks required in checklist[id][data] = count | |
| 99 | local checklist = {}
| |
| 100 | ||
| 101 | for i = nObjective,#instructions do | |
| 102 | local name,damage = unpack(slots[ instructions[i][4] ][ instructions[i][5] ]) | |
| 103 | checklist,bFull = add2checklist(checklist,name,damage,15) | |
| 104 | if bFull then | |
| 105 | return checklist | |
| 106 | end | |
| 107 | end | |
| 108 | ||
| 109 | return checklist | |
| 110 | end | |
| 111 | ||
| 112 | local function insert_rubbish(rubbishList,id,data,count) | |
| 113 | if not id then | |
| 114 | return | |
| 115 | end | |
| 116 | if not rubbishList[id] then | |
| 117 | rubbishList[id]= {}
| |
| 118 | end | |
| 119 | if not rubbishList[id][data] then | |
| 120 | rubbishList[id][data] = 0 | |
| 121 | end | |
| 122 | rubbishList[id][data] = rubbishList[id][data] + count | |
| 123 | return rubbishList | |
| 124 | end | |
| 125 | ||
| 126 | local function flatten_checklist(checklist,rubbishList) | |
| 127 | --get rid of negative count in checklist | |
| 128 | for id,table in pairs(checklist) do | |
| 129 | for data,count in pairs(table) do | |
| 130 | if count < 0 then | |
| 131 | rubbishList = insert_rubbish(rubbishList,id,data,math.abs(count)) | |
| 132 | checklist[id][data] = 0 | |
| 133 | end | |
| 134 | end | |
| 135 | end | |
| 136 | return checklist,rubbishList | |
| 137 | end | |
| 138 | ||
| 139 | function subtractInventory(checklist) | |
| 140 | local rubbishList = {}
| |
| 141 | for i = 1,16 do | |
| 142 | local deets = turtle.getItemDetail(i) | |
| 143 | ||
| 144 | if deets then | |
| 145 | if checklist[deets.name] and checklist[deets.name][deets.damage] then | |
| 146 | checklist[deets.name][deets.damage] = checklist[deets.name][deets.damage] - deets.count | |
| 147 | elseif (not deets.name:lower():find("wrench")) and (not deets.name:lower():find("hammer")) then
| |
| 148 | --not a wrench, not on the list | |
| 149 | insert_rubbish(rubbishList,deets.name,deets.damage,deets.count) | |
| 150 | end | |
| 151 | end | |
| 152 | end | |
| 153 | checklist,rubbishList = flatten_checklist(checklist,rubbishList) | |
| 154 | return checklist,rubbishList | |
| 155 | end | |
| 156 | ||
| 157 | function find_in_turtle(id,data) | |
| 158 | for i = 1,16 do | |
| 159 | local deets = turtle.getItemDetail(i) | |
| 160 | if deets and (deets.name == id and deets.damage == data) then | |
| 161 | return i,deets.count | |
| 162 | end | |
| 163 | end | |
| 164 | return nil | |
| 165 | end | |
| 166 | ||
| 167 | function throw_away(rubbishList,intoSlot) | |
| 168 | for id,table in pairs(rubbishList) do | |
| 169 | for data,count in pairs(table) do | |
| 170 | if count > 0 then | |
| 171 | local slot, amount = find_in_turtle(id,data) | |
| 172 | if amount >= count then | |
| 173 | --peripheral.call("bottom","pushItem","down",slot,count,intoSlot)
| |
| 174 | rubbishList[id][data] = 0 | |
| 175 | else | |
| 176 | local mem = turtle.getSelectedSlot() | |
| 177 | while amount < count do | |
| 178 | local i,amount_transferred = find_in_turtle(id,data) | |
| 179 | if i then | |
| 180 | turtle.select(i) | |
| 181 | turtle.transferTo(mem) | |
| 182 | local remainder = turtle.getItemCount() | |
| 183 | amount = amount + (amount_transferred-remainder) | |
| 184 | end | |
| 185 | ||
| 186 | end | |
| 187 | turtle.select(mem) | |
| 188 | end | |
| 189 | --pushItem(direction,slot,maxAmount?,intoSlot?) | |
| 190 | peripheral.call("bottom","pushItem","down",slot,amount,intoSlot)
| |
| 191 | end | |
| 192 | end | |
| 193 | end | |
| 194 | end | |
| 195 | ||
| 196 | ||
| 197 | ||
| 198 | function save(table,filename) | |
| 199 | local h = fs.open(filename,"w") | |
| 200 | if fs.exists("textutilsFIX") then
| |
| 201 | os.loadAPI("textutilsFIX")
| |
| 202 | h.write(textutilsFIX.serialize(table)) | |
| 203 | else | |
| 204 | h.write(textutils.serialize(table)) | |
| 205 | end | |
| 206 | h.close() | |
| 207 | end | |
| 208 | --throwAway file | |
| 209 | ||
| 210 | function db(entity,name) | |
| 211 | local h = fs.open("console","a")
| |
| 212 | name = name or "" | |
| 213 | os.loadAPI("textutilsFIX")
| |
| 214 | if type(entity) == "table" then | |
| 215 | h.writeLine(name..": "..textutilsFIX.serialize(table)) | |
| 216 | else | |
| 217 | h.writeLine(name..": "..tostring(entity)) | |
| 218 | end | |
| 219 | h.close() | |
| 220 | end | |
| 221 | ||
| 222 | function find_in_turtle(id,data) | |
| 223 | for i = 1,16 do | |
| 224 | local deets = turtle.getItemDetail(i) | |
| 225 | if deets and (deets.name == id and deets.damage == data) then | |
| 226 | return i,deets.count | |
| 227 | end | |
| 228 | end | |
| 229 | return nil | |
| 230 | end | |
| 231 | ||
| 232 | - | function findEmptySlots(chest) |
| 232 | + | function findEmptySlots(chest,inv) |
| 233 | - | local randomTable = {}
|
| 233 | + | |
| 234 | - | for i,v in pairs(chest) do |
| 234 | + | |
| 235 | - | table.insert(randomTable,i) |
| 235 | + | |
| 236 | emptySlots = emptySlots + 1 | |
| 237 | - | return #randomTable |
| 237 | + | |
| 238 | end | |
| 239 | return emptySlots | |
| 240 | - | function findEmptySlotsOLD(chest,inv) |
| 240 | + | |
| 241 | ||
| 242 | function throwAway2(rubbishList,chest,inv) | |
| 243 | local emptySlots = findEmptySlots(chest,inv) | |
| 244 | assert(emptySlots) | |
| 245 | --print("emptySlots = ",emptySlots)
| |
| 246 | for i = 1,16 do | |
| 247 | local count = nil | |
| 248 | local deets = turtle.getItemDetail(i) | |
| 249 | if rubbishList and deets and rubbishList[deets.name] then | |
| 250 | count = rubbishList[deets.name][deets.damage] | |
| 251 | end | |
| 252 | if count and count > 0 and emptySlots > 0 then | |
| 253 | turtle.select(i) | |
| 254 | local amount = turtle.getItemCount(i) | |
| 255 | if amount > count then | |
| 256 | turtle.dropDown(count) | |
| 257 | count = 0 | |
| 258 | elseif count <= 64 then | |
| 259 | turtle.dropDown(count) | |
| 260 | count = 0 | |
| 261 | else | |
| 262 | turtle.dropDown() | |
| 263 | count = count - 64 | |
| 264 | end | |
| 265 | emptySlots = emptySlots - 1 | |
| 266 | rubbishList[deets.name][deets.damage] = count | |
| 267 | end | |
| 268 | end | |
| 269 | return rubbishList | |
| 270 | end | |
| 271 | ||
| 272 | function take(chest_slot,amount,me,chest) | |
| 273 | sort() | |
| 274 | if me then | |
| 275 | peripheral.call("bottom","exportItem",chest[chest_slot].fingerprint,"up",amount)
| |
| 276 | else | |
| 277 | peripheral.call("bottom","pushItem","up",chest_slot,amount)
| |
| 278 | end | |
| 279 | end | |
| 280 | ||
| 281 | function take2(chest_slot,amount) | |
| 282 | assert(chest_slot) | |
| 283 | amount = amount or 64 | |
| 284 | peripheral.call("bottom","swapStacks",chest_slot,1)
| |
| 285 | turtle.suckDown(amount) | |
| 286 | end | |
| 287 | ||
| 288 | function pullBlocks(checklist,chest) | |
| 289 | local me = false | |
| 290 | if peripheral.call("bottom","getInventoryName") == "TileInterface" then
| |
| 291 | me = true | |
| 292 | end | |
| 293 | assert(checklist) | |
| 294 | assert(chest) | |
| 295 | for chest_slot,func in pairs(chest) do | |
| 296 | - | function pullBlocks(checklist,chest,invType) |
| 296 | + | |
| 297 | if me then | |
| 298 | - | if invType == "TileInterface" then |
| 298 | + | |
| 299 | damage = func.fingerprint.dmg | |
| 300 | qty = func.size | |
| 301 | else | |
| 302 | name = func.basic().id | |
| 303 | db(name,chest_slot) | |
| 304 | damage = func.basic().dmg | |
| 305 | db(damage,"dmg") | |
| 306 | qty = func.basic().qty | |
| 307 | db(qty,"qty") | |
| 308 | end | |
| 309 | local checklist_count = nil | |
| 310 | if checklist and checklist[name] then | |
| 311 | checklist_count = checklist[name][damage] | |
| 312 | end | |
| 313 | if checklist_count and checklist_count > 0 then | |
| 314 | --take | |
| 315 | ||
| 316 | if checklist_count <= qty then | |
| 317 | --take checklist_count amount | |
| 318 | take(chest_slot,checklist_count,me,chest) | |
| 319 | checklist_count = 0 | |
| 320 | db(name," name") | |
| 321 | db(checklist_count," checklist_count") | |
| 322 | db(qty," qty") | |
| 323 | elseif checklist_count>=64 then | |
| 324 | --take 64 | |
| 325 | take(chest_slot,64,me,chest) | |
| 326 | checklist_count = checklist_count - 64 | |
| 327 | db(name," name") | |
| 328 | db(checklist_count," checklist_count") | |
| 329 | db(qty," qty") | |
| 330 | elseif checklist_count > qty then | |
| 331 | --take qty | |
| 332 | take(chest_slot,qty,me,chest) | |
| 333 | checklist_count = checklist_count - qty | |
| 334 | db(name," name") | |
| 335 | db(checklist_count," checklist_count") | |
| 336 | db(qty," qty") | |
| 337 | else | |
| 338 | db(name," NOT COUNTED") | |
| 339 | db(damage) | |
| 340 | db(qty) | |
| 341 | end | |
| 342 | ||
| 343 | ||
| 344 | checklist[name][damage] = checklist_count | |
| 345 | end | |
| 346 | end | |
| 347 | return checklist | |
| 348 | end | |
| 349 | ||
| 350 | function check_chests(checklist,rubbishList) | |
| 351 | --if openperipherals | |
| 352 | if reference.multiturtle and reference.returnx and reference.returny and reference.returnz then | |
| 353 | goto(reference.finalx+1,reference.returny,reference.returnz) | |
| 354 | goto(reference.returnx,reference.returny,reference.returnz) | |
| 355 | else | |
| 356 | goto(heightPos,reference.starty,reference.startz-1) | |
| 357 | goto(reference.startx,reference.starty,reference.startz-1) | |
| 358 | end | |
| 359 | local i = 1 | |
| 360 | - | --if reference.multiturtle and reference.returnx and reference.returny and reference.returnz then |
| 360 | + | |
| 361 | local numChests = 0 | |
| 362 | while true do | |
| 363 | - | --else |
| 363 | + | if reference.multiturtle then |
| 364 | - | --goto(heightPos,reference.starty,reference.startz-1) |
| 364 | + | |
| 365 | - | --goto(reference.startx,reference.starty,reference.startz-1) |
| 365 | + | |
| 366 | - | --end |
| 366 | + | goto(reference.startx,reference.starty,reference.startz-i) |
| 367 | end | |
| 368 | local inv = peripheral.call("bottom","getInventorySize")
| |
| 369 | local invType = peripheral.call("bottom","getInventoryName")
| |
| 370 | ||
| 371 | - | --if reference.multiturtle then |
| 371 | + | if inv and inv > 0 then |
| 372 | local chest | |
| 373 | - | --else |
| 373 | + | |
| 374 | - | --goto(reference.startx,reference.starty,reference.startz-i) |
| 374 | + | |
| 375 | - | --end |
| 375 | + | |
| 376 | - | --local inv = peripheral.call("bottom","getInventorySize")
|
| 376 | + | |
| 377 | - | --local invType = peripheral.call("bottom","getInventoryName")
|
| 377 | + | |
| 378 | - | local invType = false |
| 378 | + | |
| 379 | - | local lookSee,lookData = turtle.inspectDown() |
| 379 | + | |
| 380 | - | if lookSee then |
| 380 | + | rubbishList = throwAway2(rubbishList,chest,inv) |
| 381 | - | if lookData.name:find("chest") then
|
| 381 | + | |
| 382 | - | invType = true |
| 382 | + | checklist = pullBlocks(checklist,chest) |
| 383 | - | elseif lookData.name:find("tile.BlockInterface") then
|
| 383 | + | |
| 384 | - | invType = "TileInterface" |
| 384 | + | |
| 385 | if not reference.numChests then | |
| 386 | if invType == "TileInterface" then | |
| 387 | reference.numChests = numChests | |
| 388 | updateVar(reference.filename,"reference.numChests",numChest) --needs testing | |
| 389 | - | if invType then |
| 389 | + | break |
| 390 | end | |
| 391 | end | |
| 392 | --if (everything checked off) then | |
| 393 | --go back to building | |
| 394 | --end | |
| 395 | if reference.numChests == numChests then | |
| 396 | --print("ok stop here")
| |
| 397 | break | |
| 398 | - | rubbishList = throwAway2(rubbishList,chest) |
| 398 | + | |
| 399 | else | |
| 400 | - | checklist = pullBlocks(checklist,chest,invType) |
| 400 | + | |
| 401 | if noInvo == 2 and numChests == 0 then | |
| 402 | error("needs refill chest within 2 blocks behind start location under the turtle")
| |
| 403 | end | |
| 404 | if noInvo == 3 then | |
| 405 | reference.numChests = numChests | |
| 406 | - | if invType == "TileInterface" and not reference.numChests then |
| 406 | + | |
| 407 | break | |
| 408 | end | |
| 409 | end | |
| 410 | ||
| 411 | i = i + 1 | |
| 412 | end | |
| 413 | --print("stop")
| |
| 414 | save(rubbishList,"rubbishList") | |
| 415 | save(checklist,"checklist") | |
| 416 | end | |
| 417 | ||
| 418 | ||
| 419 | --checklist = checklistMaker(1,instructions,slots) | |
| 420 | --checklist, rubbishList = subtractInventory(checklist) | |
| 421 | ||
| 422 | --save(checklist,"checklist") | |
| 423 | --save(rubbishList,"rubbishList") |