MCPcopy Create free account
hub / github.com/NetHack/NetHack / landing_spot

Function landing_spot

src/steed.c:459–572  ·  view source on GitHub ↗

* Try to find a dismount point adjacent to the steed's location. * If all else fails, try enexto(). Use enexto() as a last resort because * enexto() chooses its point randomly, possibly even outside the * room's walls, which is not what we want. * Adapted from mail daemon code. */

Source from the content-addressed store, hash-verified

457 * Adapted from mail daemon code.
458 */
459staticfn boolean
460landing_spot(
461 coord *spot, /* landing position (we fill it in) */
462 int reason,
463 int forceit)
464{
465 coord cc, try[8]; /* 8: the 8 spots adjacent to the hero's spot */
466 int i, j, best_j, clockwise_j, counterclk_j,
467 n, viable, distance, min_distance = -1;
468 coordxy x, y;
469 boolean found, impaird, kn_trap, boulder;
470 struct trap *t;
471
472 (void) memset((genericptr_t) try, 0, sizeof try);
473 n = 0;
474 j = xytodir(u.dx, u.dy);
475 if (reason == DISMOUNT_KNOCKED && j != DIR_ERR) {
476 /* we'll check preferred location first; if viable it'll be picked */
477 best_j = j;
478 try[0].x = u.dx, try[0].y = u.dy;
479 /* the two next best locations are checked second and third */
480 i = rn2(2);
481 clockwise_j = DIR_RIGHT(j); /* (j + 1) % 8 */
482 dirtocoord(&cc, clockwise_j);
483 try[1 + i].x = cc.x, try[1 + i].y = cc.y; /* [1] or [2] */
484 counterclk_j = DIR_LEFT(j); /* (j + 8 - 1) % 8 */
485 dirtocoord(&cc, counterclk_j);
486 try[2 - i].x = cc.x, try[2 - i].y = cc.y; /* [2] or [1] */
487 n = 3;
488 debugpline3("knock from saddle: best %s, next %s or %s",
489 directionname(best_j),
490 directionname(clockwise_j), directionname(counterclk_j));
491 } else {
492 best_j = clockwise_j = counterclk_j = -1;
493 }
494 for (j = 0; j < N_DIRS; ++j) {
495 /* fortunately NODIAG() handling isn't needed for DISMOUNT_KNOCKED
496 because hero can only ride when humanoid */
497 if (j == best_j || j == clockwise_j || j == counterclk_j)
498 continue;
499 /* j==0 is W, j==1 NW, j==2 N, j==3 NE, ..., around to j==7 SW;
500 so odd j values are diagonal directions here */
501 if (reason == DISMOUNT_POLY && NODIAG(u.umonnum) && (j % 1) != 0)
502 continue;
503 dirtocoord(&cc, j);
504 try[n++] = cc;
505 }
506
507 /*
508 * Up to three passes;
509 * i==0: voluntary dismount without impairment avoids known traps and
510 * boulders;
511 * i==1: voluntary dismount with impairment or knocked out of saddle
512 * avoids boulders but allows known traps;
513 * i==2: other, allow traps and boulders.
514 *
515 * Fallback to i==1 if nothing appropriate was found for i==0 and
516 * to i==2 as last resort.

Callers 1

dismount_steedFunction · 0.85

Calls 10

xytodirFunction · 0.85
rn2Function · 0.85
dirtocoordFunction · 0.85
directionnameFunction · 0.85
isokFunction · 0.85
accessibleFunction · 0.85
test_moveFunction · 0.85
t_atFunction · 0.85
sobj_atFunction · 0.85
enextoFunction · 0.85

Tested by

no test coverage detected