def build_rooms_on(self, dungeon_map): rooms = [] objects = [] for r in range(self.max_rooms): w = libtcod.random_get_int(0, self.room_min_size, self.room_max_size) h = libtcod.random_get_int(0, self.room_min_size, self.room_max_size) x = libtcod.random_get_int(0, 0, dungeon_map.width - w - 1) y = libtcod.random_get_int(0, 0, dungeon_map.height - h - 1) new_room = Rect(x, y, w, h) failed = False for other_room in rooms: if new_room.intersect(other_room): failed = True break if not failed: self._create_room(dungeon_map, new_room) (new_x, new_y) = new_room.center() if len(rooms) > 0: (prev_x, prev_y) = rooms[len(rooms)-1].center() if libtcod.random_get_int(0, 0, 1) == 1: self._create_h_tunnel(dungeon_map, prev_x, new_x, prev_y) self._create_v_tunnel(dungeon_map, prev_y, new_y, new_x) else: self._create_v_tunnel(dungeon_map, prev_y, new_y, prev_x) self._create_h_tunnel(dungeon_map, prev_x, new_x, new_y) rooms.append(new_room) return rooms
def find_clear_space(self): if len(self.rooms) == 0: return (libtcod.random_get_int(0, 0, map.width - 1), libtcod.random_get_int(0, 0, map.height - 1)) room = self.rooms[libtcod.random_get_int(0, 0, len(self.rooms) - 1)] return (libtcod.random_get_int(0, room.x1 + 1, room.x2 - 1), libtcod.random_get_int(0, room.y1 + 1, room.y2 - 1))
def make_level(width, height): level = [[wall_tile() for _ in range(height)] for _ in range(width)] start_pos = 0, 0 rooms = [] for r in range(MAX_ROOMS): # random width and height w = ltc.random_get_int(0, ROOM_MIN_SIZE, ROOM_MAX_SIZE) h = ltc.random_get_int(0, ROOM_MIN_SIZE, ROOM_MAX_SIZE) # random position without going out of the boundaries of the map x = ltc.random_get_int(0, 0, width - w - 1) y = ltc.random_get_int(0, 0, height - h - 1) new_room = Rect(x, y, w, h) # check if new room intersencts an existing room failed = any(map(new_room.intersects, rooms)) if not failed: create_room(level, new_room) if len(rooms) == 0: # this is the first room start_pos = new_room.center() else: # connect to previous room x1, y1 = new_room.center() x2, y2 = rooms[-1].center() create_h_tunnel(level, x1, x2, y1) create_v_tunnel(level, x2, y1, y2) rooms.append(new_room) return LevelData(width, height, level, rooms), start_pos
def populate_items(leveldata): for room in leveldata.rooms: for i in range(ltc.random_get_int(0, 0, MAX_ROOM_ITEMS)): x = ltc.random_get_int(0, room.x1 + 1, room.x2 - 1) y = ltc.random_get_int(0, room.y1 + 1, room.y2 - 1) if leveldata.is_passable(x, y): item = random_item(x, y) leveldata.objects.append(item)
def __init__(self, width=MAP_WIDTH, height=MAP_HEIGHT): self.width = width self.height = height self.tiles = [[Tile('wall') for y in range(self.height)] for x in range(self.width)] self.fov_map = libtcod.map_new(self.width, self.height) self.objects = [] self.rooms = [] self.num_rooms = 0 for r in range(MAX_ROOMS): w = libtcod.random_get_int(0, ROOM_MIN_SIZE, ROOM_MAX_SIZE) h = libtcod.random_get_int(0, ROOM_MIN_SIZE, ROOM_MAX_SIZE) x = libtcod.random_get_int(0, 0, MAP_WIDTH - w - 1) y = libtcod.random_get_int(0, 0, MAP_HEIGHT - h - 1) new_room = Rect(x, y, w, h) failed = False for other_room in self.rooms: if new_room.intersect(other_room): failed = True break if not failed: self.create_room(new_room) self.generate_room_objects(new_room) (new_x, new_y) = new_room.center() if self.num_rooms == 0: self.start_x = new_x self.start_y = new_y else: self.join_rooms(new_room, self.rooms[-1]) self.end_x = new_x self.end_y = new_y self.rooms.append(new_room) self.num_rooms += 1 self.tiles[self.start_x][self.start_y].type = tiletypes['up_stairs'] self.tiles[self.end_x][self.end_y].type = tiletypes['down_stairs'] for y in range(self.height): for x in range(self.width): libtcod.map_set_properties(self.fov_map, x, y, not self.tiles[x][y].type.block_sight, not self.tiles[x][y].type.blocked)
def join_rooms(self, room1, room2): cx1, cy1 = room1.center() cx2, cy2 = room2.center() if libtcod.random_get_int(0, 0, 1) == 1: self.create_h_tunnel(cx1, cx2, cy1) self.create_v_tunnel(cx2, cy1, cy2) else: self.create_v_tunnel(cx1, cy1, cy2) self.create_h_tunnel(cx1, cx2, cy2)
def random_item(x, y): total = sum(choices.values()) r = ltc.random_get_int(0, 0, total) upto = 0 for c, w in choices.iteritems(): if upto + w >= r: return c(x, y) upto += w assert False, "Failed to pick random item"
def generate_room_objects(self, room): num_monsters = libtcod.random_get_int(0, 0, MAX_ROOM_MONSTERS) for i in range(num_monsters): x = libtcod.random_get_int(0, room.x1+1, room.x2-1) y = libtcod.random_get_int(0, room.y1+1, room.y2-1) if self.is_blocked(x, y): continue pick = libtcod.random_get_int(0, 0, 100) if pick < 50: monster = Object(self, x, y, 'g', 'goblin', color=libtcod.green, blocks=True) if pick < 80: monster = Object(self, x, y, 'o', 'orc', color=libtcod.desaturated_green, blocks=True) else: monster = Object(self, x, y, 'T', 'troll', color=libtcod.darker_green, blocks=True) self.objects.append(monster)
def create_monsters_on(self, rooms): monsters = [] for room in rooms: num_monsters = libtcod.random_get_int(0, 0, self.max_room_monsters) for i in range(num_monsters): x = libtcod.random_get_int(0, room.x1 + 1, room.x2 - 1) y = libtcod.random_get_int(0, room.y1 + 1, room.y2 - 1) if libtcod.random_get_int(0, 0, 100) < 80: #80% chance of getting an orc #create an orc monster_char = 'o' else: #create a troll monster_char = 'T' monster = model.Object(x, y, monster_char, self.colors[monster_char], True) monsters.append(monster) return monsters
def __init__ (self, *args): Dungeon.__init__(self, *args) # Variables rooms = [] num_rooms = 0 for r in range(self.max_rooms): # Random width and height room_width = self.random_int(self.min_room_size, self.max_room_size) room_height = self.random_int(self.min_room_size, self.max_room_size) # Random position without going out of the boundaries of the map x = self.random_int(0, self.width - room_width - 1) y = self.random_int(0, self.height - room_height - 1) new_room = Rect(x, y, room_width, room_height) #run through the other rooms and see if they intersect with this one if True in map(lambda room: new_room.intersect(room), rooms): continue # There are no intersections, so this room is valid self.create_room(new_room) # If this is the first room, set it as the players spwan point if len(rooms) == 0: self.spawn = new_room.center() # If the room is not the first room, # connect it to the previous room with a tunnel else: self.log.debug("Placing paths between rooms {} and {}".format(rooms[len(rooms)-1].center(), new_room.center())) prev_room = rooms[len(rooms)-1] self.create_path( prev_room.center()[0], prev_room.center()[1], new_room.center()[0], new_room.center()[1], vertical_first = libtcod.random_get_int(0, 0, 1)) # Place monsters in the room self.place_monsters(new_room) # Append the new room to the list rooms.append(new_room)
def traverse_node(self, node, dat): if libtcod.bsp_is_leaf(node): # calculate the room size minx = node.x + 1 maxx = node.x + node.w - 1 miny = node.y + 1 maxy = node.y + node.h - 1 if not self.bsp_room_walls: if minx > 1: minx -= 1 if miny > 1: miny -=1 if maxx == self.MAP_WIDTH - 1: maxx -= 1 if maxy == self.MAP_HEIGHT - 1: maxy -= 1 if self.bsp_random_room: minx = libtcod.random_get_int(None, minx, maxx - self.bsp_min_room_size + 1) miny = libtcod.random_get_int(None, miny, maxy - self.bsp_min_room_size + 1) maxx = libtcod.random_get_int(None, minx + self.bsp_min_room_size - 1, maxx) maxy = libtcod.random_get_int(None, miny + self.bsp_min_room_size - 1, maxy) # resize the node to fit the room node.x = minx node.y = miny node.w = maxx-minx + 1 node.h = maxy-miny + 1 # dig the room for x in range(minx, maxx + 1): for y in range(miny, maxy + 1): self.bsp_map[x][y] = True else: # resize the node to fit its sons left = libtcod.bsp_left(node) right = libtcod.bsp_right(node) node.x = min(left.x, right.x) node.y = min(left.y, right.y) node.w = max(left.x + left.w, right.x + right.w) - node.x node.h = max(left.y + left.h, right.y + right.h) - node.y # create a corridor between the two lower nodes if node.horizontal: # vertical corridor if left.x + left.w - 1 < right.x or right.x + right.w - 1 < left.x: # no overlapping zone. we need a Z shaped corridor x1 = libtcod.random_get_int(None, left.x, left.x + left.w - 1) x2 = libtcod.random_get_int(None, right.x, right.x + right.w - 1) y = libtcod.random_get_int(None, left.y + left.h, right.y) self.vline_up(self.bsp_map, x1, y - 1) self.hline(self.bsp_map, x1, y, x2) self.vline_down(self.bsp_map, x2, y + 1) else: # straight vertical corridor minx = max(left.x, right.x) maxx = min(left.x + left.w - 1, right.x + right.w - 1) x = libtcod.random_get_int(None, minx, maxx) self.vline_down(self.bsp_map, x, right.y) self.vline_up(self.bsp_map, x, right.y - 1) else: # horizontal corridor if left.y + left.h - 1 < right.y or right.y + right.h - 1 < left.y: # no overlapping zone. we need a Z shaped corridor y1 = libtcod.random_get_int(None, left.y, left.y + left.h - 1) y2 = libtcod.random_get_int(None, right.y, right.y + right.h - 1) x = libtcod.random_get_int(None, left.x + left.w, right.x) self.hline_left(self.bsp_map, x - 1, y1) self.vline(self.bsp_map, x, y1, y2) self.hline_right(self.bsp_map, x + 1, y2) else: # straight horizontal corridor miny = max(left.y, right.y) maxy = min(left.y + left.h - 1, right.y + right.h - 1) y = libtcod.random_get_int(None, miny, maxy) self.hline_left(self.bsp_map, right.x - 1, y) self.hline_right(self.bsp_map, right.x, y) return True
def random_int (self, a, b): return libtcod.random_get_int(self.rand, a, b)
room_min_size - parameter, min size for the generated rooms. Default: 30 room_max_size - parameter, max size for the generated rooms. Default: 10 Returns: room.roomgeo list of the generated rooms in the map (corridors may be generated too, but they are not accounted for). """ rooms = [] num_rooms = 0 for r in range(maxrooms): # random room width and height rw = tcod.random_get_int(self.rg, room_min_size, room_max_size) rh = tcod.random_get_int(self.rg, room_min_size, room_max_size) # random position without going out of the boundaries of the map x = tcod.random_get_int(self.rg, 0, width - rw - 1) y = tcod.random_get_int(self.rg, 0, height - rh - 1) # "Rect" class makes rectangles easiert to work with new_room = self.roomgeo((x, y), (rw, rh)) # run through the other rooms and see if they intersect with this one failed = False for other_room in rooms: if new_room.intersect(other_room): failed = True break