* Make the mail daemon run through the dungeon. The daemon will run over * any monsters that are in its path, but will replace them later. Return * FALSE if the md gets stuck in a position where there is a monster. Return * TRUE otherwise. */
| 285 | * TRUE otherwise. |
| 286 | */ |
| 287 | staticfn boolean |
| 288 | md_rush(struct monst *md, |
| 289 | int tx, int ty) /* destination of mail daemon */ |
| 290 | { |
| 291 | struct monst *mon; /* displaced monster */ |
| 292 | int dx, dy; /* direction counters */ |
| 293 | int fx = md->mx, fy = md->my; /* current location */ |
| 294 | int nfx = fx, nfy = fy, /* new location */ |
| 295 | d1, d2; /* shortest distances */ |
| 296 | |
| 297 | /* |
| 298 | * It is possible that the monster at (fx,fy) is not the md when: |
| 299 | * the md rushed the hero and failed, and is now starting back. |
| 300 | */ |
| 301 | if (m_at(fx, fy) == md) { |
| 302 | remove_monster(fx, fy); /* pick up from orig position */ |
| 303 | newsym(fx, fy); |
| 304 | } |
| 305 | |
| 306 | /* |
| 307 | * At the beginning and exit of this loop, md is not placed in the |
| 308 | * dungeon. |
| 309 | */ |
| 310 | while (1) { |
| 311 | /* Find a good location next to (fx,fy) closest to (tx,ty). */ |
| 312 | d1 = dist2(fx, fy, tx, ty); |
| 313 | for (dx = -1; dx <= 1; dx++) |
| 314 | for (dy = -1; dy <= 1; dy++) |
| 315 | if ((dx || dy) && isok(fx + dx, fy + dy) |
| 316 | && !IS_STWALL(levl[fx + dx][fy + dy].typ)) { |
| 317 | d2 = dist2(fx + dx, fy + dy, tx, ty); |
| 318 | if (d2 < d1) { |
| 319 | d1 = d2; |
| 320 | nfx = fx + dx; |
| 321 | nfy = fy + dy; |
| 322 | } |
| 323 | } |
| 324 | |
| 325 | /* Break if the md couldn't find a new position. */ |
| 326 | if (nfx == fx && nfy == fy) |
| 327 | break; |
| 328 | |
| 329 | fx = nfx; /* this is our new position */ |
| 330 | fy = nfy; |
| 331 | |
| 332 | /* Break if the md reaches its destination. */ |
| 333 | if (fx == tx && fy == ty) |
| 334 | break; |
| 335 | |
| 336 | mon = m_at(fx, fy); /* save monster at this position */ |
| 337 | if (!Deaf) { |
| 338 | SetVoice(md, 0, 80, 0); |
| 339 | if (mon) |
| 340 | verbalize1(md_exclamations()); |
| 341 | else if (u_at(fx, fy)) |
| 342 | verbalize("Excuse me."); |
| 343 | } |
| 344 |
no test coverage detected