def toSchematic(vehicle): x0 = min(x for (x, y, z) in vehicle) y0 = min(y for (x, y, z) in vehicle) z0 = min(z for (x, y, z) in vehicle) x1 = max(x for (x, y, z) in vehicle) y1 = max(y for (x, y, z) in vehicle) z1 = max(z for (x, y, z) in vehicle) schematic = nbt.NBTFile() schematic.name = "Schematic" schematic.tags.append(nbt.TAG_Short(name="Width", value=x1 - x0 + 1)) schematic.tags.append(nbt.TAG_Short(name="Height", value=y1 - y0 + 1)) schematic.tags.append(nbt.TAG_Short(name="Length", value=z1 - z0 + 1)) schematic.tags.append(nbt.TAG_String(name="Materials", value="Alpha")) ids = b'' metas = b'' for y in range(y0, y1 + 1): for z in range(z0, z1 + 1): for x in range(x0, x1 + 1): try: b = vehicle[(x, y, z)] except: b = Block(0) ids += pack("B", b.id) metas += pack("B", b.data) blocks = nbt.TAG_Byte_Array(name="Blocks") blocks.value = ids schematic.tags.append(blocks) data = nbt.TAG_Byte_Array(name="Data") data.value = metas schematic.tags.append(data) schematic.tags.append(nbt.TAG_List(name="Entities", type=nbt.TAG_Compound)) schematic.tags.append( nbt.TAG_List(name="TileEntities", type=nbt.TAG_Compound)) return schematic
def importSchematic(mc, path, x0, y0, z0, centerX=False, centerY=False, centerZ=False, clear=False, movePlayer=True): mc.postToChat("Reading " + path) schematic = nbt.NBTFile(path, "rb") sizeX = schematic["Width"].value sizeY = schematic["Height"].value sizeZ = schematic["Length"].value def offset(x, y, z): return x + (y * sizeZ + z) * sizeX px, pz = x0, z0 if centerX: x0 -= sizeX // 2 if centerY: y0 -= sizeY // 2 if centerZ: z0 -= sizeZ // 2 corner1 = (x0, y0, z0) corner2 = (x0 + sizeX - 1, y0 + sizeY - 1, z0 + sizeZ - 1) if clear: mc.setBlocks(corner1, corner2, block.AIR) blocks = schematic["Blocks"].value data = schematic["Data"].value tileEntities = schematic["TileEntities"] tileEntityDict = {} if not isPE: for e in tileEntities: origCoords = e['x'].value, e['y'].value, e['z'].value e['x'].value += x0 e['y'].value += y0 e['z'].value += z0 tileEntityDict[origCoords] = nbtToJson(e) check1 = lambda b: b != block.CARPET.id and b not in NEED_SUPPORT check2 = lambda b: b in NEED_SUPPORT check3 = lambda b: b == block.CARPET.id mc.postToChat("Rendering") for check in (check1, check2, check3): for y in range(sizeY): if check == check1 and movePlayer: mc.player.setTilePos(px, y0 + y, pz) for x in range(sizeX): for z in range(sizeZ): i = offset(x, y, z) b = blocks[i] if b == block.AIR.id: continue d = data[i] if not check(b): if check == check1: b = block.AIR.id d = 0 else: continue if b == 33 and (d & 7) == 7: d = (d & 8) if (x, y, z) in tileEntityDict: # if b==33: \print x0+x,y0+y,z0+z,x,y,z,b,d,e mc.setBlockWithNBT(x0 + x, y0 + y, z0 + z, b, d, tileEntityDict[(x, y, z)]) else: # if b==33: print x0+x,y0+y,z0+z,x,y,z,b,d mc.setBlock(x0 + x, y0 + y, z0 + z, b, d) print("done") # TODO: entities return corner1, corner2