def makeATower(stats, level, box, wallMaterials, floorMaterials, glassMaterials, lightMaterials): width = box.maxx - box.minx height = box.maxy - box.miny depth = box.maxz - box.minz roofy = int(height / 4) * randint(2, 3) roofBox = BoundingBox((box.minx, box.maxy - roofy, box.minz), (width, roofy, depth)) makeASpire(stats, level, roofBox, wallMaterials, floorMaterials, glassMaterials, lightMaterials) y = 0 while y < height - roofy: dy = randint(3, 5) dr = randint(3, 9) w = 2 + int(width / dr) d = 2 + int(depth / dr) h = dr baseBox = BoundingBox( (box.minx + (w >> 1), box.miny + y, box.minz + (d >> 1)), (width - w, h, depth - d)) cylinderVertical(stats, level, baseBox, wallMaterials[0]) baseBox = BoundingBox( (box.minx + (w >> 1) + 1, box.miny + y + 1, box.minz + (d >> 1) + 1), (width - w - 2, h - 2, depth - d - 2)) cylinderVertical(stats, level, baseBox, (0, 0)) y += dr
def Fractal(level, box, options): # CONSTANTS method = "FRACTAL" print '%s: Started at %s' % (method, time.ctime()) (width, height, depth) = getBoxSize(box) centreWidth = (int)(width / 2) centreHeight = (int)(height / 2) centreDepth = (int)(depth / 2) AIR = (0, 0) schematic = level.extractSchematic( BoundingBox((box.minx, box.miny, box.minz), (width, height, depth))) for y in xrange(0, height): print '%s: Examining the selection area - step %s of %s' % (method, y, height - 1) for x in xrange(0, width): for z in xrange(0, depth): # If the current block is not air, blit the schematic into the corresponding area in space tempBlock = (schematic.blockAt(x, y, z), schematic.blockDataAt(x, y, z)) if tempBlock != AIR: level.copyBlocksFrom( schematic, BoundingBox((0, 0, 0), (width, height, depth)), (box.minx + x * width, box.miny + y * height, box.minz + z * height)) print '%s: Ended at %s' % (method, time.ctime())
def __init__(self, plot, **kwargs): self.plot = plot groundlevel = int( np.mean( [ plot.site.surfaceHeightAt(pos) for pos in bu.floor(plot).positions ] ) ) self.box = BoundingBox( (plot.minx, groundlevel, plot.minz), plot.size ) # front is towards the widest road if not plot.hasNeighbourWithTag('road'): self.front = random.choice( [Direction.North, Direction.East, Direction.South, Direction.West] ) else: widestRoad = max( plot.neighboursWithTag('road'), key=lambda road: min(road.width, road.length)) self.front = bu.touchDirection(plot, widestRoad) # lay out the building shell roomHeight = kwargs.get("roomHeight", 2) storeySize = Vector(self.box.width, roomHeight, self.box.length) self.storeys = [] self.floors = [] nStoreys = kwargs.get("nStoreys", 2) # split the house into a sequence alternating between height=one floors and height=x storeys for s in range(nStoreys): self.floors.append( BoundingBox(self.box.origin + (0, s*(roomHeight+1), 0), (self.box.width, 1, self.box.length)) ) self.storeys.append( BoundingBox(self.box.origin + (0, s*(roomHeight+1) +1, 0), storeySize) ) # update height of bounds self.box = bu.expandMax(self.box, dy = nStoreys*(roomHeight+1) - self.box.height) # the roof is the final, topmost 'floor' self.roof = BoundingBox(self.box.origin + (0, nStoreys*(roomHeight+1), 0), (self.box.width, 1, self.box.length))
def BlockRandomiserThing(level, box, options): # Prototype - works upwards AIR = (0, 0) method = "BlockRandomiserThing" print '%s: Started at %s' % (method, time.ctime()) # Rearranges the blocks in the selection, randomly, with a chance of leaving some of them out of the result (width, height, depth) = getBoxSize(box) schematic = level.extractSchematic( BoundingBox((box.minx, box.miny, box.minz), (width, height, depth))) for y in xrange(0, height): print '%s: Examining the selection area - step %s of %s' % (method, y, height - 1) for x in xrange(0, width): for z in xrange(0, depth): tempBlock = (schematic.blockAt(x, y, z), schematic.blockDataAt(x, y, z)) tempBlockBelow = (schematic.blockAt(x, y - 1, z), schematic.blockDataAt(x, y - 1, z)) if y > 0: if tempBlockBelow == AIR: setBlock(schematic, AIR, x, y, z) if randint(0, 100) < options["Chance of air"]: setBlock(schematic, AIR, x, y, z) level.copyBlocksFrom(schematic, BoundingBox((0, 0, 0), (width, height, depth)), (box.minx, box.miny, box.minz))
def perform(level, box, options): b=range(4096) b.remove(0) # @CodeWarrior0 and @Wout12345 explained how to merge schematics buildingSize = options["Building Size"] width = box.maxx-box.minx depth = box.maxz-box.minz height = box.maxy-box.miny x = 0 cursor = 0 while x+buildingSize < width: z = 0 while z+buildingSize < depth: print "Building "+str(x)+","+str(z) p1 = (buildingSize,randint(height-1,height),buildingSize) #p1 = (buildingSize,height,buildingSize) buildingBox = BoundingBox((0,0,0),p1) buildingSchema = level.extractSchematic(BoundingBox((box.minx+x,box.miny,box.minz+z),p1)) building(buildingSchema, buildingBox,options) level.copyBlocksFrom(buildingSchema, buildingBox, (box.minx+x, box.miny, box.minz+z ),b) buildingSchema.saveToFile(filename="BuildingGotham_"+str(randint(1000000000,9999999999))+".schematic") z += buildingSize+options["Building Gap"] x += buildingSize+options["Building Gap"] cursor += 1 if cursor%3 == 2: x += 2*options["Path Gap"] + options["Road Gap"] level.markDirtyBox(box)
def Surface(level,box,spacing): op = "Surface" #level2 = level.extractSchematic(box) # Working set level2 = MCSchematic((box.width,box.height,box.length)) box2 = BoundingBox((0,0,0),(box.width,box.height,box.length)) airlevel = MCSchematic((box.width,box.height,box.length)) airbox = BoundingBox((0,0,0),(box.width,box.height,box.length)) for x in xrange(box.minx,box.maxx): if x%10 == 0: print str(time.ctime())+" Scanning for surfaces "+op+" "+str(x) for z in xrange(box.minz,box.maxz): for y in xrange(box.miny,box.maxy): if getBlock(level,x,y,z) != (0,0): for ddx in xrange(-1,2): for ddz in xrange(-1,2): for ddy in xrange(-1,2): if not (ddx == 0 and ddy == 0 and ddz == 0): if getBlock(level,x+ddx,y+ddy,z+ddz) == (0,0): setBlock(airlevel,(1,0),x-box.minx,y-box.miny,z-box.minz) # Adjacent to air / surface else: setBlock(airlevel,(2,0),x-box.minx,y-box.miny,z-box.minz) # Airblock here for x in xrange(box.minx,box.maxx): if x%10 == 0: print str(time.ctime())+" Running "+op+" "+str(x) for z in xrange(box.minz,box.maxz): for y in xrange(box.miny,box.maxy): if getBlock(airlevel,x-box.minx,y-box.miny,z-box.minz) == (1,0): # This is a surface block setBlock(level2,getBlock(level,x,y,z),x-box.minx,y-box.miny,z-box.minz) level.copyBlocksFrom(level2, box2, (box.minx, box.miny, box.minz ))
def binaryPartition(box): partitions = [] # create a queue which holds the next areas to be partitioned queue = [] queue.append(box) # for as long as the queue still has boxes to partition... count = 0 while len(queue) > 0: count += 1 splitMe = queue.pop(0) (width, height, depth) = utilityFunctions.getBoxSize(splitMe) # print "Current partition width,depth",width,depth centre = 0 # this bool lets me know which dimension I will be splitting on. It matters when we create the new outer bound size isWidth = False # find the larger dimension and divide in half # if the larger dimension is < 10, then block this from being partitioned minSize = 12 if width > depth: # roll a random die, 1% change we stop anyways chance = random.randint(100) if depth < minSize or chance == 1: partitions.append(splitMe) continue isWidth = True centre = width / 2 else: chance = random.randint(10) if width < minSize or chance == 1: partitions.append(splitMe) continue centre = depth / 2 # a random modifier for binary splitting which is somewhere between 0 and 1/16 the total box side length randomPartition = random.randint(0, (centre / 8) + 1) # creating the new bound newBound = centre + randomPartition #creating the outer edge bounds outsideNewBounds = 0 if isWidth: outsideNewBound = width - newBound - 1 else: outsideNewBound = depth - newBound - 1 # creating the bounding boxes # NOTE: BoundingBoxes are objects contained within pymclevel and can be instantiated as follows # BoundingBox((x,y,z), (sizex, sizey, sizez)) # in this instance, you specifiy which corner to start, and then the size of the box dimensions # this is an if statement to separate out binary partitions by dimension (x and z) if isWidth: queue.append(BoundingBox((splitMe.minx, splitMe.miny, splitMe.minz), (newBound-1, 256, depth))) queue.append(BoundingBox((splitMe.minx + newBound + 1, splitMe.miny, splitMe.minz), (outsideNewBound - 1, 256, depth))) else: queue.append(BoundingBox((splitMe.minx, splitMe.miny, splitMe.minz), (width, 256, newBound - 1))) queue.append(BoundingBox((splitMe.minx, splitMe.miny, splitMe.minz + newBound + 1), (width, 256, outsideNewBound - 1))) return partitions
def perform(level,box, options): ''' Feedback to [email protected] ''' # Local variables method = options["Operation"] (method, (width, height, depth), (centreWidth, centreHeight, centreDepth)) = FuncStart(level,box,options,method) # Log start level0 = level.extractSchematic(box) # Copy the area of interest into a working area, mostly for 'speed' box0 = BoundingBox((0,0,0),(width,height,depth)) b=range(4096) b.remove(0) # @CodeWarrior0 and @Wout12345 explained how to merge schematics if method == "Islands": for i in xrange(0,1000): print i radius = randint(10,50) centrex = randint(radius+2,width-radius-2) centrez = randint(radius+2,depth-radius-2) maxy = randint(radius+2,height-radius-2) theBox = BoundingBox((0,0,0),(2*radius-1,maxy-1,2*radius-1)) theObj = MCSchematic((2*radius-1,maxy-1,2*radius-1)) island(theObj,theBox,options) level0.copyBlocksFrom(theObj, theBox, (box0.minx+centrex-radius,box0.miny,box0.minz+centrez-radius),b) elif method == "Island": theBox = BoundingBox((0,0,0),(width,height,depth)) theObj = MCSchematic((width,height,depth)) island(theObj, theBox, options) level0.copyBlocksFrom(theObj, theBox, (box0.minx,box0.miny,box0.minz),b) level.copyBlocksFrom(level0, box0, (box.minx, box.miny, box.minz )) # Copy the working area back into the world level.markDirtyBox(box) FuncEnd(level,box,options,method) # Log end
def QuadraticSurface(level, box, options): # CONSTANTS method = "QUADRATIC SURFACE" print '%s: Started at %s' % (method, time.ctime()) (width, height, depth) = getBoxSize(box) centreWidth = (int)(width / 2) centreHeight = (int)(height / 2) centreDepth = (int)(depth / 2) AIR = (0,0) BLOCKID = options["Pick a block:"].ID BLOCKDATA = options["Pick a block:"].blockData VERTMAGSCALE = options["Vertical Magnification"] HORIZMAGSCALE = options["Horizontal Magnification"] TOLERANCE = options["Tolerance"] PARAMETERS = options["Random"] schematic = level.extractSchematic(BoundingBox((box.minx, box.miny, box.minz), (width, height, depth))) # Mirror the blocks - in memory working read only copy a = random.uniform(-2, 2) b = random.uniform(-2, 2) c = random.uniform(-2, 2) f = random.uniform(-2, 2) g = random.uniform(-2, 2) h = random.uniform(-2, 2) p = random.uniform(-2, 2) q = random.uniform(-2, 2) r = random.uniform(-2, 2) d = random.uniform(-2, 2) if PARAMETERS == False: a = options["a"] b = options["b"] c = options["c"] f = options["f"] g = options["g"] h = options["h"] p = options["p"] q = options["q"] r = options["r"] d = options["d"] for xx in xrange(-centreWidth, centreWidth): print '%s of %s' % (xx, centreWidth) x = xx * HORIZMAGSCALE for yy in xrange(-centreHeight, centreHeight): y = yy * VERTMAGSCALE for zz in xrange(-centreDepth, centreDepth): z = zz * HORIZMAGSCALE if abs(a*x*x+b*y*y+c*z*z+2*f*y*z+2*g*z*x+2*h*x*y+2*p*x+2*q*y+2*r*z+d) <= TOLERANCE: setBlock(schematic, (BLOCKID, BLOCKDATA), (int)(centreWidth+xx), (int)(centreHeight+yy), (int)(centreDepth+zz)) level.copyBlocksFrom(schematic, BoundingBox((0,0,0),(width,height,depth)), (box.minx, box.miny, box.minz )) print 'a=%s b=%s c=%s f=%s g=%s h=%s p=%s q=%s r=%s d=%s' % (a,b,c,f,g,h,p,q,r,d) print '%s: Ended at %s' % (method, time.ctime())
def Fractal(level, box, options): # CONSTANTS method = "FRACTAL" print '%s: Started at %s' % (method, time.ctime()) (width, height, depth) = getBoxSize(box) centreWidth = (int)(width / 2) centreHeight = (int)(height / 2) centreDepth = (int)(depth / 2) AIR = (0, 0) XComponent = options["X Component?"] YComponent = options["Y Component?"] ZComponent = options["Z Component?"] Solid = options["Solid?"] schematic = level.extractSchematic( BoundingBox((box.minx, box.miny, box.minz), (width, height, depth))) for y in xrange(0, height): print '%s: Examining the selection area - step %s of %s' % (method, y, height - 1) for x in xrange(0, width): for z in xrange(0, depth): # If the current block is not air, blit the schematic into the corresponding area in space tempBlock = (schematic.blockAt(x, y, z), schematic.blockDataAt(x, y, z)) tempBlockAbove = (schematic.blockAt(x, y + 1, z), schematic.blockDataAt(x, y + 1, z)) if tempBlock != AIR: XModifier = 0 YModifier = 0 ZModifier = 0 if XComponent == True: XModifier = x * width if YComponent == True: YModifier = y * height if ZComponent == True: ZModifier = z * depth if Solid == False or (Solid == True and tempBlockAbove == AIR): level.copyBlocksFrom( schematic, BoundingBox((0, 0, 0), (width, height, depth)), (box.minx + XModifier, box.miny + YModifier, box.minz + ZModifier)) elif Solid == True and tempBlockAbove != AIR: fill(level, tempBlockAbove, (box.minx + XModifier, box.miny + YModifier, box.minz + ZModifier), (width, height, depth)) print '%s: Ended at %s' % (method, time.ctime())
def cantorCity(level, box, options, RAND, iter): print iter, box width = box.maxx - box.minx depth = box.maxz - box.minz height = box.maxy - box.miny # Draw the current layer if height > 0: material = getBlockFromOptions(options, "Material:") floorHeight = options["Floor Height:"] if floorHeight < 1: floorHeight = RAND.randint(1, 16) if iter > floorHeight and RAND.random() > 0.1: floorHeight = iter - floorHeight for y in xrange(box.miny, box.miny + floorHeight): for z in xrange(box.minz, box.maxz): for x in xrange(box.minx, box.maxx): setBlock(level, material, x, y, z) # Draw draw draw! # Now spawn the NEXT layer up in each corner if True: if height > 1: RATIO = options["Ratio:"] if RATIO < 1.0: RATIO = 1.0 + random() # Random splits! widthThird = int(width / RATIO) depthThird = int(depth / RATIO) MINDIM = options["Min Dimension:"] if widthThird >= MINDIM and depthThird >= MINDIM: # We stop when either dimension trends to 0 CHANCE = options["Chance:"] y = y + 1 if y < box.maxy: # Conditionally create a new box and build the next layer NewBox1 = BoundingBox( (box.minx, y, box.minz), (widthThird, box.maxy - y, depthThird)) NewBox2 = BoundingBox( (box.maxx - widthThird, y, box.minz), (widthThird, box.maxy - y, depthThird)) NewBox3 = BoundingBox( (box.maxx - widthThird, y, box.maxz - depthThird), (widthThird, box.maxy - y, depthThird)) NewBox4 = BoundingBox( (box.minx, y, box.maxz - depthThird), (widthThird, box.maxy - y, depthThird)) if RAND.random() < CHANCE: cantorCity(level, NewBox1, options, RAND, iter + 1) if RAND.random() < CHANCE: cantorCity(level, NewBox2, options, RAND, iter + 1) if RAND.random() < CHANCE: cantorCity(level, NewBox3, options, RAND, iter + 1) if RAND.random() < CHANCE: cantorCity(level, NewBox4, options, RAND, iter + 1)
def tileWindow(level,WINDOW): b=range(4096) b.remove(0) # @CodeWarrior0 and @Wout12345 explained how to merge schematics #describe(WINDOW) y = 0 while y < level.Height: x = 0 while x < (level.Width)>>1: level.copyBlocksFrom(WINDOW, BoundingBox((0,0,0),(WINDOW.Width,WINDOW.Height,WINDOW.Length)),(x,y,0),b) level.copyBlocksFrom(WINDOW, BoundingBox((0,0,0),(WINDOW.Width,WINDOW.Height,WINDOW.Length)),(level.Width-WINDOW.Width-x,y,0),b) x += WINDOW.Width y += WINDOW.Height
def jiggle(olevel, obox, level, box, options): method = "Jiggle" (method, (width, height, depth), (centreWidth, centreHeight, centreDepth)) = FuncStart(level, box, options, method) # Log start # Displace each column in the level into the original level according to the operation DX = options["Delta X:"] DY = options["Delta Y:"] DZ = options["Delta Z:"] OP = options["Operation:"] DEL = options["Delete source?"] # fill the original selection box if DEL == True: olevel.fillBlocks(obox, alphaMaterials.Air) abox = BoundingBox((0, 0, 0), (1, height, 1)) for iterX in xrange(0, width): if iterX % 10 == 0: print iterX for iterZ in xrange(0, depth): # Extract a column of blocks from the copy of the original space cbox = BoundingBox((iterX, 0, iterZ), (1, height, 1)) clevel = level.extractSchematic(cbox) # Working set dx = DX dy = DY dz = DZ if OP == "Random": if dx > 0: dx = randint(0, dx) elif dx < 0: dx = randint(dx, 0) if dy > 0: dy = randint(0, dy) elif dy < 0: dy = randint(dy, 0) if dz > 0: dz = randint(0, dz) elif dz < 0: dz = randint(dz, 0) #print cbox #print obox olevel.copyBlocksFrom(clevel, abox, (obox.minx + iterX + dx, obox.miny + dy, obox.minz + iterZ + dz)) FuncEnd(level, box, options, method)
def perform(level, box, options): minY = findBottom(level, box) fillBox = BoundingBox((box.minx, box.miny, box.minz), (box.width, max(minY - box.miny, 1), box.length)) box = BoundingBox((box.minx, minY, box.minz), (box.width, options["Max Height"], box.length)) utilityFunctions.fillBox(level, box, (0, 0)) utilityFunctions.fillBoxEmpty(level, fillBox, (alphaMaterials.Grass.ID, 0)) (houses, roads) = idonknowPartition(box) test, house_matrix = getPlanMatrix(level, box, houses) for house in houses: chooseHouse(level, house, options) for road in roads: utilityFunctions.fillBox(level, road, (208, 0)) utilityFunctions.fillBox( level, CutBar(road, 0, 0, 0, 0, options["Max Height"], 1).middle, (0, 0)) ########################## # build road # house_matrix = getPlanMatrix(level, box, houses) global tm tm = detectMap(level, box, options, house_matrix) global width width = box.maxx - box.minx global height height = box.maxz - box.minz tm_to_test_map() find_path(box) print_test_map() #clearTerrain(level,box) for i in range(len(test_map)): for j in range(len(test_map[0])): if (test_map[i][j] == '*'): print i, j utilityFunctions.setBlock(level, (options["Road Material"].ID, 0), box.minx + j, box.miny, box.minz + i) if box.minx + j + 1 < box.maxx: utilityFunctions.setBlock(level, (options["Road Material"].ID, 0), box.minx + j + 1, box.miny, box.minz + i) if box.minz + i + 1 < box.maxz: utilityFunctions.setBlock(level, (options["Road Material"].ID, 0), box.minx + j, box.miny, box.minz + i + 1)
def perform(level, box, options): print "ALife generation: Start." width = box.maxx - box.minx height = box.maxy - box.miny depth = box.maxz - box.minz material = getBlockFromOptions(options, "Material:") b = range(4096) b.remove( 0) # @CodeWarrior0 and @Wout12345 explained how to merge schematics planes = [] prevTickPlane = MCSchematic((width, height, depth)) print options["Mode"] if options["Mode"] == "Randomise": # Randomise to initialise initialise(prevTickPlane, options["Initial chance:"], material) elif options["Mode"] == "Load image": # Use black pixels to seed the generation initialiseFromImageFile( prevTickPlane, options["File path"], material, (options["Red"], options["Green"], options["Blue"])) else: # Use what's in the lowest plane of the selection box (i.e. the SOUTH most layer). Not air equals an alive cell. prevTickPlane = level.extractSchematic( BoundingBox((box.minx, box.miny, box.minz), (width, height, 1))) numTicksToRun = options["Number of ticks"] if numTicksToRun > depth: numTicksToRun = depth level.copyBlocksFrom(prevTickPlane, BoundingBox((0, 0, 0), (width, height, 1)), (box.minx, box.miny, box.minz), b) #First layer for z in xrange(1, numTicksToRun): print "Ticking", z TickPlane = MCSchematic((width, height, depth)) calculateLifeTick(prevTickPlane, TickPlane, material) # planes.append(TickPlane) # History level.copyBlocksFrom(TickPlane, BoundingBox((0, 0, 0), (width, height, 1)), (box.minx, box.miny, box.minz + z), b) prevTickPlane = TickPlane if options[ "Mode"] == "File path": # Save the last plane so it can be the next input if required. img.save(options["File path"] + "_end.png") level.markDirtyBox(box) print "ALife generation: Done." print "Complete!"
def create(generatorName, level, boxGlobal, box, agents, allStructures, materialScans, agent): print "Building a", generatorName, "at", box, " by ", str(agent) areas = GEN_Cottage.create(generatorName, level, boxGlobal, box, agents, allStructures, materialScans, agent) # Create a chimney or two for i in xrange(0, randint(1, 2)): size = randint(0, 1) for area in areas: width = area.maxx - area.minx depth = area.maxz - area.minz cx = (area.maxx + area.minx) >> 1 cz = (area.maxz + area.minz) >> 1 px = cx pz = cz if size > 0 and width > 3 and depth > 3: px = randint(area.minx + size, area.maxx - 1 - size) pz = randint(area.minz + size, area.maxz - 1 - size) height = box.maxy - area.miny chimneyHeight = randint(2 * height, 3 * height) + 1 chimneybox = BoundingBox( (px - size, area.miny, pz - size), (size * 2 + 1, chimneyHeight, size * 2 + 1)) Settlevolver.fill(level, chimneybox, (45, 0)) # Bricks if size > 0: chimneybox = BoundingBox((px, area.miny, pz), (1, chimneyHeight, 1)) Settlevolver.fill(level, chimneybox, (0, 0)) # Bricks chimneybox = BoundingBox((px - size, area.miny, pz), (size * 2 + 1, 1, 1)) Settlevolver.fill(level, chimneybox, (0, 0)) # Air chimneybox = BoundingBox((px, area.miny, pz - size), (1, 1, size * 2 + 1)) Settlevolver.fill(level, chimneybox, (0, 0)) # Air else: level.setBlockAt(px, area.miny + chimneyHeight, pz, 145) # Anvil level.setBlockDataAt(px, area.miny + chimneyHeight, pz, randint(0, 11)) if level.blockAt(px, area.miny - 1, pz) != 0: level.setBlockAt(px, area.miny, pz, 61) # Furnace level.setBlockDataAt(px, area.miny, cz, randint(2, 5)) return areas
def analyse(level): ''' Examine the object in the schematic for min, max non-empty co-ordinates so we can pack-them-in! ''' # Find the bounding box for the object within this schematic. i.e. clip empty space method = "MINETEXT" print '%s: Started at %s' % (method, time.ctime()) box = level.bounds (width, height, depth) = getBoxSize(level.bounds) print 'ANALYSE %s %s %s' % (width, height, depth) minX = width minY = height minZ = depth maxX = 0 maxY = 0 maxZ = 0 found = False for iterY in xrange(0, height): for iterX in xrange(0, width): for iterZ in xrange(0, depth): if level.blockAt(iterX, iterY, iterZ) != 0: #print 'ANALYSING %s %s %s' % (iterX, iterY, iterZ) if iterX > maxX: maxX = iterX if iterY > maxY: maxY = iterY if iterZ > maxZ: maxZ = iterZ if iterX < minX: minX = iterX if iterY < minY: minY = iterY if iterZ < minZ: minZ = iterZ found = True print 'ANALYSE RESULT %s %s %s %s %s %s' % (minX, minY, minZ, maxX, maxY, maxZ) print '%s: Ended at %s' % (method, time.ctime()) if found == False: return BoundingBox((0, 0, 0), (width, height, depth)) else: return BoundingBox((minX, 0, minZ), (maxX + 1, maxY + 1, maxZ + 1))
def _getWorldBounds(self): if len(self.allChunks) == 0: return BoundingBox((0, 0, 0), (0, 0, 0)) allChunks = numpy.array(list(self.allChunks)) min_cx = (allChunks[:, 0]).min() max_cx = (allChunks[:, 0]).max() min_cz = (allChunks[:, 1]).min() max_cz = (allChunks[:, 1]).max() origin = (min_cx << 4, 0, min_cz << 4) size = ((max_cx - min_cx + 1) << 4, self.Height, (max_cz - min_cz + 1) << 4) return BoundingBox(origin, size)
def drawToolReticle(self): if self.level is None: return GL.glPolygonOffset(DepthOffset.CloneMarkers, DepthOffset.CloneMarkers) color = self.color if self.destPoint is not None: color = (self.color[0], self.color[1], self.color[2], 0.06) box = self.getDestBox() if self.draggingFace is not None: o = list(self.draggingOrigin()) s = list(box.size) for i in range(3): if i == self.draggingFace >> 1: continue o[i] -= 1000 s[i] += 2000 guideBox = BoundingBox(o, s) color = self.draggingColor GL.glColor(1.0, 1.0, 1.0, 0.33) with gl.glEnable(GL.GL_BLEND, GL.GL_TEXTURE_2D, GL.GL_DEPTH_TEST): self.editor.sixteenBlockTex.bind() drawFace(guideBox, self.draggingFace ^ 1) else: box = self.getReticleBox() if box is None: return self.drawRepeatedCube(box, color) GL.glPolygonOffset(DepthOffset.CloneReticle, DepthOffset.CloneReticle) if self.destPoint: box = self.getDestBox() if self.draggingFace is not None: face = self.draggingFace box = BoundingBox(self.draggingOrigin(), box.size) face, point = self.boxFaceUnderCursor(box) if face is not None: GL.glEnable(GL.GL_BLEND) GL.glDisable(GL.GL_DEPTH_TEST) GL.glColor(*self.color) drawFace(box, face) GL.glDisable(GL.GL_BLEND) GL.glEnable(GL.GL_DEPTH_TEST)
def getChunk(self, cx, cz): if (cx, cz) in self.chunkCache: return self.chunkCache[cx, cz] class FakeBrushChunk(pymclevel.level.FakeChunk): Entities = [] TileEntities = [] f = FakeBrushChunk() f.world = self f.chunkPosition = (cx, cz) mask = createBrushMask( brushSize, brushStyle, (0, 0, 0), BoundingBox((cx << 4, 0, cz << 4), (16, self.Height, 16))) f.Blocks = numpy.zeros(mask.shape, dtype='uint8') f.Data = numpy.zeros(mask.shape, dtype='uint8') f.BlockLight = self.zerolight f.SkyLight = self.zerolight if blockInfo.ID: f.Blocks[mask] = blockInfo.ID f.Data[mask] = blockInfo.blockData else: f.Blocks[mask] = 255 self.chunkCache[cx, cz] = f return f
def perform(originalLevel, originalBox, options): ''' Feedback to [email protected] ''' # Local variables method = options["Operation"] (method, (width, height, depth), (centreWidth, centreHeight, centreDepth)) = FuncStart(originalLevel, originalBox, options, method) # Log start SUCCESS = False level = originalLevel.extractSchematic(originalBox) # Working set box = BoundingBox((0, 0, 0), (width, height, depth)) # Operations go here - switch to the function based on selected operation SUCCESS = Bridge(level, box, options) # Conditionally copy back the working area into the world if SUCCESS == True: # Copy from work area back into the world b = range(4096) b.remove( 0 ) # @CodeWarrior0 and @Wout12345 explained how to merge schematics originalLevel.copyBlocksFrom( level, box, (originalBox.minx, originalBox.miny, originalBox.minz), b) originalLevel.markDirtyBox(originalBox) FuncEnd(originalLevel, box, options, method) # Log end
def perform(self, recordUndo=True): if recordUndo: self.undoLevel = self.extractUndo(self.level, self.box) self.filter.perform(self.level, BoundingBox(self.box), self.options) pass
def buildSimpleFarmHouse(level, box, options): #fencesBox = CutBar(box,1,1,1,1,boxSize[1]).middle #baseBox = CutBar(fencesBox, 2,2,2,2, boxSize[1]).middle #build fences and base #fenceLeft, fenceRight,fenceFront, fenceBack = buildFence(level, fencesBox, options,1) centerX = (box.minx+box.maxx)//2 centerZ = (box.minz + box.minz)//2 for y in range(0, 250): if level.blockAt(centerX, y, centerZ) != 0 and level.blockAt(centerX, y+1, centerZ)==0: minY = y break box = BoundingBox((box.minx, minY+1, box.minz),(box.width, box.height, box.length)) utilityFunctions.fillBox(level, CutBar(box,0,0,0,0,options["Max Height"],2).middle,(0,0)) wallPartBox = buildBase(level,box,(options["Base"].ID, 0), 1) floorBoxes = buildWall(level, wallPartBox,(options["Base"].ID, 0), random.randint(5,25)) for i in range(size(floorBoxes)-1): fillFrame(level, floorBoxes[i], (45,0), floorBoxes[i].height) #build the wall of the house if size(floorBoxes)>=2: buildRoof(level,AddBar(floorBoxes[-1],2,2,3,3).full, (options["Roof"].ID, 0),1, 10) else: buildRoof(level,AddBar(floorBoxes[-1],2,2,3,3).full, (options["Roof"].ID, 0),1, 1)
def tryToPlaceStructure(level, box, allStructures, potentialStructureSize, potentialStructureLocation, resource, recurse): (resourceBlockID, resourceBlockData), (resourceX, resourceY, resourceZ) = resource szx, szy, szz = potentialStructureSize pslx, psly, pslz = potentialStructureLocation if not (pslx < box.minx or pslx + szx >= box.maxx or pslz < box.minz or pslz + szz >= box.maxz): # Ok to try to position this structure. Check for height here y = psly # Some past solutions I've seen to this problem don't work with the existing terrain and, instead, create a bit of urban sprawl. if not (y < box.miny or y + szy >= box.maxy): # It can fit in the allocated space! Check for collisions newBox = BoundingBox((pslx, y, pslz), (szx, szy, szz)) collidesWith = checkForCollisions(newBox, allStructures) if len(collidesWith) == 0: return newBox # All good - pop this thing here else: # Else... Merge? Stack? Ignore? # Try stacking topY = newBox.maxy topBox = newBox for t, b in collidesWith: if b.maxy > topY: topBox = b if topBox != newBox and recurse == True: # Found a new box. Try to place this one on top of it. tryToPlaceStructure(level, box, allStructures, potentialStructureSize, (pslx, topY, pslz), resource, recurse) else: return None # We cannot place this box, sadly.
def perform(self, recordUndo=True): sourceBox = self.sourceBox if recordUndo: self.undoLevel = self.extractUndo( self.level, BoundingBox(self.destPoint, self.sourceBox.size)) blocksToCopy = None if not (self.copyAir and self.copyWater): blocksToCopy = range(pymclevel.materials.id_limit) if not self.copyAir: blocksToCopy.remove(0) if not self.copyWater: blocksToCopy.remove(8) if not self.copyWater: blocksToCopy.remove(9) with setWindowCaption("Copying - "): i = self.level.copyBlocksFromIter( self.sourceLevel, self.sourceBox, self.destPoint, blocksToCopy, create=True, biomes=self.copyBiomes, staticCommands=self.staticCommands, first=False) showProgress( _("Copying {0:n} blocks...").format(self.sourceBox.volume), i)
def perform(originalLevel, originalBox, options): ''' Feedback to [email protected] ''' # Local variables method = "perform" (method, (width, height, depth), (centreWidth, centreHeight, centreDepth)) = FuncStart(originalLevel, originalBox, options, method) # Log start SUCCESS = True level = originalLevel.extractSchematic(originalBox) # Working set box = BoundingBox((0, 0, 0), (width, height, depth)) stairSmooth(level, box, options) if SUCCESS == True: # Copy from work area back into the world b = range(4096) b.remove( 0 ) # @CodeWarrior0 and @Wout12345 explained how to merge schematics originalLevel.copyBlocksFrom( level, box, (originalBox.minx, originalBox.miny, originalBox.minz), b) originalLevel.markDirtyBox(originalBox) FuncEnd(originalLevel, box, options, method) # Log end
def selectionBoxForCorners(self, p1, p2): ''' considers p1,p2 as the marked corners of a selection. returns a BoundingBox containing all the blocks within.''' if self.editor.level is None: return None p1, p2 = list(p1), list(p2) # d = [(a-b) for a,b in zip(p1,p2)] for i in range(3): if p1[i] > p2[i]: t = p2[i] p2[i] = p1[i] p1[i] = t p2[i] += 1 size = list(map(lambda a, b: a - b, p2, p1)) if p1[1] < 0: size[1] += p1[1] p1[1] = 0 h = self.editor.level.Height if p1[1] >= h: p1[1] = h - 1 size[1] = 1 if p1[1] + size[1] >= h: size[1] = h - p1[1] return BoundingBox(p1, size)
def makePyramid(level, box, options, floors): [cx,cy,cz]=[(box.minx+box.maxx)/2, (box.miny+box.maxy)/2, (box.minz+box.maxz)/2] boxSize = utilityFunctions.getBoxSize(box) minWidth = min(boxSize[0], boxSize[2]) step = 2 count=0 for floor in range(floors-1): subBox = BoundingBox((box.minx+floor,floor+box.miny,box.minz+floor),(boxSize[0]-step*floor, 1, boxSize[2]-step*floor)) if subBox.width>1 and subBox.length>1: utilityFunctions.setSquareFrame(level,(options["Wall"].ID,0), subBox.minx, subBox.miny, subBox.minz, subBox.length,subBox.width) count += 1 else: break subBox = BoundingBox((box.minx+count,count+box.miny,box.minz+count),(boxSize[0]-step*count, 1, boxSize[2]-step*count)) print subBox makeFloor(level, subBox, options)
def perform(self, recordUndo=True): if self.level.saving: alert(_("Cannot perform action while saving is taking place")) return if recordUndo: self.canUndo = True self.undoLevel = self.extractUndo( self.level, BoundingBox(self.destPoint, self.sourceBox.size)) blocksToCopy = None if not (self.copyAir and self.copyWater): blocksToCopy = range(pymclevel.materials.id_limit) if not self.copyAir: blocksToCopy.remove(0) if not self.copyWater: blocksToCopy.remove(8) if not self.copyWater: blocksToCopy.remove(9) with setWindowCaption("Copying - "): i = self.level.copyBlocksFromIter( self.sourceLevel, self.sourceBox, self.destPoint, blocksToCopy, create=True, biomes=self.copyBiomes, staticCommands=self.staticCommands, moveSpawnerPos=self.moveSpawnerPos, regenerateUUID=self.regenerateUUID, first=False) showProgress( _("Copying {0:n} blocks...").format(self.sourceBox.volume), i)
def processCoords(coords): newcoords = collections.deque() for (x, y, z) in coords: for _dir, offsets in pymclevel.faceDirections: dx, dy, dz = offsets p = (x + dx, y + dy, z + dz) nx, ny, nz = p b = op.level.blockAt(nx, ny, nz) if indiscriminate: if b == 2: b = 3 if b == doomedBlock: if checkData: if op.level.blockDataAt(nx, ny, nz) != doomedBlockData: continue saveUndoChunk(nx // 16, nz // 16) op.level.setBlockAt(nx, ny, nz, op.options['Block'].ID) op.level.setBlockDataAt(nx, ny, nz, op.options['Block'].blockData) if tileEntity: if op.level.tileEntityAt(nx, ny, nz): op.level.removeTileEntitiesInBox(BoundingBox((nx, ny, nz), (1, 1, 1))) tileEntityObject = TileEntity.Create(tileEntity, (nx, ny, nz)) createTileEntities(tileEntityObject, op.level) newcoords.append(p) return newcoords