monster looks for items it wants nearby */
| 1327 | |
| 1328 | /* monster looks for items it wants nearby */ |
| 1329 | staticfn boolean |
| 1330 | m_search_items( |
| 1331 | struct monst *mtmp, |
| 1332 | coordxy *ggx, coordxy *ggy, |
| 1333 | int *mmoved, |
| 1334 | int *appr) |
| 1335 | { |
| 1336 | int minr = SQSRCHRADIUS; /* not too far away */ |
| 1337 | struct obj *otmp; |
| 1338 | coordxy xx, yy; |
| 1339 | coordxy hmx, hmy, lmx, lmy; |
| 1340 | struct trap *ttmp; |
| 1341 | coordxy omx = mtmp->mx, omy = mtmp->my; |
| 1342 | struct permonst *ptr = mtmp->data; |
| 1343 | struct monst *mtoo; |
| 1344 | boolean costly; |
| 1345 | |
| 1346 | /* cut down the search radius if it thinks character is closer. */ |
| 1347 | if (distmin(mtmp->mux, mtmp->muy, omx, omy) < SQSRCHRADIUS |
| 1348 | && !mtmp->mpeaceful) |
| 1349 | minr--; |
| 1350 | /* guards shouldn't get too distracted */ |
| 1351 | if (!mtmp->mpeaceful && is_mercenary(ptr)) |
| 1352 | minr = 1; |
| 1353 | |
| 1354 | /* in shop, usually skip */ |
| 1355 | if (*in_rooms(omx, omy, SHOPBASE) && (rn2(25) || mtmp->isshk)) |
| 1356 | goto finish_search; |
| 1357 | |
| 1358 | /* distmin() gives a rectangular area */ |
| 1359 | hmx = min(COLNO - 1, omx + minr); |
| 1360 | hmy = min(ROWNO - 1, omy + minr); |
| 1361 | lmx = max(1, omx - minr); |
| 1362 | lmy = max(0, omy - minr); |
| 1363 | |
| 1364 | for (xx = lmx; xx <= hmx; xx++) { |
| 1365 | for (yy = lmy; yy <= hmy; yy++) { |
| 1366 | /* no object here */ |
| 1367 | if (!OBJ_AT(xx, yy)) |
| 1368 | continue; |
| 1369 | /* found an object closer already */ |
| 1370 | if (minr < distmin(omx, omy, xx, yy)) |
| 1371 | continue; |
| 1372 | /* the mfndpos() test for whether to allow a move to a |
| 1373 | water location accepts flyers, but they can't reach |
| 1374 | underwater objects, so being able to move to a spot |
| 1375 | is insufficient for deciding whether to do so */ |
| 1376 | if (!could_reach_item(mtmp, xx, yy)) |
| 1377 | continue; |
| 1378 | /* hiders avoid hero's line of sight */ |
| 1379 | if (hides_under(ptr) && cansee(xx, yy)) |
| 1380 | continue; |
| 1381 | /* don't get stuck circling around object that's |
| 1382 | underneath an immobile or hidden monster; |
| 1383 | paralysis victims excluded */ |
| 1384 | if ((mtoo = m_at(xx, yy)) != 0 |
| 1385 | && (helpless(mtoo) || mtoo->mundetected |
| 1386 | || (mtoo->mappearance && !mtoo->iswiz) |
no test coverage detected