Exemple #1
0
def main():
    # Size of the SCREEN!!! IT'S THE SCREEN, JERRY!  THE SCREEN!
    screen_width = 80
    screen_height = 50

    # Size of the map
    map_width = 80
    map_height = 43

    # size of the BARS!!!!!!!
    bar_width = 20
    panel_height = 7
    panel_y = screen_height - panel_height

    # MESSAGES!!!!!
    message_x = bar_width + 2
    message_width = screen_width - bar_width - 2
    message_height = panel_height - 1

    # Some variables for the rooms in the map
    room_max_size = 10
    room_min_size = 6
    max_rooms = 30

    # MONSTERS
    max_monsters_per_room = 3
    max_items_per_room = 2

    fov_algorithm = 0
    fov_light_walls = True
    fov_radius = 10
    # reg colors
    colors = {
        'dark_wall': libtcod.Color(0, 0, 100),
        'dark_ground': libtcod.Color(50, 50, 150),
        'light_wall': libtcod.Color(130, 110, 50),
        'light_ground': libtcod.Color(200, 180, 50)
    }

    # debug colors
    colors = {
        'dark_wall': libtcod.Color(0, 0, 100),
        'dark_ground': libtcod.Color(50, 50, 150),
        'light_wall': libtcod.Color(130, 110, 50),
        'light_ground': libtcod.Color(200, 180, 50)
    }

    # Components and Entities
    fighter_component = Fighter(hp=30, defense=2, power=5)
    inventory_component = Inventory(26)

    player = Entity(0,
                    0,
                    '@',
                    libtcod.white,
                    'Player',
                    blocks=True,
                    render_order=RenderOrder.ACTOR,
                    fighter=fighter_component,
                    inventory=inventory_component)

    entities = [player]

    libtcod.console_set_custom_font(
        'arial10x10.png',
        libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD)

    libtcod.console_init_root(screen_width,
                              screen_height,
                              'libtcod tutorial revised',
                              False,
                              vsync=True,
                              renderer=libtcod.RENDERER_SDL2)

    con = libtcod.console.Console(screen_width, screen_height)
    panel = libtcod.console_new(screen_width, panel_height)

    game_map = GameMap(map_width, map_height)
    game_map.make_map(max_rooms, room_min_size, room_max_size, map_width,
                      map_height, player, entities, max_monsters_per_room,
                      max_items_per_room)
    print("{}: {}".format("Rooms", len(game_map.rooms)))

    fov_recompute = True

    fov_map = initialize_fov(game_map)

    message_log = MessageLog(message_x, message_width, message_height)

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

    game_state = GameStates.PLAYERS_TURN

    # can't get this code to work the way it's supposed to, so whateves
    # while not tcod.event.get() == 'QUIT':
    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.x, player.y, fov_radius,
                          fov_light_walls, fov_algorithm)

        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)

        fov_recompute = False

        libtcod.console_flush()

        clear_all(con, entities)

        action = handle_keys(key)

        move = action.get('move')
        pickup = action.get('pickup')
        exit = action.get('exit')
        # command = action.get('command')

        fullscreen = action.get('fullscreen')

        player_turn_results = []

        if move and game_state == GameStates.PLAYERS_TURN:
            dx, dy = move
            destination_x = player.x + dx
            destination_y = player.y + dy

            if not game_map.is_blocked(destination_x, destination_y):
                target = get_blocking_entities_at_location(
                    entities, destination_x, destination_y)

                if target:
                    attack_results = player.fighter.attack(target)
                    player_turn_results.extend(attack_results)
                else:
                    player.move(dx, dy)

                    fov_recompute = True

                game_state = GameStates.ENEMY_TURN
        elif pickup and game_state == GameStates.PLAYERS_TURN:
            for entity in entities:
                if entity.item and entity.x == player.x and entity.y == player.y:
                    pickup_results = player.inventory.add_item(entity)
                    player_turn_results.extend(pickup_results)

                    break
            else:
                message_log.add_message(
                    Message('There is nothing here to pick up.',
                            libtcod.yellow))

        if exit:
            return True

        if fullscreen:
            libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())

        for player_turn_result in player_turn_results:
            # player's result loop
            message = player_turn_result.get('message')
            dead_entity = player_turn_result.get('dead')
            item_added = player_turn_result.get('item_added')

            if message:
                message_log.add_message(message)

            if dead_entity:
                if dead_entity == player:
                    message, game_state = kill_player(dead_entity)
                else:
                    message = kill_monster(dead_entity)
                message_log.add_message(message)
            if item_added:
                entities.remove(item_added)
                game_state = GameStates.ENEMY_TURN

        if game_state == GameStates.ENEMY_TURN:
            for entity in entities:
                if entity.ai:
                    enemy_turn_results = entity.ai.take_turn(
                        player, fov_map, game_map, entities)

                    for enemy_turn_result in enemy_turn_results:
                        # enemy results loop
                        message = enemy_turn_result.get('message')
                        dead_entity = enemy_turn_result.get('dead')

                        if message:
                            message_log.add_message(message)

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

                            message_log.add_message(message)

                            if game_state == GameStates.PLAYER_DEAD:
                                break
                    if game_state == GameStates.PLAYER_DEAD:
                        break

            else:
                game_state = GameStates.PLAYERS_TURN
Exemple #2
0
def main():
    window_title: str = 'Bearlibterm/TCOD Roguelike'

    screen_width: int = 40
    screen_height: int = 20
    map_width: int = 80
    map_height: int = 40

    room_max_size: int = 10
    room_min_size: int = 6
    max_rooms: int = 100

    fov_algorithm: int = 0
    fov_light_walls: bool = True
    fov_radius: int = 10

    max_monsters_per_room: int = 3

    colors = {
        'dark_wall': terminal.color_from_argb(0, 0, 0, 100),
        'dark_ground': terminal.color_from_argb(0, 50, 50, 150),
        'light_wall': terminal.color_from_argb(0, 255, 255, 255),
        'light_ground': terminal.color_from_argb(0, 255, 255, 255)
    }

    game_running: bool = True

    fov_recompute: bool = True

    player: Entity = Entity(x=0,
                            y=0,
                            char='@',
                            color=terminal.color_from_argb(0, 255, 255, 255),
                            name='Player',
                            blocks=True)
    entities = [player]

    game_map: GameMap = GameMap(width=map_width, height=map_height)
    game_map.make_map(max_rooms, room_min_size, room_max_size, map_width,
                      map_height, player, entities, max_monsters_per_room)

    camera = Camera(x=0,
                    y=0,
                    width=screen_width,
                    height=screen_height,
                    map_width=map_width,
                    map_height=map_height)
    camera.update(player)

    game_state: GameStates = GameStates.PLAYERS_TURN

    terminal.open()
    terminal.set(
        f'window: size={screen_width}x{screen_height}, title="{window_title}";'
    )

    while game_running:
        if fov_recompute:
            game_map.compute_fov(x=player.x,
                                 y=player.y,
                                 radius=fov_radius,
                                 light_walls=fov_light_walls,
                                 algorithm=fov_algorithm)

        render_all(entities=entities,
                   game_map=game_map,
                   colors=colors,
                   camera=camera)

        fov_recompute = False

        terminal.refresh()

        if terminal.has_input():
            terminal_input: int = terminal.read()

            action = handle_keys(terminal_input)

            escape = action.get('escape')
            movement = action.get('movement')

            if escape:
                game_running = False

            if movement and game_state == GameStates.PLAYERS_TURN:
                dx, dy = movement
                destination_x: int = player.x + dx
                destination_y: int = player.y + dy

                if not game_map.is_blocked(destination_x, destination_y):
                    target: Entity = get_blocking_entities_at_location(
                        entities, destination_x, destination_y)

                    if target:
                        print(
                            f'You kick the {target.name} in the shins, much to its annoyance!'
                        )
                    else:
                        player.move(dx, dy)
                        print(f'player map coords: {player.x}, {player.y}')
                        shift_x = -player.x + int(screen_width / 2)
                        shift_y = -player.y + int(screen_height / 2)
                        print(f'shift coords: {shift_x}, {shift_y}')
                        camera.update(player)
                        print(f'camera coords: {camera.x}, {camera.y}')

                        fov_recompute = True

                    game_state = GameStates.ENEMY_TURN

            if game_state == GameStates.ENEMY_TURN:
                for entity in entities:
                    if entity != player:
                        print(
                            f'The {entity.name} ponders the meaning of its existence.'
                        )

                game_state = GameStates.PLAYERS_TURN

        terminal.clear()

    terminal.close()
Exemple #3
0
def main():
    screen_width = 80
    screen_height = 50
    map_width = 80
    map_height = 45
    room_max_size = 10
    room_min_size = 6
    max_rooms = 30

    fov_algorithm = 0
    fov_light_walls = True
    fov_radius = 10

    max_monsters_per_room = 3

    colors = {
        'dark_wall': libtcod.Color(0, 0, 100),
        'dark_ground': libtcod.Color(50, 50, 150),
        'light_wall': libtcod.Color(130, 110, 50),
        'light_ground': libtcod.Color(200, 180, 50)
    }

    player = Entity(0, 0, '@', libtcod.red, 'Player', blocks=True)
    entities = [player]

    libtcod.console_set_custom_font(
        'arial10x10.png',
        libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD)
    libtcod.console_init_root(screen_width, screen_height, 'ROUGE', False)

    con = libtcod.console_new(screen_width, screen_height)
    game_map = GameMap(map_width, map_height)
    game_map.make_map(max_rooms, room_min_size, room_max_size, map_width,
                      map_height, player, entities, max_monsters_per_room)

    fov_recompute = True
    fov_map = initialize_fov(game_map)

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

    game_state = GameStates.PLAYER_TURN

    while not libtcod.console_is_window_closed():

        libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS, key, mouse)

        if fov_recompute:
            recompute_fov(fov_map, player.x, player.y, fov_radius)

        render_all(con, entities, game_map, fov_map, fov_recompute,
                   screen_width, screen_height, colors)
        fov_recompute = False
        libtcod.console_flush()
        clear_all(con, entities)

        action = handle_keys(key)

        move = action.get('move')
        exit = action.get('exit')
        fullscreen = action.get('fullscreen')

        if move and game_state == GameStates.PLAYER_TURN:
            dx, dy = move
            destination_x = player.x + dx
            destination_y = player.y + dy

            if not game_map.is_blocked(destination_x, destination_y):
                target = get_blocking_entities_at_location(
                    entities, destination_x, destination_y)
                if target:
                    print('You kick the ' + target.name +
                          ' in the shines, much to its annoyance!')
                else:
                    player.move(dx, dy)
                    fov_recompute = True
                game_state = GameStates.ENEMY_TURN

        if exit:
            return True

        if fullscreen:
            libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())

        if game_state == GameStates.ENEMY_TURN:
            for entity in entities:
                if entity != player:
                    print('The ' + entity.name +
                          ' ponders the meaning of its existence...')
            game_state = GameStates.PLAYER_TURN
Exemple #4
0
def main():

    # screen constants
    screen_width = 80
    screen_height = 50

    # UI Stuff
    bar_width = 20
    panel_height = 7
    panel_y = screen_height - panel_height

    message_x = bar_width + 2
    message_width = screen_width - bar_width - 2
    message_height = panel_height - 1
    
    # map stuff
    map_width = 80
    map_height = 43
    room_max_size = 10
    room_min_size = 6
    max_rooms = 30
    max_monsters_per_room = 4

    # FOV constants
    fov_algorithm = 0
    fov_light_walls = True
    fov_radius = 10

    
    colors = {
        'dark_wall': libtcod.Color(0, 0, 100),
        'dark_ground': libtcod.Color(50, 50, 150),
        'light_wall': libtcod.Color(130, 110, 50),
        'light_ground': libtcod.Color(200, 180, 50)
    }
    fighter_component = Fighter(hp=30, defense=2, power=5)
    player = Entity(0, 0, '@', libtcod.white, 'Player', blocks=True, render_order=RenderOrder.ACTOR, fighter=fighter_component)
    entities = [player]

    libtcod.console_set_custom_font('assets/consolas12x12_gs_tc.png', libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD)
    # libtcod.console_set_custom_font('assets/arial10x10.png' , libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD)

    libtcod.console_init_root(screen_width, screen_height, 'libtcod tutorial revised', False, renderer=libtcod.RENDERER_SDL2, vsync=False)

    con = libtcod.console.Console(screen_width, screen_height) # main console
    panel = libtcod.console.Console(screen_width, panel_height) # ui panel

    message_log = MessageLog(message_x, message_width, message_height)

    game_map = GameMap(map_width, map_height)
    game_map.make_map(max_rooms, room_min_size, room_max_size, map_width, map_height, player, entities, max_monsters_per_room)
    
    fov_recompute = True
    fov_map = initialize_fov(game_map)

    turn_count = 0
    
    key = libtcod.Key()
    mouse = libtcod.Mouse()
    
    game_state = GameStates.PLAYERS_TURN

    # main game loop
    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.x, player.y, fov_radius, fov_light_walls, fov_algorithm)
            
        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)
        fov_recompute = False

        libtcod.console_flush()

        clear_all(con,entities)

        action = handle_keys(key)

        move = action.get('move')
        exit = action.get('exit')
        fullscreen = action.get('fullscreen')
        
        player_turn_results = []

        if move and game_state == GameStates.PLAYERS_TURN:
            dx, dy = move
            destination_x = player.x + dx
            destination_y = player.y + dy
            
            if not game_map.is_blocked(destination_x, destination_y):
                target = get_blocking_entities_at_location(entities, destination_x, destination_y)
                if target:
                    attack_results = player.fighter.attack(target)
                    player_turn_results.extend(attack_results)
                else:
                    player.move(dx,dy)
                    fov_recompute = True
                                    
                game_state = GameStates.ENEMY_TURN

        if exit:
            return True

        if fullscreen:
            libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())

        for player_turn_result in player_turn_results:
            message = player_turn_result.get('message')
            dead_entity = player_turn_result.get('dead')

            if message:
                message_log.add_message(message)

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

                message_log.add_message(message)
        if game_state == GameStates.ENEMY_TURN:
            turn_count += 1

            for entity in entities:
                time_based_results = entity.processTimeBasedEffects(turn_count)
                for tb_result in time_based_results:
                    message = tb_result.get('message')
                    if message:
                        message_log.add_message(message)
                
                if entity.ai:
                    enemy_turn_results = entity.ai.take_turn(player, fov_map, game_map, entities)

                    for enemy_turn_result in enemy_turn_results:
                        message = enemy_turn_result.get('message')
                        dead_entity = enemy_turn_result.get('dead')

                        if message:
                            message_log.add_message(message)

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

                            message_log.add_message(message)

                            if game_state == GameStates.PLAYER_DEAD:
                                break

                    if game_state == GameStates.PLAYER_DEAD:
                        break
            else:
                game_state = GameStates.PLAYERS_TURN
Exemple #5
0
def play_game(player, entities, game_map, message_log, game_state,
              root_console, con, panel, constants):
    tdl.set_font("arial10x10.png", greyscale=True, altLayout=True)

    fov_recompute = True
    mouse_coordinates = (0, 0)
    previous_game_state = game_state
    targeting_item = None

    while not tdl.event.is_window_closed():
        if fov_recompute:
            game_map.compute_fov(player.x,
                                 player.y,
                                 fov=constants["fov_algorithm"],
                                 radius=constants["fov_radius"],
                                 light_walls=constants["fov_light_walls"])

        render_all(con, panel, entities, player, game_map, fov_recompute,
                   root_console, message_log, constants["screen_width"],
                   constants["screen_height"], constants["bar_width"],
                   constants["panel_height"], constants["panel_y"],
                   mouse_coordinates, constants["colors"], game_state)
        tdl.flush()

        clear_all(con, entities)
        fov_recompute = False

        for event in tdl.event.get():
            if event.type == "KEYDOWN":
                user_input = event
                break
            elif event.type == "MOUSEMOTION":
                mouse_coordinates = event.cell
            elif event.type == "MOUSEDOWN":
                user_mouse_input = event
                break
        else:
            user_input = None
            user_mouse_input = None

        if not (user_input or user_mouse_input):
            continue

        action = handle_keys(user_input, game_state)
        mouse_action = handle_mouse(user_mouse_input)

        move = action.get("move")
        wait = action.get("wait")
        pickup = action.get("pickup")
        show_inventory = action.get("show_inventory")
        drop_inventory = action.get("drop_inventory")
        inventory_index = action.get("inventory_index")
        take_stairs = action.get("take_stairs")
        level_up = action.get("level_up")
        show_character_screen = action.get("show_character_screen")
        exit = action.get("exit")
        fullscreen = action.get("fullscreen")

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

        player_turn_results = []

        if move and game_state == GameStates.PLAYERS_TURN:
            dx, dy = move
            destination_x = player.x + dx
            destination_y = player.y + dy

            if game_map.walkable[destination_x, destination_y]:
                target = get_blocking_entities_at_location(
                    entities, destination_x, destination_y)

                if target:
                    attack_results = player.fighter.attack(target)
                    player_turn_results.extend(attack_results)
                else:
                    player.move(dx, dy)
                    fov_recompute = True

                game_state = GameStates.ENEMY_TURN

        elif wait:
            game_state = GameStates.ENEMY_TURN

        elif pickup and game_state == GameStates.PLAYERS_TURN:
            for entity in entities:
                if entity.item and entity.x == player.x and entity.y == player.y:
                    pickup_results = player.inventory.add_item(
                        entity, constants["colors"])
                    player_turn_results.extend(pickup_results)

                    break
            else:
                message_log.add_message(
                    Message("Nothing to pick up.",
                            constants["colors"].get("yellow")))

        if show_inventory:
            previous_game_state = game_state
            game_state = GameStates.SHOW_INVENTORY

        if drop_inventory:
            previous_game_state = game_state
            game_state = GameStates.DROP_INVENTORY

        if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len(
                player.inventory.items):
            item = player.inventory.items[inventory_index]

            if game_state == GameStates.SHOW_INVENTORY:
                player_turn_results.extend(
                    player.inventory.use(item,
                                         constants["colors"],
                                         entities=entities,
                                         game_map=game_map))
            elif game_state == GameStates.DROP_INVENTORY:
                player_turn_results.extend(
                    player.inventory.drop_item(item, constants["colors"]))

        if take_stairs and game_state == GameStates.PLAYERS_TURN:
            for entity in entities:
                if entity.stairs and entity.x == player.x and entity.y == player.y:
                    game_map, entities = next_floor(player, message_log,
                                                    entity.stairs.floor,
                                                    constants)
                    fov_recompute = True
                    con.clear()

                    break
            else:
                message_log.add_message(
                    Message("There are no stairs here.",
                            constants["colors"].get("yellow")))

        if level_up:
            if level_up == "hp":
                player.fighter.base_max_hp += 20
                player.fighter.hp += 20
            elif level_up == "str":
                player.fighter.base_power += 1
            elif level_up == "def":
                player.fighter.base_defense += 1

            game_state = previous_game_state

        if show_character_screen:
            previous_game_state = game_state
            game_state = GameStates.CHARACTER_SCREEN

        if game_state == GameStates.TARGETING:
            if left_click:
                target_x, target_y = left_click

                item_use_results = player.inventory.use(targeting_item,
                                                        constants["colors"],
                                                        entities=entities,
                                                        game_map=game_map,
                                                        target_x=target_x,
                                                        target_y=target_y)
                player_turn_results.extend(item_use_results)
            elif right_click:
                player_turn_results.append({"targeting_cancelled": True})

        if exit:
            if game_state in (GameStates.SHOW_INVENTORY,
                              GameStates.DROP_INVENTORY,
                              GameStates.CHARACTER_SCREEN):
                game_state = previous_game_state
            elif game_state == GameStates.TARGETING:
                player_turn_results.append({"targeting_cancelled": True})
            else:
                save_game(player, entities, game_map, message_log, game_state)

                return True

        if fullscreen:
            tdl.set_fullscreen(not tdl.get_fullscreen())

        for player_turn_result in player_turn_results:
            message = player_turn_result.get("message")
            dead_entity = player_turn_result.get("dead")
            item_added = player_turn_result.get("item_added")
            item_consumed = player_turn_result.get("consumed")
            item_dropped = player_turn_result.get("item_dropped")
            equip = player_turn_result.get("equip")
            targeting = player_turn_result.get("targeting")
            targeting_cancelled = player_turn_result.get("targeting_cancelled")
            xp = player_turn_result.get("xp")

            if message:
                message_log.add_message(message)

            if dead_entity:
                if dead_entity == player:
                    message, game_state = kill_player(dead_entity,
                                                      constants["colors"])
                else:
                    message = kill_monster(dead_entity, constants["colors"])

                message_log.add_message(message)

            if item_added:
                entities.remove(item_added)

                game_state = GameStates.ENEMY_TURN

            if item_consumed:
                game_state = GameStates.ENEMY_TURN

            if item_dropped:
                entities.append(item_dropped)

                game_state = GameStates.ENEMY_TURN

            if equip:
                equip_results = player.equipment.toggle_equip(equip)

                for equip_result in equip_results:
                    equipped = equip_result.get("equipped")
                    dequipped = equip_result.get("dequipped")

                    if equipped:
                        message_log.add_message(
                            Message("Equipped {0}.".format(equipped.name)))

                    if dequipped:
                        message_log.add_message(
                            Message("Removed {0}.".format(dequipped.name)))

                game_state = GameStates.ENEMY_TURN

            if targeting:
                previous_game_state = GameStates.PLAYERS_TURN
                game_state = GameStates.TARGETING

                targeting_item = targeting

                message_log.add_message(targeting_item.item.targeting_message)

            if targeting_cancelled:
                game_state = previous_game_state

                message_log.add_message(Message("Targeting cancelled."))

            if xp:
                leveled_up = player.level.add_xp(xp)
                message_log.add_message(
                    Message("{0} experience gained.".format(xp)))

                if leveled_up:
                    #todo take another shot at the level up message
                    message_log.add_message(
                        Message(
                            "Your effort pays off, and you reach level {0}!".
                            format(player.level.current_level),
                            constants["colors"].get("yellow")))
                    previous_game_state = game_state
                    game_state = GameStates.LEVEL_UP

        if game_state == GameStates.ENEMY_TURN:
            for entity in entities:
                if entity.ai:
                    enemy_turn_results = entity.ai.take_turn(
                        player, game_map, entities)

                    for enemy_turn_result in enemy_turn_results:
                        message = enemy_turn_result.get("message")
                        dead_entity = enemy_turn_result.get("dead")

                        if message:
                            message_log.add_message(message)

                        if dead_entity:
                            if dead_entity == player:
                                message, game_state = kill_player(
                                    dead_entity, constants["colors"])
                            else:
                                message = kill_monster(dead_entity,
                                                       constants["colors"])

                            message_log.add_message(message)

                            if game_state == GameStates.PLAYER_DEAD:
                                break

                    if game_state == GameStates.PLAYER_DEAD:
                        break
            else:
                game_state = GameStates.PLAYERS_TURN
Exemple #6
0
def main():
    screen_width = 80
    screen_height = 50

    bar_width = 20
    panel_height = 7
    panel_y = screen_height - panel_height

    message_x = bar_width + 2
    message_width = screen_width - bar_width - 2
    message_height = panel_height - 1

    map_width = 80
    map_height = 43

    room_max_size = 10
    room_min_size = 6
    max_rooms = 30

    fov_algorithm = 0
    fov_light_walls = True
    fov_radius = 10

    max_monsters_per_room = 3
    max_items_per_room = 2

    colors = {
        'dark_wall': libtcod.Color(0, 0, 100),
        'dark_ground': libtcod.Color(50, 50, 150),
        'light_wall': libtcod.Color(130, 110, 50),
        'light_ground': libtcod.Color(200, 180, 50)
    }

    fighter_component = Fighter(hp=30, defense=2, power=5)
    inventory_component = Inventory(26)
    player = Entity(0,
                    0,
                    '@',
                    libtcod.white,
                    'Player',
                    blocks=True,
                    fighter=fighter_component,
                    render_order=RenderOrder.ACTOR,
                    inventory=inventory_component)
    entities = [player]

    libtcod.console_set_custom_font(
        'arial10x10.png',
        libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD)

    libtcod.console_init_root(screen_width, screen_height, 'Game', False)

    con = libtcod.console_new(screen_width, screen_height)
    panel = libtcod.console_new(screen_width, panel_height)

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

    fov_recompute = True

    fov_map = initialize_fov(game_map)

    message_log = MessageLog(message_x, message_width, message_height)

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

    game_state = GameStates.PLAYERS_TURN
    prev_game_state = game_state

    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.x, player.y, fov_radius,
                          fov_light_walls, fov_algorithm)

        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)

        fov_recompute = False

        libtcod.console_flush()

        clear_all(con, entities)

        action = handle_keys(key, game_state)

        move = action.get('move')
        pickup = action.get('pickup')
        show_inventory = action.get('show_inventory')
        inventory_index = action.get('inventory_index')
        exit = action.get('exit')
        fullscreen = action.get('fullscreen')

        player_turn_results = []

        if move and game_state == GameStates.PLAYERS_TURN:
            dx, dy = move
            destination_x = player.x + dx
            destination_y = player.y + dy

            if not game_map.is_blocked(destination_x, destination_y):
                target = get_blocking_entities_at_location(
                    entities, destination_x, destination_y)

                if target:
                    attack_results = player.fighter.attack(target)
                    player_turn_results.extend(attack_results)
                else:
                    player.move(dx, dy)

                #fov_recompute = True
                game_state = GameStates.ENEMY_TURN

        elif pickup and game_state == GameStates.PLAYERS_TURN:
            for entity in entities:
                if entity.item and entity.x == player.x and entity.y == player.y:
                    pickup_results = player.inventory.add_item(entity)
                    player_turn_results.extend(pickup_results)

                    break

                else:
                    message_log.add_message(
                        Message('Nothing here to pick up', libtcod.yellow))

        if show_inventory:
            fov_recompute = True
            prev_game_state = game_state
            game_state = GameStates.SHOW_INVENTORY

        if inventory_index is not None and prev_game_state != GameStates.PLAYER_DEAD and inventory_index < len(
                player.inventory.items):
            item = player.inventory.items[inventory_index]
            player_turn_results.extend(player.inventory.use(item))

        if exit:
            if game_state == GameStates.SHOW_INVENTORY:
                game_state = prev_game_state
                fov_recompute = True
            else:
                return True

        if fullscreen:
            libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())

        for player_turn_result in player_turn_results:
            message = player_turn_result.get('message')
            dead_entity = player_turn_result.get('dead')
            item_added = player_turn_result.get('item_added')
            item_consumed = player_turn_result.get('consumed')

            if message:
                message_log.add_message(message)

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

                message_log.add_message(message)

            if item_added:
                entities.remove(item_added)

                game_state = GameStates.ENEMY_TURN

            if item_consumed:
                game_state = GameStates.ENEMY_TURN

        if game_state == GameStates.ENEMY_TURN:
            for entity in entities:
                if entity.ai:
                    enemy_turn_results = entity.ai.take_turn(
                        player, fov_map, game_map, entities)

                    for enemy_turn_result in enemy_turn_results:
                        message = enemy_turn_result.get('message')
                        dead_entity = enemy_turn_result.get('dead')

                        if message:
                            message_log.add_message(message)
                        if dead_entity:
                            if dead_entity == player:
                                message, game_state = kill_player(dead_entity)
                            else:
                                message = kill_monster(dead_entity)

                            message_log.add_message(message)

                            if game_state == GameStates.PLAYER_DEAD:
                                break

                    if game_state == GameStates.PLAYER_DEAD:
                        fov_recompute = True
                        break

            else:
                game_state = GameStates.PLAYERS_TURN
                fov_recompute = True
Exemple #7
0
def main():
    # set main game window size
    screen_width = 80
    screen_height = 60

    bar_width = 20
    panel_height = 7
    panel_y = screen_height - panel_height

    message_x = bar_width + 2
    message_width = screen_width - bar_width - 2
    message_height = panel_height - 1

    map_width = 80
    map_height = 53

    room_max_size = 10
    room_min_size = 6
    max_rooms = 30

    fov_algorithm = 'PERMISSIVE'
    fov_light_walls = True
    fov_radius = 10

    max_monsters_per_room = 3

    colors = {
        'dark_wall': (26, 26, 26),
        'dark_ground': (51, 51, 51),
        'light_wall': (26, 20, 13),
        'light_ground': (51, 41, 26),
        'desaturated_green': (63, 127, 63),
        'darker_green': (0, 127, 0),
        'dark_red': (191, 0, 0),
        'white': (255, 255, 255),
        'black': (0, 0, 0),
        'red': (255, 0, 0),
        'orange': (255, 127, 0),
        'light_red': (255, 114, 114),
        'darker_red': (127, 0, 0)
    }

    fighter_component = Fighter(hp=30, defence=2, power=5)
    player = Entity(0,
                    0,
                    '@', (128, 102, 64),
                    'Player',
                    blocks=True,
                    render_order=RenderOrder.ACTOR,
                    fighter=fighter_component)
    entities = [player]

    # Font differs from one in tutorial as I use this ti work in REXpaint
    tdl.set_font('cp437_12x12.png', greyscale=True, altLayout=False)

    # Main game window
    root_console = tdl.init(screen_width,
                            screen_height,
                            title='MFRL revised tutorial')
    con = tdl.Console(screen_width, screen_height)
    panel = tdl.Console(screen_width, panel_height)

    game_map = GameMap(map_width, map_height)
    make_map(game_map, max_rooms, room_min_size, room_max_size, map_width,
             map_height, player, entities, max_monsters_per_room, colors)

    fov_recompute = True

    message_log = MessageLog(message_x, message_width, message_height)

    mouse_coordinates = (0, 0)

    game_state = GameStates.PLAYERS_TURN

    while not tdl.event.is_window_closed():
        if fov_recompute:
            game_map.compute_fov(player.x,
                                 player.y,
                                 fov=fov_algorithm,
                                 radius=fov_radius,
                                 light_walls=fov_light_walls)

        render_all(con, panel, entities, player, game_map, fov_recompute,
                   root_console, message_log, screen_width, screen_height,
                   bar_width, panel_height, panel_y, mouse_coordinates, colors)

        # And draw it all
        tdl.flush()

        clear_all(con, entities)

        fov_recompute = False

        for event in tdl.event.get():
            if event.type == 'KEYDOWN':
                user_input = event
                break
            elif event.type == 'MOUSEMOTION':
                mouse_coordinates = event.cell
        else:
            user_input = None
        '''
        As in tutorial:
        Python has a lesser-known feature where you can put an 'else' statement
        after a for loop, and that else statement only executes
        if we didn't break out of the loop!
        So in this scenario, if we didn't encounter any 'KEYDOWN' event,
        then we set user_input to None by default.
        '''

        if not user_input:
            continue

        action = handle_keys(user_input)

        move = action.get('move')
        exit_game = action.get('exit')
        fullscreen = action.get('fullscreen')

        player_turn_results = []

        if move and game_state == GameStates.PLAYERS_TURN:
            dx, dy = move
            destination_x = player.x + dx
            destination_y = player.y + dy

            if game_map.walkable[destination_x, destination_y]:
                target = get_blocking_entities_at_location(
                    entities, destination_x, destination_y)

                if target:
                    attack_results = player.fighter.attack(target)
                    player_turn_results.extend(attack_results)
                else:
                    player.move(dx, dy)

                    fov_recompute = True

                game_state = GameStates.ENEMY_TURN

        if exit_game:
            return True  # Exit main loop and the game

        if fullscreen:
            tdl.set_fullscreen(not tdl.get_fullscreen())

        for player_turn_result in player_turn_results:
            message = player_turn_result.get('message')
            dead_entity = player_turn_result.get('dead')

            if message:
                message_log.add_message(message)

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

                message_log.add_message(message)

        if game_state == GameStates.ENEMY_TURN:
            for entity in entities:
                if entity.ai:
                    enemy_turn_results = entity.ai.take_turn(
                        player, game_map, entities)

                    for enemy_turn_result in enemy_turn_results:
                        message = enemy_turn_result.get('message')
                        dead_entity = enemy_turn_result.get('dead')

                        if message:
                            message_log.add_message(message)

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

                            message_log.add_message(message)

                            if game_state == GameStates.PLAYER_DEAD:
                                break

                    if game_state == GameStates.PLAYER_DEAD:
                        break
            else:
                game_state = GameStates.PLAYERS_TURN
Exemple #8
0
def hunt_target(curr_actor, entities, game_map) -> list or str:
    astar = pathfind.AStar(game_map)
    enemies = []
    closest_coords = []
    closest_dist = None
    path = None
    command = {'End Turn': 'End Turn'}

    for entity in entities:
        if entity is not curr_actor:
            if (entity.x, entity.y) in curr_actor.fighter.fov_visible:
                if global_vars.debug: print(entity.name + ' is visible')
                enemies.append(entity)
    if len(enemies) != 0:
        for enemy in enemies:
            dist = sum(
                ((abs(enemy.x - curr_actor.x)), (abs(enemy.y - curr_actor.y))))
            if closest_dist is None or dist < closest_dist:
                closest_dist = dist
                closest_coords = [enemy.x, enemy.y]
                closest_enemy = enemy
    else:
        #See if there's a known loc for an enemy in history
        if len(curr_actor.fighter.ai.target_memory) > 0:
            for entry in curr_actor.fighter.ai.target_memory:
                x, y = entry.get('last_loc')
                dist = sum(((abs(x - curr_actor.x)), (abs(y - curr_actor.y))))
                if closest_dist is None or dist < closest_dist:
                    closest_dist = dist
                    closest_coords = [x, y]
                    closest_enemy = entry.get('target')
        else:
            command = random_hunt(curr_actor, entities, game_map)

    if closest_dist is not None:
        path = astar.get_path(curr_actor.x, curr_actor.y, closest_coords[0],
                              closest_coords[1])
        if len(path) == 0:  #What to do if you reached the last known loc?
            if (closest_enemy.x,
                    closest_enemy.y) in curr_actor.fighter.fov_visible:
                path = astar.get_path(curr_actor.x, curr_actor.y,
                                      closest_enemy.x, closest_enemy.y)
            else:
                for entry in curr_actor.fighter.ai.target_memory:
                    if entry.get('target') == closest_enemy:
                        curr_actor.fighter.ai.target_memory.remove(entry)
                        command = random_hunt(curr_actor, entities, game_map)
    try:
        if len(path) > 1:
            y_dir = None
            x_dir = None
            x, y = path[0]
            x_mod = x - curr_actor.x
            y_mod = y - curr_actor.y

            if y_mod == -1: y_dir = 'n'
            if y_mod == 1: y_dir = 's'
            if x_mod == -1: x_dir = 'w'
            if x_mod == 1: x_dir = 'e'
            if x_dir is not None and y_dir is not None:
                mv_dir = str(y_dir + x_dir)
            elif y_dir is not None:
                mv_dir = y_dir
            else:
                mv_dir = x_dir
            command = {'move': mv_dir}

        elif len(path) == 1:
            if get_blocking_entities_at_location(
                    entities, closest_coords[0],
                    closest_coords[1]) is not None:
                #Spin to closest enemy
                if len(curr_actor.fighter.targets) == 0:
                    angle = entity_angle(closest_enemy, curr_actor)
                    if angle <= 180: command = {'spin': 'ccw'}
                    else: command = {'spin': 'cw'}
    except:
        pass

    return command
def main():
    screen_width = 80
    screen_height = 50
    map_width = screen_width
    map_height = screen_height - 5

    room_max_size = 10
    room_min_size = 6
    max_rooms = 30

    fov_algorithm = 0
    fov_light_walls = True
    fov_radius = 10

    max_monsters_per_room = 3

    colors = {
        'dark_wall': libtcod.Color(0, 0, 100),
        'dark_ground': libtcod.Color(50, 50, 150),
        'light_wall': libtcod.Color(130, 110, 50),
        'light_ground': libtcod.Color(200, 180, 500),
    }

    player = Entity(screen_width // 2,
                    screen_height // 2,
                    '@',
                    libtcod.white,
                    'Player',
                    blocks=True)
    entities = [player]

    libtcod.console_set_custom_font(
        'dejavu10x10_gs_tc.png',
        libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD)

    libtcod.console_init_root(screen_width, screen_height,
                              'libtcod tutorial revised', False)

    con = libtcod.console_new(screen_width, screen_height)

    game_map = GameMap(map_width, map_height)
    game_map.make_map(max_rooms, room_min_size, room_max_size, map_width,
                      map_height, player, entities, max_monsters_per_room)

    fov_recompute = True

    fov_map = initialize_fov(game_map)

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

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

        if fov_recompute:
            recompute_fov(fov_map, player.x, player.y, fov_radius,
                          fov_light_walls, fov_algorithm)

        render_all(con, entities, game_map, fov_map, fov_recompute,
                   screen_width, screen_height, colors)

        fov_recompute = False

        libtcod.console_flush()

        clear_all(con, entities)

        action = handle_keys(key)

        move = action.get('move')
        exit = action.get('exit')
        fullscreen = action.get('fullscreen')

        if move:
            dx, dy = move

            destination_x = player.x + dx
            destination_y = player.y + dy

            if not game_map.is_blocked(destination_x, destination_y):
                target = get_blocking_entities_at_location(
                    entities, destination_x, destination_y)

                if target:
                    print(
                        'You kick the {} in the shins, much to its cansternation!'
                        .format(target.name))
                else:
                    player.move(dx, dy)
                    fov_recompute = True

        if exit:
            return True

        if fullscreen:
            libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())
Exemple #10
0
def play_game(player, entities, game_map, message_log, game_state, con, panel, constants, priority_queue, global_variables, world):
    fov_recompute = True

    fov_map = initialize_fov(game_map)

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

    # Variables used to make decisions during the game.
    targeting_item = None
    previous_game_state = game_state

    # Turn on camera.
    camera = Camera(constants['camera_width'], constants['camera_height'], player.x, player.y, constants['map_width'], constants['map_height'])

    # Actviate cursor.
    cursor = Cursor()

    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.x, player.y, constants['fov_radius'], constants['fov_light_walls'], constants['fov_algorithm'])

        # Only render and recompute FOV while on the player's turn.
        if not game_state == GameStates.ENEMY_TURN:
            render_all(con, panel, entities, player, 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'], game_state,
                    camera, cursor)

            fov_recompute = False

            libtcod.console_flush()

            # The console is cleared, but it will only be flushed on the player's turn. 
            clear_all(con, entities, camera.x, camera.y, cursor)

        action = handle_keys(key, game_state)
        mouse_action = handle_mouse(mouse)

        enemy = None # If it's not the player's turn, it's _this_ enemy's turn.

        # Decide the entity's turn.
        if not priority_queue.empty() and game_state == GameStates.ENEMY_TURN:
            queue_ID = priority_queue.get_ID() # This removes the topmost ID from the queue.
            for entity in entities:
                if queue_ID == entity.ID and not entity.is_dead(): # If the entity is dead, do nothing. It has already been removed from the queue.
                    if entity.ai == None: #it's the player
                        # The player gets reinserted into the queue after their action.
                        game_state = GameStates.PLAYERS_TURN
                        break
                    else:
                        # The enemy gets reinserted into the queue after their action.
                        enemy = entity
                        break

        """

        List of possible actions taken by the player.
        TODO: Cut things up via GameState more clearly.

        """
        move = action.get('move')
        wait = action.get('wait')
        pickup = action.get('pickup')
        show_inventory = action.get('show_inventory')
        drop_inventory = action.get('drop_inventory')
        inventory_index = action.get('inventory_index')
        exit = action.get('exit')
        fullscreen = action.get('fullscreen')
        level_up = action.get('level_up')
        show_character_screen = action.get('show_character_screen')
        show_extract_materia_menu = action.get('show_extract_materia_menu') # Prompt the player to extra materia from creature.
        extraction_index = action.get('extraction_index')                   # Select this entry from the extraction menu.
        look = action.get('look')                                           # Enter the LOOK GameState.
        select = action.get('select')                                       # A target has been selected via keyboard.

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

        player_turn_results = []

        if move and game_state == GameStates.PLAYERS_TURN:
            # TODO: Prevent player from moving outside the map.
            dx, dy = move
            destination_x = player.x + dx
            destination_y = player.y + dy

            if not game_map.is_blocked(destination_x, destination_y):
                target = get_blocking_entities_at_location(entities, destination_x, destination_y)

                if target:
                    attack_results = player.fighter.attack(target)
                    player_turn_results.extend(attack_results)
                else:
                    # Check to see if the player is lined up with the center.
                    # If so, move the camera with the player.
                    camera_x, camera_y = camera.absolute_center()
                    if player.x == camera_x:
                        camera.move(dx, 0)
                    if player.y == camera_y:
                        camera.move(0, dy)
                    
                    player.move(dx, dy)
                    
                    fov_recompute = True

                priority_queue.put(player.fighter.speed, player.ID) # The player spends their turn to move/attack.
                game_state = GameStates.ENEMY_TURN

        elif move and game_state == GameStates.LOOK:
            # Move the cursor.
            dx, dy = move
            cursor.move(dx, dy, constants['camera_width'], constants['camera_height'], camera.x, camera.y)

        elif wait and game_state == GameStates.PLAYERS_TURN:
            # Puts the player second in queue. 
            priority_queue.put_next(player.ID)
            game_state = GameStates.ENEMY_TURN

        elif pickup and game_state == GameStates.PLAYERS_TURN:
            for entity in entities:
                if entity.item and entity.x == player.x and entity.y == player.y:
                    pickup_results = player.inventory.add_item(entity)
                    player_turn_results.extend(pickup_results)
                    priority_queue.put(player.fighter.speed, player.ID) # The player spends their turn picking up stuff.
                    game_state = GameStates.ENEMY_TURN

                    break
            else:
                message_log.add_message(Message('There is nothing here to pick up.', libtcod.yellow))

        if show_inventory and game_state == GameStates.PLAYERS_TURN:
            previous_game_state = game_state
            game_state = GameStates.SHOW_INVENTORY

        if drop_inventory and game_state == GameStates.PLAYERS_TURN:
            previous_game_state = game_state
            game_state = GameStates.DROP_INVENTORY

        if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len(player.inventory.items):
            item = player.inventory.items[inventory_index]
            if game_state == GameStates.SHOW_INVENTORY:
                player_turn_results.extend(player.inventory.use(item))
            elif game_state == GameStates.DROP_INVENTORY:
                player_turn_results.extend(player.inventory.drop_item(item))
       
        if game_state == GameStates.TARGETING:
            # Mouse targeting
            if left_click:
                target_x, target_y = left_click
                target_x += camera.x
                target_y += camera.y

                item_use_results = player.inventory.use(targeting_item, entities=entities, fov_map=fov_map, target_x=target_x, target_y=target_y)
                player_turn_results.extend(item_use_results)
            elif right_click:
                player_turn_results.append({'targeting_cancelled': True})

            # Keyboard targeting
            if move:
                # Move the cursor.
                dx, dy = move
                cursor.move(dx, dy, constants['camera_width'], constants['camera_height'], camera.x, camera.y)
            
            if select:
                # Hit the chosen target.
                target_x, target_y = cursor.x, cursor.y

                item_use_results = player.inventory.use(targeting_item, entities=entities, fov_map=fov_map, target_x=target_x, target_y=target_y)
                player_turn_results.extend(item_use_results)
        
        if exit:
            if game_state in (GameStates.SHOW_INVENTORY, GameStates.DROP_INVENTORY, GameStates.CHARACTER_SCREEN, GameStates.MATERIA_SCREEN, GameStates.LOOK):
                game_state = previous_game_state
            elif game_state == GameStates.TARGETING:
                player_turn_results.append({'targeting_cancelled': True})
            else:
                save_game(player, entities, game_map, message_log, game_state, priority_queue, global_variables, world)
                return True

        if fullscreen:
            libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())

        if level_up:
            if level_up == 'hp':
                player.fighter.max_hp += 20
                player.fighter.hp += 20
            elif level_up == 'str':
                player.fighter.power += 1
            elif level_up == 'def':
                player.fighter.defense += 1

            game_state = previous_game_state

        if show_character_screen and game_state == GameStates.PLAYERS_TURN:
            previous_game_state = game_state
            game_state = GameStates.CHARACTER_SCREEN

        if show_extract_materia_menu and game_state == GameStates.PLAYERS_TURN:
            previous_game_state = game_state
            game_state = GameStates.MATERIA_SCREEN

        if extraction_index is not None and previous_game_state != GameStates.PLAYER_DEAD:
            # Create the list of items that have materia
            item_list = player.inventory.item_list_with_property('materia')
            # Check to see the index is inside this list
            if extraction_index < len(item_list):
                # Create an item called "type Materia (lvl n)"
                extracting_item = item_list[extraction_index] # This is the pokeball entity.
                materia_type = extracting_item.item.caught_entity.materia[0]
                materia_level = extracting_item.item.caught_entity.materia[1]
                materia_name = materia_type.capitalize() + ' Materia (lvl ' + str(materia_level) + ')'
                
                item_component = Item(use_function=item_functions.materia, type=materia_type, level=materia_level)
                materia_item = Entity(0, 0, '*', libtcod.white, materia_name, global_variables.get_new_ID(), RenderOrder.ITEM, item=item_component)

                # Add it to the inventory
                player.inventory.add_item(materia_item)
                entities.append(materia_item)

                # Remove the entity from which it came from the parent entity holding it
                extracting_item.item.caught_entity = None
                # Return the pokeball to a "catch" mode instead of release.
                # TODO: There are now two instances of switching the pokeball from one function to another. Consider moving this inside the Item class.
                extracting_item.item.swap_messages()
                extracting_item.item.use_function = item_functions.catch
        
        if look:
            previous_game_state = game_state
            cursor.x, cursor.y = player.x, player.y
            game_state = GameStates.LOOK

        """

        List of possible results from actions taken by the player.

        """
        for player_turn_result in player_turn_results:
            message = player_turn_result.get('message')
            dead_entity = player_turn_result.get('dead')
            item_added = player_turn_result.get('item_added')
            item_consumed = player_turn_result.get('consumed')
            item_dropped = player_turn_result.get('item_dropped')
            targeting = player_turn_result.get('targeting')
            targeting_cancelled = player_turn_result.get('targeting_cancelled')
            thrown = player_turn_result.get('thrown')                               # This item was thrown. Returns the item entity.
            catch = player_turn_result.get('catch')                                 # This item catches pokemon. Returns the caught entity.
            release = player_turn_result.get('release')                             # This item released pokemon. Returns the released entity.
            xp = player_turn_result.get('xp')

            if message:
                message_log.add_message(message)

            if dead_entity:
                if dead_entity == player:
                    message, game_state = kill_player(dead_entity)
                else:
                    message = kill_monster(dead_entity)
                message_log.add_message(message)

            if item_added:
                entities.remove(item_added)

            if item_consumed:
                # Removed from inventory in inventory.py
                pass

            if item_dropped:
                entities.append(item_dropped)

            if targeting:
                previous_game_state = GameStates.PLAYERS_TURN
                game_state = GameStates.TARGETING
                
                cursor.x, cursor.y = player.x, player.y

                targeting_item = targeting

                message_log.add_message(targeting_item.item.targeting_message)

            if targeting_cancelled:
                game_state = previous_game_state

                message_log.add_message(Message('Targeting cancelled'))

            if thrown:
                # Removed from inventory in inventory.py
                thrown.x, thrown.y = player_turn_result.get('target_xy')
                entities.append(thrown)
                game_state = GameStates.PLAYERS_TURN

            if catch:
                entities.remove(catch)

            if release:
                release.x, release.y = player_turn_result.get('target_xy')
                entities.append(release)
                priority_queue.put(release.fighter.speed, release.ID)
            
            if xp:
                leveled_up = player.level.add_xp(xp)
                message_log.add_message(Message('You gain {0} experience points.'.format(xp)))

                if leveled_up:
                    message_log.add_message(Message(
                        'Your battle skills grow stronger! You reached level {0}'.format(player.level.current_level) + '!', libtcod.yellow))
                    previous_game_state = game_state
                    game_state = GameStates.LEVEL_UP

        if game_state == GameStates.ENEMY_TURN and enemy:
            enemy_turn_results = enemy.ai.take_turn(player, fov_map, game_map, entities)

            for enemy_turn_result in enemy_turn_results:
                message = enemy_turn_result.get('message')
                dead_entity = enemy_turn_result.get('dead')

                if message:
                    message_log.add_message(message)

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

                    message_log.add_message(message)

                    if game_state == GameStates.PLAYER_DEAD:
                        break

            if game_state == GameStates.PLAYER_DEAD:
                break

            elif not enemy.ai == None:
                priority_queue.put(enemy.fighter.speed, enemy.ID)
Exemple #11
0
def play_game(player, entities, game_map, message_log, game_state, con, panel,
              constants):
    fov_recompute = True

    fov_map = initialize_fov(game_map)

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

    if not game_state == GameStates.PLAYER_DEAD:
        game_state = GameStates.PLAYERS_TURN

    previous_game_state = game_state

    targeting_item = None

    if not game_state == GameStates.PLAYER_DEAD:
        PLAYERDEADSTATE = False
    else:
        PLAYERDEADSTATE = True

    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.x, player.y, constants['fov_radius'],
                          constants['fov_light_walls'],
                          constants['fov_algorithm'])

        render_all(con, panel, entities, player, 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'], constants['kill_count'], game_state,
                   constants['wall_tile'], constants['floor_tile'])

        fov_recompute = False

        libtcod.console_flush()

        clear_all(con, entities)

        action = handle_keys(key, game_state)
        mouse_action = handle_mouse(mouse)

        move = action.get('move')
        wait = action.get('wait')
        pickup = action.get('pickup')
        show_inventory = action.get('show_inventory')
        drop_inventory = action.get('drop_inventory')
        drop_equipment = action.get('drop_equipment')
        show_equipment_inventory = action.get('show_equipment_inventory')
        show_bag = action.get('show_bag')
        inventory_index = action.get('inventory_index')
        equipment_inventory_index = action.get('equipment_inventory_index')
        take_stairs = action.get('take_stairs')
        level_up = action.get('level_up')
        show_character_screen = action.get('show_character_screen')
        show_help_menu = action.get('show_help_menu')
        exit = action.get('exit')
        exit_quit_menu = action.get('exit_quit_menu')
        fullscreen = action.get('fullscreen')
        cast_magic_wand = action.get('cast_magic_wand')
        drop_menu = action.get('drop_menu')
        sell_menu = action.get('sell_menu')
        sell_equipment_menu = action.get('sell_equipment_menu')
        buy_menu = action.get('buy_menu')
        buy_equipment_menu = action.get('buy_equipment_menu')
        shop_menu = action.get('shop_menu')
        shop_menu_index = action.get('shop_menu_index')
        shop_equipment_menu_index = action.get('shop_equipment_menu_index')

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

        player_turn_results = []

        if move and game_state == GameStates.PLAYERS_TURN:
            dx, dy = move
            destination_x = player.x + dx
            destination_y = player.y + dy

            if not game_map.is_blocked(destination_x, destination_y):
                target = get_blocking_entities_at_location(
                    entities, destination_x, destination_y)

                if target:
                    attack_results = player.fighter.attack(target,
                                                           constants,
                                                           entities=entities)
                    #playsound('sounds/attack.m4a', block=False)
                    player_turn_results.extend(attack_results)
                else:
                    player.move(dx, dy)

                    fov_recompute = True

                game_state = GameStates.ENEMY_TURN

        elif wait:
            game_state = GameStates.ENEMY_TURN

        elif pickup and game_state == GameStates.PLAYERS_TURN:
            for entity in entities:
                if entity.item and (
                        not entity.equippable
                ) and entity.x == player.x and entity.y == player.y:
                    pickup_results = player.inventory.add_item(entity)
                    player_turn_results.extend(pickup_results)

                    break

                elif entity.item and entity.x == player.x and entity.y == player.y:
                    pickup_results = player.equipment_inventory.add_item(
                        entity)
                    player_turn_results.extend(pickup_results)

                    break
            else:
                message_log.add_message(
                    Message("There is nothing here to pick up...",
                            libtcod.yellow))

        if show_inventory:
            previous_game_state = game_state
            game_state = GameStates.SHOW_INVENTORY

        if show_equipment_inventory:
            previous_game_state = game_state
            game_state = GameStates.SHOW_EQUIPMENT_INVENTORY

        if drop_inventory:
            previous_game_state = game_state
            game_state = GameStates.DROP_INVENTORY

        if drop_equipment:
            previous_game_state = game_state
            game_state = GameStates.DROP_EQUIPMENT

        if show_bag:
            previous_game_state = game_state
            game_state = GameStates.SHOW_BAG

        if drop_menu:
            previous_game_state = game_state
            game_state = GameStates.DROP_MENU

        if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len(
                player.inventory.items):
            item = player.inventory.items[inventory_index]

            if game_state == GameStates.SHOW_INVENTORY:
                player_turn_results.extend(
                    player.inventory.use(item,
                                         entities=entities,
                                         fov_map=fov_map))
            elif game_state == GameStates.DROP_INVENTORY:
                player_turn_results.extend(player.inventory.drop_item(item))
            elif game_state == GameStates.SELL_MENU:
                player_turn_results.extend(
                    player.inventory.sell(item, game_state))

        if equipment_inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and equipment_inventory_index < len(
                player.equipment_inventory.items):
            equip_item = player.equipment_inventory.items[
                equipment_inventory_index]

            if game_state == GameStates.SHOW_EQUIPMENT_INVENTORY:
                player_turn_results.extend(
                    player.equipment_inventory.use(equip_item))
            elif game_state == GameStates.DROP_EQUIPMENT:
                player_turn_results.extend(
                    player.equipment_inventory.drop_item(equip_item))
            elif game_state == GameStates.SELL_EQUIPMENT_MENU:
                player_turn_results.extend(
                    player.equipment_inventory.sell(equip_item, game_state))

        if shop_menu_index is not None and previous_game_state != GameStates.PLAYER_DEAD:
            item = game_map.shop_items[shop_menu_index]

            if game_state == GameStates.BUY_MENU:
                player_turn_results.extend(
                    player.inventory.buy(item, game_state))

        if shop_equipment_menu_index is not None and previous_game_state != GameStates.PLAYER_DEAD:
            item = game_map.shop_equipment_items[shop_equipment_menu_index]

            if game_state == GameStates.BUY_EQUIPMENT_MENU:
                player_turn_results.extend(
                    player.equipment_inventory.buy(item, game_state))

        if take_stairs and game_state == GameStates.PLAYERS_TURN:
            for entity in entities:
                if entity.stairs and entity.x == player.x and entity.y == player.y:
                    entities = game_map.next_floor(player, message_log,
                                                   constants)
                    fov_map = initialize_fov(game_map)
                    fov_recompute = True
                    libtcod.console_clear(con)

                    break
            else:
                message_log.add_message(
                    Message("There are no stairs here...", libtcod.yellow))

        if cast_magic_wand and game_state == GameStates.PLAYERS_TURN:
            wand = player.inventory.search("Magic Wand")
            staff = player.inventory.search("Wizard Staff")
            if wand is None and staff is None:
                message_log.add_message(
                    Message("You cannot cast magic without a magic item!",
                            libtcod.orange))
            else:
                player_turn_results.extend(
                    player.inventory.use(wand,
                                         entities=entities,
                                         fov_map=fov_map))

                game_state = GameStates.ENEMY_TURN

        if level_up:
            if level_up == 'hp':
                player.fighter.base_max_hp += 20
                player.fighter.hp += 20
                message_log.add_message(
                    Message("You leveled up your HP!", libtcod.light_cyan))
            elif level_up == 'str':
                player.fighter.base_power += 1
                message_log.add_message(
                    Message("You leveled up your ATTACK!", libtcod.light_cyan))
            elif level_up == 'def':
                player.fighter.base_defense += 1
                message_log.add_message(
                    Message("You leveled up your DEFENSE!",
                            libtcod.light_cyan))
            elif level_up == 'mgk':
                player.fighter.base_magic += 1
                message_log.add_message(
                    Message("You leveled up your MAGIC!", libtcod.light_cyan))
            elif level_up == 'mgk_def':
                player.fighter.base_magic_defense += 1
                message_log.add_message(
                    Message("You leveled up your MAGIC RESISTANCE!",
                            libtcod.light_cyan))

            game_state = previous_game_state

        if show_character_screen:
            previous_game_state = game_state
            game_state = GameStates.CHARACTER_SCREEN

        if show_help_menu:
            previous_game_state = game_state
            game_state = GameStates.HELP_MENU

        if sell_menu:
            previous_game_state = game_state
            game_state = GameStates.SELL_MENU

        if sell_equipment_menu:
            previous_game_state = game_state
            game_state = GameStates.SELL_EQUIPMENT_MENU

        if buy_menu:
            previous_game_state = game_state
            game_state = GameStates.BUY_MENU

        if buy_equipment_menu:
            previous_game_state = game_state
            game_state = GameStates.BUY_EQUIPMENT_MENU

        if shop_menu:
            previous_game_state = game_state
            game_state = GameStates.SHOP_MENU

        if game_state == GameStates.TARGETING:
            if left_click:
                target_x, target_y = left_click

                item_use_results = player.inventory.use(targeting_item,
                                                        entities=entities,
                                                        fov_map=fov_map,
                                                        target_x=target_x,
                                                        target_y=target_y)
                player_turn_results.extend(item_use_results)
            elif right_click:
                player_turn_results.append({'targeting_cancelled': True})

        if exit:
            if game_state in (GameStates.SHOW_INVENTORY,
                              GameStates.DROP_INVENTORY,
                              GameStates.DROP_EQUIPMENT,
                              GameStates.CHARACTER_SCREEN,
                              GameStates.HELP_MENU,
                              GameStates.SHOW_EQUIPMENT_INVENTORY,
                              GameStates.SELL_MENU, GameStates.BUY_MENU,
                              GameStates.SELL_EQUIPMENT_MENU,
                              GameStates.BUY_EQUIPMENT_MENU):
                game_state = previous_game_state
            elif game_state == GameStates.TARGETING:
                player_turn_results.append({'targeting_cancelled': True})
            elif game_state == GameStates.SHOW_BAG:
                if PLAYERDEADSTATE == True:
                    game_state = GameStates.PLAYER_DEAD
                else:
                    game_state = GameStates.PLAYERS_TURN
            elif game_state == GameStates.SHOP_MENU:
                if PLAYERDEADSTATE == True:
                    game_state = GameStates.PLAYER_DEAD
                else:
                    game_state = GameStates.PLAYERS_TURN
            elif game_state == GameStates.PLAYERS_TURN:
                game_state = GameStates.QUIT_MENU
            elif game_state == GameStates.DROP_MENU:
                game_state = GameStates.PLAYERS_TURN
            else:
                save_game(player, entities, game_map, message_log, game_state)

                return True

        if exit_quit_menu:
            if game_state == GameStates.QUIT_MENU:
                game_state = previous_game_state

        if fullscreen:
            libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())

        for player_turn_result in player_turn_results:
            message = player_turn_result.get('message')
            dead_entity = player_turn_result.get('dead')
            item_added = player_turn_result.get('item_added')
            equipment_item_added = player_turn_result.get(
                'equipment_item_added')
            item_consumed = player_turn_result.get('consumed')
            equipment_consumed = player_turn_result.get('equipment_consumed')
            item_dropped = player_turn_result.get('item_dropped')
            loot_dropped = player_turn_result.get('loot_dropped')
            staff_used = player_turn_result.get('staff_used')
            equip = player_turn_result.get('equip')
            targeting = player_turn_result.get('targeting')
            targeting_cancelled = player_turn_result.get('targeting_cancelled')
            xp = player_turn_result.get('xp')
            item_bought = player_turn_result.get('item_bought')
            equipment_bought = player_turn_result.get('equipment_bought')

            if message:
                message_log.add_message(message)

            if targeting_cancelled:
                game_state = previous_game_state

                message_log.add_message(Message('Targeting cancelled'))

            if xp:
                leveled_up = player.level.add_xp(xp)
                message_log.add_message(
                    Message("You gain {0} experience points.".format(xp)))

                if leveled_up:
                    message_log.add_message(
                        Message(
                            "Your battle prowess grows stronger! You reached level {0}!"
                            .format(player.level.current_level),
                            libtcod.yellow))
                    previous_game_state = game_state
                    game_state = GameStates.LEVEL_UP

            if dead_entity:
                if dead_entity == player:
                    PLAYERDEADSTATE = True
                    message, game_state = kill_player(dead_entity, constants)
                    message_log.add_message(message)
                else:
                    monster_name = ''
                    monster_name = dead_entity.name
                    message = kill_monster(dead_entity, player, constants)
                    constants['kill_count'] += 1
                    message_log.add_message(message)

                    while dead_entity.inventory.items:
                        item = dead_entity.inventory.items[0]
                        dead_entity.inventory.loot_item(item)
                        entities.append(item)
                        message_log.add_message(
                            Message(
                                "The {0} dropped the {1}.".format(
                                    monster_name, item.name), libtcod.yellow))

            if item_added:
                entities.remove(item_added)

                game_state = GameStates.ENEMY_TURN

            if equipment_item_added:
                entities.remove(equipment_item_added)

                game_state = GameStates.ENEMY_TURN

            if item_consumed:
                game_state = GameStates.ENEMY_TURN

            if item_bought:
                game_map.shop_items.remove(item_bought)

                game_state = GameStates.ENEMY_TURN

            if equipment_bought:
                game_map.shop_equipment_items.remove(equipment_bought)

                game_state = GameStates.ENEMY_TURN

            if equipment_consumed:
                game_state = GameStates.ENEMY_TURN

            if staff_used:
                game_state = GameStates.ENEMY_TURN

            if targeting:
                previous_game_state = GameStates.PLAYERS_TURN
                game_state = GameStates.TARGETING

                targeting_item = targeting

                message_log.add_message(targeting_item.item.targeting_message)

            if item_dropped:
                entities.append(item_dropped)

                game_state = GameStates.ENEMY_TURN

            if loot_dropped:
                entities.append(loot_dropped)

                game_state = GameStates.ENEMY_TURN

            if equip:
                equip_results = player.equipment.toggle_equip(equip)

                for equip_result in equip_results:
                    equipped = equip_result.get('equipped')
                    dequipped = equip_result.get('dequipped')

                    if equipped:
                        message_log.add_message(
                            Message("You equipped the {0}".format(
                                equipped.name)))

                    if dequipped:
                        message_log.add_message(
                            Message("You dequipped the {0}".format(
                                dequipped.name)))

                game_state = GameStates.ENEMY_TURN

        if game_state == GameStates.ENEMY_TURN:
            fov_recompute = True
            for entity in entities:
                if entity.ai:
                    enemy_turn_results = entity.ai.take_turn(
                        player, fov_map, game_map, entities, constants)

                    for enemy_turn_result in enemy_turn_results:
                        message = enemy_turn_result.get('message')
                        dead_entity = enemy_turn_result.get('dead')

                        if message:
                            message_log.add_message(message)

                        if dead_entity:
                            if dead_entity == player:
                                PLAYERDEADSTATE = True
                                message, game_state = kill_player(
                                    dead_entity, constants)
                                message_log.add_message(message)
                            else:
                                monster_name = ''
                                monster_name = dead_entity.name
                                message = kill_monster(dead_entity, player,
                                                       constants)
                                constants['kill_count'] += 1
                                message_log.add_message(message)

                                while dead_entity.inventory.items:
                                    item = dead_entity.inventory.items[0]
                                    dead_entity.inventory.loot_item(item)
                                    entities.append(item)
                                    message_log.add_message(
                                        Message(
                                            "The {0} dropped the {1}.".format(
                                                monster_name, item.name),
                                            libtcod.yellow))

                            if game_state == GameStates.PLAYER_DEAD:
                                break
                    if game_state == GameStates.PLAYER_DEAD:
                        break
            else:
                game_state = GameStates.PLAYERS_TURN
Exemple #12
0
def play_game(player, entities, game_map, message_log, game_state, con, panel,
              constants, camera):

    fov_recompute = True
    fov_map = initalize_fov(game_map)

    camera.update(player)

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

    previous_game_state = game_state

    targeting_item = None

    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.x, player.y, constants['fov_radius'],
                          constants['fov_light_walls'],
                          constants['fov_algorithm'])

        render_all(con, panel, entities, player, 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'], game_state, camera)
        fov_recompute = False

        libtcod.console_flush()

        clear_all(con, entities, camera)

        action = handle_keys(key, game_state)
        mouse_action = handle_mouse(mouse)

        move = action.get('move')
        wait = action.get('wait')
        pickup = action.get('pickup')
        show_inventory = action.get('show_inventory')
        drop_inventory = action.get('drop_inventory')
        inventory_index = action.get('inventory_index')
        take_stairs = action.get('take_stairs')
        level_up = action.get('level_up')
        show_character_screen = action.get('show_character_screen')
        exit = action.get('exit')
        fullscreen = action.get('fullscreen')
        fullscreen_console = action.get('fullscreen_console')

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

        wheel_up = mouse_action.get('wheel_up')
        wheel_down = mouse_action.get('wheel_down')

        player_turn_results = []

        if wheel_up:
            message_log.scroll_up()

        if wheel_down:
            message_log.scroll_down()

        if move and game_state == GameStates.PLAYERS_TURN:
            dx, dy = move
            destination_x = player.x + dx
            destination_y = player.y + dy

            if not game_map.is_blocked(destination_x, destination_y):
                target = get_blocking_entities_at_location(
                    entities, destination_x, destination_y)

                if target:
                    attack_results = player.fighter.attack(target)
                    player_turn_results.extend(attack_results)
                else:
                    player.move(dx, dy)
                    camera.update(player)
                    fov_recompute = True

                game_state = GameStates.ENEMY_TURN

        elif wait:
            game_state = GameStates.ENEMY_TURN

        elif pickup and game_state == GameStates.PLAYERS_TURN:
            for entity in entities:
                if entity.usable and entity.x == player.x and entity.y == player.y:
                    pickup_results = player.inventory.add_item(entity)
                    player_turn_results.extend(pickup_results)

                    break
            else:
                message_log.add_message(
                    Message(
                        'You fumble around on the ground but find nothing.',
                        libtcod.yellow))

        if show_inventory:
            previous_game_state = game_state
            game_state = GameStates.SHOW_INVENTORY

        if drop_inventory:
            previous_game_state = game_state
            game_state = GameStates.DROP_INVENTORY

        if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len(
                player.inventory.items):
            item = player.inventory.items[inventory_index]

            if game_state == GameStates.SHOW_INVENTORY:
                player_turn_results.extend(
                    player.inventory.use(item,
                                         entities=entities,
                                         fov_map=fov_map))
            elif game_state == GameStates.DROP_INVENTORY:
                player_turn_results.extend(player.inventory.drop_item(item))

        if take_stairs and game_state == GameStates.PLAYERS_TURN:
            for entity in entities:
                if entity.stairs and entity.x == player.x and entity.y == player.y:
                    entities = game_map.next_floor(player, message_log,
                                                   constants)
                    fov_map = initalize_fov(game_map)
                    camera.update(player)
                    fov_recompute = True
                    libtcod.console_clear(con)

                    break
            else:
                message_log.add_message(
                    Message('There are no stairs here.', libtcod.yellow))

        if level_up:
            if level_up == 'hp':
                player.fighter.base_max_hp += 20  # TODO: Consider putting these in constants
                player.fighter.hp += 20
            elif level_up == 'str':
                player.fighter.base_power += 1
            elif level_up == 'def':
                player.fighter.base_defense += 1
            elif level_up == 'speed':
                player.fighter.base_speed -= 10

            # game_state = previous_game_state   # This is the only way I found that the level up book doesn't lock
            game_state = GameStates.PLAYERS_TURN  # the game, hopefully it's fine but it may give an extra turn on lvl up

        if show_character_screen:
            previous_game_state = game_state
            game_state = GameStates.CHARACTER_SCREEN

        if fullscreen_console:
            previous_game_state = game_state
            game_state = GameStates.FULLSCREEN_CONSOLE

        if game_state == GameStates.TARGETING:
            if left_click:
                target_x, target_y = left_click

                item_use_results = player.inventory.use(targeting_item,
                                                        entities=entities,
                                                        fov_map=fov_map,
                                                        target_x=target_x,
                                                        target_y=target_y)
                player_turn_results.extend(item_use_results)
            elif right_click:
                player_turn_results.append({'targeting_cancelled': True})

        if exit:
            if game_map.dungeon_level == -1:  # Testing arena case needs no save file
                return True
            elif game_state in (GameStates.SHOW_INVENTORY,
                                GameStates.DROP_INVENTORY,
                                GameStates.CHARACTER_SCREEN,
                                GameStates.FULLSCREEN_CONSOLE):
                game_state = previous_game_state
            elif game_state == GameStates.TARGETING:
                player_turn_results.append({'targeting_cancelled': True})
            else:
                save_game(player, entities, game_map, message_log, game_state)
                return True

        if fullscreen:
            libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())

        for player_turn_result in player_turn_results:
            message = player_turn_result.get('message')
            dead_entity = player_turn_result.get('dead')
            item_added = player_turn_result.get('item_added')
            item_consumed = player_turn_result.get('consumed')
            item_dropped = player_turn_result.get('item_dropped')
            equip = player_turn_result.get('equip')
            targeting = player_turn_result.get('targeting')
            targeting_cancelled = player_turn_result.get('targeting_cancelled')
            xp = player_turn_result.get('xp')

            if message:
                message_log.add_message(message)

            if targeting_cancelled:
                game_state = previous_game_state

                message_log.add_message(Message('Targeting cancelled'))

            if xp:
                leveled_up = player.level.add_xp(xp)
                message_log.add_message(Message('You gain {0} xp.'.format(xp)))

                if leveled_up:
                    message_log.add_message(
                        Message(
                            'You have honed your skills to reach level {0}.'.
                            format(player.level.current_level), libtcod.cyan))
                    previous_game_state = game_state
                    game_state = GameStates.LEVEL_UP

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

                message_log.add_message(message)

            if item_added:
                entities.remove(item_added)

                game_state = GameStates.ENEMY_TURN

            if item_consumed:
                game_state = GameStates.ENEMY_TURN

            if targeting:
                previous_game_state = GameStates.PLAYERS_TURN
                game_state = GameStates.TARGETING

                targeting_item = targeting

                message_log.add_message(
                    targeting_item.usable.targeting_message)

            if equip:
                equip_results = player.equipment.toggle_equip(equip)

                for equip_result in equip_results:
                    equipped = equip_result.get('equipped')
                    unequipped = equip_result.get('unequipped')

                    if equipped:
                        message_log.add_message(
                            Message('You equipped the {0}.'.format(
                                equipped.name)))

                    if unequipped:
                        message_log.add_message(
                            Message('You unequipped the {0}.'.format(
                                unequipped.name)))

                game_state = GameStates.ENEMY_TURN

            if item_dropped:
                entities.append(item_dropped)

                game_state = GameStates.ENEMY_TURN

        if game_state == GameStates.ENEMY_TURN:
            for entity in entities:
                if entity.ai:
                    current_moves = entity.fighter.current_moves
                    current_moves -= player.fighter.base_speed

                    while (current_moves <= 0):
                        enemy_turn_results = entity.ai.take_turn(
                            player, fov_map, game_map, entities)
                        for enemy_turn_result in enemy_turn_results:
                            message = enemy_turn_result.get('message')
                            dead_entity = enemy_turn_result.get('dead')

                            if message:
                                message_log.add_message(message)

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

                                message_log.add_message(message)

                                if game_state == GameStates.PLAYER_DEAD:
                                    break  # Break game loop
                        if game_state == GameStates.PLAYER_DEAD:
                            break  # Break game loop

                        current_moves += entity.fighter.speed
                    entity.fighter.current_moves = current_moves
                else:
                    game_state = GameStates.PLAYERS_TURN
def main():
    screen_width = 80
    screen_height = 50

    bar_width = 20
    panel_height = 7
    panel_y = screen_height - panel_height

    message_x = bar_width + 2
    message_width = screen_width - bar_width - 2
    message_height = panel_height - 1

    map_width = 80
    map_height = 43

    room_max_size = 30
    room_min_size = 6
    max_rooms = 30

    fov_algorithm = 2
    fov_light_walls = True
    fov_radius = 10

    max_monsters_per_room = 3
    max_items_per_room = 2

    colors = {
        'dark_wall': libtcod.Color(0, 0, 100),
        'dark_ground': libtcod.Color(50, 50, 150),
        'light_wall': libtcod.Color(130, 110, 50),
        'light_ground': libtcod.Color(200, 180, 50)
    }

    til = Tile(False)

    fighter_component = Fighter(30, defense=2, power=5)

    player = Entity(0,
                    0,
                    '@',
                    libtcod.white,
                    'Player',
                    blocks=True,
                    fighter=fighter_component,
                    render_order=RenderOrder.ACTOR)
    entities = [player]

    libtcod.console_set_custom_font(
        'arial10x10.png',
        libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD)

    libtcod.console_init_root(screen_width, screen_height,
                              'libtcod tutorial revised', False)

    con = libtcod.console_new(screen_width, screen_height)
    panel = libtcod.console_new(screen_width, panel_height)

    map = GameMap(map_width, map_height)
    map.make_map(max_rooms, room_min_size, room_max_size, map_width,
                 map_height, player, entities, max_monsters_per_room,
                 max_items_per_room)

    fov_recompute = True

    fov_map = initialize_fov(map)

    message_log = MessageLog(message_x, message_width, message_height)

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

    game_state = GameStates.PLAYERS_TURN

    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.x, player.y, fov_radius,
                          fov_light_walls, fov_algorithm)

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

        render_all(con, panel, entities_in_render_order, player, map, fov_map,
                   fov_recompute, message_log, screen_width, screen_height,
                   bar_width, panel_height, panel_y, mouse, colors)

        fov_recompute = False

        libtcod.console_flush()

        clear_all(con, entities)

        action = handle_keys(key)

        move = action.get('move')
        exit = action.get('exit')
        fullscreen = action.get('fullscreen')

        player_turn_results = []

        if move and game_state == GameStates.PLAYERS_TURN:
            dx, dy = move
            destination_x = player.x + dx
            destination_y = player.y + dy
            if not map.is_blocked(destination_x, destination_y):
                target = get_blocking_entities_at_location(
                    entities, destination_x, destination_y)

                if target:
                    attack_results = player.fighter.attack(target)
                    player_turn_results.extend(attack_results)
                else:
                    player.move(dx, dy)
                    fov_recompute = True

                game_state = GameStates.ENEMY_TURN

            else:
                message_log.add_message(Message('stuck'))

        if fullscreen:
            libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())

        if exit:
            return True

        for player_turn_result in player_turn_results:
            message = player_turn_result.get('message')
            dead_entity = player_turn_result.get('dead')

            if message:
                message_log.add_message(message)

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

                message_log.add_message(message)

        if game_state == GameStates.ENEMY_TURN:
            for entity in entities_in_render_order:
                if entity != player and entity.ai != None:
                    enemy_turn_results = entity.ai.take_turn(
                        fov_map, player, map, entities)

                    for enemy_turn_result in enemy_turn_results:
                        message = enemy_turn_result.get('message')
                        dead_entity = enemy_turn_result.get('dead')

                        if message:
                            message_log.add_message(message)

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

                        message_log.add_message(message)

                        if game_state == GameStates.PLAYER_DEAD:
                            break

            game_state = GameStates.PLAYERS_TURN
Exemple #14
0
def main():
    # console props
    screen_width = 80
    screen_height = 50

    # UI settings
    bar_width = 20
    ui_panel_height = 7
    ui_panel_y = screen_height - ui_panel_height
    ## Message system
    message_x = bar_width + 2
    message_width = screen_width - bar_width - 2
    message_height = ui_panel_height - 1
    message_log = MessageLog(message_x, message_width, message_height)

    # map props
    map_width = 80
    map_height = 43
    room_max_size = 10
    room_min_size = 6
    max_rooms = 30
    max_monsters_per_room = 3
    max_items_per_room = 4

    # FOV settings
    fov_algorithm = 0
    fov_light_walls = True
    fov_radius = 10
    fov_recompute = True # we don't need to recompute FOV everytime (wait, fight, use item)

    # Colors dictionary
    colors = {
        'dark_wall': libtcod.Color(0, 0, 100),
        'dark_ground': libtcod.Color(50, 50, 150),
        'light_wall': libtcod.Color(130, 110, 50),
        'light_ground': libtcod.Color(200, 180, 50)
    }

    # Entities setup
    player_fighter_comp = Fighter(30, 2, 5)
    player_inventory_comp = Inventory(12)
    player = Entity(0, 0, '@', libtcod.white, 'Player', True, RenderOrder.ACTOR, 
                    player_fighter_comp, inventory=player_inventory_comp)
    entities = [player]
    game_state = GameStates.PLAYERS_TURN
    previous_game_state = game_state

    # Consoles setup
    libtcod.console_set_custom_font('arial10x10.png', libtcod.FONT_TYPE_GRAYSCALE | libtcod.FONT_LAYOUT_TCOD)
    libtcod.console_init_root(screen_width, screen_height, 'First Shem RL. Thanks Tutorial', False)
    con = libtcod.console.Console(screen_width, screen_height)
    ui_panel = libtcod.console.Console(screen_width, ui_panel_height)

    # Gamemap setup
    game_map = GameMap(map_width, map_height)
    game_map.make_map(max_rooms, room_min_size, room_max_size, player, entities, max_monsters_per_room, max_items_per_room)

    fov_map = initialize_fov(game_map)

    # Input setup
    key = libtcod.Key()
    mouse = libtcod.Mouse()

    targeting_item = None

    # WARN Check tcod.event for QUIT events
    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.x, player.y, fov_radius, fov_light_walls, fov_algorithm)

        render_all(con, entities, player, game_map, fov_map, fov_recompute, screen_width, screen_height, 
                    ui_panel, bar_width, ui_panel_height, ui_panel_y, message_log, mouse, game_state, colors)

        fov_recompute = False

        libtcod.console_flush()

        clear_all(con, entities)

        # Input handling
        action = handle_keys(key, game_state)
        mouse_action = handle_mouse(mouse)

        move = action.get('move')
        exit = action.get('exit')
        pickup = action.get('pickup')
        show_inventory = action.get('show_inventory')
        drop_inventory = action.get('drop_inventory')
        inventory_index = action.get('inventory_index')
        fullscreen = action.get('fullscreen')

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

        player_turn_results = []

        # Movement handling
        if move and game_state == GameStates.PLAYERS_TURN:
            dx, dy = move
            dest_x = player.x + dx
            dest_y = player.y + dy

            if not game_map.is_blocked(dest_x, dest_y):
                target = get_blocking_entities_at_location(entities, dest_x, dest_y)

                if target:
                    attack_results = player.fighter.attack(target)
                    player_turn_results.extend(attack_results)
                else:
                    player.move(dx, dy)
                    fov_recompute = True

            game_state = GameStates.ENEMY_TURN
        # Pickup handling
        elif pickup and game_state == GameStates.PLAYERS_TURN:
            for entity in entities:
                if entity.item and entity.x == player.x and entity.y == player.y:
                    pickup_results = player.inventory.add_item(entity)
                    player_turn_results.extend(pickup_results)

                    break
            else:
                message_log.add_message(Message('There is nothing here to pickup', libtcod.yellow))

        # Menus display handling
        if show_inventory:
            previous_game_state = game_state
            game_state = GameStates.SHOW_INVENTORY
        if drop_inventory:
            previous_game_state = game_state
            game_state = GameStates.DROP_INVENTORY

        # Items usage handling
        if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len(player.inventory.items):
            item = player.inventory.items[inventory_index]
            if game_state == GameStates.SHOW_INVENTORY:
                player_turn_results.extend(player.inventory.use(item, entities=entities, fov_map=fov_map))
            elif game_state == GameStates.DROP_INVENTORY:
                player_turn_results.extend(player.inventory.drop_item(item))

        if game_state == GameStates.TARGETING:
            if left_click:
                target_x, target_y = left_click

                item_use_results = player.inventory.use(targeting_item, entities=entities, fov_map=fov_map,
                                                        target_x=target_x, target_y=target_y)
                player_turn_results.extend(item_use_results)
            elif right_click:
                player_turn_results.append({'targeting_cancelled': True})

        if exit:
            if game_state in (GameStates.SHOW_INVENTORY, GameStates.DROP_INVENTORY):
                game_state = previous_game_state
            elif game_state == GameStates.TARGETING:
                player_turn_results.append({'targeting_cancelled': True})
            else:
                return True

        if fullscreen:
            libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen)

        # Print turn results
        for p_t_result in player_turn_results:
            message = p_t_result.get('message')
            dead_entity = p_t_result.get('dead')
            item_added =p_t_result.get('item_added')
            item_consumed = p_t_result.get('item_consumed')
            item_dropped = p_t_result.get('item_dropped')
            targeting = p_t_result.get('targeting')
            targeting_cancelled = p_t_result.get('targeting_cancelled')

            if message:
                message_log.add_message(message)

            if dead_entity:
                if dead_entity == player:
                    message, game_state = kill_player(dead_entity)
                else:
                    message = kill_monster(dead_entity)
                message_log.add_message(message)

            if item_added:
                entities.remove(item_added)
                game_state = GameStates.ENEMY_TURN

            if item_consumed:
                game_state = GameStates.ENEMY_TURN

            if targeting:
                previous_game_state = GameStates.PLAYERS_TURN
                game_state = GameStates.TARGETING

                targeting_item = targeting

                message_log.add_message(targeting_item.item.targeting_message)

            if targeting_cancelled:
                game_state = previous_game_state

                message_log.add_message(Message('Targeting cancelled'))

            if item_dropped:
                entities.append(item_dropped)
                game_state = GameStates.ENEMY_TURN

        # ENEMIES TURN
        if game_state == GameStates.ENEMY_TURN:
            for entity in entities:
                if entity.ai:
                    enemy_turn_results = entity.ai.take_turn(player, fov_map, game_map, entities)

                    for e_t_result in enemy_turn_results:
                        message = e_t_result.get('message')
                        dead_entity = e_t_result.get('dead')

                        if message:
                            message_log.add_message(message)

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

                            message_log.add_message(message)

                            if game_state == GameStates.PLAYER_DEAD:
                                break
                    if game_state == GameStates.PLAYER_DEAD:
                        break
            else:
                game_state = GameStates.PLAYERS_TURN
Exemple #15
0
def play_game(player, entities, game_map, message_log, game_state, con, panel,
              constants):
    fov_recompute = True

    fov_map = initialize_fov(game_map)

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

    game_state = GameStates.CHARACTER_CREATION
    previous_game_state = game_state

    targeting_item = None
    targeting_skill = None
    ggender = Gender.male

    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.x, player.y, constants['fov_radius'],
                          constants['fov_light_walls'],
                          constants['fov_algorithm'])

        render_all(con, panel, entities, player, 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'], game_state)

        fov_recompute = False

        libtcod.console_flush()

        clear_all(con, entities)

        action = handle_keys(player, key, game_state)
        mouse_action = handle_mouse(mouse)

        move = action.get('move')
        wait = action.get('wait')
        pickup = action.get('pickup')
        use_skills = action.get('use_skills')
        show_inventory = action.get('show_inventory')
        drop_inventory = action.get('drop_inventory')
        inventory_index = action.get('inventory_index')
        skill_index = action.get('skill_index')
        take_stairs = action.get('take_stairs')
        take_upstairs = action.get('take_upstairs')
        level_up = action.get('level_up')
        show_character_screen = action.get('show_character_screen')
        character_creation = action.get('character_creation')
        job = action.get('job')
        gender = action.get('gender')
        skill_selection = action.get('skill_selection')
        exit = action.get('exit')
        fullscreen = action.get('fullscreen')

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

        player_turn_results = []

        if move and game_state == GameStates.PLAYERS_TURN:
            #The starvation variable increases or decreases as the player gets more psyche and gets hungrier.
            libtcod.console_flush()
            starvation_variable = 1
            player.fighter.nutrition -= 1
            dx, dy = move
            destination_x = player.x + dx
            destination_y = player.y + dy

            if player.fighter.nutrition <= 0:
                kill_player(player)
                game_state = GameStates.PLAYER_DEAD
                message_log.add_message(
                    Message('You have starved to death.', libtcod.red))

            if player.fighter.starvation_bonus >= 20 and player.fighter.psyche <= 5 or player.fighter.psyche == 5:
                starvation_variable = 0
            elif player.fighter.starvation_bonus >= 40 and player.fighter.psyche <= 10 or player.fighter.psyche == 10:
                starvation_variable = 0

            if player.fighter.nutrition <= 100:
                player.fighter.starvation_bonus += starvation_variable

            elif player.fighter.nutrition >= 100:
                player.fighter.starvation_bonus += 0

            if not game_map.is_blocked(destination_x, destination_y):
                target = get_blocking_entities_at_location(
                    entities, destination_x, destination_y)

                if target:
                    attack_results = player.fighter.attack(target)
                    player_turn_results.extend(attack_results)
                else:
                    player.move(dx, dy)

                    fov_recompute = True

                game_state = GameStates.ENEMY_TURN

        elif wait:
            game_state = GameStates.ENEMY_TURN

        elif gender == Gender.male:
            player.fighter.gender = 1

        elif gender == Gender.female:
            player.fighter.gender = 2

        elif gender == Gender.agender:
            player.fighter.gender = 3

        elif pickup and game_state == GameStates.PLAYERS_TURN:
            for entity in entities:
                if (entity.item or entity.equippable
                    ) and entity.x == player.x and entity.y == player.y:
                    pickup_results = player.inventory.add_item(entity)
                    player_turn_results.extend(pickup_results)

                    break
            else:
                message_log.add_message(
                    Message('There is nothing here to pick up.',
                            libtcod.yellow))

        if show_inventory:
            previous_game_state = game_state
            game_state = GameStates.SHOW_INVENTORY

        if use_skills:
            previous_game_state = game_state
            game_state = GameStates.SHOW_SKILL_MENU

        if drop_inventory:
            previous_game_state = game_state
            game_state = GameStates.DROP_INVENTORY

        if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len(
                player.inventory.items):
            item = player.inventory.items[inventory_index]

            if game_state == GameStates.SHOW_INVENTORY:
                player_turn_results.extend(
                    player.inventory.use(item,
                                         entities=entities,
                                         fov_map=fov_map))
                libtcod.console_flush()
                libtcod.console_clear(con)
            elif game_state == GameStates.DROP_INVENTORY:
                player_turn_results.extend(player.inventory.drop_item(item))
                libtcod.console_flush()
                libtcod.console_clear(con)

        if skill_index is not None and previous_game_state != GameStates.PLAYER_DEAD and skill_index < len(
                player.skills.skill_list):
            skill = player.skills.skill_list[skill_index]

            if game_state == GameStates.SHOW_SKILL_MENU:
                player_turn_results.extend(
                    player.skills.use(skill,
                                      entities=entities,
                                      fov_map=fov_map))
                libtcod.console_flush()
                libtcod.console_clear(con)

        if take_stairs and game_state == GameStates.PLAYERS_TURN:
            for entity in entities:
                if entity.stairs and entity.x == player.x and entity.y == player.y:
                    entities = game_map.next_floor(player, message_log,
                                                   constants)
                    fov_map = initialize_fov(game_map)
                    fov_recompute = True
                    libtcod.console_clear(con)

                    break
            else:
                message_log.add_message(
                    Message('There are no stairs here.', libtcod.yellow))

        if take_upstairs and game_state == GameStates.PLAYERS_TURN:
            for entity in entities:
                if entity.stairs and entity.x == player.x and entity.y == player.y:
                    entities = game_map.previous_floor(player, message_log,
                                                       constants)
                    fov_map = initialize_fov(game_map)
                    fov_recompute = True
                    libtcod.console_clear(con)

                    break
            else:
                message_log.add_message(
                    Message('There are no stairs here.', libtcod.yellow))

        if level_up:
            if level_up == 'hp':
                player.fighter.base_max_hp += 10
                player.fighter.hp += 10
            elif level_up == 'str':
                player.fighter.base_power += 1
            elif level_up == 'def':
                player.fighter.base_defense += 1
            libtcod.console_flush()
            libtcod.console_clear(con)
            game_state = GameStates.JOB_SELECTION


#For some reason the skil menu is linked here. I wonder why?
        if job:
            if job == 'pri':
                player.fighter.base_max_hp += 20
                player.fighter.hp += 20
                player.fighter.job += 1
                player.fighter.priest_level += 1
                skill_component = Skill(use_function=prayer,
                                        amount=40,
                                        mana_cost=5)
                bandage = Entity(0,
                                 0,
                                 '?',
                                 libtcod.yellow,
                                 'Cure Light Wounds',
                                 skill=skill_component)
                player.skills.add_skill(bandage)
            elif job == 'fig':
                player.fighter.base_power += 2
                player.fighter.base_defense += 1
                player.fighter.job += 2
                player.fighter.fighter_level += 1
            elif job == 'thi':
                skill_component = Skill(use_function=hide)
                tornado = Entity(0,
                                 0,
                                 '?',
                                 libtcod.yellow,
                                 'Hide',
                                 skill=skill_component)
                player.fighter.base_defense += 2
                player.fighter.base_power += 1
                player.fighter.base_agility += 0.5
                player.fighter.job += 3
                player.fighter.thief_level += 1
                player.skills.add_skill(tornado)
            elif job == 'wiz':
                skill_component = Skill(
                    use_function=cast_spell_fireball,
                    mana_cost=10,
                    skill_targeting=True,
                    targeting_message=Message(
                        'Left-click a target tile for the fireball, or right-click to cancel.',
                        libtcod.light_cyan),
                    damage=25,
                    radius=3)
                x = entity.x
                y = entity.y
                fireball = Entity(x,
                                  y,
                                  '?',
                                  libtcod.red,
                                  'Fireball',
                                  skill=skill_component)
                player.skills.add_skill(fireball)
            elif job == 'psy':
                skill_component = Charm()
                charm = SkillEntity(' ',
                                    libtcod.yellow,
                                    'Charm',
                                    skill=skill_component)
                player.fighter.base_psyche += 3
                player.fighter.job = 5
                skill_component = Skill(use_function=cast_mind_lightning,
                                        maximum_range=5,
                                        hunger_cost=40 +
                                        player.fighter.psyche / 2)
                psybolt = Entity(0,
                                 0,
                                 ' ',
                                 libtcod.yellow,
                                 'PsyBolt',
                                 skill=skill_component)
                player.skills.add_skill(psybolt)
                player.skills.add_skill(charm)

            libtcod.console_flush()
            libtcod.console_clear(con)
            game_state = GameStates.PLAYERS_TURN

        if character_creation:
            if character_creation == 'mern':
                player.fighter.base_max_hp += 20
                player.fighter.hp += 20
                player.fighter.race += 1
            elif character_creation == 'avis':
                player.fighter.base_power += 1
                player.fighter.race += 2
            elif character_creation == 'lepra':
                player.fighter.base_defense += 1
                player.fighter.race += 3
            elif character_creation == 'giant':
                player.fighter.base_agility -= 5
                player.fighter.base_power += 6
                player.fighter.hp += 60
                player.fighter.base_max_hp += 60
                player.fighter.race += 4
            elif character_creation == 'change':
                player.fighter.base_agility += 2
                player.fighter.race += 5
            elif character_creation == 'fae':
                player.fighter.base_agility += 10
                player.fighter.hp -= 75
                player.fighter.base_max_hp -= 75
                player.fighter.race += 6
            libtcod.console_flush()
            libtcod.console_clear(con)
            game_state = GameStates.GENDER_SELECTION
        # damn son thats a lot of menus
        # like a lot

        if gender:
            if gender == 'm':
                player.fighter.base_max_hp += 10
                player.fighter.hp += 10
                player.fighter.gender += 1
            elif gender == 'f':
                player.fighter.base_power += 5
                player.fighter.base_max_hp -= 20
                player.fighter.hp -= 20
                player.fighter.gender += 2
            elif gender == 'a':
                player.fighter.gender += 3
            libtcod.console_flush()
            libtcod.console_clear(con)
            game_state = GameStates.PLAYERS_TURN

        if show_character_screen:
            previous_game_state = game_state
            game_state = GameStates.CHARACTER_SCREEN

        if game_state == GameStates.TARGETING:
            if left_click:
                target_x, target_y = left_click

                item_use_results = player.inventory.use(targeting_item,
                                                        entities=entities,
                                                        fov_map=fov_map,
                                                        target_x=target_x,
                                                        target_y=target_y)
                player_turn_results.extend(item_use_results)
                libtcod.console_flush()
                libtcod.console_clear(con)
            elif right_click:
                player_turn_results.append({'targeting_cancelled': True})
                libtcod.console_flush()
                libtcod.console_clear(con)

        if game_state == GameStates.SKILL_TARGETING:
            if left_click:
                target_x, target_y = left_click

                skill_use_results = player.skills.use(targeting_skill,
                                                      entities=entities,
                                                      fov_map=fov_map,
                                                      target_x=target_x,
                                                      target_y=target_y)
                player_turn_results.extend(skill_use_results)
                libtcod.console_flush()
            elif right_click:
                player_turn_results.append({'targeting_cancelled': True})
                libtcod.console_flush()
                libtcod.console_clear(con)

        if exit:
            if game_state in (GameStates.SHOW_INVENTORY,
                              GameStates.DROP_INVENTORY,
                              GameStates.CHARACTER_SCREEN):
                game_state = previous_game_state
            elif game_state == GameStates.SHOW_SKILL_MENU:
                game_state = GameStates.PLAYERS_TURN
            elif game_state == GameStates.TARGETING:
                player_turn_results.append({'targeting_cancelled': True})
            elif game_state == GameStates.SKILL_TARGETING:
                player_turn_results.append({'targeting_cancelled': True})
            else:
                save_game(player, entities, game_map, message_log, game_state)
                libtcod.console_flush()
                libtcod.console_clear(panel)
                libtcod.console_clear(con)

                return True

        if fullscreen:
            libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())

        for player_turn_result in player_turn_results:
            message = player_turn_result.get('message')
            dead_entity = player_turn_result.get('dead')
            item_added = player_turn_result.get('item_added')
            skill_added = player_turn_result.get('skill_added')
            item_consumed = player_turn_result.get('consumed')
            item_dropped = player_turn_result.get('item_dropped')
            equip = player_turn_result.get('equip')
            targeting = player_turn_result.get('targeting')
            skill_targeting = player_turn_result.get('skill_targeting')
            targeting_cancelled = player_turn_result.get('targeting_cancelled')
            xp = player_turn_result.get('xp')
            skill_used = player_turn_result.get('used')

            if message:
                message_log.add_message(message)

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

                message_log.add_message(message)

            if item_added:
                entities.remove(item_added)

                game_state = GameStates.ENEMY_TURN

            if item_consumed:
                game_state = GameStates.ENEMY_TURN

            if skill_added:
                game_state = GameStates.ENEMY_TURN

            if skill_used:
                game_state = GameStates.ENEMY_TURN

            if item_dropped:
                entities.append(item_dropped)

                game_state = GameStates.ENEMY_TURN

            if equip:
                equip_results = player.equipment.toggle_equip(equip)

                for equip_result in equip_results:
                    equipped = equip_result.get('equipped')
                    dequipped = equip_result.get('dequipped')

                    if equipped:
                        message_log.add_message(
                            Message('You equipped the {0}'.format(
                                equipped.name)))

                    if dequipped:
                        message_log.add_message(
                            Message('You dequipped the {0}'.format(
                                dequipped.name)))

                game_state = GameStates.ENEMY_TURN

            if targeting:
                previous_game_state = GameStates.PLAYERS_TURN
                game_state = GameStates.TARGETING

                targeting_item = targeting

                message_log.add_message(targeting_item.item.targeting_message)

            if skill_targeting:
                previous_game_state = GameStates.PLAYERS_TURN
                game_state = GameStates.SKILL_TARGETING

                targeting_skill = skill_targeting

                message_log.add_message(
                    targeting_skill.skill.targeting_message)

            if targeting_cancelled:
                game_state = previous_game_state

                message_log.add_message(Message('Targeting cancelled'))

            if xp:
                leveled_up = player.level.add_xp(xp)
                message_log.add_message(
                    Message('You gain {0} experience points.'.format(xp)))

                if leveled_up:

                    previous_game_state = game_state
                    game_state = GameStates.LEVEL_UP

        if game_state == GameStates.ENEMY_TURN:

            if player.fighter.nutrition <= 0:
                kill_player(player)
                game_state = GameStates.PLAYER_DEAD
                message_log.add_message(
                    Message('You have starved to death.', libtcod.red))

            if player.fighter.nutrition <= 100 and player.fighter.stealthed == 1:
                player.fighter.stealthed = 0

            for entity in entities:
                if entity.ai:
                    enemy_turn_results = entity.ai.take_turn(
                        player, fov_map, game_map, entities)

                    for enemy_turn_result in enemy_turn_results:
                        message = enemy_turn_result.get('message')
                        dead_entity = enemy_turn_result.get('dead')

                        if message:
                            message_log.add_message(message)

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

                            message_log.add_message(message)

                            if game_state == GameStates.PLAYER_DEAD:
                                break

                    if game_state == GameStates.PLAYER_DEAD:
                        break
            else:
                game_state = GameStates.PLAYERS_TURN
Exemple #16
0
def main():

	# Console Parameters
	screen_width = 80
	screen_height = 50
	
	# GUI Parameters
	bar_width = 20
	panel_height = 7
	panel_y = screen_height - panel_height

    # Message Parameters
	message_x = bar_width + 2
	message_width = screen_width - bar_width - 2
	message_height = panel_height - 1

	# Map Parameters
	map_width = 80
	map_height = 43

	# Room Parameters
	room_max_size = 10
	room_min_size = 6
	max_rooms = 30

	# Field of View Parameters
	fov_algorithm = 0
	fov_light_walls = True
	fov_radius = 10
	
    # Spawn parameters
	max_monsters_per_room = 3
	max_items_per_room = 2

	# Tile Colors
	colors = {
		'dark_wall': libtcod.Color(0, 0, 100),
		'dark_ground': libtcod.Color(50, 50, 150),
		'light_wall': libtcod.Color(130, 110, 50),
		'light_ground': libtcod.Color(200, 180, 50)
		}

	# Entity Variables
	fighter_component = Fighter(
		hp=30, 
		defense=2, 
		power=5
		)
	inventory_component = Inventory(26)
	player = Entity(
		0, 
		0, 
		'@', 
		libtcod.white, 
		'Player', 
		blocks=True,
		render_order=RenderOrder.ACTOR,
		fighter=fighter_component,
		inventory=inventory_component
		)
	entities = [player]

	# Map Generator
	game_map = GameMap(         # defines the game map dimensions, calling GameMap class
		map_width, 
		map_height
		)
	game_map.make_map(          # generates the map
		max_rooms, 
		room_min_size, 
		room_max_size, 
		map_width, 
		map_height, 
		player, 
		entities, 
		max_monsters_per_room,
		max_items_per_room
		)
	
	fov_recompute = True
	fov_map = initialize_fov(game_map)

	# Console & GUI
	libtcod.console_set_custom_font('assets/arial10x10.png', libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD)
	libtcod.console_init_root(screen_width, screen_height, 'libtcod tutorial revised', False)
	con = libtcod.console_new(screen_width, screen_height)
	panel = libtcod.console_new(screen_width, panel_height)

	message_log = MessageLog(message_x, message_width, message_height)

	# Input Functions
	key = libtcod.Key()
	mouse = libtcod.Mouse()

	# Game States
	game_state = GameStates.PLAYERS_TURN
	previous_game_state = game_state

#############################################################
#                      MAIN GAME LOOP                       #
#############################################################

    # So long as the window is open, do...
	while not libtcod.console_is_window_closed():
		libtcod.sys_check_for_event(
			libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, 
			key, 
			mouse)

        # TRUE on Move, trigger recompute
		if fov_recompute:
			recompute_fov(
				fov_map, 
				player.x, 
				player.y, 
				fov_radius, 
				fov_light_walls, 
				fov_algorithm
				)

		# Render the frame
		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
			)
		
        # Recompute FOV only on player move
		fov_recompute = False

		# Clean up the screen
		libtcod.console_flush()
		clear_all(
			con, 
			entities
			)

# INPUT HANDLERS

		action = handle_keys(key, game_state)
		move = action.get('move')
		pickup = action.get('pickup')
		show_inventory = action.get('show_inventory')
		drop_inventory = action.get('drop_inventory')
		inventory_index = action.get('inventory_index')
		exit = action.get('exit')
		fullscreen = action.get('fullscreen')

# Entity Turn Logics
		
    # PLAYER TURN
    
		# Combat Results
		player_turn_results = []        

        # Move
		if move and game_state == GameStates.PLAYERS_TURN:
			dx, dy = move
			destination_x = player.x + dx
			destination_y = player.y + dy

			if not game_map.is_blocked(destination_x, destination_y):
				target = get_blocking_entities_at_location(
					entities, 
					destination_x, 
					destination_y
					)

				if target:
					attack_results = player.fighter.attack(target)
					player_turn_results.extend(attack_results)
				else: 
					player.move(dx, dy)

					fov_recompute = True          
				# PASS TURN
				game_state = GameStates.ENEMY_TURN

		# Pickup
		elif pickup and game_state == GameStates.PLAYERS_TURN:
			for entity in entities:
				if entity.item and entity.x == player.x and entity.y == player.y:       # If item x,y == player x,y
					pickup_results = player.inventory.add_item(entity)
					player_turn_results.extend(pickup_results)
					
					break
				
			else:
				message_log.add_message(Message('There is nothing here to pick up.', libtcod.yellow))

		# Show Inventory
		if show_inventory:
			previous_game_state = game_state
			game_state = GameStates.SHOW_INVENTORY

		# Drop Inventory
		if drop_inventory:
			previous_game_state = game_state
			game_state = GameStates.DROP_INVENTORY

		# Inventory Index
		if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len(
				player.inventory.items):
			item = player.inventory.items[inventory_index]

			if game_state == GameStates.SHOW_INVENTORY:
				player_turn_results.extend(player.inventory.use(item))
			elif game_state == GameStates.DROP_INVENTORY:
				player_turn_results.extend(player.inventory.drop_item(item))

        # ESC Key Logic
		if exit:
			if game_state in (GameStates.SHOW_INVENTORY, GameStates.DROP_INVENTORY):
				game_state = previous_game_state
			else:
				return True
		
        # Fullscreen
		if fullscreen:
			libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())
		
		# Handling end of player turn
		for player_turn_result in player_turn_results:
			message = player_turn_result.get('message')
			dead_entity = player_turn_result.get('dead')
			item_added = player_turn_result.get('item_added')
			item_consumed = player_turn_result.get('consumed')
			item_dropped = player_turn_result.get('item_dropped')
			
			if message:
				message_log.add_message(message)
			
			if dead_entity:
				if dead_entity == player:
					message, game_state = kill_player(dead_entity)
				else:
					message = kill_monster(dead_entity)
				message_log.add_message(message)
				
			if item_added:
				entities.remove(item_added)
				game_state = GameStates.ENEMY_TURN
    
			if item_consumed:
				game_state = GameStates.ENEMY_TURN
    
			if item_dropped:
				entities.append(item_dropped)
    
				game_state = GameStates.ENEMY_TURN

    # ENEMY TURN
    
        # Handling the enemy turn
		if game_state == GameStates.ENEMY_TURN:
			for entity in entities:
				if entity.ai:
					enemy_turn_results = entity.ai.take_turn(
						player,
						fov_map,
						game_map,
						entities
					)
					
					for enemy_turn_result in enemy_turn_results:
						message = enemy_turn_result.get('message')
						dead_entity = enemy_turn_result.get('dead')
					
						if message:
							message_log.add_message(message)
							
						if dead_entity:
							if dead_entity == player:
								message, game_state = kill_player(dead_entity)
							else: 
								message = kill_monster(dead_entity)
								
							message_log.add_message(message)
							
							if game_state == GameStates.PLAYER_DEAD:
								break
							
					if game_state == GameStates.PLAYER_DEAD:
						break
					
			# Pass turn back to Player
			else:
				game_state = GameStates.PLAYERS_TURN
Exemple #17
0
def main():
     # some initializations, main console
    title = 'NOIGUE L.C.'
    tcod.sys_set_fps(LIMIT_FPS)
    tcod.console_set_custom_font(
        "arial10x10.png", tcod.FONT_TYPE_GREYSCALE | tcod.FONT_LAYOUT_TCOD,)
    tcod.console_init_root(SCREEN_WIDTH, SCREEN_HEIGHT,
                           title, renderer=tcod.RENDERER_SDL2, order="F")
    con = tcod.console.Console(MAP_WIDTH, MAP_HEIGHT)
    con.default_fg = tcod.white
    game_state = GameStates.INTRO_SCREEN
    # inputs
    key = tcod.Key()
    mouse = tcod.Mouse()
    while not tcod.console_is_window_closed():
        tcod.sys_check_for_event(
            tcod.EVENT_KEY_PRESS, key, mouse)
        if game_state == GameStates.INTRO_SCREEN:
            game_state = start_screen(con, game_state, key, title)
        elif game_state == GameStates.EXIT:
            break
        elif game_state == GameStates.CLASS_CHOICE:
            game_state = class_choice(con, game_state, key, title)
        elif game_state == GameStates.PLAYERS_TURN:
            # start pyo server
            pyo_server = Server(duplex=0).boot()
            pyo_server.start()
            # create player
            player = Entity(0, 0, '@', tcod.white, 'Player',
                            blocks=True, type=Noiseur(sound=Noise()), inventory=Inventory(26), render=RenderOrder.ENTITY)
            player.type.sound_out()
            entities = [player]
            previous_game_state = game_state
            # create sub-panels
            panels = []
            panel = Panel(0, CAMERA_HEIGHT, SCREEN_WIDTH,
                          SCREEN_HEIGHT-CAMERA_HEIGHT, "log")
            panels.append(panel)
            panel = Panel(CAMERA_WIDTH, 0, SCREEN_WIDTH -
                          CAMERA_WIDTH, CAMERA_HEIGHT, "sidebar")
            panels.append(panel)
            message_log = MessageLog(
                2, SCREEN_WIDTH-4, SCREEN_HEIGHT-CAMERA_HEIGHT-2)
            # create game map and place entities, fov
            camera = Camera()
            game_map = GameMap()
            game_map.make_map(player, entities)
            fov = FOV(game_map)
            # compute fov
            fov.recompute_fov(player)
            # main loop
            targeting_item = None
            while not tcod.console_is_window_closed():
                # get events
                tcod.sys_check_for_event(
                    tcod.EVENT_KEY_PRESS | tcod.EVENT_MOUSE, key, mouse)
                # render everything
                render_all(con, panels, entities, player, game_map,
                           fov, message_log, game_state, camera)
                tcod.console_flush()
                clear_all(con, panels, entities, camera)
                # get action from keyboard
                action = handle_keys(key, game_state)
                mouse_action = handle_mouse(mouse)
                move = action.get("move")
                pickup = action.get('pickup')
                show_inventory = action.get('show_inventory')
                if show_inventory:
                    previous_game_state = game_state
                    game_state=GameStates.SHOW_INVENTORY
                inventory_index = action.get('inventory_index')
                exit = action.get("exit")
                fullscreen = action.get("fullscreen")
                left_click = mouse_action.get('left_click')
                right_click = mouse_action.get('right_click')
                # deal with actions
                player_turn_results = []
                if game_state == GameStates.PLAYERS_TURN:
                    if move:
                        dx, dy = move
                        destination_x = player.x + dx
                        destination_y = player.y + dy
                        if not game_map.is_blocked(destination_x, destination_y):
                            target = get_blocking_entities_at_location(
                                entities, destination_x, destination_y)
                            if not target:
                                player.move(dx, dy)
                                fov.recompute = True
                        game_state = GameStates.ENEMY_TURN
                    elif pickup :
                        for entity in entities:
                            if entity.item and entity.x == player.x and entity.y == player.y:
                                pickup_results = player.inventory.add_item(entity)
                                player_turn_results.extend(pickup_results)
                                break
                        else:
                            message_log.add_message(
                                Message('There is nothing here to pick up.', tcod.yellow))
                if game_state == GameStates.SHOW_INVENTORY:
                    if inventory_index is not None and inventory_index < len(player.inventory.items):
                        item = player.inventory.items[inventory_index]
                        player_turn_results.extend(player.inventory.use(item, entities=entities, fov_map=fov.map))
                if game_state == GameStates.TARGETING:
                    if left_click:
                        target_x, target_y = left_click
                        item_use_results = player.inventory.use(targeting_item, entities=entities, fov_map=fov.map,
                                                                target_x=int(target_x+camera.x), target_y=int(target_y+camera.y))
                        player_turn_results.extend(item_use_results)
                    elif right_click:
                        player_turn_results.append({'targeting_cancelled': True})
                for player_turn_result in player_turn_results:
                    message = player_turn_result.get('message')
                    item_added = player_turn_result.get('item_added')
                    item_consumed = player_turn_result.get('consumed')
                    targeting = player_turn_result.get('targeting')
                    targeting_cancelled = player_turn_result.get('targeting_cancelled')
                    if message:
                        message_log.add_message(message)
                    if item_added:
                        entities.remove(item_added)
                        game_state = GameStates.ENEMY_TURN
                    if item_consumed:
                        game_state = GameStates.ENEMY_TURN
                    if targeting:
                        previous_game_state = GameStates.PLAYERS_TURN
                        game_state = GameStates.TARGETING
                        targeting_item = targeting
                        message_log.add_message(targeting_item.item.targeting_message)
                    if targeting_cancelled:
                        game_state = previous_game_state
                        message_log.add_message(Message('Targeting cancelled'))
                if game_state == GameStates.ENEMY_TURN:
                    for entity in entities:
                        if entity.ai:
                            enemy_turn_results = entity.ai.take_turn(
                                player, entity, fov, game_map, entities)
                            for enemy_turn_result in enemy_turn_results:
                                message = enemy_turn_result.get('message')
                                if message:
                                    message_log.add_message(message)
                    else:
                        game_state = GameStates.PLAYERS_TURN
                if exit:
                    if game_state == GameStates.SHOW_INVENTORY:
                        game_state = previous_game_state
                    elif game_state == GameStates.TARGETING:
                        player_turn_results.append({'targeting_cancelled': True})
                    else:
                        pyo_server.stop()
                        return True
                if fullscreen:
                    tcod.console_set_fullscreen(
                        not tcod.console_is_fullscreen())
Exemple #18
0
def main():

    # Game and map constants
    screen_width = 80
    screen_height = 50

    # HP Bar paramters
    bar_width = 20

    # Panel for bars
    panel_height = 7
    panel_y = screen_height - panel_height

    # Message bar
    message_x = bar_width + 2
    message_width = screen_width - bar_width - 2
    message_height = panel_height - 1

    # Map size
    map_width = 80
    map_height = 43

    # Room parameters
    room_max_size = 10
    room_min_size = 6
    max_rooms = 30

    # FoV Variables
    fov_algoritm = 0
    fov_light_walls = True
    fov_radius = 10

    # Entity limits
    max_monsters_per_room = 3
    max_items_per_room = 2

    colors = {
        'dark_wall': tcod.Color(0, 0, 100),
        'dark_ground': tcod.Color(50, 50, 150),
        'light_wall': tcod.Color(130, 110, 50),
        'light_ground': tcod.Color(200, 180, 50)
    }

    fighter_component = Fighter(hp=30, defense=2, power=5)
    inventory_component = Inventory(26)
    player = Entity(0,
                    0,
                    '@',
                    tcod.white,
                    'Player',
                    blocks=True,
                    render_order=RenderOrder.ACTOR,
                    fighter=fighter_component,
                    inventory=inventory_component)
    entities = [player]

    tcod.console_set_custom_font(
        'Bisasam_24x24.png', tcod.FONT_TYPE_GREYSCALE | tcod.FONT_LAYOUT_CP437)

    tcod.console_init_root(screen_width,
                           screen_height,
                           'tcodtutorial revised',
                           False,
                           renderer=tcod.RENDERER_SDL2)
    con = tcod.console.Console(screen_width, screen_height)

    panel = tcod.console.Console(screen_width, panel_height)

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

    fov_recompute = True

    fov_map = initialize_fov(game_map)

    message_log = MessageLog(message_x, message_width, message_height)

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

    game_state = GameStates.PLAYERS_TURN
    previous_game_state = game_state

    while not tcod.console_is_window_closed():
        tcod.sys_check_for_event(tcod.EVENT_KEY_PRESS | tcod.EVENT_MOUSE, key,
                                 mouse)
        if fov_recompute:
            recompute_fov(fov_map, player.x, player.y, fov_radius)

        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)
        fov_recompute = False
        tcod.console_flush()
        clear_all(con, entities)

        action = handle_keys(key, game_state)

        move = action.get('move')
        pickup = action.get('pickup')
        exit = action.get('exit')
        fullscreen = action.get('fullscreen')
        show_inventory = action.get('show_inventory')
        inventory_index = action.get('inventory_index')

        player_turn_results = []

        # Move and/or attack action
        if move and game_state == GameStates.PLAYERS_TURN:
            dx, dy = move

            destination_x = player.x + dx
            destination_y = player.y + dy

            if not game_map.is_blocked(destination_x, destination_y):
                target = get_blocking_entities_at_location(
                    entities, destination_x, destination_y)

                if target:
                    attack_results = player.fighter.attack(target)
                    player_turn_results.extend(attack_results)
                else:
                    player.move(dx, dy)

                    fov_recompute = True

                game_state = GameStates.ENEMY_TURN
        # Picking up an item
        elif pickup and game_state == GameStates.PLAYERS_TURN:
            for entity in entities:
                if entity.item and entity.x == player.x and entity.y == player.y:
                    pickup_results = player.inventory.add_item(entity)
                    player_turn_results.extend(pickup_results)

                    break
            else:
                message_log.add_message(
                    Message('There is nothing here to pick up.', tcod.yellow))

        # Open inventory
        if show_inventory:
            previous_game_state = game_state
            game_state = GameStates.SHOW_INVENTORY

        if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len(
                player.inventory.items):
            item = player.inventory.items[inventory_index]
            print(item.name)

        # Exit game
        if exit:
            if game_state == GameStates.SHOW_INVENTORY:
                # Escape from inventory menu back to game
                game_state = previous_game_state
            else:
                return True

        # Set to fullscreen
        if fullscreen:
            tcod.console_set_fullscreen((not tcod.console_is_fullscreen()))

        ## PROCESS PLAYER'S TURN
        for player_turn_result in player_turn_results:
            message = player_turn_result.get('message')
            dead_entity = player_turn_result.get('dead')
            item_added = player_turn_result.get('item_added')

            if message:
                message_log.add_message(message)

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

                message_log.add_message(message)

            if item_added:
                entities.remove(item_added)

                game_state = GameStates.ENEMY_TURN

        if game_state == GameStates.ENEMY_TURN:
            for entity in entities:
                # If entity has 'ai', i.e. can move or attack etc, get
                if entity.ai:
                    enemy_turn_results = entity.ai.take_turn(
                        player, fov_map, game_map, entities)

                    for enemy_turn_result in enemy_turn_results:
                        message = enemy_turn_result.get('message')
                        dead_entity = enemy_turn_result.get('dead')

                        if message:
                            message_log.add_message(message)

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

                            message_log.add_message(message)

                            if game_state == GameStates.PLAYER_DEAD:
                                break

                    if game_state == GameStates.PLAYER_DEAD:
                        break
            else:
                game_state = GameStates.PLAYERS_TURN
Exemple #19
0
def play_game(player, entities, game_map, message_log, game_state, con, panel,
              constants):
    fov_recompute = True

    fov_map = initialize_fov(game_map)

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

    game_state = GameStates.RACE_SELECTION
    previous_game_state = game_state

    targeting_item = None

    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.x, player.y, constants['fov_radius'],
                          constants['fov_light_walls'],
                          constants['fov_algorithm'])

        render_all(con, panel, entities, player, 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'], game_state)

        fov_recompute = False

        libtcod.console_flush()

        clear_all(con, entities)

        action = handle_keys(key, game_state)
        mouse_action = handle_mouse(mouse)

        move = action.get('move')
        wait = action.get('wait')
        pickup = action.get('pickup')
        see_skills = action.get('see_skills')
        show_inventory = action.get('show_inventory')
        drop_inventory = action.get('drop_inventory')
        inventory_index = action.get('inventory_index')
        skills_index = action.get('skill_index')
        take_stairs = action.get('take_stairs')
        level_up = action.get('level_up')
        job = action.get('job')
        show_character_screen = action.get('show_character_screen')
        race = action.get('race')
        exit = action.get('exit')
        fullscreen = action.get('fullscreen')
        job_menu = action.get('job_menu')

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

        player_turn_results = []

        print(game_state)

        if move and game_state == GameStates.PLAYERS_TURN:
            dx, dy = move
            destination_x = player.x + dx
            destination_y = player.y + dy

            if player.fighter.status_effects.grace == True:
                player.fighter.nutrition -= 50
            else:
                player.fighter.nutrition -= 1

            if not game_map.is_blocked(destination_x, destination_y):
                target = get_blocking_entities_at_location(
                    entities, destination_x, destination_y)

                if target:
                    attack_results = player.fighter.attack(target)
                    player_turn_results.extend(attack_results)
                else:
                    player.move(dx, dy)

                    fov_recompute = True

                game_state = GameStates.ENEMY_TURN

        elif wait:
            game_state = GameStates.ENEMY_TURN

        elif pickup and game_state == GameStates.PLAYERS_TURN:
            for entity in entities:
                if entity.item and entity.x == player.x and entity.y == player.y:
                    pickup_results = player.inventory.add_item(entity)
                    player_turn_results.extend(pickup_results)

                    break
            else:
                message_log.add_message(
                    Message('There is nothing here to pick up.',
                            libtcod.yellow))

        if show_inventory:
            previous_game_state = game_state
            game_state = GameStates.SHOW_INVENTORY

        if job_menu:
            game_state = GameStates.JOB_MENU

        if see_skills:
            previous_game_state = game_state
            game_state = GameStates.SKILL_SELECTION

        if drop_inventory:
            previous_game_state = game_state
            game_state = GameStates.DROP_INVENTORY

        if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len(
                player.inventory.items):
            item = player.inventory.items[inventory_index]

            if game_state == GameStates.SHOW_INVENTORY:
                player_turn_results.extend(
                    player.inventory.use(item,
                                         entities=entities,
                                         fov_map=fov_map))
            elif game_state == GameStates.DROP_INVENTORY:
                player_turn_results.extend(player.inventory.drop_item(item))

        if skills_index is not None and previous_game_state != GameStates.PLAYER_DEAD and skills_index < len(
                player.skills.skills):
            item = player.skills.skills[skills_index]

            if game_state == GameStates.SKILL_SELECTION:
                player_turn_results.extend(
                    player.skills.use(item, entities=entities,
                                      fov_map=fov_map))

        if take_stairs and game_state == GameStates.PLAYERS_TURN:
            for entity in entities:
                if entity.stairs and entity.x == player.x and entity.y == player.y:
                    entities = game_map.next_floor(player, message_log,
                                                   constants)
                    fov_map = initialize_fov(game_map)
                    fov_recompute = True
                    libtcod.console_clear(con)

                    break
                elif entity.upstairs and entity.x == player.x and entity.y == player.y:
                    entities = game_map.previous_floor(player, message_log,
                                                       constants)
                    fov_map = initialize_fov(game_map)
                    fov_recompute = True
                    libtcod.console_clear(con)

                    break
            else:
                message_log.add_message(
                    Message('There are no stairs here.', libtcod.yellow))

        if level_up:
            if level_up == 'hp':
                player.fighter.base_max_hp += 20
                player.fighter.hp += 20
            elif level_up == 'str':
                player.fighter.base_power += 1
            elif level_up == 'def':
                player.fighter.base_defense += 1
            game_state = GameStates.CLASS_SELECTION

        if show_character_screen:
            previous_game_state = game_state
            game_state = GameStates.CHARACTER_SCREEN

        if job:
            if job == 'cleric':
                player.fighter.job.cleric_level += 1
            elif job == 'fighter':
                player.fighter.job.fighter_level += 1
            elif job == 'thief':
                player.fighter.job.thief_level += 1
            elif job == 'wizard':
                player.fighter.job.wizard_level += 1

            game_state = previous_game_state
        if game_state == GameStates.TARGETING:
            if left_click:
                target_x, target_y = left_click
                if targeting_item.skill:
                    item_use_results = player.skills.use(targeting_item,
                                                         entities=entities,
                                                         fov_map=fov_map,
                                                         target_x=target_x,
                                                         target_y=target_y)
                else:
                    item_use_results = player.inventory.use(targeting_item,
                                                            entities=entities,
                                                            fov_map=fov_map,
                                                            target_x=target_x,
                                                            target_y=target_y)
                player_turn_results.extend(item_use_results)
            elif right_click:
                player_turn_results.append({'targeting_cancelled': True})

        if exit:
            if game_state == GameStates.JOB_MENU:
                game_state = GameStates.CHARACTER_SCREEN
            elif game_state in (GameStates.SHOW_INVENTORY,
                                GameStates.DROP_INVENTORY,
                                GameStates.CHARACTER_SCREEN,
                                GameStates.SKILL_SELECTION):
                game_state = previous_game_state
            elif game_state == GameStates.TARGETING:
                player_turn_results.append({'targeting_cancelled': True})
            else:
                save_game(player, entities, game_map, message_log, game_state)

                return True

        if fullscreen:
            libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())

        for player_turn_result in player_turn_results:
            message = player_turn_result.get('message')
            dead_entity = player_turn_result.get('dead')
            item_added = player_turn_result.get('item_added')
            item_consumed = player_turn_result.get('consumed')
            item_dropped = player_turn_result.get('item_dropped')
            equip = player_turn_result.get('equip')
            targeting = player_turn_result.get('targeting')
            skill_targeting = player_turn_result.get('skill_targeting')
            targeting_cancelled = player_turn_result.get('targeting_cancelled')
            xp = player_turn_result.get('xp')

            if message:
                message_log.add_message(message)

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

                message_log.add_message(message)

            if item_added:
                entities.remove(item_added)

                game_state = GameStates.ENEMY_TURN

            if item_consumed:
                game_state = GameStates.ENEMY_TURN

            if item_dropped:
                entities.append(item_dropped)

                game_state = GameStates.ENEMY_TURN

            if equip:
                equip_results = player.equipment.toggle_equip(equip)

                for equip_result in equip_results:
                    equipped = equip_result.get('equipped')
                    dequipped = equip_result.get('dequipped')

                    if equipped:
                        message_log.add_message(
                            Message('You equipped the {0}'.format(
                                equipped.name)))

                    if dequipped:
                        message_log.add_message(
                            Message('You dequipped the {0}'.format(
                                dequipped.name)))

                game_state = GameStates.ENEMY_TURN

            if targeting:
                previous_game_state = GameStates.PLAYERS_TURN
                game_state = GameStates.TARGETING

                targeting_item = targeting

                message_log.add_message(targeting_item.item.targeting_message)

            if skill_targeting:
                previous_game_state = GameStates.PLAYERS_TURN
                game_state = GameStates.TARGETING

                targeting_item = skill_targeting

                message_log.add_message(targeting_item.skill.targeting_message)

            if targeting_cancelled:
                game_state = previous_game_state

                message_log.add_message(Message('Targeting cancelled'))

            if xp:
                leveled_up = player.level.add_xp(xp)
                message_log.add_message(
                    Message('You gain {0} experience points.'.format(xp)))

                if leveled_up:

                    previous_game_state = game_state
                    game_state = GameStates.LEVEL_UP

        if race:
            if race == 'mern':
                player.fighter.race = 'Human'
                player.fighter.levels_quickly = True
            elif race == 'elf':
                player.fighter.race = 'Elf'
                player.fighter.base_defense += 2
                player.fighter.base_constitution -= 2
            elif race == 'dwarf':
                player.fighter.race = 'Dwarf'
                player.fighter.base_defense -= 2
                player.fighter.base_constitution += 2
            elif race == 'halfling':
                player.fighter.race = 'Halfling'
                player.fighter.base_defense += 4
                player.fighter.base_power -= 3
                player.fighter.base_constitution -= 1
            elif race == 'gnome':
                player.fighter.race = 'Gnome'
                player.fighter.base_constitution += 2
                player.fighter.base_willpower += 2
                player.fighter.base_power -= 4
            elif race == 'draconian':
                player.fighter.race = 'Draconian'
                player.fighter.large = True
                player.fighter.base_constitution += 3
                player.fighter.base_defense -= 4
                player.fighter.base_power += 3
            elif race == 'orc':
                player.fighter.race = 'Orc'
                player.fighter.base_constitution += 1
                player.fighter.base_defense -= 3
                player.fighter.base_power += 2
            elif race == 'goblin':
                player.fighter.race = 'Goblin'
                player.fighter.base_constitution += 1
                player.fighter.base_defense -= 3
                player.fighter.base_power += 2
            elif race == 'fairy':
                player.fighter.race = 'Fairy'
                player.fighter.base_constitution -= 6
                player.fighter.base_defense += 6
                player.fighter.base_power -= 6
                skill_component = Skill(use_function=become_accurate)
                skill = Skill_Entity('Faerie Dance', skill=skill_component)
                player.skills.add_skill(skill)
            elif race == 'turtle':
                player.fighter.race = 'Giant Turtle'
                player.fighter.base_constitution += 8
                player.fighter.base_defense -= 12
                player.fighter.base_power += 3
                player.fighter.large = True
                player.fighter.cant_wear_armour = True
            elif race == 'lizard':
                player.fighter.race = 'Lizardperson'
                skill_component = Skill(
                    use_function=acid_spit,
                    targeting=True,
                    targeting_message=Message(
                        'Left-click a target tile for the spit, or right-click to cancel.',
                        libtcod.light_cyan),
                    damage=25)
                skill = Skill_Entity('Acid Spit', skill=skill_component)
                player.skills.add_skill(skill)
                player.fighter.base_defense -= 2
                player.fighter.base_power += 3
            elif race == 'frog':
                player.fighter.race = 'Frogperson'
                player.fighter.base_defense += 3
                player.fighter.base_power -= 2
                skill_component = Skill(use_function=become_graceful)
                skill = Skill_Entity('Slimy Skin', skill=skill_component)
                player.skills.add_skill(skill)
            elif race == 'giant':
                player.fighter.race = 'Giant'
                player.fighter.base_defense -= 7
                player.fighter.base_power += 5
                player.fighter.base_constitution += 5
                player.fighter.large = True
            elif race == 'troll':
                player.fighter.race = 'Troll'
                player.fighter.base_defense -= 7
                player.fighter.base_power += 4
                player.fighter.base_constitution += 2
                player.fighter.large = True
                player.fighter.carnivore = True
                player.fighter.sharp_claws = True
            elif race == 'skeleton':
                player.fighter.race = 'Skeleton'
                player.fighter.base_power += 1
                player.fighter.base_constitution += 1
                player.fighter.base_defense -= 4
            elif race == 'biter':
                player.fighter.race = 'Biter'
                player.fighter.base_constitution -= 2
                player.fighter.base_defense += 4
                player.player.fighter.sharp_claws = True
            elif race == 'kobold':
                player.fighter.race = 'Kobold'
                player.fighter.base_power -= 3
                player.fighter.base_defense += 3
                player.fighter.large = True
            elif race == 'chaosling':
                player.fighter.race = 'chaosling'
                player.fighter.base_power += 2
                player.fighter.base_defense += 2
                player.fighter.base_constitution += 2
                player.fighter.base_willpower -= 6
                player.fighter.hates_law = True
            elif race == 'reaper':
                player.fighter.race = 'Reaper'
                player.fighter.base_power += 4
                player.fighter.base_constitution += 2
                player.fighter.base_willpower -= 10
                player.fighter.bloodthirsty = True
            elif race == 'nymph':
                player.fighter.race = 'Nymph'
                player.fighter.base_power -= 5
                player.fighter.base_defense += 5
            elif race == 'octopode':
                player.fighter.race = 'Octopode'
                player.fighter.base_defense += 3
                player.fighter.eight_arms = True
                player.fighter.cant_wear_armour = True
            elif race == 'cat':
                player.fighter.race = 'Housecat'
                player.fighter.base_defense += 6
                player.fighter.base_constitution -= 3
            elif race == 'merfolk':
                player.fighter.race = 'Merfolk'
                player.fighter.swimmer = True
                player.fighter.base_defense += 3
                player.fighter.base_constitution += 3
                player.fighter.base_power -= 4
            elif race == 'mud':
                player.fighter.race = 'Mud Man'
                skill_component = Skill(
                    use_function=throw_mudball,
                    targeting=True,
                    targeting_message=Message(
                        'Left-click a target tile for the ball, or right-click to cancel.',
                        libtcod.light_cyan),
                    damage=25)
                skill = Skill_Entity('Throw Mudball', skill=skill_component)
                player.skills.add_skill(skill)
                player.fighter.base_defense += 3
                player.fighter.base_constitution -= 3
            elif race == 'dryad':
                player.fighter.race = 'Dryad'
                player.fighter.one_with_nature = True
                player.fighter.base_power += 4
                player.fighter.base_defence -= 4
            elif race == 'naga':
                player.fighter.race = 'Naga'
                skill_component = Skill(
                    use_function=poison_bite,
                    targeting=True,
                    targeting_message=Message(
                        'Left-click a target tile for the bite, or right-click to cancel.',
                        libtcod.light_cyan),
                    damage=25)
                skill = Skill_Entity('Naga Bite', skill=skill_component)
                player.skills.add_skill(skill)
                player.fighter.base_defense += 4
                player.fighter.base_power -= 4
                player.fighter.no_legs = True
            elif race == 'golem':
                player.fighter.race = 'Rogue Golem'
                player.fighter.golem = True
                player.fighter.base_defense += 10
                player.fighter.base_power += 10
                player.fighter.base_willpower += 13
            elif race == 'tengu':
                player.fighter.race = 'Tengu'
                player.fighter.base_defense += 4
                player.fighter.base_power -= 2
                player.fighter.base_constitution -= 3
            libtcod.console_flush()
            game_state = GameStates.PLAYERS_TURN

        if game_state == GameStates.ENEMY_TURN:
            if player.fighter.nutrition < 1:
                game_state = GameStates.PLAYER_DEAD
                kill_player(player)

            for entity in entities:
                if entity.ai:
                    enemy_turn_results = entity.ai.take_turn(
                        player, fov_map, game_map, entities)

                    for enemy_turn_result in enemy_turn_results:
                        message = enemy_turn_result.get('message')
                        dead_entity = enemy_turn_result.get('dead')

                        if message:
                            message_log.add_message(message)

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

                            message_log.add_message(message)

                            if game_state == GameStates.PLAYER_DEAD:
                                break

                    if game_state == GameStates.PLAYER_DEAD:
                        break
            else:
                game_state = GameStates.PLAYERS_TURN
def play_game(player, entities, game_map, message_log, root_console, panel,
              hp_bar, xp_bar, constants):
    root_console.clear(fg=(255, 255, 255))
    fov_map = initialize_fov(game_map)
    fov_recompute = True

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

    game_state = GameStates.PLAYERS_TURN
    turn_number = 0
    turns_passed = 0
    start_turn = 0
    previous_game_state = game_state

    targeting_item = None
    exploring = False
    resting = False
    to_down_stairs = False

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

        if fov_recompute:
            recompute_fov(fov_map, player.x, player.y, constants['fov_radius'],
                          constants['fov_light_walls'],
                          constants['fov_algorithm'])
            render_all(
                root_console, panel, hp_bar, xp_bar, entities, player,
                game_map, fov_map, message_log, constants['root_width'],
                constants['root_height'], constants['game_window_width'],
                constants['game_window_height'], constants['panel_width'],
                constants['panel_height'], constants['stat_bar_width'],
                constants['stat_bar_height'], constants['fx_panel_width'],
                constants['fx_panel_height'], constants['camera_width'],
                constants['camera_height'], game_state, turn_number)
            fov_recompute = False
            custrender.clear((0, 0, 0))
            custrender.accumulate(
                root_console, custrender.get_viewport(root_console, True,
                                                      True))
            custrender.present()
            clear_all(root_console, entities)

        action = handle_keys(key, game_state)
        mouse_action = handle_mouse(mouse)

        move = action.get('move')
        wait = action.get('wait')
        rest = action.get('rest')
        pickup = action.get('pickup')
        show_inventory = action.get('show_inventory')
        drop_inventory = action.get('drop_inventory')
        show_loadout = action.get('show_loadout')
        look = action.get('look')
        inventory_index = action.get('inventory_index')
        loadout_index = action.get('loadout_index')
        take_stairs = action.get('take_stairs')
        level_up = action.get('level_up')
        show_character_screen = action.get('show_character_screen')
        show_ability_screen = action.get('show_ability_screen')
        esc_menu = action.get('esc_menu')
        help = action.get('help')
        exit = action.get('exit')
        quit = action.get('quit')
        fullscreen = action.get('fullscreen')
        auto_explore = action.get('auto_explore')
        left_click = mouse_action.get('left_click')
        right_click = mouse_action.get('right_click')

        target_x = player.x
        target_y = player.y
        player_turn_results = []

        # For all actions that do not return to the main menu, recompute fov (prevents off-screen window drawing errors)
        if action != quit and action != fullscreen and not resting:
            fov_recompute = True
            root_console.clear(fg=(255, 255, 255))

        if move and game_state == GameStates.PLAYERS_TURN:
            if exploring:
                exploring = False
                previous_game_state = game_state
                message_log.add_message(
                    Message('Autoexploration cancelled.', libtcod.yellow))
            elif resting:
                resting = False
                previous_game_state = game_state
                message_log.add_message(
                    Message('You stop resting.', libtcod.yellow))
            elif to_down_stairs:
                to_down_stairs = False
                previous_game_state = game_state
                message_log.add_message(
                    Message('You stop heading towards the stairs.',
                            libtcod.yellow))

            dx, dy = move
            destination_x = player.x + dx
            destination_y = player.y + dy
            if not game_map.is_blocked(destination_x, destination_y):
                target = get_blocking_entities_at_location(
                    entities, destination_x, destination_y)
                if target:
                    attack_results = player.fighter.attack(target)
                    player_turn_results.extend(attack_results)
                else:
                    player.move(dx, dy, game_map)
                game_state = GameStates.ENEMY_TURN

        if auto_explore and game_state == GameStates.PLAYERS_TURN:
            if entities_in_fov(entities, fov_map, message_log):
                game_state = GameStates.PLAYERS_TURN
            elif GameMap.explore(game_map, player, message_log) is True:
                game_state = GameStates.ENEMY_TURN
                exploring = True
            else:
                exploring = False

        if exploring and game_state == GameStates.PLAYERS_TURN:
            if entities_in_fov(entities, fov_map, message_log):
                game_state = GameStates.PLAYERS_TURN
                exploring = False
            elif GameMap.explore(game_map, player, message_log) is True:
                game_state = GameStates.ENEMY_TURN
                exploring = True
            else:
                exploring = False

        elif wait:
            game_state = GameStates.ENEMY_TURN

        elif rest and game_state == GameStates.PLAYERS_TURN:
            if player.fighter.current_hp == player.fighter.base_max_hp:
                message_log.add_message(
                    Message('You are already at full health.', libtcod.yellow))
            elif entity_in_fov(entities, fov_map):
                message_log.add_message(
                    Message('You cannot rest when enemies are nearby.',
                            libtcod.yellow))
            elif player.fighter.current_hp < player.fighter.base_max_hp:
                game_state = GameStates.ENEMY_TURN
                resting = True
                start_turn = turn_number
            else:
                resting = False

        if resting and game_state == GameStates.PLAYERS_TURN:
            if player.fighter.current_hp == player.fighter.base_max_hp:
                resting = False
                message_log.add_message(
                    Message(
                        'You rest for {0} turns, returning to max HP.'.format(
                            turns_passed), libtcod.yellow))
            elif entities_in_fov(entities, fov_map, message_log):
                message_log.add_message(
                    Message(
                        'You rested for a total of {0} turns.'.format(
                            turns_passed), libtcod.yellow))
                resting = False
                fov_recompute = True
            else:
                turns_passed = turn_number - start_turn
                game_state = GameStates.ENEMY_TURN

        elif pickup and game_state == GameStates.PLAYERS_TURN:
            for entity in entities:
                if entity.item and entity.x == player.x and entity.y == player.y:
                    pickup_results = player.inventory.pick_up(player, entity)
                    entities.remove(entity)
                    player_turn_results.extend(pickup_results)
                    break
            else:
                message_log.add_message(
                    Message('There is nothing here to pick up.',
                            libtcod.yellow))

        if show_inventory:
            previous_game_state = game_state
            game_state = GameStates.SHOW_INVENTORY

        if drop_inventory:
            previous_game_state = game_state
            game_state = GameStates.DROP_INVENTORY

        if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len(
                player.inventory.inv_items):
            item = player.inventory.inv_items[inventory_index]

            if game_state == GameStates.SHOW_INVENTORY:
                player_turn_results.extend(
                    player.inventory.use(player,
                                         item,
                                         entities=entities,
                                         fov_map=fov_map))
            elif game_state == GameStates.DROP_INVENTORY:
                player_turn_results.extend(
                    player.inventory.drop_item(player, item))

        if show_loadout:
            previous_game_state = game_state
            game_state = GameStates.SHOW_LOADOUT

        if loadout_index is not None and previous_game_state != GameStates.PLAYER_DEAD and loadout_index < len(
                player.inventory.equip_items):
            item = player.inventory.equip_items[loadout_index]
            if game_state == GameStates.SHOW_LOADOUT:
                player_turn_results.extend(
                    player.inventory.dequip(player, item))
            elif game_state == GameStates.DROP_INVENTORY:
                player_turn_results.extend(
                    player.inventory.drop_item(player, item))

        if look:
            previous_game_state = game_state
            game_state = GameStates.LOOK

        if take_stairs and game_state == GameStates.PLAYERS_TURN:
            for entity in entities:
                if entity.stairs and entity.x == player.x and entity.y == player.y:
                    entities = game_map.next_floor(player)
                    fov_map = initialize_fov(game_map)
                    message_log.add_message(
                        Message(
                            f'You descend to level {game_map.dungeon_level} of the '
                            f'SludgeWorks...', libtcod.yellow))
                    break
            else:
                if entities_in_fov(entities, fov_map, message_log):
                    game_state = GameStates.PLAYERS_TURN
                elif GameMap.to_down_stairs(game_map, player, entities,
                                            message_log) is True:
                    game_state = GameStates.ENEMY_TURN
                    to_down_stairs = True

        if to_down_stairs and game_state == GameStates.PLAYERS_TURN:
            if entities_in_fov(entities, fov_map, message_log):
                game_state = GameStates.PLAYERS_TURN
                to_down_stairs = False
            elif GameMap.to_down_stairs(game_map, player, entities,
                                        message_log) is True:
                game_state = GameStates.ENEMY_TURN
            else:
                to_down_stairs = False

        if level_up:
            hit_dice = roll_dice(1, 8)
            player.fighter.level += 1
            player.fighter.base_max_hp += roll_dice(
                1, hit_dice + player.fighter.vitality_modifier)
            if level_up == 'str':
                player.fighter.base_strength += 1
            elif level_up == 'agi':
                player.fighter.base_dexterity += 1
            game_state = previous_game_state

        if show_character_screen:
            previous_game_state = game_state
            game_state = GameStates.CHARACTER_SCREEN

        if show_ability_screen:
            previous_game_state = game_state
            game_state = GameStates.ABILITY_SCREEN

        if game_state == GameStates.TARGETING:
            libtcod.console_wait_for_keypress(True)
            target_overlay(root_console, constants['game_window_width'],
                           constants['game_window_height'], target_x, target_y)
            if move:
                dx, dy = move
                target_x += dx
                target_y += dy
            if left_click:
                target_x, target_y = left_click
                item_use_results = player.inventory.use(player,
                                                        targeting_item,
                                                        entities=entities,
                                                        fov_map=fov_map,
                                                        target_x=target_x,
                                                        target_y=target_y)
                player_turn_results.extend(item_use_results)
            elif right_click:
                player_turn_results.append({'targeting_cancelled': True})

        if esc_menu:
            if exploring:
                exploring = False
                previous_game_state = game_state
                message_log.add_message(
                    Message('Autoexploration cancelled.', libtcod.yellow))
            elif resting:
                resting = False
                previous_game_state = game_state
                message_log.add_message(
                    Message('You stop resting.', libtcod.yellow))
            elif to_down_stairs:
                to_down_stairs = False
                previous_game_state = game_state
                message_log.add_message(
                    Message('You stop heading towards the stairs.',
                            libtcod.yellow))
            else:
                previous_game_state = game_state
                game_state = GameStates.ESC_MENU

        if help:
            game_state = GameStates.HELP_MENU

        if exit:
            if game_state == GameStates.TARGETING:
                player_turn_results.append({'targeting_cancelled': True})
                return True
            else:
                game_state = previous_game_state

        if quit and not game_state == GameStates.PLAYER_DEAD:
            save_game(player, entities, game_map, message_log, game_state)
            return True
        elif quit:
            delete_char_save()
            return True

        if fullscreen:
            libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())

        for player_turn_result in player_turn_results:
            message = player_turn_result.get('message')
            dead_entity = player_turn_result.get('dead')
            item_added = player_turn_result.get('item_added')
            item_consumed = player_turn_result.get('consumed')
            item_dropped = player_turn_result.get('item_dropped')
            equipped = player_turn_result.get('equipped')
            dequipped = player_turn_result.get('dequipped')
            targeting = player_turn_result.get('targeting')
            targeting_cancelled = player_turn_result.get('targeting_cancelled')
            xp = player_turn_result.get('xp')

            if message:
                message_log.add_message(message)

            if dead_entity:
                if dead_entity == player:
                    message, game_state = kill_player(dead_entity)
                else:
                    message = kill_monster(dead_entity, entities)
                message_log.add_message(message)

            if item_added or item_consumed or equipped or dequipped:
                game_state = GameStates.ENEMY_TURN

            if item_dropped:
                entities.append(item_dropped)
                game_state = GameStates.ENEMY_TURN

            if targeting:
                previous_game_state = GameStates.PLAYERS_TURN
                game_state = GameStates.TARGETING
                targeting_item = targeting
                message_log.add_message(targeting_item.item.targeting_message)

            if targeting_cancelled:
                game_state = previous_game_state
                message_log.add_message(Message('Targeting cancelled'))

            if xp:
                leveled_up = player.level.add_xp(xp)
                message_log.add_message(
                    Message('You gain {0} experience points.'.format(xp)))
                if leveled_up:
                    message_log.add_message(
                        Message(
                            'You level up! You are now level {0}'.format(
                                player.level.current_level) + '!',
                            libtcod.yellow))
                    previous_game_state = game_state
                    game_state = GameStates.LEVEL_UP

        if game_state == GameStates.ENEMY_TURN:
            for entity in entities:
                if entity.name == 'Phosphorescent Dahlia' and entity_in_fov(
                        entities, fov_map):
                    # Cycle through colours for the phosphorescent dahlia
                    dahlia_colour = [
                        libtcod.light_azure, libtcod.azure, libtcod.dark_azure
                    ]
                    entity.colour = choice(dahlia_colour)
                if entity.ai:
                    if entity.regenerates:
                        # Heal-over time effect for enemies that regenerate
                        if turn_number % 4 == 0:
                            if entity.fighter.current_hp < entity.fighter.base_max_hp:
                                entity.fighter.current_hp += 1

                    enemy_turn_results = entity.ai.take_turn(
                        player, fov_map, game_map, entities)

                    for enemy_turn_result in enemy_turn_results:
                        message = enemy_turn_result.get('message')
                        dead_entity = enemy_turn_result.get('dead')

                        if message:
                            message_log.add_message(message)

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

                            message_log.add_message(message)

                            if game_state == GameStates.PLAYER_DEAD:
                                break
                    if game_state == GameStates.PLAYER_DEAD:
                        break

            else:
                # Heal-over time effect for the player
                if turn_number % 4 == 0:
                    if player.fighter.current_hp < player.fighter.base_max_hp:
                        player.fighter.current_hp += 1
                turn_number += 1
                game_state = GameStates.PLAYERS_TURN
Exemple #21
0
def target_with_accuracy(owner, target_x, target_y, accuracy, game_map,
                         entities):
    blocked = False
    acc_roll = libtcod.random_get_int(0, 0, 100)
    if DEBUG:
        print('DEBUG {} actual target: {}, {}'.format(owner.name, target_x,
                                                      target_y))
        print('DEBUG {} roll: {}, accuracy: {}'.format(owner.name, acc_roll,
                                                       accuracy))
    if acc_roll < accuracy:  # hit! return target
        newtarget_x = target_x
        newtarget_y = target_y
        hit = 'yes'
    else:  # miss! continue the line a bit longer to allow the projectile to keep moving
        xoff = libtcod.random_get_int(0, 1, 1)
        yoff = libtcod.random_get_int(0, 1, 1)
        pos_or_neg = libtcod.random_get_int(0, 0, 1)
        if pos_or_neg:
            target_x = target_x + xoff
        else:
            target_x = target_x - xoff
        pos_or_neg = libtcod.random_get_int(0, 0, 1)
        if pos_or_neg:
            target_y = target_y + yoff
        else:
            target_y = target_y - yoff

        # build new line extending out much further
        newtarget_x = 2 * target_x - 1 * owner.x
        newtarget_y = 2 * target_y - 1 * owner.y

        # make sure its in the game map
        if newtarget_x <= 0:
            newtarget_y = newtarget_y - newtarget_x
            newtarget_x = 0
            if DEBUG:
                print('DEBUG {} out_of_map, using {}, {}'.format(
                    owner.name, newtarget_x, newtarget_y))
        elif newtarget_x >= game_map.width - 1:
            newtarget_y = newtarget_y - (newtarget_x - game_map.width - 1)
            newtarget_x = game_map.width - 1
            if DEBUG:
                print('DEBUG {} out_of_map, using {}, {}'.format(
                    owner.name, newtarget_x, newtarget_y))
        if newtarget_y <= 0:
            newtarget_x = newtarget_x - newtarget_y
            newtarget_y = 0
            if DEBUG:
                print('DEBUG {} out_of_map, using {}, {}'.format(
                    owner.name, newtarget_x, newtarget_y))
        elif newtarget_y >= game_map.height - 1:
            newtarget_x = newtarget_x - (newtarget_y - game_map.height - 1)
            newtarget_y = game_map.height - 1
            if DEBUG:
                print('DEBUG {} out_of_map, using {}, {}'.format(
                    owner.name, newtarget_x, newtarget_y))

        for pts in libtcod.line_iter(owner.x, owner.y, newtarget_x,
                                     newtarget_y):
            if game_map.is_blocked(
                    pts[0], pts[1]) or get_blocking_entities_at_location(
                        entities, pts[0], pts[1]):
                if (pts[0], pts[1]) != (owner.x, owner.y):
                    if DEBUG:
                        print('DEBUG {} blocked'.format(owner.name))
                    newtarget_x = pts[0]
                    newtarget_y = pts[1]
                    break
        hit = 'no'
        if DEBUG:
            print('DEBUG {} failed roll, new target: {}, {}, player: {}, {}'.
                  format(owner.name, newtarget_x, newtarget_y, owner.x,
                         owner.y))
    if game_map.is_blocked(newtarget_x, newtarget_y):
        blocked = True

    return hit, blocked, newtarget_x, newtarget_y
Exemple #22
0
def main():
    screen_width = 80
    screen_height = 50

    bar_width = 20
    panel_height = 7
    paney_y = screen_height - panel_height

    message_x = bar_width + 2
    message_width = screen_width - bar_width - 2
    message_height = panel_height - 1

    map_width = 80
    map_height = 43

    room_max_size = 10
    room_min_size = 6
    max_rooms = 30

    fov_algorithm = 1
    fov_light_walls = True
    fov_radius = 10

    max_monsters_per_room = 3

    colors = {
        'dark_wall': libtcod.Color(0, 0, 100),
        'dark_ground': libtcod.Color(50, 50, 150),
        'light_wall': libtcod.Color(130, 110, 50),
        #'light_wall': libtcod.Color(175, 170, 135),
        'light_ground': libtcod.Color(200, 180, 50)
        #'light_ground': libtcod.Color(235, 220, 170)
    }

    fighter_component = Fighter(hp=30, defense=2, power=5)
    player = Entity(0,
                    0,
                    '@',
                    libtcod.white,
                    'Player',
                    blocks=True,
                    render_order=RenderOrder.ACTOR,
                    fighter=fighter_component)

    entities = [player]

    # sets font for console
    libtcod.console_set_custom_font(
        'arial12x12.png',
        libtcod.FONT_TYPE_GRAYSCALE | libtcod.FONT_LAYOUT_TCOD)

    libtcod.console_init_root(screen_width, screen_height, 'libtcod tutorial',
                              False)

    con = libtcod.console.Console(screen_width, screen_height)
    panel = libtcod.console.Console(screen_width, panel_height)

    # initialize the game map
    game_map = GameMap(map_width, map_height)
    game_map.make_map(max_rooms, room_min_size, room_max_size, map_width,
                      map_height, player, entities, max_monsters_per_room)

    fov_recompute = True

    fov_map = initialize_fov(game_map)

    message_log = Messagelog(message_x, message_width, message_height)

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

    game_state = GamesStates.PLAYERS_TURN

    while not libtcod.console_is_window_closed():
        # captures new events
        libtcod.sys_check_for_event(
            libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse)

        if fov_recompute:
            recompute_fov(fov_map, player.x, player.y, fov_radius,
                          fov_light_walls, fov_algorithm)

        render_all(con, panel, entities, player, game_map, fov_map,
                   fov_recompute, message_log, screen_width, screen_height,
                   bar_width, panel_height, paney_y, mouse, colors)

        fov_recompute = False

        libtcod.console_flush()

        clear_all(con, entities)

        action = handle_keys(key)

        move = action.get('move')
        exit = action.get('exit')
        fullscreen = action.get('fullscreen')

        player_turn_results = []

        if move and game_state == GamesStates.PLAYERS_TURN:
            dx, dy = move
            destinaiton_x = player.x + dx
            destination_y = player.y + dy

            if not game_map.is_blocked(destinaiton_x, destination_y):
                target = get_blocking_entities_at_location(
                    entities, destinaiton_x, destination_y)

                if target:
                    attack_results = player.fighter.attack(target)
                    player_turn_results.extend(attack_results)
                else:
                    player.move(dx, dy)

                    fov_recompute = True

                game_state = GamesStates.ENEMY_TURN

        if exit:
            return True

        if fullscreen:
            libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())

        for player_turn_result in player_turn_results:
            message = player_turn_result.get('message')
            dead_entity = player_turn_result.get('dead')

            if message:
                message_log.add_message(message)

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

                message_log.add_message(message)

        if game_state == GamesStates.ENEMY_TURN:
            for entity in entities:
                if entity.ai:
                    enemy_turn_results = entity.ai.take_turn(
                        player, fov_map, game_map, entities)

                    for enemy_turn_result in enemy_turn_results:
                        message = enemy_turn_result.get('message')
                        dead_entity = enemy_turn_result.get('dead')

                        if message:
                            message_log.add_message(message)

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

                            message_log.add_message(message)

                            if game_state == GamesStates.PLAYER_DEAD:
                                break

                    if game_state == GamesStates.PLAYER_DEAD:
                        break

            else:
                game_state = GamesStates.PLAYERS_TURN
Exemple #23
0
def play_game(player, entities, game_map, message_log, game_state, con, panel,
              constants):
    fov_recompute = True

    fov_map = initialize_fov(game_map)

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

    game_state = GameStates.PLAYER_TURN
    previous_game_state = game_state

    targeting_item = None

    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.x, player.y, constants['fov_radius'],
                          constants['fov_light_walls'],
                          constants['fov_algorithm'])

        render_all(con, panel, entities, player, 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'], game_state)

        fov_recompute = False

        libtcod.console_flush()

        clear_all(con, entities)

        action = handle_keys(key, game_state)
        mouse_action = handle_mouse(mouse)

        move = action.get('move')
        pickup = action.get('pickup')
        show_inventory = action.get('show_inventory')
        drop_inventory = action.get('drop_inventory')
        inventory_index = action.get('inventory_index')
        exit = action.get('exit')
        fullscreen = action.get('fullscreen')

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

        player_turn_results = []

        if move and game_state == GameStates.PLAYER_TURN:
            dx, dy = move
            destination_x = player.x + dx
            destination_y = player.y + dy

            if not game_map.is_blocked(destination_x, destination_y):
                target = get_blocking_entities_at_location(
                    entities, destination_x, destination_y)

                if target:
                    attack_results = player.fighter.attack(target)
                    player_turn_results.extend(attack_results)
                else:
                    player.move(dx, dy)

                    fov_recompute = True

                game_state = GameStates.ENEMY_TURN

        elif pickup and game_state == GameStates.PLAYER_TURN:
            for entity in entities:
                if entity.item and entity.x == player.x and entity.y == player.y:
                    pickup_results = player.inventory.add_item(entity)
                    player_turn_results.extend(pickup_results)

                    break
            else:
                message_log.add_message(
                    Message('There is nothing here to pick up.',
                            libtcod.yellow))

        if show_inventory:
            previous_game_state = game_state
            game_state = GameStates.SHOW_INVENTORY

        if drop_inventory:
            previous_game_state = game_state
            game_state = GameStates.DROP_INVENTORY

        if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len(
                player.inventory.items):
            item = player.inventory.items[inventory_index]

            if game_state == GameStates.SHOW_INVENTORY:
                player_turn_results.extend(
                    player.inventory.use(item,
                                         entities=entities,
                                         fov_map=fov_map))
            elif game_state == GameStates.DROP_INVENTORY:
                player_turn_results.extend(player.inventory.drop_item(item))

        if game_state == GameStates.TARGETING:
            if left_click:
                target_x, target_y = left_click

                item_use_results = player.inventory.use(targeting_item,
                                                        entities=entities,
                                                        fov_map=fov_map,
                                                        target_x=target_x,
                                                        target_y=target_y)
                player_turn_results.extend(item_use_results)
            elif right_click:
                player_turn_results.append({'targeting_cancelled': True})

        if exit:
            if game_state in (GameStates.SHOW_INVENTORY,
                              GameStates.DROP_INVENTORY):
                game_state = previous_game_state
            elif game_state == GameStates.TARGETING:
                player_turn_results.append({'targeting_cancelled': True})
            else:
                save_game(player, entities, game_map, message_log, game_state)

                return True

        if fullscreen:
            libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())

        for player_turn_result in player_turn_results:
            message = player_turn_result.get('message')
            dead_entity = player_turn_result.get('dead')
            item_added = player_turn_result.get('item_added')
            item_consumed = player_turn_result.get('consumed')
            item_dropped = player_turn_result.get('item_dropped')
            targeting = player_turn_result.get('targeting')
            targeting_cancelled = player_turn_result.get('targeting_cancelled')

            if message:
                message_log.add_message(message)

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

                message_log.add_message(message)

            if item_added:
                entities.remove(item_added)

                game_state = GameStates.ENEMY_TURN

            if item_consumed:
                game_state = GameStates.ENEMY_TURN

            if item_dropped:
                entities.append(item_dropped)

                game_state = GameStates.ENEMY_TURN

            if targeting:
                previous_game_state = GameStates.PLAYER_TURN
                game_state = GameStates.TARGETING

                targeting_item = targeting

                message_log.add_message(targeting_item.item.targeting_message)

            if targeting_cancelled:
                game_state = previous_game_state

                message_log.add_message(Message('Targeting cancelled'))

        if game_state == GameStates.ENEMY_TURN:
            for entity in entities:
                if entity.ai:
                    enemy_turn_results = entity.ai.take_turn(
                        player, fov_map, game_map, entities)

                    for enemy_turn_result in enemy_turn_results:
                        message = enemy_turn_result.get('message')
                        dead_entity = enemy_turn_result.get('dead')

                        if message:
                            message_log.add_message(message)

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

                            message_log.add_message(message)

                            if game_state == GameStates.PLAYER_DEAD:
                                break

                    if game_state == GameStates.PLAYER_DEAD:
                        break
            else:
                game_state = GameStates.PLAYER_TURN
Exemple #24
0
def main():
    screen_width = 80
    screen_height = 50

    bar_width = 20
    panel_height = 7
    panel_y = screen_height - panel_height

    message_x = bar_width + 2
    message_width = screen_width - bar_width - 2
    message_height = panel_height - 1

    map_width = 80
    map_height = 43

    room_max_size = 10
    room_min_size = 6
    max_rooms = 30

    fov_algorithm = 'BASIC'
    fov_light_walls = True
    fov_radius = 10

    max_monsters_per_room = 3
    max_items_per_room = 2

    colors = {
        'dark_wall': (0, 0, 100),
        'dark_ground': (50, 50, 150),
        'light_wall': (130, 110, 50),
        'light_ground': (200, 180, 50),
        'desaturated_green': (63, 127, 63),
        'darker_green': (0, 127, 0),
        'dark_red': (191, 0, 0),
        'white': (255, 255, 255),
        'black': (0, 0, 0),
        'red': (255, 0, 0),
        'orange': (255, 127, 0),
        'light_red': (255, 114, 114),
        'darker_red': (127, 0, 0),
        'violet': (127, 0, 255),
        'yellow': (255, 255, 0),
        'blue': (0, 0, 255),
        'green': (0, 255, 0),
        'light_cyan': (114, 255, 255),
        'light_pink': (255, 114, 184)
    }

    fighter_component = Fighter(hp=30, defense=2, power=5)
    inventory_component = Inventory(26)
    player = Entity(0, 0, '@', (255, 255, 255), 'Player', blocks=True, render_order=RenderOrder.ACTOR,
                    fighter=fighter_component, inventory=inventory_component)
    entities = [player]

    tdl.set_font('arial10x10.png', greyscale=True, altLayout=True)

    root_console = tdl.init(screen_width, screen_height, title='Roguelike Tutorial Revised')
    con = tdl.Console(screen_width, screen_height)
    panel = tdl.Console(screen_width, panel_height)

    game_map = GameMap(map_width, map_height)
    make_map(game_map, max_rooms, room_min_size, room_max_size, map_width, map_height, player, entities,
             max_monsters_per_room, max_items_per_room, colors)

    fov_recompute = True

    message_log = MessageLog(message_x, message_width, message_height)

    mouse_coordinates = (0, 0)

    game_state = GameStates.PLAYERS_TURN
    previous_game_state = game_state
    

    while not tdl.event.is_window_closed():
        if fov_recompute:
            game_map.compute_fov(player.x, player.y, fov=fov_algorithm, radius=fov_radius, light_walls=fov_light_walls)

        render_all(con, panel, entities, player, game_map, fov_recompute, root_console, message_log, screen_width,
                   screen_height, bar_width, panel_height, panel_y, mouse_coordinates, colors, game_state)
        tdl.flush()

        clear_all(con, entities)

        fov_recompute = False

        for event in tdl.event.get():
            if event.type == 'KEYDOWN':
                user_input = event
                break
            elif event.type == 'MOUSEMOTION':
                mouse_coordinates = event.cell
            elif event.type == 'MOUSEDOWN':
                user_mouse_input = event
                break
        else:
            user_input = None
            user_mouse_input = None

        if not (user_input or user_mouse_input):
            continue

        action = handle_keys(user_input, game_state)
        mouse_action = handle_mouse(user_mouse_input)

        move = action.get('move')
        pickup = action.get('pickup')
        show_inventory = action.get('show_inventory')
        drop_inventory = action.get('drop_inventory')
        inventory_index = action.get('inventory_index')
        exit = action.get('exit')
        fullscreen = action.get('fullscreen')

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

        player_turn_results = []

        if move and game_state == GameStates.PLAYERS_TURN:
            dx, dy = move
            destination_x = player.x + dx
            destination_y = player.y + dy

            if game_map.walkable[destination_x, destination_y]:
                target = get_blocking_entities_at_location(entities, destination_x, destination_y)

                if target:
                    attack_results = player.fighter.attack(target)
                    player_turn_results.extend(attack_results)
                else:
                    player.move(dx, dy)

                    fov_recompute = True

                game_state = GameStates.ENEMY_TURN

        elif pickup and game_state == GameStates.PLAYERS_TURN:
            for entity in entities:
                if entity.item and entity.x == player.x and entity.y == player.y:
                    pickup_results = player.inventory.add_item(entity, colors)
                    player_turn_results.extend(pickup_results)

                    break
            else:
                message_log.add_message(Message('There is nothing here to pick up.', colors.get('yellow')))

        if show_inventory:
            previous_game_state = game_state
            game_state = GameStates.SHOW_INVENTORY

        if drop_inventory:
            previous_game_state = game_state
            game_state = GameStates.DROP_INVENTORY

        if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len(
                player.inventory.items):
            item = player.inventory.items[inventory_index]

            if game_state == GameStates.SHOW_INVENTORY:
                player_turn_results.extend(player.inventory.use(item, colors, entities=entities, game_map=game_map))
            elif game_state == GameStates.DROP_INVENTORY:
                player_turn_results.extend(player.inventory.drop_item(item, colors))

        if game_state == GameStates.TARGETING:
            if left_click:
                target_x, target_y = left_click

                item_use_results = player.inventory.use(targeting_item, colors, entities=entities, game_map=game_map, target_x=target_x, target_y=target_y)
                player_turn_results.extend(item_use_results)
            elif right_click:
                player_turn_results.append({'targeting_cancelled':True})

        if exit:
            if game_state in (GameStates.SHOW_INVENTORY, GameStates.DROP_INVENTORY):
                game_state = previous_game_state
            elif game_state == GameStates.TARGETING:
                player_turn_results.append({'targeting_cancelled': True})
            else:
                return True

        if fullscreen:
            tdl.set_fullscreen(not tdl.get_fullscreen())

        for player_turn_result in player_turn_results:
            message = player_turn_result.get('message')
            dead_entity = player_turn_result.get('dead')
            item_added = player_turn_result.get('item_added')
            item_consumed = player_turn_result.get('consumed')
            item_dropped = player_turn_result.get('item_dropped')
            targeting = player_turn_result.get('targeting')
            targeting_cancelled = player_turn_result.get('targeting_cancelled')

            if message:
                message_log.add_message(message)

            if targeting_cancelled:
                game_state = previous_game_state
                message_log.add_message(Message('Targeting cancelled.'))

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

                message_log.add_message(message)

            if item_added:
                entities.remove(item_added)

                game_state = GameStates.ENEMY_TURN

            if item_consumed:
                game_state = GameStates.ENEMY_TURN

            if item_dropped:
                entities.append(item_dropped)

                game_state = GameStates.ENEMY_TURN

            if targeting:
                previous_game_state = GameStates.PLAYERS_TURN
                game_state = GameStates.TARGETING

                targeting_item = targeting

                message_log.add_message(targeting_item.item.targeting_message)

        if game_state == GameStates.ENEMY_TURN:
            for entity in entities:
                if entity.ai:
                    enemy_turn_results = entity.ai.take_turn(player, game_map, entities)

                    for enemy_turn_result in enemy_turn_results:
                        message = enemy_turn_result.get('message')
                        dead_entity = enemy_turn_result.get('dead')

                        if message:
                            message_log.add_message(message)

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

                            message_log.add_message(message)

                            if game_state == GameStates.PLAYER_DEAD:
                                break

                    if game_state == GameStates.PLAYER_DEAD:
                        break
            else:
                game_state = GameStates.PLAYERS_TURN
Exemple #25
0
def main():
    constants = get_constants()

    libtcod.console_set_custom_font(
        'arial10x10.png',
        libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD)

    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, entities, game_map, message_log, game_state = get_game_variables(
        constants)

    fov_recompute = True  # used to tell algo when to change field of view, i.e. only when moving not when standing still/attacking

    fov_map = initialize_fov(game_map)

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

    previous_game_state = game_state  # Used to not skip a players turn if they do something like pick up an item

    targeting_item = None

    while not libtcod.console_is_window_closed(
    ):  # a loop that won't end until the game window is closed
        libtcod.sys_check_for_event(
            libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE, key, mouse
        )  # this captures user input and updates the key/mouse variables above

        if fov_recompute:
            recompute_fov(
                fov_map, player.x, player.y, constants['fov_radius'],
                constants['fov_light_walls'],
                constants['fov_algorithm'])  # coming from fov_functions

        render_all(
            con, panel, entities, player, 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'], game_state
        )  # con is the current console, entities is drawn in render_functions

        fov_recompute = False

        libtcod.console_flush()  # this presents everything on screen

        clear_all(
            con, entities
        )  # put a blank below our character so it doesn't leave a trail, see render_functions.py
        """Action Handling"""
        action = handle_keys(
            key, game_state
        )  # calls our handle keys function from the input_handlers file, using our key variable, to result in a dictionary called action
        mouse_action = handle_mouse(mouse)

        move = action.get(
            'move'
        )  # uses the action dictionary created above to return move, exit, pickup or fullscreen from handle_keys function
        pickup = action.get('pickup')
        show_inventory = action.get('show_inventory')
        drop_inventory = action.get('drop_inventory')
        inventory_index = action.get('inventory_index')
        exit = action.get('exit')
        fullscreen = action.get('fullscreen')

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

        player_turn_results = []

        if move and game_state == GameStates.PLAYERS_TURN:
            dx, dy = move
            destination_x = player.x + dx
            destination_y = player.y + dy

            if not game_map.is_blocked(destination_x, destination_y):
                target = get_blocking_entities_at_location(
                    entities, destination_x, destination_y)

                if target:  # i.e. does something to the target blocking the way
                    attack_results = player.fighter.attack(target)
                    player_turn_results.extend(attack_results)

                else:
                    player.move(dx, dy)  # gets move function from entity class

                    fov_recompute = True  # sets fov to True (i.e. to change) when we move

                game_state = GameStates.ENEMY_TURN  # switches it to the enemies turn after moving

        elif pickup and game_state == GameStates.PLAYERS_TURN:
            for entity in entities:
                if entity.item and entity.x == player.x and entity.y == player.y:
                    pickup_results = player.inventory.add_item(entity)
                    player_turn_results.extend(pickup_results)

                    break
            else:
                message_log.add_message(
                    Message('There is nothing here to pick up.',
                            libtcod.yellow))

        if show_inventory:
            previous_game_state = game_state  # ref'd at top, stops it skipping to enemies turn
            game_state = GameStates.SHOW_INVENTORY  # switching to this game state with different keys

        if drop_inventory:
            previous_game_state = game_state
            game_state = GameStates.DROP_INVENTORY

        if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len(
                player.inventory.items):
            item = player.inventory.items[inventory_index]

            if game_state == GameStates.SHOW_INVENTORY:
                player_turn_results.extend(
                    player.inventory.use(item,
                                         entities=entities,
                                         fov_map=fov_map))
            elif game_state == GameStates.DROP_INVENTORY:
                player_turn_results.extend(player.inventory.drop_item(item))

        if game_state == GameStates.TARGETING:
            if left_click:
                target_x, target_y = left_click

                item_use_results = player.inventory.use(targeting_item,
                                                        entities=entities,
                                                        fov_map=fov_map,
                                                        target_x=target_x,
                                                        target_y=target_y)
                player_turn_results.extend(item_use_results)
            elif right_click:
                player_turn_results.append({'targeting_cancelled': True})

        if exit:
            if game_state in (GameStates.SHOW_INVENTORY,
                              GameStates.DROP_INVENTORY):
                game_state = previous_game_state  # now the Esc key just exits the inventory menu, rather than the whole game
            elif game_state == GameStates.TARGETING:
                player_turn_results.append({'targeting_cancelled': True})
            else:
                return True

        if fullscreen:
            libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())

        for player_turn_result in player_turn_results:
            message = player_turn_result.get('message')
            dead_entity = player_turn_result.get('dead')
            item_added = player_turn_result.get('item_added')
            item_consumed = player_turn_result.get('consumed')
            item_dropped = player_turn_result.get('item_dropped')
            targeting = player_turn_result.get('targeting')
            targeting_cancelled = player_turn_result.get('targeting_cancelled')

            if message:
                message_log.add_message(message)

            if targeting_cancelled:
                game_state = previous_game_state

                message_log.add_message(Message('Targeting cancelled'))

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

                message_log.add_message(message)

            if item_added:
                entities.remove(item_added)

                game_state = GameStates.ENEMY_TURN

            if item_consumed:
                game_state = GameStates.ENEMY_TURN

            if targeting:
                previous_game_state = GameStates.PLAYERS_TURN
                game_state = GameStates.TARGETING

                targeting_item = targeting

                message_log.add_message(targeting_item.item.targeting_message)

            if item_dropped:
                entities.append(item_dropped)

                game_state = GameStates.ENEMY_TURN

        if game_state == GameStates.ENEMY_TURN:
            for entity in entities:
                if entity.ai:  # note, the player and items etc won't have an AI component, so this skips them
                    enemy_turn_results = entity.ai.take_turn(
                        player, fov_map, game_map, entities
                    )  # take turn managed in ai file, tells it to move towards or attack player

                    for enemy_turn_result in enemy_turn_results:
                        message = enemy_turn_result.get('message')
                        dead_entity = enemy_turn_result.get('dead')

                        if message:
                            message_log.add_message(message)

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

                            message_log.add_message(message)

                        if game_state == GameStates.PLAYER_DEAD:
                            break

                    if game_state == GameStates.PLAYER_DEAD:
                        break
            else:
                game_state = GameStates.PLAYERS_TURN
def play_game(player, entities, game_map, message_log, game_state, con, panel,
              panel_bg, info, info_bg, player_con, player_con_bg, constants,
              permanent_cooldown_counter):
    fov_recompute = True

    fov_map = initialize_fov(game_map)

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

    game_state = GameStates.PLAYERS_TURN
    previous_game_state = game_state

    targeting_item = None
    targeting_feat = None

    game_turn_counter = 0
    cooldown_counter = permanent_cooldown_counter

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

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

        render_all(con, panel, panel_bg, info, info_bg, player_con,
                   player_con_bg, entities, player, game_map, fov_map,
                   fov_recompute, message_log, constants['screen_width'],
                   constants['screen_height'], constants['map_width'],
                   constants['map_height'], constants['bar_width'],
                   constants['panel_height'], constants['panel_y'],
                   constants['info_width'], constants['info_x'],
                   constants['player_con_width'], constants['player_con_x'],
                   constants['player_con_y'], mouse, constants['colors'],
                   game_state)

        fov_recompute = False

        libtcod.console_flush()

        clear_all(con, entities)

        action = handle_keys(key, game_state)
        mouse_action = handle_mouse(mouse)

        move = action.get('move')
        wait = action.get('wait')
        pickup = action.get('pickup')
        show_inventory = action.get('show_inventory')
        show_abilities = action.get('show_abilities')
        use = action.get('use')
        drop = action.get('drop')
        inventory_index = action.get('inventory_index')
        ability_index = action.get('ability_index')
        take_stairs = action.get('take_stairs')
        level_up = action.get('level_up')
        show_character_screen = action.get('show_character_screen')
        exit = action.get('exit')
        fullscreen = action.get('fullscreen')

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

        player_turn_results = []

        if move and game_state == GameStates.PLAYERS_TURN:
            dx, dy = move
            destination_x = player.x + dx
            destination_y = player.y + dy

            if not game_map.is_blocked(destination_x, destination_y):
                target = get_blocking_entities_at_location(
                    entities, destination_x, destination_y)

                if target:
                    attack_results = player.fighter.attack(target)
                    player_turn_results.extend(attack_results)

                else:
                    player.move(dx, dy)
                    fov_recompute = True
                    if game_map.is_door(destination_x, player.y):
                        message_log.add_message(
                            Message('The door creaks open.', libtcod.yellow))

                game_state = GameStates.ENEMY_TURN

        elif wait:
            game_state = GameStates.ENEMY_TURN

        elif pickup and game_state == GameStates.PLAYERS_TURN:
            for entity in entities:
                if entity.item and entity.x == player.x and entity.y == player.y:
                    pickup_results = player.inventory.add_item(entity)
                    player_turn_results.extend(pickup_results)
                    break
            else:
                message_log.add_message(
                    Message('There is nothing here to pick up.',
                            libtcod.yellow))

        if show_inventory:
            previous_game_state = game_state
            game_state = GameStates.SHOW_INVENTORY

        if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len(
                player.inventory.items):
            item_index = inventory_index
            item = player.inventory.items[inventory_index][0]

            item.selected = True
            game_state = GameStates.ITEM_MENU

        if use:
            player_turn_results.extend(
                player.inventory.use(item,
                                     item_index,
                                     entities=entities,
                                     fov_map=fov_map))
            game_state = GameStates.SHOW_INVENTORY
            if game_state != GameStates.TARGETING:
                item.selected = False
            else:
                item.selected = True
        elif drop:
            player_turn_results.extend(
                player.inventory.drop_item(item, item_index))
            item.selected = False

        if show_abilities:
            previous_game_state = game_state
            game_state = GameStates.SHOW_ABILITIES

        if ability_index is not None and previous_game_state != GameStates.PLAYER_DEAD and ability_index < len(
                player.abilities.feats):
            feat = player.abilities.feats[ability_index]

            if feat.turn_performed is None or (
                    cooldown_counter - feat.turn_performed > feat.cooldown):
                player_turn_results.extend(
                    player.abilities.perform(
                        feat,
                        turn_performed=cooldown_counter,
                        entities=entities,
                        fov_map=fov_map,
                        ability_power=player.fighter.ability_power))
            else:
                message_log.add_message(
                    Message('That ability is on cooldown.', libtcod.white))

        if take_stairs and game_state == GameStates.PLAYERS_TURN:
            for entity in entities:
                if entity.stairs and entity.x == player.x and entity.y == player.y:
                    entities = game_map.next_floor(player, message_log,
                                                   constants)
                    fov_map = initialize_fov(game_map)
                    fov_recompute = True
                    libtcod.console_clear(con)

                    break
            else:
                message_log.add_message(
                    Message('There are no stairs here.', libtcod.yellow))

        if level_up:
            if level_up == 'hp':
                player.fighter.base_max_hp += 20
                player.fighter.hp += 20
            elif level_up == 'str':
                player.fighter.base_strength += 1
            elif level_up == 'def':
                player.fighter.base_defense += 1
            elif level_up == 'dog':
                player.fighter.base_dodge += 3
            elif level_up == 'ap':
                player.fighter.base_ability_power += 2
            elif level_up == 'crit':
                player.fighter.base_crit_chance += 5

            game_state = previous_game_state

        if show_character_screen:
            previous_game_state = game_state
            game_state = GameStates.CHARACTER_SCREEN

        if game_state == GameStates.TARGETING:
            if left_click:
                target_x, target_y = left_click

                if hasattr(targeting, 'item'):
                    item_use_results = player.inventory.use(targeting_item,
                                                            item_index,
                                                            entities=entities,
                                                            fov_map=fov_map,
                                                            target_x=target_x,
                                                            target_y=target_y)
                    player_turn_results.extend(item_use_results)
                    item.selected = False

                else:
                    if feat.turn_performed is None or game_state == GameStates.TARGETING or (
                            cooldown_counter - feat.turn_performed >
                            feat.cooldown):
                        feat_use_results = player.abilities.perform(
                            targeting_feat,
                            turn_performed=cooldown_counter,
                            entities=entities,
                            fov_map=fov_map,
                            target_x=target_x,
                            target_y=target_y,
                            ability_power=player.fighter.ability_power)
                        player_turn_results.extend(feat_use_results)
                    else:
                        message_log.add_message(
                            Message('That ability is on cooldown.',
                                    libtcod.white))

            elif right_click:
                player_turn_results.append({'targeting_cancelled': True})

        if exit:
            if game_state in (GameStates.SHOW_INVENTORY,
                              GameStates.SHOW_ABILITIES,
                              GameStates.CHARACTER_SCREEN):
                game_state = previous_game_state
                for item in player.inventory.items:
                    if hasattr(item[0], 'selected') and item[0].selected:
                        item[0].selected = False
            elif game_state == GameStates.ITEM_MENU:
                for item in player.inventory.items:
                    if hasattr(item[0], 'selected') and item[0].selected:
                        item[0].selected = False
                game_state = GameStates.SHOW_INVENTORY

            elif game_state == GameStates.TARGETING:
                player_turn_results.append({'targeting_cancelled': True})
                for item in player.inventory.items:
                    if hasattr(item[0], 'selected') and item[0].selected:
                        item[0].selected = False
            else:
                save_game(player, entities, game_map, message_log, game_state,
                          cooldown_counter)

                return True

        if fullscreen:
            libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())

        for player_turn_result in player_turn_results:
            message = player_turn_result.get('message')
            dead_entity = player_turn_result.get('dead')
            item_added = player_turn_result.get('item_added')
            item_consumed = player_turn_result.get('consumed')
            feat_performed = player_turn_result.get('performed')
            item_dropped = player_turn_result.get('item_dropped')
            enemy_item_dropped = player_turn_result.get('enemy_item_dropped')
            equip = player_turn_result.get('equip')
            targeting = player_turn_result.get('targeting')
            targeting_cancelled = player_turn_result.get('targeting_cancelled')
            xp = player_turn_result.get('xp')

            if message:
                message_log.add_message(message)

            if dead_entity:
                if dead_entity == player:
                    message, game_state = kill_player(dead_entity)
                else:
                    message, loot = kill_monster(dead_entity)
                    if loot is not None:
                        player_turn_results.extend(
                            dead_entity.inventory.drop_item(
                                loot[0],
                                dead_entity.inventory.items.index(loot)))

                message_log.add_message(message)

            if item_added:
                entities.remove(item_added)

                game_state = GameStates.ENEMY_TURN

            if item_consumed:
                game_state = GameStates.ENEMY_TURN

            if feat_performed:
                game_state = GameStates.ENEMY_TURN

            if item_dropped:
                entities.append(item_dropped)

                game_state = GameStates.ENEMY_TURN

            if enemy_item_dropped:
                entities.append(enemy_item_dropped)

            if equip:
                equip_results = player.equipment.toggle_equip(equip)

                for equip_result in equip_results:
                    equipped = equip_result.get('equipped')
                    unequipped = equip_result.get('unequipped')

                    if equipped:
                        message_log.add_message(
                            Message('You equipped the {0}'.format(
                                equipped.name)))

                    if unequipped:
                        message_log.add_message(
                            Message('You unequipped the {0}'.format(
                                unequipped.name)))

                game_state = GameStates.ENEMY_TURN

            if targeting:
                previous_game_state = GameStates.PLAYERS_TURN
                game_state = GameStates.TARGETING

                if hasattr(targeting, 'item'):
                    targeting_item = targeting

                    message_log.add_message(
                        targeting_item.item.targeting_message)

                else:
                    targeting_feat = targeting

                    message_log.add_message(targeting_feat.targeting_message)

            if targeting_cancelled:
                game_state = previous_game_state

                message_log.add_message(Message('Targeting Cancelled'))

            if xp:
                leveled_up = player.level.add_xp(xp)
                message_log.add_message(
                    Message('You gain {0} experience points.'.format(xp)))

                if leveled_up:
                    message_log.add_message(
                        Message(
                            'You have faced enough horrors and grow stronger, you reach level {0}'
                            .format(player.level.curr_level) + '!',
                            libtcod.yellow))
                    previous_game_state = game_state
                    game_state = GameStates.LEVEL_UP

        if game_state == GameStates.ENEMY_TURN:
            game_turn_counter += 1
            cooldown_counter += 1

            for feat in player.abilities.feats:
                if feat.turn_performed is not None:
                    if ((cooldown_counter - 1) -
                            feat.turn_performed) < feat.cooldown:
                        feat.turn_ready = str(feat.cooldown -
                                              (cooldown_counter -
                                               feat.turn_performed) + 1)
                    else:
                        feat.turn_ready = "Ready!"

            for entity in entities:
                if entity.ai:
                    enemy_turn_results = entity.ai.take_turn(
                        player, fov_map, game_map, entities, game_turn_counter)

                    for enemy_turn_result in enemy_turn_results:
                        message = enemy_turn_result.get('message')
                        dead_entity = enemy_turn_result.get('dead')

                        if message:
                            message_log.add_message(message)

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

                            message_log.add_message(message)

                            if game_state == GameStates.PLAYER_DEAD:
                                break

                    if game_state == GameStates.PLAYER_DEAD:
                        break
            else:
                game_state = GameStates.PLAYERS_TURN
Exemple #27
0
def main():
    #Set the initial variables
    constants = get_constants()
    color_palette = Palette()
    kolors = color_palette.get_colors()
    mod_key = 'none'
    mouse = 'none'

    #Build and initialize the random monster rosters
    cr = RosterLists()
    cr.build_roster_lists()
    cr.build_monster_manual()
    current_roster = cr.get_roster_lists()
    current_mm = cr.get_monster_manual()

    #Set the font file and settings
    tcod.console_set_custom_font(
        constants['font_file'],
        tcod.FONT_TYPE_GREYSCALE | tcod.FONT_LAYOUT_TCOD)
    tcod.console_map_ascii_codes_to_font(256, 32, 0,
                                         1)  #map all characters in 2nd row
    tcod.console_map_ascii_codes_to_font(256 + 32, 32, 0,
                                         2)  #map all characters in 3rd row

    #Create the screen, the root console
    root_con = tcod.console_init_root(
        constants['screen_width'], constants['screen_height'],
        constants['screen_title'], constants['screen_fullscreen'],
        constants['screen_renderer'], constants['screen_order'],
        constants['screen_vsync'])

    #Create another console where we'll draw before overlaying it on the root
    main_con = tcod.console.Console(constants['screen_width'],
                                    constants['screen_height'],
                                    constants['screen_order'])

    #Create panel console for the hp bar and message log
    panel_con = tcod.console.Console(constants['screen_width'],
                                     constants['panel_height'],
                                     constants['screen_order'])

    #Initialize player, entities, game_map
    player, entities, game_map, indoors, message_log, game_state = get_game_variables(
        constants, kolors, current_roster, current_mm)

    interface_skin = 'Tutorial'  #Choices: Graph, Tutorial

    if interface_skin == 'Graph':
        color_palette.set_color('dark_wall', 70, 130, 180)
        color_palette.set_color('dark_ground', 70, 130, 180)

    #Initialize FOV and calculate on start
    fov_recompute = True
    fov_map = initialize_fov(game_map)
    game_type = 'normal'  #choices normal, viewer

    #Initialize the message log
    #    message_log = MessageLog(constants['message_x'], constants['message_width'], constants['message_height'])

    #Initialize main loop
    #    game_state = GameStates.PLAYERS_TURN
    previous_game_state = game_state
    targeting_item = None
    end_game = False
    while not end_game:
        #Recomput FOV if necessary
        if fov_recompute:
            recompute_fov(fov_map, player.x, player.y, constants['fov_radius'],
                          constants['fov_light_walls'],
                          constants['fov_algorithm'])

        #Render all entities & tiles on main console and blit them to the root console
        render_all(main_con, root_con, panel_con, entities, player, game_map,
                   fov_map, fov_recompute, message_log,
                   constants['screen_width'], constants['screen_height'],
                   kolors, game_type, interface_skin, indoors,
                   constants['hp_bar_width'], constants['panel_height'],
                   constants['panel_y'], mouse, game_state)

        #Reset FOV check
        fov_recompute = False
        #Update the console with our changes
        tcod.console_flush()
        #Erase all entities on main console so they won't smear on next update
        clear_all(main_con, entities)

        #initialize loop variables
        action = {'none': True}
        mouse_action = {'none': True}

        #Detect and handle events
        for event in tcod.event.get():
            if event.type == "QUIT":  #Window was closed
                action = {'exit': True}
            elif event.type == "KEYUP" and event.sym == 1073742049:
                mod_key = 'none'
            elif event.type == "KEYDOWN":  #A key was depressed
                if event.mod == True and event.sym == 1073742049:
                    mod_key = 'l_shift'
                action = handle_keys(event, mod_key, game_state)
            elif event.type == "MOUSEMOTION":  #Mouse was moved
                mouse = event.tile
            elif event.type == "MOUSEBUTTONDOWN":
                mouse = event.tile
                mouse_action = handle_mouse(mouse, event.button)
            #else:
            #print(event)

        #Get action type
        move = action.get('move')
        pickup = action.get('pickup')
        show_inventory = action.get('show_inventory')
        drop_inventory = action.get('drop_inventory')
        inventory_index = action.get('inventory_index')
        exit = action.get('exit')
        error = action.get('error')
        wait = action.get('wait')
        vision = action.get('vision')
        left_click = mouse_action.get('left_click')
        right_click = mouse_action.get('right_click')

        #List to store the results of damage
        player_turn_results = []

        #Process player actions
        if move and game_state == GameStates.PLAYERS_TURN:
            dx, dy = move
            destination_x = player.x + dx
            destination_y = player.y + dy
            #If no terrain is blocking then try to move the player
            if not game_map.is_blocked(destination_x, destination_y):
                #If no entity is blocking then move the player
                target = get_blocking_entities_at_location(
                    entities, destination_x, destination_y)
                if target:
                    attack_results = player.fighter.attack(target)
                    player_turn_results.extend(attack_results)
                else:
                    player.move(dx, dy)
                    #Recalculate FOV if player moves
                    fov_recompute = True
                game_state = GameStates.ENEMY_TURN
        elif pickup and game_state == GameStates.PLAYERS_TURN:
            for entity in entities:
                if entity.item and entity.x == player.x and entity.y == player.y:
                    pickup_results = player.inventory.add_item(entity)
                    player_turn_results.extend(pickup_results)

                    break
            else:
                message_log.add_message(
                    Message('There is nothing here to pick up.', tcod.yellow))

        if show_inventory:
            previous_game_state = game_state
            game_state = GameStates.SHOW_INVENTORY

        if drop_inventory:
            previous_game_state = game_state
            game_state = GameStates.DROP_INVENTORY

        if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len(
                player.inventory.items):
            item = player.inventory.items[inventory_index]
            if game_state == GameStates.SHOW_INVENTORY:
                player_turn_results.extend(
                    player.inventory.use(item,
                                         entities=entities,
                                         fov_map=fov_map))
            elif game_state == GameStates.DROP_INVENTORY:
                player_turn_results.extend(player.inventory.drop_item(item))

        if game_state == GameStates.TARGETING:
            if left_click:
                target_x, target_y = left_click
                item_use_results = player.inventory.use(targeting_item,
                                                        entities=entities,
                                                        fov_map=fov_map,
                                                        target_x=target_x,
                                                        target_y=target_y)
                player_turn_results.extend(item_use_results)
            elif right_click:
                player_turn_results.append({'targeting_cancelled': True})

        if exit:
            if exit == 'menu' and game_state in (GameStates.SHOW_INVENTORY,
                                                 GameStates.DROP_INVENTORY):
                game_state = previous_game_state
            elif game_state == GameStates.TARGETING:
                player_turn_results.append({'targeting_cancelled': True})
            else:
                if exit == True:
                    end_game = True

        if error:
            error_text = error
            print("Error detected", error_text)

        if vision and game_state == GameStates.PLAYERS_TURN:
            if vision == 'third eye':
                if interface_skin == 'Tutorial':
                    interface_skin = third_eye('open_eye', color_palette,
                                               indoors)
                elif interface_skin == 'Graph':
                    interface_skin = third_eye('close_eye', color_palette,
                                               indoors)

            #Recalculate FOV
            fov_recompute = True
            game_state = GameStates.ENEMY_TURN

        if wait and game_state == GameStates.PLAYERS_TURN:
            if game_type == 'viewer':
                entities = game_map.next_map(player, map_type, constants,
                                             entities, kolors, current_roster,
                                             current_mm)
                fov_map = initialize_fov(game_map)
                fov_recompute = True
                main_con.clear(fg=(0, 0, 0))
            else:
                game_state = GameStates.ENEMY_TURN

        #Process player turn results
        for player_turn_result in player_turn_results:
            message = player_turn_result.get('message')
            dead_entity = player_turn_result.get('dead')
            item_added = player_turn_result.get('item_added')
            item_consumed = player_turn_result.get('consumed')
            item_dropped = player_turn_result.get('item_dropped')
            targeting = player_turn_result.get('targeting')
            targeting_cancelled = player_turn_result.get('targeting_cancelled')

            if message:
                message_log.add_message(message)

            if targeting_cancelled:
                game_state = previous_game_state
                message_log.add_message(Message('Targeting cancelled'))

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

                message_log.add_message(message)

            if item_added:
                entities.remove(item_added)
                game_state = GameStates.ENEMY_TURN

            if item_consumed:
                game_state = GameStates.ENEMY_TURN

            if targeting:
                previous_game_state = GameStates.PLAYERS_TURN
                game_state = GameStates.TARGETING
                targeting_item = targeting
                message_log.add_message(targeting_item.item.targeting_message)

            if item_dropped:
                entities.append(item_dropped)
                game_state = GameStates.ENEMY_TURN

        #Enemy turn
        if game_state == GameStates.ENEMY_TURN:
            for entity in entities:
                if entity.ai:
                    enemy_turn_results = entity.ai.take_turn(
                        player, fov_map, game_map, entities)

                    for enemy_turn_result in enemy_turn_results:
                        message = enemy_turn_result.get('message')
                        dead_entity = enemy_turn_result.get('dead')

                        if message:
                            message_log.add_message(message)

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

                            message_log.add_message(message)

                            if game_state == GameStates.PLAYER_DEAD:
                                break

                    if game_state == GameStates.PLAYER_DEAD:
                        break
            else:
                game_state = GameStates.PLAYERS_TURN
Exemple #28
0
def play_game(player, entities, game_map, message_log, game_state, con, panel,
              constants):
    fov_recompute = True

    fov_map = initialize_fov(game_map)

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

    game_state = GameStates.PLAYERS_TURN
    previous_game_state = game_state

    targeting_item = None

    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.x, player.y, constants['fov_radius'],
                          constants['fov_light_walls'],
                          constants['fov_algorithm'])

        render_all(con, panel, entities, player, 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'], game_state)

        fov_recompute = False

        libtcod.console_flush()

        clear_all(con, entities)

        action = handle_keys(key, game_state)
        mouse_action = handle_mouse(mouse)

        move = action.get('move')
        wait = action.get('wait')
        pickup = action.get('pickup')
        show_inventory = action.get('show_inventory')
        drop_inventory = action.get('drop_inventory')
        inventory_index = action.get('inventory_index')
        take_stairs = action.get('take_stairs')
        level_up = action.get('level_up')
        show_character_screen = action.get('show_character_screen')
        exit = action.get('exit')
        fullscreen = action.get('fullscreen')

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

        player_turn_results = []

        if move and game_state == GameStates.PLAYERS_TURN:
            dx, dy = move
            destination_x = player.x + dx
            destination_y = player.y + dy

            if not game_map.is_blocked(destination_x, destination_y):
                target = get_blocking_entities_at_location(
                    entities, destination_x, destination_y)

                if target:
                    attack_results = player.fighter.attack(target)
                    player_turn_results.extend(attack_results)
                else:
                    player.move(dx, dy)

                    fov_recompute = True

                game_state = GameStates.ENEMY_TURN

        elif wait:
            game_state = GameStates.ENEMY_TURN

        elif pickup and game_state == GameStates.PLAYERS_TURN:
            for entity in entities:
                if entity.item and entity.x == player.x and entity.y == player.y:
                    pickup_results = player.inventory.add_item(entity)
                    player_turn_results.extend(pickup_results)

                    break
            else:
                message_log.add_message(
                    Message('There is nothing here to pick up.',
                            libtcod.yellow))

        if show_inventory:
            previous_game_state = game_state
            game_state = GameStates.SHOW_INVENTORY

        if drop_inventory:
            previous_game_state = game_state
            game_state = GameStates.DROP_INVENTORY

        if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len(
                player.inventory.items):
            item = player.inventory.items[inventory_index]

            if game_state == GameStates.SHOW_INVENTORY:
                player_turn_results.extend(
                    player.inventory.use(item,
                                         entities=entities,
                                         fov_map=fov_map))
            elif game_state == GameStates.DROP_INVENTORY:
                player_turn_results.extend(player.inventory.drop_item(item))

        if take_stairs and game_state == GameStates.PLAYERS_TURN:
            for entity in entities:
                if entity.stairs and entity.x == player.x and entity.y == player.y:
                    entities = game_map.next_floor(player, message_log,
                                                   constants)
                    fov_map = initialize_fov(game_map)
                    fov_recompute = True
                    libtcod.console_clear(con)

                    break
            else:
                message_log.add_message(
                    Message('There are no stairs here.', libtcod.yellow))

        if level_up:
            if level_up == 'hp':
                player.fighter.base_max_hp += 20
                player.fighter.hp += 20
            elif level_up == 'str':
                player.fighter.base_power += 1
            elif level_up == 'def':
                player.fighter.base_defense += 1

            game_state = previous_game_state

        if show_character_screen:
            previous_game_state = game_state
            game_state = GameStates.CHARACTER_SCREEN

        if game_state == GameStates.TARGETING:
            if left_click:
                target_x, target_y = left_click

                item_use_results = player.inventory.use(targeting_item,
                                                        entities=entities,
                                                        fov_map=fov_map,
                                                        target_x=target_x,
                                                        target_y=target_y)
                player_turn_results.extend(item_use_results)
            elif right_click:
                player_turn_results.append({'targeting_cancelled': True})

        if exit:
            if game_state in (GameStates.SHOW_INVENTORY,
                              GameStates.DROP_INVENTORY,
                              GameStates.CHARACTER_SCREEN):
                game_state = previous_game_state
            elif game_state == GameStates.TARGETING:
                player_turn_results.append({'targeting_cancelled': True})
            else:
                save_game(player, entities, game_map, message_log, game_state)

                return True

        if fullscreen:
            libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())

        for player_turn_result in player_turn_results:
            message = player_turn_result.get('message')
            dead_entity = player_turn_result.get('dead')
            item_added = player_turn_result.get('item_added')
            item_consumed = player_turn_result.get('consumed')
            item_dropped = player_turn_result.get('item_dropped')
            equip = player_turn_result.get('equip')
            targeting = player_turn_result.get('targeting')
            targeting_cancelled = player_turn_result.get('targeting_cancelled')
            xp = player_turn_result.get('xp')

            if message:
                message_log.add_message(message)

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

                message_log.add_message(message)

            if item_added:
                entities.remove(item_added)

                game_state = GameStates.ENEMY_TURN

            if item_consumed:
                game_state = GameStates.ENEMY_TURN

            if item_dropped:
                entities.append(item_dropped)

                game_state = GameStates.ENEMY_TURN

            if equip:
                equip_results = player.equipment.toggle_equip(equip)

                for equip_result in equip_results:
                    equipped = equip_result.get('equipped')
                    dequipped = equip_result.get('dequipped')

                    if equipped:
                        message_log.add_message(
                            Message('You equipped the {0}'.format(
                                equipped.name)))

                    if dequipped:
                        message_log.add_message(
                            Message('You dequipped the {0}'.format(
                                dequipped.name)))

                game_state = GameStates.ENEMY_TURN

            if targeting:
                previous_game_state = GameStates.PLAYERS_TURN
                game_state = GameStates.TARGETING

                targeting_item = targeting

                message_log.add_message(targeting_item.item.targeting_message)

            if targeting_cancelled:
                game_state = previous_game_state

                message_log.add_message(Message('Targeting cancelled'))

            if xp:
                leveled_up = player.level.add_xp(xp)
                message_log.add_message(
                    Message('You gain {0} experience points.'.format(xp)))

                if leveled_up:
                    message_log.add_message(
                        Message(
                            'Your battle skills grow stronger! You reached level {0}'
                            .format(player.level.current_level) + '!',
                            libtcod.yellow))
                    previous_game_state = game_state
                    game_state = GameStates.LEVEL_UP

        if game_state == GameStates.ENEMY_TURN:
            for entity in entities:
                if entity.ai:
                    enemy_turn_results = entity.ai.take_turn(
                        player, fov_map, game_map, entities)

                    for enemy_turn_result in enemy_turn_results:
                        message = enemy_turn_result.get('message')
                        dead_entity = enemy_turn_result.get('dead')

                        if message:
                            message_log.add_message(message)

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

                            message_log.add_message(message)

                            if game_state == GameStates.PLAYER_DEAD:
                                break

                    if game_state == GameStates.PLAYER_DEAD:
                        break
            else:
                game_state = GameStates.PLAYERS_TURN
Exemple #29
0
def play_game(player, entities, world_map, message_log, game_state, current_enemy, con, panel, constants):
    # print("entities: ")
    # for entity in entities:
    #     print(entity.name)
    current_map = world_map.maps[world_map.x][world_map.y]
    # entities = current_map.entities
    # print("entities: ")
    # for entity in entities:
    #     print(entity.name)

    fov_recompute = True

    fov_map = initialize_fov(current_map)

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

    previous_game_state = game_state

    targeting_item = None
    player_target = Target(0,0)


    #main game loop
    while not tcod.console_is_window_closed():
        #updates the key and mouse variables with any key or mouse events
        tcod.sys_check_for_event(tcod.EVENT_KEY_PRESS, key, mouse)

        if fov_recompute:
            fov_map = initialize_fov(current_map)
            recompute_fov(fov_map, player, constants['fov_radius'], entities,
                constants['fov_light_walls'], constants['fov_algorithm'])

        render_all(con, panel, entities, player, current_map, fov_map, fov_recompute,
            message_log,  constants['screen_width'], constants['screen_height'], constants['bar_width'],
            constants['panel_height'], constants['panel_y'], constants['colors'], game_state, current_enemy, player_target)

        tcod.console_flush()

        clear_all(con, entities)

        action = handle_keys(key, game_state)

        move = action.get('move')
        exit = action.get('exit')
        fullscreen = action.get('fullscreen')
        pickup = action.get('pickup')
        show_inventory = action.get('show_inventory')
        inventory_index = action.get('inventory_index')
        drop_inventory = action.get('drop_inventory')
        look = action.get('look')
        move_target = action.get('move_target')
        target_selected = action.get('target_selected')

        player_turn_results = []

        #Current errors:
        # (FIXED) x and y are being set to default make_map values in opposite moves
        # diagonal moves off the edge of the map cause a crash
        # !!!FOCUS!!! entity lists are not attached to maps, so buildings remain while entities refresh

        # Need to readd player to returning maps

        #!!!!!!!!!
        #WHEN A USER SAVES AND LOADS ON A GAME_MAP, A PERMANENT "DUMB" COPY OF
        #THEIR BODY IS LEFT AT THE POSITION THEY SAVED AND LOADED
        #UPON SUBSEQUENT RETURNS TO THE MAP
        #
        #THE GLITCH ONLY OCCURS WHEN THE USER LEAVES THE MAP
        #SOMEHOW, PLAYER IS KEPT IN ENTITIES OVER TRANSITIONS
        #Each gamemap needs a copy of player? (maybe)

        #If you save and load multiple times on one map before leaving it, the
        #dumb copy spawns at the first position you saved and loaded at.
        #!!!!!!!!!
        if move and game_state == GameStates.PLAYER_TURN:
            dx, dy = move
            destination_x = player.x + dx
            destination_y = player.y + dy

            if destination_x == current_map.width:
                if world_map.x < 9:
                    world_map.move_to(world_map.x+1, world_map.y, constants, player)
                    current_map = world_map.maps[world_map.x][world_map.y]
                    entities = current_map.entities
                    destination_x = 0
                    dx = 0
                    player.x = 0
                    player.y = destination_y
                else:
                    destination_x = player.x
                    destination_y = player.y
                    message_log.add_message(Message('You can\'t go that way', tcod.blue))
                print(str(world_map.x)+" ,"+str(world_map.y))
            elif destination_y == current_map.height:
                if world_map.y > 0:
                    world_map.move_to(world_map.x, world_map.y-1, constants, player)
                    current_map = world_map.maps[world_map.x][world_map.y]
                    entities = current_map.entities
                    destination_y = 0
                    dy = 0
                    player.y = 0
                    player.x = destination_x
                else:
                    destination_x = player.x
                    destination_y = player.y
                    message_log.add_message(Message('You can\'t go that way', tcod.blue))
                print(str(world_map.x)+" ,"+str(world_map.y))
            elif destination_x == -1:
                if world_map.x > 0:
                    world_map.move_to(world_map.x-1, world_map.y, constants, player)
                    current_map = world_map.maps[world_map.x][world_map.y]
                    entities = current_map.entities
                    destination_x = current_map.width-1
                    dx = 0
                    player.x = current_map.width-1
                    player.y = destination_y
                else:
                    destination_x = player.x
                    destination_y = player.y
                    message_log.add_message(Message('You can\'t go that way', tcod.blue))
                print(str(world_map.x)+" ,"+str(world_map.y))
            elif destination_y == -1:
                if world_map.y < 9:
                    world_map.move_to(world_map.x, world_map.y+1, constants, player)
                    current_map = world_map.maps[world_map.x][world_map.y]
                    entities = current_map.entities
                    destination_y = current_map.height-1
                    dy = 0
                    player.y = current_map.height-1
                    player.x = destination_x
                else:
                    destination_x = player.x
                    destination_y = player.y
                    message_log.add_message(Message('You can\'t go that way', tcod.blue))
                print(str(world_map.x)+" ,"+str(world_map.y))

            if not current_map.is_blocked(destination_x, destination_y):
                target = get_blocking_entities_at_location(entities, destination_x, destination_y)
                if target:
                    if target.fighter and target != player:
                        attack_results = player.fighter.attack(target)
                        player_turn_results.extend(attack_results)
                    elif target.breakable:
                        attack_results = player.fighter.attack(target)
                        player_turn_results.extend(attack_results)
                else:
                    player.move(dx, dy)
                    fov_recompute = True

            game_state = GameStates.ENEMY_TURN

        elif pickup and game_state == GameStates.PLAYER_TURN:
            for entity in entities:
                if entity.item and entity.x == player.x and entity.y == player.y:
                    pickup_results = player.inventory.add_item(entity)
                    player_turn_results.extend(pickup_results)
                    break
            else:
                message_log.add_message(Message('There is nothing here to pick up', tcod.yellow))

        if show_inventory:
            previous_game_state = game_state
            game_state = GameStates.SHOW_INVENTORY

        if drop_inventory:
            previous_game_state = game_state
            game_state = GameStates.DROP_INVENTORY

        if look:
            previous_game_state = game_state
            player_target.set(player.x, player.y)
            game_state = GameStates.LOOKING

        if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len(player.inventory.items):
            item = player.inventory.items[inventory_index]
            if game_state == GameStates.SHOW_INVENTORY:
                player_turn_results.extend(player.inventory.use(item, entities = entities, fov_map = fov_map))
            elif game_state == GameStates.DROP_INVENTORY:
                player_turn_results.extend(player.inventory.drop_item(item))

        if exit:
            if game_state in (GameStates.SHOW_INVENTORY, GameStates.DROP_INVENTORY, GameStates.LOOKING):
                game_state = previous_game_state
            elif game_state == GameStates.TARGETING:
                player_turn_results.append({'targeting_cancelled': True})
            else:
                save_game(player, entities, world_map, message_log, game_state, current_enemy)

                return True

        if fullscreen:
            tcod.console_set_fullscreen(not tcod.console_is_fullscreen())

        if game_state == GameStates.TARGETING:
            if move_target:
                dx, dy = move_target
                player_target.move(dx, dy)
            if target_selected:
                item_use_results = player.inventory.use(targeting_item,
                    entities=entities, fov_map=fov_map, target_x=player_target.x,
                        target_y=player_target.y)
                player_turn_results.extend(item_use_results)


        for player_turn_result in player_turn_results:
            message = player_turn_result.get('message')
            dead_entity = player_turn_result.get('dead')
            destroyed_entity = player_turn_result.get('destroyed')
            item_added = player_turn_result.get('item_added')
            item_consumed = player_turn_result.get('consumed')
            item_dropped = player_turn_result.get('item_dropped')
            targeting = player_turn_result.get('targeting')
            targeting_cancelled = player_turn_result.get('targeting_cancelled')

            if message:
                message_log.add_message(message)

            if targeting_cancelled:
                game_state = previous_game_state
                message_log.add_message(Message('Targeting cancelled'))

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

                message_log.add_message(message)

            if destroyed_entity:
                message = destroy_object(destroyed_entity)
                message_log.add_message(message)

            if item_added:
                entities.remove(item_added)

                game_state = GameStates.ENEMY_TURN

            if item_consumed:
                game_state = GameStates.ENEMY_TURN

            if targeting:
                previous_game_state = GameStates.PLAYER_TURN
                game_state = GameStates.TARGETING
                player_target.set(player.x, player.y)

                targeting_item = targeting

                message_log.add_message(targeting_item.item.targeting_message)

            if item_dropped:
                entities.append(item_dropped)
                game_state = GameStates.ENEMY_TURN

        if game_state == GameStates.ENEMY_TURN:
            for entity in entities:
                if entity.ai:
                    enemy_turn_results = entity.ai.take_turn(player, fov_map, current_map, entities)

                    for enemy_turn_result in enemy_turn_results:
                        message = enemy_turn_result.get('message')
                        dead_entity = enemy_turn_result.get('dead')

                        if message:
                            message_log.add_message(message)
                        if dead_entity:
                            if dead_entity == player:
                                message, game_state = kill_player(dead_entity)
                            else:
                                message = kill_monster(dead_entity)
                            message_log.add_message(message)
                            if game_state == GameStates.PLAYER_DEAD:
                                break

                    if game_state == GameStates.PLAYER_DEAD:
                        break
            else:
                game_state = GameStates.PLAYER_TURN

        if game_state == GameStates.LOOKING and move_target:
            dx, dy = move_target
            player_target.move(dx, dy)
Exemple #30
0
def play_game(player, entities, game_map, message_log, game_state, con, panel, constants):
	fov_recompute = True

	fov_map = initialize_fov(game_map)

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

	game_state = GameStates.PLAYERS_TURN
	previous_game_state = game_state

	targeting_item = None

	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.x, player.y, constants['fov_radius'], constants['fov_light_walls'],
						  constants['fov_algorithm'])

		render_all(con, panel, entities, player, 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'], game_state)

		fov_recompute = False

		libtcod.console_flush()

		clear_all(con, entities)

		action = handle_keys(key, game_state)
		mouse_action = handle_mouse(mouse)

		move = action.get('move')
		wait = action.get('wait')
		pickup = action.get('pickup')
		show_inventory = action.get('show_inventory')
		drop_inventory = action.get('drop_inventory')
		inventory_index = action.get('inventory_index')
		take_stairs = action.get('take_stairs')
		level_up = action.get('level_up')
		show_character_screen = action.get('show_character_screen')
		exit = action.get('exit')
		fullscreen = action.get('fullscreen')

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

		player_turn_results = []

		if move and game_state == GameStates.PLAYERS_TURN:
			dx, dy = move
			destination_x = player.x + dx
			destination_y = player.y + dy

			if not game_map.is_blocked(destination_x, destination_y):
				target = get_blocking_entities_at_location(entities, destination_x, destination_y)

				if target:
					attack_results = player.fighter.attack(target)
					player_turn_results.extend(attack_results)
				else:
					player.move(dx, dy)

					fov_recompute = True

				game_state = GameStates.ENEMY_TURN

		elif wait:
			game_state = GameStates.ENEMY_TURN

		elif pickup and game_state == GameStates.PLAYERS_TURN:
			for entity in entities:
				if entity.item and entity.x == player.x and entity.y == player.y:
					pickup_results = player.inventory.add_item(entity)
					player_turn_results.extend(pickup_results)

					break
			else:
				message_log.add_message(Message('There is nothing here to pick up.', libtcod.yellow))

		if show_inventory:
			previous_game_state = game_state
			game_state = GameStates.SHOW_INVENTORY

		if drop_inventory:
			previous_game_state = game_state
			game_state = GameStates.DROP_INVENTORY

		if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len(
				player.inventory.items):
			item = player.inventory.items[inventory_index]

			if game_state == GameStates.SHOW_INVENTORY:
				player_turn_results.extend(player.inventory.use(item, entities=entities, fov_map=fov_map))
			elif game_state == GameStates.DROP_INVENTORY:
				player_turn_results.extend(player.inventory.drop_item(item))

		if take_stairs and game_state == GameStates.PLAYERS_TURN:
			for entity in entities:
				if entity.stairs and entity.x == player.x and entity.y == player.y:
					entities = game_map.next_floor(player, message_log, constants)
					fov_map = initialize_fov(game_map)
					fov_recompute = True
					libtcod.console_clear(con)

					break

				else:
					message_log.add_message(Message('There are no stairs here.', libtcod.yellow))

		if level_up:
			if level_up == 'hp':
				player.fighter.max_hp += 20
				player.fighter.hp += 20
			elif level_up == 'str':
				player.fighter.power += 1
			elif level_up == 'def':
				player.fighter.defense += 1

			game_state = previous_game_state

		if show_character_screen:
			previous_game_state = game_state
			game_state = GameStates.CHARACTER_SCREEN

		if game_state == GameStates.TARGETING:
			if left_click:
				target_x, target_y = left_click

				item_use_results = player.inventory.use(targeting_item, entities=entities, fov_map=fov_map,
														target_x=target_x, target_y=target_y)
				player_turn_results.extend(item_use_results)
			elif right_click:
				player_turn_results.append({'targeting_cancelled': True})

		if exit:
			if game_state in (GameStates.SHOW_INVENTORY, GameStates.DROP_INVENTORY, GameStates.CHARACTER_SCREEN):
				game_state = previous_game_state
			elif game_state == GameStates.TARGETING:
				player_turn_results.append({'targeting_cancelled': True})
			else:
				save_game(player, entities, game_map, message_log, game_state)

				return True

		if fullscreen:
			libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())

		for player_turn_result in player_turn_results:
			message = player_turn_result.get('message')
			dead_entity = player_turn_result.get('dead')
			item_added = player_turn_result.get('item_added')
			item_consumed = player_turn_result.get('consumed')
			item_dropped = player_turn_result.get('item_dropped')
			targeting = player_turn_result.get('targeting')
			targeting_cancelled = player_turn_result.get('targeting_cancelled')
			xp = player_turn_result.get('xp')

			if message:
				message_log.add_message(message)

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

				message_log.add_message(message)

			if item_added:
				entities.remove(item_added)

				game_state = GameStates.ENEMY_TURN

			if item_consumed:
				game_state = GameStates.ENEMY_TURN

			if item_dropped:
				entities.append(item_dropped)

				game_state = GameStates.ENEMY_TURN

			if targeting:
				previous_game_state = GameStates.PLAYERS_TURN
				game_state = GameStates.TARGETING

				targeting_item = targeting

				message_log.add_message(targeting_item.item.targeting_message)

			if targeting_cancelled:
				game_state = previous_game_state

				message_log.add_message(Message('Targeting cancelled'))

			if xp:
				leveled_up = player.level.add_xp(xp)
				message_log.add_message(Message('You gain {0} experience points.'.format(xp)))

				if leveled_up:
					message_log.add_message(Message(
						'Your battle skills grow stronger! You reached level {0}'.format(
							player.level.current_level) + '!', libtcod.yellow))
					previous_game_state = game_state
					game_state = GameStates.LEVEL_UP


		if game_state == GameStates.ENEMY_TURN:
			for entity in entities:
				if entity.ai:
					enemy_turn_results = entity.ai.take_turn(player, fov_map, game_map, entities)

					for enemy_turn_result in enemy_turn_results:
						message = enemy_turn_result.get('message')
						dead_entity = enemy_turn_result.get('dead')

						if message:
							message_log.add_message(message)

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

							message_log.add_message(message)

							if game_state == GameStates.PLAYER_DEAD:
								break

					if game_state == GameStates.PLAYER_DEAD:
						break
			else:
				game_state = GameStates.PLAYERS_TURN
Exemple #31
0
def play_game(player, entities, game_map, message_log, game_state,
              root_console, con, panel, lexicon, constants):
    tdl.set_font('resources/arial10x10.png', greyscale=True, altLayout=True)

    fov_recompute = True
    fov_radius = 2
    if player.body.l_eye.state.name != 'LOST':
        fov_radius += 9
    if player.body.r_eye.state.name != 'LOST':
        fov_radius += 9

    mouse_coordinates = (0, 0)

    previous_game_state = game_state

    #game_state = GameStates.HELP_SCREEN

    targeting_item = None

    invisible_turns = 0

    verse = ''

    reading_scroll = None

    message_log.add_message(Message("Press '?' for Help Screen"))

    #uncomment the next line to facilitate manual testing of new spells
    print(lexicon)

    while not tdl.event.is_window_closed():
        if fov_recompute:
            fov_radius = 2
            if player.body.l_eye.state.name != 'LOST':
                fov_radius += 4
            if player.body.r_eye.state.name != 'LOST':
                fov_radius += 4
            game_map.compute_fov(player.x,
                                 player.y,
                                 fov=constants['fov_algorithm'],
                                 radius=fov_radius,
                                 light_walls=constants['fov_light_walls'])

        render_all(con, panel, entities, player, game_map, fov_recompute,
                   root_console, message_log, constants['screen_width'],
                   constants['screen_height'], constants['bar_width'],
                   constants['panel_height'], constants['panel_y'],
                   mouse_coordinates, constants['colors'], game_state,
                   reading_scroll)
        tdl.flush()

        clear_all(con, entities)

        fov_recompute = False

        for event in tdl.event.get():
            if event.type == 'KEYDOWN':
                user_input = event
                break
            elif event.type == 'MOUSEMOTION':
                mouse_coordinates = event.cell
            elif event.type == 'MOUSEDOWN':
                user_mouse_input = event
                break
        else:
            user_input = None
            user_mouse_input = None

        if not (user_input or user_mouse_input):
            continue

        action = handle_keys(user_input, game_state)

        mouse_action = handle_mouse(user_mouse_input)

        move = action.get('move')
        wait = action.get('wait')
        pickup = action.get('pickup')
        show_inventory = action.get('show_inventory')
        drop_inventory = action.get('drop_inventory')
        inventory_index = action.get('inventory_index')
        take_down_stairs = action.get('take_down_stairs')
        take_up_stairs = action.get('take_up_stairs')
        level_up = action.get('level_up')
        show_character_screen = action.get('show_character_screen')
        show_body_screen = action.get('show_body_screen')
        show_help_screen = action.get('show_help_screen')
        look_around = action.get('look_around')
        cast_spell = action.get('cast_spell')
        letter = action.get('letter')
        exit = action.get('exit')
        fullscreen = action.get('fullscreen')
        make_visible = False

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

        player_turn_results = []

        if move and game_state == GameStates.PLAYERS_TURN:
            if not player.fighter.visible:
                invisible_turns -= 1
                if invisible_turns <= 0:
                    make_visible = True
            dx, dy = move
            destination_x = player.x + dx
            destination_y = player.y + dy

            if game_map.walkable[destination_x, destination_y]:
                target = get_blocking_entities_at_location(
                    entities, destination_x, destination_y)
                if target:
                    attack_results = player.fighter.attack(target)
                    player_turn_results.extend(attack_results)
                    if not player.fighter.visible:
                        player.fighter.make_visible()
                        message_log.add_message(
                            Message('You are visible again!'))
                else:
                    player.move(dx, dy)
                    fov_recompute = True

                game_state = GameStates.ENEMY_TURN

        elif wait and game_state == GameStates.PLAYERS_TURN:
            player.body.pump_blood()
            for entity in entities:
                if entity.fountain and entity.x == player.x and entity.y == player.y:
                    if entity.fountain.water:
                        entity.fountain.drink(player)
                        message_log.add_message(
                            Message('You drink and feel refreshed.',
                                    constants['colors'].get('blue')))
                    else:
                        message_log.add_message(
                            Message('The fountain is dry.',
                                    constants['colors'].get('yellow')))

            game_state = GameStates.ENEMY_TURN

        elif pickup and game_state == GameStates.PLAYERS_TURN:
            for entity in entities:
                if entity.item and entity.x == player.x and entity.y == player.y:
                    pickup_results = player.inventory.add_item(
                        entity, constants['colors'])
                    player_turn_results.extend(pickup_results)

                    break
            else:
                message_log.add_message(
                    Message('There is nothing here to pick up.',
                            constants['colors'].get('yellow')))

        if show_inventory and game_state != GameStates.SHOW_INVENTORY:
            previous_game_state = game_state
            game_state = GameStates.SHOW_INVENTORY

        if drop_inventory:
            previous_game_state = game_state
            game_state = GameStates.DROP_INVENTORY

        if inventory_index is not None and previous_game_state != GameStates.PLAYER_DEAD and inventory_index < len(
                player.inventory.items):

            item = player.inventory.items[inventory_index]

            if game_state == GameStates.SHOW_INVENTORY:
                if item.name.split()[0] == 'Scroll':
                    game_state = GameStates.READ_SCROLL
                    reading_scroll = item
                else:
                    player_turn_results.extend(
                        player.inventory.use(item,
                                             constants['colors'],
                                             entities=entities,
                                             game_map=game_map))
            elif game_state == GameStates.DROP_INVENTORY:
                player_turn_results.extend(
                    player.inventory.drop_item(item, constants['colors']))

        if look_around:
            if game_state != GameStates.UNDERWORLD:
                seen = ', '.join([
                    entity.name for entity in entities
                    if game_map.fov[entity.x, entity.y]
                    and entity is not player and not entity.ghost
                ])
                message_log.add_message(
                    Message('You see: {0}.'.format(seen),
                            constants['colors'].get('white')))
            else:
                seen = ', '.join([
                    entity.name for entity in entities
                    if game_map.fov[entity.x, entity.y]
                    and entity is not player and entity.ghost
                ])
                message_log.add_message(
                    Message('You see: {0}.'.format(seen),
                            constants['colors'].get('white')))

        if cast_spell:
            message_log.add_message(
                Message('You begin a magic spell incantation.',
                        constants['colors'].get('white')))
            previous_game_state = game_state
            game_state = GameStates.CASTING_SPELL

        if letter:
            if letter == '.':
                magic_verse = []
                for i in verse.split():
                    if player.caster.mana > 0 and player.caster.focus > 0:
                        player.caster.mana -= 1
                        player.caster.focus -= 1
                        magic_verse.append(i)
                verse = ' '.join(translate(magic_verse, lexicon))
                message_log.add_message(
                    Message(verse, constants['colors'].get('white')))
                spell_results = player.caster.cast_spell(
                    verse.split(), game_map, entities, constants['colors'])
                verse = ''
                player_turn_results.extend(spell_results)
            else:
                verse += letter

        if take_down_stairs and game_state == GameStates.PLAYERS_TURN:
            for entity in entities:
                if entity.stairs and entity.x == player.x and entity.y == player.y:
                    if entity.stairs.direction == 'down':
                        save_floor(player, entities, game_map)
                        game_map, entities = next_floor(
                            player, message_log, entity.stairs.floor,
                            constants, lexicon, 'down')
                        fov_recompute = True
                        con.clear()

                        break
                    else:
                        message_log.add_message(
                            Message('These are not down stairs.',
                                    constants['colors'].get('yellow')))
                        break
            else:
                message_log.add_message(
                    Message('There are no stairs here.',
                            constants['colors'].get('yellow')))

        if take_up_stairs and game_state == GameStates.PLAYERS_TURN:
            for entity in entities:
                if entity.stairs and entity.x == player.x and entity.y == player.y:
                    if entity.stairs.direction == 'up':
                        save_floor(player, entities, game_map)
                        game_map, entities = next_floor(
                            player, message_log, entity.stairs.floor,
                            constants, lexicon, 'up')
                        fov_recompute = True
                        con.clear()

                        break
                    else:
                        message_log.add_message(
                            Message('These are not up stairs.',
                                    constants['colors'].get('yellow')))
                        break
            else:
                message_log.add_message(
                    Message('There are no stairs here.',
                            constants['colors'].get('yellow')))

        if level_up:
            if level_up == 'hp':
                player.fighter.base_max_hp += 20
                player.fighter.hp += 20
            elif level_up == 'str':
                player.fighter.base_power += 2
            elif level_up == 'def':
                player.fighter.base_defense += 1
            elif level_up == 'mp':
                player.caster.base_max_mana += 2
                player.caster.mana += 2
            elif level_up == 'fcs':
                player.caster.base_max_focus += 1
                player.caster.focus += 1

            game_state = previous_game_state

        if show_character_screen:
            previous_game_state = game_state
            game_state = GameStates.CHARACTER_SCREEN

        if show_body_screen:
            previous_game_state = game_state
            game_state = GameStates.BODY_SCREEN

        if show_help_screen:
            previous_game_state = game_state
            game_state = GameStates.HELP_SCREEN

        if game_state == GameStates.TARGETING:
            if left_click:
                target_x, target_y = left_click

                item_use_results = player.inventory.use(targeting_item,
                                                        constants['colors'],
                                                        entities=entities,
                                                        game_map=game_map,
                                                        target_x=target_x,
                                                        target_y=target_y)
                player_turn_results.extend(item_use_results)
            elif right_click:
                player_turn_results.append({'targeting_cancelled': True})

        if exit:
            if game_state in (GameStates.SHOW_INVENTORY,
                              GameStates.DROP_INVENTORY,
                              GameStates.CHARACTER_SCREEN,
                              GameStates.HELP_SCREEN, GameStates.BODY_SCREEN):
                game_state = previous_game_state
            elif game_state == GameStates.TARGETING:
                player_turn_results.append({'targeting_cancelled': True})
            elif game_state == GameStates.READ_SCROLL:
                game_state = GameStates.PLAYERS_TURN
            else:
                save_game(player, entities, game_map, message_log, game_state,
                          lexicon)
                return True

        if fullscreen:
            tdl.set_fullscreen(not tdl.get_fullscreen())

        if make_visible:
            player.fighter.make_visible()

            make_visible = False

            message_log.add_message(Message('You are visible again!'))
            game_state = GameStates.ENEMY_TURN

        for player_turn_result in player_turn_results:
            message = player_turn_result.get('message')
            dead_entity = player_turn_result.get('dead')
            item_added = player_turn_result.get('item_added')
            item_consumed = player_turn_result.get('consumed')
            item_dropped = player_turn_result.get('item_dropped')
            equip = player_turn_result.get('equip')
            targeting = player_turn_result.get('targeting')
            targeting_cancelled = player_turn_result.get('targeting_cancelled')
            xp = player_turn_result.get('xp')
            magic_xp = player_turn_result.get('magic_xp')
            invisible = player_turn_result.get('invisible')
            spell_cast = player_turn_result.get('spell_cast')
            spell_failed = player_turn_result.get('spell_failed')

            if invisible:
                invisible_turns = player_turn_result.get('invisible_turns')
                game_state = GameStates.ENEMY_TURN

            if make_visible:
                player.fighter.make_visible()

                make_visible = False

                message_log.add_message(Message('You are visible again!'))
                game_state = GameStates.ENEMY_TURN

            if message:
                message_log.add_message(message)

            if targeting_cancelled:
                game_state = previous_game_state

                message_log.add_message(Message('Targeting cancelled'))

            if dead_entity:
                if dead_entity == player:
                    message, game_state = kill_player(dead_entity,
                                                      constants['colors'])
                else:
                    message = kill_monster(dead_entity, entities,
                                           constants['colors'])

                message_log.add_message(message)

            if item_added:
                if not player.fighter.visible:
                    invisible_turns -= 1
                    if invisible_turns <= 0:
                        make_visible = True
                entities.remove(item_added)

                game_state = GameStates.ENEMY_TURN

            if item_consumed:
                if not player.fighter.visible:
                    invisible_turns -= 1
                    if invisible_turns <= 0:
                        make_visible = True

                game_state = GameStates.ENEMY_TURN

            if item_dropped:
                if not player.fighter.visible:
                    invisible_turns -= 1
                    if invisible_turns <= 0:
                        make_visible = True
                entities.append(item_dropped)

                game_state = GameStates.ENEMY_TURN

            if spell_cast:
                if not player.fighter.visible:
                    invisible_turns -= 1
                    if invisible_turns <= 0:
                        make_visible = True

                game_state = GameStates.ENEMY_TURN

            if spell_failed:
                if not player.fighter.visible:
                    invisible_turns -= 1
                    if invisible_turns <= 0:
                        make_visible = True

                game_state = GameStates.ENEMY_TURN

            if equip:
                equip_results = player.equipment.toggle_equip(equip)

                for equip_result in equip_results:
                    equipped = equip_result.get('equipped')
                    dequipped = equip_result.get('dequipped')

                    if equipped:
                        message_log.add_message(
                            Message('You equipped the {0}'.format(
                                equipped.name)))

                    if dequipped:
                        message_log.add_message(
                            Message('You dequipped the {0}'.format(
                                dequipped.name)))

                game_stat = GameStates.ENEMY_TURN

            if targeting:
                previous_game_state = GameStates.PLAYERS_TURN
                game_state = GameStates.TARGETING

                targeting_item = targeting

                message_log.add_message(targeting_item.item.targeting_message)

            if xp:
                leveled_up = player.level.add_fighter_xp(xp)
                message_log.add_message(
                    Message('You gain {0} experience points.'.format(xp)))

                if leveled_up:
                    message_log.add_message(
                        Message(
                            'Your fighting skills improve! You reach combat level {0}'
                            .format(player.level.fighter_level) + '!',
                            constants['colors'].get('yellow')))
                    previous_game_state = game_state
                    game_state = GameStates.LEVEL_UP

            if magic_xp:
                magic_leveled_up = player.level.add_caster_xp(magic_xp)
                message_log.add_message(
                    Message('You gain {0} magic experience points.'.format(
                        magic_xp)))

                if magic_leveled_up:
                    message_log.add_message(
                        Message(
                            'Your casting skills improve! You reach magic level {0}'
                            .format(player.level.caster_level) + '!',
                            constants['colors'].get('yellow')))
                    previous_game_state = game_state
                    game_state = GameStates.MAGIC_LEVEL_UP

        if game_state == GameStates.ENEMY_TURN:

            if player.caster.focus < player.caster.max_focus:
                player.caster.focus += player.caster.regeneration
            for entity in entities:
                if entity.body and entity.body.alive:
                    body_turn_results = entity.body.take_turn()
                    for result in body_turn_results:
                        dead_entity = result.get('dead')
                        message = result.get('message')
                        if dead_entity:
                            if dead_entity == player:
                                message, game_state = kill_player(
                                    dead_entity, constants['colors'])
                            else:
                                message = kill_monster(dead_entity, entities,
                                                       constants['colors'])

                            message_log.add_message(message)

                            if game_state == GameStates.PLAYER_DEAD:
                                break
                        if message:
                            message_log.add_message(message)

                if entity.ai and entity.body.animated:
                    enemy_turn_results = entity.ai.take_turn(
                        player, game_map, entities)

                    for enemy_turn_result in enemy_turn_results:
                        message = enemy_turn_result.get('message')
                        dead_entity = enemy_turn_result.get('dead')
                        xp = enemy_turn_result.get('xp')

                        if message:
                            message_log.add_message(message)

                        if xp:
                            leveled_up = player.level.add_fighter_xp(xp)

                            if leveled_up:
                                message_log.add_message(
                                    Message(
                                        'Your fighting skills improve! You reach combat level {0}'
                                        .format(player.level.fighter_level) +
                                        '!',
                                        constants['colors'].get('yellow')))
                                previous_game_state = game_state
                                game_state = GameStates.LEVEL_UP

                        if dead_entity:
                            if dead_entity == player:
                                message, game_state = kill_player(
                                    dead_entity, constants['colors'])
                            else:
                                message = kill_monster(dead_entity, entities,
                                                       constants['colors'])

                            message_log.add_message(message)

                            if game_state == GameStates.PLAYER_DEAD:
                                break

                    if game_state == GameStates.PLAYER_DEAD:
                        break
            else:
                if game_state == GameStates.LEVEL_UP:
                    previous_game_state = GameStates.PLAYERS_TURN
                else:
                    game_state = GameStates.PLAYERS_TURN