def merge(base_world_fn, insert_world_fn): print "merging {0} into {1}".format(insert_world_fn, base_world_fn) base_level = mclevel.fromFile(base_world_fn) bounds = base_level.bounds print "World size: \n {0[0]:7} north to south\n {0[2]:7} east to west".format(bounds.size) print "Smallest and largest points: ({0[0]},{0[2]}), ({1[0]},{1[2]})".format(bounds.origin, bounds.maximum) base_n, z, base_w = bounds.origin base_s, z, base_e = bounds.maximum (base_w, base_s), (base_e, base_n) = bounding_box(base_level) insert_level = mclevel.fromFile(insert_world_fn) bounds = insert_level.bounds print "World size: \n {0[0]:7} north to south\n {0[2]:7} east to west".format(bounds.size) print "Smallest and largest points: ({0[0]},{0[2]}), ({1[0]},{1[2]})".format(bounds.origin, bounds.maximum) print bounding_box(insert_level) level_w, z, level_s = bounds.origin level_n, z, level_e = bounds.maximum (level_w, level_s), (level_e, level_n) = bounding_box(insert_level) move_n = (level_n * -1) - 16 # move_e = level_w * -1 move_e = base_e + 16 command = "{0} import {1} {2},0,{3}".format(base_world_fn, insert_world_fn, move_e, move_n) print "python pymclevel/mce.py {0}".format(command) subprocess.check_call(["python", "pymclevel/mce.py"] + command.split()) open("edit.txt", "a").write(command + "\n")
def trace_combine(self, world_dir, combine, methods, select, join): """ Find the contour at the interface between existing and empty chunks, then merge appropriately with existing data. """ level = mclevel.fromFile(world_dir) trace = self.__trace(mclevel.fromFile(world_dir)) trace = self.__select(select, trace) edges = self.__join(join, methods, trace) if combine: self.edges.update(edges) else: self.edges = edges
def __init__(self, tag=None, layout=None, offset=1): # handles: # - file-based (tag=foo, layout=None) # - layout-based (tag=None, layout=[[[(1, 'Stone')]]]) if tag is None and layout is None: raise AttributeError('tag or layout must be specified') if layout is None: filename = 'schematics/%s.schematic' % tag if not os.path.exists(filename): raise IOError('no file found') else: schem = mclevel.fromFile(filename) self.layout = [[ Schematic.compressrow([(1, (int(schem.Blocks[elemX, elemZ, elemY]), int(schem.Data[elemX, elemZ, elemY]))) for elemY in xrange(schem.Height)]) for elemZ in xrange(schem.Length) ] for elemX in xrange(schem.Width)] else: self.layout = layout self.offset = offset self.width = len(self.layout) self.length = len(self.layout[0]) self.height = height(self.layout[0][0])
def __init__(self, tag=None, layout=None, offset=1): # handles: # - file-based (tag=foo, layout=None) # - layout-based (tag=None, layout=[[[(1, 'Stone')]]]) if tag == None and layout == None: raise AttributeError, "tag or layout must be specified" if layout == None: filename = "%s.schematic" % tag if not os.path.exists(filename): raise IOError, "no file found" else: schem = mclevel.fromFile(filename) self.layout = [ [ Schematic.compressrow( [ (1, (int(schem.Blocks[elemX, elemZ, elemY]), int(schem.Data[elemX, elemZ, elemY]))) for elemY in xrange(schem.Height) ] ) for elemZ in xrange(schem.Length) ] for elemX in xrange(schem.Width) ] else: self.layout = layout self.offset = offset self.width = len(self.layout) self.length = len(self.layout[0]) self.height = height(self.layout[0][0])
def testCreate(self): # log.info("Schematic from indev") size = (64, 64, 64) temp = mktemp("testcreate.schematic") schematic = MCSchematic(shape=size, filename=temp, mats='Classic') level = self.indevLevel.level schematic.copyBlocksFrom(level, BoundingBox((0, 0, 0), (64, 64, 64,)), (0, 0, 0)) assert ((schematic.Blocks[0:64, 0:64, 0:64] == level.Blocks[0:64, 0:64, 0:64]).all()) schematic.copyBlocksFrom(level, BoundingBox((0, 0, 0), (64, 64, 64,)), (-32, -32, -32)) assert ((schematic.Blocks[0:32, 0:32, 0:32] == level.Blocks[32:64, 32:64, 32:64]).all()) schematic.saveInPlace() schem = mclevel.fromFile("schematics/CreativeInABox.schematic") tempSchematic = MCSchematic(shape=(1, 1, 3)) tempSchematic.copyBlocksFrom(schem, BoundingBox((0, 0, 0), (1, 1, 3)), (0, 0, 0)) level = self.anvilLevel.level for cx, cz in itertools.product(xrange(0, 4), xrange(0, 4)): try: level.createChunk(cx, cz) except ValueError: pass schematic.copyBlocksFrom(level, BoundingBox((0, 0, 0), (64, 64, 64,)), (0, 0, 0)) schematic.close() os.remove(temp)
def CentreBlock(level, box, length, x_axis, y_axis, itemID, itemName, subID): # Add Yellow Wool cc = mclevel.fromFile(IS_Path+"ItemSorter-CC.schematic") updateCB(cc, itemID, itemName, subID); schematic_cc = cc.extractSchematic(cc.bounds) level.copyBlocksFrom(schematic_cc, schematic_cc.bounds, box.origin+(x_axis,y_axis,length), create=True); return length + cc.Length
def __init__(self, path = None): self.path = path try: self.world = mclevel.fromFile(path, True, False) except (IOError, ValueError), e: self.world = None raise ValueError("Not a Minecraft Map: " + str(e))
def find_edges(worldDir, edgeFilename): level = mclevel.fromFile(worldDir) edgeFile = open(edgeFilename, "w") sys.stdout.write("finding edges...") chunks = [] for chunk in level.allChunks: chunks.append(chunk) erodeTasks = [] examined = 0 lastProgress = 0 numChunks = len(chunks) for chunk in chunks: checkChunk(level, chunk, erodeTasks) examined += 1 progress = examined * 100 / numChunks if progress != lastProgress: lastProgress = progress sys.stdout.write("\rfinding edges (%d%%)..." % (progress)) print("") edgeFile.write("# erodeType erodeDirection posX posZ\n") numEdgeChunks = 0 for task in erodeTasks: edgeFile.write("%s\n" % (task)) numEdgeChunks += 1 edgeFile.close() print("found %d edge(s)" % (numEdgeChunks))
def loadWorld(self, world): worldpath = os.path.expanduser(world) if os.path.exists(worldpath): self.level = mclevel.fromFile(worldpath) else: self.level = mclevel.loadWorld(world)
def _import(self, command): """ import <filename> <destPoint> [noair] [nowater] Imports a level or schematic into this world, beginning at destPoint. Supported formats include - Alpha single or multiplayer world folder containing level.dat, - Zipfile containing Alpha world folder, - Classic single-player .mine, - Classic multiplayer server_level.dat, - Indev .mclevel - Schematic from RedstoneSim, MCEdit, mce - .inv from INVEdit (appears as a chest) """ if len(command) == 0: self.printUsage("import") return filename = command.pop(0) destPoint = self.readPoint(command) blocksToCopy = self.readBlocksToCopy(command) importLevel = mclevel.fromFile(filename) self.level.copyBlocksFrom(importLevel, importLevel.bounds, destPoint, blocksToCopy, create=True) self.needsSave = True print "Imported {0} blocks.".format(importLevel.bounds.volume)
def smooth(worldDir, edgeFilename, width = 16): level = mclevel.fromFile(worldDir) newEdgeFile = open(edgeFilename + ".tmp", "w") edgeFile = open(edgeFilename, "r") width = int(width) / 2 erosionTasks = [] for line in edgeFile.readlines(): originalLine = line line = line.strip() # Preserve comments if line.startswith("#"): newEdgeFile.write(originalLine) else: task = ErosionTask.fromString(line) erosionTasks.append(task) edgeFile.close() numTasks = len(erosionTasks) skipped = 0 smoothed = 0 treeDecayList = [] if erosionTasks: examined = 0 for erosionTask in erosionTasks: examined += 1 sys.stdout.write("\rexamining edge %d of %d..." % (examined, numTasks)) # If the task didn't run (because it requires chunks that # haven't been generated yet), write it back to edges.txt. if erosionTask.run(level, treeDecayList, width): smoothed += 1 else: skipped += 1 newEdgeFile.write("%s\n" % (task)) print("") decay_trees(level, treeDecayList) print("saving changes...") level.saveInPlace() newEdgeFile.close() if smoothed: print("smoothed %d edge(s)" % (smoothed)) shutil.move(newEdgeFile.name, edgeFilename) else: os.remove(newEdgeFile.name) if skipped: print("%d edge(s) can't be smoothed yet, since they're not fully explored" % (skipped)) elif smoothed == numTasks: print("the map is perfectly smoothed -- nothing to do!")
def main(): usage = "%s path/to/world/directory" % os.path.basename(sys.argv[0]) if not len(sys.argv) == 2: sys.exit("One argument is required. Usage: %s" % usage) world_directory = sys.argv[1] if not os.path.isdir(world_directory): sys.exit("Not a directory: %s" % world_directory) log.info("Attempting to read world. This scans the directory " "for chunks. Might take a while.") world = mclevel.fromFile(world_directory) random.seed(world.RandomSeed) log.info("Resetting python seed to %d" % world.RandomSeed) idx, t0 = modifyWorld(world) duration = time.time() - t0 chunks_per_sec = (idx + 1) / duration log.info("Total number of modified chunks: %s." % (idx + 1)) log.info("Duration: %.2f s. Chunks per second: %.2f." % ( duration, chunks_per_sec)) # Save the level.dat and any chunks that have been marked for # writing to disk. This also compresses any chunks marked for # recompression. log.info("Save modified world to disk (might take a moment).") world.saveInPlace() log.info("Exiting.")
def __init__(self, world_dir): self.__level = mclevel.fromFile(world_dir) self.log_interval = 1 self.log_function = None self.__measured = (None, None)
def ice_wall(worldDir): level = mclevel.fromFile(worldDir) print("making an ice wall around the world...") chunks = [] for chunk in level.allChunks: chunks.append(chunk) erodeTasks = [] aroundMe = [(-1, -1), (0, -1), (1, -1), (-1, 0), (1, 0), (-1, 1), (0, 1), (1, 1)] i = 0 for chunkPos in chunks: i += 1 sys.stdout.write("\r chunk %d of %d" % (i, len(chunks))) (cx, cz) = chunkPos for (dx, dz) in aroundMe: if (cx + dx, cz + dz) not in chunks: # It's an edge chunk! Make a GIANT ICE WALL. chunk = level.getChunk(cx, cz) chunk.Blocks[:, :, 1:] = iceID chunk.chunkChanged() break print("") level.saveInPlace()
def testCreate(self): # log.info("Schematic from indev") size = (64, 64, 64) temp = mktemp("testcreate.schematic") schematic = MCSchematic(shape=size, filename=temp, mats='Classic') level = self.indevLevel.level schematic.copyBlocksFrom(level, BoundingBox((0, 0, 0), (64, 64, 64,)), (0, 0, 0)) assert((schematic.Blocks[0:64, 0:64, 0:64] == level.Blocks[0:64, 0:64, 0:64]).all()) schematic.copyBlocksFrom(level, BoundingBox((0, 0, 0), (64, 64, 64,)), (-32, -32, -32)) assert((schematic.Blocks[0:32, 0:32, 0:32] == level.Blocks[32:64, 32:64, 32:64]).all()) schematic.saveInPlace() schem = mclevel.fromFile("schematics/CreativeInABox.schematic") tempSchematic = MCSchematic(shape=(1, 1, 3)) tempSchematic.copyBlocksFrom(schem, BoundingBox((0, 0, 0), (1, 1, 3)), (0, 0, 0)) level = self.anvilLevel.level for cx, cz in itertools.product(xrange(0, 4), xrange(0, 4)): try: level.createChunk(cx, cz) except ValueError: pass schematic.copyBlocksFrom(level, BoundingBox((0, 0, 0), (64, 64, 64,)), (0, 0, 0)) schematic.close() os.remove(temp)
def init_map(self): ############################################### filename = self.settings["level_name"] self.level = mclevel.fromFile(filename) self.level.setPlayerGameType(1, "Player") pos = [self.settings["spawn_x"], self.settings["spawn_y"], self.settings["spawn_z"]] self.level.setPlayerPosition( pos ) self.level.setPlayerSpawnPosition( pos ) rows = self.size_x / self.resolution cols = self.size_y / self.resolution o_x = self.settings["origin_x"] o_y = self.settings["origin_y"] o_z = self.settings["origin_z"] ovs = self.settings["oversize"] box = BoundingBox( (o_x - ovs, o_y, o_z - ovs ), ( rows + ovs * 2, ovs, cols + ovs * 2)) print("creating chunks") chunksCreated = self.level.createChunksInBox( box ) print("Created %d chunks" % len( chunksCreated ) ) print("filling air") self.level.fillBlocks( box, self.level.materials.blockWithID(0,0) ) print("filled %d blocks" % box.volume ) print("filling base layer") box = BoundingBox( (o_x - ovs, o_y - 10, o_z - ovs ), ( rows + ovs * 2, 10, cols + ovs * 2)) item = self.readBlockInfo( self.settings["base_item"] ) self.level.fillBlocks( box, item ) print("filled %d blocks" % box.volume )
def loadWorld(world_name): # Attempt to open the world. Look in cwd first, then try to search the # user's save directory. world = None try: print "Trying to open:", world_name world = mclevel.fromFile(world_name) except: saveFileDir = mclevel.saveFileDir world_name = os.path.join(saveFileDir, world_name) print "Trying to open:", world_name try: world = mclevel.fromFile(world_name) except: print "Failed to open world:",world_name sys.exit(1) print 'Loaded world: %s (%d chunks)' % (world_name, world.chunkCount) return world
def CentreRight(level, box, length, x_axis, y_axis): # Closing Centre Block cr = mclevel.fromFile(IS_Path+"ItemSorter-CR.schematic") schematic_cr = cr.extractSchematic(cr.bounds) level.copyBlocksFrom(schematic_cr, schematic_cr.bounds, box.origin+(x_axis,y_axis,length), create=True); x_axis = x_axis+cr.Width length = 0 return (length, x_axis)
def trace_world(self, world_dir, methods): """ Find the contour of the existing world defining the edges at the contour interface. """ method_bits = reduce(lambda a, x: a | self.methods[x].bit, methods, 0) trace = self.__trace(mclevel.fromFile(world_dir)) self.edges = dict((k, EdgeData(method_bits, v)) for k, v in trace.iteritems())
def trace_world(self, world_dir, methods): """ Find the contour of the existing world defining the edges at the contour interface. """ method_bits = reduce(lambda a, x: a | self.methods[x].bit, methods, 0) trace = self.__trace(mclevel.fromFile(world_dir)) self.edges = dict( (k, EdgeData(method_bits, v)) for k, v in trace.iteritems())
def center(name): """Returns the center chunk values for a given region.""" worlddir = os.path.join('worlds', name, 'level.dat') world = mclevel.fromFile(worlddir) bounds = world.bounds centerx = bounds.origin[0]+bounds.size[0]/2 centerz = bounds.origin[2]+bounds.size[2]/2 bounds = None world = None return centerx/16, centerz/16
def center(name): """Returns the center chunk values for a given region.""" worlddir = os.path.join('worlds', name, 'level.dat') world = mclevel.fromFile(worlddir) bounds = world.bounds centerx = bounds.origin[0] + bounds.size[0] / 2 centerz = bounds.origin[2] + bounds.size[2] / 2 bounds = None world = None return centerx / 16, centerz / 16
def loadWorld(world_name): '''Attempt to load a world file. Look in the literal path first, then look in the typical save directory for the given platform. Check to see if the mcdungeon cache directory exists, and create it if not.''' # Attempt to open the world. Look in cwd first, then try to search the # user's save directory. global cfg global cache_path world = None try: print "Trying to open:", world_name world = mclevel.fromFile(world_name) oworld = ov_world.World(world_name) except: saveFileDir = mclevel.saveFileDir world_name = os.path.join(saveFileDir, world_name) print "Trying to open:", world_name try: world = mclevel.fromFile(world_name) oworld = ov_world.World(world_name) except: print "Failed to open world:", world_name sys.exit(1) print 'Loaded world: %s (%d chunks, %d blocks high)' % (world_name, world.chunkCount, world.Height) # Create the mcdungeon cache dir if needed. cache_path = os.path.join(world_name, cfg.cache_dir) if os.path.exists(cache_path) is False: os.makedirs(cache_path) # Find the mapstore path print 'Looking for data directory:', os.path.join(cfg.mapstore, 'data') if not os.path.exists(os.path.join(cfg.mapstore, 'data')): cfg.mapstore = os.path.join(mclevel.saveFileDir, cfg.mapstore) print 'Looking for data directory:', os.path.join(cfg.mapstore, 'data') if not os.path.exists(os.path.join(cfg.mapstore, 'data')): print "Cannot find world data directory!" sys.exit(1) return world, oworld
def testImportSchematic(self): level = self.anvilLevel.level cx, cz = level.allChunks.next() schem = mclevel.fromFile("schematics/CreativeInABox.schematic") box = BoundingBox((cx * 16, 64, cz * 16), schem.bounds.size) level.copyBlocksFrom(schem, schem.bounds, (0, 64, 0)) schem = MCSchematic(shape=schem.bounds.size) schem.copyBlocksFrom(level, box, (0, 0, 0)) convertedSourceBlocks, convertedSourceData = block_copy.convertBlocks(schem, level, schem.Blocks, schem.Data) assert (level.getChunk(cx, cz).Blocks[0:1, 0:3, 64:65] == convertedSourceBlocks).all()
def testImportSchematic(self): level = self.anvilLevel.level cx, cz = level.allChunks.next() schem = mclevel.fromFile("schematics/CreativeInABox.schematic") box = BoundingBox((cx * 16, 64, cz * 16), schem.bounds.size) level.copyBlocksFrom(schem, schem.bounds, (0, 64, 0)) schem = MCSchematic(shape=schem.bounds.size) schem.copyBlocksFrom(level, box, (0, 0, 0)) convertedSourceBlocks, convertedSourceData = block_copy.convertBlocks( schem, level, schem.Blocks, schem.Data) assert (level.getChunk( cx, cz).Blocks[0:1, 0:3, 64:65] == convertedSourceBlocks).all()
def manmade_relight(): t = templevel.TempLevel("TimeRelight", createFunc=lambda f:MCInfdevOldLevel(f, create=True)) world = t.level station = mclevel.fromFile("testfiles/station.schematic") times = 2 for x in range(times): for z in range(times): world.copyBlocksFrom(station, station.bounds, (x * station.Width, 63, z * station.Length), create=True) t = timeit(lambda: world.generateLights(world.allChunks), number=1) print "Relight manmade building: %d chunks in %.02f seconds (%.02fms per chunk)" % (world.chunkCount, t, t / world.chunkCount * 1000)
def manmade_relight(): t = templevel.TempLevel("TimeRelight", createFunc=lambda f: MCInfdevOldLevel(f, create=True)) world = t.level station = mclevel.fromFile("testfiles/station.schematic") times = 2 for x in range(times): for z in range(times): world.copyBlocksFrom(station, station.bounds, (x * station.Width, 63, z * station.Length), create=True) t = timeit(lambda: world.generateLights(world.allChunks), number=1) print "Relight manmade building: %d chunks in %.02f seconds (%.02fms per chunk)" % ( world.chunkCount, t, t / world.chunkCount * 1000)
def load(self): self.level = mclevel.fromFile(self.path) self.spawnX = 0 #self.level.root_tag['Data']['SpawnX'].value self.spawnY = 64 #self.level.root_tag['Data']['SpawnY'].value self.spawnZ = 0 #self.level.root_tag['Data']['SpawnZ'].value self.age = self.level.root_tag['Data']['Time'].value self.time = self.level.root_tag['Data']['DayTime'].value self.gametype = self.level.root_tag['Data']['GameType'].value # Load a 5x5 around spawn self.loadChunkRange(int(self.spawnX) >> 4, int(self.spawnZ) >> 4, 5, 5) print "Loaded %s chunks!" % len(self.loaded_chunks) self.loaded = True
def __init__(self, filename, createFunc=None): if not os.path.exists(filename): filename = join("testfiles", filename) tmpname = mktemp(os.path.basename(filename)) if os.path.exists(filename): if os.path.isdir(filename): shutil.copytree(filename, tmpname) else: shutil.copy(filename, tmpname) elif createFunc: createFunc(tmpname) else: raise IOError("File %s not found." % filename) self.tmpname = tmpname self.level = mclevel.fromFile(tmpname) atexit.register(self.removeTemp)
def __init__(self, world_dir): self.__level = mclevel.fromFile(world_dir) self.__block_roles = self.BlockRoleIDs( self.__block_material(self.terrain), self.__block_material(self.supported), self.__block_material(self.supported2), self.__block_material(self.immutable), self.__block_material(self.solvent), self.__block_material(self.disolve, ('ID', ('ID', 'blockData'))), self.__block_material(self.water), self.__block_material(self.tree_trunks), self.__block_material(self.tree_leaves), self.__block_material(self.tree_trunks_replace, (('ID', 'blockData'), None)), self.__block_material(self.update), ) self.log_interval = 1 self.log_function = None
def trace(self, world_dir): """ Find the contour at the interface between existing and empty chunks, then merge appropriately with existing data. """ level = mclevel.fromFile(world_dir) all_chunks = set(level.allChunks) for chunk in all_chunks: x, y = chunk self.maxX[y], self.minX[y] = max([x, self.maxX.get(y, 0)]), min([x, self.minX.get(y, 0)]) self.maxY[x], self.minY[x] = max([y, self.maxY.get(x, 0)]), min([y, self.minY.get(x, 0)]) # jezt ermitteln wir die bounding box self.bb_minX, self.bb_maxX = min(self.minX.values()), max(self.maxX.values()) self.bb_minY, self.bb_maxY = min(self.minY.values()), max(self.maxY.values()) self.HEIGHT = self.bb_maxX - self.bb_minX self.WIDTH = self.bb_maxY - self.bb_minY
def main(args=sys.argv): logging.basicConfig(level=logging.INFO, format="%(message)s", stream=sys.stdout) if not args[1:]: print """\ USAGE buildawall.py <level.dat> """ return 1 world = mclevel.fromFile(args[1]) WallBuilder(world).build_walls() print "Generating light." world.generateLights() print "Saving." world.saveInPlace() print "Saved." return 0
def trace_combine(self, world_dir, combine, methods, select, join): """ Find the contour at the interface between existing and empty chunks, then merge appropriately with existing data. """ level = mclevel.fromFile(world_dir) # NOTE: The 'trace' only records edge contours while the 'edges' # also specify the merge method for the edge. if select in (self.SelectOperation.missing, ): trace = self.__select_direct(select, level) edges = self.__join(join, methods, trace, self.__find_join_direct) else: trace = self.__trace(level) trace = self.__select_edge(select, trace) edges = self.__join(join, methods, trace, self.__find_join_edge) if combine: self.edges.update(edges) else: self.edges = edges
def trace_combine(self, world_dir, combine, methods, select, join): """ Find the contour at the interface between existing and empty chunks, then merge appropriately with existing data. """ level = mclevel.fromFile(world_dir) # NOTE: The 'trace' only records edge contours while the 'edges' # also specify the merge method for the edge. if select in (self.SelectOperation.missing,): trace = self.__select_direct(select, level) edges = self.__join(join, methods, trace, self.__find_join_direct) else: trace = self.__trace(level) trace = self.__select_edge(select, trace) edges = self.__join(join, methods, trace, self.__find_join_edge) if combine: self.edges.update(edges) else: self.edges = edges
def main(*args): # Load the world level = mclevel.fromFile(default_location) chunks = level.chunkCount sys.stderr.write("Found %d chunks in '%s'.\n" % (chunks, default_location) ) # Convert material names into a material id tuple rail_ids = tuple(level.materials[material_name].ID for material_name in rail_names) rail_locations = list() # output # Iterate through every chunk for c, (chunk, slices, point) in enumerate(level.getAllChunkSlices() ): (cx, cz) = chunk.chunkPosition rails = (chunk.Blocks == any(rail_ids) ) # If there are any rails... if rails.any(): # rails contains three lists [x,z,y] of the full chunk, containing booleans i = rails.nonzero() # indicies of true items number = len(i[0]) # number of rails for n in range(0, number): rail_locations.append(( (cx*16) + i[0][n], (cz*16) + i[1][n], i[2][n] )) # Print progress if (c+1) % 100 == 0: sys.stderr.write("\r%.2f%% complete. (%d chunks remaining...) " % (100.0*(float(c) / chunks), chunks - c) ) sys.stderr.flush() # Output the data sys.stdout.write("#x\tz\ty\n") for location in rail_locations: sys.stdout.write("%d\t%d\t%d\n" % location) sys.stderr.write("\nDone!\n") return 0
def init_map(self): ############################################### filename = self.settings["level_name"] self.level = mclevel.fromFile(filename) self.level.setPlayerGameType(1, "Player") pos = [ self.settings["spawn_x"], self.settings["spawn_y"], self.settings["spawn_z"] ] self.level.setPlayerPosition(pos) self.level.setPlayerSpawnPosition(pos) rows = self.size_x / self.resolution cols = self.size_y / self.resolution o_x = self.settings["origin_x"] o_y = self.settings["origin_y"] o_z = self.settings["origin_z"] ovs = self.settings["oversize"] box = BoundingBox((o_x - ovs, o_y, o_z - ovs), (rows + ovs * 2, ovs, cols + ovs * 2)) print("creating chunks") chunksCreated = self.level.createChunksInBox(box) print("Created %d chunks" % len(chunksCreated)) print("filling air") self.level.fillBlocks(box, self.level.materials.blockWithID(0, 0)) print("filled %d blocks" % box.volume) print("filling base layer") box = BoundingBox((o_x - ovs, o_y - 10, o_z - ovs), (rows + ovs * 2, 10, cols + ovs * 2)) item = self.readBlockInfo(self.settings["base_item"]) self.level.fillBlocks(box, item) print("filled %d blocks" % box.volume)
def copy_from(paths): exit_if_file_exists(RAW_DATA_FILE, "Data") print("Chests and signs in %s will be prepared for migration." % plural(len(paths), "world")) n = len(paths) labelItems = {} for (i, path) in enumerate(paths): print("\nLoading source world %d of %d (%s)..." % (i + 1, n, path)) level = mclevel.fromFile(path) (numChunks, chests_c, signs_c) = copy_from_single(level) chestsToMigrate = label_chests(labelItems, chests_c, signs_c, closest_only = True) print("%s will be migrated." % plural(chestsToMigrate, "chest")) print("\nSaving results...") allData = nbt.TAG_Compound() for label in labelItems: allItems = [] for x in labelItems[label][KEY_CHESTS]: allItems.extend(x[0]['Items']) if len(allItems) > 0: allData[label] = nbt.TAG_List(allItems) allData.save(RAW_DATA_FILE) print("Finished.")
#Run peterborough_cathedral_west_front_removed.py first! from plyfile import PlyData, PlyElement import sys from pymclevel import mclevel #from pymclevel import pocket #from leveldbpocket import PocketLeveldbWorld LEVEL_PATH = "outputs/peterborough-cathedral" X_OFFSET = 57 Z_OFFSET = 38 Y_OFFSET = 69 level = mclevel.fromFile(LEVEL_PATH) plydata = PlyData.read( 'data/peterborough-cathedral/west_front_dense_point_cloud.ply') d = {} print(len(d)) for e in plydata['vertex']: x = int(round(e['x'])) y = int(round(e['y'])) z = int(round(e['z'])) key = "x" + str(x) + "y" + str(y) + "z" + str(z) d[key] = (x, y, z) print(len(d))
def save(world): print 'changing' for chunk in (world.getChunk(cx, cy) for cx, cy in world.allChunks): if hasattr(chunk, 'modified') and chunk.modified == True: chunk.chunkChanged() print 'lighting' world.generateLights() print 'saving' world.saveInPlace() if __name__ == '__main__': import time world = mclevel.fromFile(sys.argv[-1]) print 'air blocks:', common.Block.AIR_VALUES flood_filler = flood_fill.MCFloodFill(world) if len(sys.argv) > 2: # old engine layer = flood_filler.get_starting_layer() print 'layer contains', len(layer), 'blocks' flood_filler.flood_fill(layer) print 'flood filling done' thinner = thinning.MCDistanceThinner(flood_filler.chunks) thinner.image = world thinner.perform_thinning() else: try: thinner = flood_filler.dilate() except common.PleaseSave:
def main(): # parse options opts = docopt.docopt(__doc__) logging.basicConfig( level=logging.INFO if opts['--verbose'] else logging.WARN) levelname = opts['<levelname>'] texturemap_fn = opts['<texturemap>'] depthmap_fn = opts['<depthmap>'] log.info('Loading texture map...') tm_im = Image.open(texturemap_fn) log.info('Loading depth map...') dm_im = Image.open(depthmap_fn) tm_im = tm_im.resize((1920 // 2, 1080 // 2), Image.ANTIALIAS) dm_im = dm_im.resize((1920 // 2, 1080 // 2), Image.ANTIALIAS) # Flip images to correspond to MC's co-ord syste, tm_im = tm_im.transpose(Image.FLIP_LEFT_RIGHT) dm_im = dm_im.transpose(Image.FLIP_LEFT_RIGHT) alpha = np.asarray(tm_im.convert('RGBA'))[:, :, 3].astype(np.float32) alpha /= alpha.max() texture = np.asarray(tm_im.convert('L')).astype(np.float32) texture /= texture.max() depth = np.asarray(dm_im.convert('L')).astype(np.float32) depth /= depth.max() if texture.shape != depth.shape: log.error( 'Texture map is {0[1]}x{0[0]} whereas depth map is {1[1]}x{1[0]}'. format(texture.shape, depth.shape)) return 1 log.info('Loading world...') world = mclevel.fromFile(levelname) xchunks, zchunks = tuple(s // 16 for s in texture.shape) log.info('Creating empty chunks...') chunks = [] dx, dz = (xchunks >> 1), (zchunks >> 1) for xchunk in np.arange(xchunks) - dx: for zchunk in np.arange(zchunks) - dz: chunks.append((xchunk, zchunk)) world.createChunks(chunks) log.info('Processing chunks...') n_processed = 0 for xchunk, zchunk in chunks: n_processed += 1 if n_processed % 100 == 0: log.info('Processing chunk {0}/{1}'.format(n_processed, len(chunks))) chunk = world.getChunk(xchunk, zchunk) px, pz = (xchunk + dx) * 16, (zchunk + dz) * 16 # Reset chunk chunk.Blocks[:] = world.materials.Air.ID chunk.Data[:] = 0 colour = texture[px:(px + 16), pz:(pz + 16)] height = depth[px:(px + 16), pz:(pz + 16)] mask = alpha[px:(px + 16), pz:(pz + 16)] # Scale height height = np.where(mask > 0, height * 64 + 70, 10) # Get floor value of height / 16 block_height = np.floor(height).astype(np.int32) drift_height = np.floor((height - block_height) * 9).astype(np.uint8) for x in range(colour.shape[0]): for z in range(colour.shape[0]): h = block_height[x, z] chunk.Blocks[x, z, :h] = world.materials.Snow.ID if drift_height[x, z] != 0: chunk.Blocks[x, z, h] = world.materials.SnowLayer.ID chunk.Data[x, z, h] = drift_height[x, z] - 1 chunk.chunkChanged() world.generateLights() world.saveInPlace() return 0 # success
def perform(level, box, options): import WorldConverter reload(WorldConverter) answer = None try: update_data = urllib2.urlopen( 'https://raw.githubusercontent.com/gentlegiantJGC/Minecraft-World-Converter/master/version.txt' ).read().split(';') if filter_version != update_data[0]: #this part I found in the MCedit source code so credit to the MCedit team answer = albow.ask( ('Version {} is available').format(update_data[0]), ['Download', 'Ignore'], default=0, cancel=1) except: print 'Tried checking if there was an update however there was an issue' if answer == "Download": from mcplatform import platform_open platform_open(update_data[1]) raise Exception(update_data[2].replace('\\n', '\n\n')) skippedBlocks = [] convertFrom = options['Convert From'] convertTo = options['Convert To'] if convertFrom == convertTo: raise Exception( "due to some bug that I can't work out this doesn't currently work" ) # needs cleaning up (ideally idenfifying map by actual map type rather than user input?) filePath = None filePath = mcplatform.askOpenFile(title="Select a PC world to read from", schematics=False) if filePath is not None: levelOld = mclevel.fromFile(filePath) else: raise Exception('no file given') if len(list(levelOld.allChunks)) > options["Break Every"]: chunksDonePath = None chunksDonePath = mcplatform.askOpenFile( title="Select somewhere to save chunk list", schematics=False) if chunksDonePath is not None: chunksDoneFO = open(chunksDonePath).read() if chunksDoneFO == '': chunksDoneList = [] else: chunksDoneList = json.loads(chunksDoneFO) else: raise Exception('no file given') else: chunksDoneList = [] chunksDonePath = None # level.showProgress("Processed 0 chunks of {}".format(len(list(levelOld.allChunks))),) # def convertWorld chunksDone = 0 import time t = time.time() for chunkOldCoords in levelOld.allChunks: cx, cz = chunkOldCoords if [cx, cz] in chunksDoneList: chunksDone += 1 continue else: chunksDoneList.append(chunkOldCoords) chunkOld = levelOld.getChunk(cx, cz) generateChunk(level, True, cx, cz, 15) chunk = level.getChunk(cx, cz) chunk.Blocks[:] = copy.deepcopy(chunkOld.Blocks) chunk.Data[:] = copy.deepcopy(chunkOld.Data) if options["NBT"] == "Delete": for e in chunk.TileEntities[:]: del e for e in chunk.Entities[:]: del e for e in chunkOld.TileEntities: # try: # except: # pass chunk.TileEntities.append(copy.deepcopy(e)) ''' copying entities to bedrock seems to cause issues so removed this code until a fix is found for e in chunkOld.Entities: chunk.Entities.append(copy.deepcopy(e)) ''' # chunk.TileEntities = copy.deepcopy(chunkOld.TileEntities) # chunk.Entities = copy.deepcopy(chunkOld.Entities) #else: #need to work out how to copy entities across to the PC version. The above code errors # get a list of all the unique blocks chunkBlockList = np.unique(np.add(chunkOld.Blocks * 16, chunkOld.Data)) # go through every block in that list and find the converted id, data and tile entity for block in chunkBlockList: blockID = block >> 4 blockData = block % 16 blockIDNew, blockDataNew, nbtNew = WorldConverter.convertBlock( convertFrom, convertTo, blockID, blockData) # if blockIDNew is equal to -1 then there is a tile enitity requirement if blockIDNew == -1: # for every location with that block id+data combo for coord in np.argwhere( np.logical_and(chunkOld.Blocks == blockID, chunkOld.Data == blockData)): x, z, y = coord x += cx * 16 z += cz * 16 # get the tile entity te = level.tileEntityAt(x, y, z) if te is None: # if the tile entity does not exist, use fallback id blockIDNew, blockDataNew, nbtNew = WorldConverter.convertBlock( convertFrom, convertTo, blockID, blockData, fallBack=True) if nbtNew is not None: te = WorldConverter.createBlockEntity( chunk, convertTo, blockIDNew, x, y, z) else: # if it does exist blockIDNew, blockDataNew, nbtNew = WorldConverter.convertBlock( convertFrom, convertTo, blockID, blockData, te) level.setBlockAt(x, y, z, blockIDNew) level.setBlockDataAt(x, y, z, blockDataNew) if te is not None and nbtNew is not None: # merge nbtNew with tile entity for nbtToSet in nbtNew: te[nbtToSet['key']] = strToNBT['nbtType']( nbtToSet['value']) # if -2 then there was an exception elif blockIDNew == -2: # print chunkOldCoords # print block # raise Exception skippedBlocks.append((blockID, blockData)) elif blockIDNew != blockID or blockDataNew != blockData: convertTheseBlocks = np.logical_and(chunkOld.Blocks == blockID, chunkOld.Data == blockData) if blockIDNew != blockID: chunk.Blocks[convertTheseBlocks] = blockIDNew if blockDataNew != blockData: chunk.Data[convertTheseBlocks] = blockDataNew if nbtNew is not None and blockIDNew not in [-1, -2]: # for all blocks where there was not a tile entity requirement for coord in np.argwhere( np.logical_and(chunkOld.Blocks == blockID, chunkOld.Data == blockData)): x, z, y = coord x += cx * 16 z += cz * 16 # get the tile entity te = level.tileEntityAt(x, y, z) if te is None: te = WorldConverter.createBlockEntity( chunk, convertTo, blockIDNew, x, y, z) # merge nbtNew with tile entity for nbtToSet in nbtNew: te[nbtToSet['key']] = strToNBT['nbtType']( nbtToSet['value']) if blockIDNew in requiresBlockEntity[convertTo]: for coord in np.argwhere( np.logical_and(chunkOld.Blocks == blockID, chunkOld.Data == blockData)): x, z, y = coord x += cx * 16 z += cz * 16 if level.tileEntityAt(x, y, z) is None: WorldConverter.createBlockEntity( chunk, convertTo, blockIDNew, x, y, z) for te in chunk.TileEntities[:]: WorldConverter.convertBlockEntity(convertFrom, convertTo, te) for e in chunk.Entities[:]: WorldConverter.convertEntity(convertFrom, convertTo, e) # biomes if options['Biomes']: if convertFrom == 'PC': if chunkOld.root_tag and 'Level' in chunkOld.root_tag.keys( ) and 'Biomes' in chunkOld.root_tag["Level"].keys(): array = copy.deepcopy( chunkOld.root_tag["Level"]["Biomes"].value) else: array = np.ones(256) elif convertFrom == 'PE': array = np.fromstring(chunkOld.Biomes.tostring(), 'uint8') if convertTo == 'PC': if chunk.root_tag and 'Level' in chunk.root_tag.keys( ) and 'Biomes' in chunk.root_tag["Level"].keys(): chunk.root_tag["Level"]["Biomes"].value = array elif convertTo == 'PE': array.shape = (16, 16) for biomeID in np.unique(array): chunk.Biomes[array == biomeID] = biomeID # chunk.Biomes[:] = array chunk.chunkChanged() chunksDone += 1 print '{}/{}'.format(chunksDone, len(list(levelOld.allChunks))) if chunksDone % options["Break Every"] == options["Break Every"] - 1: break if skippedBlocks != []: WorldConverter.bugReport( submitThis='skippedBlocks:{}'.format(skippedBlocks)) # print skippedBlocks # for _ in levelNew.saveInPlaceGen(): # pass levelOld.close() print time.time() - t if chunksDonePath is not None: chunksDoneFO = open(chunksDonePath, 'w') json.dump(chunksDoneList, chunksDoneFO) chunksDoneFO.close()
def _reload(self, command): self.level = mclevel.fromFile(self.level.filename)
def natural_relight(): world = mclevel.fromFile("testfiles/AnvilWorld") t = timeit(lambda: world.generateLights(world.allChunks), number=1) print "Relight natural terrain: %d chunks in %.02f seconds (%.02fms per chunk)" % ( world.chunkCount, t, t / world.chunkCount * 1000)
def do_convert(self, image): ############################################### filename = self.settings["level_name"] self.level = mclevel.fromFile(filename) self.level.setPlayerGameType(1, "Player") pos = [self.settings["spawn_x"], self.settings["spawn_y"], self.settings["spawn_z"]] self.level.setPlayerPosition( pos ) self.level.setPlayerSpawnPosition( pos ) rows = image.shape[0] cols = image.shape[1] o_x = self.settings["origin_x"] o_y = self.settings["origin_y"] o_z = self.settings["origin_z"] ovs = self.settings["oversize"] box = BoundingBox( (o_x - ovs, o_y - ovs, o_z - ovs ), ( rows + ovs * 2, ovs * 2, cols + ovs * 2)) print("creating chunks") chunksCreated = self.level.createChunksInBox( box ) print("Created %d chunks" % len( chunksCreated ) ) print("filling air") self.level.fillBlocks( box, self.level.materials.blockWithID(0,0) ) print("filled %d blocks" % box.volume ) print("filling base layer") box = BoundingBox( (o_x - ovs, o_y - 10, o_z - ovs ), ( rows + ovs * 2, 10, cols + ovs * 2)) item = self.readBlockInfo( self.settings["unexplored_item"] ) self.level.fillBlocks( box, item ) print("filled %d blocks" % box.volume ) print("creating map") for r in range( rows ): print(" row %d / %d" % (r, rows) ); for c in range( cols ): x = o_x + r y = o_y z = o_z + c if image[rows-r-1,c] > self.settings["empty_thresh"]: item = self.readBlockInfo( self.settings["empty_item"]) self.level.setBlockAt(x,y,z, item.ID) if self.settings["do_ceiling"] : item = self.readBlockInfo( self.settings["ceiling_item"]) y2 = y + self.settings["occupied_height"] self.level.setBlockAt(x,y2,z, item.ID) if image[rows-r-1,c] < self.settings["occ_thresh"]: h = self.settings["occupied_height"] item = self.readBlockInfo( self.settings["occupied_item"]) box = BoundingBox( (x,y,z),(1,h,1) ) self.level.fillBlocks( box, item ) print("saving map") self.level.saveInPlace() print("done")
def testINVEditChests(self): invFile = mclevel.fromFile("schematics/Chests/TinkerersBox.inv") assert invFile.Blocks.any() assert not invFile.Data.any() assert len(invFile.Entities) == 0 assert len(invFile.TileEntities) == 1
OUTPUT_LEVEL_PATH = "outputs/peterborough-cathedral" DSM_PATH = "data/peterborough-cathedral/dsm_trimmed.png" DTM_PATH = "data/peterborough-cathedral/dtm_trimmed.png" BUILDINGS_PATH = "data/peterborough-cathedral/" ROADS_PATH = "data/peterborough-cathedral/" CATHEDRAL_PATH = "data/peterborough-cathedral/cathedral.png" X_OFFSET = 0 Z_OFFSET = 0 Y_OFFSET = 64 if os.path.exists(OUTPUT_LEVEL_PATH): shutil.rmtree(OUTPUT_LEVEL_PATH) shutil.copytree(LEVEL_PATH,OUTPUT_LEVEL_PATH) level = mclevel.fromFile(OUTPUT_LEVEL_PATH); R_OLD, G_OLD, B_OLD, A_OLD = (0, 0, 0, 255) R_NEW, G_NEW, B_NEW, A_NEW = (0, 174, 239, 255) dsm_image = Image.open(DSM_PATH) dtm_image = Image.open(DTM_PATH) cathedral_mask = Image.open(CATHEDRAL_PATH) #buildings_mask = Image.open(BUILDINGS_PATH) rgba_dsm_image = dsm_image.convert('RGBA') rgba_dtm_image = dtm_image.convert('RGBA') rgba_cathedral_mask = cathedral_mask.convert('RGBA') #rgba_buildings_mask = buildings_mask.convert('RGBA') dsm_pixels = rgba_dsm_image.load()
#import ./mce.py import math from pymclevel import mclevel, box, materials, nbt from pymclevel.materials import alphaMaterials as m world = mclevel.fromFile("C:\Users\daniel\AppData\Roaming\.minecraft\saves\Danil's World (Danil)-2") #offsetx, offsety, offsetz = world.getPlayerPosition('Player') offsetx = -1140 offsety = 150 offsetz = -1347 offsetx = -550 offsety = 115 offsetz = -1691 shape = [(x,y,z) for x in range(0,100) for y in range(0,100) for z in range(0,100)] for (x,y,z) in shape: world.setBlockAt(int(math.floor(x+offsetx)), int(math.floor(y+offsety)), int(math.floor(z+offsetz)), 0) shape = [(x,y,z) for x in range(0,100) for y in range(0,100) for z in range(0,100) if (((x-50)*(x-50)+(y-50)*(y-50)+(z-50)*(z-50)) % 256 < 16) and (((x-50)*(x-50)+(y-50)*(y-50)+(z-50)*(z-50)) < 50**2)] for (x,y,z) in shape: if (((x-50)*(x-50)+(y-50)*(y-50)+(z-50)*(z-50)) > 17**2): world.setBlockAt(int(math.floor(x+offsetx)), int(math.floor(y+offsety)), int(math.floor(z+offsetz)), 159) world.setBlockDataAt(int(math.floor(x+offsetx)), int(math.floor(y+offsety)), int(math.floor(z+offsetz)), (((x-50)*(x-50)+(y-50)*(y-50)+(z-50)*(z-50)) % 3 + 8)) else: world.setBlockAt(int(math.floor(x+offsetx)), int(math.floor(y+offsety)), int(math.floor(z+offsetz)), 169) world.setBlockDataAt(int(math.floor(x+offsetx)), int(math.floor(y+offsety)), int(math.floor(z+offsetz)), 0)
def openworld(name): if osp.isfile(name): return mclevel.fromFile(name, readonly=True) else: return mclevel.loadWorld(name)