Beispiel #1
0
def suitable_for_door(dungeon_level, position):
    current_terrain = dungeon_level.get_tile_or_unknown(position).get_terrain()
    if current_terrain.has("is_solid") or current_terrain.has("is_chasm"):
        return False

    up_terrain = dungeon_level.get_tile_or_unknown(
        geo.add_2d(position, direction.UP)).get_terrain()
    down_terrain = dungeon_level.get_tile_or_unknown(
        geo.add_2d(position, direction.DOWN)).get_terrain()
    left_terrain = dungeon_level.get_tile_or_unknown(
        geo.add_2d(position, direction.LEFT)).get_terrain()
    right_terrain = dungeon_level.get_tile_or_unknown(
        geo.add_2d(position, direction.RIGHT)).get_terrain()

    # No door next to other door or chasm, it looks silly.
    terrains = [up_terrain, down_terrain, left_terrain, right_terrain]
    if any([
            terrain.has("is_door") or terrain.has("is_chasm")
            for terrain in terrains
    ]):
        return False

    # Are there any walls to connect with the door?
    up = up_terrain.has("is_solid")
    down = down_terrain.has("is_solid")
    left = left_terrain.has("is_solid")
    right = right_terrain.has("is_solid")
    return ((up and down and not (left or right))
            or (left and right and not (up or down)))
Beispiel #2
0
 def draw_everything(self, camera, tile_matrix):
     for y in range(self.height):
         for x in range(self.width):
             position = (x, y)
             tile_position = geo.add_2d(position, camera.camera_offset)
             the_tile = get_tile_or_unknown(tile_position, tile_matrix)
             the_tile.draw_seen(self.console, position)
Beispiel #3
0
def put_tile_and_surrounding_tiles_on_fire(dungeon_level, position, min_fire_time, max_fire_time, game_state):
    fire = new_fire_cloud(game_state, random.randrange(min_fire_time, max_fire_time))
    fire.mover.replace_move(position, dungeon_level)
    for d in direction.DIRECTIONS:
        point = geometry.add_2d(d, position)
        fire = new_fire_cloud(game_state, random.randrange(min_fire_time, max_fire_time))
        fire.mover.replace_move(point, dungeon_level)
Beispiel #4
0
 def _before_act(self):
     neighbours = [geometry.add_2d(offset, self.parent.position.value) for offset in direction.AXIS_DIRECTIONS]
     random.shuffle(neighbours)
     for neighbour in neighbours:
         if self.point_has_flammable(neighbour) and self.try_spread_to_position(neighbour):
             break
     return gametime.single_turn
Beispiel #5
0
 def position_can_have_web(self, dungeon_level, position):
     surrounding_tiles = [dungeon_level.get_tile_or_unknown(geometry.add_2d(position, d))
                          for d in direction.DIRECTIONS]
     surrounding_solid_terrains = len([tile for tile in surrounding_tiles
                                       if tile.get_terrain().has("is_solid")])
     surrounding_dungeon_features = len([tile for tile in surrounding_tiles
                                         if tile.get_dungeon_feature()])
     return surrounding_dungeon_features + surrounding_solid_terrains > 2
Beispiel #6
0
 def _split_slime(self, split_direction):
     if self._slime.health.hp.value < 3:
         return
     new_slime = self._slime.clone_function.value(self._slime.game_state.value)
     if new_slime.mover.try_move_roll_over(geometry.add_2d(self._slime.position.value, split_direction),
                                           self._slime.dungeon_level.value):
         health = self._slime.health.hp.value / 2
         self._slime.health.hp.value = health
         new_slime.health.hp.value = health
         new_slime.monster_actor_state.value = MonsterActorState.HUNTING
Beispiel #7
0
def _get_walkable_neighbors(entity, position, dungeon_level):
    result_positions = []
    for direction_ in direction.DIRECTIONS:
        neighbor_position = geo.add_2d(position, direction_)
        try:
            neighbor = dungeon_level.get_tile(neighbor_position)
            if entity.mover.can_pass_terrain(neighbor.get_terrain()):
                result_positions.append(neighbor_position)
        except IndexError:
            pass
    return result_positions
Beispiel #8
0
def dfs_tunnler(dungeon_level, start_position, min_length, max_length,
                tile_brush, end_condition_func, direction_list=None):
    position = start_position
    direction_ = random.sample(direction_list, 1)[0]
    while not end_condition_func():
        direction_ = direction.turn_left_or_right(direction_)
        length = random.randint(min_length, max_length)
        tile_brush.apply_brush(dungeon_level, position)
        for _ in range(length):
            position = geo.add_2d(position, direction_)
            tile_brush.apply_brush(dungeon_level, position)
def put_tile_and_surrounding_tiles_on_fire(dungeon_level, position,
                                           min_fire_time, max_fire_time,
                                           game_state):
    fire = new_fire_cloud(game_state,
                          random.randrange(min_fire_time, max_fire_time))
    fire.mover.replace_move(position, dungeon_level)
    for d in direction.DIRECTIONS:
        point = geometry.add_2d(d, position)
        fire = new_fire_cloud(game_state,
                              random.randrange(min_fire_time, max_fire_time))
        fire.mover.replace_move(point, dungeon_level)
def player_status_menu(player):
    split_width = 27
    content_padding = (2, 2)
    player_status_stack_panel = gui.StackPanelVertical(geo.add_2d((0, 0), content_padding),
                                                       alignment=gui.StackPanelVertical.ALIGN_LEFT,
                                                       vertical_space=1)
    player_status_stack_panel_row_1 = gui.StackPanelHorizontal((0, 0), alignment=gui.StackPanelHorizontal.ALIGN_TOP,
                                                               horizontal_space=1)
    player_status_stack_panel.append(player_status_stack_panel_row_1)
    player_status_stack_panel_row_1.append(gui.BigSymbolUIElement((0, 0), player.graphic_char))
    player_description_stack = gui.StackPanelVertical((0, 0), alignment=gui.StackPanelVertical.ALIGN_LEFT,
                                                      vertical_space=1)
    player_status_stack_panel_row_1.append(player_description_stack)
    player_description_stack.append(gui.TextBox(player.description.name, (2, 0), colors.WHITE))
    player_description_stack.append(gui.TextBox(player.race.value + "\n" + player.job.value, (2, 0), colors.WHITE))

    player_description_stack.append(gui.new_player_hp_bar(12, player.health.hp))
    player_description_stack.append(gui.new_player_sanity_bar(12, Counter(10, 10)))

    player_status_stack_panel_row_2 = gui.StackPanelHorizontal((0, 0), alignment=gui.StackPanelHorizontal.ALIGN_TOP,
                                                               horizontal_space=3)
    player_status_stack_panel.append(player_status_stack_panel_row_2)
    player_status_stack_panel_row_2.append(new_player_status_stack(player, 8))
    player_status_stack_panel_row_2.append(new_player_weapon_table(player, 8))

    description_card = gui.new_item_description_card()
    power_list = get_power_list(player, description_card)
    if len(power_list.menu_items) > 0:
        player_status_stack_panel.append(gui.VerticalSpace(1))
    player_status_stack_panel.append(power_list)

    bg_rect_height = (player_status_stack_panel.total_height + 4)
    bg_rect = rectfactory.center_of_screen_rect(split_width, bg_rect_height)

    player_status_stack_panel.offset = geo.add_2d(bg_rect.top_left, (2, 2))

    styled_bg_rect = get_menu_background(bg_rect, style.rogue_classic_theme.rect_style)

    dock = gui.UIDock(rectfactory.full_screen_rect())
    dock.bottom = description_card
    return state.UIState(gui.UIElementList([styled_bg_rect, player_status_stack_panel, dock]))
Beispiel #11
0
 def _get_point_behind_unless_solid(self, enemy_position, distance, dungeon_level):
     """
     Gets point right behind me seen from my enemy.
     """
     right_behind_direction = geometry.other_side_of_point_direction(enemy_position, self.parent.position.value)
     last_result = self.parent.position.value
     for _ in range(distance):
         result = geometry.add_2d(right_behind_direction, last_result)
         if position_is_solid(result, dungeon_level):
             return last_result
         last_result = result
     return result
Beispiel #12
0
def suitable_for_door(dungeon_level, position):
    current_terrain = dungeon_level.get_tile_or_unknown(position).get_terrain()
    if current_terrain.has("is_solid") or current_terrain.has("is_chasm"):
        return False

    up_terrain = dungeon_level.get_tile_or_unknown(geo.add_2d(position, direction.UP)).get_terrain()
    down_terrain = dungeon_level.get_tile_or_unknown(geo.add_2d(position, direction.DOWN)).get_terrain()
    left_terrain = dungeon_level.get_tile_or_unknown(geo.add_2d(position, direction.LEFT)).get_terrain()
    right_terrain = dungeon_level.get_tile_or_unknown(geo.add_2d(position, direction.RIGHT)).get_terrain()

    # No door next to other door or chasm, it looks silly.
    terrains = [up_terrain, down_terrain, left_terrain, right_terrain]
    if any([terrain.has("is_door") or terrain.has("is_chasm") for terrain in terrains]):
        return False

    # Are there any walls to connect with the door?
    up = up_terrain.has("is_solid")
    down = down_terrain.has("is_solid")
    left = left_terrain.has("is_solid")
    right = right_terrain.has("is_solid")
    return ((up and down and not (left or right)) or
            (left and right and not (up or down)))
Beispiel #13
0
 def _on_successful_step(self):
     position = self.parent.position.value
     surrounding_points = [geometry.add_2d(d, position) for d in direction.DIRECTIONS]
     for p in surrounding_points:
         entities = self.parent.dungeon_level.value.get_tile_or_unknown(p).get_entities()
         if len(entities) > 0:
             entity = entities[0]
             for e in entity.get_children_with_tag(trigger.ENEMY_STEPPING_NEXT_TO_ME_TRIGGER_TAG):
                 if e.can_trigger(source_entity=entity, target_entity=self.parent):
                     e.trigger(source_entity=entity, target_entity=self.parent)
             for e in self.parent.get_children_with_tag(trigger.STEP_NEXT_TO_ENEMY_TRIGGER_TAG):
                 if e.can_trigger(source_entity=self.parent, target_entity=entity):
                     e.trigger(source_entity=self.parent, target_entity=entity)
Beispiel #14
0
 def _get_point_behind_unless_solid(self, enemy_position, distance,
                                    dungeon_level):
     """
     Gets point right behind me seen from my enemy.
     """
     right_behind_direction = geometry.other_side_of_point_direction(
         enemy_position, self.parent.position.value)
     last_result = self.parent.position.value
     for _ in range(distance):
         result = geometry.add_2d(right_behind_direction, last_result)
         if position_is_solid(result, dungeon_level):
             return last_result
         last_result = result
     return result
Beispiel #15
0
 def spread(self):
     minimal_cloud_size = 2
     if self.parent.density.value < minimal_cloud_size:
         self.parent.mover.try_remove_from_dungeon()
         return gametime.single_turn
     density_per_tile = max(self.parent.density.value / 4, 1)
     neighbours = [geometry.add_2d(offset, self.parent.position.value) for offset in direction.AXIS_DIRECTIONS]
     random.shuffle(neighbours)
     for neighbour in neighbours:
         self._float_to_position(neighbour, density_per_tile)
         if self.parent.density.value < density_per_tile:
             break
         if self.parent.density.value < minimal_cloud_size:
             break
Beispiel #16
0
def cellular_automata(dungeon_level):
    for y in range(dungeon_level.height):
        for x in range(dungeon_level.width):
            position = (x, y)
            neighbors = [geo.add_2d(position, direction_)
                         for direction_ in direction.DIRECTIONS]

            solid_neighbors = 0
            for point in neighbors:
                if (not dungeon_level.has_tile(point) or
                        dungeon_level.get_tile(point).get_terrain().has("is_solid")):
                    solid_neighbors += 1
            _apply_cellular_automata_rule_on_tile(dungeon_level, position,
                                                  solid_neighbors)
Beispiel #17
0
 def after_tick(self, time):
     self.time_to_next_attempt -= time
     if self.time_to_next_attempt > 0:
         return
     my_position = self.parent.position.value
     chance = self.web_chance_per_turn / float(len(direction.DIRECTIONS))
     dungeon_level = self.parent.dungeon_level.value
     for d in direction.DIRECTIONS:
         point = geometry.add_2d(my_position, d)
         if (random.random() < chance and dungeon_level and
                     len(dungeon_level.get_tile_or_unknown(point).get_entities()) == 0 and
                 self.position_can_have_web(dungeon_level, point)):
             web = new_spider_web()
             web.mover.try_move(point, dungeon_level)
     self.time_to_next_attempt = self.time_interval
Beispiel #18
0
 def try_step_left_or_right(self, next_point):
     step_direction = geometry.sub_2d(next_point, self.parent.position.value)
     if step_direction not in direction.DIRECTIONS:
         return False
     alternate_directions = [direction.turn_slight_left(step_direction),
                             direction.turn_slight_right(step_direction)]
     random.shuffle(alternate_directions)
     for d in alternate_directions:
         new_position = geometry.add_2d(d, self.parent.position.value)
         terrain = self.parent.dungeon_level.value.get_tile_or_unknown(new_position).get_terrain()
         if self.parent.mover.can_pass_terrain(terrain):
             energy_spent = self.parent.stepper.try_move_or_bump(new_position)
             if energy_spent > 0:
                 return energy_spent
     return 0
Beispiel #19
0
 def _blink(self, entity):
     sight = entity.sight_radius.value
     possible_destinations = []
     for x in range(-sight, sight + 1):
         for y in range(-sight, sight + 1):
             if x == 0 and y == 0:
                 continue
             p = geometry.add_2d((x, y), entity.position.value)
             if entity.dungeon_mask.can_see_point(p):
                 possible_destinations.append(p)
     random.shuffle(possible_destinations)
     for position in possible_destinations:
         is_safe = (entity.dungeon_level.value.get_tile_or_unknown(position).get_terrain().has("is_floor")
                    or entity.status_flags.has_status(StatusFlags.FLYING))
         if is_safe and entity.mover.try_move(position):
             break
Beispiel #20
0
def dfs_tunnler(dungeon_level,
                start_position,
                min_length,
                max_length,
                tile_brush,
                end_condition_func,
                direction_list=None):
    position = start_position
    direction_ = random.sample(direction_list, 1)[0]
    while not end_condition_func():
        direction_ = direction.turn_left_or_right(direction_)
        length = random.randint(min_length, max_length)
        tile_brush.apply_brush(dungeon_level, position)
        for _ in range(length):
            position = geo.add_2d(position, direction_)
            tile_brush.apply_brush(dungeon_level, position)
 def _blink(self, entity):
     sight = entity.sight_radius.value
     possible_destinations = []
     for x in range(-sight, sight + 1):
         for y in range(-sight, sight + 1):
             if x == 0 and y == 0:
                 continue
             p = geometry.add_2d((x, y), entity.position.value)
             if entity.dungeon_mask.can_see_point(p):
                 possible_destinations.append(p)
     random.shuffle(possible_destinations)
     for position in possible_destinations:
         is_safe = (entity.dungeon_level.value.get_tile_or_unknown(
             position).get_terrain().has("is_floor")
                    or entity.status_flags.has_status(StatusFlags.FLYING))
         if is_safe and entity.mover.try_move(position):
             break
Beispiel #22
0
def cellular_automata(dungeon_level):
    for y in range(dungeon_level.height):
        for x in range(dungeon_level.width):
            position = (x, y)
            neighbors = [
                geo.add_2d(position, direction_)
                for direction_ in direction.DIRECTIONS
            ]

            solid_neighbors = 0
            for point in neighbors:
                if (not dungeon_level.has_tile(point)
                        or dungeon_level.get_tile(point).get_terrain().has(
                            "is_solid")):
                    solid_neighbors += 1
            _apply_cellular_automata_rule_on_tile(dungeon_level, position,
                                                  solid_neighbors)
Beispiel #23
0
    def try_move_roll_over(self, new_position, new_dungeon_level=None):
        """
        Tries to move parent to new position.
        Or an adjacent tile if it is already occupied.

        Returns true if it is successful, false otherwise.
        """
        if self.try_move(new_position, new_dungeon_level):
            return True
            # Do not shuffle public constants!
        directions = list(direction.DIRECTIONS)
        random.shuffle(directions)
        for d in directions:
            destination = geometry.add_2d(d, new_position)
            if self.try_move(destination, new_dungeon_level):
                return True
        return False
Beispiel #24
0
 def trigger(self, **kwargs):
     #message = messenger.ENTITY_EXPLODES % {"target_entity": self.parent.description.name}
     source_entity = kwargs[action.SOURCE_ENTITY]
     target_position = kwargs[action.TARGET_POSITION]
     game_state = kwargs[action.GAME_STATE]
     explosion = new_explosion_cloud(game_state, 1)
     explosion.graphic_char.color_fg = colors.YELLOW
     explosion.mover.replace_move(target_position, source_entity.dungeon_level.value)
     for d in direction.DIRECTIONS:
         if d in direction.AXIS_DIRECTIONS:
             color = colors.ORANGE
         else:
             color = colors.RED
         point = geometry.add_2d(d, target_position)
         explosion = new_explosion_cloud(game_state, 1)
         explosion.graphic_char.color_fg = color
         explosion.mover.replace_move(point, source_entity.dungeon_level.value)
Beispiel #25
0
def random_explosion(dungeon_level, start_pos, tile_brush,
                     end_condition_func, move_list=None):
    if move_list is None:
        move_list = direction.DIRECTIONS
    position = start_pos
    visited = set()
    unvisited_positions = set()
    while not end_condition_func():
        tile_brush.apply_brush(dungeon_level, position)
        visited.add(position)
        neighbors = set([geo.add_2d(position, _direction)
                         for _direction in move_list])
        unvisited_neighbors = neighbors - visited
        unvisited_positions = unvisited_positions | unvisited_neighbors
        if len(unvisited_positions) >= 1:
            position = random.sample(unvisited_positions, 1)[0]
        else:
            break
Beispiel #26
0
 def after_tick(self, time):
     self.time_to_next_burn_attempt -= time
     if self.time_to_next_burn_attempt > 0:
         return
     my_position = self.parent.position.value
     chance = self.fire_chance_per_turn / float(len(direction.DIRECTIONS))
     for d in direction.DIRECTIONS:
         point = geometry.add_2d(my_position, d)
         dungeon_level = self.parent.dungeon_level.value
         if not dungeon_level:
             break
         fire = new_fire_cloud(self.parent.game_state.value, random.randrange(6, 10))
         if (random.random() < chance and len(dungeon_level.get_tile_or_unknown(point).get_entities()) == 0 and
                 fire.mover.can_move(point, dungeon_level)):
             animate_flight(self.parent.game_state.value, [my_position, point],
                            fire.graphic_char.icon, fire.graphic_char.color_fg)
             fire.mover.try_move(point, dungeon_level)
     self.time_to_next_burn_attempt = self.time_interval
Beispiel #27
0
    def __init__(self, state_stack, message, width=settings.MINIMUM_WIDTH * 0.8,
                 max_height=settings.MINIMUM_HEIGHT * 0.8):
        self.message = message
        self._width = width
        self.max_height = max_height
        self._state_stack = state_stack

        margin = style.interface_theme.margin
        self.text_stack_panel = gui.StackPanelVertical((-1, -1), vertical_space=1)
        self.text_stack_panel.append(gui.TextBoxWrap(message, (0, 0), colors.GRAY, self.width, max_height))
        self.text_stack_panel.append(gui.TextBoxWrap(messenger.PRESS_ENTER_TO_ACCEPT, (0, 0),
                                                     colors.LIGHT_ORANGE, self.width, max_height))
        self.text_stack_panel.update()
        rect = rectfactory.ratio_of_screen_rect(self.text_stack_panel.width + margin[0] * 2,
                                                 self.text_stack_panel.height + margin[1] * 2,
                                                 0.5, 0.3)
        self.text_stack_panel.offset = geo.add_2d(rect.top_left, (2, 2))
        self.bg_rectangle = gui.StyledRectangle(rect, style.interface_theme.rect_style)
        self.result = False
 def trigger(self, **kwargs):
     #message = messenger.ENTITY_EXPLODES % {"target_entity": self.parent.description.name}
     source_entity = kwargs[action.SOURCE_ENTITY]
     target_position = kwargs[action.TARGET_POSITION]
     game_state = kwargs[action.GAME_STATE]
     explosion = new_explosion_cloud(game_state, 1)
     explosion.graphic_char.color_fg = colors.YELLOW
     explosion.mover.replace_move(target_position,
                                  source_entity.dungeon_level.value)
     for d in direction.DIRECTIONS:
         if d in direction.AXIS_DIRECTIONS:
             color = colors.ORANGE
         else:
             color = colors.RED
         point = geometry.add_2d(d, target_position)
         explosion = new_explosion_cloud(game_state, 1)
         explosion.graphic_char.color_fg = color
         explosion.mover.replace_move(point,
                                      source_entity.dungeon_level.value)
Beispiel #29
0
def random_explosion(dungeon_level,
                     start_pos,
                     tile_brush,
                     end_condition_func,
                     move_list=None):
    if move_list is None:
        move_list = direction.DIRECTIONS
    position = start_pos
    visited = set()
    unvisited_positions = set()
    while not end_condition_func():
        tile_brush.apply_brush(dungeon_level, position)
        visited.add(position)
        neighbors = set(
            [geo.add_2d(position, _direction) for _direction in move_list])
        unvisited_neighbors = neighbors - visited
        unvisited_positions = unvisited_positions | unvisited_neighbors
        if len(unvisited_positions) >= 1:
            position = random.sample(unvisited_positions, 1)[0]
        else:
            break
Beispiel #30
0
    def _keep_player_at_distance(self):
        player = self.get_player_if_seen()
        if player is None:
            return False

        if not self.parent.monster_actor_state.value == MonsterActorState.HUNTING:
            return False

        current_distance_to_optimal = self.distance_to_optimal_distance(self.parent.position.value,
                                                                        player.position.value)
        if current_distance_to_optimal == 0:
            return True

        for d in direction.get_shuffled_directions():
            possible_step = geo.add_2d(d, self.parent.position.value)
            if (self.distance_to_optimal_distance(possible_step, player.position.value)
                    < current_distance_to_optimal):
                energy_used = self.parent.stepper.try_step_in_direction(d)
                if energy_used > 0:
                    self.newly_spent_energy += energy_used
                    return True
        return False
Beispiel #31
0
 def draw(self, offset=geo.zero2d()):
     real_offset = geo.int_2d(geo.add_2d(geo.add_2d(self.offset, offset), self.margin))
     self._item_stack_panel.draw(real_offset)
Beispiel #32
0
 def try_step_in_direction(self, direction):
     return self.try_move_or_bump(geometry.add_2d(self.parent.position.value, direction))
Beispiel #33
0
 def apply_brush(self, dungeon_level, position):
     shape = random.sample(self.shapes, 1)[0]
     for point in shape:
         dungeon_position = geo.add_2d(point, position)
         self.tile_modifier.modify(dungeon_level, dungeon_position)
Beispiel #34
0
 def apply_brush(self, dungeon_level, position):
     for point in self.shape:
         dungeon_position = geo.add_2d(point, position)
         self.tile_modifier.modify(dungeon_level, dungeon_position)
Beispiel #35
0
def generate_dungeon_exploded_rooms(depth, rooms, room_area, rectangle_room_chance):
    aprox_room_radius = math.sqrt(room_area) * 1.2

    room_distance = aprox_room_radius

    grid_side = int(max(rooms / 2 + 1, math.sqrt(rooms + 1) + 1))
    triangle_points = shapegenerator.triangle_points(room_distance,
                                                     grid_side, grid_side)

    room_positions = random.sample(triangle_points, rooms)
    minor_room_positions = set()
    room_graph = graph.Graph()
    corridors_points = set()
    for room_position in room_positions:
        room_graph.add_point(room_position)
    while not room_graph.is_connected():
        edge = random.sample(room_positions, 2)
        while room_graph.has_edge(edge[0], edge[1]):
            edge = random.sample(room_positions, 2)
        room_graph.add_edge(edge[0], edge[1])
        mid_point = random.sample(shapegenerator.get_opposite_rectangle_corners(edge[0], edge[1]), 1)[0]
        minor_room_positions.add(mid_point)
        corridor = shapegenerator.three_point_rectangle_draw(edge[0], mid_point, edge[1])
        corridors_points.update(corridor)

    #  Corridor and small corner room shape generation
    open_points = corridors_points
    used_roms_positions = []
    for position in room_positions:
        if random.random() > rectangle_room_chance:
            used_roms_positions.append(position)
            if rng.coin_flip():
                room_points = shapegenerator.random_explosion(position, room_area, direction.AXIS_DIRECTIONS)
            else:
                room_points = shapegenerator.fractal_rectangle(position, 3, 3)
            open_points.update(room_points)

    for position in minor_room_positions:
        room_points = shapegenerator.random_explosion(position, room_area / 4, direction.AXIS_DIRECTIONS)
        open_points.update(room_points)
    open_points = shapegenerator.smooth_shape(open_points)
    open_points = shapegenerator.smooth_shape(open_points)

    possible_door_points = set()
    for position in set(room_positions) - set(used_roms_positions):
        width = random.randrange(3, 8)
        height = random.randrange(3, 8)
        offset_x = random.randrange(width)
        offset_y = random.randrange(height)
        top_left_corner = geo.sub_2d(position, (offset_x, offset_y))
        bottom_right_corner = geo.add_2d(top_left_corner, (width, height))
        room_points = shapegenerator.get_rectangle_shape(top_left_corner, bottom_right_corner)
        surrounding_points = shapegenerator.get_rectangle_shape(geo.sub_2d(top_left_corner, (1, 1)),
                                                                geo.add_2d(bottom_right_corner, (1, 1))) - room_points
        open_points.update(room_points)
        possible_door_points |= surrounding_points

    # Redraw corridors to make sure no dead rooms appear.
    open_points.update(corridors_points)

    plant_points = set()
    if rng.coin_flip() or rng.coin_flip():
        for room_position in room_positions:
            if rng.coin_flip() and rng.coin_flip():
                continue
            room_x, room_y = room_position
            variance = 7
            chasm_start_point = (random.randrange(room_x - variance, room_x + variance),
                                 random.randrange(room_y - variance, room_y + variance))
            plant_points.update(shapegenerator.random_explosion(chasm_start_point,
                                                                room_area * 0.2, direction.AXIS_DIRECTIONS))

    #  Chasm shape generation
    chasm_points = set()
    for room_position in room_positions:
        room_x, room_y = room_position
        variance = 10
        chasm_start_point = (random.randrange(room_x - variance, room_x + variance),
                             random.randrange(room_y - variance, room_y + variance))
        chasm_points.update(shapegenerator.random_explosion(chasm_start_point,
                                                            room_area * 0.8, direction.AXIS_DIRECTIONS))
    chasm_points = shapegenerator.smooth_shape(chasm_points)
    chasm_points = shapegenerator.smooth_shape(chasm_points)

    # Normalize Points to dungeon
    frame = (2, 2)  # Just to be safe we won't try to draw outside Dungeon.
    level_shape = shapegenerator.Shape(open_points)
    plant_shape = shapegenerator.Shape(plant_points)
    chasm_shape = shapegenerator.Shape(chasm_points)
    possible_door_shape = shapegenerator.Shape(possible_door_points)
    dungeon_rect = shapegenerator.Shape(open_points | chasm_points).calc_rect()
    dungeon_rect_with_frame = dungeon_rect.expanded_by(frame)
    normalized_chasm_points = chasm_shape.offset_points(geo.sub_2d(frame, dungeon_rect.top_left))
    normalized_plant_points = plant_shape.offset_points(geo.sub_2d(frame, dungeon_rect.top_left))
    normalized_possible_door_points = possible_door_shape.offset_points(geo.sub_2d(frame, dungeon_rect.top_left))
    normalized_open_points = level_shape.offset_points(geo.sub_2d(frame, dungeon_rect.top_left))

    # Apply shapes to dungeon
    dungeon_level = get_full_wall_dungeon(dungeon_rect_with_frame.width, dungeon_rect_with_frame.height, depth)

    brush = SinglePointBrush(ReplaceComponent(terrain.Chasm))
    apply_brush_to_points(dungeon_level, normalized_chasm_points, brush)

    brush = SinglePointBrush(ReplaceComponent(terrain.Floor))
    apply_brush_to_points(dungeon_level, normalized_open_points, brush)

    brush = SinglePointBrush(ReplaceComponent(dungeonfeature.new_plant))
    apply_brush_to_terrains_with_flag(dungeon_level, normalized_plant_points, brush, terrain.Floor.FLOOR_FLAG)

    door_brush = DoorIfSuitableBrush()
    apply_brush_to_points(dungeon_level, normalized_possible_door_points, door_brush)

    feature_positions = random.sample(normalized_open_points, 4)
    place_up_down_stairs(dungeon_level, feature_positions[0], feature_positions[1])
    _place_feature_replace_terrain_with_floor(dungeonfeature.new_fountain(), dungeon_level, feature_positions[2])
    if rng.coin_flip():
        _place_feature_replace_terrain_with_floor(dungeonfeature.new_blood_fountain(), dungeon_level, feature_positions[3])

    return dungeon_level
Beispiel #36
0
def place_up_down_stairs_at_center(dungeon_level):
    center = (dungeon_level.width / 2,
              dungeon_level.height / 2)
    next_to_center = geo.add_2d(center, (0, 1))
    place_up_down_stairs(dungeon_level, center, next_to_center)
    return True
Beispiel #37
0
 def get_tiles_surrounding_position(self, position):
     return [self.get_tile_or_unknown(geo.add_2d(offset, position))
             for offset in direction.AXIS_DIRECTIONS]
Beispiel #38
0
 def try_move_or_bump(self, _):
     new_position = geometry.add_2d(random.choice(direction.DIRECTIONS), self.parent.position.value)
     return super(RandomStepper, self).try_move_or_bump(new_position)