def _degrief(self, command): """ degrief [ <height> ] Reverse a few forms of griefing by removing Adminium, Obsidian, Fire, and Lava wherever they occur above the specified height. Without a height, uses height level 32. Removes natural surface lava. Also see removeEntities """ box = self.level.bounds box = BoundingBox(box.origin + (0, 32, 0), box.size - (0, 32, 0)) if len(command): try: box.miny = int(command[0]) except ValueError: pass print("Removing grief matter and surface lava above height {0}...". format(box.miny)) self.level.fillBlocks(box, self.level.materials.Air, blocksToReplace=[ self.level.materials.Bedrock, self.level.materials.Obsidian, self.level.materials.Fire, self.level.materials.LavaActive, self.level.materials.Lava, ]) self.needsSave = True
def testCopyConvertBlocks(self): indevlevel = self.indevLevel.level level = self.anvilLevel.level x, y, z = level.bounds.origin x += level.bounds.size[0] / 2 & ~15 z += level.bounds.size[2] / 2 & ~15 x -= indevlevel.Width / 2 z -= indevlevel.Height / 2 middle = (x, y, z) oldEntityCount = len( level.getEntitiesInBox(BoundingBox(middle, indevlevel.bounds.size))) level.copyBlocksFrom(indevlevel, indevlevel.bounds, middle) convertedSourceBlocks, convertedSourceData = block_copy.convertBlocks( indevlevel, level, indevlevel.Blocks[0:16, 0:16, 0:indevlevel.Height], indevlevel.Data[0:16, 0:16, 0:indevlevel.Height]) assert ((level.getChunk( x >> 4, z >> 4).Blocks[0:16, 0:16, 0:indevlevel.Height] == convertedSourceBlocks).all()) assert (oldEntityCount + len(indevlevel.getEntitiesInBox(indevlevel.bounds)) == len( level.getEntitiesInBox( BoundingBox(middle, indevlevel.bounds.size))))
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 _degrief(self, command): """ degrief [ <height> ] Reverse a few forms of griefing by removing Adminium, Obsidian, Fire, and Lava wherever they occur above the specified height. Without a height, uses height level 32. Removes natural surface lava. Also see removeEntities """ box = self.level.bounds box = BoundingBox(box.origin + (0, 32, 0), box.size - (0, 32, 0)) if len(command): try: box.miny = int(command[0]) except ValueError: pass print "Removing grief matter and surface lava above height {0}...".format(box.miny) self.level.fillBlocks(box, self.level.materials.Air, blocksToReplace=[self.level.materials.Bedrock, self.level.materials.Obsidian, self.level.materials.Fire, self.level.materials.LavaActive, self.level.materials.Lava, ] ) self.needsSave = True
def _clone(self, command): """ clone <sourceBox> <destPoint> [noair] [nowater] Clone blocks in a cuboid starting at sourcePoint and extending for sourceSize blocks in each direction. Blocks and entities in the area are cloned at destPoint. """ if len(command) == 0: self.printUsage("clone") return box = self.readBox(command) destPoint = self.readPoint(command) destPoint = list(map(int, list(map(floor, destPoint)))) blocksToCopy = self.readBlocksToCopy(command) tempSchematic = self.level.extractSchematic(box) self.level.copyBlocksFrom(tempSchematic, BoundingBox((0, 0, 0), box.origin), destPoint, blocksToCopy) self.needsSave = True print("Cloned 0 blocks.")
def add_block(self, blk): ############################################### o_x = self.settings["origin_x"] o_y = self.settings["origin_y"] o_z = self.settings["origin_z"] blk_size = float(blk[6]) / self.resolution x1 = (self.max_x - float(blk[0])) / self.resolution + o_x y1 = (float(blk[1]) - self.min_y) / self.resolution + o_y z1 = (float(blk[2]) - self.min_z) / self.resolution + o_z r = (int(blk[3])) g = (int(blk[4])) b = (int(blk[5])) box = BoundingBox((x1, y1, z1), (blk_size, blk_size, blk_size)) closest_block = getBlockFromColor((r, g, b)) blockID = closest_block[1] data = closest_block[3] item = self.level.materials.blockWithID(blockID, data) self.level.fillBlocks(box, item)
def testCopy(self): indevlevel = self.indevlevel.level creativelevel = self.creativelevel.level creativelevel.copyBlocksFrom(indevlevel, BoundingBox((0, 0, 0), (64, 64, 64,)), (0, 0, 0)) assert (numpy.array((indevlevel.Blocks[0:64, 0:64, 0:64]) == (creativelevel.Blocks[0:64, 0:64, 0:64])).all()) creativelevel.saveInPlace()
def testFill(self): indevlevel = self.indevlevel.level indevlevel.fillBlocks( BoundingBox((0, 0, 0), ( 64, 64, 64, )), indevlevel.materials.Sand, [indevlevel.materials.Stone, indevlevel.materials.Dirt]) indevlevel.saveInPlace()
def nbttree_mouse_down(e): if e.num_clicks > 1: if tree.selected_item and tree.selected_item[3].startswith('(') and tree.selected_item[3].endswith(')'): s = ast.literal_eval(tree.selected_item[3]) editor.mainViewport.cameraPosition = (s[0] + 0.5, s[1] + 2, s[2] - 1) editor.mainViewport.yaw = 0.0 editor.mainViewport.pitch = 45.0 newBox = BoundingBox(s, (1, 1, 1)) editor.selectionTool.setSelection(newBox) tree.treeRow.__class__.mouse_down(tree.treeRow, e)
def testFill(self): level = self.anvilLevel.level cx, cz = level.allChunks.next() box = BoundingBox((cx * 16, 0, cz * 16), (32, level.Height, 32)) level.fillBlocks(box, level.materials.WoodPlanks) level.fillBlocks(box, level.materials.WoodPlanks, [level.materials.Stone]) level.saveInPlace() c = level.getChunk(cx, cz) assert (c.Blocks == 5).all()
def testRotate(self): level = self.anvilLevel.level schematic = level.extractSchematic(BoundingBox((0, 0, 0), (21, 11, 8))) schematic.rotateLeft() level.copyBlocksFrom(schematic, schematic.bounds, level.bounds.origin, biomes=True, create=True) schematic.flipEastWest() level.copyBlocksFrom(schematic, schematic.bounds, level.bounds.origin, biomes=True, create=True) schematic.flipVertical() level.copyBlocksFrom(schematic, schematic.bounds, level.bounds.origin, biomes=True, create=True)
def testCopy(self): indevlevel = self.indevlevel.level srclevel = self.srclevel.level indevlevel.copyBlocksFrom(srclevel, BoundingBox((0, 0, 0), ( 64, 64, 64, )), (0, 0, 0)) assert ((indevlevel.Blocks[0:64, 0:64, 0:64] == srclevel.Blocks[0:64, 0:64, 0:64]).all())
def drawToolReticle(self): if self.movingPlayer is None: return pos, direction = self.editor.blockFaceUnderCursor pos = (pos[0], pos[1] + 2, pos[2]) x, y, z = pos # x,y,z=map(lambda p,d: p+d, pos, direction) GL.glEnable(GL.GL_BLEND) GL.glColor(1.0, 1.0, 1.0, 0.5) self.drawCharacterHead(x + 0.5, y + 0.75, z + 0.5, self.revPlayerPos[self.movingPlayer]) GL.glDisable(GL.GL_BLEND) GL.glEnable(GL.GL_DEPTH_TEST) self.drawCharacterHead(x + 0.5, y + 0.75, z + 0.5, self.revPlayerPos[self.movingPlayer]) drawTerrainCuttingWire(BoundingBox((x, y, z), (1, 1, 1))) drawTerrainCuttingWire(BoundingBox((x, y - 1, z), (1, 1, 1))) #drawTerrainCuttingWire( BoundingBox((x,y-2,z), (1,1,1)) ) GL.glDisable(GL.GL_DEPTH_TEST)
def testZipSchematic(self): level = self.anvilLevel.level x, y, z = level.bounds.origin x += level.bounds.size[0] / 2 & ~15 z += level.bounds.size[2] / 2 & ~15 box = BoundingBox((x, y, z), (64, 64, 64,)) zs = level.extractZipSchematic(box) assert (box.chunkCount == zs.chunkCount) zs.close() os.remove(zs.filename)
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 drawCage(self, x, y, z): cageTexVerts = pymclevel.MCInfdevOldLevel.materials.blockTextures[52, 0] cageTexVerts = numpy.array([((tx, ty), (tx + 16, ty), (tx + 16, ty + 16), (tx, ty + 16)) for (tx, ty) in cageTexVerts], dtype='float32') GL.glEnable(GL.GL_ALPHA_TEST) drawCube(BoundingBox((x, y, z), (1, 1, 1)), texture=pymclevel.alphaMaterials.terrainTexture, textureVertices=cageTexVerts) GL.glDisable(GL.GL_ALPHA_TEST)
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 readBox(self, command): self.prettySplit(command) sourcePoint = self.readIntPoint(command) if command[0].lower() == "to": command.pop(0) sourcePoint2 = self.readIntPoint(command) sourceSize = sourcePoint2 - sourcePoint else: sourceSize = self.readIntPoint(command, isPoint=False) if len([p for p in sourceSize if p <= 0]): raise UsageError("Box size cannot be zero or negative") box = BoundingBox(sourcePoint, sourceSize) return box
def drawCage(self, x, y, z): cageTexVerts = numpy.array(pymclevel.MCInfdevOldLevel.materials.blockTextures[52, 0]) pixelScale = 0.5 if self.editor.level.materials.name in ("Pocket", "Alpha") else 1.0 texSize = 16 * pixelScale cageTexVerts *= pixelScale cageTexVerts = numpy.array( [((tx, ty), (tx + texSize, ty), (tx + texSize, ty + texSize), (tx, ty + texSize)) for (tx, ty) in cageTexVerts], dtype='float32') GL.glEnable(GL.GL_ALPHA_TEST) drawCube(BoundingBox((x, y, z), (1, 1, 1)), texture=pymclevel.alphaMaterials.terrainTexture, textureVertices=cageTexVerts) GL.glDisable(GL.GL_ALPHA_TEST)
def testSaveRelight(self): indevlevel = self.indevLevel.level level = self.anvilLevel.level cx, cz = -3, -1 level.deleteChunk(cx, cz) level.createChunk(cx, cz) level.copyBlocksFrom(indevlevel, BoundingBox((0, 0, 0), ( 32, 64, 32, )), level.bounds.origin) level.generateLights() level.saveInPlace()
def drawToolReticle(self): pos, direction = self.editor.blockFaceUnderCursor x, y, z = map(lambda p, d: p + d, pos, direction) color = (1.0, 1.0, 1.0, 0.5) if isinstance(self.editor.level, pymclevel.MCInfdevOldLevel) and self.spawnProtection: if not positionValid(self.editor.level, (x, y, z)): color = (1.0, 0.0, 0.0, 0.5) GL.glColor(*color) GL.glEnable(GL.GL_BLEND) self.drawCage(x, y, z) self.drawCharacterHead(x + 0.5, y + 0.5, z + 0.5) GL.glDisable(GL.GL_BLEND) GL.glEnable(GL.GL_DEPTH_TEST) self.drawCage(x, y, z) self.drawCharacterHead(x + 0.5, y + 0.5, z + 0.5) color2 = map(lambda a: a * 0.4, color) drawTerrainCuttingWire(BoundingBox((x, y, z), (1, 1, 1)), color2, color) GL.glDisable(GL.GL_DEPTH_TEST)
def __init__(self, project_file_path, floor_block, level, box, floor_height=255): self.project_file_path = project_file_path self.floor_block = floor_block self.floor_height = floor_height self.area = box self.level = level self.files = None self.functions_path = None self.behavior_pack_uuid = None project_data = None is_project = True # Test if file is json project file -> project_data, use_as_project try: with open(project_file_path) as project_file: project_data = json.load(project_file) except BaseException: is_project = False if is_project: # The file is a json project file if isinstance(project_data, dict): if (('files' not in project_data.keys()) or ('area' not in project_data.keys())): raise Exception('Invalid project file structure. ' + type(project_data) + ' Code:wiv5af') self.files = project_data['files'] area = project_data['area'] minx = area[0] if area[0] < area[3] else area[3] miny = area[1] if area[1] < area[4] else area[4] minz = area[2] if area[2] < area[5] else area[5] maxx = area[0] if area[0] > area[3] else area[3] maxy = area[1] if area[1] > area[4] else area[4] maxz = area[2] if area[2] > area[5] else area[5] self.area = BoundingBox( origin=(minx, miny, minz), size=(maxx-minx, maxy-miny, maxz-minz) ) # Save additional options data if 'floor_height' in project_data.keys(): self.floor_height = project_data['floor_height'] if 'behavior_pack_uuid' in project_data.keys(): self.behavior_pack_uuid = \ project_data['behavior_pack_uuid'] if 'functions_path' in project_data.keys(): self.functions_path = project_data['functions_path'] elif isinstance(project_data, list): self.files = project_data else: raise Exception('Invalid project file structure. ' + type(project_data) + ' Code:x6ibzz') path = os.path.split(project_file_path)[0] if self.functions_path is not None: self.functions_path = os.path.join(path, self.functions_path) else: # The file is a brfunction self.files = [os.path.basename(project_file_path)]
def fit_elements(meta_input, element_list, OPTIONS): schematic_bufferX = 3 #schematic_bufferZ = 4 # Also, the schematics must be spaced out a certain length as well total_schematic_lengthX = sum(s.size[0] for s in element_list) sizeX = total_schematic_lengthX + schematic_bufferX * len(element_list) + 2 sizeZ = element_list[0].size[2] sizeZ += 2 * max(len(meta_input.input_domain), len( meta_input.output_range)) + 6 sizeY = max(s.size[1] for s in element_list) + 5 level = MCSchematic(shape=(sizeX, sizeY, sizeZ)) box = BoundingBox((0, 0, 0), (sizeX, sizeY, sizeZ)) cx, cy, cz = 2, 0, 0 schematic_origins = {} for s in element_list: schematic_origins[s] = [cx, cy, cz] level.copyBlocksFrom(s.schematic, BoundingBox((0, 0, 0), s.size), (cx, cy, cz)) cx += s.size[0] + schematic_bufferX # The schematics contain their own *relative* input locations in a dict of the form # input name --> (x, y, z). We wish to make a giant composite list of all the *absolute* locations # of the inputs, this time of the form (x, y, z) --> input name. We obtain the absolute # location by adding the individual schematic origin (in our coordinate system) with the # schematic's relative coordinate. absolute_input_locations = {} for s in element_list: for key, value in s.relative_input_locations.items(): abs_loc = add_tuples(schematic_origins[s], value) absolute_input_locations[abs_loc] = key # The z value for all the input locations will be the same. We just need to grab an arbitrary # one and use it to define the starting z location for the input rails input_z = 5 + absolute_input_locations.keys()[0][2] input_rail_z_values = {} for i in meta_input.input_domain: input_rail_z_values[i] = input_z input_z += 2 absolute_output_locations = {} for s in element_list: for key, value in s.relative_output_locations.items(): abs_loc = add_tuples(schematic_origins[s], value) absolute_output_locations[abs_loc] = key output_z = 4 + absolute_output_locations.keys()[0][2] output_rail_z_values = {} for i in meta_input.output_range: output_rail_z_values[i] = output_z output_z += 2 # Step through the input locations and build backward to to the point where it joins # up with the appropriate input rail. The rail will actually be built later. for input_loc, input_name in absolute_input_locations.items(): cx, cy, cz = input_loc[0], input_loc[1], input_loc[2] cz += 1 while (cz < input_rail_z_values[input_name] - 1): level.setBlockAt(cx, cy, cz, REDSTONE) cz += 1 level.setBlockAt(cx, cy, cz, REPEATER) cz += 1 level.setBlockAt(cx, cy, cz, WOOL) level.setBlockDataAt(cx, cy, cz, meta_input.input_color_key[input_name]) cy += 1 level.setBlockAt(cx, cy, cz, REDSTONE) # Step through the output locations and build backward to to the point where it joins # up with the appropriate output rail. The rail will actually be built later. for output_loc, output_name in absolute_output_locations.items(): if OPTIONS["make_output_rail"] == False: continue cx, cy, cz = output_loc[0], output_loc[1], output_loc[2] cz += 1 while (cz < output_rail_z_values[output_name] - 1): level.setBlockAt(cx, cy, cz, REDSTONE) cy -= 1 level.setBlockAt(cx, cy, cz, WOOL) level.setBlockDataAt(cx, cy, cz, meta_input.output_color_key[output_name]) cy += 1 cz += 1 level.setBlockAt(cx, cy, cz, REPEATER) level.setBlockDataAt(cx, cy, cz, REPEATER_TOWARD_POS_Z) cy -= 1 level.setBlockAt(cx, cy, cz, WOOL) level.setBlockDataAt(cx, cy, cz, meta_input.output_color_key[output_name]) cy += 1 cz += 1 level.setBlockAt(cx, cy, cz, WOOL) level.setBlockDataAt(cx, cy, cz, meta_input.output_color_key[output_name]) cy += 1 level.setBlockAt(cx, cy, cz, REDSTONE) # Now build the input rails! for input_name, input_z_value in input_rail_z_values.items(): cx, cy, cz = 0, 2, input_z_value while cx < sizeX: cy -= 1 if level.blockAt(cx, cy, cz) != REDSTONE: level.setBlockAt(cx, cy, cz, WOOL) level.setBlockDataAt(cx, cy, cz, meta_input.input_color_key[input_name]) level.setBlockAt(cx, cy, cz - 1, WOOL) level.setBlockDataAt(cx, cy, cz - 1, WOOL_BLACK) level.setBlockAt(cx, cy, cz + 1, WOOL) level.setBlockDataAt(cx, cy, cz + 1, WOOL_BLACK) cy += 1 level.setBlockAt(cx, cy, cz, REDSTONE) cx += 1 # We need to put repeaters on the input rail. There are multiple ways to do so. If POSSIBLE, # use the gap method. To do this we need to perform the following algorithm to find the # gaps inbetween inputs. # Find the x values of the 'gaps' between clusters # of inputs. These are nice open spots to put repeaters. The following is a 'find the gap' # algorithm that ends up with a list of x values where repeaters should be placed (rep_locs) # Get the x values of the inputs input_x_values = list(x[0] for x in absolute_input_locations.keys()) input_x_values.sort() # Get the differences between each pair of input x values diffs = list(input_x_values[i] - input_x_values[i - 1] for i in range(1, len(input_x_values))) # Where these differences are more than 2, that means that we had a jump in the x values. # Obtain the indexes of the two input x values on either side of the jump gap_index_pairs = list( (i, i + 1) for i in range(len(diffs)) if diffs[i] > 2) # Finally, for each index pair, we want the x value in between the x values at those indices: # input_x_values[x] ---------------- (*) --------------- input_x_values[y] for each (x, y) pair in gap_index_pairs rep_locs = list(input_x_values[x] + int((input_x_values[y] - input_x_values[x]) / 2) for x, y in gap_index_pairs) # Now put repeaters on the input rail # We can get away with gap method if the rep_locs are within 15 spaces apart. Otherwise, # we'll HAVE to use an ugly-ass method rep_loc_spacings = list(rep_locs[i] - rep_locs[i - 1] for i in range(1, len(rep_locs))) if len(rep_loc_spacings) > 0: rep_loc_max_spacing = max(rep_loc_spacings) else: # The method fails... just set max spacing to something ridiculous so that it does the other method rep_loc_max_spacing = 100 if rep_loc_max_spacing <= 14: print "inputs - gap method" # GAP METHOD -- very nice looking, but doesn't work when the input domain is very large # because there *won't be any* gaps within 15 units, so it will place no repeaters. cy = 2 for iter_cx in rep_locs: for iter_cz in input_rail_z_values.values(): level.setBlockAt(iter_cx, cy, iter_cz, REPEATER) level.setBlockDataAt(iter_cx, cy, iter_cz, REPEATER_TOWARD_POS_X) else: print "inputs - method 2" # Method 2 -- aesthetically displeasing... has to fudge around the block edges and produces # lines of repeaters with 'imperfections' from scooting the necessary ones for input_name, input_z_value in input_rail_z_values.items(): cx, cy, cz = 12, 2, input_z_value while cx < sizeX: if level.blockAt(cx, cy - 1, cz) == REDSTONE: level.setBlockAt(cx - 2, cy, cz, REPEATER) level.setBlockDataAt(cx - 2, cy, cz, REPEATER_TOWARD_POS_X) elif level.blockAt(cx - 1, cy - 1, cz) == REDSTONE: level.setBlockAt(cx + 1, cy, cz, REPEATER) level.setBlockDataAt(cx + 1, cy, cz, REPEATER_TOWARD_POS_X) elif level.blockAt(cx + 1, cy - 1, cz) == REDSTONE: level.setBlockAt(cx - 1, cy, cz, REPEATER) level.setBlockDataAt(cx - 1, cy, cz, REPEATER_TOWARD_POS_X) else: level.setBlockAt(cx, cy, cz, REPEATER) level.setBlockDataAt(cx, cy, cz, REPEATER_TOWARD_POS_X) cx += 12 if OPTIONS["make_output_rail"]: # Now build the output rails! outputHeight = absolute_output_locations.keys()[0][1] + 2 for output_name, output_z_value in output_rail_z_values.items(): cx, cy, cz = 0, outputHeight, output_z_value while cx < sizeX: cy -= 1 if level.blockAt(cx, cy, cz) != REDSTONE: level.setBlockAt(cx, cy, cz, WOOL) level.setBlockDataAt( cx, cy, cz, meta_input.output_color_key[output_name]) level.setBlockAt(cx, cy, cz - 1, WOOL) level.setBlockDataAt(cx, cy, cz - 1, WOOL_BLACK) level.setBlockAt(cx, cy, cz + 1, WOOL) level.setBlockDataAt(cx, cy, cz + 1, WOOL_BLACK) cy += 1 level.setBlockAt(cx, cy, cz, REDSTONE) cx += 1 # We need to find gaps for the gap method again output_x_values = list(x[0] for x in absolute_output_locations.keys()) output_x_values.sort() diffs = list(output_x_values[i] - output_x_values[i - 1] for i in range(1, len(output_x_values))) gap_index_pairs = list( (i, i + 1) for i in range(len(diffs)) if diffs[i] > 2) rep_locs = list(output_x_values[x] + int((output_x_values[y] - output_x_values[x]) / 2) for x, y in gap_index_pairs) if len(rep_loc_spacings) > 0: rep_loc_max_spacing = max(rep_loc_spacings) else: # The method fails... just set max spacing to something ridiculous so that it does the other method rep_loc_max_spacing = 100 if rep_loc_max_spacing < 14: print "outputs - gap method" # GAP METHOD -- very nice looking, but doesn't work when the input domain is very large # because there *won't be any* gaps within 15 units, so it will place no repeaters. cy = outputHeight for iter_cx in rep_locs: for iter_cz in output_rail_z_values.values(): level.setBlockAt(iter_cx, cy, iter_cz, REPEATER) level.setBlockDataAt(iter_cx, cy, iter_cz, REPEATER_TOWARD_NEG_X) else: print "outputs - method 2" # Method 2 -- aesthetically displeasing... has to fudge around the block edges and produces # lines of repeaters with 'imperfections' from scooting the necessary ones for output_name, output_z_value in output_rail_z_values.items(): cx, cy, cz = 12, outputHeight, output_z_value while cx < sizeX: if level.blockAt(cx, cy - 1, cz) == REDSTONE: level.setBlockAt(cx - 2, cy, cz, REPEATER) level.setBlockDataAt(cx - 2, cy, cz, REPEATER_TOWARD_NEG_X) elif level.blockAt(cx - 1, cy - 1, cz) == REDSTONE: level.setBlockAt(cx + 1, cy, cz, REPEATER) level.setBlockDataAt(cx + 1, cy, cz, REPEATER_TOWARD_NEG_X) elif level.blockAt(cx + 1, cy - 1, cz) == REDSTONE: level.setBlockAt(cx - 1, cy, cz, REPEATER) level.setBlockDataAt(cx - 1, cy, cz, REPEATER_TOWARD_NEG_X) else: level.setBlockAt(cx, cy, cz, REPEATER) level.setBlockDataAt(cx, cy, cz, REPEATER_TOWARD_NEG_X) cx += 12 return level
def _testCreate(filename): gen.createLevel(filename, BoundingBox((-128, 0, -128), (128, 128, 128)))
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 perform(level, box, options): global search by = options["Match by:"] matchtype = options["Match block type (for TileEntity searches):"] matchblock = options["Match block:"] matchdata = options["Match block data:"] matchtile = options["Match tile entities (for Block searches):"] matchname = u"" if options["Match Tag Name:"] == "None" else unicode( options["Match Tag Name:"]) matchval = u"" if options["Match Tag Value:"] == "None" else unicode( options["Match Tag Value:"]) caseSensitive = not options["Case insensitive:"] matchtagtype = tagtypes[options[ "Match Tag Type:"]] if options["Match Tag Type:"] != "Any" else "Any" op = options["Operation:"] #-# if newLayout: datas = [] #-# if not caseSensitive: matchname = matchname.upper() matchval = matchval.upper() if matchtile and matchname == "" and matchval == "": alert( "\nInvalid Tag Name and Value; the present values will match every tag of the specified type." ) if search is None or op == "Start New Search" or op == "Dump Found Coordinates": search = [] if not search: if by == "Block": for x in xrange(box.minx, box.maxx): for z in xrange(box.minz, box.maxz): for y in xrange(box.miny, box.maxy): block = level.blockAt(x, y, z) data = level.blockDataAt(x, y, z) if block == matchblock.ID and ( not matchdata or data == matchblock.blockData): pass else: continue if matchtile: tile = level.tileEntityAt(x, y, z) if tile is not None: if not FindTag(tile, matchname, matchval, tagses[matchtagtype], caseSensitive): continue else: continue search.append((x, y, z)) if newLayout: datas.append(data) elif by == "TileEntity": for (chunk, _, _) in level.getChunkSlices(box): for e in chunk.TileEntities: x = e["x"].value y = e["y"].value z = e["z"].value if (x, y, z) in box: if matchtype: block = level.blockAt(x, y, z) data = level.blockDataAt(x, y, z) if block == matchblock.ID and ( not matchdata or data == matchblock.blockData): pass else: continue if not FindTag(e, matchname, matchval, tagses[matchtagtype], caseSensitive): continue search.append((x, y, z)) if newLayout: datas.append(e) else: for (chunk, _, _) in level.getChunkSlices(box): for e in chunk.Entities: x = e["Pos"][0].value y = e["Pos"][1].value z = e["Pos"][2].value if (x, y, z) in box: if FindTag(e, matchname, matchval, tagses[matchtagtype], caseSensitive): search.append((x, y, z)) if newLayout: datas.append(e) if not search: alert("\nNo matching blocks/tile entities found") else: search.sort() if op == "Dump Found Coordinates": alert("\nMatching Coordinates:\n" + "\n".join("%d, %d, %d" % pos for pos in search)) else: #-# if newLayout: treeData = {} for i in range(len(search)): if by == 'Block': treeData[u"%s" % (search[i], )] = datas[i] else: treeData[u"%s" % ((datas[i]['Pos'][0].value, datas[i]['Pos'][1].value, datas[i]['Pos'][2].value), )] = datas[i] inputs[1][1][1][1] = {'Data': treeData} options[""](inputs[1]) else: for s in search: editor.mainViewport.cameraPosition = (s[0] + 0.5, s[1] + 2, s[2] - 1) editor.mainViewport.yaw = 0.0 editor.mainViewport.pitch = 45.0 newBox = BoundingBox(s, (1, 1, 1)) editor.selectionTool.setSelection(newBox) if not editor.YesNoWidget( "Matching blocks/tile entities found at " + str(s) + ".\nContinue search?"): alert("\nSearch halted.") else: alert("\nEnd of search.")
def generate(comb_equation, use_input_color_key=None, use_output_color_key=None): inputs = comb_equation.inputs minterms = comb_equation.minterms form = form_tall if len(minterms) > 5 else form_short formBox = formBox_tall if len(minterms) > 5 else formBox_short implicantLimit = 13 if len(minterms) > 5 else 5 while len(minterms) % implicantLimit != 0: minterms.append({}) numXCopies = int(math.ceil(len(inputs) / 4)) sizeX = numXCopies * form.Width + 2 numYCopies = int(math.ceil(len(minterms) / implicantLimit)) sizeY = numYCopies * form.Height + 3 sizeZ = form.Length + 1 # print sizeX, sizeY, sizeZ level = MCSchematic(shape=(sizeX, sizeY, sizeZ)) box = BoundingBox((0, 0, 0), (sizeX, sizeY, sizeZ)) # ================================================================================================ # Paste the schematic the number of times we know we'll need pasteX = 0 for i in range(numXCopies): pasteY = 1 for i in range(numYCopies): level.copyBlocksFrom(form, formBox, (pasteX, pasteY, 0)) pasteY += form.Height pasteX += form.Width # Fill the bottom plane with a ground # level.fillBlocks(BoundingBox((0, 0, 0), (sizeX, 1, sizeZ)), alphaMaterials.BlockofIron) # Build X-ways across each row corresponding to each term cx = 0 cy = 2 cz = 1 numTerms = 0 side = CLOSE_SIDE relative_input_locations = {} for termIndex in range(len(minterms)): term = minterms[termIndex] cx = 0 for i in inputs: if i in term.keys(): mat = TORCH if term[i] else REDSTONE else: mat = AIR data = TORCH_POINTING_NEG_Z if (cz == 1) else TORCH_POINTING_POS_Z level.setBlockAt(cx, cy, cz, mat) level.setBlockDataAt(cx, cy, cz, data) if termIndex == 0: sx = cx sy = cy - 2 sz = cz + 4 for iter_sz in [sz, sz + 1, sz + 2, sz + 3]: level.setBlockAt(sx, sy, iter_sz, WOOL) data = WOOL_BLACK if use_input_color_key == None else use_input_color_key[ i] level.setBlockDataAt(sx, sy, iter_sz, data) relative_input_locations[i] = [sx, sy, sz + 2] cx += 2 # Build the slice of the side scaffolding that goes on this row's height level: # ----------------------------------------------------------------------------- prevCy = cy prevCz = cz cx = box.width - 2 if side == CLOSE_SIDE: cz -= 1 cy -= 1 elif side == FAR_SIDE: cz += 1 cy -= 1 if len(term) > 0: level.setBlockAt(cx, cy, cz, TORCH) level.setBlockDataAt(cx, cy, cz, TORCH_POINTING_POS_X) cx += 1 cy -= 1 if numTerms in [0, 1]: level.setBlockAt(cx, cy, cz, DOUBLE_SLAB) level.setBlockDataAt(cx, cy, cz, DOUBLE_SLAB_STONE) else: level.setBlockAt(cx, cy, cz, SLAB) level.setBlockDataAt(cx, cy, cz, STONE_SLAB_TOP) cy += 1 level.setBlockAt(cx, cy, cz, REDSTONE) if side == CLOSE_SIDE: cz += 1 elif side == FAR_SIDE: cz -= 1 level.setBlockAt(cx, cy, cz, SLAB) level.setBlockDataAt(cx, cy, cz, STONE_SLAB_TOP) cy += 1 level.setBlockAt(cx, cy, cz, REDSTONE) if side == CLOSE_SIDE: currentCloseTowerTopY = cy currentCloseTowerTopZ = cz elif side == FAR_SIDE: currentFarTowerTopY = cy currentFarTowerTopZ = cz cy = prevCy cz = prevCz # ----------------------------------------------------------------------------- # Switch sides side = FAR_SIDE if (side == CLOSE_SIDE) else CLOSE_SIDE # The z location alternates depending on the side if side == CLOSE_SIDE: cz = 1 if side == FAR_SIDE: cz = 8 # Keep track of the number of terms numTerms += 1 # JUMP LOGIC # Normal case: cy goes up by one, we are working term by term up one paste of the schematic # Special case: We have done 13 terms, and need to 'jump' to the next paste of the schematic # This requires some special connecting and bridging. # ------------------------------------------------------------------------------------------ if numTerms == implicantLimit: sx = box.width - 1 sy = currentCloseTowerTopY sz = currentCloseTowerTopZ sz += 1 level.setBlockAt(sx, sy, sz, WOOL) level.setBlockDataAt(sx, sy, sz, WOOL_BLACK) sz += 1 level.setBlockAt(sx, sy, sz, TORCH) level.setBlockDataAt(sx, sy, sz, TORCH_POINTING_POS_Z) sy += 1 for itr_sz in [sz, sz - 1, sz - 2]: level.setBlockAt(sx, sy, itr_sz, WOOL) level.setBlockDataAt(sx, sy, itr_sz, WOOL_BLACK) sy += 1 level.setBlockAt(sx, sy, sz, TORCH) level.setBlockDataAt(sx, sy, sz, TORCH_ON_GROUND) sz -= 1 level.setBlockAt(sx, sy, sz, REDSTONE) sz -= 1 level.setBlockAt(sx, sy, sz, REPEATER) # If we are finished with the whole thing, make the lead the exposes # The signal to the rest of the world if termIndex == len(minterms) - 1: sz += 2 sy += 1 data = WOOL_BLACK if use_output_color_key == None else use_output_color_key[ comb_equation.name] for iter_sz in range(sz, sz + 7, 1): level.setBlockAt(sx, sy, iter_sz, WOOL) level.setBlockDataAt(sx, sy, iter_sz, data) sy += 1 level.setBlockAt(sx, sy, iter_sz, REDSTONE) sy -= 1 sz += 7 level.setBlockAt(sx, sy, sz, WOOL) level.setBlockDataAt(sx, sy, sz, data) sy += 1 level.setBlockAt(sx, sy, sz, REPEATER) level.setBlockDataAt(sx, sy, sz, REPEATER_TOWARD_POS_Z) lead_location = [sx, sy, sz] # ----------------------------------------------------- sx = box.width - 1 sy = currentFarTowerTopY sz = currentFarTowerTopZ sz -= 1 level.setBlockAt(sx, sy, sz, WOOL) level.setBlockDataAt(sx, sy, sz, WOOL_BLACK) sy += 1 level.setBlockAt(sx, sy, sz, 75) level.setBlockDataAt(sx, sy, sz, 5) sz += 1 level.setBlockAt(sx, sy, sz, WOOL) level.setBlockDataAt(sx, sy, sz, WOOL_BLACK) sz -= 1 sy += 1 level.setBlockAt(sx, sy, sz, WOOL) level.setBlockDataAt(sx, sy, sz, WOOL_BLACK) sz += 1 level.setBlockAt(sx, sy, sz, REDSTONE) sz += 1 level.setBlockAt(sx, sy, sz, WOOL) level.setBlockDataAt(sx, sy, sz, WOOL_BLACK) sy += 1 level.setBlockAt(sx, sy, sz, TORCH) level.setBlockDataAt(sx, sy, sz, TORCH_ON_GROUND) # Now reset the variables for working up the next paste: cy += 4 numTerms = 0 side = CLOSE_SIDE cz = 1 else: cy += 1 # level.setBlockAt(0, 0, 0, 20) # level.setBlockAt(box.width-1, box.height-1, box.length-1, 20) # # Flip the entire schematic around to help make the fitting routine more 'sane' # # Also adjust location variables (like the locations of the lead and inputs) to # # reflect the Z-flip # # level.flipEastWest() # lead_location[2] = sizeZ - 1 - lead_location[2] # for ril in relative_input_locations.values(): # ril[2] = sizeZ - 1 - ril[2] # level.setBlockAt(*lead_location, blockID = 35) # level.setBlockDataAt(*lead_location, newdata = 0) # # for ril in relative_input_locations.values(): # level.setBlockAt(*ril, blockID = GLASS) ret = CombinationalElement(level) ret.relative_output_locations = {comb_equation.name: lead_location} ret.relative_input_locations = relative_input_locations ret.size = (sizeX, sizeY, sizeZ) return ret
from __future__ import division import os, math me = os.path.dirname(__file__) from block_constants import * from Element import CombinationalElement from pymclevel.schematic import MCSchematic from pymclevel.box import BoundingBox from pymclevel import alphaMaterials form_tall = MCSchematic( filename=os.path.join(me, "..", "res", "generic_boolean_blank.schematic")) form_short = MCSchematic(filename=os.path.join( me, "..", "res", "generic_boolean_short_blank.schematic")) formBox_tall = BoundingBox( (0, 0, 0), (form_tall.Width, form_tall.Height, form_tall.Length)) formBox_short = BoundingBox( (0, 0, 0), (form_short.Width, form_short.Height, form_short.Length)) def generate(comb_equation, use_input_color_key=None, use_output_color_key=None): inputs = comb_equation.inputs minterms = comb_equation.minterms form = form_tall if len(minterms) > 5 else form_short formBox = formBox_tall if len(minterms) > 5 else formBox_short implicantLimit = 13 if len(minterms) > 5 else 5
def testReplace(self): level = self.anvilLevel.level level.fillBlocks(BoundingBox( (-11, 0, -7), (38, level.Height, 25)), level.materials.WoodPlanks, [level.materials.Dirt, level.materials.Grass])
def testCreateChunks(self): level = self.anvilLevel.level for ch in list(level.allChunks): level.deleteChunk(*ch) level.createChunksInBox(BoundingBox((0, 0, 0), (32, 0, 32)))