示例#1
0
class Buffer(QtGui.QTextEdit, QtCore.QObject):
    def __init__(self, parent, id=0, name="", filepath="", text="", std_modes=[], primary_mode=None):
        super(Buffer, self).__init__(parent)
        self.parent = parent

        # initialize class variables
        self.id = id
        self.name = name
        self.filepath = filepath
        self.actions = {}
        self.std_modes = std_modes
        self.primary_mode = primary_mode

        self.cursor = Cursor(self)
        self.mark_mode = False
        self.setText(text)
        self.cursor.moveCursor(QtGui.QTextCursor.EndOfLine)
        # stop markmode if the text changed
        self.textChanged.connect(self.onTextChanged)
        self.setCursorWidth(0)


    def setText(self, text):
        text = text + " "
        super(Buffer, self).setText(text)

    def toPlainText(self):
        text = super(Buffer, self).toPlainText()
        return text[:-1]
        
    def insertPlainText(self, text):
        super(Buffer, self).insertPlainText(text)
        
    @QtCore.pyqtSlot()
    def onTextChanged(self):
        self.unset_mark_mode()

    def unset_mark_mode(self):
        self.mark_mode = False
        self.cursor.clear()
        
    def copy(self, parent):
        newBuffer = Buffer(parent, self.id, self.name, self.filepath, "", self.std_modes, self.primary_mode)
        newBuffer.setTextCursor(self.textCursor())
        newBuffer.cursor = self.cursor.copy(newBuffer)
        doc = self.document()
        newBuffer.setDocument(doc)
        return newBuffer

    def moveCursor(self, MoveOperation, MoveMode=QtGui.QTextCursor.MoveAnchor):
        self.cursor.moveCursor(MoveOperation, MoveMode)

    def insert(self, char):
        self.cursor.insert(char)
        
    def backspace(self):
        self.cursor.backspace()

    def enter(self):
        self.cursor.enter()
示例#2
0
def play_floor(game_map, player, consoles, game_turn, current_floor):
    """Play a floor of the dungeon.

    This function contains the main game loop.  This loop controls the flow for
    a single turn of the game.

    A generic turn progresses through the following general phases:

      - Get player input.
      - Compute and then execute consequences of that input.
      - Complete status and environment checks post player turn.
      - All enemies and environmental hazards take turns.

    In addition, during special game states, the main game loop is also
    responsible for:

      - Playing animations (each tick of the game loop progresses the animation
        one frame).
      - Moving a cursor during cursor input events (i.e. targeting a staff or
        thrown potion).
    """
    #-------------------------------------------------------------------------
    # Game State Varaibles
    #-------------------------------------------------------------------------
    root_console, map_console, bottom_panel_console, top_panel_console = consoles
    # Initial values for game states
    game_state = GameStates.PLAYER_TURN
    previous_game_state = game_state
    # After an animation finishes, we need to continue processing the stack of
    # player turn results (animations are popped off first, so there will still
    # be results from the previous turn on the stack).  This flag will skip the
    # gathering of user input which ususally occurs before processing the
    # player turn stack.
    skip_player_input = False
    # This will be populated when we are playing an animation.  Call
    # .next_frame on this object to draw the next frame of the animation. This
    # method returns False until the animation is finished, after the last
    # frame is player, will return True.
    animation_player = None
    # A queue for storing enemy targets that have taken damage.  Used to render
    # enemy health bars in the UI.
    harmed_queue = deque(maxlen=3)
    # A cursor object for allowing the user to select a space on the map, will
    # be populated when the game state is in cursor select mode.
    cursor = None
    # A list of recently dead enemies.  We need this to defer drawing thier
    # corpses until *after* any animations have finished.
    dead_entities = []
    # Stacks for holding the results of player and enemy turns.
    player_turn_results = []
    enemy_turn_results = []
    # Log of game messages.
    message_log = MessageLog(MESSAGE_CONFIG)
    # A counter for how many times we have incremented the game loop on this
    # floor.  Used to trigger updates that happen regularly with regards to
    # game loop.  For example, graphical shimmering of water and ice.
    game_loop = -1

    #-------------------------------------------------------------------------
    # Main Game Loop.
    #-------------------------------------------------------------------------
    while not tdl.event.is_window_closed():

        game_loop += 1

        #---------------------------------------------------------------------
        # Game loop variables
        #---------------------------------------------------------------------
        user_input = None

        #---------------------------------------------------------------------
        # Recompute the player's field of view.
        #---------------------------------------------------------------------
        game_map.compute_fov(player.x,
                             player.y,
                             fov=FOV_CONFIG["algorithm"],
                             radius=FOV_CONFIG["radius"],
                             light_walls=FOV_CONFIG["light_walls"])

        #---------------------------------------------------------------------
        # Shimmer the colors of entities that shimmer.
        #---------------------------------------------------------------------
        if game_loop % SHIMMER_INTERVAL == 0:
            for entity in game_map.entities:
                if entity.shimmer:
                    entity.shimmer.shimmer()

        #---------------------------------------------------------------
        # Clear the illumination array, which is recomputed from scratch
        # each time terrain takes their turns.
        #---------------------------------------------------------------
        if game_state == GameStates.PLAYER_TURN:
            game_map.illuminated[:, :] = 0
            for entity in (e for e in game_map.entities if e.illuminatable):
                entity.illuminatable.illuminate(game_map)

        #---------------------------------------------------------------------
        # Render and display the dungeon and its inhabitates.
        #---------------------------------------------------------------------
        game_map.update_and_draw_all()

        #---------------------------------------------------------------------
        # Render the UI
        #---------------------------------------------------------------------
        # Top panel.
        top_panel_console.clear(fg=COLORS['white'], bg=COLORS['black'])
        top_panel_console.draw_str(
            0,
            0, f" Current Floor: {current_floor}  Turn Number: {game_turn}"
            f" Position: {player.x}, {player.y}",
            fg=(255, 255, 255))
        player.harmable.render_status_bar(top_panel_console, 1, 2)
        player.swimmable.render_status_bar(top_panel_console,
                                           TOP_PANEL_CONFIG['bar_width'] + 2,
                                           2)
        if player.status_manager:
            player.status_manager.render_status_bar(
                top_panel_console, 2 * TOP_PANEL_CONFIG['bar_width'] + 4, 2)
        # Bottom panel.
        bottom_panel_console.clear(fg=COLORS['white'], bg=COLORS['black'])
        for idx, entity in enumerate(e for e in harmed_queue if e != player):
            entity.harmable.render_status_bar(bottom_panel_console, 1,
                                              2 * idx + 1)
        message_log.render(bottom_panel_console)

        #---------------------------------------------------------------------
        # Draw the selection cursor if in cursor input state.
        #---------------------------------------------------------------------
        if game_state == GameStates.CURSOR_INPUT:
            cursor.draw()

        #---------------------------------------------------------------------
        # Render any menus.
        #---------------------------------------------------------------------
        if game_state in INVENTORY_STATES:
            inventory_message, highlight_attr = construct_inventory_data(
                game_state)
            menu_console, menu_x, menu_y = invetory_menu(
                inventory_message,
                player.inventory,
                inventory_width=50,
                screen_width=SCREEN_WIDTH,
                screen_height=SCREEN_HEIGHT,
                highlight_attr=highlight_attr)

        #---------------------------------------------------------------------
        # Advance the frame of any animations.
        #---------------------------------------------------------------------
        if game_state == GameStates.ANIMATION_PLAYING:
            animation_finished = animation_player.next_frame()
            sleep(ANIMATION_INTERVAL)
            if animation_finished:
                skip_player_input = True
                game_state, previous_game_state = previous_game_state, game_state

        # DEBUG
        # These switched highlight the various game state arrays.
        # highlight_array(game_map.walkable, game_map, COLORS['cursor_tail'])
        # highlight_array(game_map.door, game_map, COLORS['cursor_tail'])
        # highlight_array(game_map.blocked, game_map, COLORS['cursor_tail'])
        # highlight_array(game_map.fire, game_map, COLORS['darker_red'])
        # highlight_array(game_map.steam, game_map, COLORS['desaturated_green'])
        # highlight_array(game_map.terrain, game_map, COLORS['cursor_tail'])
        # highlight_array(game_map.water, game_map, COLORS['cursor_tail'])
        # draw_dijkstra_map_of_radius(game_map, player, radius=3)

        #---------------------------------------------------------------------
        # Blit the subconsoles to the main console and flush all rendering.
        #---------------------------------------------------------------------
        root_console.blit(game_map.console, 0, MAP_PANEL_CONFIG['y'],
                          SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0)
        root_console.blit(top_panel_console, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT,
                          0, 0)
        root_console.blit(bottom_panel_console, 0, BOTTOM_PANEL_CONFIG['y'],
                          SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0)
        if game_state in INVENTORY_STATES:
            root_console.blit(menu_console, menu_x, menu_y, SCREEN_WIDTH,
                              SCREEN_HEIGHT, 0, 0)
        tdl.flush()

        #---------------------------------------------------------------------
        # Clear all the entities drawn to the consoles, else we will re-draw
        # them in the same positions next game loop.
        #---------------------------------------------------------------------
        game_map.undraw_all()

        #---------------------------------------------------------------------
        # Get key input from the player.
        #---------------------------------------------------------------------
        if not skip_player_input:
            user_input = get_user_input()
            if game_state in INPUT_STATES and not user_input:
                continue
        action = player.input_handler.handle_keys(user_input, game_state)

        #----------------------------------------------------------------------
        # Handle player actions.
        #......................................................................
        # Here we process the consequences of input from the player that
        # affect the game state.  These consequences are added to a queue for
        # later processing.  This allows consequences to have further
        # consequences, which are then also added to the queue.  The messages
        # on the queue are constantly popped and dealt with until the queue is
        # empty, after which we pass the turn.
        #----------------------------------------------------------------------
        cursor_select = action.get(InputTypes.CURSOR_SELECT)
        inventory_index = action.get(InputTypes.INVENTORY_INDEX)
        move = action.get(InputTypes.MOVE)
        pickup = action.get(InputTypes.PICKUP)

        #----------------------------------------------------------------------
        # Player Move Action
        #......................................................................
        # The player has entered a move action.  Chack if the space in that
        # direction is movable, and if so put a move result on the queue.  If
        # if not, attack the blocking entity by putting an attack action on the
        # queue.
        #----------------------------------------------------------------------
        # Unless the player moves, we do not need to recompute the fov.
        if move and game_state == GameStates.PLAYER_TURN:
            player_move_or_attack(move,
                                  player=player,
                                  game_map=game_map,
                                  player_turn_results=player_turn_results)
        #----------------------------------------------------------------------
        # Player Pickup
        #......................................................................
        # The player has attempted to pickup an item.  If there is an item in
        # the players space, put a pickup action on the queue.
        #----------------------------------------------------------------------
        elif pickup and game_state == GameStates.PLAYER_TURN:
            pickup_entity(game_map, player, player_turn_results)
        #----------------------------------------------------------------------
        # Player Inventory use / drop
        #......................................................................
        # The player has attempted to use or drop an item from the inventory.
        # Check which state we are in (using or dropping) and put an
        # instruction on the queue.
        #----------------------------------------------------------------------
        elif (game_state in INVENTORY_STATES and inventory_index is not None
              and inventory_index < len(player.inventory.items)
              # The inventory can be opened after the player has died, but we
              # don't want to let them use any items.
              and previous_game_state != GameStates.PLAYER_DEAD):
            item = player.inventory.items[inventory_index]
            process_selected_item(item,
                                  player=player,
                                  game_map=game_map,
                                  game_state=game_state,
                                  player_turn_results=player_turn_results)
            game_state, previous_game_state = previous_game_state, game_state

        #----------------------------------------------------------------------
        # Handle cursor movement.
        #......................................................................
        # The player is currently in cursor select mode, where they have free
        # control of a cursor to select and square within their visible range.
        #----------------------------------------------------------------------
        if move and game_state == GameStates.CURSOR_INPUT:
            cursor.move(*move)
        if cursor_select and game_state == GameStates.CURSOR_INPUT:
            player_turn_results.extend(cursor.select())
            game_state, previous_game_state = previous_game_state, game_state
            cursor = None

        #----------------------------------------------------------------------
        # Process the results stack
        #......................................................................
        # We are done processing player inputs, and may have some results on
        # the player turn stack.  Process the stack by popping off the top
        # result from the queue.  There are many different possible results,
        # so each is handled with a dedicated handler.
        #
        # Note: Handling a result may result in other results being added to
        # the stack, so we continually process the results stack until it is
        # empty.
        #----------------------------------------------------------------------
        while (game_state
               not in (GameStates.CURSOR_INPUT, GameStates.ANIMATION_PLAYING)
               and player_turn_results != []):

            # Sort the turn results stack by the priority order.
            player_turn_results = sorted(
                flatten_list_of_dictionaries(player_turn_results),
                key=lambda d: get_key_from_single_key_dict(d))

            result = player_turn_results.pop()
            result_type, result_data = unpack_single_key_dict(result)

            if result_type == ResultTypes.RESTORE_PLAYER_INPUT:
                skip_player_input = False
            # Play an animation.
            if result_type == ResultTypes.ANIMATION:
                animation_player = construct_animation(result_data, game_map)
                # After the animation finishes, we do not want to get input
                # from the player before continuing to process the results
                # stack, so set a flag signaling to skip this step, and then
                # push a message that will restore it once we come back to
                # continue processing the stack.
                skip_player_input = True
                player_turn_results.append(
                    {ResultTypes.RESTORE_PLAYER_INPUT: True})
                game_state, previous_game_state = (
                    GameStates.ANIMATION_PLAYING, game_state)
                break
            # Drop into cursor input mode.
            if result_type == ResultTypes.CURSOR_MODE:
                x, y, callback, mode = result_data
                cursor = Cursor(player.x,
                                player.y,
                                game_map,
                                callback=callback,
                                cursor_type=mode)
                game_state, previous_game_state = (GameStates.CURSOR_INPUT,
                                                   game_state)
                break
            # Move the player.
            if result_type == ResultTypes.MOVE:
                player.movable.move(game_map, *result_data)
            # Find a random open position on the map, and move the player there
            # immediately.
            if result_type == ResultTypes.MOVE_TO_RANDOM_POSITION:
                entity = result_data
                position = game_map.find_random_open_position()
                entity.movable.set_position_if_able(game_map, *position)
            # Set the player's position, used when moving more than one step or
            # teleporting (say, due to a raipier attack or teleport staff).
            if result_type == ResultTypes.SET_POSITION:
                entity, x, y = result_data
                entity.movable.set_position_if_able(game_map, x, y)
            # Add a message to the log.
            if result_type == ResultTypes.MESSAGE:
                message_log.add_message(result_data)
            # Add an item to the inventory, and remove it from the game map.
            if result_type == ResultTypes.ADD_ITEM_TO_INVENTORY:
                entity, item = result_data
                entity.inventory.add(item)
                item.commitable.delete(game_map)
            # Remove consumed items from inventory
            if result_type == ResultTypes.DISCARD_ITEM:
                item, consumed = result_data
                if consumed:
                    player.inventory.remove(item)
            # Remove dropped items from inventory and place on the map
            if result_type == ResultTypes.DROP_ITEM_FROM_INVENTORY:
                entity, item = result_data
                entity.inventory.remove(item)
                item.x, item.y = entity.x, entity.y
                game_map.entities.append(item)
            # Process a damage message, possibly transforming it.
            if result_type == ResultTypes.DAMAGE:
                process_damage(game_map, result_data, player_turn_results)
            # Commit damage to an entity.
            if result_type == ResultTypes.HARM:
                process_harm(game_map, result_data, player_turn_results,
                             harmed_queue)
            # Increase the maximum HP of an entity
            if result_type == ResultTypes.INCREASE_MAX_HP:
                entity, amount = result_data
                entity.harmable.max_hp += amount
            # Increase the maximum attack power of an entity
            if result_type == ResultTypes.INCREASE_ATTACK_POWER:
                entity, amount = result_data
                entity.attacker.power += amount
            # Don defensive equipment.
            if result_type == ResultTypes.EQUIP_ARMOR:
                entity, armor = result_data
                entity_equip_armor(entity, armor, player_turn_results)
            # Don offensive equipment.
            if result_type == ResultTypes.EQUIP_WEAPON:
                entity, weapon = result_data
                entity_equip_weapon(entity, weapon, player_turn_results)
            # Remove defensive equipment.
            if result_type == ResultTypes.REMOVE_ARMOR:
                entity, armor = result_data
                entity_remove_armor(entity, armor, player_turn_results)
            # Remove offensive equipment.
            if result_type == ResultTypes.REMOVE_WEAPON:
                entity, weapon = result_data
                entity_remove_weapon(entity, weapon, player_turn_results)
            # Put an entity in a confused state
            if result_type == ResultTypes.CONFUSE:
                entity = result_data
                apply_status(entity, player, PlayerConfusedManager,
                             EnemyConfusedManager)
            if result_type == ResultTypes.DOUBLE_SPEED:
                entity = result_data
                apply_status(entity, player, SpeedManager, SpeedManager)
            # Freeze the player
            if result_type == ResultTypes.FREEZE:
                entity = result_data
                apply_status(entity, player, None, EnemyFrozenManager)
            # Add a new entity to the game.
            if result_type == ResultTypes.ADD_ENTITY:
                entity = result_data
                entity.commitable.commit(game_map)
                player_turn_results.extend(encroach_on_all(entity, game_map))
            # Remove an entity from the game.
            if result_type == ResultTypes.REMOVE_ENTITY:
                entity = result_data
                entity.commitable.delete(game_map)
            # Handle death
            if result_type == ResultTypes.DEAD_ENTITY:
                dead_entity = result_data
                if dead_entity == player:
                    player_turn_results.extend(kill_player(player))
                    game_state = GameStates.PLAYER_DEAD
                elif dead_entity:
                    player_turn_results.extend(
                        kill_monster(dead_entity, game_map))
                    make_corpse(dead_entity)
            # Handle a player death message.  Death messages are special in
            # that they immediately break out of the game loop.
            if result_type == ResultTypes.DEATH_MESSAGE:
                death_message = result_data
                message_log.add_message(death_message)
                break
            # End the player's turn
            if result_type == ResultTypes.END_TURN:
                game_turn += 1
                game_state, previous_game_state = (GameStates.POST_PLAYER_TURN,
                                                   game_state)

        #---------------------------------------------------------------------
        # Post player turn checks.
        #---------------------------------------------------------------------
        if game_state == GameStates.POST_PLAYER_TURN:
            # Check if the player has entered into a square containing stairs.
            # If so, end the current floor immediately.
            if (player.x, player.y) == game_map.upward_stairs_position:
                game_map.entities.remove(player)
                return FloorResultTypes.INCREMENT_FLOOR, game_turn
            if (player.x, player.y) == game_map.downward_stairs_position:
                game_map.entities.remove(player)
                return FloorResultTypes.DECREMENT_FLOOR, game_turn
            # All rechargable items get ticked.
            for item in player.inventory:
                if item.rechargeable:
                    enemy_turn_results.extend(item.rechargeable.tick())
            # All confused entities get ticked
            if player.status_manager:
                player.status_manager.tick()
            # All encroaching entities interact with their cellmates.
            enemy_turn_results.extend(encroach_on_all(player, game_map))
            # The player re-gains or loses swim stamina.
            if game_map.water[player.x, player.y]:
                enemy_turn_results.extend(player.swimmable.swim())
            else:
                enemy_turn_results.extend(player.swimmable.rest())
            # Pass the turn to the enemies.
            game_state = GameStates.ENEMY_TURN

        #-------------------------------------------------------------------
        # All enemies and terrain take thier turns.
        #-------------------------------------------------------------------
        if game_state == GameStates.ENEMY_TURN:

            for entity in (e for e in game_map.entities if e != player):
                # Enemies move and attack if possible.
                if entity.ai:
                    enemy_turn_results.extend(
                        entity.ai.take_turn(player, game_map))
                # If the enemy has a current status, tick it.
                if entity.status_manager:
                    entity.status_manager.tick()
                # Fire and gas dissipates.
                if entity.dissipatable:
                    enemy_turn_results.extend(
                        entity.dissipatable.dissipate(game_map))
                # Interact with water.
                if game_map.water[entity.x, entity.y] and entity.floatable:
                    enemy_turn_results.extend(entity.floatable.float(game_map))
                if game_map.water[entity.x, entity.y] and entity.swimmable:
                    enemy_turn_results.extend(entity.swimmable.swim())
                # Fire burns entities in the same space.
                if entity.entity_type == EntityTypes.FIRE:
                    burnable_entities_at_position = (
                        get_all_entities_with_component_in_position(
                            (entity.x, entity.y), game_map, "burnable"))
                    for e in burnable_entities_at_position:
                        enemy_turn_results.extend(e.burnable.burn(game_map))
                # Fire and gas spreads.
                if entity.spreadable:
                    enemy_turn_results.extend(
                        entity.spreadable.spread(game_map))
                # Steam scalds entities in the same space.
                if entity.entity_type == EntityTypes.STEAM:
                    scaldable_entities_at_position = (
                        get_all_entities_with_component_in_position(
                            (entity.x, entity.y), game_map, "scaldable"))
                    for e in scaldable_entities_at_position:
                        enemy_turn_results.extend(e.scaldable.scald(game_map))
            game_state = GameStates.PLAYER_TURN

        #---------------------------------------------------------------------
        # Process all result actions of enemy turns.
        #---------------------------------------------------------------------
        while enemy_turn_results != []:

            enemy_turn_results = sorted(
                flatten_list_of_dictionaries(enemy_turn_results),
                key=lambda d: get_key_from_single_key_dict(d))

            result = enemy_turn_results.pop()
            result_type, result_data = unpack_single_key_dict(result)

            # Handle a move action
            if result_type == ResultTypes.SET_POSITION:
                monster, x, y = result_data
                monster.movable.set_position_if_able(game_map, x, y)
            # Handle a move towards action.  Move towards a target.
            if result_type == ResultTypes.MOVE_TOWARDS:
                monster, target_x, target_y = result_data
                monster.movable.move_towards(game_map, target_x, target_y)
            # Handle a move random adjacent action.  Move to a random adjacent
            # square.
            if result_type == ResultTypes.MOVE_RANDOM_ADJACENT:
                monster = result_data
                monster.movable.move_to_random_adjacent(game_map)
            # Handle a simple message.
            if result_type == ResultTypes.MESSAGE:
                message = result_data
                message_log.add_message(message)
            # Handle damage dealt, possibly transforming it.
            if result_type == ResultTypes.DAMAGE:
                process_damage(game_map, result_data, enemy_turn_results)
            # Commit damage to an entity.
            if result_type == ResultTypes.HARM:
                process_harm(game_map, result_data, enemy_turn_results,
                             harmed_queue)
            # Add a use to an item
            if result_type == ResultTypes.RECHARGE_ITEM:
                item = result_data
                item.consumable.uses += 1
            # Entities swim and thier stamana decreases.
            if result_type == ResultTypes.CHANGE_SWIM_STAMINA:
                entity, stamina_change = result_data
                entity.swimmable.change_stamina(stamina_change)
            # Add a new entity to the game.
            if result_type == ResultTypes.ADD_ENTITY:
                entity = result_data
                entity.commitable.commit(game_map)
            # Remove an entity from the game.
            if result_type == ResultTypes.REMOVE_ENTITY:
                entity = result_data
                entity.commitable.delete(game_map)
            # Handle death.
            if result_type == ResultTypes.DEAD_ENTITY:
                dead_entity = result_data
                if dead_entity == player:
                    enemy_turn_results.extend(kill_player(player))
                    game_state = GameStates.PLAYER_DEAD
                elif dead_entity:
                    enemy_turn_results.extend(
                        kill_monster(dead_entity, game_map))
                    make_corpse(dead_entity)

        #---------------------------------------------------------------------
        # Handle meta actions,
        #---------------------------------------------------------------------
        show_invetory = action.get(InputTypes.SHOW_INVENTORY)
        if game_state == GameStates.PLAYER_TURN and show_invetory:
            previous_game_state = game_state
            game_state = GameStates.SHOW_INVENTORY

        drop_inventory = action.get(InputTypes.DROP_INVENTORY)
        if game_state == GameStates.PLAYER_TURN and drop_inventory:
            previous_game_state = game_state
            game_state = GameStates.DROP_INVENTORY

        throw_inventory = action.get(InputTypes.THROW_INVENTORY)
        if game_state == GameStates.PLAYER_TURN and throw_inventory:
            previous_game_state = game_state
            game_state = GameStates.THROW_INVENTORY

        equip_inventory = action.get(InputTypes.EQUIP_INVENTORY)
        if game_state == GameStates.PLAYER_TURN and equip_inventory:
            previous_game_state = game_state
            game_state = GameStates.EQUIP_INVENTORY

        exit = action.get(InputTypes.EXIT)
        if exit:
            if game_state == GameStates.CURSOR_INPUT:
                cursor.clear()
            if game_state in CANCEL_STATES:
                game_state, previous_game_state = (previous_game_state,
                                                   game_state)
            else:
                return FloorResultTypes.END_GAME, game_turn

        fullscreen = action.get(InputTypes.FULLSCREEN)
        if fullscreen:
            tdl.set_fullscreen(not tdl.get_fullscreen())

        #---------------------------------------------------------------------
        # If the player is dead, the game is over.
        #---------------------------------------------------------------------
        if game_state == GameStates.PLAYER_DEAD:
            continue