Exemple #1
0
    def find_in_bounds_orthogonal(self, point: Point, delta: int = 1) -> Point:
        if delta == 1:
            to_check = point.neighbors
            for check in to_check:
                try:
                    if self.floor.contains_point(check):
                        return check
                except CellOutOfBoundsError:
                    continue
        else:
            to_check = [
                Point(0, -delta),
                Point(delta, 0),
                Point(0, delta),
                Point(-delta, 0)
            ]

            for check in to_check:
                try:
                    if self.floor.contains_point(point + check):
                        return point + check
                except CellOutOfBoundsError:
                    continue

        # Don't return None, just in case
        return point
 def draw(self, ctx):
     color_fg = '#ffffff'
     color_bg = '#000000'
     if self.is_first_responder:
         color_fg = '#000000'
         color_bg = '#ffffff'
     ctx.color(color_fg)
     ctx.bkcolor(color_bg)
     ctx.print(Point(self.bounds.width, 2), '↑')
     ctx.print(Point(self.bounds.width, self.bounds.height), '↓')
Exemple #3
0
 def draw(self, ctx):
     color_fg = '#ffffff'
     color_bg = '#000000'
     if self.is_first_responder:
         color_fg = '#000000'
         color_bg = '#ffffff'
     ctx.color(color_fg)
     ctx.bkcolor(color_bg)
     ctx.print(Point(0, 0), '← ')
     ctx.print(Point(self.bounds.width - 2, 0), ' →')
Exemple #4
0
 def update_pos(self):
     self.unblock()
     if self.delta_pos != Point(0, 0):
         self._pos += self.delta_pos
         bearlib.clear(self._pos.x, self._pos.y, 1, 1)
         self._visible_points = get_visible_points(
             self.position,
             self.map.get_allows_light,
             max_distance=self._range)
     self.update_block()
     self.delta_pos = Point(0, 0)
Exemple #5
0
    def draw(self, ctx):
        color_fg = self.color_selected_fg if self.is_first_responder else self.color_unselected_fg
        color_bg = self.color_selected_bg if self.is_first_responder else self.color_unselected_bg
        ctx.color(color_fg)
        ctx.bkcolor(color_bg)
        ctx.print(Point(0, 0), self.text)

        text_len = len(self.text)

        if self.bounds.width > text_len:
            ctx.print(Point(text_len, 0), '_' * (self.bounds.width - text_len))

        if self.is_first_responder and int(time() * 1.2) % 2 == 0:
            ctx.put(Point(text_len, 0), '▒')
Exemple #6
0
 def diagonals(self, point: Point, delta: int = 2) -> List[Tile]:
     to_check = [neighbor for neighbor in point.diagonal_neighbors]
     to_check.extend([
         Point(-delta, -delta),
         Point(delta, delta),
         Point(delta, -delta),
         Point(-delta, delta)
     ])
     safe = []
     for check in to_check:
         try:
             safe.append(self.floor.cell(point + check))
         except CellOutOfBoundsError:
             pass
     return safe
Exemple #7
0
 def layout_subviews(self):
     for i in range(len(self.labels)):
         is_in_view = self.get_is_in_view(i)
         if is_in_view:
             y = 1 + self.frame.y + i - self.min_row
             self.labels[i].frame = Rect(
                 Point(self.frame.x + 1, y),
                 Size(self.frame.width - self.value_column_width - 2, 1))
             self.values[i].frame = Rect(
                 Point(
                     self.frame.x + 1 + self.frame.width -
                     self.value_column_width - 2, y),
                 Size(self.value_column_width, 1))
         self.labels[i].is_hidden = not is_in_view
         self.values[i].is_hidden = not is_in_view
Exemple #8
0
    def __init__(self, tile: Tile, map: 'Map', scene: 'GameScene'):
        super().__init__(tile, map, scene)
        self.name = self.NAME
        self.description = self.DESCRIPTION
        self._hp = self.BASE_HP
        self._max_hp = self.BASE_HP
        self._tp = self.BASE_TP
        self._max_tp = self.BASE_TP
        self._xp = 0
        self._bump_damage = 1
        self._range = self.RANGE

        self.frozen = 0
        self.state = ActorState.ALIVE

        # Ephemeral deltas
        self.delta_hp = 0
        self.delta_tp = 0
        self.delta_pos = Point(0, 0)
        self.delta_xp = 0

        self._states = {}
        self._visible_points = get_visible_points(self.position,
                                                  self.map.get_allows_light,
                                                  max_distance=self._range)
Exemple #9
0
    def draw(self, ctx):
        ctx.color(self.color_fg)
        ctx.bkcolor(self.color_bg or '#000000')
        if self.clear:
            ctx.clear_area(self.bounds)
        x = 0
        if self.align_horz == 'center':
            x = self.bounds.width / 2 - self.intrinsic_size.width / 2
        elif self.align_horz == 'right':
            x = self.bounds.width - self.intrinsic_size.width

        y = 0
        if self.align_vert == 'center':
            y = self.bounds.height / 2 - self.intrinsic_size.height / 2
        elif self.align_vert == 'bottom':
            y = self.bounds.height - self.intrinsic_size.height
        if self.intrinsic_size.width > self.bounds.width and self.wrap:  # if width exceeds bounds - wrap words
            w = self.bounds.width
        else:
            w = 0
        ctx.print(Point(x, y).floored, self.text, w)
        ctx.color('#ffffff')
        ctx.bkcolor(
            '#000000'
        )  # because sometimes bkcolor i used to draw something else...
Exemple #10
0
 def bounds(self, new_value):
     if new_value.origin != Point(0, 0):
         raise ValueError("Bounds is always anchored at (0, 0)")
     if new_value == self._bounds:
         return
     self._bounds = new_value
     self._frame = self._frame.with_size(new_value.size)
     self.set_needs_layout(True)
Exemple #11
0
 def __init__(self):
     super().__init__()
     self.area = None
     self.level = None
     self._local_x = 0
     self._local_y = 0
     self.region = None
     self.world_x = 0
     self.world_y = 0
     self.point = Point(self._local_x, self._local_y)
Exemple #12
0
    def __init__(self, scene: 'GameScene'):

        self.__floors = {}

        self._floor_size = self.FLOOR_SIZE
        self._origin = self.ORIGIN
        self._center = Point(int(self._floor_size.width / 2),
                             int(self._floor_size.height / 2))

        self._view_size = self.VIEW_SIZE
        self._view_rect = Rect(self._origin, self._view_size)
        self._view_center = Point(int(self._view_size.width / 2),
                                  int(self._view_size.height / 2))

        self._current_floor = 0

        self.scene = scene

        for i in range(0, self.FLOORS):
            self.__floors[i] = Floor(self._origin, self._floor_size)
            self.populate_floor(self.__floors[i])

        for index in self.__floors:
            floor = self.__floors.get(index + 1)
            if floor:
                self.place_stairs(index, index + 1)

        for floor in self.__floors.values():
            if floor.stairs_down and floor.stairs_up:
                floor.connect_tiles(floor.stairs_down, floor.stairs_up)

        player_start_tile = self.floor.cell(
            self.floor.stairs_up.point.get_farthest_point(
                [tile.point for tile in self.floor.get_open_tiles()]))
        self.player = Player(player_start_tile, self, self.scene)
        self.floor.connect_tiles(player_start_tile, self.floor.stairs_up)

        last_floor = self.get_floor(self.FLOORS - 1)
        chronotherium_start_tile = last_floor.cell(
            last_floor.find_open_point())
        Chronotherium(chronotherium_start_tile, self, self.scene)
        last_floor.connect_tiles(chronotherium_start_tile,
                                 last_floor.stairs_down)
Exemple #13
0
 def draw_displays(self, viewer_fov, ctx):
     current_level = self.camera.location.level
     for priority in sorted(current_level.displays.keys(),
                            key=lambda k: k.value):
         for game_object in current_level.displays[priority]:
             x, y = game_object.location.get_local_coords()
             if (x, y) in viewer_fov:
                 relative_point = self.camera.transform(Point(x, y))
                 if relative_point is not None:
                     ctx.printf(relative_point,
                                game_object.display.get_draw_info())
Exemple #14
0
def engrave_bsp_divisions(tilemap, node):
    """
  Debugging method. Sets the debug_character on the cells on the dividing lines
  between the 4 difficulty quadrants.
  """
    if node.level > 1:
        return
    if node.value:
        if node.is_horz:
            x = node.rect.x + node.value
            for y in range(node.rect.y, node.rect.y2 + 1):
                tilemap.cell(Point(x, y)).debug_character = '|'
        else:
            y = node.rect.y + node.value
            for x in range(node.rect.x, node.rect.x2 + 1):
                tilemap.cell(Point(x, y)).debug_character = '-'
    if node.child_a:
        engrave_bsp_divisions(tilemap, node.child_a)
    if node.child_b:
        engrave_bsp_divisions(tilemap, node.child_b)
Exemple #15
0
def generate_and_engrave_corridors(tilemap, root):
    """
  Rooms have already been engraved, so add corridors. Rules for corridors:

  * There is one corridor between each pair of siblings in the BSP tree. If
    that statement doesn't make sense to you, then please go read more
    Wikipedia.
  * There is an exception to that rule: the sole ancestor for each quadrant
    (remember the blog post!) does not have a corridor to its sibling. Instead,
    explicitly draw corridors between specific rooms in each quadrant.
  """
    # generate corridors between rooms WITHIN a quadrant
    sibling_pairs = [(a, b) for (a, b) in root.sibling_pairs
                     if a.level > 2 and b.level > 2]
    for (a, b) in sibling_pairs:
        engrave_corridor_between_rooms(tilemap, a.leftmost_leaf.data['room'],
                                       b.leftmost_leaf.data['room'])

    # generate corridors between quadrants (the glowing ones)
    room_aa_bottom = get_room_nearest(
        root.get_node_at_path('aa').leaves, Point(0, tilemap.size.height / 2))
    room_ab_top = get_room_nearest(
        root.get_node_at_path('ab').leaves, room_aa_bottom.rect.center)
    engrave_corridor_between_rooms(tilemap, room_aa_bottom, room_ab_top,
                                   'transition-1-2')

    room_ab_right = get_room_nearest(
        root.get_node_at_path('ab').leaves,
        Point(tilemap.size.width / 2, tilemap.size.height))
    room_bb_left = get_room_nearest(
        root.get_node_at_path('bb').leaves, room_ab_right.rect.center)
    engrave_corridor_between_rooms(tilemap, room_ab_right, room_bb_left,
                                   'transition-2-3')

    room_bb_top = get_room_nearest(
        root.get_node_at_path('bb').leaves,
        Point(tilemap.size.width, tilemap.size.height / 2))
    room_ba_bottom = get_room_nearest(
        root.get_node_at_path('ba').leaves, room_bb_top.rect.center)
    engrave_corridor_between_rooms(tilemap, room_bb_top, room_ba_bottom,
                                   'transition-3-4')
Exemple #16
0
    def draw_tiles(self, viewer_fov, ctx):
        current_level = self.camera.location.level
        for x, y in viewer_fov:
            tile = current_level.get_tile((x, y))
            if not tile:
                continue

            relative_point = self.camera.transform(Point(x, y))
            if relative_point is None:
                continue

            ctx.printf(relative_point, tile.display.get_draw_info())
Exemple #17
0
 def __init__(self, game, selection, executor):
     self.game = game
     self.action_mapping = game.action_mapping
     views = game.game_scene.view.subviews.copy()
     self.label = LabelView("")
     self.cursor_view = CursorView(game, self)
     views.append(self.label)
     views.append(self.cursor_view)
     super().__init__(views=views)
     self.executor = executor
     self.selection = selection
     self.cursor_position = Point(*executor.location.get_local_coords())
    def layout_subviews(self):
        self.rect_view.apply_springs_and_struts_layout_in_superview()
        if self.scroll_fraction >= 0:
            self.scroll_indicator_view.frame = Rect(
                Point(self.bounds.width - 1, 1 +
                      floor(self.inner_height * self.scroll_fraction)),
                Size(1, 1))

        for i in range(len(self.labels)):
            is_in_view = self.get_is_in_view(i)
            if is_in_view:
                y = 1 + self.bounds.y + i - self.min_row
                self.labels[i].frame = Rect(
                    Point(self.bounds.x + 1, y),
                    Size(self.bounds.width - self.value_column_width - 2, 1))
                self.values[i].frame = Rect(
                    Point(self.bounds.x + 1 + self.bounds.width -
                          self.value_column_width - 2, y),
                    Size(self.value_column_width, 1))
            self.labels[i].is_hidden = not is_in_view
            self.values[i].is_hidden = not is_in_view
Exemple #19
0
 def __init__(self):
     self.window = Window()
     self.message_log = []
     self.gutter = []
     self.gutter_size = Size(
         self.window.width - MAP_SIZE.width + MAP_ORIGIN.x,
         self.window.height - MAP_ORIGIN.y)
     self.gutter_rect = Rect(
         Point(self.window.width - self.gutter_size.width,
               self.window.height - self.gutter_size.height),
         self.gutter_size)
     self.log_height = LOG_HEIGHT
     super().__init__()
Exemple #20
0
    def __init__(self, path):
        self._image = load_xp_file(path)
        self.size = Size(self._image['width'], self._image['height'])
        self.num_layers = self._image['layer_count']

        self._draw_calls_by_layer = []
        for layer_i, layer in enumerate(self._image['layer_data']):
            calls = []
            for x, col in enumerate(layer['cells']):
                for y, cell in enumerate(col):
                    fg = _read_color(cell, 'fore_r', 'fore_g', 'fore_b')
                    bg = self._read_bg_color(layer_i, x, y)
                    calls.append((Point(x, y), cell['keycode'], fg, bg))
            self._draw_calls_by_layer.append(calls)
Exemple #21
0
    def __init__(self, frame=None, subviews=None, scene=None, layout_options=None, clear=False):
        if isinstance(layout_options, dict):  # have pity on the user's imports
            opts = LayoutOptions()._asdict()
            opts.update(layout_options)
            layout_options = LayoutOptions(**opts)
        self.clear = clear
        self._scene = scene
        self._superview_weakref = lambda: None
        self.needs_layout = True
        self._frame = frame or ZERO_RECT
        self._bounds = self.frame.with_origin(Point(0, 0))
        self.subviews = []
        self.add_subviews(subviews or [])
        self.is_first_responder = False
        self.is_hidden = False

        self.layout_spec = frame
        self.layout_options = layout_options or LayoutOptions()
Exemple #22
0
    def draw(self, ctx):
        ctx.color(self.color_fg)
        ctx.bkcolor(self.color_bg or '#000000')
        if self.clear:
            ctx.clear_area(self.bounds)
        x = 0
        if self.align_horz == 'center':
            x = self.bounds.width / 2 - self.intrinsic_size.width / 2
        elif self.align_horz == 'right':
            x = self.bounds.width - self.intrinsic_size.width

        y = 0
        if self.align_vert == 'center':
            y = self.bounds.height / 2 - self.intrinsic_size.height / 2
        elif self.align_vert == 'bottom':
            y = self.bounds.height - self.intrinsic_size.height

        ctx.print(Point(x, y).floored, self.text)
def _cast_light(los_cache, get_allows_light, cx, cy, row, start, end, radius,
                xx, xy, yx, yy):
    if start < end:
        return

    radius_squared = radius * radius

    for j in range(row, radius + 1):
        dx, dy = -j - 1, -j
        blocked = False
        while dx <= 0:
            dx += 1
            # Translate the dx, dy coordinates into map coordinates:
            X, Y = cx + dx * xx + dy * xy, cy + dx * yx + dy * yy
            point = Point(X, Y)
            # l_slope and r_slope store the slopes of the left and right
            # extremities of the square we're considering:
            l_slope, r_slope = (dx - 0.5) / (dy + 0.5), (dx + 0.5) / (dy - 0.5)
            if start < r_slope:
                continue
            elif end > l_slope:
                break
            else:
                # Our light beam is touching this square; light it:
                if dx * dx + dy * dy < radius_squared:
                    los_cache.add(point)
                if blocked:
                    # we're scanning a row of blocked squares:
                    if not get_allows_light(point):
                        new_start = r_slope
                        continue
                    else:
                        blocked = False
                        start = new_start
                else:
                    if not get_allows_light(point) and j < radius:
                        # This is a blocking square, start a child scan:
                        blocked = True
                        _cast_light(los_cache, get_allows_light, cx, cy, j + 1,
                                    start, l_slope, radius, xx, xy, yx, yy)
                        new_start = r_slope
        # Row is scanned; do next row unless last square was blocked:
        if blocked:
            break
Exemple #24
0
def main():
    terminal.open()
    tilemap = TileMap(Size(80, 24))

    player_pos = Point(0, 0)
    for y, row in enumerate(dungeon):
        for x, char in enumerate(row):
            cell = tilemap[Point(x, y)]
            if char == '.':
                cell.terrain = 0
            elif char == '#':
                cell.terrain = 1
            elif char == '@':
                player_pos = Point(x, y)
            else:
                raise ValueError(char)

    terminal.refresh()
    terminal.clear()
    draw(tilemap, player_pos)
    try:
        while True:
            terminal.clear()
            draw(tilemap, player_pos)
            terminal.refresh()
            if terminal.has_input():
                char = terminal.read()
                if char == terminal.TK_Q:
                    break
                if char == terminal.TK_UP:
                    player_pos = player_pos + Point(0, -1)
                if char == terminal.TK_DOWN:
                    player_pos = player_pos + Point(0, 1)
                if char == terminal.TK_LEFT:
                    player_pos = player_pos + Point(-1, 0)
                if char == terminal.TK_RIGHT:
                    player_pos = player_pos + Point(1, 0)
    except KeyboardInterrupt:
        pass
    finally:
        terminal.close()
Exemple #25
0
def generate_dungeon(size):
    """
  Tie it all together. Returns a fully populated RogueBasementTilemap of the
  given size.
  """

    # Make a blank tilemap
    tilemap = RogueBasementTileMap(size)

    # Make a BSP tree where the minimum room size is 4 and the random-split
    # function is the helper defined just above this function
    generator = RandomBSPTree(tilemap.size, 4, randrange_func=_bsp_randrange)

    # key is difficulty (int).
    # values are the topmost ancestor for all nodes of that difficulty. A node
    # knows what difficulty it is based on which ancestor it has.
    difficulty_map = {
        # This 'aa', 'ab' notation is just a quicker, less error-prone way of
        # saying node.child_a.child_b and such.
        0: generator.root.get_node_at_path('aa'),
        1: generator.root.get_node_at_path('ab'),
        2: generator.root.get_node_at_path('bb'),
        3: generator.root.get_node_at_path('ba'),
    }

    # Create a room in each leaf
    rooms = [
        generate_room(leaf, difficulty_map) for leaf in generator.root.leaves
    ]
    # Set the cell terrain values
    engrave_rooms(tilemap, rooms)
    # Make corridors
    generate_and_engrave_corridors(tilemap, generator.root)

    # Place stairs up (no game value, just a marker)
    stairs_up_room = get_room_nearest(
        generator.root.get_node_at_path('aa').leaves,
        Point(tilemap.size.width / 2, tilemap.size.height / 4))
    stairs_up = stairs_up_room.rect.with_inset(1).get_random_point()
    tilemap.points_of_interest['stairs_up'] = stairs_up
    tilemap.occupied_cells.add(stairs_up)
    tilemap.cell(tilemap.points_of_interest['stairs_up']
                 ).feature = EnumFeature.STAIRS_UP

    # Place stairs down
    stairs_down_room = get_room_nearest(
        generator.root.get_node_at_path('ba').leaves,
        Point(tilemap.size.width / 2, tilemap.size.height / 2))
    stairs_down = stairs_down_room.rect.with_inset(1).get_random_point()
    tilemap.points_of_interest['stairs_down'] = stairs_down
    tilemap.occupied_cells.add(stairs_down)
    tilemap.cell(tilemap.points_of_interest['stairs_down']
                 ).feature = EnumFeature.STAIRS_DOWN

    # Tell all the cells how difficult they are (you know, for the music)
    engrave_difficulty(generator.root)

    # Figure out where the monsters and items go
    place_monsters(tilemap)
    place_items(tilemap)

    #engrave_bsp_divisions(tilemap, generator.root)
    return tilemap
Exemple #26
0
 def __init__(self, *args, **kwargs):
   super().__init__(*args, **kwargs)
   self.offset = Point(0, 0)
Exemple #27
0
 def intrinsic_size(self):
     return Point(0, 0)
Exemple #28
0
def _apply_springs_and_struts_layout_to_view(view):
    options = view.layout_options
    spec = view.layout_spec
    superview_bounds = view.superview.bounds

    fields = [
        ('left', 'right', 'x', 'width'),
        ('top', 'bottom', 'y', 'height'),
    ]

    final_frame = Rect(Point(-1000, -1000), Size(-1000, -1000))

    for field_start, field_end, field_coord, field_size in fields:
        debug_string = options.get_debug_string_for_keys(
            [field_start, field_size, field_end])
        matches = (options.get_is_defined(field_start),
                   options.get_is_defined(field_size),
                   options.get_is_defined(field_end))
        if matches == (True, True, True):
            raise ValueError(
                "Invalid spring/strut definition: {}".format(debug_string))
        if matches == (False, False, False):
            raise ValueError(
                "Invalid spring/strut definition: {}".format(debug_string))
        elif matches == (True, False, False):
            setattr(final_frame, field_coord,
                    options.get_value(field_start, view))
            # pretend that size is constant from frame
            setattr(final_frame, field_size, getattr(spec, field_size))
        elif matches == (True, True, False):
            setattr(final_frame, field_coord,
                    options.get_value(field_start, view))
            setattr(final_frame, field_size,
                    options.get_value(field_size, view))
        elif matches == (False, True, False):  # magical centering!
            size_val = options.get_value(field_size, view)
            setattr(final_frame, field_size, size_val)
            setattr(final_frame, field_coord,
                    getattr(superview_bounds, field_size) / 2 - size_val / 2)
        elif matches == (False, True, True):
            size_val = options.get_value(field_size, view)
            setattr(
                final_frame, field_coord,
                getattr(superview_bounds, field_size) -
                options.get_value(field_end, view) - size_val)
            setattr(final_frame, field_size, size_val)
        elif matches == (False, False, True):
            setattr(
                final_frame, field_coord,
                getattr(superview_bounds, field_size) -
                options.get_value(field_end, view))
            # pretend that size is constant from frame
            setattr(final_frame, field_size, getattr(spec, field_size))
        elif matches == (True, False, True):
            start_val = options.get_value(field_start, view)
            end_val = options.get_value(field_end, view)
            setattr(final_frame, field_coord, start_val)
            setattr(
                final_frame, field_size,
                getattr(superview_bounds, field_size) - start_val - end_val)
        else:
            raise ValueError("Unhandled case: {}".format(debug_string))

    assert (final_frame.x != -1000)
    assert (final_frame.y != -1000)
    assert (final_frame.width != -1000)
    assert (final_frame.height != -1000)
    view.frame = final_frame.floored
Exemple #29
0
import weakref
from collections import namedtuple
from numbers import Real

from clubsandwich.geom import Point, Rect, Size
from clubsandwich.blt.context import BearLibTerminalContext
from .layout_options import LayoutOptions

ZERO_RECT = Rect(Point(0, 0), Size(0, 0))


class View:
    def __init__(self,
                 frame=None,
                 subviews=None,
                 scene=None,
                 layout_options=None):
        if isinstance(layout_options, dict):  # have pity on the user's imports
            opts = LayoutOptions()._asdict()
            opts.update(layout_options)
            layout_options = LayoutOptions(**opts)
        self._scene = scene
        self._superview_weakref = lambda: None
        self.needs_layout = True
        self._frame = frame or ZERO_RECT
        self._bounds = self.frame.with_origin(Point(0, 0))
        self.subviews = []
        self.add_subviews(subviews or [])
        self.is_first_responder = False
        self.is_hidden = False
Exemple #30
0
 def frame(self, new_value):
     if new_value == self._frame:
         return
     self._frame = new_value
     self._bounds = new_value.with_origin(Point(0, 0))
     self.set_needs_layout(True)