def test_bsp(): """ commented out statements work in libtcod-cffi """ bsp = libtcodpy.bsp_new_with_size(0, 0, 64, 64) repr(bsp) # test __repr__ on leaf libtcodpy.bsp_resize(bsp, 0, 0, 32, 32) assert bsp != None # test getter/setters bsp.x = bsp.x bsp.y = bsp.y bsp.w = bsp.w bsp.h = bsp.h bsp.position = bsp.position bsp.horizontal = bsp.horizontal bsp.level = bsp.level # cover functions on leaf #self.assertFalse(libtcodpy.bsp_left(bsp)) #self.assertFalse(libtcodpy.bsp_right(bsp)) #self.assertFalse(libtcodpy.bsp_father(bsp)) assert libtcodpy.bsp_is_leaf(bsp) assert libtcodpy.bsp_contains(bsp, 1, 1) #self.assertFalse(libtcodpy.bsp_contains(bsp, -1, -1)) #self.assertEqual(libtcodpy.bsp_find_node(bsp, 1, 1), bsp) #self.assertFalse(libtcodpy.bsp_find_node(bsp, -1, -1)) libtcodpy.bsp_split_once(bsp, False, 4) repr(bsp) # test __repr__ with parent libtcodpy.bsp_split_once(bsp, True, 4) repr(bsp) # cover functions on parent assert libtcodpy.bsp_left(bsp) assert libtcodpy.bsp_right(bsp) #self.assertFalse(libtcodpy.bsp_father(bsp)) assert not libtcodpy.bsp_is_leaf(bsp) #self.assertEqual(libtcodpy.bsp_father(libtcodpy.bsp_left(bsp)), bsp) #self.assertEqual(libtcodpy.bsp_father(libtcodpy.bsp_right(bsp)), bsp) libtcodpy.bsp_split_recursive(bsp, None, 4, 2, 2, 1.0, 1.0) # cover bsp_traverse def traverse(node, user_data): return True libtcodpy.bsp_traverse_pre_order(bsp, traverse) libtcodpy.bsp_traverse_in_order(bsp, traverse) libtcodpy.bsp_traverse_post_order(bsp, traverse) libtcodpy.bsp_traverse_level_order(bsp, traverse) libtcodpy.bsp_traverse_inverted_level_order(bsp, traverse) # test __repr__ on deleted node son = libtcodpy.bsp_left(bsp) libtcodpy.bsp_remove_sons(bsp) repr(son) libtcodpy.bsp_delete(bsp)
def add_floor_variety(level, nodes, chance=0.25): for node in nodes: if libtcod.bsp_is_leaf(node): mutator = Tile.make_floor2 if rand(0,2) == 1 else Tile.make_floor3 if rand(0,999)/1000.0 < chance: rect = Rect(node.x, node.y, node.w, node.h) for xy in rect.xy_values(): if level.map[xy].type == FLOOR: mutator(level.map[xy])
def process_node(self, node, rooms): if libtcod.bsp_is_leaf(node): width = random.randint(7, node.w) height = random.randint(7, node.h) x = random.randint(node.x, node.x+node.w-width) y = random.randint(node.y, node.y+node.h-height) rooms.append(Room(x, y, width, height)) else: self.process_node(libtcod.bsp_left(node), rooms) self.process_node(libtcod.bsp_right(node), rooms)
def process_node(self, node, userData): """ Processes a BSP node. | Creates a room, if the node is a leaf and then smoothes its corners. | If the node is not a leaf, connect the child nodes with a corridor """ from components import Object from render import render_all from nightcaste import initialize_fov if libtcod.bsp_is_leaf(node): #Create Rooms for leafs (level n) min_w = node.w - (node.w/2) min_h = node.h - (node.h/2) width = libtcod.random_get_int(0, min_w, node.w) height = libtcod.random_get_int(0, min_h, node.h) room = Rect(self, libtcod.random_get_int(0, node.x, (node.x + node.w)-width), libtcod.random_get_int(0, node.y, (node.y + node.h)-height), width, height) self.create_room(room) self.smooth_room_corners(room) self.rooms.append(room) elif not libtcod.bsp_is_leaf(node): #Connect rooms with corridors for levels n-1 self.corridor(node) return True
def bsp_leaf_create_room(node, data): global rooms # We want only the leaves. # Since we are traversing in inverted-level-order, # we have traversed all the leaves once we get to the first non-leaf node. if not libtcod.bsp_is_leaf(node): return False # Otherwise, resize the leaf to the room size. # random width and height within leaf size new_w = libtcod.random_get_int(0, ROOM_MIN_SIZE, node.w) new_h = libtcod.random_get_int(0, ROOM_MIN_SIZE, node.h) # random position without going out of the boundaries of the leaf new_x = libtcod.random_get_int(0, node.x, node.x + node.w - new_w) new_y = libtcod.random_get_int(0, node.y, node.y + node.h - new_h) # "Rect" class makes rectangles easier to work with new_room = Room(new_x, new_y, new_w, new_h) # append the new room to the list of rooms # if this is the first room (rooms doesn't exist), # then create rooms = [new_room] try: rooms.append(new_room) except NameError: rooms = [new_room] # We don't need to test for intersection # because each leaf contains exactly one room. # "paint" the room to the map's tiles # go through the tiles in the rectangle and make them passable for x in range(new_room.x1 + 1, new_room.x2): for y in range(new_room.y1 + 1, new_room.y2): g.level_map[y][x] = Tile(tile_types.CAVE_FLOOR) # add some contents to this room, such as monsters place_objects(new_room) return True
def bsp_leaf_create_tunnel(node, data): # connect each pair of subdivisions with a tunnel if not libtcod.bsp_is_leaf(node): # center coordinates of left child (left_x, left_y) = room_center(libtcod.bsp_left(node)) # center coordinates of right child (right_x, right_y) = room_center(libtcod.bsp_right(node)) # flip a coin (random number that is either 0 or 1) if libtcod.random_get_int(0, 0, 1) == 1: # first move horizontally, then vertically create_h_tunnel(left_x, right_x, left_y) create_v_tunnel(left_y, right_y, right_x) else: # first move vertically, then horizontally create_v_tunnel(left_y, right_y, left_x) create_h_tunnel(left_x, right_x, right_y) return True
def fill_node(self, node, tunnels=4, room_has_walls=True, min_size=6, random_fill=True): 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 room_has_walls: if minx > 1: minx -= 1 if miny > 1: miny -= 1 if maxx == self.map.size.w - 2: maxx -= 1 if maxy == self.map.size.h - 2: maxy -= 1 if random_fill: minx = libtcod.random_get_int(None, minx, maxx - min_size + 1) miny = libtcod.random_get_int(None, miny, maxy - min_size + 1) maxx = libtcod.random_get_int(None, minx + min_size - 1, maxx) maxy = libtcod.random_get_int(None, miny + min_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.map[Pos(x, y)].make_floor() else: # resize the node to fit its sons for i in range(tunnels): 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 self.create_corridor(node, left, right)
def traverseNode(self, node, dat): bsp_random_room = True bsp_min_room_size = 5 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 minx > 1: minx -= 1 if miny > 1: miny -= 1 if maxx == self.width - 1: maxx -= 1 if maxy == self.height - 1: maxy -= 1 if bsp_random_room: minx = libtcod.random_get_int(None, minx, maxx - bsp_min_room_size + 1) miny = libtcod.random_get_int(None, miny, maxy - bsp_min_room_size + 1) maxx = libtcod.random_get_int(None, minx + bsp_min_room_size - 1, maxx) maxy = libtcod.random_get_int(None, miny + 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.digMap(x, y) 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(x1, y - 1) self.hline(x1, y, x2) self.vline_down(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(x, right.y) self.vline_up(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(x - 1, y1) self.vline(x, y1, y2) self.hline_right(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(right.x - 1, y) self.hline_right(right.x, y) return True # required or the library shits itself
def traverse_node(node, dat): global bsp_rooms #Create rooms if libtcod.bsp_is_leaf(node): minx = node.x + 1 maxx = node.x + node.w - 1 miny = node.y + 1 maxy = node.y + node.h - 1 if maxx == cfg.MAP_WIDTH - 1: maxx -= 1 if maxy == cfg.MAP_HEIGHT - 1: maxy -= 1 #If it's False the rooms sizes are random, else the rooms are filled to the node's size if cfg.FULL_ROOMS == False: minx = libtcod.random_get_int(None, minx, maxx - cfg.MIN_SIZE + 1) miny = libtcod.random_get_int(None, miny, maxy - cfg.MIN_SIZE + 1) maxx = libtcod.random_get_int(None, minx + cfg.MIN_SIZE - 2, maxx) maxy = libtcod.random_get_int(None, miny + cfg.MIN_SIZE - 2, maxy) node.x = minx node.y = miny node.w = maxx-minx + 1 node.h = maxy-miny + 1 #Dig room for x in range(minx, maxx + 1): for y in range(miny, maxy + 1): cfg.map[x][y].blocked = False cfg.map[x][y].block_sight = False #Add center coordinates to the list of rooms bsp_rooms.append(((minx + maxx) / 2, (miny + maxy) / 2)) #Create corridors else: 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 if node.horizontal: if left.x + left.w - 1 < right.x or right.x + right.w - 1 < left.x: 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) vline_up(cfg.map, x1, y - 1) hline(cfg.map, x1, y, x2) vline_down(cfg.map, x2, y + 1) else: 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) # catch out-of-bounds attempts while x > cfg.MAP_WIDTH - 1: x -= 1 vline_down(cfg.map, x, right.y) vline_up(cfg.map, x, right.y - 1) else: if left.y + left.h - 1 < right.y or right.y + right.h - 1 < left.y: 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) hline_left(cfg.map, x - 1, y1) vline(cfg.map, x, y1, y2) hline_right(cfg.map, x + 1, y2) else: 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) # catch out-of-bounds attempts while y > cfg.MAP_HEIGHT - 1: y -= 1 hline_left(cfg.map, right.x - 1, y) hline_right(cfg.map, right.x, y) return True
def traverse_node(node, dat): # create rooms if lib.bsp_is_leaf(node): minx = node.x + 1 maxx = node.x + node.w - 1 miny = node.y + 1 maxy = node.y + node.h - 1 if maxx == var.MAP_WIDTH - 1: maxx -= 1 if maxy == var.MAP_HEIGHT - 1: maxy -= 1 # if its false, the room sizes are random, else the rooms are filled to the node's size if var.FULL_ROOMS == False: minx = random.randint(minx, maxx - var.MIN_SIZE + 2) miny = random.randint(miny, maxy - var.MIN_SIZE + 2) maxx = random.randint(minx + var.MIN_SIZE - 2, maxx) maxy = random.randint(miny + var.MIN_SIZE - 2, maxy) node.x = minx node.y = miny node.w = maxx - minx + 1 node.h = maxy - miny + 1 # Dig room for x in range(minx, maxx + 1): for y in range(miny, maxy + 1): var.map[x][y].blocked = False var.map[x][y].block_sight = False # add center coordinates to the list of rooms var.bsp_rooms.append(((minx + maxx) / 2, (miny + maxy) / 2)) # create corridors else: left = lib.bsp_left(node) right = lib.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 if node.horizontal: if left.x + left.w - 1 < right.x or right.x + right.w - 1 < left.x: x1 = random.randint(left.x, left.x + left.w - 1) x2 = random.randint(right.x, right.x + right.w - 1) y = random.randint(left.y + left.h, right.y) vline_up(var.map, x1, y - 1) hline(var.map, x1, y, x2) vline_down(var.map, x2, y + 1) else: minx = max(left.x, right.x) maxx = min(left.x + left.w - 1, right.x + right.w - 1) x = random.randint(minx, maxx) # catch out of bounds attempts while x > var.MAP_WIDTH - 1: x -= 1 vline_down(var.map, x, right.y) vline_up(var.map, x, right.y - 1) else: if left.y + left.h - 1 < right.y or right.y + right.h - 1 < left.y: y1 = random.randint(left.y, left.y + left.h - 1) y2 = random.randint(right.y, right.y + right.h - 1) x = random.randint(left.x + left.w, right.x) hline_left(var.map, x - 1, y1) vline(var.map, x, y1, y2) hline_right(var.map, x + 1, y2) else: miny = max(left.y, right.y) maxy = min(left.y + left.h - 1, right.y + right.h - 1) y = random.randint(miny, maxy) # catch out of bounds attempts while y > var.MAP_HEIGHT - 1: y -= 1 hline_left(var.map, right.x - 1, y) hline_right(var.map, right.x, y) return True
def handle_node(node, user_data): if tcod.bsp_is_leaf(node): rectangle(node.x, node.y, node.w + 1, node.h + 1, house_array) return True else: return False
def _traverse_node(self, node, dat): # Create room if libtcod.bsp_is_leaf(node): minx = node.x + 1 maxx = node.x + node.w - 1 miny = node.y + 1 maxy = node.y + node.h - 1 if maxx == self.map_width - 1: maxx -= 1 if maxy == self.map_height - 1: maxy -= 1 if self.full_rooms is False: minx = libtcod.random_get_int(None, minx, maxx - self.min_room_size + 1) miny = libtcod.random_get_int(None, miny, maxy - self.min_room_size + 1) maxx = libtcod.random_get_int(None, minx + self.min_room_size - 2, maxx) maxy = libtcod.random_get_int(None, miny + self.min_room_size - 2, maxy) node.x = minx node.y = miny node.w = maxx - minx + 1 node.h = maxy - miny + 1 # Dig room for x in range(minx, maxx + 1): for y in range(miny, maxy + 1): self._map[x][y].blocked = False self._map[x][y].block_sight = False self._rooms.append(((minx + maxx) // 2, (miny + maxy) // 2)) self._place_objects(minx, miny, maxx, maxy) # Create corridor else: 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 if node.horizontal: if left.x + left.w - 1 < right.x \ or right.x + right.w - 1 < left.x: 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(x1, y - 1) self._hline(x1, y, x2) self._vline_down(x2, y + 1) else: 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(x, right.y) self._vline_up(x, right.y - 1) else: if left.y + left.h - 1 < right.y \ or right.y + right.h - 1 < left.y: 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(x - 1, y1) self._vline(x, y1, y2) self._hline_right(x + 1, y2) else: miny = max(left.y, right.y) maxy = max(left.y + left.h - 1, right.y + right.h - 1) y = libtcod.random_get_int(None, miny, maxy) self._hline_left(right.x - 1, y) self._hline_right(right.x, y) return True
def traverseNode(self,node,dat): bsp_random_room=True bsp_min_room_size=5 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 minx > 1: minx -= 1 if miny > 1: miny -=1 if maxx == self.width - 1: maxx -= 1 if maxy == self.height - 1: maxy -= 1 if bsp_random_room: minx = libtcod.random_get_int(None, minx, maxx - bsp_min_room_size + 1) miny = libtcod.random_get_int(None, miny, maxy - bsp_min_room_size + 1) maxx = libtcod.random_get_int(None, minx + bsp_min_room_size - 1, maxx) maxy = libtcod.random_get_int(None, miny + 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.digMap(x,y); 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(x1, y - 1) self.hline(x1, y, x2) self.vline_down(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(x, right.y) self.vline_up(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(x - 1, y1) self.vline(x, y1, y2) self.hline_right(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(right.x - 1, y) self.hline_right(right.x, y) return True # required or the library shits itself
def bsp_callback(node, data): if tcod.bsp_is_leaf(node): l = Rect(node.x, node.y, node.w, node.h) leafs.append(l) return True #importent - C wizardy :0