Exemplo n.º 1
0
def placeLighting(level):
    # Place lights around the exterior of the dwelling. Find external corners and attach to them
    y = 3
    AIR = (0, 0)
    TORCH_EAST = (50, 1)
    TORCH_WEST = (50, 2)
    TORCH_SOUTH = (50, 3)
    TORCH_NORTH = (50, 4)
    TORCH_UP = (50, 5)

    torchLocations = []
    for z in xrange(0, level.Length):
        for x in xrange(0, level.Width):
            blockHere = getBlock(level, x, y, z)
            if blockHere != AIR:
                blockEast = getBlock(level, x + 1, y, z)
                blockWest = getBlock(level, x - 1, y, z)
                blockSouth = getBlock(level, x, y, z + 1)
                blockNorth = getBlock(level, x, y, z - 1)
                if blockEast != AIR and blockSouth != AIR and blockWest == AIR and blockNorth == AIR:
                    torchLocations.append((x - 1, y, z, TORCH_WEST))
                    torchLocations.append((x, y, z - 1, TORCH_NORTH))
                elif blockEast == AIR and blockSouth != AIR and blockWest != AIR and blockNorth == AIR:
                    torchLocations.append((x + 1, y, z, TORCH_EAST))
                    torchLocations.append((x, y, z - 1, TORCH_NORTH))
                elif blockEast == AIR and blockSouth == AIR and blockWest != AIR and blockNorth != AIR:
                    torchLocations.append((x + 1, y, z, TORCH_EAST))
                    torchLocations.append((x, y, z + 1, TORCH_SOUTH))
                elif blockEast != AIR and blockSouth == AIR and blockWest == AIR and blockNorth != AIR:
                    torchLocations.append((x - 1, y, z, TORCH_WEST))
                    torchLocations.append((x, y, z + 1, TORCH_SOUTH))

    for (x, y, z, block) in torchLocations:
        setBlock(level, x, y, z, block)
Exemplo n.º 2
0
def placeWindows(level):
    # This is at the HOUSE level because the windows are on exterior walls only
    # Punch through the level placing glass if the current block is an exterior wall facing the right way
    AIR = (0, 0)
    GLASS = (20, 0)
    y = 2  # Window height
    DOUBLEHEIGHTWINDOWS = False
    if randint(1, 10) == 10:
        DOUBLEHEIGHTWINDOWS = True

    # tunnel width-wise
    z = randint(3, 4)

    while z < level.Length:
        for x in xrange(1, level.Width - 1):
            if getBlock(level, x, y, z) != AIR:
                if getBlock(level, x - 1, y, z) == AIR:
                    if getBlock(level, x + 1, y,
                                z) == AIR:  # Behind and in front are air
                        floorInFront = getBlock(level, x - 1, 0, z)
                        floorBehind = getBlock(level, x + 1, 0, z)
                        if (floorInFront == AIR and floorBehind != AIR) or (
                                floorInFront != AIR and floorBehind == AIR):
                            setBlock(level, x, y, z, GLASS)
                            if DOUBLEHEIGHTWINDOWS:
                                setBlock(level, x, y + 1, z, GLASS)

        z += 2

    # Tunnel depth-wise

    # tunnel width-wise
    x = randint(3, 4)

    while x < level.Width:
        for z in xrange(1, level.Length - 1):
            if getBlock(level, x, y, z) != AIR:
                if getBlock(level, x, y, z - 1) == AIR:
                    if getBlock(level, x, y,
                                z + 1) == AIR:  # Behind and in front are air
                        floorInFront = getBlock(level, x, 0, z - 1)
                        floorBehind = getBlock(level, x, 0, z + 1)
                        if (floorInFront == AIR and floorBehind != AIR) or (
                                floorInFront != AIR and floorBehind == AIR):
                            setBlock(level, x, y, z, GLASS)
                            if DOUBLEHEIGHTWINDOWS:
                                setBlock(level, x, y + 1, z, GLASS)

        x += 2
Exemplo n.º 3
0
def create(generatorName, level, areas):
    # This module creates a settlement in the selection based on the availableAreas.
    SMALL = 8
    MEDIUM = 16
    LARGE = 32

    settlementA = [
        "House", "FarmLand", "House", "TownSquare", "Tower"
    ]  #["TownSquare","TownHall","Farm","House"] # Add any generator types here
    for i in xrange(0, randint(30, 100)):
        randval = randint(1, 10)
        if randval == 1:
            settlementA.append("Tower")
        if randval == 2:
            settlementA.append("House")
        else:
            settlementA.append("FarmLand")
    settlements = [
        settlementA
    ]  # In reality you'll mix this up with different blueprints, probably based on biome type

    # Optional: Check bounds and whether we can do anything

    chosenVariant = settlements[randint(0,
                                        len(settlements) -
                                        1)]  # Pick one at random

    BADFOUNDATIONBLOCKS = [8, 9, 10, 11]
    plotAreas = []
    for (box, flag) in areas:
        (heightMap, minHeight, maxHeight, layerMap, blocks,
         blockIDs) = profileCell(level, (box.minx, box.miny, box.minz),
                                 (box.maxx, box.maxy, box.maxz))
        edgeMap = mapEdges(heightMap, 1)
        cells = identifyContiguousAreas(edgeMap)
        print cells
        # The cells list is (posx,posy,size). So we are going to build a new set of boxes and use them to generate the settlement
        for (x, y, size) in cells:
            if False:  # Debug
                col = randint(0, 15)
                for ix in xrange(box.minx + x, box.minx + x + size):
                    for iz in xrange(box.minz + y, box.minz + y + size):
                        setBlock(level, ix, box.maxy - 3, iz, (35, col))
                        # print ix,box.maxy-3,iz
            if size >= SMALL:  # Minimum size to generate against
                # Check if this area has water or lava in it, in which case we can't build here
                okToBuild = True
                badFoundationCount = 0
                width, depth, dim = layerMap.shape
                px = x + 1
                py = y + 1
                while py < y + 1 + size:
                    if px < width - 1 and py < depth - 1:
                        if layerMap[px][py][0] in BADFOUNDATIONBLOCKS:
                            badFoundationCount += 1
                            print "Badfoundations :", badFoundationCount
                            if badFoundationCount > 9:  # is a problem for us
                                print "Badfoundations:", badFoundationCount
                                okToBuild = False  # Can't build on quicksand (or lava and water)
                                py = y + 1 + size  # exit loop
                    px += 1
                    if px >= x + 1 + size:
                        px = x + 1
                        py += 1
                if okToBuild == True:
                    # what is the height to use? Try for average...
                    avgHeight = 0
                    for ppx in xrange(x, x + size):
                        for ppy in xrange(y, y + size):
                            avgHeight += heightMap[ppx][ppy]
                    avgHeight = int(avgHeight / (size * size))
                    print avgHeight
                    plotArea = BoundingBox(
                        (box.minx + x, avgHeight, box.minz + y),
                        (size, box.maxy - (avgHeight),
                         size))  # Save this plot, discard all others
                    plotAreas.append((plotArea, True))
                    print "Viable area", plotArea
                else:
                    print "Bad foundations at", x, y, size

    resultAreas = []
    keepGoing = True
    blueprintCounter = 0
    while keepGoing == True and len(plotAreas) > 0 and blueprintCounter < len(
            chosenVariant):  # Bounds checking
        shuffle(plotAreas)
        (box, availableFlag) = plotAreas.pop()  # Get an area
        if availableFlag == True:
            # Chop up the box to allocate space to the child. We'll use a 2D centre segmentation method
            width, height, depth = getDimensionsFromBox(box)

            size = -1
            if width >= LARGE and height >= LARGE and depth >= LARGE:
                size = LARGE
            elif width >= MEDIUM and height >= MEDIUM and depth >= MEDIUM:
                size = MEDIUM
            elif width >= SMALL and height > SMALL and depth > SMALL:
                size = SMALL
            if size != -1:  # -1 is invalid - selection too small
                # Carve up the area, allocate the central portion to the delegate generator, and return the free ones to the area stack for re-use
                chopXPos1 = ((box.maxx + box.minx) >> 1) - (size >> 1)
                chopXPos2 = ((box.maxx + box.minx) >> 1) + (size >> 1)
                chopZPos1 = ((box.maxz + box.minz) >> 1) - (size >> 1)
                chopZPos2 = ((box.maxz + box.minz) >> 1) + (size >> 1)

                # These are the free areas
                areas.append((BoundingBox(
                    (box.minx, box.miny, box.minz),
                    (chopXPos1 - box.minx, height, chopZPos2 - box.minz)),
                              True))
                areas.append((BoundingBox(
                    (box.minx, box.miny, chopZPos2),
                    (chopXPos2 - box.minx, height, box.maxz - 1 - chopZPos2)),
                              True))
                areas.append((BoundingBox((chopXPos2, box.miny, chopZPos1),
                                          (box.maxx - 1 - chopXPos2, height,
                                           box.maxz - 1 - chopZPos1)), True))
                areas.append((BoundingBox(
                    (chopXPos1, box.miny, box.minz),
                    (box.maxx - 1 - chopXPos1, height, chopZPos1 - box.minz)),
                              True))

                # This is the new building location
                newBox = BoundingBox((0, 0, 0), (size, size, size))

                # Create a new level to generate the building within and, once built, copy it back over onto the level
                # scratchpadHouse = makeBlankAreaOfSizeWHD(size,height,size)

                # Clear out all the nuisance blocks

                AIR = (0, 0)
                for y in xrange(box.miny, box.miny + size):
                    for z in xrange(chopZPos1, chopZPos1 + size):
                        for x in xrange(chopXPos1, chopXPos1 + size):
                            (theBlockID,
                             theBlockData) = getBlock(level, x, y, z)
                            if theBlockID in IGNOREBLOCKIDS:
                                setBlock(level, x, y, z, AIR)

                scratchpadLand = copyAreaOfSizeWHDFromSchematicAtPosXYZ(
                    level, size, height, size, chopXPos1, box.miny, chopZPos1)
                newGeneratedAreas = delegateGeneration(
                    chosenVariant[blueprintCounter], scratchpadLand,
                    [(newBox, True)])
                # scratchpadLand.copyBlocksFrom(scratchpadHouse,BoundingBox((0,0,0),(size,height,size)),(0,0,0))
                pasteAreaOfSizeWHDToSchematicAtPosXYZ(scratchpadLand, level,
                                                      scratchpadLand.Width,
                                                      scratchpadLand.Height,
                                                      scratchpadLand.Length,
                                                      chopXPos1, box.miny,
                                                      chopZPos1)
                # Put in some support pylons if there are parts of the house suspended...
                log("Placing building supports")
                for iz in xrange(chopZPos1, chopZPos1 + scratchpadLand.Length):
                    for ix in xrange(chopXPos1,
                                     chopXPos1 + scratchpadLand.Width):
                        iy = box.miny + scratchpadLand.Height - 1
                        drawPylon = False
                        while (iy >= 0
                               and drawPylon == True) or (drawPylon == False
                                                          and iy >= box.miny):
                            (theBlockID,
                             theBlockData) = getBlock(level, ix, iy, iz)
                            if drawPylon == True and (
                                    theBlockID == 0
                                    or theBlockID in IGNOREBLOCKIDS or
                                    theBlockID in [8, 9, 10, 11]):  # + Liquids
                                setBlock(level, ix, iy, iz,
                                         (4, 0))  # Cobblestone
                            elif theBlockID == 4:
                                drawPylon = True
                            elif drawPylon == True:
                                drawPylon = False  # Turn it off
                                iy = 0  # Break out
                            iy -= 1

                blueprintCounter += 1  # Move onto the next building type
                resultAreas.append((box, True))
            else:
                log("Unable to find space for generation within area " +
                    str(box))
                # Discard this area, it's too small a fragment and cannot be effectively used at this time
                # This causes the areas list to tend to empty
                # TODO: consider putting micro-details into tiny areas

    # Segmentation of the village - low walls and lines of trees/shrubs
    # Voronoi cells
    log("Creating yards and walls")
    minx = 1000000000
    minz = 1000000000
    maxx = -1000000000
    maxz = -1000000000
    points = []

    for (box, flag) in resultAreas:
        box1centrex = (box.maxx + box.minx) >> 1
        box1centrez = (box.maxz + box.minz) >> 1
        points.append((box1centrex, box1centrez))
        if box1centrex < minx: minx = box1centrex
        if box1centrex > maxx: maxx = box1centrex
        if box1centrez < minz: minz = box1centrez
        if box1centrez > maxz: maxz = box1centrez
    log(str(points))
    v = zeros((maxx - minx, maxz - minz, 4))
    for z in xrange(minz, maxz):
        for x in xrange(minx, maxx):
            px = x - minx
            pz = z - minz
            if v[px][pz][3] == 0: v[px][pz][2] = 1000000000
            for X, Z in points:
                dx = x - X
                dz = z - Z
                dist = dx * dx + dz * dz
                if dist < v[px][pz][2]:
                    v[px][pz][0] = X  # Which point we're associated with
                    v[px][pz][1] = Z
                    v[px][pz][2] = dist  # Store a distance
                    v[px][pz][3] = 1  # Mark processed
    print v
    edgePoints = []
    # Find edgePoints - those points which are adjacent to a different zone by (X,Z)
    for z in xrange(0, maxz - minz - 1):
        for x in xrange(0, maxx - minx - 1):
            if v[x][z][3] == 1 and v[x][z + 1][3] == 1 and v[x + 1][z][3] == 1:
                if v[x][z][0] != v[x + 1][z][0] or v[x][z][1] != v[
                        x + 1][z][1] or v[x][z][0] != v[x][
                            z + 1][0] or v[x][z][1] != v[x][z + 1][
                                1]:  # If any of the rightmost/nextmost points are different, this is an edge
                    edgePoints.append((x + minx, z + minz))
    log("Making walls")
    log(str(len(edgePoints)))
    COBBLESTONE = 4
    MOSSCOBBLESTONE = 48
    COBBLESTONEWALL = 139
    TORCH_UP = (50, 5)
    for x, z in edgePoints:
        if randint(1, 10) > 5:
            y = level.Height
            while y >= 0:
                theBlockID, theBlockData = getBlock(level, x, y, z)
                if theBlockID == 2:  # Grass
                    if randint(1, 10) < 0:  # Shrubs and trees DISABLED
                        LEAVES = (18, randint(0, 11))
                        LOG = (17, randint(0, 3))
                        ht = randint(1, 6)
                        for y1 in xrange(y, y + ht):
                            setBlock(level, x, y1, z, LOG)
                            for dx in range(-1, 2):
                                setBlock(level, x + dx, y1, z, LEAVES)
                            for dz in range(-1, 2):
                                setBlock(level, x, y1, dz + dz, LEAVES)
                        for y1 in xrange(y + ht, y + ht + (ht >> 1)):
                            setBlock(level, x, y1, z, LEAVES)
                    else:
                        setBlock(level, x, y, z, (MOSSCOBBLESTONE, 0))
                        if randint(1, 10) > 2:
                            setBlock(level, x, y + 1, z, (COBBLESTONE, 0))
                            if randint(1, 10) > 5:
                                setBlock(level, x, y + 2, z,
                                         (COBBLESTONEWALL, randint(0, 1)))
                                if randint(1, 10) > 8:
                                    setBlock(level, x, y + 3, z, TORCH_UP)
                    y = 0  # Break. Job done
                y -= 1

    # Paths in the grass through resultAreas
    log("Making paths")
    heightW, heightD = heightMap.shape
    PATH = (208, 0)
    pathCount = 20
    while pathCount > 0 and len(resultAreas) > pathCount:
        (box, flag) = resultAreas[randint(0, len(resultAreas) - 1)]
        (box2, flag1) = resultAreas[randint(0, len(resultAreas) - 1)]
        if flag and flag1 and box != box2:
            pathCount -= 1
            log("Pathing... " + str(pathCount))
            box1centrex = (box.maxx + box.minx) >> 1
            box1centrez = (box.maxz + box.minz) >> 1
            box2centrex = (box2.maxx + box2.minx) >> 1
            box2centrez = (box2.maxz + box2.minz) >> 1
            # Calculate the line from box1 to box 2
            P = []
            P.append((box1centrex, 0, box1centrez))
            P.append(P[0])
            P.append(
                (((box1centrex + box2centrex) >> 1) + randint(-100, 100), 0,
                 ((box1centrez + box2centrez) >> 1) + randint(-100, 100)))
            P.append((box2centrex, 0, box2centrez))
            P.append(P[len(P) - 1])
            Q = calcLinesSmooth(4, P)
            for (x, y, z) in Q:
                x = x + randint(-2, 2)
                z = z + randint(-2, 2)
                if randint(1, 10) > 3:
                    y = level.Height
                    while y >= 0:
                        theBlockID, theBlockData = getBlock(level, x, y, z)
                        if theBlockID == 2:  # Grass
                            setBlock(level, x, y, z, PATH)
                            y = 0  # Break. Job done
                        y -= 1
    return resultAreas  # Tell the parent generator what we've done
def Farmland(level, box):
    crops = [
        (0, 0),
        (59, 0),
        (59, 1),
        (59, 2),
        (59, 3),
        (59, 4),
        (59, 5),
        (59, 6),
        (59, 7),
        (142, 0),
        (142, 1),
        (142, 2),
        (142, 3),
        (142, 4),
        (142, 5),
        (142, 6),
        (142, 7),
        (141, 0),
        (141, 1),
        (141, 2),
        (141, 3),
        (141, 4),
        (141, 5),
        (141, 6),
        (141, 7),
        # (207,0),(207,1),(207,2),(207,3), # <- This block is ICE on PE and so cannot be used
        (31, 1)
    ]

    CROPS = "RANDOM"
    CROPS_MAT = crops[randint(0, len(crops) - 1)]

    FARM_MAT = (60, 7)
    EDGE_MAT = (3, 0)
    WATER_MAT = (9, 0)
    WATERCOVER_MAT = (111, 0)
    FENCE_MAT = (85, 0)
    SURFACE_MAT = (2, 0)
    AIR = (0, 0)

    (midx, midz) = ((box.minx + box.maxx) >> 1, (box.minz + box.maxz) >> 1)

    # Find the surface blocks
    (surfid, surfdata) = SURFACE_MAT
    surfaceBlocks = []
    for z in xrange(box.minz, box.maxz):
        if z % 100 == 0: print "Processing Row: ", z
        for x in xrange(box.minx, box.maxx):
            for y1 in xrange(0, box.maxy - box.miny):
                y = box.maxy - y1 - 1
                (bid, bdata) = getBlock(level, x, y, z)
                if bid == surfid:
                    blockAbove = getBlock(level, x, y + 1, z)
                    if blockAbove == AIR:
                        surfaceBlocks.append((x, y, z))
                        break  # Found the top of this column, move on
                if bid == 31 and CROPS == "RANDOM":
                    setBlock(level, x, y, z, AIR)

    # Now, for each of the locations we found, flip to farmland and put the crop on top

    print "Found ", len(surfaceBlocks), " blocks. Springtime planting underway"

    for (x, y, z) in surfaceBlocks:
        if x == box.minx or x == box.maxx - 1 or z == box.minz or z == box.maxz - 1:
            if random() > 0.4:
                setBlock(level, x, y + 1, z, FENCE_MAT)
            if random() > 0.7:
                setBlock(level, x, y, z, EDGE_MAT)
        else:
            setBlock(level, x, y, z, FARM_MAT)

            if (x - midx) % 5 == 0 and (z - midz) % 5 == 0:  # Place water?
                bw = getBlock(level, x - 1, y, z)
                be = getBlock(level, x + 1, y, z)
                bn = getBlock(level, x, y, z - 1)
                bs = getBlock(level, x, y, z + 1)
                if bw != AIR and be != AIR and bn != AIR and bs != AIR:
                    setBlock(level, x, y, z, WATER_MAT)
                    if getBlock(level, x, y + 1, z) == AIR:
                        setBlock(level, x, y + 1, z, WATERCOVER_MAT)
            else:
                setBlock(level, x, y + 1, z, CROPS_MAT)

    print "Complete"
Exemplo n.º 5
0
def create(generatorName, level, areas):
    '''
		We are passed:
		- a string naming this method as 'generatorName',
		- a pymclevel "level" or MCSchematic object as 'level',
		- and a list of (BoundingBox,flag) tuples as 'areas'
	'''

    log("Generating a " + generatorName)  # Dump a message to the console

    # Some useful material definitions
    AIR = (0, 0)
    STONEBRICKS = (98, 1)
    COBBLESTONE = (4, 0)
    BRICKS = (45, 0)
    WOODPLANKS = (5, 0)
    FLOORHEIGHT = 5

    while len(
            areas
    ) > 0:  # Iterate through the possible build plot areas we were passed.
        (box, availableFlag) = areas.pop()  # Select the first area BoundingBox
        if availableFlag == True:  # Confirm we're allowed to use it
            log("Generating a " + generatorName + " at " +
                str(box))  # Informational to show we found a plot to build in
            width, height, depth = getDimensionsFromBox(
                box)  # Find out how much space we've been given
            if width >= 16 and depth >= 16:  # Minimum viable generation space
                cx = width >> 1  # Pre-calculate the centre via halving through a bit shift
                cz = depth >> 1  # Pre-calculate the centre via halving through a bit shift

                # A tower is a cylinder with a hat on it.
                towerHeight = height  # This is a normal tower with a flat roof
                if randint(1, 10) > 7:
                    towerHeight = int(
                        height / 3 *
                        2)  # Leave 33% room for the roof otherwise

                radius = cx - (cx >> 1)  # Push the tower wall into the box
                r2 = radius * radius  # Square of the radius. We'll use this a little later to work out if we are in or outside the tower wall
                for y in xrange(0, towerHeight):
                    for z in xrange(0, depth):
                        dz = z - cz  # distance to centre on z axis
                        ddz = dz * dz  # pre-calculate the distance squared
                        for x in xrange(0, width):
                            dx = x - cx  # distance to centre on x axis
                            ddx = dx * dx  # pre-calculate the distance squared
                            dist2 = ddx + ddz  # square of the distance. No need to square-root this
                            if dist2 <= r2:  # We're within the tower
                                material = AIR  # Default to overwriting the tower space with air
                                if dist2 > r2 - 16:  # This is the wall thickness
                                    material = STONEBRICKS  # Wall
                                else:  # Inside the wall within a room. Put a floor at this offset
                                    if y % FLOORHEIGHT == 1:
                                        material = WOODPLANKS
                                if y == 0 or (material != AIR and width > 16
                                              and randint(1, 10) == 1):
                                    material = COBBLESTONE  # Bottom layer cobblestone which is allows us to pack in empty space below

                                setBlock(
                                    level, box.minx + x, box.miny + y,
                                    box.minz + z, material
                                )  # Clear the block from this position regardless of what it is
                # Draw the roof, if this tower has one
                for y in xrange(towerHeight, height):
                    scalingRatio = 1.0 - float(y - towerHeight) / float(
                        height - towerHeight
                    )  # this works out how much to taper the radius
                    rad = (cx / 3 * 2) * scalingRatio
                    r2 = int(rad *
                             rad)  # The radius gets smaller the higher we go
                    for z in xrange(0, depth):
                        dz = z - cz  # distance to centre on z axis
                        ddz = dz * dz  # pre-calculate the distance squared
                        for x in xrange(0, width):
                            dx = x - cx  # distance to centre on x axis
                            ddx = dx * dx  # pre-calculate the distance squared
                            dist2 = ddx + ddz  # square of the distance. No need to square-root this
                            if dist2 <= r2:  # We're within the roof
                                material = BRICKS
                                setBlock(level, box.minx + x, box.miny + y,
                                         box.minz + z,
                                         material)  # Draw the roof

                # Window features and doorways
                towerRadius = radius >> 1
                for y in xrange(0, towerHeight):
                    # Randomly punch windows through
                    if y % FLOORHEIGHT == 3 or y == 2:  # y == 2 for ground floor access
                        for x in xrange(cx - towerRadius + 1,
                                        cx + towerRadius):
                            if x != cx:
                                if randint(1, 10) == 1:
                                    hitWall = False
                                    for z in xrange(0, depth):  # Drill through
                                        theBlock = getBlock(
                                            level, box.minx + x, box.miny + y,
                                            box.minz + z)
                                        if theBlock != AIR and hitWall == False:
                                            hitWall = False
                                            setBlock(level, box.minx + x,
                                                     box.miny + y,
                                                     box.minz + z, AIR)
                                            setBlock(level, box.minx + x,
                                                     box.miny + y + 1,
                                                     box.minz + z, AIR)
                                            z = depth

                        for z in xrange(cz - towerRadius + 1,
                                        cz + towerRadius):
                            if z != cz:
                                if randint(1, 10) == 1:
                                    hitWall = False
                                    for x in xrange(0, width):  # Drill through
                                        theBlock = getBlock(
                                            level, box.minx + x, box.miny + y,
                                            box.minz + z)
                                        if theBlock != AIR and hitWall == False:
                                            hitWall = False
                                            setBlock(level, box.minx + x,
                                                     box.miny + y,
                                                     box.minz + z, AIR)
                                            setBlock(level, box.minx + x,
                                                     box.miny + y + 1,
                                                     box.minz + z, AIR)
                                            x = width
Exemplo n.º 6
0
def placeDoors(level):
    # This is at the "HOUSE" level because the doors are common to rooms, and exterior walls
    # Punch through the level placing door if the current block is an exterior wall facing the right way
    AIR = (0, 0)
    DOOREAST = (64, 0)  # bitwise or with 0x8 for the top
    DOOREASTTOP = (64, 8)  # bitwise or with 0x8 for the top
    DOORWEST = (64, 2)  # bitwise or with 0x8 for the top
    DOORWESTTOP = (64, 10)  # bitwise or with 0x8 for the top

    DOORSOUTH = (64, 1)  # bitwise or with 0x8 for the top
    DOORSOUTHTOP = (64, 9)  # bitwise or with 0x8 for the top
    DOORNORTH = (64, 3)  # bitwise or with 0x8 for the top
    DOORNORTHTOP = (64, 11)  # bitwise or with 0x8 for the top

    doorsPlaced = 0
    iterations = 0  # Iteration cap
    while doorsPlaced == 0 and iterations <= 3:
        y = 1  # Door height
        # tunnel width-wise
        z = randint(4 - iterations, 5)

        while z < level.Length:
            for x in xrange(1, level.Width - 1):
                if getBlock(level, x, y, z) != AIR:
                    if getBlock(level, x - 1, y, z) == AIR:
                        if getBlock(level, x + 1, y,
                                    z) == AIR:  # Behind and in front are air
                            floorInFront = getBlock(level, x - 1, 0, z)
                            floorBehind = getBlock(level, x + 1, 0, z)
                            if floorBehind != AIR or floorInFront != AIR and getBlock(
                                    level, x - 2, y, z) != DOOREAST:
                                material = DOOREAST
                                materialtop = DOOREASTTOP
                                if randint(1, 2) == 1:
                                    material = DOORWEST
                                    materialtop = DOORWESTTOP
                                setBlock(level, x, y, z, material)
                                setBlock(level, x, y + 1, z, materialtop)
                                doorsPlaced += 1

            z += randint(4 - iterations, 5 - iterations)

        # Tunnel depth-wise

        # tunnel width-wise
        x = randint(4 - iterations, 5)

        while x < level.Width:
            for z in xrange(1, level.Length - 1):
                if getBlock(level, x, y, z) != AIR:
                    if getBlock(level, x, y, z - 1) == AIR:
                        if getBlock(level, x, y, z +
                                    1) == AIR:  # Behind and in front are air
                            floorInFront = getBlock(level, x, 0, z - 1)
                            floorBehind = getBlock(level, x, 0, z + 1)
                            if floorBehind != AIR or floorInFront != AIR and getBlock(
                                    level, x - 2, y, z) != DOORSOUTH:
                                material = DOORSOUTH
                                materialtop = DOORSOUTHTOP
                                if randint(1, 2) == 1:
                                    material = DOORNORTH
                                    materialtop = DOORNORTHTOP
                                setBlock(level, x, y, z, material)
                                setBlock(level, x, y + 1, z, materialtop)
                                doorsPlaced += 1

            x += randint(4 - iterations, 5 - iterations)
        iterations += 1
Exemplo n.º 7
0
    def furnish(self, level):
        # Based on the type of room, place things around.
        log("Furnishing...")
        AIR = (0, 0)
        DOORS = [64]
        (ox, oy, oz) = self.pos
        width, height, depth = self.size
        colortheme = randint(0, 15)
        if self.type == "Bedroom":
            # Place a bed

            # Bed. Location shouldn't be adjacent to a door. Find a spot with the head to a wall. Fair share of orientations
            BEDFOOTNORTH = (26, 0)
            BEDFOOTEAST = (26, 1)
            BEDFOOTSOUTH = (26, 2)
            BEDFOOTWEST = (26, 3)
            BEDHEADNORTH = (26, 8)
            BEDHEADEAST = (26, 9)
            BEDHEADSOUTH = (26, 10)
            BEDHEADWEST = (26, 11)

            # Walk the floor looking for a safe place to put a bed
            y = oy + 1
            attempts = 100
            while attempts > 0:
                attempts -= 1
                x = randint(ox + 1, ox + width - 1)
                z = randint(oz + 1, oz + depth - 1)
                thisSpot = getBlock(level, x, y, z)
                if thisSpot == AIR:
                    wid, wdata = westSpot = getBlock(level, x - 1, y, z)
                    eid, edata = eastSpot = getBlock(level, x + 1, y, z)
                    sid, sdata = southSpot = getBlock(level, x, y, z + 1)
                    nid, ndata = northSpot = getBlock(level, x, y, z - 1)
                    if westSpot != AIR and eastSpot == AIR and wid not in DOORS and nid not in DOORS and sid not in DOORS:
                        eid, edata = eastSpot = getBlock(level, x + 2, y, z)
                        sid, sdata = southSpot = getBlock(
                            level, x + 1, y, z + 1)
                        nid, ndata = northSpot = getBlock(
                            level, x + 1, y, z - 1)
                        if eid not in DOORS and sid not in DOORS and nid not in DOORS:
                            setBlock(level, x, y, z, BEDHEADEAST)
                            setBlock(level, x + 1, y, z, BEDFOOTEAST)
                            attempts = 0

                    elif eastSpot != AIR and westSpot == AIR and eid not in DOORS and nid not in DOORS and sid not in DOORS:
                        wid, edata = westSpot = getBlock(level, x - 2, y, z)
                        sid, sdata = southSpot = getBlock(
                            level, x - 1, y, z + 1)
                        nid, ndata = northSpot = getBlock(
                            level, x - 1, y, z - 1)
                        if wid not in DOORS and sid not in DOORS and nid not in DOORS:
                            setBlock(level, x, y, z, BEDHEADWEST)
                            setBlock(level, x - 1, y, z, BEDFOOTWEST)
                            attempts = 0

                    elif northSpot != AIR and southSpot == AIR and eid not in DOORS and wid not in DOORS and nid not in DOORS:
                        wid, edata = westSpot = getBlock(
                            level, x - 1, y, z + 1)
                        eid, sdata = southSpot = getBlock(
                            level, x + 1, y, z + 1)
                        sid, ndata = northSpot = getBlock(level, x, y, z + 2)
                        if wid not in DOORS and sid not in DOORS and eid not in DOORS:
                            setBlock(level, x, y, z, BEDHEADSOUTH)
                            setBlock(level, x, y, z + 1, BEDFOOTSOUTH)
                            attempts = 0

                    elif northSpot == AIR and southSpot != AIR and eid not in DOORS and wid not in DOORS and sid not in DOORS:
                        wid, edata = westSpot = getBlock(
                            level, x - 1, y, z - 1)
                        eid, sdata = southSpot = getBlock(
                            level, x + 1, y, z - 1)
                        nid, ndata = northSpot = getBlock(level, x, y, z - 2)
                        if wid not in DOORS and eid not in DOORS and nid not in DOORS:
                            setBlock(level, x, y, z, BEDHEADNORTH)
                            setBlock(level, x, y, z - 1, BEDFOOTNORTH)
                            attempts = 0

        if self.type == "LivingRoom":
            STAIRCHAIR = 53  # 0,1,2,3
            log("Chairs")
            placements = []
            for i in xrange(0, randint(2, 8)):
                placements.append(STAIRCHAIR)
            y = oy + 1
            attempts = 100
            while attempts > 0 and len(placements) > 0:
                attempts -= 1
                x = randint(ox + 1, ox + width - 1)
                z = randint(oz + 1, oz + depth - 1)
                thisSpot = getBlock(level, x, y, z)
                if thisSpot == AIR:
                    wid, wdata = westSpot = getBlock(level, x - 1, y, z)
                    eid, edata = eastSpot = getBlock(level, x + 1, y, z)
                    sid, sdata = southSpot = getBlock(level, x, y, z + 1)
                    nid, ndata = northSpot = getBlock(level, x, y, z - 1)
                    if westSpot == AIR and eastSpot == AIR and southSpot == AIR and northSpot == AIR:
                        block = placements.pop()
                        setBlock(level, x, y, z, (block, randint(0, 3)))

        if self.type == "Kitchen":
            CRAFTINGTABLE = 58
            FURNACE = 61  # 2,3,4,5
            CAULDRON = 118  # 0,1,2,3
            log("Kitchen")
            placements = [CAULDRON, FURNACE, CRAFTINGTABLE]

            # Walk the floor looking for a safe place to put a crafting table
            y = oy + 1
            attempts = 100
            while attempts > 0 and len(placements) > 0:
                attempts -= 1
                x = randint(ox + 1, ox + width - 1)
                z = randint(oz + 1, oz + depth - 1)
                thisSpot = getBlock(level, x, y, z)
                if thisSpot == AIR:
                    wid, wdata = westSpot = getBlock(level, x - 1, y, z)
                    eid, edata = eastSpot = getBlock(level, x + 1, y, z)
                    sid, sdata = southSpot = getBlock(level, x, y, z + 1)
                    nid, ndata = northSpot = getBlock(level, x, y, z - 1)
                    if westSpot != AIR and eastSpot == AIR and wid not in DOORS and nid not in DOORS and sid not in DOORS:
                        block = placements.pop()
                        blockID = 0
                        if block == CAULDRON:
                            blockID = randint(0, 3)
                        elif block == FURNACE:
                            blockID = 4
                        setBlock(level, x, y, z, (block, blockID))

                    elif eastSpot != AIR and westSpot == AIR and eid not in DOORS and nid not in DOORS and sid not in DOORS:
                        block = placements.pop()
                        blockID = 0
                        if block == CAULDRON:
                            blockID = randint(0, 3)
                        elif block == FURNACE:
                            blockID = 5
                        setBlock(level, x, y, z, (block, blockID))

                    elif northSpot != AIR and southSpot == AIR and eid not in DOORS and wid not in DOORS and nid not in DOORS:
                        block = placements.pop()
                        blockID = 0
                        if block == CAULDRON:
                            blockID = randint(0, 3)
                        elif block == FURNACE:
                            blockID = 3
                        setBlock(level, x, y, z, (block, blockID))

                    elif northSpot == AIR and southSpot != AIR and eid not in DOORS and wid not in DOORS and sid not in DOORS:
                        block = placements.pop()
                        blockID = 0
                        if block == CAULDRON:
                            blockID = randint(0, 3)
                        elif block == FURNACE:
                            blockID = 2
                        setBlock(level, x, y, z, (block, blockID))

        # All rooms - table and torch
        log("Chest")
        CHEST = 54
        y = oy + 1
        attempts = 100
        while attempts > 0:
            attempts -= 1
            x = randint(ox + 1, ox + width - 1)
            z = randint(oz + 1, oz + depth - 1)
            thisSpot = getBlock(level, x, y, z)
            if thisSpot == AIR:
                wid, wdata = westSpot = getBlock(level, x - 1, y, z)
                eid, edata = eastSpot = getBlock(level, x + 1, y, z)
                sid, sdata = southSpot = getBlock(level, x, y, z + 1)
                nid, ndata = northSpot = getBlock(level, x, y, z - 1)
                if westSpot == AIR and eastSpot == AIR and southSpot == AIR and northSpot == AIR:
                    setBlock(level, x, y, z, (CHEST, randint(2, 5)))
                    attempts = 0
        log("Light")
        TORCH_UP = (50, 5)
        #TABLE = (85,0) # Fence
        y = oy + 1
        attempts = 100
        while attempts > 0:
            attempts -= 1
            x = randint(ox + 1, ox + width - 1)
            z = randint(oz + 1, oz + depth - 1)
            thisSpot = getBlock(level, x, y, z)
            if thisSpot == AIR:
                wid, wdata = westSpot = getBlock(level, x - 1, y, z)
                eid, edata = eastSpot = getBlock(level, x + 1, y, z)
                sid, sdata = southSpot = getBlock(level, x, y, z + 1)
                nid, ndata = northSpot = getBlock(level, x, y, z - 1)
                if westSpot == AIR and eastSpot == AIR and southSpot == AIR and northSpot == AIR:
                    setBlock(level, x, y, z, (35, colortheme))
                    setBlock(level, x, y + 1, z, TORCH_UP)
                    attempts = 0

        log("Carpet")
        # All rooms - Carpet
        CARPET = 171
        if randint(1, 10) < 10:  # Add carpet
            log("Adding carpet")
            offset = randint(1, 3)
            fill(level, (ox + offset, oy + 1, oz + offset),
                 (ox + width - offset, oy + 2, oz + depth - offset),
                 (CARPET, colortheme))