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
Beispiel #2
0
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