item *game::inv_map_for_liquid(const item &liquid, const std::string &title, int radius)
{
    auto filter = [&]( const item &candidate ) {
        return candidate.get_remaining_capacity_for_liquid( liquid ) > 0;
    };

    return inv_map_splice( filter, title, radius ).get_item();
}
item *game::inv_map_for_liquid(const item &liquid, const std::string &title, int radius)
{
    // Vehicle filter shouldn't allow buckets
    auto sealable_filter = [&]( const item &candidate ) {
        return candidate.get_remaining_capacity_for_liquid( liquid, false ) > 0;
    };

    // Map filter should allow buckets
    auto bucket_filter = [&]( const item &candidate ) {
        return candidate.get_remaining_capacity_for_liquid( liquid, true ) > 0;
    };

    // Inventory filter should allow only held buckets
    auto inv_filter = [&]( const item &candidate ) {
        return candidate.get_remaining_capacity_for_liquid( liquid, &candidate == &g->u.weapon ) > 0;
    };

    return inv_map_splice( inv_filter, bucket_filter, sealable_filter, title, radius,
                           string_format( _( "You don't have a suitable container for carrying %s." ),
                           liquid.type_name( 1 ).c_str() ) ).get_item();
}
item_location game::inv_map_splice( item_filter filter, const std::string &title, int radius )
{
    return inv_map_splice( filter, filter, filter, title, radius );
}
int game::inv_for_filter( const std::string &title, item_filter filter,
                          const std::string &none_message )
{
    return u.get_item_position( inv_map_splice( filter, title, -1, none_message ).get_item() );
}