예제 #1
0
    def event_force_move(self, entity, dx, dy):
        game_map = self.container.map

        position = entity[PositionComponent]

        x1 = position.x
        y1 = position.y

        x2 = x1 + dx
        y2 = y1 + dy

        for i, (x, y) in enumerate(tcod.line_iter(x1, y1, x2, y2)):
            if not game_map.walkable[x, y]:
                self.container.event('wall_slam', entity=entity)
                break

            other_entity = next(
                (e for e in self.container.entities if PositionComponent in e
                 and BlockingComponent in e and e[PositionComponent].x == x
                 and e[PositionComponent].y == y and e is not entity),
                None,
            )

            if other_entity is not None:
                self.container.event('entity_slam',
                                     entity=entity,
                                     other_entity=other_entity)
                break

            else:
                position.x = x
                position.y = y
예제 #2
0
    def event_cursor_fire(self):
        player = self.container.player
        cursor = next(
            (e for e in self.container.entities
             if CursorComponent in e and PositionComponent in e),
            None,
        )
        if cursor is None:
            return

        item = get_weapon(player)

        if item is None or WeaponComponent not in item:
            self.container.event('no_weapon_equipped')
            return

        wc: WeaponComponent = item[WeaponComponent]
        max_range = wc.max_range

        player_position = player[PositionComponent]
        cursor_position = cursor[PositionComponent]

        x1 = player_position.x
        y1 = player_position.y

        x2 = cursor_position.x
        y2 = cursor_position.y

        if wc.smite:
            blocking_entity = next(
                (e for e in self.container.entities
                 if PositionComponent in e and CombatComponent in e and
                 e[PositionComponent].x == x2 and e[PositionComponent].y == y2
                 and e is not player and e is not cursor),
                None,
            )
            if blocking_entity is not None:
                self.container.event('attack',
                                     attacker=player,
                                     defender=blocking_entity)
                return
        else:
            for i, (x, y) in enumerate(tcod.line_iter(x1, y1, x2, y2)):
                if i > max_range:
                    break

                blocking_entity = next(
                    (e for e in self.container.entities
                     if PositionComponent in e and BlockingComponent in e
                     and e[PositionComponent].x == x and e[PositionComponent].y
                     == y and e is not player and e is not cursor),
                    None,
                )
                if blocking_entity is not None:
                    self.container.event('attack',
                                         attacker=player,
                                         defender=blocking_entity)
                    return

            self.container.event('no_target')
예제 #3
0
    def build_path(self):
        """
        Build a path using only cardinal directions from self to chosen_tile.
        """
        path = []
        legal_tiles = []
        closest_tile = None

        legal_tiles.extend(self.legal_tiles.get('green'))
        legal_tiles.extend(self.legal_tiles.get('yellow'))
        legal_tiles.extend(self.legal_tiles.get('red'))

        if len(legal_tiles) > 0 and self.chosen_tile not in legal_tiles:
            closest_tile = legal_tiles.pop()
            for tile in legal_tiles:
                if distance_to(
                        tile, self.chosen_tile, manhattan=False) < distance_to(
                            closest_tile, self.chosen_tile, manhattan=False):
                    closest_tile = tile

        xo, yo = self.owner.location.x, self.owner.location.y
        xd, yd = self.chosen_tile
        if closest_tile:
            xd, yd = closest_tile

        path = list(libtcod.line_iter(xo, yo, xd, yd))

        if path:
            self.path = fill_in_line(path)
            return self.path

        return []
예제 #4
0
 def click_move(self, x, y, game_map, entities):
     line = libtcod.line_iter(self.x, self.y, x, y)
     skip_first = True
     for x, y in line:
         if skip_first:
             skip_first = False
         else:
             self.move_towards(x, y, game_map, entities)
예제 #5
0
def path_unblocked(game_map, xo, yo, xd, yd):
    path = list(libtcod.line_iter(xo, yo, xd, yd))

    for (x, y) in path:
        if 0 < x < game_map.width and 0 < y < game_map.height and not game_map.tiles[
                'blocks_path'][x][y]:
            return True
    else:
        return False
예제 #6
0
    def calculate_movement_range(self, game_map):
        """
        Find three lists of tiles the player may move to. 
        First list is in case of speed increase.
        Second list is in case of speed equilibrium.
        Third list is in case of speed decrease.
        """

        green_list = []
        yellow_list = []
        red_list = []

        x = self.owner.location.x
        y = self.owner.location.y

        min = -self.max_impulse
        max = self.max_impulse + 1

        for xi in range(min, max):
            for yi in range(min, max):
                if (abs(xi) + abs(yi)) <= self.max_impulse:
                    xo = self.owner.location.x
                    xd = x + self.speed_x + xi
                    yo = self.owner.location.y
                    yd = y + self.speed_y + yi

                    new_speed = abs(xd - xo) + abs(yd - yo)
                    line = list(libtcod.line_iter(xo, yo, xd, yd))
                    good_tile = True

                    if new_speed > self.max_speed:
                        # Can't exceed max speed.
                        continue
                    if game_map.is_blocked(xd, yd):
                        # Can't path to blocked tiles.
                        continue

                    for tile in line:
                        xt, yt = tile
                        if game_map.is_blocked(xt, yt):
                            # Can't path to tiles behind blocked tiles.
                            good_tile = False

                    if new_speed > self.speed and new_speed <= self.cruising_speed and good_tile:
                        green_list.append(
                            (x + self.speed_x + xi, y + self.speed_y + yi))
                    if new_speed == self.speed and new_speed <= self.cruising_speed and good_tile:
                        yellow_list.append(
                            (x + self.speed_x + xi, y + self.speed_y + yi))
                    if new_speed < self.speed and new_speed <= self.cruising_speed and good_tile:
                        red_list.append(
                            (x + self.speed_x + xi, y + self.speed_y + yi))

        self.legal_tiles['red'] = red_list
        self.legal_tiles['yellow'] = yellow_list
        self.legal_tiles['green'] = green_list
예제 #7
0
def handle_activation(thing, actor, target_pos, rng):
    if thing in activates_as:
        actor_pos = props.position[actor]
        for pos in tcod.line_iter(actor_pos[0], actor_pos[1], target_pos[0],
                                  target_pos[1]):
            if pos in props.terrain_at:
                t = props.terrain_at[pos]
                if t == things.mountains:
                    props.terrain_at[pos] = things.desert
                    events.terrain_change.trigger(pos)
예제 #8
0
def find_line(coords1: Tuple[int, int],
              coords2: Tuple[int, int],
              include_origin: bool = False) -> Iterator[Tuple[int, int]]:
    """Converts who x,y coords into a list of tiles. coords1 = (x1, y1) coords2 = (x2, y2)"""
    x1, y1 = coords1
    x2, y2 = coords2
    rtn = tcod.line_iter(x1, y1, x2, y2)
    if not include_origin:
        next(rtn)

    return rtn
예제 #9
0
    def __init__(self, xo, yo, xd, yd):
        self.step = 0
        path = list(tcod.line_iter(xo, yo, xd, yd))

        if randint(0, 1) == 0:  # "Close" star
            self.glyph = ord('.')
            self.color = (
                255, 255, 255
            )  # choice([(128, 128, 255), (255, 255, 0), (255, 128, 128), (255, 255, 255)])
            slow_path = [
                point for point in path[0:len(path) // 4] for _ in (0, 1)
            ]
            fast_path = path[len(path) // 4:]

            full_path = slow_path + fast_path

            self.path = full_path[randint(0, 4):]
        else:  # "Far" star
            self.glyph = ord('.')
            self.color = (
                191, 191, 191
            )  # choice([(64, 64, 128), (128, 128, 0), (128, 64, 64), (128, 128, 128)])
            path = path[len(path) // randint(3, 4):]
            self.path = [point for point in path for _ in (0, 1)]
예제 #10
0
def test_line_iter():
    """
    libtcodpy.line_iter
    """
    assert list(libtcodpy.line_iter(*LINE_ARGS)) == INCLUSIVE_RESULTS
예제 #11
0
def test_line_iter():
    """
    libtcodpy.line_iter
    """
    assert list(libtcodpy.line_iter(*LINE_ARGS)) == INCLUSIVE_RESULTS
예제 #12
0
def render_all(entities, player, game_map, message_log, bar_width, panel_y,
               coordinates, camera, game_state, targeting_item):

    entities_in_render_order = sorted(entities,
                                      key=lambda x: x.render_order.value)
    # Draw the map

    camera_moved = camera.move_camera(player.x, player.y, game_map)

    terminal.layer(RenderLayer.MAP.value)

    if camera_moved:
        clear_map_layer()

    game_map.render_from_camera(camera)

    # Draw all entities in the list
    terminal.layer(RenderLayer.ENTITIES.value)
    for entity in entities_in_render_order:
        entity.draw(camera, game_map)

    terminal.layer(RenderLayer.OVERLAY.value)
    clear_layer()

    for efx in game_map.effects:
        efx.update()
        if efx.expired:
            game_map.effects.remove(efx)
        elif efx.render:
            (term_x, term_y) = camera.map_to_term_coord(efx.x, efx.y)
            terminal.put(term_x, term_y, efx.gfx_effect_tile)

    if game_state == GameStates.TARGETING:
        from entity import get_blocking_entities_at_location
        terminal.composition(terminal.TK_ON)

        mouse_map_x = int(coordinates[0] / 4)
        mouse_map_y = int(coordinates[1] / 2)

        mouse_map_x += camera.camera_x
        mouse_map_y += camera.camera_y

        line = tcod.line_iter(player.x, player.y, mouse_map_x, mouse_map_y)

        for coord in line:
            if coord[0] == player.x and coord[1] == player.y:
                continue
            cell_term_x, cell_term_y = camera.map_to_term_coord(
                coord[0], coord[1])
            if coord[0] == mouse_map_x and coord[
                    1] == mouse_map_y and game_map.fov[
                        coord[0], coord[1]] and not game_map.is_blocked(
                            coord[0], coord[1]):
                terminal.color(terminal.color_from_argb(125, 0, 255, 0))
            elif get_blocking_entities_at_location(entities, coord[0],
                                                   coord[1]):
                terminal.color(terminal.color_from_argb(125, 255, 0, 0))
            elif not game_map.fov[coord[0], coord[1]] or game_map.is_blocked(
                    coord[0], coord[1]):
                terminal.color(terminal.color_from_argb(125, 255, 0, 0))
            else:
                terminal.color(terminal.color_from_argb(125, 255, 255, 0))
            terminal.put(x=cell_term_x, y=cell_term_y, c=0x3014)
            terminal.composition(terminal.TK_OFF)

        if targeting_item:
            function_kwargs = targeting_item.item.function_kwargs
            if function_kwargs:
                radius = function_kwargs.get("radius")
                if radius:
                    for cell_x, cell_y in disk(mouse_map_x, mouse_map_y,
                                               radius, game_map.width,
                                               game_map.height):
                        (cell_term_x, cell_term_y) = camera.map_to_term_coord(
                            cell_x, cell_y)
                        if cell_term_x and cell_term_y:  # Omit cells outside of the terminal window
                            if get_blocking_entities_at_location(
                                    entities, cell_x,
                                    cell_y) and game_map.fov[cell_x, cell_y]:
                                terminal.color(
                                    terminal.color_from_argb(125, 0, 255, 0))
                            else:
                                terminal.color(
                                    terminal.color_from_argb(125, 139, 0, 0))
                            terminal.put(x=cell_term_x,
                                         y=cell_term_y,
                                         c=0x3014)

    terminal.layer(RenderLayer.HUD.value)
    clear_layer()

    # HP bar
    render_bar(1, panel_y + 6, bar_width, 'HP', player.fighter.current_hp,
               player.fighter.max_hp, "red", "darker red")

    terminal.printf(1, panel_y + 7, f"Dungeon Level: {game_map.dungeon_level}")

    entity_names = get_names_under_mouse(coordinates, camera, entities,
                                         game_map)
    terminal.printf(1, panel_y, f"[color=white]{entity_names.title()}")

    terminal.layer(RenderLayer.HUD.value)
    line_y = panel_y + 1
    for message in message_log.messages:
        terminal.color(terminal.color_from_name(message.color))
        print_shadowed_text(message_log.x, line_y, message.text)
        line_y += 1

    if game_state in (GameStates.SHOW_INVENTORY, GameStates.DROP_INVENTORY):
        if game_state == GameStates.SHOW_INVENTORY:
            title = "INVENTORY – press key next to item to use it"
        elif game_state == GameStates.DROP_INVENTORY:
            title = "INVENTORY – press key next to item to drop it"
        inventory_menu(player, title).draw()
예제 #13
0
def main():
    constants = get_constants()

    libtcod.console_set_custom_font(
        'rexpaint_cp437_10x10.png',
        libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_ASCII_INROW)

    libtcod.console_init_root(constants['screen_width'],
                              constants['screen_height'],
                              title='MVP v0.0')

    con = libtcod.console_new(constants['screen_width'],
                              constants['screen_height'])
    panel = libtcod.console_new(constants['screen_width'],
                                constants['screen_height'])
    status = libtcod.console_new(constants['screen_width'],
                                 constants['screen_height'])

    player = None
    cursor = None
    entities = []
    game_map = None
    message_log = None
    game_state = None
    turn_state = None
    event_queue = None

    player, cursor, entities, game_map, message_log, game_state, turn_state, event_queue = get_game_variables(
        constants)

    previous_game_state = game_state

    key = libtcod.Key()
    mouse = libtcod.Mouse()

    fov_recompute = True
    fov_map = initialize_fov(game_map)

    while not libtcod.console_is_window_closed():
        libtcod.sys_check_for_event(
            libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse)

        if fov_recompute:
            recompute_fov(fov_map, player.location.x, player.location.y,
                          constants['fov_radius'],
                          constants['fov_light_walls'],
                          constants['fov_algorithm'])

        entities_extended = entities.copy()
        entities_extended.append(cursor)

        render_all(con, panel, entities_extended, game_map, fov_map,
                   fov_recompute, message_log, constants['screen_width'],
                   constants['screen_height'], constants['bar_width'],
                   constants['panel_height'], constants['panel_y'], mouse,
                   constants['colors'], status, constants['status_height'],
                   constants['status_width'], constants['status_x'],
                   game_state, turn_state, player, cursor)

        libtcod.console_flush()

        clear_all(con, entities_extended)

        fov_recompute = False
        """
        Handle the Player Actions.
        """
        action = handle_keys(key, game_state)
        mouse_action = handle_mouse(mouse)

        if action or mouse_action or mouse.dx or mouse.dy:
            fov_recompute = True

        move = action.get('move')  # Attempt to move.
        delta_speed = action.get(
            'delta_speed'
        )  # Changes the max speed reached by the unit durnig autopathing movement.
        next_turn_phase = action.get(
            'next_turn_phase')  # Move to the next phase.
        reset_targets = action.get('reset_targets')  # Reset targets.
        select = action.get(
            'select')  # A target has been selected via keyboard.
        show_weapons_menu = action.get(
            'show_weapons_menu'
        )  # Show the weapons menu in order to choose a weapon to fire.
        weapons_menu_index = action.get(
            'weapons_menu_index')  # Choose an item from the weapons menu.
        look = action.get('look')  # Enter the LOOK game state.
        exit = action.get('exit')  # Exit whatever screen is open.
        fullscreen = action.get('fullscreen')  # Set game to full screen.

        left_click = mouse_action.get('left_click')
        right_click = mouse_action.get('right_click')

        # TODO: Figure out where this should go.
        if look and game_state == GameStates.PLAYER_TURN:
            previous_game_state = game_state
            game_state = GameStates.LOOK
            cursor.cursor.turn_on(player)
            continue
        """
        Handle the turn.
        """
        if game_state == GameStates.ENEMY_TURN or game_state == GameStates.PLAYER_TURN:
            turn_results = []
            active_entity = None

            # Choose the active entity.
            if not event_queue.empty():
                entity_uuid = event_queue.fetch()
                for entity in entities:
                    if entity.uuid == entity_uuid:
                        entity.age += 1
                        active_entity = entity

            # This phase is not for the active_entity.
            if turn_state == TurnStates.UPKEEP_PHASE:
                for entity in entities:
                    if entity.required_game_state == game_state:
                        entity.reset()
                    else:
                        entity.reset(only_action_points=True)

                event_queue.register_list(entities)
                turn_state = TurnStates.PRE_MOVEMENT_PHASE

            # This phase is for the player only.
            if turn_state == TurnStates.PRE_MOVEMENT_PHASE:

                if game_state == GameStates.ENEMY_TURN:
                    turn_state = TurnStates.MOVEMENT_PHASE
                else:
                    # Change player max speed.
                    if delta_speed:
                        turn_results.append(
                            player.propulsion.change_cruising_speed(
                                delta_speed))

                    # Highlight the legal tiles.
                    if not player.propulsion.legal_tiles:
                        game_map.reset_highlighted()
                        player.propulsion.calculate_movement_range(game_map)

                        game_map.set_highlighted(
                            player.propulsion.legal_tiles['red'],
                            color=libtcod.dark_red)
                        game_map.set_highlighted(
                            player.propulsion.legal_tiles['green'],
                            color=libtcod.light_green)
                        game_map.set_highlighted(
                            player.propulsion.legal_tiles['yellow'],
                            color=libtcod.yellow)
                        fov_recompute = True

                        if player.propulsion.chosen_tile:
                            player.propulsion.choose_tile(
                                player.propulsion.chosen_tile, game_map)
                            game_map.set_pathable(player.propulsion.path,
                                                  color=libtcod.blue)
                            fov_recompute = True

                    # Left clicking choose path final destination.
                    if left_click:
                        game_map.reset_pathable()
                        player.propulsion.path.clear()
                        turn_results.append(
                            player.propulsion.choose_tile((mouse.cx, mouse.cy),
                                                          game_map))
                        game_map.set_pathable(player.propulsion.path,
                                              color=libtcod.blue)
                        fov_recompute = True

                    # Right clicking deconstructs path.
                    if right_click:
                        game_map.reset_pathable()
                        player.propulsion.chosen_tile = None
                        player.propulsion.reset()

                    # Attempt to end the turn.
                    if next_turn_phase:
                        if not player.propulsion.chosen_tile:
                            # Phase doesn't end, but goes through one last time with a chosen tile.
                            player.propulsion.chosen_tile = (player.location.x,
                                                             player.location.y)
                        else:
                            next_turn_phase = False
                            player.propulsion.update_speed()
                            turn_state = TurnStates.MOVEMENT_PHASE

            # This phase is the big one. All entities act, except for projectiles of this game_state.
            # This phase ends when all entities have spent their action_points.
            if turn_state == TurnStates.MOVEMENT_PHASE:
                if active_entity:
                    if active_entity is player:
                        if active_entity.required_game_state == game_state:
                            turn_results.extend(
                                movement(player, entities, game_map))

                            if next_turn_phase:
                                next_turn_phase = False
                                player.action_points = 0

                        elif not active_entity.required_game_state == game_state:
                            turn_results.extend(
                                player.arsenal.fire_active_weapon())

                    else:
                        turn_results.extend(
                            active_entity.ai.take_turn(game_state, turn_state,
                                                       entities, game_map))

                if active_entity is None and event_queue.empty():
                    turn_state = TurnStates.POST_MOVEMENT_PHASE

            # This phase is not for the active_entity.
            if turn_state == TurnStates.POST_MOVEMENT_PHASE:
                game_map.reset_flags()
                fov_recompute = True
                turn_state = TurnStates.PRE_ATTACK_PHASE

            # This phase is not for the active_entity.
            # Entities have their action points refilled in order to use their weapons.
            if turn_state == TurnStates.PRE_ATTACK_PHASE:
                if game_state == GameStates.PLAYER_TURN:
                    message_log.add_message(
                        Message(
                            'Press f to target. Press ESC to stop targeting. Enter to change phase. Press r to choose new targets.',
                            libtcod.orange))

                for entity in entities:
                    entity.reset(only_action_points=True)

                event_queue.register_list(entities)
                turn_state = TurnStates.ATTACK_PHASE

            # This phase is for active_entity of the required game_state.
            # They choose their weapons and targets.
            if turn_state == TurnStates.ATTACK_PHASE:
                if active_entity:
                    if active_entity is player:
                        if active_entity.required_game_state == game_state:
                            if show_weapons_menu:
                                previous_game_state = game_state
                                game_state = GameStates.SHOW_WEAPONS_MENU

                            if reset_targets:
                                active_entity.arsenal.reset()
                                message_log.add_message(
                                    Message('Targeting reset.',
                                            libtcod.light_blue))
                                game_map.reset_flags()
                                fov_recompute = True

                            if next_turn_phase:
                                next_turn_phase = False
                                active_entity.action_points = 0

                        else:
                            active_entity.action_points = 0

                    elif active_entity.ai:
                        turn_results.extend(
                            active_entity.ai.take_turn(game_state, turn_state,
                                                       entities, game_map))

                if active_entity is None and event_queue.empty():
                    turn_state = TurnStates.POST_ATTACK_PHASE

            # This phase is not for active_entity.
            if turn_state == TurnStates.POST_ATTACK_PHASE:
                fov_recompute = True
                game_map.reset_flags()
                w = player.arsenal.get_active_weapon()
                if w is not None:
                    for x, y in w.targets:
                        erase_cell(con, x, y)

                turn_state = TurnStates.CLEANUP_PHASE

            # This phase is useless?
            if turn_state == TurnStates.CLEANUP_PHASE:
                if game_state == GameStates.PLAYER_TURN:
                    game_state = GameStates.ENEMY_TURN
                elif game_state == GameStates.ENEMY_TURN:
                    game_state = GameStates.PLAYER_TURN

                turn_state = TurnStates.UPKEEP_PHASE

            # Communicate turn_results.
            for result in turn_results:
                message = result.get(
                    'message')  # Push a message to the message log.
                dead_entity = result.get('dead')  # Kill the entity.
                remove_entity = result.get(
                    'remove')  # Remove the entity (leaves no corpse behind).
                new_projectile = result.get(
                    'new_projectile')  # Creates a new projectile.
                end_turn = result.get('end_turn')  # End the turn.

                if result:
                    fov_recompute = True

                if dead_entity:
                    if dead_entity == player:
                        message, game_state = kill_player(dead_entity)
                    else:
                        message = kill_enemy(dead_entity)

                    event_queue.release(dead_entity)

                if new_projectile:
                    entity_type, location, target, APs, required_game_state = new_projectile
                    projectile = factory.entity_factory(
                        entity_type, location, entities)
                    projectile.action_points = APs
                    xo, yo = location
                    xd, yd = target

                    ### Path extending code.
                    # Determine maximums, based on direction.
                    if xd - xo > 0:
                        max_x = game_map.width
                    else:
                        max_x = 0
                    if yd - yo > 0:
                        max_y = game_map.height
                    else:
                        max_y = 0

                    # Determine the endpoints.
                    if xo - xd == 0:
                        # The projectile moves vertically.
                        y_end = max_y
                    else:
                        y_end = yo - (xo - max_x) * (yo - yd) // (xo - xd)
                    if yo - yd == 0:
                        # The projectile moves horizontally.
                        x_end = max_x
                    else:
                        x_end = xo - (yo - max_y) * (xo - xd) // (yo - yd)

                    # Ensure the enpoints are in the map.
                    if not 0 < y_end < game_map.width:
                        y_end = max_y
                    if not 0 < x_end < game_map.height:
                        x_end = max_x

                    projectile.projectile.path = list(
                        libtcod.line_iter(int(x_end), int(y_end), xo, yo))
                    projectile.projectile.path.pop(
                    )  # Don't start where the shooter is standing.
                    projectile.projectile.path.pop(
                        0)  # Don't end out of bounds.
                    projectile.required_game_state = required_game_state

                    event_queue.register(projectile)

                if remove_entity:
                    entities.remove(remove_entity)

                if end_turn:
                    active_entity.action_points = 0

                if message:
                    message_log.add_message(Message(message, libtcod.yellow))

            # Refill the queue with the active_entity, if appropriate.
            if active_entity and active_entity.action_points > 0:
                event_queue.register(active_entity)
        """
        Handle the targeting cursor.
        """
        if game_state == GameStates.TARGETING:
            targeting_results = []

            if move:
                cursor.cursor.move(move, player.arsenal.get_active_weapon(),
                                   player)

            elif select:
                cursor.cursor.target(game_map,
                                     player.arsenal.get_active_weapon())
                fov_recompute = True

            for result in targeting_results:
                message = result.get('message')
                target = result.get('target')

                if message:
                    message_log.add_message(Message(message, libtcod.red))

                if target:
                    pass
        """
        Handle the Show Weapons Menu state.
        """
        if game_state == GameStates.SHOW_WEAPONS_MENU:
            menu_results = []

            if weapons_menu_index is not None and weapons_menu_index < len(
                    player.arsenal.weapons
            ) and previous_game_state != GameStates.PLAYER_DEAD:
                menu_results.append(
                    player.arsenal.weapons[weapons_menu_index].activate())
                cursor.cursor.turn_on(
                    player, player.arsenal.weapons[weapons_menu_index].targets)
                game_state = GameStates.TARGETING

            for result in menu_results:
                message = result.get('message')

                if message:
                    message_log.add_message(
                        Message(message, libtcod.dark_green))
        """
        Handle the Look game state.
        """
        if game_state == GameStates.LOOK:
            if move:
                dx, dy = move
                cursor_movement(cursor, dx, dy)
        """
        Handle the death of the player.
        """
        if game_state == GameStates.PLAYER_DEAD:
            print('You have died.')
            return True
        """
        Handle commands that activate regardless of game state.
        """
        if exit:
            if game_state == GameStates.SHOW_WEAPONS_MENU or game_state == GameStates.LOOK:
                game_state = previous_game_state
                cursor.cursor.turn_off()

            elif game_state == GameStates.TARGETING:
                cursor.cursor.turn_off()

                fov_recompute = True
                game_state = previous_game_state

            else:
                return True

        if fullscreen:
            libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())
예제 #14
0
    def choose_tile(self, tile, game_map):
        """
        Attempt to choose a tile.
        """
        ### Choose tile.
        self.chosen_tile = tile
        xo, yo = self.owner.location.x, self.owner.location.y
        xd, yd = tile

        ### Check to see if it's in the legal tile range.
        legal_tiles = []
        legal_tiles.extend(self.legal_tiles.get('green'))
        legal_tiles.extend(self.legal_tiles.get('yellow'))
        legal_tiles.extend(self.legal_tiles.get('red'))

        if legal_tiles and tile in legal_tiles:
            path = list(libtcod.line_iter(xo, yo, xd, yd))

            if path:
                self.path = fill_in_line(path)

            return {}

        ### Adjust speed.
        # Calculate true_angle
        xc, yc = xo + self.speed_x, yo + self.speed_y  # This is the center of the legal_tiles grid.

        dx = xd - xc
        dy = yd - yc

        true_angle = math.atan2(dy, dx)
        true_angle = int(true_angle * 180 / math.pi) + 180
        # Now loop over all possible impulses in order to find the closest angle.
        available_impulse = self.max_speed - self.speed
        if available_impulse > self.max_impulse:
            available_impulse = self.max_impulse

        closest_angle = 999
        closest_impulse = 0

        for impulse_x in range(-available_impulse, available_impulse + 1):
            for impulse_y in range(-available_impulse, available_impulse + 1):
                # Try every combo of impulse available.
                if (abs(impulse_x) + abs(impulse_y) <= available_impulse
                        and abs(self.speed_x + impulse_x) +
                        abs(self.speed_y + impulse_y) <= self.cruising_speed):
                    # If it's not more than what's available, see what the angle would be.
                    new_angle = math.atan2(impulse_y, impulse_x)
                    new_angle = int(new_angle * 180 / math.pi) + 180

                    if (abs(new_angle - true_angle) <
                            abs(closest_angle - true_angle) or
                        (abs(new_angle - true_angle)
                         == abs(closest_angle - true_angle) and
                         abs(impulse_x) + abs(impulse_y) > closest_impulse)):
                        # If the angle is close, then we have a new coordinate.
                        closest_angle = new_angle
                        closest_impulse = abs(impulse_x) + abs(impulse_y)
                        dx = impulse_x
                        dy = impulse_y

        new_xd, new_yd = xo + dx + self.speed_x, yo + dy + self.speed_y

        path = list(libtcod.line_iter(xo, yo, new_xd, new_yd))

        if path:
            self.path = fill_in_line(path)

        return {}
예제 #15
0
파일: ai.py 프로젝트: theq629/wastrl
	def can_see(self, actor_pos, target_pos):
		for pos in tcod.line_iter(actor_pos[0], actor_pos[1], target_pos[0], target_pos[1]):
			if any(t in props.blocks_vision for t in props.things_at[pos]):
				return False
		return True