예제 #1
0
    def _create(self, command):
        """
    create [ <filename> ]

    Create and load a new Minecraft Alpha world. This world will have no
    chunks and a random terrain seed. If run from the shell, filename is not
    needed because you already specified a filename earlier in the command.
    For example:

        mce.py MyWorld create

    """
        if len(command) < 1:
            raise UsageError("Expected a filename")

        filename = command[0]
        if not os.path.exists(filename):
            os.mkdir(filename)

        if not os.path.isdir(filename):
            raise IOError("{0} already exists".format(filename))

        if mclevel.MCInfdevOldLevel.isLevel(filename):
            raise IOError(
                "{0} is already a Minecraft Alpha world".format(filename))

        level = mclevel.MCInfdevOldLevel(filename, create=True)

        self.level = level
예제 #2
0
        numchunks += 1

    world.saveInPlace()
    print "Saved %d chunks." % numchunks


# Where does the world file go?
i = 0
worlddir = None
while not worlddir or os.path.exists(worlddir):
    i += 1
    name = "world" + " " + map_type + " " + str(i)
    worlddir = os.path.join(minecraft_save_dir, name)

print "Creating world %s" % worlddir
world = mclevel.MCInfdevOldLevel(worlddir, create=True)
from pymclevel.nbt import TAG_Int, TAG_String, TAG_Byte_Array
tags = [
    TAG_Int(0, "MapFeatures"),
    TAG_String("flat", "generatorName"),
    TAG_String("0", "generatorOptions")
]
for tag in tags:
    world.root_tag['Data'].add(tag)

peak = [10, 255, 10]

print "Creating chunks."

x_extent = len(elevation)
x_min = 0
예제 #3
0
    def __call__(self):
        """Actually build the Minecraft world that corresponds to a tile."""

        # calculate offsets
        ox = (self.tilex - self.tiles['xmin']) * self.size
        oy = (self.tiley - self.tiles['ymin']) * self.size
        sx = self.size
        sy = self.size

        # load arrays from map file
        mapds = gdal.Open(self.mapfile, GA_ReadOnly)
        lcarray = mapds.GetRasterBand(Region.rasters['landcover']).ReadAsArray(
            ox, oy, sx, sy)
        elarray = mapds.GetRasterBand(Region.rasters['elevation']).ReadAsArray(
            ox, oy, sx, sy)
        bathyarray = mapds.GetRasterBand(Region.rasters['bathy']).ReadAsArray(
            ox, oy, sx, sy)
        crustarray = mapds.GetRasterBand(Region.rasters['crust']).ReadAsArray(
            ox, oy, sx, sy)

        # calculate Minecraft corners
        self.mcoffsetx = self.tilex * self.size
        self.mcoffsetz = self.tiley * self.size

        # build a Minecraft world via pymclevel from blocks and data
        self.world = mclevel.MCInfdevOldLevel(self.tiledir, create=True)
        tilebox = box.BoundingBox((self.mcoffsetx, 0, self.mcoffsetz),
                                  (self.size, self.world.Height, self.size))
        self.world.createChunksInBox(tilebox)

        # do the terrain thing (no trees, ore or building)
        self.peak = [0, 0, 0]
        treeobjs = dict([(tree.name, tree) for tree in treeObjs])
        self.trees = dict([(name, list()) for name in treeobjs])

        for myx, myz in product(xrange(self.size), xrange(self.size)):
            mcx = int(self.mcoffsetx + myx)
            mcz = int(self.mcoffsetz + myz)
            mcy = int(elarray[myz, myx])
            lcval = int(lcarray[myz, myx])
            bathyval = int(bathyarray[myz, myx])
            crustval = int(crustarray[myz, myx])
            if mcy > self.peak[1]:
                self.peak = [mcx, mcy, mcz]
            (blocks, datas, tree) = Terrain.place(mcx, mcy, mcz, lcval,
                                                  crustval, bathyval,
                                                  self.doSchematics)
            [
                self.world.setBlockAt(mcx, y, mcz, block)
                for (y, block) in blocks if block != 0
            ]
            [
                self.world.setBlockDataAt(mcx, y, mcz, data)
                for (y, data) in datas if data != 0
            ]
            # if trees are placed, elevation cannot be changed
            if tree:
                Tree.placetreeintile(self, tree, mcx, mcy, mcz)

        # now that terrain and trees are done, place ore
        if self.doOre:
            Ore.placeoreintile(self)

        # stick the player and the spawn at the peak
        setspawnandsave(self.world, self.peak)

        # write Tile.yaml with relevant data (peak at least)
        # NB: world is not dump-friendly. :-)
        del self.world
        stream = file(os.path.join(self.tiledir, 'Tile.yaml'), 'w')
        yaml.dump(self, stream)
        stream.close()

        # return peak
        return self.peak
예제 #4
0
def main():
    """Builds a region."""
    # example:
    # ./BuildRegion.py --name BlockIsland

    # parse options and get results
    parser = argparse.ArgumentParser(
        description='Builds Minecraft worlds from regions.')
    parser.add_argument('--name',
                        required=True,
                        type=str,
                        help='name of the region to be built')
    parser.add_argument('--debug',
                        action='store_true',
                        help='enable debug output')
    parser.add_argument(
        '--single',
        action='store_true',
        help='enable single-threaded mode for debugging or profiling')
    args = parser.parse_args()

    # enable debug
    if (args.debug):
        print "Do something!"

    # build the region
    print "Building region %s..." % args.name
    yamlfile = file(os.path.join('regions', args.name, 'Region.yaml'))
    myRegion = yaml.load(yamlfile)
    yamlfile.close()

    # exit if map does not exist
    if not os.path.exists(myRegion.mapfile):
        raise IOError('no map file exists')

    # tree and ore variables
    treeobjs = dict([(tree.name, tree) for tree in treeObjs])
    trees = dict([(name, list()) for name in treeobjs])
    oreobjs = dict([(ore.name, ore) for ore in oreObjs])
    ores = dict([(name, list()) for name in oreobjs])

    # generate overall world
    worlddir = os.path.join('worlds', args.name)
    world = mclevel.MCInfdevOldLevel(worlddir, create=True)
    peak = [0, 0, 0]

    # generate individual tiles
    tilexrange = xrange(myRegion.tiles['xmin'], myRegion.tiles['xmax'])
    tileyrange = xrange(myRegion.tiles['ymin'], myRegion.tiles['ymax'])
    name = myRegion.name
    tiles = [(name, x, y) for x, y in product(tilexrange, tileyrange)]
    if args.single:
        # single process version - works
        for tile in tiles:
            buildtile(tile)
    else:
        # multi-process ... let's see...
        pool = Pool()
        pool.map(buildtile, tiles)
        pool.close()
        pool.join()

    # merge individual worlds into it
    print "Merging %d tiles into one world..." % len(tiles)
    for tile in tiles:
        (name, x, y) = tile
        tiledir = os.path.join('regions', name, 'Tiles', '%dx%d' % (x, y))
        tilefile = file(os.path.join(tiledir, 'Tile.yaml'))
        newtile = yaml.load(tilefile)
        tilefile.close()
        if (newtile.peak[1] > peak[1]):
            peak = newtile.peak
        for treetype in newtile.trees:
            trees.setdefault(treetype, []).extend(newtile.trees[treetype])
        if myRegion.doOre:
            for oretype in newtile.ores:
                ores.setdefault(oretype, []).extend(newtile.ores[oretype])
        tileworld = mclevel.MCInfdevOldLevel(tiledir, create=False)
        world.copyBlocksFrom(tileworld, tileworld.bounds,
                             tileworld.bounds.origin)
        tileworld = False

    # plant trees in our world
    print "Planting %d trees at the region level..." % sum(
        [len(trees[treetype]) for treetype in trees])
    Tree.placetreesinregion(trees, treeobjs, world)

    # deposit ores in our world
    if myRegion.doOre:
        print "Depositing %d ores at the region level..." % sum(
            [len(ores[oretype]) for oretype in ores])
        Ore.placeoreinregion(ores, oreobjs, world)

    # replace all 'end stone' with stone
    print "Replacing all 'end stone' with stone..."
    EndStoneID = world.materials["End Stone"].ID
    StoneID = world.materials["Stone"].ID
    for xpos, zpos in world.allChunks:
        chunk = world.getChunk(xpos, zpos)
        chunk.Blocks[chunk.Blocks == EndStoneID] = StoneID

    # tie up loose ends
    setspawnandsave(world, peak)