The clear_path() function I mentioned does exactly that, though I got the argument wrong now that I think of it, instead of:
if( m.clear_path( smoker.x, smoker.y, smoke_candidate.x, smoke_candidate.y,
smoke_distance, -1, 100, junk ) ) {
it should be:
if( m.clear_path( smoker.x, smoker.y, smoke_candidate.x, smoke_candidate.y,
smoke_distance, 1, 100, junk ) ) {
Explanation, that first numneric argument is the “minimum move cost” per-tile, if move cost is 0, it means non-navigable, in other words a wall. The second is the maximum, but we don’t care about it being too high, so it’s set to a ridiculous value.