Пример #1
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('There is nothing here 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(f'You equipped the {equipped.name}'))

                    if dequipped:
                        message_log.add_message(
                            Message(f'You dequipped the {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) + '!',
                            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
Пример #2
0
def play_game(player, entities, game_map, message_log, game_state, con, panel):
    fov_recompute = True

    mouse_coordinates = (0, 0)

    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:
            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, message_log, mouse_coordinates, game_state)
        libtcod.console_flush()

        clear_all(con, entities)

        fov_recompute = False

        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 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 and game_state == GameStates.PLAYERS_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.add_item(entity)
                    player_turn_results.extend(pickup_results)

                    break
            else:
                message_log.add_message(Message('There is nothing here to pick up', colors.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

        # Player is manipulating 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, game_map=game_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:
                    game_map, entities = next_floor(player, message_log, entity.stairs.floor)
                    fov_recompute = True
                    con.clear()

                    break
            else:
                message_log.add_message(Message('There are no stairs here', colors.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, 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:
            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(f'You gain {xp} experience points'))

                if leveled_up:
                    message_log.add_message(Message(
                        f'Your battle skills grow stronger! You reached level {player.level.current_level}!',
                        colors.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)
                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(f'You equipped the {equipped.name}'))

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

                game_state = GameStates.ENEMY_TURN

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

                targeting_item = targeting

                # noinspection PyUnresolvedReferences
                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)
                            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
Пример #3
0
def play(player, entities, game_map, display, state):

    mouse_coordinates = (0, 0)
    prev_state = state
    targeting_item = None

    while not tdl.event.is_window_closed():

        game_map.player_FOV()
        display.render_all(mouse_coordinates, state, targeting_item)
        tdl.flush()
        display.clear_all()

        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, state)
        mouse_action = handle_mouse(user_mouse_input)

        move = action.get('move')
        exit = action.get('exit')
        pickup = action.get('pickup')
        wait = action.get('wait')
        inventory = action.get('inventory')
        drop = action.get('drop')
        shop = action.get('shop')
        buy = action.get('buy')
        sell = action.get('sell')
        sell_index = action.get('vendor_sell_index')
        buy_index = action.get('vendor_buy_index')
        inventory_index = action.get('inventory_index')
        go_down = action.get('go_down')
        level_up = action.get('level_up')
        character_screen = action.get('character_screen')
        fullscreen = action.get('fullscreen')
        direction_selected = action.get('direction_selected')
        controls_screen = action.get('controls_screen')

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

        player_turn_results = []

        if exit:
            if state in (GameStates.VENDOR_BUY, GameStates.VENDOR_SELL):
                state = prev_state
                prev_state = GameStates.PLAYER_TURN
            elif state in (GameStates.SHOW_INVENTORY, GameStates.DROP_INVENTORY,
                           GameStates.CHARACTER_SCREEN, GameStates.VENDOR_SELECT,
                           GameStates.SHOW_CONTROLS):
                state = prev_state
            elif state in (GameStates.TARGETING, GameStates.DIRECTIONAL_TARGETING):
                player_turn_results.append({'targeting_cancelled': True})
            else:
                save_game(player, entities, game_map, display.log, state)
                return True

        if move and state == GameStates.PLAYER_TURN:
            dx, dy = move
            dest_x = player.x + dx
            dest_y = player.y + dy
            if game_map.walkable[dest_x, dest_y]:
                if len(player.inventory.items) <= player.inventory.capacity:
                    target = get_impassable_entities_at(entities, dest_x, dest_y)
                    if target:
                        attack_results = player.fighter.attack(target)
                        player_turn_results.extend(attack_results)
                    else:
                        player.move(dx, dy)
                    state = GameStates.ENEMY_TURN
                else:
                    display.write(Message('You are overburdened and cannot move!', Colors.YELLOW))

        elif pickup and 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(entity)
                    player_turn_results.extend(pickup_results)
                    break
            else:
                display.write(Message('There is nothing here to pick up', Colors.YELLOW))

        if wait and state == GameStates.PLAYER_TURN:
            state = GameStates.ENEMY_TURN

        if inventory:
            prev_state = state
            state = GameStates.SHOW_INVENTORY

        if buy:
            prev_state = state
            state = GameStates.VENDOR_SELL

        if sell:
            prev_state = state
            state = GameStates.VENDOR_BUY

        if character_screen:
            prev_state = state
            state = GameStates.CHARACTER_SCREEN

        if controls_screen:
            prev_state = state
            state = GameStates.SHOW_CONTROLS

        if drop:
            prev_state = state
            state = GameStates.DROP_INVENTORY

        if inventory_index is not None and prev_state != GameStates.PLAYER_DEAD and inventory_index < len(player.inventory.items):
            item = player.inventory.items[inventory_index]
            if state == GameStates.SHOW_INVENTORY:
                player_turn_results.extend(player.inventory.use(
                    item, game_map=game_map, source=player))
            else:
                player_turn_results.extend(player.inventory.drop(item))

        if buy_index is not None and prev_state != GameStates.PLAYER_DEAD and buy_index < len(player.inventory.items):
            item = player.inventory.get_and_remove(buy_index)
            vendor = None
            for entity in entities:
                if entity.vendor and entity.x == player.x and entity.y == player.y:
                    vendor = entity
            if vendor:
                vendor.vendor.purchase(item)
                player.inventory.cashola += item.item.price
        if sell_index is not None:
            vendor = None
            item = None
            for entity in entities:
                if entity.vendor and entity.x == player.x and entity.y == player.y:
                    vendor = entity
            if vendor:
                price = vendor.vendor.get_price(sell_index)
                if price is None:
                    display.write(Message('I\'m afraid I don\'t have that listing.', Colors.YELLOW))
                elif player.inventory.cashola < price:
                    display.write(Message('I\'m afraid you can\'t afford that item.', Colors.YELLOW))
                else:
                    item = vendor.vendor.sell(sell_index)

            if item:
                player.inventory.silent_add(item)
                player.inventory.cashola -= item.item.price

        if go_down and state == GameStates.PLAYER_TURN:
            for entity in entities:
                if entity.stairs and entity.x == player.x and entity.y == player.y:
                    game_map, entities = next_floor(player, display, entity.stairs.target_floor)
                    break
            else:
                display.write(Message('There are no stairs here.', Colors.YELLOW))

        if shop and state == GameStates.PLAYER_TURN:
            for entity in entities:
                if entity.vendor and entity.x == player.x and entity.y == player.y:
                    prev_state = state
                    state = GameStates.VENDOR_SELECT
                    break
            else:
                display.write(Message('There are no vendors here.', Colors.YELLOW))

        if state == GameStates.TARGETING:
            if left_click:
                target_x, target_y = left_click
                item_use_results = player.inventory.use(
                    targeting_item, 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 state == GameStates.DIRECTIONAL_TARGETING:
            if direction_selected:
                item_use_results = player.inventory.use(
                    targeting_item, game_map=game_map, direction=direction_selected)
                player_turn_results.extend(item_use_results)

        if level_up:
            if level_up == 'constitution':
                player.fighter.base_max_hp += 20
                player.fighter.hp += 20
            elif level_up == 'strength':
                player.fighter.base_power += 1
            elif level_up == 'agility':
                player.fighter.base_defense += 1
            elif level_up == 'dexterity':
                player.fighter.base_accuracy += 2
            elif level_up == 'endurance':
                if player.inventory.base_capacity > 23:
                    display.write(Message('You cannot advance endurance further!', Colors.YELLOW))
                    continue
                player.inventory.base_capacity += 3
            state = prev_state

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

        for player_result in player_turn_results:
            player_message = player_result.get('message')
            dead_entity_PT = player_result.get('dead')
            item_added = player_result.get('item_added')
            item_consumed = player_result.get('consumed')
            item_dropped = player_result.get('item_dropped')
            equip = player_result.get('equip')
            charge_used = player_result.get('charge_used')
            targeting = player_result.get('targeting')
            directional_targeting = player_result.get('directional_targeting')
            targeting_cancelled = player_result.get('targeting_cancelled')
            xp = player_result.get('xp')

            if player_message:
                display.write(player_message)

            if dead_entity_PT:
                if dead_entity_PT == player:
                    player_message, state = kill_player(dead_entity_PT)
                else:
                    player_message = kill_monster(dead_entity_PT, game_map)

                display.write(player_message)

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

            if item_consumed:
                state = GameStates.ENEMY_TURN

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

            if charge_used:
                state = GameStates.ENEMY_TURN

            if targeting_cancelled:
                state = GameStates.PLAYER_TURN
                display.write(Message('Targeting cancelled'))

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

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

                    if equipped:
                        display.write(Message('You equip the {0}'.format(equipped.name)))
                    if removed:
                        display.write(Message('You remove the {0}'.format(removed.name)))

                state = GameStates.ENEMY_TURN

            if xp:
                leveled_up = player.level.add_xp(xp)
                if leveled_up:
                    display.write(Message('Welcome to level {0}!'.format(
                        player.level.current_level), Colors.LIGHT_RED))
                    prev_state = state
                    state = GameStates.LEVEL_UP

            # canceling from targeting will return to PLAYER mode, not INVENTORY
            if targeting:
                prev_state = GameStates.PLAYER_TURN
                state = GameStates.TARGETING
                targeting_item = targeting
                display.write(targeting_item.item.targeting_msg)

            if directional_targeting:
                prev_state = GameStates.PLAYER_TURN
                state = GameStates.DIRECTIONAL_TARGETING
                targeting_item = directional_targeting
                display.write(targeting_item.item.targeting_msg)

        sanity_check(player)

        if state == GameStates.ENEMY_TURN:
            game_map.enemy_FOV()
            for entity in entities:
                if entity.regeneration:
                    entity.regeneration.regen()
                if entity.ai:
                    enemy_turn_results = entity.ai.take_turn(player, game_map)

                    for enemy_result in enemy_turn_results:
                        enemy_message = enemy_result.get('message')
                        dead_entity_ET = enemy_result.get('dead')

                        if enemy_message:
                            display.write(enemy_message)
                        if dead_entity_ET:
                            if dead_entity_ET == player:
                                enemy_message, state = kill_player(dead_entity_ET)
                            else:
                                enemy_message = kill_monster(dead_entity_ET, game_map)

                            display.write(enemy_message)

                            if state == GameStates.PLAYER_DEAD:
                                break

                    if state == GameStates.PLAYER_DEAD:
                            break
            else:
                state = GameStates.PLAYER_TURN
Пример #4
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
Пример #5
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