void inventory_selector::set_to_drop(int it_pos, int count)
{
    player &u = g->u;
    if (it_pos == -1) { // weapon
        if (u.weapon.is_null()) {
            return;
        }
        if (count > 0 && (!u.weapon.count_by_charges() || count >= u.weapon.charges)) {
            count = -1; // drop whole item, because it can not be separated, or the requested count means all
        }
        // Must bypass the set_drop_count() that takes a stack,
        // because it must get a direct reference to weapon.
        set_drop_count(it_pos, count, u.weapon);
    } else if (it_pos < -1) { // worn
        item& armor = u.i_at( it_pos );
        if( armor.is_null() ) {
            return; // invalid it_pos -> ignore
        }
        if (count > 0) {
            count = -1; // can only drop a whole worn item
        }
        set_drop_count(it_pos, count, armor);
    } else { // inventory
        const std::list<item> &stack = u.inv.const_stack(it_pos);
        if (stack.empty()) {
            return; // invalid it_pos -> ignore
        }
        set_drop_count(it_pos, count, stack);
    }
}
void inventory_selector::set_to_drop(int it_pos, int count)
{
    player &u = g->u;
    if (it_pos == -1) { // weapon
        if (u.weapon.is_null()) {
            return;
        }
        if (count > 0 && (!u.weapon.count_by_charges() || count >= u.weapon.charges)) {
            count = -1; // drop whole item, because it can not be separated, or the requested count means all
        }
        set_drop_count(it_pos, count, u.weapon);
    } else if (it_pos < -1) { // worn
        const size_t wpos = player::worn_position_to_index(it_pos);
        if (wpos >= u.worn.size()) {
            return; // invalid it_pos -> ignore
        }
        if (count > 0) {
            count = -1; // can only drop a whole worn item
        }
        set_drop_count(it_pos, count, u.worn[wpos]);
    } else { // inventory
        const std::list<item> &stack = u.inv.const_stack(it_pos);
        if (stack.empty()) {
            return; // invalid it_pos -> ignore
        }
        set_drop_count(it_pos, count, stack);
    }
}
void inventory_selector::set_selected_to_drop(int count)
{
    const itemstack_vector &items = in_inventory ? this->items : this->worn;
    const size_t &selected = in_inventory ? selected_i: selected_w;
    if (selected >= items.size()) {
        return;
    }
    const itemstack_or_category &cur_entry = items[selected];
    if (cur_entry.it != NULL && cur_entry.slice != NULL) {
        set_drop_count(cur_entry.item_pos, count, *cur_entry.slice);
    } else if (cur_entry.it != NULL) {
        set_drop_count(cur_entry.item_pos, count, *cur_entry.it);
    }
}
std::list<std::pair<int, int>> inventory_selector::execute_multidrop( const std::string &title )
{
    insert_selection_column( "ITEMS TO DROP", _( "ITEMS TO DROP" ) );
    prepare_columns( true );

    int count = 0;
    while( true ) {
        display( title, SM_MULTIDROP );

        const std::string action = ctxt.handle_input();
        const long ch = ctxt.get_raw_input().get_first_input();
        auto entry = find_entry_by_invlet( ch );

        if( ch >= '0' && ch <= '9' ) {
            count = std::min( count, INT_MAX / 10 - 10 );
            count *= 10;
            count += ch - '0';
        } else if( entry != nullptr ) {
            set_drop_count( *entry, count );
            count = 0;
        } else if( action == "RIGHT" ) {
            for( const auto &entry : get_active_column().get_all_selected() ) {
                set_drop_count( *entry, count );
            }
            count = 0;
        } else if( action == "CONFIRM" ) {
            break;
        } else if( action == "QUIT" ) {
            return std::list<std::pair<int, int> >();
        } else {
            on_action( action );
            count = 0;
        }
    }

    std::list<std::pair<int, int>> dropped_pos_and_qty;

    for( auto drop_pair : dropping ) {
        dropped_pos_and_qty.push_back( std::make_pair( drop_pair.first, drop_pair.second ) );
    }

    return dropped_pos_and_qty;
}
void inventory_selector::set_drop_count(int it_pos, int count, const std::list<item> &stack)
{
    if (stack.size() == 1) {
        const item &it = stack.front();
        if (count > 0 && (!it.count_by_charges() || count >= it.charges)) {
            count = -1; // drop whole item, because it can not be separated, or count is big enough anyway
        }
    } else if (count > 0 && (size_t) count >= stack.size()) {
        count = -1; // count indicates whole stack anyway
    } else if (stack.empty()) {
        return;
    }
    set_drop_count(it_pos, count, stack.front());
}