Hack to prevent a dog from being endlessly stuck near an object that * it can't reach, such as caught in a teleport scroll niche. It recursively * checks to see if the squares in between are good. The checking could be * a little smarter; a full check would probably be useful in m_move() too. * Since the maximum food distance is 5, this should never be more than 5 * calls deep. */
| 1376 | * calls deep. |
| 1377 | */ |
| 1378 | staticfn boolean |
| 1379 | can_reach_location( |
| 1380 | struct monst *mon, |
| 1381 | coordxy mx, coordxy my, |
| 1382 | coordxy fx, coordxy fy) |
| 1383 | { |
| 1384 | int i, j; |
| 1385 | int dist; |
| 1386 | |
| 1387 | if (mx == fx && my == fy) |
| 1388 | return TRUE; |
| 1389 | if (!isok(mx, my)) |
| 1390 | return FALSE; /* should not happen */ |
| 1391 | |
| 1392 | dist = dist2(mx, my, fx, fy); |
| 1393 | for (i = mx - 1; i <= mx + 1; i++) { |
| 1394 | for (j = my - 1; j <= my + 1; j++) { |
| 1395 | if (!isok(i, j)) |
| 1396 | continue; |
| 1397 | if (dist2(i, j, fx, fy) >= dist) |
| 1398 | continue; |
| 1399 | if (IS_OBSTRUCTED(levl[i][j].typ) && !passes_walls(mon->data) |
| 1400 | && (!may_dig(i, j) || !tunnels(mon->data) |
| 1401 | /* tunnelling monsters can't do that on the rogue level */ |
| 1402 | || Is_rogue_level(&u.uz))) |
| 1403 | continue; |
| 1404 | if (IS_DOOR(levl[i][j].typ) |
| 1405 | && (levl[i][j].doormask & (D_CLOSED | D_LOCKED))) |
| 1406 | continue; |
| 1407 | if (!could_reach_item(mon, i, j)) |
| 1408 | continue; |
| 1409 | if (can_reach_location(mon, i, j, fx, fy)) |
| 1410 | return TRUE; |
| 1411 | } |
| 1412 | } |
| 1413 | return FALSE; |
| 1414 | } |
| 1415 | |
| 1416 | /* do_clear_area client */ |
| 1417 | staticfn void |
no test coverage detected