예제 #1
0
def test_drawing_function(func, min_x_step=3, max_x_step=11, min_z_step=0, max_z_step=1, z_jumps=1, higher=0,
                          thickness=1, filled=False, material=block.GLOWSTONE_BLOCK, render="rotate"):
    home()
    pos = my_tile_pos()
    pos = V3(pos.x, pos.y + higher, pos.z)

    all_points = []
    x_counter = 0
    for x in range(min_x_step, max_x_step):
        x_counter += (2 * x) + 3
        for i, z in enumerate(xfrange(min_z_step, max_z_step, z_jumps)):
            points = func(V3(pos.x + x_counter, pos.y, pos.z + (i * (max_x_step * 1.8))), x, z, filled=filled,
                          thickness=thickness)
            draw_point_list(points=points, material=material, options=Map(choice_type=render))
            all_points += points

    class Temp():
        def __init__(self, points):
            self.points = points

        def clear(self):
            for p in self.points:
                create_block(p, block.AIR.id)

    return Temp(all_points)
예제 #2
0
 def trace(self, x, y, scene):
     O = scene.camera.transform.position
     Q = scene.camera.LookAt
     color = V3.zero()
     Q.x = x
     Q.y = y
     #converter Q para coordenada de mundo?
     D = (Q - O).normalize()
     rayO = O
     rayD = D
     reflection = 1.
     bounce = 0
     while bounce < self.num_bounces:
         hit = self.trace_ray(rayO, rayD, scene)
         if hit is None:
             break
         obj, M, N, col_ray = hit
         # reflexao
         rayO = M + N * .0001
         rayD = (rayD - 2 * V3.dot(rayD, N) * N).normalize()
         bounce += 1
         color += reflection * col_ray
         if hasattr(obj, 'material'):
             reflection *= obj.material.reflection
     return color
예제 #3
0
def startCam(self):
    self.fov = 90
    self.near = 1
    self.far = 50
    self.transform.position = V3(0., 0, -1.)
    self.speed = V3.zero()
    self.LookAt = V3.zero()
예제 #4
0
def my_pos(trunc=True):
    try:
        pos = mc.player.getPos()
    except mcpi.connection.RequestError:
        pos = V3(0, 0, 0)
    if trunc:
        return V3(math.floor(pos.x), math.floor(pos.y), math.floor(pos.z))
    else:
        return V3(pos.x, pos.y, pos.z)
예제 #5
0
def my_tile_pos(clamp_to_ground=True):
    try:
        pos = mc.player.getTilePos()
        if clamp_to_ground:
            height = get_height(pos)
            pos.y = height
    except mcpi.connection.RequestError:
        print("CONNECTION ERROR #1 - Can't get Player Tile Pos")
        pos = V3(0, 0, 0)
    return V3(pos.x, pos.y, pos.z)
예제 #6
0
def prep(size=0, ground=True):
    if size > 0:
        corner1 = V3(mid_point.x - size, mid_point.y, mid_point.z - size)
        corner2 = V3(mid_point.x + size, mid_point.y, mid_point.z + size)
    else:
        corner1, corner2 = V3(-60, 0, 40), V3(120, 0, 200)

    debug("Bulldozing building zone...")
    if ground: create_block_filled_box(vg.up(corner1, -1), vg.up(corner2, -3), block.GRASS.id, data=None)
    create_block_filled_box(vg.up(corner1, 0), vg.up(corner2, 70), block.AIR.id, data=None)
    debug("...Finished bulldozing")
예제 #7
0
 def intersect(self,orig,dest):
     normal = V3(*self.faces[0][2])
     orig = orig.normalize()
     dest = orig.normalize()
     denom = V3.dot(normal,dest)
     if denom < 1e-6:
         return np.inf
     d = V3.dot(self.transform.position - orig, normal) / denom
     if d < 0:
         return np.inf
     return d
예제 #8
0
def test_shapes(line=True, buff=13, texture_base=89, texture_main="Glass", info=False):
    texture = Texture1D.Texture1D(Map(gradient=True, gradient_type="linear", onlyBlock=True, name_contains=texture_main,
                                      colors=Texture1D.COLOR_MAPS.Rainbow, axis="y"))

    def draw(func, position, radius=5, height=8, material=texture_base, info=False):
        points = func(V3(position.x, position.y, position.z), radius, .7, height=height)
        draw_point_list(points, material, options=Map(info=info))
        return points

    pos = my_tile_pos()

    higher = 8

    all_points = []
    if line is True:
        p1 = V3(pos.x + buff, pos.y, pos.z)
        p2 = V3(pos.x + (buff * 1.8), pos.y, pos.z)
        p3 = V3(pos.x + (buff * 3.3), pos.y, pos.z)
        p4 = V3(pos.x + (buff * 4.5), pos.y, pos.z)
        p5 = V3(pos.x + (buff * 5.7), pos.y, pos.z)
    else:
        p1 = V3(pos.x + buff, pos.y, pos.z)
        p2 = V3(pos.x, pos.y, pos.z)
        p3 = V3(pos.x, pos.y, pos.z - buff)
        p4 = V3(pos.x - buff, pos.y, pos.z)
        p5 = V3(pos.x, pos.y, pos.z + buff)

    all_points.extend(draw(vg.circle, p1, material=texture_base, info=info))
    all_points.extend(draw(vg.sphere, vg.up(p1, higher), radius=5, material=texture, info=info))

    all_points.extend(draw(vg.square, p2, material=texture_base, info=info))
    all_points.extend(draw(vg.box, vg.up(p2, higher), radius=4, material=texture, info=info))

    all_points.extend(draw(vg.circle, p3, material=texture_base, info=info))
    all_points.extend(draw(vg.cone, vg.up(p3, higher / 2), height=9, material=texture, info=info))

    all_points.extend(draw(vg.circle, p4, material=texture_base, info=info))
    all_points.extend(draw(vg.cylinder, vg.up(p4, higher / 2), material=texture, info=info))

    all_points.extend(draw(vg.square, p5, material=texture_base, info=info))
    all_points.extend(draw(vg.rectangular_pyramid, vg.up(p5, higher / 2), height=8, material=texture, info=info))

    class Temp:
        def __init__(self, points):
            self.points = points

        def clear(self):
            for p in self.points:
                create_block(p, block.AIR.id)

    return Temp(all_points)
def decorate_roof(obj, options=Map()):
    settings = options.options
    if not settings.roof:
        return obj

    material = Blocks.match(settings.roof_material)
    if material:
        obj.material = material

    if str.startswith(settings.roof, "pointy"):
        height = settings.roof_pointy_multiplier * options.radius
        pointy = V3(options.center.x,
                    options.center.y + options.height + height,
                    options.center.z)

        for i, vec in enumerate(options.corner_vectors):
            roof_line = vg.getLine(vec.x, vec.y + 1, vec.z, pointy.x,
                                   pointy.y + 1, pointy.z)
            obj.points_edges += roof_line

            if not settings.roof == "pointy_lines":
                next_roof_point = options.corner_vectors[(i + 1) % len(
                    options.corner_vectors)]

                # Triangle to pointy face
                triangle_face = [vec, pointy, next_roof_point]
                roof_face = vg.unique_points(
                    vg.getFace([V3(v.x, v.y + 1, v.z) for v in triangle_face]))
                obj.points = obj.points.union(roof_face)

    elif str.startswith(settings.roof, "triangular"):
        obj.decorations.append("roof_triangular")
    elif str.startswith(settings.roof, "battlement"):
        height = settings.roof_battlement_height or 1
        spacing = settings.roof_battlement_space or 2

        for i, vec in enumerate(options.corner_vectors):
            next_roof_point = options.corner_vectors[(i + 1) % len(
                options.corner_vectors)]
            # TODO: Add X,Z outward from center as option
            roof_line = vg.getLine(vec.x, vec.y + height, vec.z,
                                   next_roof_point.x,
                                   next_roof_point.y + height,
                                   next_roof_point.z)

            obj.points = obj.points.union(
                vg.points_spaced(roof_line, Map(every=spacing)))

    elif str.startswith(settings.roof, "shape"):
        obj.decorations.append("roof_floating_shape")
    return obj
예제 #10
0
    def trace_ray(self, rayO, rayD, scene):
        # traca o raio
        dist_min = np.inf
        N = [0, 0, 0]
        for obj in scene.objects:
            #for face in obj.faces:
            #vs = []
            #for f in face[0]:
            #e = obj.edges[f]
            #v = obj.vertices[e[0]]
            #vs += [v]
            #dist_obj,n = TriIntersect(vs,rayO, rayD)
            dist_obj = obj.intersect(rayO, rayD)
            if dist_obj < dist_min:
                dist_min = dist_obj
                i_min = scene.objects.index(obj)
#N = n
# Raio nao interceptou nada, sai
        if dist_min == np.inf:
            return
        # Senao, ele bateu em algo (vamos pegar o mais proximo)
        obj = scene.objects[i_min]
        # andamos dist_min na direcao destino saindo da origem
        # p achar o ponto de intersecao
        M = rayO + rayD * dist_min

        N = obj.normal(M)
        toL = (scene.lights[0].transform.position - M).normalize()
        toO = (scene.camera.transform.position - M).normalize()
        # Sombras
        l = [
            obj_sh.intersect(M + N * .0001, toL)
            for k, obj_sh in enumerate(scene.objects) if k != i_min
        ]
        if l and min(l) < np.inf:
            return
        #Cores
        obj_color = V4.one()
        col_ray = scene.lights[0].ambient
        #print(col_ray.pure())
        # Lambert shading (diffuse)
        #print(V3.dot(N, toL))
        col_ray += obj.material.diffuse * max(V3.dot(N, toL), 0) * obj_color

        #print(col_ray.pure())
        # Blinn-Phong shading (specular)
        col_ray += obj.material.specular * max(
            V3.dot(N, (toL + toO).normalize()),
            0)**scene.lights[0].Kspecular * scene.lights[0].color
        #print(col_ray.pure())
        return obj, M, N, col_ray
예제 #11
0
 def __init__(self,parent,transform):
     super().__init__(parent,transform)
     size = 5
     self.vertices = [
         V3(0,0,0)*size,
         V3(1,0,0)*size,
         V3(0,1,0)*size,
         V3(0,0,1)*size
     ]
     self.edges = [
         [0,1],
         [0,2],
         [0,3]
     ]
예제 #12
0
 def __init__(self,position=None,rotation=None,scale=None):
     self.localx = (1,0,0)
     self.localy = (0,1,0)
     self.localz = (0,0,1)
     if position is None:
         self.position = V3.zero()
     else:
         self.position = position
     if rotation is None:
         self.rotation = V3.zero()
     else:
         self.rotation = rotation
     if scale is None:
         self.scale = V3.one()
     else:
         self.scale = scale
예제 #13
0
def pos_in_front(dist=1):
    pos = my_pos()
    d = my_dir()
    x = round(pos.x + (d.x * dist))
    y = round(pos.y + (d.y * dist))
    z = round(pos.z + (d.z * dist))
    return V3(x, y, z)
예제 #14
0
def scan(show_location=False):
    direction = my_rot()
    target = vg.up(my_pos())

    # print("Facing:", direction)
    if direction == 'w':
        x_range = [1]
        z_range = [-2, -1, 0, 1, 2]
    elif direction == 'e':
        x_range = [-1]
        z_range = [2, 1, 0, -1, -2]
    elif direction == 's':
        x_range = [-3, -2, -1, 0, 1]
        z_range = [0]
    else:
        # n
        x_range = [-2, -1, 0, 1, 2]
        z_range = [-2]

    blocks = []
    for y in [2, 1, 0, -1, -2]:
        text = ""
        for x in x_range:
            for z in z_range:
                new_point = target + V3(x, y, z)
                b = mc.getBlockWithData(new_point.x, new_point.y, new_point.z)

                name = Blocks.name_by_id(b.id, b.data)
                loc = str(new_point.x) + "," + str(new_point.y) + "," + str(
                    new_point.z) + " : " if show_location else ""
                line = "(" + loc + str(b.id) + "," + str(b.data) + ": " + name + ")  "

                text += line.ljust(28)
                blocks.append(b)
        print(text)
예제 #15
0
def clear(size=0):
    if size > 0:
        corner1 = V3(mid_point.x - size, mid_point.y, mid_point.z - size)
        corner2 = V3(mid_point.x + size, mid_point.y, mid_point.z + size)
    else:
        corner1, corner2 = V3(-60, 0, 40), V3(120, 0, 200)

    debug("Removing Everything...(fly in 10 seconds)")
    create_block_filled_box(vg.up(corner1, -5), vg.up(corner2, 50), block.AIR.id, data=None)

    debug("...Adding Grass...")
    create_block_filled_box(vg.up(corner1, -1), vg.up(corner2, -1), block.GRASS.id, data=None)

    debug("...Stone underneath...")
    create_block_filled_box(vg.up(corner1, -2), vg.up(corner2, -5), block.STONE.id, data=None)
    debug("...Finished")
예제 #16
0
    def __init__(self, pos=False, options=Map()):
        if not helpers.mc:
            helpers.mc = helpers.connect()

        self.seed = options.seed or vg.get_seed()
        vg.init_with_seed(self.seed)
        self.sides = options.sides or 4
        self.polys = []

        if options.p1 and options.p2:
            p1, p2 = vg.min_max_points(options.p1, options.p2)
            options.width = abs(p2.x - p1.x) - 2
            options.depth = abs(p2.z - p1.z) - 2
            options.radius = math.floor(min(options.width, options.depth) / 2)
            pos = V3(round((p1.x + p2.x) / 2), p1.y, round((p1.z + p2.z) / 2))
            if options.sides == 4:
                options.p1 = p1
                options.p2 = p2
        else:
            # If position isn't set, use the player position
            if pos is False:
                pos = helpers.my_tile_pos()

        # If "force_height" not passed in as an option, then pick height of the terrain at the x,z point
        # if not options.force_height:
        #     setattr(pos, "y", helpers.get_height(pos))

        self.options = options
        self.radius = options.radius or vg.rand_in_range(4, 10)
        self.options = choose_random_options(self.options)
        self.center = V3(pos.x, pos.y, pos.z)

        self.biome = "Plains"  # TODO: self.biome.title(options.biome or helpers.biome_at(pos))

        rand_max = min(max(math.ceil(self.radius * 2.5), 6), 40)  # keep buildings between 4-40 height
        self.height = options.height or vg.rand_in_range(4, rand_max)
        self.corner_vectors = []

        self.material = options.material or block.STONE.id
        self.material_edges = options.material_edges or block.IRON_BLOCK.id  # TODO: Change based on biome, have rand list

        self.name = options.name or self.biome + " house"

        # Create the walls and major polygons
        self.create_polys(options)
    def __init__(self, p1, p2, options=Map()):
        self.crop = options.crop or np.random.choice(
            ["cane", "wheat", "carrot", "potato", "cactus"])
        self.blocks = []

        rim, inner_rec = vg.rectangle(p1, p2)
        for block in rim + inner_rec:
            if not block in self.blocks and type(block) == V3:
                self.blocks.append(block)

        self.center = V3(round(abs(p2.x + p1.x) / 2), p1.y,
                         round(abs(p2.z + p1.z) / 2))
예제 #18
0
 def __init__(self,parent,transform):
     super().__init__(parent,transform)
     self.vertices = [
         V3(-0.5,-0.5,0),
         V3(0.5,-0.5,0),
         V3(-0.5,0.5,0),
         V3(0.5,0.5,0)
     ]
     self.edges = [
         [2,3],
         [3,1],
         [1,2],
         
         [2,1],
         [1,0],
         [0,2]
     ]
     self.faces = [
         [[0,1,2],[(0,1),(1,1),(1,0)],[0,0,1]],
         [[3,4,5],[(0,1),(1,0),(0,0)],[0,0,1]]
     ]
예제 #19
0
def test_polyhedron():
    # TODO: Revamp this
    import VoxelGraphics as vg

    pos = my_pos()
    points = vg.getFace([(pos.x, pos.y, pos.z), (pos.x + 20, pos.y + 20, pos.z), (pos.x + 20, pos.y + 20, pos.z + 20),
                         (pos.x, pos.y, pos.z + 20)])
    draw_point_list(points, block.GLASS.id)

    n = 20
    for t in range(0, n):
        (x1, z1) = (100 * math.cos(t * 2 * math.pi / n), 80 * math.sin(t * 2 * math.pi / n))
        for p in vg.traverse(V3(pos.x, pos.y - 1, pos.z), V3(pos.x + x1, pos.y - 1, pos.z + z1)):
            create_block(p, block.OBSIDIAN)

    n = 40
    vertices = []
    for t in range(0, n):
        (x1, z1) = (100 * math.cos(t * 2 * math.pi / n), 80 * math.sin(t * 2 * math.pi / n))
        vertices.append((pos.x + x1, pos.y, pos.z + z1))
    points = vg.getFace(vertices)
    draw_point_list(points, block.STAINED_GLASS_BLUE)
예제 #20
0
파일: GS.py 프로젝트: leokaplan/inf2608
def updateCam(self, dt):
    self.speed = V3.zero()
    spd = 1
    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                self.speed += V3(1, 0, 0) * -spd
            if event.key == pygame.K_RIGHT:
                self.speed += V3(1, 0, 0) * spd
            if event.key == pygame.K_DOWN:
                self.speed += V3(0, 1, 0) * -spd
            if event.key == pygame.K_UP:
                self.speed += V3(0, 1, 0) * spd
    self.transform.position -= self.speed * dt
    for event in pygame.event.get():
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT or event.key == pygame.K_DOWN or event.key == pygame.K_UP:
                self.speed = V3.zero()
def decorate_wall(obj, options):

    if options.options.windows == "window_line":
        spaced_points = vg.extrude(
            obj.bottom(), Map(spacing=V3(0, math.ceil(obj.height / 2), 0)))
        for vec in spaced_points:
            obj.features.append(Feature("window", vec,
                                        options=options.options))

    elif options.options.windows == "window_line_double":
        spaced_points = vg.extrude(
            obj.bottom(), Map(spacing=V3(0, math.ceil(obj.height / 2), 0)))
        spaced_points2 = vg.extrude(spaced_points, Map(spacing=V3(0, 1, 0)))
        for vec in spaced_points + spaced_points2:
            obj.features.append(Feature("window", vec,
                                        options=options.options))

    elif options.options.windows == "window_slits":
        spaced_points = vg.points_spaced(obj.bottom(), Map(every=5))
        spaced_points = vg.extrude(
            spaced_points, Map(spacing=V3(0, math.ceil(obj.height / 2), 0)))
        spaced_points2 = vg.extrude(spaced_points, Map(spacing=V3(0, 1, 0)))
        for vec in spaced_points + spaced_points2:
            obj.features.append(Feature("spacing", vec))

    else:
        spaced_points = vg.points_spaced(obj.bottom(), Map(every=3))
        spaced_points = vg.extrude(
            spaced_points, Map(spacing=V3(0, math.ceil(obj.height / 2), 0)))
        for vec in spaced_points:
            obj.features.append(Feature("window", vec,
                                        options=options.options))

    mid_points = vg.middle_of_line(obj.bottom(),
                                   Map(center=True, max_width=2, point_per=10))
    for vec in mid_points:
        obj.features.append(
            Feature(
                "door", vec,
                Map(cardinality=obj.cardinality,
                    door_inside=options.options.door_inside)))

    return obj
예제 #22
0
def TriIntersect(tri, o, dest):
    v0 = tri[0]
    v1 = tri[1]
    v2 = tri[2]
    v0v1 = v1 - v0
    v0v2 = v2 - v0
    N = v0v1.cross(v0v2)
    area = N.len()
    NR = V3.dot(N, dest)
    if math.fabs(NR) < 1e-6:
        return np.inf

    d = V3.dot(N, v0)

    t = (V3.dot(N, o) + d) / NR

    #if t < 0:
    #    return np.inf

    P = o + t * dest
    edge0 = v1 - v0
    vp0 = P - v0
    C = edge0.cross(vp0)
    if V3.dot(N, C) < 0:
        return np.inf, N

    edge1 = v2 - v1
    vp1 = P - v1
    C = edge0.cross(vp1)
    if V3.dot(N, C) < 0:
        return np.inf, N

    edge2 = v0 - v2
    vp2 = P - v2
    C = edge0.cross(vp2)
    if V3.dot(N, C) < 0:
        return np.inf, N

    return d, N
예제 #23
0
def go_tower():
    move_me_to(V3(-786, 1, 263))
예제 #24
0
def my_dir():
    try:
        d = mc.player.getDirection()
    except mcpi.connection.RequestError:
        d = V3(0, 0, 0)
    return V3(d.x, d.y, d.z)
예제 #25
0
    all_points.extend(draw(vg.square, p5, material=texture_base, info=info))
    all_points.extend(draw(vg.rectangular_pyramid, vg.up(p5, higher / 2), height=8, material=texture, info=info))

    class Temp:
        def __init__(self, points):
            self.points = points

        def clear(self):
            for p in self.points:
                create_block(p, block.AIR.id)

    return Temp(all_points)


mid1, mid2 = V3(0, 0, 60), V3(50, 0, 110)
mid_point = V3(30, 0, 120)


def home():
    mc.player.setPos(mid_point)


def prep(size=0, ground=True):
    if size > 0:
        corner1 = V3(mid_point.x - size, mid_point.y, mid_point.z - size)
        corner2 = V3(mid_point.x + size, mid_point.y, mid_point.z + size)
    else:
        corner1, corner2 = V3(-60, 0, 40), V3(120, 0, 200)

    debug("Bulldozing building zone...")
예제 #26
0
    self.near = 1
    self.far = 50
    self.transform.position = V3(0., 0, -1.)
    self.speed = V3.zero()
    self.LookAt = V3.zero()


presenter = Presenter(400, 300)
presenter.bind(scene)

scene.loadtexture(0, 't4puc-rio.jpeg')
scene.createLight(V4(5., 5., 0., 1.), V4(0.7, 0.7, 0.5, 1.0),
                  V4(0.5, 0.5, 0.5, 1.0))

plane = scene.createPlane()
plane.transform.position = V3(0, 0, 0)
#plane.material = Material(1,1,1)
plane.textures = [0, 0]
plane.material = Material(1, 0.0, 0.0)
plane.i = 0.2


def updatep(self, dt):
    self.faces[0][2] = [0, math.sin(self.i), 0]
    self.i += 0.2


plane.update = types.MethodType(updatep, plane)
scene.camera.start = types.MethodType(startCam, scene.camera)

presenter.show()
def test_c(size=0):
    # c = Castle(False, Map(p1=V3(0-size, -1, 90-size), p2=V3(60+size, -1, 150+size)))
    c = Castle(False, Map(p1=V3(0-size, -1, 90-size), p2=V3(60+size, -1, 150+size), window_style="open_slit_and_above"))
    print("Building Castle")
    c.build()
    return c


if __name__ == "__main__":
    import time, os

    if "PYCHARM_HOSTED" in os.environ:
        # Running from within PyCharm

        test_zones = [Map(p1=V3(-10, -1, 80), p2=V3(0, -1, 103)),
                      Map(p1=V3(0, -1, 80), p2=V3(14, -1, 103)),
                      Map(p1=V3(15, -1, 80), p2=V3(28, -1, 107)),
                      Map(p1=V3(28, -1, 80), p2=V3(44, -1, 107)),
                      Map(p1=V3(45, -1, 80), p2=V3(70, -1, 87))]

        helpers.prep()
        c = city(60, buildings=True, castle=True)
        # c = test_c(10)
        # c = helpers.test_shapes()
        # c = Neighborhoods(test_zones[0:2])
#        c.build()
        time.sleep(10)
        c.clear()

        # t = Texture1D.COMMON_TEXTURES.OldStoneWall
def test_c(size=0):
    # c = Castle(False, Map(p1=V3(0-size, -1, 90-size), p2=V3(60+size, -1, 150+size)))
    c = Castle(False, Map(p1=V3(0-size, -1, 90-size), p2=V3(60+size, -1, 150+size), window_style="open_slit_and_above"))
    print("Building Castle")
    c.build()
    return c
예제 #29
0
 def draw(func, position, radius=5, height=8, material=texture_base, info=False):
     points = func(V3(position.x, position.y, position.z), radius, .7, height=height)
     draw_point_list(points, material, options=Map(info=info))
     return points
def city(size=0, layout="castle", farms=False, buildings=False, streets=True, castle=True):
    # Testing location numbers
    mid_point = V3(30, 0, 120)

    if size > 0:
        mid1 = V3(mid_point.x - size, mid_point.y, mid_point.z - size)
        mid2 = V3(mid_point.x + size, mid_point.y, mid_point.z + size)
    else:
        mid1, mid2 = V3(0, 0, 60), V3(50, 0, 110)
        size = 25

    helpers.prep(size+20)

    print("Building zone and street-map using layout:", layout)
    if layout == "castle":
        all_zones = build_castle_streetmap(mid1, mid2, Map(min_x=20, min_z=20))
    else:
        all_zones = vg.partition(mid1, mid2, Map(minx=20, minz=20))
    print("-", len(all_zones), "zones identified")

    farm_zones = []
    building_zones = []
    castle_zone = False

    # Sort zones
    for zone in all_zones:
        if zone.width < 8 or zone.depth < 8:
            farm_zones.append(zone)
        else:
            building_zones.append(zone)

    print("-", len(farm_zones), " farm zones identified")

    # Make the largest zone a castle
    if not castle_zone:
        largest = 0
        largest_index = -1
        for i, zone in enumerate(building_zones):
            size = (zone.width * zone.depth) + min(zone.width, zone.depth) ** 2
            if size > largest:
                largest = size
                largest_index = i
                castle_zone = zone
        building_zones.pop(largest_index)

    print("-", len(building_zones), " building zones identified")
    print("- Castle size", castle_zone.width, "width by", castle_zone.depth, "depth by", castle_zone.height, "height")

    # Turn zones into creations
    s = Streets(all_zones, Map(style="blacktop"))
    f = Farmzones(farm_zones)
    n = Neighborhoods(building_zones)
    c = Castle(options=castle_zone)

    z = [all_zones, farm_zones, building_zones, castle_zone]

    # Build the creations
    if streets: s.build()
    if farms: f.build()
    if buildings: n.build()
    if castle: c.build()

    class Temp:
        def __init__(self, s, f, n, c, z):
            self.s = s
            self.f = f
            self.n = n
            self.c = c
            self.zones = z

        def clear(self):
            self.s.clear()
            self.f.clear()
            self.n.clear()
            self.c.clear()

    return Temp(s=s, f=f, n=n, c=c, z=z)