def get_game_variables(constants):
    constants = get_constants()
    fighter_component = Fighter(hp=constants['player_hp'], defense=constants['player_def'], power=constants['player_pwr'])
    inventory_component = Inventory(26)
    player = Entity(0, 0, constants['player_tile'], libtcod.white, 'Player', blocks=True,
                    render_order=RenderOrder.ACTOR, fighter=fighter_component, inventory=inventory_component)
    entities = [player]

    game_map = GameMap(constants['map_width'], constants['map_height'])
    game_map.make_map(constants['max_rooms'], constants['room_min_size'], constants['room_max_size'],
                      constants['map_width'], constants['map_height'], player, entities,
                      constants['max_monsters_per_room'], constants['max_items_per_room'])

    message_log = MessageLog(constants['message_x'], constants['message_width'], constants['message_height'])

    game_state = GameStates.PLAYERS_TURN

    return player, entities, game_map, message_log, game_state
Пример #2
0
import tcod as libtcod
from render_functions import RenderOrder
from game_states import GameStates
from game_messages import Message
from loader_functions.constants import get_constants

constants = get_constants()


def kill_player(player):
    player.char = constants['player_tile']
    player.color = libtcod.dark_red

    return Message('You died!', libtcod.red), GameStates.PLAYER_DEAD


def kill_monster(monster):
    death_message = Message('{0} is dead!'.format(monster.name.capitalize()),
                            libtcod.orange)

    monster.char = constants['orc_tile']
    if monster.name == 'Troll':
        monster.char = constants['troll_tile']
    elif monster.name == 'Orc':
        monster.char = constants['orc_tile']
    monster.color = libtcod.dark_red
    monster.blocks = False
    monster.fighter = None
    monster.ai = None
    monster.name = 'remains of ' + monster.name
    monster.render_order = RenderOrder.CORPSE
Пример #3
0
    def make_map(self, max_rooms, room_min_size, room_max_size, map_width,
                 map_height, player, entities, max_monsters_per_room,
                 max_items_per_room):
        constants = get_constants()
        rooms = []
        num_rooms = 0

        center_of_last_room_x = None
        center_of_last_room_y = None

        for r in range(max_rooms):
            # random width and height
            w = randint(room_min_size, room_max_size)
            h = randint(room_min_size, room_max_size)
            # random position without going out of the boundaries of the map
            x = randint(0, map_width - w - 1)
            y = randint(0, map_height - h - 1)

            # "Rect" class makes rectangles easier to work with
            new_room = Rect(x, y, w, h)

            # run through the other rooms and see if they intersect with this one
            for other_room in rooms:
                if new_room.intersect(other_room):
                    break

            else:
                # this means there are no intersections, so this room is valid
                # "paint" it to the map's tiles
                self.create_room(new_room)

                # center coordinates of new room, will be useful later
                (new_x, new_y) = new_room.center()

                center_of_last_room_x = new_x
                center_of_last_room_y = new_y

                if num_rooms == 0:
                    # this is the first room, where the player starts at
                    player.x = new_x
                    player.y = new_y

                else:
                    # all rooms after the first:
                    # connect it to the previous room with a tunnel

                    # center coordinates of previous room
                    (prev_x, prev_y) = rooms[num_rooms - 1].center()

                    # flip a coin (random number that is either 0 or 1)
                    if randint(0, 1) == 1:
                        # first move horizontally, then vertically
                        self.create_h_tunnel(prev_x, new_x, prev_y)
                        self.create_v_tunnel(prev_y, new_y, new_x)
                    else:
                        # first move vertically, then horizontally
                        self.create_v_tunnel(prev_y, new_y, prev_x)
                        self.create_h_tunnel(prev_x, new_x, new_y)

                    self.place_entities(new_room, entities,
                                        max_monsters_per_room,
                                        max_items_per_room)

                # finally, append the new room to the list
                rooms.append(new_room)
                num_rooms += 1

        stairs_component = Stairs(self.dungeon_level + 1)
        down_stairs = Entity(center_of_last_room_x,
                             center_of_last_room_y,
                             constants['stairsdown_tile'],
                             libtcod.white,
                             'Stairs',
                             render_order=RenderOrder.STAIRS,
                             stairs=stairs_component)
        entities.append(down_stairs)
Пример #4
0
    def place_entities(self, room, entities, max_monsters_per_room,
                       max_items_per_room):
        constants = get_constants()
        # Get a random number of monsters
        number_of_monsters = randint(0, max_monsters_per_room)
        number_of_items = randint(0, max_items_per_room)

        for i in range(number_of_monsters):
            # Choose a random location in the room
            x = randint(room.x1 + 1, room.x2 - 1)
            y = randint(room.y1 + 1, room.y2 - 1)

            if not any([
                    entity
                    for entity in entities if entity.x == x and entity.y == y
            ]):
                if randint(0, 100) < 80:
                    fighter_component = Fighter(hp=constants['orc_hp'],
                                                defense=constants['orc_def'],
                                                power=constants['orc_pwr'])
                    ai_component = BasicMonster()
                    monster = Entity(x,
                                     y,
                                     constants['orc_tile'],
                                     libtcod.desaturated_green,
                                     'Orc',
                                     blocks=True,
                                     render_order=RenderOrder.ACTOR,
                                     fighter=fighter_component,
                                     ai=ai_component)
                else:
                    fighter_component = Fighter(hp=constants['troll_hp'],
                                                defense=constants['troll_def'],
                                                power=constants['troll_pwr'])
                    ai_component = BasicMonster()
                    monster = Entity(x,
                                     y,
                                     constants['troll_tile'],
                                     libtcod.darker_green,
                                     'Troll',
                                     blocks=True,
                                     fighter=fighter_component,
                                     render_order=RenderOrder.ACTOR,
                                     ai=ai_component)

                entities.append(monster)

        for i in range(number_of_items):
            x = randint(room.x1 + 1, room.x2 - 1)
            y = randint(room.y1 + 1, room.y2 - 1)

            if not any([
                    entity
                    for entity in entities if entity.x == x and entity.y == y
            ]):
                item_chance = randint(0, 100)

                if item_chance < 70:

                    item_component = Item(use_function=heal, amount=4)
                    item = Entity(x,
                                  y,
                                  constants['healingpotion_tile'],
                                  libtcod.violet,
                                  'Healing Potion',
                                  render_order=RenderOrder.ITEM,
                                  item=item_component)
                elif item_chance < 80:
                    item_component = Item(
                        use_function=cast_fireball,
                        targeting=True,
                        targeting_message=Message(
                            'Left-click a target tile for the fireball, or right-click to cancel.',
                            libtcod.light_cyan),
                        damage=12,
                        radius=3)
                    item = Entity(x,
                                  y,
                                  constants['scroll_tile'],
                                  libtcod.red,
                                  'Fireball Scroll',
                                  render_order=RenderOrder.ITEM,
                                  item=item_component)
                elif item_chance < 90:
                    item_component = Item(
                        use_function=cast_confuse,
                        targeting=True,
                        targeting_message=Message(
                            'Left-click an enemy to confuse it, or right-click to cancel.',
                            libtcod.light_cyan))
                    item = Entity(x,
                                  y,
                                  constants['scroll_tile'],
                                  libtcod.light_pink,
                                  'Confusion Scroll',
                                  render_order=RenderOrder.ITEM,
                                  item=item_component)
                else:
                    item_component = Item(use_function=cast_lightning,
                                          damage=20,
                                          maximum_range=5)
                    item = Entity(x,
                                  y,
                                  constants['scroll_tile'],
                                  libtcod.yellow,
                                  'Lightning Scroll',
                                  render_order=RenderOrder.ITEM,
                                  item=item_component)
                entities.append(item)
def render_all(con, panel, entities, player, game_map, fov_map, fov_recompute,
               message_log, screen_width, screen_height, bar_width,
               panel_height, panel_y, mouse, colors, game_state):
    load_font()
    constants = get_constants()
    if fov_recompute:
        for y in range(game_map.height):
            for x in range(game_map.width):
                visible = libtcod.map_is_in_fov(fov_map, x, y)
                wall = game_map.tiles[x][y].block_sight

                if visible:
                    if wall:
                        libtcod.console_put_char_ex(con, x, y,
                                                    constants['wall_tile'],
                                                    libtcod.white,
                                                    libtcod.black)
                    else:
                        libtcod.console_put_char_ex(con, x, y,
                                                    constants['floor_tile'],
                                                    libtcod.white,
                                                    libtcod.black)
                        game_map.tiles[x][y].explored = True
                elif game_map.tiles[x][y].explored:
                    if wall:
                        libtcod.console_put_char_ex(con, x, y,
                                                    constants['wall_tile'],
                                                    libtcod.grey,
                                                    libtcod.black)
                    else:
                        libtcod.console_put_char_ex(con, x, y,
                                                    constants['floor_tile'],
                                                    libtcod.grey,
                                                    libtcod.black)

    entities_in_render_order = sorted(entities,
                                      key=lambda x: x.render_order.value)

    # Draw all entities in the list
    for entity in entities_in_render_order:
        draw_entity(con, entity, fov_map, game_map)

    libtcod.console_blit(con, 0, 0, screen_width, screen_height, 0, 0, 0)

    libtcod.console_set_default_background(panel, libtcod.black)
    libtcod.console_clear(panel)

    # Print the game messages, one line at a time
    y = 1
    for message in message_log.messages:
        libtcod.console_set_default_foreground(panel, message.color)
        libtcod.console_print_ex(panel, message_log.x, y, libtcod.BKGND_NONE,
                                 libtcod.LEFT, message.text)
        y += 1

    def get_names_under_mouse(mouse, entities, fov_map):
        (x, y) = (mouse.cx, mouse.cy)

        names = [
            entity.name for entity in entities
            if entity.x == x and entity.y == y
            and libtcod.map_is_in_fov(fov_map, entity.x, entity.y)
        ]
        names = ', '.join(names)

        return names.capitalize()

    render_bar(panel, 1, 1, bar_width, 'HP', player.fighter.hp,
               player.fighter.max_hp, libtcod.light_red, libtcod.darker_red)
    libtcod.console_print_ex(
        panel, 1, 3, libtcod.BKGND_NONE, libtcod.LEFT,
        'Dungeon level: {0}'.format(game_map.dungeon_level))

    libtcod.console_set_default_foreground(panel, libtcod.light_gray)
    libtcod.console_print_ex(panel, 1, 0, libtcod.BKGND_NONE, libtcod.LEFT,
                             get_names_under_mouse(mouse, entities, fov_map))

    libtcod.console_blit(panel, 0, 0, screen_width, panel_height, 0, 0,
                         panel_y)

    if game_state in (GameStates.SHOW_INVENTORY, GameStates.DROP_INVENTORY):
        if game_state == GameStates.SHOW_INVENTORY:
            inventory_title = 'Press the key next to an item to use it, or Esc to cancel.\n'
        else:
            inventory_title = 'Press the key next to an item to drop it, or Esc to cancel.\n'

        inventory_menu(con, inventory_title, player.inventory, 50,
                       screen_width, screen_height)
Пример #6
0
def main():
    load_font()
    constants = get_constants()

    libtcod.console_set_custom_font(
        constants['font_file'],
        libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD, 32, 10)

    libtcod.console_init_root(constants['screen_width'],
                              constants['screen_height'],
                              constants['window_title'], False)

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

    player = None
    entities = []
    game_map = None
    message_log = None
    game_state = None

    show_main_menu = True
    show_load_error_message = False

    main_menu_background_image = libtcod.image_load(
        constants['main_menu_background_image'])

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

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

        if show_main_menu:
            main_menu(con, main_menu_background_image,
                      constants['screen_width'], constants['screen_height'])

            if show_load_error_message:
                message_box(con, 'No save game to load', 50,
                            constants['screen_width'],
                            constants['screen_height'])

            libtcod.console_flush()

            action = handle_main_menu(key)

            new_game = action.get('new_game')
            load_saved_game = action.get('load_game')
            exit_game = action.get('exit')

            if show_load_error_message and (new_game or load_saved_game
                                            or exit_game):
                show_load_error_message = False
            elif new_game:
                player, entities, game_map, message_log, game_state = get_game_variables(
                    constants)
                game_state = GameStates.PLAYERS_TURN

                show_main_menu = False
            elif load_saved_game:
                try:
                    player, entities, game_map, message_log, game_state = load_game(
                    )
                    show_main_menu = False
                except FileNotFoundError:
                    show_load_error_message = True
            elif exit_game:
                break

        else:
            libtcod.console_clear(con)
            play_game(player, entities, game_map, message_log, game_state, con,
                      panel, constants)

            show_main_menu = True