Move from (ax,ay) to (bx,by), but only if distance is up to BOLT_LIM and only in straight line or diagonal, calling fnc for each step. Stops if fnc return TRUE, or if step was blocked by wall or closed door. Returns TRUE if fnc returned TRUE. */
| 1292 | Stops if fnc return TRUE, or if step was blocked by wall or closed door. |
| 1293 | Returns TRUE if fnc returned TRUE. */ |
| 1294 | boolean |
| 1295 | linedup_callback( |
| 1296 | coordxy ax, |
| 1297 | coordxy ay, |
| 1298 | coordxy bx, |
| 1299 | coordxy by, |
| 1300 | boolean (*fnc)(coordxy, coordxy)) |
| 1301 | { |
| 1302 | int dx, dy; |
| 1303 | |
| 1304 | /* These two values are set for use after successful return. */ |
| 1305 | gt.tbx = ax - bx; |
| 1306 | gt.tby = ay - by; |
| 1307 | |
| 1308 | /* sometimes displacement makes a monster think that you're at its |
| 1309 | own location; prevent it from throwing and zapping in that case */ |
| 1310 | if (!gt.tbx && !gt.tby) |
| 1311 | return FALSE; |
| 1312 | |
| 1313 | /* straight line, orthogonal to the map or diagonal */ |
| 1314 | if ((!gt.tbx || !gt.tby || abs(gt.tbx) == abs(gt.tby)) |
| 1315 | && distmin(gt.tbx, gt.tby, 0, 0) < BOLT_LIM) { |
| 1316 | dx = sgn(ax - bx), dy = sgn(ay - by); |
| 1317 | do { |
| 1318 | /* <bx,by> is guaranteed to eventually converge with <ax,ay> */ |
| 1319 | bx += dx, by += dy; |
| 1320 | if (blocking_terrain(bx, by)) |
| 1321 | return FALSE; |
| 1322 | if ((*fnc)(bx, by)) |
| 1323 | return TRUE; |
| 1324 | } while (bx != ax || by != ay); |
| 1325 | } |
| 1326 | return FALSE; |
| 1327 | } |
| 1328 | |
| 1329 | boolean |
| 1330 | linedup( |
no test coverage detected