SHOW:
|
|
- or go back to the newest paste.
| 1 | --made by me | |
| 2 | --setup() made by orwell | |
| 3 | ||
| 4 | local tArgs = { ... }
| |
| 5 | if #tArgs < 1 then | |
| 6 | error("Usage: blueprint <gunzipped schematic file>")
| |
| 7 | end | |
| 8 | ||
| 9 | if not fs.exists("textutilsFIX") then
| |
| 10 | shell.run("pastebin get 3wguFBXn textutilsFIX")
| |
| 11 | end | |
| 12 | ||
| 13 | if not fs.exists("grid") then
| |
| 14 | shell.run("pastebin get EjYUEQqx grid")
| |
| 15 | end | |
| 16 | ||
| 17 | shell.run("grid")
| |
| 18 | os.loadAPI("textutilsFIX")
| |
| 19 | ||
| 20 | local filename = tArgs[1] | |
| 21 | ||
| 22 | if not fs.exists(filename) then | |
| 23 | error("File does not exist.")
| |
| 24 | end | |
| 25 | ||
| 26 | function save(name,table) | |
| 27 | local h = fs.open(name,"w") | |
| 28 | table = textutils.serialize(table) | |
| 29 | h.write(table) | |
| 30 | h.close() | |
| 31 | end | |
| 32 | ||
| 33 | function saveIns(name,table) | |
| 34 | local h = fs.open(name,"w") | |
| 35 | h.writeLine(name.." = {}")
| |
| 36 | for i,coord in pairs(table) do | |
| 37 | h.writeLine(name.."["..i.."] = {"..table.concat(coord,",").."}")
| |
| 38 | - | function saveBlueprint(reference,slots,instructions,uniqueblocks) |
| 38 | + | |
| 39 | end | |
| 40 | h.close() | |
| 41 | end | |
| 42 | ||
| 43 | function saveBlueprint(reference,slots,instructions,uniqueblocks,nTurtle) | |
| 44 | local fname = filename:gsub("%.(.*)","")..".blueprint"
| |
| 45 | if nTurtle then | |
| 46 | fname = fname.."["..tostring(nTurtle).."]" | |
| 47 | end | |
| 48 | local h = fs.open(fname,"w") | |
| 49 | h.writeLine("reference ="..textutils.serialize(reference)..";")
| |
| 50 | h.writeLine("slots = "..textutils.serialize(slots)..";")
| |
| 51 | h.writeLine("uniqueblocks = "..textutils.serialize(uniqueblocks)..";")
| |
| 52 | h.writeLine("instructions = "..textutilsFIX.serialize(instructions)..";")
| |
| 53 | h.close() | |
| 54 | return fname | |
| 55 | end | |
| 56 | ||
| 57 | local block_id = {}
| |
| 58 | ||
| 59 | block_id[0] = "Air" | |
| 60 | block_id[1] = "Stone" | |
| 61 | block_id[2] = "Grass" | |
| 62 | block_id[3] = "Dirt" | |
| 63 | block_id[4] = "Cobblestone" | |
| 64 | block_id[5] = "Wood Planks" | |
| 65 | block_id[6] = "Sapling" | |
| 66 | block_id[7] = "Bedrock" | |
| 67 | block_id[8] = "Water" | |
| 68 | block_id[9] = "Stationary water" | |
| 69 | block_id[10] = "Lava" | |
| 70 | block_id[11] = "Stationary lava" | |
| 71 | block_id[12] = "Sand" | |
| 72 | block_id[13] = "Gravel" | |
| 73 | block_id[14] = "Gold Ore" | |
| 74 | block_id[15] = "Iron (Ore)" | |
| 75 | block_id[16] = "Coal Ore" | |
| 76 | block_id[17] = "Wood" | |
| 77 | block_id[18] = "Leaves" | |
| 78 | block_id[19] = "Sponge" | |
| 79 | block_id[20] = "Glass" | |
| 80 | block_id[21] = "Lapis Lazuli (Ore)" | |
| 81 | block_id[22] = "Lapis Lazuli (Block)" | |
| 82 | block_id[23] = "Dispenser" | |
| 83 | block_id[24] = "Sandstone" | |
| 84 | block_id[25] = "Note Block Tile entity" | |
| 85 | block_id[26] = "Bed" | |
| 86 | block_id[27] = "Powered Rail " | |
| 87 | block_id[28] = "Detector Rail " | |
| 88 | block_id[29] = "Sticky Piston" | |
| 89 | block_id[30] = "Cobweb" | |
| 90 | block_id[31] = "Tall Grass" | |
| 91 | block_id[32] = "Dead Bush" | |
| 92 | block_id[33] = "Piston" | |
| 93 | block_id[34] = "Piston Extension" | |
| 94 | block_id[35] = "Wool" | |
| 95 | block_id[36] = "Block moved by Piston" | |
| 96 | block_id[37] = "Dandelionandelion" | |
| 97 | block_id[38] = "Rose" | |
| 98 | block_id[39] = "Brown Mushroom" | |
| 99 | block_id[40] = "Red Mushroom" | |
| 100 | block_id[41] = "Block of Gold" | |
| 101 | block_id[42] = "Block of Iron" | |
| 102 | block_id[43] = "Double Slabs" | |
| 103 | block_id[44] = "Slabs" | |
| 104 | block_id[45] = "Brick Block" | |
| 105 | block_id[46] = "TNT" | |
| 106 | block_id[47] = "Bookshelf" | |
| 107 | block_id[48] = "Moss Stone" | |
| 108 | block_id[49] = "Obsidian" | |
| 109 | block_id[50] = "Torch" | |
| 110 | block_id[51] = "Fire" | |
| 111 | block_id[52] = "Monster Spawner" | |
| 112 | block_id[53] = "Wooden Stairs" | |
| 113 | block_id[54] = "Chest" | |
| 114 | block_id[55] = "Redstone (Wire)" | |
| 115 | block_id[56] = "Diamond (Ore)" | |
| 116 | block_id[57] = "Block of Diamond" | |
| 117 | block_id[58] = "Crafting Table" | |
| 118 | block_id[59] = "Seeds" | |
| 119 | block_id[60] = "Farland" | |
| 120 | block_id[61] = "Furnace" | |
| 121 | block_id[62] = "Burning Furnace" | |
| 122 | block_id[63] = "Sign Post" | |
| 123 | block_id[64] = "Wooden Door" | |
| 124 | block_id[65] = "Ladders" | |
| 125 | block_id[66] = "Rails" | |
| 126 | block_id[67] = "Cobblestone Stairs" | |
| 127 | block_id[68] = "Wall Sign" | |
| 128 | block_id[69] = "Lever" | |
| 129 | block_id[70] = "Stone Pressure Plate" | |
| 130 | block_id[71] = "Iron Door" | |
| 131 | block_id[72] = "Wooden Pressure Plates" | |
| 132 | block_id[73] = "Redstone Ore" | |
| 133 | block_id[74] = "Glowing Redstone Ore" | |
| 134 | block_id[75] = "Redstone Torch" | |
| 135 | block_id[76] = "Redstone Torch" | |
| 136 | block_id[77] = "Stone Button " | |
| 137 | block_id[78] = "Snow" | |
| 138 | block_id[79] = "Ice" | |
| 139 | block_id[80] = "Snow Block" | |
| 140 | block_id[81] = "Cactus" | |
| 141 | block_id[82] = "Clay (Block)" | |
| 142 | block_id[83] = "Sugar Cane" | |
| 143 | block_id[84] = "Jukebox" | |
| 144 | block_id[85] = "Fence" | |
| 145 | block_id[86] = "Pumpkin" | |
| 146 | block_id[87] = "Netherrack" | |
| 147 | block_id[88] = "Soul Sand" | |
| 148 | block_id[89] = "Glowstone" | |
| 149 | block_id[90] = "Portal" | |
| 150 | block_id[91] = "Jack-O-Lantern" | |
| 151 | block_id[92] = "Cake Block" | |
| 152 | block_id[93] = "Redstone Repeater" | |
| 153 | block_id[94] = "Redstone Repeater" | |
| 154 | block_id[95] = "Stained Glass" | |
| 155 | block_id[96] = "Trapdoors" | |
| 156 | block_id[97] = "Hidden Silverfish" | |
| 157 | block_id[98] = "Stone Bricks" | |
| 158 | block_id[99] = "Huge brown and red mushroom" | |
| 159 | block_id[100] = "Huge brown and red mushroom" | |
| 160 | block_id[101] = "Iron Bars" | |
| 161 | block_id[102] = "Glass Pane" | |
| 162 | block_id[103] = "Melon" | |
| 163 | block_id[104] = "Pumpkin Stem" | |
| 164 | block_id[105] = "Melon Stem" | |
| 165 | block_id[106] = "Vines" | |
| 166 | block_id[107] = "Fence Gate" | |
| 167 | block_id[108] = "Brick Stairs" | |
| 168 | block_id[109] = "Stone Brick Stairs" | |
| 169 | block_id[110] = "Mycelium" | |
| 170 | block_id[111] = "Lily Pad" | |
| 171 | block_id[112] = "Nether Brick" | |
| 172 | block_id[113] = "Nether Brick Fence" | |
| 173 | block_id[114] = "Nether Brick Stairs" | |
| 174 | block_id[115] = "Nether Wart" | |
| 175 | block_id[116] = "Enchantment Table" | |
| 176 | block_id[117] = "Brewing Stand" | |
| 177 | block_id[118] = "Cauldron" | |
| 178 | block_id[119] = "End Portal" | |
| 179 | block_id[120] = "End Portal Frame" | |
| 180 | block_id[121] = "End Stone " | |
| 181 | block_id[126] = "Wood Slabs" | |
| 182 | block_id[128] = "Sandstone Stairs" | |
| 183 | block_id[134] = "Spruce Wood Stairs" | |
| 184 | block_id[135] = "Birch Wood Stairs" | |
| 185 | block_id[136] = "Jungle Wood Stairs" | |
| 186 | block_id[156] = "Quartz Stairs" | |
| 187 | block_id[159] = "Stained Clay" | |
| 188 | block_id[160] = "Stained Glass Pane" | |
| 189 | block_id[163] = "Acacia Wood Stairs" | |
| 190 | block_id[164] = "Dark Oak Wood Stairs" | |
| 191 | block_id[171] = "Carpet" | |
| 192 | block_id[172] = "Hardened Clay" | |
| 193 | block_id[256] = "Iron Ingotron Shovel" | |
| 194 | block_id[257] = "Iron Pickaxe" | |
| 195 | block_id[258] = "Iron Axe" | |
| 196 | block_id[259] = "Flint and Steel" | |
| 197 | block_id[260] = "Red Apple" | |
| 198 | block_id[261] = "Bow" | |
| 199 | block_id[262] = "Arrow" | |
| 200 | block_id[263] = "Coal" | |
| 201 | ||
| 202 | local woolColors = {}
| |
| 203 | woolColors[0] = "White" | |
| 204 | woolColors[1] = "Orange" | |
| 205 | woolColors[2] = "Magenta" | |
| 206 | woolColors[3] = "Light Blue" | |
| 207 | woolColors[4] = "Yellow" | |
| 208 | woolColors[5] = "Lime" | |
| 209 | woolColors[6] = "Pink" | |
| 210 | woolColors[7] = "Gray" | |
| 211 | woolColors[8] = "Light Gray" | |
| 212 | woolColors[9] = "Cyan" | |
| 213 | woolColors[10] = "Purple" | |
| 214 | woolColors[11] = "Blue" | |
| 215 | woolColors[12] = "Brown" | |
| 216 | woolColors[13] = "Green" | |
| 217 | woolColors[14] = "Red" | |
| 218 | woolColors[15] = "Black" | |
| 219 | ||
| 220 | local woodTypes = {}
| |
| 221 | woodTypes[0] = "Oak" | |
| 222 | woodTypes[1] = "Spruce" | |
| 223 | woodTypes[2] = "Birch" | |
| 224 | woodTypes[3] = "Jungle" | |
| 225 | woodTypes[4] = "Acacia" | |
| 226 | woodTypes[5] = "Dark Oak" | |
| 227 | ||
| 228 | local stairOrientation = {}
| |
| 229 | stairOrientation[0] = "East" | |
| 230 | - | local nonWoodenSlabs = {
|
| 230 | + | |
| 231 | - | [0] = "Stone", |
| 231 | + | |
| 232 | - | [1] = "Sandstone", |
| 232 | + | |
| 233 | - | [2] = "Wooden", |
| 233 | + | |
| 234 | - | [3] = "Cobblestone", |
| 234 | + | |
| 235 | - | [4] = "Bricks", |
| 235 | + | |
| 236 | - | [5] = "Stone Bricks", |
| 236 | + | |
| 237 | - | [6] = "Nether Brick", |
| 237 | + | |
| 238 | - | [7] = "Quartz", |
| 238 | + | local nonWoodenSlabs = {
|
| 239 | - | [8] = "Inverted Stone", |
| 239 | + | [0] = "Stone", |
| 240 | - | [9] = "Inverted Sandstone", |
| 240 | + | [1] = "Sandstone", |
| 241 | - | [10] = "Inverted Wooden", |
| 241 | + | [2] = "Wooden", |
| 242 | - | [11] = "Inverted Cobblestone", |
| 242 | + | [3] = "Cobblestone", |
| 243 | - | [12] = "Inverted Bricks", |
| 243 | + | [4] = "Bricks", |
| 244 | - | [13] = "Inverted Stone Bricks", |
| 244 | + | [5] = "Stone Bricks", |
| 245 | - | [14] = "Inverted Nether Brick", |
| 245 | + | [6] = "Nether Brick", |
| 246 | - | [15] = "Inverted Quartz", |
| 246 | + | [7] = "Quartz", |
| 247 | [8] = "Inverted Stone", | |
| 248 | [9] = "Inverted Sandstone", | |
| 249 | [10] = "Inverted Wooden", | |
| 250 | [11] = "Inverted Cobblestone", | |
| 251 | [12] = "Inverted Bricks", | |
| 252 | [13] = "Inverted Stone Bricks", | |
| 253 | [14] = "Inverted Nether Brick", | |
| 254 | [15] = "Inverted Quartz", | |
| 255 | } | |
| 256 | ||
| 257 | local length = 0 | |
| 258 | local height = 0 | |
| 259 | - | blockData = blockData or nil |
| 259 | + | |
| 260 | - | local str = nil |
| 260 | + | |
| 261 | - | if(block_id[id] == nil) then |
| 261 | + | |
| 262 | - | return tostring(id)..", "..tostring(blockData) |
| 262 | + | |
| 263 | - | else |
| 263 | + | |
| 264 | - | if(blockData) then |
| 264 | + | blockData = blockData or nil |
| 265 | - | if(id == 35) or (id == 159) or (id == 95) or (id == 160) or (id == 171) then |
| 265 | + | local str = nil |
| 266 | - | str = tostring(woolColors[blockData]) .. " " .. tostring(block_id[id]) |
| 266 | + | if(block_id[id] == nil) then |
| 267 | - | return str |
| 267 | + | return tostring(id)..", "..tostring(blockData) |
| 268 | - | elseif id == 5 or id==17 or id==126 then |
| 268 | + | |
| 269 | - | str = tostring(woodTypes[blockData]).." "..tostring(block_id[id]) |
| 269 | + | if(blockData) then |
| 270 | - | return str |
| 270 | + | if(id == 35) or (id == 159) or (id == 95) or (id == 160) or (id == 171) then |
| 271 | - | elseif id == 44 or id == 43 then |
| 271 | + | str = tostring(woolColors[blockData]) .. " " .. tostring(block_id[id]) |
| 272 | - | str = tostring(nonWoodenSlabs[blockData]).." "..tostring(block_id[id]) |
| 272 | + | return str |
| 273 | - | return str |
| 273 | + | elseif id == 5 or id==17 or id==126 then |
| 274 | - | end |
| 274 | + | str = tostring(woodTypes[blockData]).." "..tostring(block_id[id]) |
| 275 | return str | |
| 276 | - | return block_id[id] |
| 276 | + | elseif id == 44 or id == 43 then |
| 277 | str = tostring(nonWoodenSlabs[blockData]).." "..tostring(block_id[id]) | |
| 278 | return str | |
| 279 | end | |
| 280 | return block_id[id] | |
| 281 | end | |
| 282 | end | |
| 283 | end | |
| 284 | ||
| 285 | function getBlockId(x,y,z) | |
| 286 | return blocks[y + z*width + x*length*width + 1] | |
| 287 | end | |
| 288 | ||
| 289 | function getData(x,y,z) | |
| 290 | return data[y + z*width + x*length*width + 1] | |
| 291 | end | |
| 292 | ||
| 293 | function readbytes(h, n) | |
| 294 | for i=1,n do | |
| 295 | h.read() | |
| 296 | end | |
| 297 | end | |
| 298 | ||
| 299 | function readname(h) | |
| 300 | local n1 = h.read() | |
| 301 | local n2 = h.read() | |
| 302 | ||
| 303 | if(n1 == nil or n2 == nil) then | |
| 304 | return "" | |
| 305 | end | |
| 306 | ||
| 307 | local n = n1*256 + n2 | |
| 308 | ||
| 309 | local str = "" | |
| 310 | for i=1,n do | |
| 311 | local c = h.read() | |
| 312 | if c == nil then | |
| 313 | return | |
| 314 | end | |
| 315 | str = str .. string.char(c) | |
| 316 | end | |
| 317 | return str | |
| 318 | end | |
| 319 | ||
| 320 | function parse(a, h, containsName) | |
| 321 | local containsName = containsName or true | |
| 322 | local i,i1,i2,i3,i4 | |
| 323 | if a==0 then | |
| 324 | return | |
| 325 | end | |
| 326 | if containsName then | |
| 327 | name = readname(h) | |
| 328 | end | |
| 329 | ||
| 330 | if a==1 then | |
| 331 | readbytes(h,1) | |
| 332 | elseif a==2 then | |
| 333 | i1 = h.read() | |
| 334 | i2 = h.read() | |
| 335 | i = i1*256 + i2 | |
| 336 | if(name=="Height") then | |
| 337 | height = i | |
| 338 | elseif (name=="Length") then | |
| 339 | length = i | |
| 340 | elseif (name=="Width") then | |
| 341 | width = i | |
| 342 | end | |
| 343 | elseif a==3 then | |
| 344 | readbytes(h,4) | |
| 345 | elseif a==4 then | |
| 346 | readbytes(h,8) | |
| 347 | elseif a==5 then | |
| 348 | readbytes(h,4) | |
| 349 | elseif a==6 then | |
| 350 | readbytes(h,8) | |
| 351 | elseif a==7 then | |
| 352 | i1 = h.read() | |
| 353 | i2 = h.read() | |
| 354 | i3 = h.read() | |
| 355 | i4 = h.read() | |
| 356 | i = i1*256*256*256 + i2*256*256 + i3*256 + i4 | |
| 357 | if name == "Blocks" then | |
| 358 | for i=1,i do | |
| 359 | table.insert(blocks, h.read()) | |
| 360 | end | |
| 361 | elseif name == "Data" then | |
| 362 | for i=1,i do | |
| 363 | table.insert(data, h.read()) | |
| 364 | end | |
| 365 | else | |
| 366 | readbytes(h,i) | |
| 367 | end | |
| 368 | elseif a==8 then | |
| 369 | i1 = h.read() | |
| 370 | i2 = h.read() | |
| 371 | i = i1*256 + i2 | |
| 372 | readbytes(h,i) | |
| 373 | elseif a==9 then | |
| 374 | --readbytes(h,5) | |
| 375 | local type = h.read() | |
| 376 | i1 = h.read() | |
| 377 | i2 = h.read() | |
| 378 | i3 = h.read() | |
| 379 | i4 = h.read() | |
| 380 | i = i1*256*256*256 + i2*256*256 + i3*256 + i4 | |
| 381 | for j=1,i do | |
| 382 | parse(h.read(), h, false) | |
| 383 | end | |
| 384 | end | |
| 385 | end | |
| 386 | ||
| 387 | function forward() | |
| 388 | while not turtle.forward() do | |
| 389 | turtle.dig() | |
| 390 | end | |
| 391 | end | |
| 392 | ||
| 393 | function up() | |
| 394 | while not turtle.up() do | |
| 395 | turtle.digUp() | |
| 396 | end | |
| 397 | end | |
| 398 | ||
| 399 | function down() | |
| 400 | while not turtle.down() do | |
| 401 | turtle.digDown() | |
| 402 | end | |
| 403 | end | |
| 404 | ||
| 405 | function place() | |
| 406 | - | local function setColor(color) |
| 406 | + | |
| 407 | - | if term.isColor() then |
| 407 | + | |
| 408 | - | term.setTextColor(color) |
| 408 | + | |
| 409 | end | |
| 410 | ||
| 411 | local function show_selected_slot(n) | |
| 412 | local w,h = term.getCursorPos() | |
| 413 | local itemData = turtle.getItemDetail(newSelect) | |
| 414 | if itemData then | |
| 415 | term.clearLine() | |
| 416 | term.setCursorPos(1,h) | |
| 417 | write(" "..itemData.name..", "..itemData.damage)
| |
| 418 | else | |
| 419 | term.clearLine() | |
| 420 | term.setCursorPos(1,h) | |
| 421 | write(" ")
| |
| 422 | end | |
| 423 | return itemData | |
| 424 | end | |
| 425 | ||
| 426 | local function setColor(color) | |
| 427 | if term.isColor() then | |
| 428 | term.setTextColor(color) | |
| 429 | end | |
| 430 | end | |
| 431 | ||
| 432 | function setup(filename) | |
| 433 | --input file | |
| 434 | --returns blocks,data | |
| 435 | --requires parse, getBlockName | |
| 436 | ||
| 437 | if not fs.exists(filename) then | |
| 438 | error("File "..tostring(filename).." does not exist.")
| |
| 439 | end | |
| 440 | h = fs.open(filename, "rb") | |
| 441 | ||
| 442 | local a = 0 | |
| 443 | while (a ~= nil) do | |
| 444 | a = h.read() | |
| 445 | parse(a, h) | |
| 446 | end | |
| 447 | ||
| 448 | write("length: " .. length)
| |
| 449 | write(" width: " .. width)
| |
| 450 | write(" height: " .. height .. "\n")
| |
| 451 | ||
| 452 | uniqueblocks={}
| |
| 453 | for i,v in ipairs(blocks) do | |
| 454 | found = false | |
| 455 | for j,w in ipairs(uniqueblocks) do | |
| 456 | ||
| 457 | --[[if (w.blockID==v and (w.data==data[i] or w.blockID ~= 35)) then | |
| 458 | found = true | |
| 459 | w.amount = w.amount + 1 | |
| 460 | break | |
| 461 | end]]-- | |
| 462 | ||
| 463 | --for now, data is only accounted for when the block is whool | |
| 464 | if (w.blockID==v) and (w.data==data[i]) then | |
| 465 | found = true | |
| 466 | w.amount = w.amount + 1 | |
| 467 | break | |
| 468 | end | |
| 469 | end | |
| 470 | ||
| 471 | if found==false then | |
| 472 | uniqueblocks[#uniqueblocks+1] = {}
| |
| 473 | uniqueblocks[#uniqueblocks].blockID = v | |
| 474 | uniqueblocks[#uniqueblocks].data = data[i] | |
| 475 | uniqueblocks[#uniqueblocks].amount = 1 | |
| 476 | end | |
| 477 | end | |
| 478 | ||
| 479 | if fs.exists("slots") then
| |
| 480 | print("slots file discovered...")
| |
| 481 | print("skipping setup")
| |
| 482 | h.close() | |
| 483 | return | |
| 484 | end | |
| 485 | ||
| 486 | - | local stacks = math.ceil( (v.amount/64) ) |
| 486 | + | |
| 487 | for i,v in ipairs(uniqueblocks) do | |
| 488 | - | write(" -" .. getBlockName(v.blockID, v.data))
|
| 488 | + | |
| 489 | read() | |
| 490 | - | write("("..v.blockID..","..v.data..")")
|
| 490 | + | |
| 491 | ||
| 492 | - | write(": ")
|
| 492 | + | local stacks = math.ceil( (v.amount/64) ) |
| 493 | setColor(colors.white) | |
| 494 | - | if v.amount > 64 then |
| 494 | + | write(" -" .. getBlockName(v.blockID, v.data))
|
| 495 | - | setColor(colors.magenta) |
| 495 | + | setColor(colors.lightGray) |
| 496 | - | print(stacks.." stacks") |
| 496 | + | write("("..v.blockID..","..v.data..")")
|
| 497 | setColor(colors.white) | |
| 498 | - | setColor(colors.cyan) |
| 498 | + | write(": ")
|
| 499 | - | print(v.amount) |
| 499 | + | |
| 500 | if v.amount > 64 then | |
| 501 | setColor(colors.magenta) | |
| 502 | print(stacks.." stacks") | |
| 503 | else | |
| 504 | setColor(colors.cyan) | |
| 505 | - | print("Use arrowKeys and enter to select slots containing which block the turtle will use for the specified blockType")
|
| 505 | + | print(v.amount) |
| 506 | - | print("select an empty block or press x to skip(not use) the specified blockType ie air")
|
| 506 | + | |
| 507 | end | |
| 508 | ||
| 509 | setColor(colors.white) | |
| 510 | ||
| 511 | read() | |
| 512 | - | setColor(colors.green) |
| 512 | + | |
| 513 | - | print(" -in which slots is " .. getBlockName(block.blockID, blockData).."("..block.blockID..","..blockData .. ") ?")
|
| 513 | + | |
| 514 | print("Use arrowKeys and enter to select slots containing block the turtle will use for the printed blockType")
| |
| 515 | setColor(colors.gray) | |
| 516 | print("press x to skip(not use) the specified blockType")
| |
| 517 | setColor(colors.white) | |
| 518 | slots={}
| |
| 519 | for i,block in ipairs(uniqueblocks) do | |
| 520 | local n = nil | |
| 521 | blockData = block.data | |
| 522 | ||
| 523 | setColor(colors.lightGray) | |
| 524 | write(" -in which slots is ")
| |
| 525 | setColor(colors.lime) | |
| 526 | write(getBlockName(block.blockID, blockData)) | |
| 527 | setColor(colors.lightGray) | |
| 528 | print("("..block.blockID..","..blockData .. ") ?")
| |
| 529 | setColor(colors.white) | |
| 530 | if not slots[block.blockID] then | |
| 531 | slots[block.blockID] = {}
| |
| 532 | end | |
| 533 | slots[block.blockID][blockData] = {}
| |
| 534 | show_selected_slot(turtle.getSelectedSlot()) | |
| 535 | --input none | |
| 536 | --output(n) | |
| 537 | ||
| 538 | --(oldWay) | |
| 539 | if tArgs[2] == "sim" or tArgs[2] == "simulate" then | |
| 540 | write(" ")
| |
| 541 | str = read() | |
| 542 | n = tonumber(str) | |
| 543 | else | |
| 544 | n = numberSelector() | |
| 545 | end | |
| 546 | ||
| 547 | local itemData = show_selected_slot(n) | |
| 548 | if(n and itemData) then | |
| 549 | print() | |
| 550 | slots[block.blockID][blockData] = {itemData.name,itemData.damage}
| |
| 551 | else | |
| 552 | local w,h = term.getCursorPos() | |
| 553 | term.clearLine() | |
| 554 | term.setCursorPos(1,h) | |
| 555 | print(" SKIPPING")
| |
| 556 | slots[block.blockID][blockData] = {}
| |
| 557 | end | |
| 558 | end | |
| 559 | ||
| 560 | h.close() | |
| 561 | save("slots",slots)
| |
| 562 | end | |
| 563 | ||
| 564 | function numberSelector() | |
| 565 | ||
| 566 | local function selectNext(newSelect) | |
| 567 | if newSelect >= 1 and newSelect <= 16 then | |
| 568 | turtle.select(newSelect) | |
| 569 | show_selected_slot(newSelect) | |
| 570 | end | |
| 571 | end | |
| 572 | ||
| 573 | local function ifKey(events,nKey,fn,...) | |
| 574 | if events[1] == "key" and events[2] == tonumber(nKey) then | |
| 575 | fn(...) | |
| 576 | end | |
| 577 | end | |
| 578 | ||
| 579 | local bRunning = true | |
| 580 | local bNothing = false | |
| 581 | while bRunning do | |
| 582 | local events = { os.pullEvent("key") }
| |
| 583 | local newSelect | |
| 584 | local selected = turtle.getSelectedSlot() | |
| 585 | ||
| 586 | ifKey(events,203,function() newSelect = selected - 1 ; selectNext(newSelect) ; end) | |
| 587 | ifKey(events,205,function() newSelect = selected + 1 ; selectNext(newSelect) ; end) | |
| 588 | ifKey(events,200,function() newSelect = selected - 4 ; selectNext(newSelect) ; end) | |
| 589 | ifKey(events,208,function() newSelect = selected + 4 ; selectNext(newSelect) ; end) | |
| 590 | ifKey(events,28,function() bRunning = false ; end) | |
| 591 | ifKey(events,45,function() bNothing = true ; bRunning = false ; end) | |
| 592 | ifKey(events,15,function() bNothing = true ; bRunning = false; end) | |
| 593 | ||
| 594 | for i = 2,13 do | |
| 595 | ifKey(events,i,function() selectNext(i-1) end) | |
| 596 | end | |
| 597 | for i = 26,27 do | |
| 598 | ifKey(events,i,function() selectNext(i-13) end) | |
| 599 | end | |
| 600 | for i = 39,40 do | |
| 601 | ifKey(events,i,function() selectNext(i-24) end) | |
| 602 | end | |
| 603 | end | |
| 604 | if bNothing then | |
| 605 | return nil | |
| 606 | else | |
| 607 | return turtle.getSelectedSlot() | |
| 608 | end | |
| 609 | end | |
| 610 | ||
| 611 | -- [[ Iterators ]] -- | |
| 612 | ||
| 613 | function checkIfAir() | |
| 614 | --finds the location to place the next block | |
| 615 | while true do | |
| 616 | x,y,z = iterate(x,y,z,startx,starty,startz,height-1,width-1,length-1) | |
| 617 | --makes the turtle build faster by having to travel less | |
| 618 | blockID2 = getBlockId(x,y,z) -- temporary variable | |
| 619 | blockData2 = getData(x,y,z) -- temporary variable | |
| 620 | if slots[blockID2] then | |
| 621 | -- makes sure the next block to place at location is not air | |
| 622 | slot_2nd = slots[blockID2][blockData2] | |
| 623 | if slot_2nd then | |
| 624 | if #slot_2nd > 0 then | |
| 625 | recordObj(x,y,z) | |
| 626 | break | |
| 627 | end | |
| 628 | end | |
| 629 | end | |
| 630 | end | |
| 631 | end | |
| 632 | ||
| 633 | function check(x,y,z,startx,starty,startz) | |
| 634 | if x%2==startx%2 then | |
| 635 | oddx = true | |
| 636 | if y%2==starty%2 then | |
| 637 | oddy = true | |
| 638 | else | |
| 639 | oddy = false | |
| 640 | end | |
| 641 | else | |
| 642 | oddx = false | |
| 643 | if y%2==starty%2 then | |
| 644 | oddy = false | |
| 645 | else | |
| 646 | oddy = true | |
| 647 | end | |
| 648 | end | |
| 649 | return oddx,oddy | |
| 650 | end | |
| 651 | ||
| 652 | ||
| 653 | function Yiterate(x,y,z,startx,starty,startz,finalx,finaly,finalz) | |
| 654 | ||
| 655 | local height = finalx | |
| 656 | local width = finaly | |
| 657 | local length = finalz | |
| 658 | ||
| 659 | if oddx then | |
| 660 | if y < width then | |
| 661 | y = y + 1 | |
| 662 | elseif y == width then | |
| 663 | if x < height then | |
| 664 | x = x + 1 | |
| 665 | --elseif x == height then | |
| 666 | --x,y,z = "max","max","max" | |
| 667 | end | |
| 668 | end | |
| 669 | else | |
| 670 | if y <= starty then | |
| 671 | if x < height then | |
| 672 | x = x + 1 | |
| 673 | elseif x == height then | |
| 674 | x = "max" | |
| 675 | y = "max" | |
| 676 | z = "max" | |
| 677 | end | |
| 678 | else | |
| 679 | y=y-1 | |
| 680 | end | |
| 681 | end | |
| 682 | return x,y,z | |
| 683 | end | |
| 684 | ||
| 685 | function iterate(x,y,z,startx,starty,startz,finalx,finaly,finalz) | |
| 686 | ||
| 687 | local height = finalx | |
| 688 | local width = finaly | |
| 689 | local length = finalz | |
| 690 | ||
| 691 | ||
| 692 | local oddx,oddy = check(x,y,z,startx,starty,startz) | |
| 693 | if z == length and oddy then | |
| 694 | x,y,z = Yiterate(x,y,z,startx,starty,startz,finalx,finaly,finalz) | |
| 695 | elseif z == startz and oddy then | |
| 696 | z = z + 1 | |
| 697 | elseif z == startz and (not oddy) then | |
| 698 | x,y,z = Yiterate(x,y,z,startx,starty,startz,finalx,finaly,finalz) | |
| 699 | elseif z==length and (not oddy) then | |
| 700 | z = z - 1 | |
| 701 | ||
| 702 | elseif z < length then | |
| 703 | if oddy then | |
| 704 | z = z + 1 | |
| 705 | else | |
| 706 | z = z - 1 | |
| 707 | end | |
| 708 | end | |
| 709 | return x,y,z | |
| 710 | end | |
| 711 | ||
| 712 | -- [[ TSP_algorithm API ]] -- | |
| 713 | ||
| 714 | local w,h = term.getSize() | |
| 715 | ||
| 716 | local function calculateDistance(tNode1,tNode2) | |
| 717 | local turnCost = 0 | |
| 718 | local deltaY,deltaZ | |
| 719 | local y1 = tNode1[2] | |
| 720 | local z1 = tNode1[3] | |
| 721 | local y2 = tNode2[2] | |
| 722 | local z2 = tNode2[3] | |
| 723 | ||
| 724 | deltaZ = z2-z1 | |
| 725 | deltaY = y2-y1 | |
| 726 | ||
| 727 | if deltaZ == 0 or deltaY == 0 then | |
| 728 | turnCost = 0 | |
| 729 | else | |
| 730 | turnCost = 1 | |
| 731 | end | |
| 732 | ||
| 733 | return math.abs(deltaZ) + math.abs(deltaY) + turnCost | |
| 734 | --return math.sqrt( (z2-z1)^2 + (y2-y1)^2 ) | |
| 735 | end | |
| 736 | ||
| 737 | local function twoOptSwap(route, i, k) | |
| 738 | local new_route = {}
| |
| 739 | for c = 1,i-1 do | |
| 740 | table.insert(new_route,route[c]) | |
| 741 | end | |
| 742 | for c = k,i,-1 do | |
| 743 | table.insert(new_route,route[c]) | |
| 744 | end | |
| 745 | for c = k+1,#route do | |
| 746 | table.insert(new_route,route[c]) | |
| 747 | end | |
| 748 | return new_route | |
| 749 | end | |
| 750 | ||
| 751 | local function calculateTotalDistance(route) | |
| 752 | local total = 0 | |
| 753 | for i = 1,#route-1 do | |
| 754 | - | term.setCursorPos(coord[2],coord[3]) |
| 754 | + | |
| 755 | - | term.write(string.char(i+64)) |
| 755 | + | |
| 756 | return total | |
| 757 | end | |
| 758 | ||
| 759 | local function display(route,distance) | |
| 760 | local l,h = term.getSize() | |
| 761 | shell.run("clear")
| |
| 762 | ||
| 763 | for i = 1,#route-1 do | |
| 764 | paintutils.drawLine(route[i][2],route[i][3],route[i+1][2],route[i+1][3],colors.lime) | |
| 765 | end | |
| 766 | for i,coord in pairs(route) do | |
| 767 | term.setBackgroundColor(colors.yellow) | |
| 768 | term.setTextColor(colors.magenta) | |
| 769 | if coord[2] < l and coord[2] >= 1 and coord[3] >= 1 and coord[3] < h then | |
| 770 | term.setCursorPos(coord[2],coord[3]) | |
| 771 | local char = i + 64 | |
| 772 | if char > 190 then | |
| 773 | char = char - 190 | |
| 774 | end | |
| 775 | if char > 380 then | |
| 776 | char = char - 380 | |
| 777 | end | |
| 778 | term.write(string.char(char)) | |
| 779 | end | |
| 780 | end | |
| 781 | term.setBackgroundColor(colors.black) | |
| 782 | term.setTextColor(colors.white) | |
| 783 | term.setCursorPos(1,h) | |
| 784 | term.write(distance) | |
| 785 | end | |
| 786 | ||
| 787 | local route = {}
| |
| 788 | route[1] = {1,28,3}
| |
| 789 | route[2] = {1,36,13}
| |
| 790 | route[3] = {1,20,8}
| |
| 791 | route[4] = {1,8,8}
| |
| 792 | route[5] = {1,44,5}
| |
| 793 | route[6] = {1,32,13}
| |
| 794 | route[7] = {1,20,17}
| |
| 795 | --route[8] = {1,28,3}
| |
| 796 | ||
| 797 | function tsp_algorithm(existing_route) | |
| 798 | local improve = 0 | |
| 799 | while improve < 3 do | |
| 800 | local best_distance = calculateTotalDistance(existing_route) | |
| 801 | for i = 2,#existing_route-1 do | |
| 802 | for k = i + 1, #existing_route do | |
| 803 | new_route = twoOptSwap(existing_route, i, k) | |
| 804 | new_distance = calculateTotalDistance(new_route) | |
| 805 | if new_distance < best_distance then | |
| 806 | improve = 0 | |
| 807 | existing_route = new_route | |
| 808 | best_distance = calculateTotalDistance(existing_route) | |
| 809 | display(existing_route,best_distance) | |
| 810 | sleep(0) | |
| 811 | end | |
| 812 | end | |
| 813 | end | |
| 814 | improve = improve + 1 | |
| 815 | end | |
| 816 | return existing_route, best_distance | |
| 817 | end | |
| 818 | ||
| 819 | -- [[ schematic --> blueprint ]] -- | |
| 820 | ||
| 821 | --turtles[i].instructions[n] = {x,y,z,id,data}
| |
| 822 | --i = multiturtle ie 1,2,3,4 ; n = step ie 1 - 256 (no air) | |
| 823 | ||
| 824 | --fn splits 16x16 grid between 4 turtles returning startx,y,z and endx,y,z of 4 4x4 grids | |
| 825 | --fn takes each 4x4 grid and turns them into instructions[n] = {x,y,z,id,data}
| |
| 826 | --fn for master turtle to setup all slave turtles with the instructions[n] table and goto/find/place functions | |
| 827 | ||
| 828 | function blueprint(startx,starty,startz,finalx,finaly,finalz) | |
| 829 | --uses iterator to make instructions[n] table | |
| 830 | local x,y,z = startx,starty,startz | |
| 831 | local instructions = {}
| |
| 832 | local nTimes = (finalx+1-startx)*(finaly+1-starty)*(finalz+1-startz) | |
| 833 | for i=1,nTimes do | |
| 834 | if x == "max" then | |
| 835 | break | |
| 836 | end | |
| 837 | local id = getBlockId(x,y,z) | |
| 838 | local data = getData(x,y,z) | |
| 839 | if id > 0 then | |
| 840 | table.insert(instructions,{x,y,z,id,data})
| |
| 841 | end | |
| 842 | x,y,z = iterate(x,y,z,startx,starty,startz,finalx,finaly,finalz) | |
| 843 | end | |
| 844 | return instructions | |
| 845 | end | |
| 846 | ||
| 847 | function improveBlueprint(instructions,startx,starty,startz,finalx,finaly,finalz) | |
| 848 | local function instructions2layers(instructions) | |
| 849 | local layers = {}
| |
| 850 | for x = startx,finalx do | |
| 851 | layers[x] = {}
| |
| 852 | for n=1,#instructions do | |
| 853 | if instructions[n][1] == x then | |
| 854 | table.insert(layers[x],{unpack(instructions[n],1,3)})
| |
| 855 | end | |
| 856 | end | |
| 857 | end | |
| 858 | return layers | |
| 859 | end | |
| 860 | local function organize(layers) | |
| 861 | local startingPosition = {startx,starty,startz}
| |
| 862 | for x = startx,finalx do | |
| 863 | table.insert(layers[x],1,startingPosition) | |
| 864 | layers[x] = tsp_algorithm(layers[x]) | |
| 865 | startingPosition = layers[x][#layers[x]] | |
| 866 | end | |
| 867 | return layers | |
| 868 | end | |
| 869 | ||
| 870 | local function layers2instructions(layers) | |
| 871 | local instructions = {}
| |
| 872 | --organizedlayers only | |
| 873 | for x = startx,finalx do | |
| 874 | for i = 2,#layers[x] do | |
| 875 | table.insert(instructions,layers[x][i]) | |
| 876 | end | |
| 877 | end | |
| 878 | return instructions | |
| 879 | end | |
| 880 | - | term.setCursorPos(instructions[n][2]+1,instructions[n][3]+1) |
| 880 | + | |
| 881 | - | term.setBackgroundColor(2^instructions[n][5]) |
| 881 | + | |
| 882 | - | term.write(" ")
|
| 882 | + | |
| 883 | instructions[n][4] = getBlockId(unpack(instructions[n],1,3)) | |
| 884 | instructions[n][5] = getData(unpack(instructions[n],1,3)) | |
| 885 | end | |
| 886 | return instructions | |
| 887 | end | |
| 888 | ||
| 889 | local layers = instructions2layers(instructions) | |
| 890 | layers = organize(layers) | |
| 891 | local new_instructions = layers2instructions(layers) | |
| 892 | new_instructions = add_id_and_data(new_instructions) | |
| 893 | return new_instructions | |
| 894 | end | |
| 895 | ||
| 896 | function simulateIns(instructions) | |
| 897 | local w,h = term.getSize() | |
| 898 | local lastx = 0 | |
| 899 | shell.run("clr")
| |
| 900 | for n = 1,#instructions do | |
| 901 | if lastx~=instructions[n][1] then | |
| 902 | term.setBackgroundColor(colors.black) | |
| 903 | shell.run("clr")
| |
| 904 | end | |
| 905 | if instructions[n][2]+1 >= 1 and instructions[n][3]+1 >= 1 and instructions[n][2]+1 < w and instructions[n][3]+1 < h then | |
| 906 | term.setCursorPos(instructions[n][2]+1,instructions[n][3]+1) | |
| 907 | term.setBackgroundColor(2^instructions[n][5]) | |
| 908 | term.write(" ")
| |
| 909 | end | |
| 910 | lastx = instructions[n][1] | |
| 911 | sleep(0) | |
| 912 | end | |
| 913 | end | |
| 914 | ||
| 915 | function orientation_check(reference,slots) | |
| 916 | for id,table in pairs(slots) do | |
| 917 | for data,table2 in pairs(table) do | |
| 918 | if table2 and table2[1] then | |
| 919 | if (table2[1]:find("stairs") or table2[1]:find("chest") or table2[1]:find("furnace")) then
| |
| 920 | for n = 1,5 do | |
| 921 | term.scroll(1) | |
| 922 | sleep(0) | |
| 923 | end | |
| 924 | print("orientation required")
| |
| 925 | print("what direction is the turtle facing?")
| |
| 926 | local r | |
| 927 | while true do | |
| 928 | write(" ")
| |
| 929 | if term.isColor() then | |
| 930 | term.setTextColor(colors.yellow) | |
| 931 | end | |
| 932 | - | local reference = {
|
| 932 | + | |
| 933 | r = tostring(r):lower() | |
| 934 | term.setTextColor(colors.white) | |
| 935 | if r ~= "south" and r~= "north" and r~= "west" and r~= "east" then | |
| 936 | print(r.. " not recognized, north/south/east/west?") | |
| 937 | else | |
| 938 | break | |
| 939 | end | |
| 940 | end | |
| 941 | ||
| 942 | reference.relativeDirection = r | |
| 943 | print("don't forget to include wrench in turtle!")
| |
| 944 | reference.wrench = true | |
| 945 | return reference | |
| 946 | end | |
| 947 | end | |
| 948 | end | |
| 949 | end | |
| 950 | return reference | |
| 951 | end | |
| 952 | ||
| 953 | function multiturtle_check(reference) | |
| 954 | write("How many Turtles?: ")
| |
| 955 | - | local ins = blueprint(reference.startx,reference.starty,reference.startz,reference.finalx,reference.finaly,reference.finalz) |
| 955 | + | local n = read() |
| 956 | - | if tArgs[2] == "tsp" then |
| 956 | + | n = tonumber(n) |
| 957 | - | ins = improveBlueprint(ins,reference.startx,reference.starty,reference.startz,reference.finalx,reference.finaly,reference.finalz) |
| 957 | + | if n then |
| 958 | if n == 1 then | |
| 959 | reference.multiturtle = false | |
| 960 | else | |
| 961 | reference.multiturtle = n | |
| 962 | - | local fname = saveBlueprint(reference,slots,ins,uniqueblocks) |
| 962 | + | |
| 963 | - | print(fname," saved") |
| 963 | + | |
| 964 | print() | |
| 965 | return reference | |
| 966 | end | |
| 967 | ||
| 968 | local function Main() | |
| 969 | setup(filename) | |
| 970 | ||
| 971 | --save("blocks",blocks)
| |
| 972 | --save("data",data)
| |
| 973 | --save("uniqueblocks",uniqueblocks)
| |
| 974 | ||
| 975 | reference = {
| |
| 976 | startx = 0, | |
| 977 | starty = 0, | |
| 978 | startz = 0, | |
| 979 | finalx = height-1, | |
| 980 | finaly = width-1, | |
| 981 | finalz = length-1, | |
| 982 | height = height, | |
| 983 | width = width, | |
| 984 | length = length, | |
| 985 | wrench = false, | |
| 986 | multiturtle = false, -- otherwise its a number (1,2,4,8,12,etc), | |
| 987 | relativeDirection = "south", | |
| 988 | numChests = false, | |
| 989 | filename = false, | |
| 990 | returnx = 0, | |
| 991 | returny = 0, | |
| 992 | returnz = -1, | |
| 993 | } | |
| 994 | ||
| 995 | if not slots then | |
| 996 | slots = textutils.unserialize( fs.open("slots","r").readAll() )
| |
| 997 | end | |
| 998 | ||
| 999 | reference = orientation_check(reference,slots) | |
| 1000 | reference = multiturtle_check(reference) | |
| 1001 | ||
| 1002 | local instructions = blueprint(reference.startx,reference.starty,reference.startz,reference.finalx,reference.finaly,reference.finalz) | |
| 1003 | if reference.multiturtle then | |
| 1004 | local A1 = Class_Grid(instructions,reference.starty,reference.startz,reference.finaly,reference.finalz) | |
| 1005 | local startLocations = {nTurtleSplit(reference.multiturtle,A1)}
| |
| 1006 | for i,v in pairs(startLocations) do | |
| 1007 | local nTurtle = i | |
| 1008 | local ref = reference | |
| 1009 | ref.starty = v.starty | |
| 1010 | ref.startz = v.startz | |
| 1011 | ref.finaly = v.finaly | |
| 1012 | ref.finalz = v.finalz | |
| 1013 | local ins = blueprint(ref.startx,v.starty,v.startz,ref.finalx,v.finaly,v.finalz) | |
| 1014 | if tArgs[2] == "tsp" then | |
| 1015 | ins = improveBlueprint(ins,ref.startx,ref.starty,ref.startz,ref.finalx,ref.finaly,ref.finalz) | |
| 1016 | end | |
| 1017 | ||
| 1018 | local fname = saveBlueprint(ref,slots,ins,uniqueblocks,nTurtle) | |
| 1019 | print(ref.starty," ",ref.startz," ",ref.finaly," ",ref.finalz) | |
| 1020 | print(fname," saved") | |
| 1021 | end | |
| 1022 | else | |
| 1023 | ||
| 1024 | if tArgs[2] == "tsp" then | |
| 1025 | instructions = improveBlueprint(instructions,reference.startx,reference.starty,reference.startz,reference.finalx,reference.finaly,reference.finalz) | |
| 1026 | end | |
| 1027 | --textutils.pagedPrint(textutils.serialize(ins)) | |
| 1028 | --saveIns("instructions",ins)
| |
| 1029 | local fname = saveBlueprint(reference,slots,instructions,uniqueblocks) | |
| 1030 | print(fname," saved") | |
| 1031 | --delete slots,reference,ins,uniqueblocks files | |
| 1032 | end | |
| 1033 | end | |
| 1034 | ||
| 1035 | Main() |