Ejemplo n.º 1
0
 def build_object(self, me, txt):
     o = MapObject(me, self.fn, txt, self.size_multiplier)
     o.max_relpos = [self.max_relpos[0], self.max_relpos[1]]
     o.min_relpos = [self.min_relpos[0], self.min_relpos[1]]
     o.is_ground = self.is_ground
     ##        if self.randomize_relpos:
     ##            o.randomize_relpos()
     return o
Ejemplo n.º 2
0
 def initialize_rivers(self):
     lm = self.lm
     img_fullsize = self.get_material_image("Shallow water")
     imgs = {}
     for dx in [-1, 0, 1]:
         for dy in [-1, 0, 1]:
             imgs = tm.build_tiles(
                 img_fullsize,
                 lm.cell_sizes,
                 lm.nframes,
                 dx * lm.nframes,
                 dy * lm.nframes,  #dx, dy
                 sin=False)
             river_obj = MapObject(self, imgs[0], "river", 1.)
             river_obj.is_ground = True
             self.register_object_type(river_obj)
Ejemplo n.º 3
0
def add_river_greedy(me, lm, material_dict, imgs, rounded_river, min_length):
    """Computes and draw a random river."""
    print("     Building random river...")
    cell_source = get_river_source(material_dict)
    if not (cell_source):
        print("no cell source")
        return
    xi, yi = cell_source
    cell_source = lm.cells[xi][yi]
    path = [cell_source]
    cell_xy = cell_source
    maxn = 1000
    it = 0
    should_finish = False
    margin = 0.01
    lake_probability = 0.5
    while True:
        if it > maxn:
            break
        elif "water" in cell_xy.material.name.lower():
            break
        elif should_finish:
            break
        it += 1
        section_length = random.randint(2, 10)
        if random.random() < 0.5:
            sign = 1
        else:
            sign = -1
        if random.random() < 0.5:
            dx, dy = sign, 0
        else:
            dx, dy = 0, sign
##        print(dx,dy,section_length)
################################################
        for i in range(section_length):
            if should_finish:
                break
            x = cell_xy.coord[0] + dx
            y = cell_xy.coord[1] + dy
            new_cell = lm.get_cell_at(x, y)
            if new_cell is None:
                break
            elif new_cell.h - margin > cell_xy.h:
                if cell_xy.material.name != new_cell.material.name:
                    break
            elif new_cell in path:
                break
            elif new_cell.name != "river":
                is_valid = True
                for neigh in new_cell.get_neighbors_von_neuman():
                    if neigh:
                        if not (neigh is cell_xy):
                            if neigh.name == "river":
                                is_valid = False
                                break
                            elif "water" in neigh.material.name.lower():
                                should_finish = True
                            elif neigh in path:
                                is_valid = False
                                break
                if is_valid:
                    cell_xy = new_cell
                    path.append(new_cell)


##                    print("OK",dx,dy,section_length)
                else:
                    break
            else:
                break
    #4) change the end to first shallow shore cell
    actual_path = []
    for cell in path:
        if cell.name == "river":
            break
        actual_path.append(cell)
        if "water" in cell.material.name.lower():
            break
        else:  #LAKE ?
            next_to_water = False
            for neigh in cell.get_neighbors_von_neuman():
                if neigh:
                    if "water" in neigh.material.name.lower():
                        next_to_water = True
                        break
            if next_to_water:
                break
    if len(actual_path) < min_length:
        return
    if actual_path[0].material.name == actual_path[-1].material.name:
        return
    elif not ("water" in actual_path[-1].material.name.lower()):
        if random.random() < lake_probability:
            pass
        else:
            return
    #build images of river
    objs = {}
    for delta in imgs:  #imgs[(dx,dy)][zoom]
        river_obj = MapObject(me, imgs[delta][0], "river", 1.)
        river_obj.is_ground = True
        river_obj.lm = lm
        objs[delta] = river_obj
    #5) add river cells to map and layer
    for i, cell in enumerate(actual_path):
        prepare_cell_for_river(lm, cell)
        dx, dy, corner = get_path_orientation(i, cell, actual_path)
        if rounded_river:
            c = objs.get((dx, dy, corner))
        else:
            c = objs.get((dx, dy, None))
        if not c:
            raise Exception("No river object for delta", dx, dy, corner)
        assert cell.name != "river"
        c = c.add_copy_on_cell(cell)
        cell.name = "river"
        lm.static_objects.append(c)

    if actual_path:
        ##        print("RIVER BUILT:", [cell.coord for cell in actual_path])
        if not ("water" in actual_path[-1].material.name.lower()):
            for neigh in actual_path[-1].get_neighbors_moore():
                if neigh and neigh.name != "river":
                    prepare_cell_for_river(lm, neigh)
                    river_obj = MapObject(me, imgs[(0, 0, None)][0], "river",
                                          1.)
                    river_obj.is_ground = True
                    river_obj.lm = lm
                    river_obj = river_obj.add_copy_on_cell(neigh)
                    neigh.name = "river"
                    lm.static_objects.append(river_obj)
    return objs
Ejemplo n.º 4
0
    def add_static_objects(self, me, seed_static):
        #1) We use another hmap to decide where we want trees (or any other object)
        S = len(me.hmap)
        m = ng.generate_terrain(S,
                                n_octaves=self.static_objects_n_octaves,
                                persistance=self.static_objects_persistance,
                                chunk=seed_static)
        ng.normalize(m)
        self.smap = m

        #me.lm is a superimposed map on which we decide to blit some static objects:
        #3) We build the objects that we want.
        # its up to you to decide what should be the size of the object (3rd arg)
        for d in custom.distributions:
            d.build_objects(me)

        #
        cobble = MapObject(me, self.cobble_fn, "cobblestone",
                           self.cobble_fn_size)
        cobble.is_ground = True
        self.cobblestone = cobble
        bridge_h = MapObject(me,
                             self.bridge_h,
                             "bridge",
                             self.bridge_h_size,
                             str_type="bridge_h")
        bridge_h.is_ground = True
        bridge_h.max_relpos = [0., 0.]
        bridge_h.min_relpos = [0., 0.]
        bridge_v = MapObject(me,
                             self.bridge_v,
                             "bridge",
                             self.bridge_v_size,
                             str_type="bridge_v")
        bridge_v.is_ground = True
        bridge_v.max_relpos = [0., 0.]
        bridge_v.min_relpos = [0., 0.]
        self.bridge_h_mapobject = bridge_h
        self.bridge_v_mapobject = bridge_v
        self._objects = {
            "cobble": cobble,
            "bridge_h": bridge_h,
            "bridge_v": bridge_v,
            "road": cobble
        }
        for d in custom.distributions:
            for o in d.objects:
                self._objects[o.name] = o

        #4) add the objects via distributors, to add them randomly in a nice way
        for d in custom.distributions:
            distributor = d.get_distributor(me, me.lm, self.smap)
            distributor.distribute_objects(me.lm, exclusive=d.exclusive)

        self.cobbles = [
            cobble,
            cobble.flip(True, False),
            cobble.flip(False, True),
            cobble.flip(True, True)
        ]
        ############################################################################
        #Here we show how to use the path finder for a given unit of the game
        #Actually, we use it here in order to build cobblestone roads on the map
        me.initialize_rivers()
        costs_materials_road = {name: 1. for name in me.materials}
        costs_materials_road["Snow"] = 10.  #unit is 10 times slower in snow
        costs_materials_road["Thin snow"] = 2.  #twice slower on thin snow...
        costs_materials_road["Sand"] = 2.
        ##        for name in me.materials:
        ##            if "water" in name.lower():
        ##                costs_materials_road[name] = 10
        river_type = me.object_types["river"]
        bush_int_type = self._objects["bush"].int_type
        village_int_type = self._objects["village"].int_type

        costs_objects_road = {
            bush_int_type: 2.,
            cobble.int_type: 0.9,
            river_type: 2.
        }  #unit is 2 times slower in rivers
        #Materials allowed (here we allow water because we add bridges)
        possible_materials_road = list(me.materials)
        for name in me.materials:
            if "water" in name.lower():
                possible_materials_road.remove(name)
        possible_objects_road = [
            cobble.int_type, bush_int_type, village_int_type, river_type
        ]
        ########################################################################
        #now we build a path for rivers, just like we did with roads.
        costs_materials_river = {name: 1. for name in me.materials}
        #Materials allowed (here we allow water because we add bridges)
        possible_materials_river = list(me.materials)
        possible_objects_river = []
        random.seed(self.seed_static_objects)
        n_roads = 0
        n_rivers = 0
        lm = me.lm
        self.imgs_river = self.build_imgs_river(me)
        material_dict = get_materials_dict(lm)
        self.update_loading_bar("Finding paths for rivers and roads...", 0.6)
        for i in range(self.max_number_of_rivers):
            add_river_greedy(me,
                             me.lm,
                             material_dict,
                             self.imgs_river,
                             self.rounded_river,
                             min_length=self.min_river_length)