Example #1
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.mapname):
        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)
Example #2
0
    def __call__(self):
        """Actually build the Minecraft world that corresponds to a tile."""

        if self.skip == True:
            self.log.log_info("Skipping extant tile %dx%d" % (self.tilex, self.tiley))
            self.world = mclevel.MCInfdevOldLevel(self.tiledir)
            peak = self.world.playerSpawnPosition()
            self.peak = peak[1] - 2
            del self.world
            return self.peak

        # 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.mapname, 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)
        orthor = mapds.GetRasterBand(Region.rasters['orthor']).ReadAsArray(ox, oy, sx, sy)
        orthog = mapds.GetRasterBand(Region.rasters['orthog']).ReadAsArray(ox, oy, sx, sy)
        orthob = mapds.GetRasterBand(Region.rasters['orthob']).ReadAsArray(ox, oy, sx, sy)
        orthoir = mapds.GetRasterBand(Region.rasters['orthoir']).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])
            rval  = int(orthor[myz, myx])
            gval  = int(orthog[myz, myx])
            bval  = int(orthob[myz, myx])
            irval = int(orthoir[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, rval, gval, bval, irval)
            [ 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)

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

        # 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
Example #3
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)
Example #4
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
Example #5
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('--single', action='store_true', \
                        help='enable single-threaded mode for debugging or profiling')
    parser.add_argument('--safemerge', action='store_true', \
                        help='use \"safer\" method of merging tiles together')
    parser.add_argument("-v", "--verbosity", action="count", \
                        help="increase output verbosity")
    parser.add_argument("-q", "--quiet", action="store_true", \
                        help="suppress informational output")
    args = parser.parse_args()

    # set up logging
    log_level = klog_levels.LOG_INFO
    if args.quiet:
        log_level = klog_levels.LOG_ERROR
    if args.verbosity:
        # v=1 is DEBUG 1, v=2 is DEBUG 2, and so on
        log_level += args.verbosity
    log = klogger(log_level)

    # build the region
    log.log_info("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.mapname):
        log.log_fatal("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]
    save(world)
    world = None

    # generate individual tiles
    tilexrange = xrange(myRegion.tiles['xmin'], myRegion.tiles['xmax'])
    tileyrange = xrange(myRegion.tiles['ymin'], myRegion.tiles['ymax'])
    name = myRegion.name
    tiles = [(log, name, x, y) for x, y in product(tilexrange, tileyrange)]
    if args.single:
        # single process version
        log.log_warn("Single-threaded region merge")
        for tile in tiles:
            buildtile(tile)
    else:
        # multi-process version
        pool = Pool()
        rs = pool.map_async(buildtile, tiles)
        pool.close()
        while not(rs.ready()):
            remaining = rs._number_left
            log.log_info("Waiting for %s buildtile tasks to complete..." %
                         remaining)
            time.sleep(10)
        pool.join()        # Just as a precaution.

    # Necessary for tile-welding -> regions
    cleanmkdir(worlddir)
    cleanmkdir(os.path.join(worlddir, 'region'))

    # Generate regions
    if not(args.safemerge):
        regionsize = 32 * 16
        regionxrange = xrange(int(floor(myRegion.tiles['xmin'] * (myRegion.tilesize / float(regionsize)))), \
                              int(ceil(myRegion.tiles['xmax'] * (myRegion.tilesize / float(regionsize)))))
        regionyrange = xrange(int(floor(myRegion.tiles['ymin'] * (myRegion.tilesize / float(regionsize)))), \
                              int(ceil(myRegion.tiles['ymax'] * (myRegion.tilesize / float(regionsize)))))
    
        regions = [(log, name, x, y) for x, y in product(regionxrange, regionyrange)]
    
        # merge individual tiles into regions
        log.log_info("Merging %d tiles into one world..." % len(tiles))
        for tile in tiles:
            (dummy, name, x, y) = tile
            tiledir = os.path.join('Regions', name, 'Tiles', '%dx%d' % (x, y))
            if not(os.path.isfile(os.path.join(tiledir, 'Tile.yaml'))):
                log.log_fatal("The following tile is missing. Please re-run this script:\n%s" % \
                      os.path.join(tiledir, 'Tile.yaml'))

        if args.single:
            # single process version
            log.log_warn("Single-threaded region merge")
            for region in regions:
                buildregion(region)
        else:
            # multi-process version
            pool = Pool()
            rs = pool.map_async(buildregion, regions)
            pool.close()
            while not(rs.ready()):
                remaining = rs._number_left
                log.log_info("Waiting for %s buildregion tasks to complete..." %
                             remaining)
                time.sleep(10)
            pool.join()        # Just as a precaution.

    world = mclevel.MCInfdevOldLevel(worlddir, create=True)
    if not(args.safemerge):
        mcoffsetx = myRegion.tiles['xmin'] * myRegion.tilesize
        mcoffsetz = myRegion.tiles['ymin'] * myRegion.tilesize
        mcsizex   = (myRegion.tiles['xmax'] - myRegion.tiles['xmin']) * myRegion.tilesize
        mcsizez   = (myRegion.tiles['ymax'] - myRegion.tiles['ymin']) * myRegion.tilesize
        tilebox = box.BoundingBox((mcoffsetx, 0, mcoffsetz), (mcsizex, world.Height, mcsizez))
        world.createChunksInBox(tilebox)

    for tile in tiles:
        (dummy, 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])
        if args.safemerge:
            tileworld = mclevel.MCInfdevOldLevel(tiledir, create=False)
            world.copyBlocksFrom(tileworld, tileworld.bounds, tileworld.bounds.origin)
            tileworld = False

    # plant trees in our world
    log.log_info("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:
        log.log_info("Depositing %d ores at the region level..." % \
                     sum([len(ores[oretype]) for oretype in ores]))
        Ore.placeoreinregion(ores, oreobjs, world)

    # tie up loose ends
    world.setPlayerGameType(1)
    setspawnandsave(world, peak)
    oldyamlpath = os.path.join('Regions', args.name, 'Region.yaml')
    newyamlpath = os.path.join('Worlds', args.name, 'Region.yaml')
    shutil.copy(oldyamlpath, newyamlpath)
    shutil.rmtree(os.path.join('Regions', name, 'Tiles'))