char name[BUFSZ]; /* actual killer name */
};
-E const schar xdir[], ydir[], zdir[];
+enum movementdirs {
+ DIR_ERR = -1,
+ DIR_W,
+ DIR_NW,
+ DIR_N,
+ DIR_NE,
+ DIR_E,
+ DIR_SE,
+ DIR_S,
+ DIR_SW,
+ DIR_UP,
+ DIR_DOWN,
+
+ N_DIRS_Z
+};
+/* N_DIRS_Z, minus up & down */
+#define N_DIRS (N_DIRS_Z - 2)
+/* direction adjustments */
+#define DIR_180(dir) (((dir) + 4) % N_DIRS)
+#define DIR_LEFT(dir) (((dir) + 7) % N_DIRS)
+#define DIR_RIGHT(dir) (((dir) + 1) % N_DIRS)
+#define DIR_LEFT2(dir) (((dir) + 6) % N_DIRS)
+#define DIR_RIGHT2(dir) (((dir) + 2) % N_DIRS)
+#define DIR_CLAMP(dir) (((dir) + N_DIRS) % N_DIRS)
+
+extern const schar xdir[], ydir[], zdir[], dirs_ord[];
struct multishot {
int n, i;
boolean pcHack_compat; /* for numpad: affects 5, M-5, and M-0 */
boolean phone_layout; /* inverted keypad: 1,2,3 above, 7,8,9 below */
boolean swap_yz; /* QWERTZ keyboards; use z to move NW, y to zap */
- char move_W, move_NW, move_N, move_NE, move_E, move_SE, move_S, move_SW;
+ char move[N_DIRS]; /* char used for moving one step in direction */
const char *dirchars; /* current movement/direction characters */
const char *alphadirchars; /* same as dirchars if !numpad */
const struct ext_func_tab *commands[256]; /* indexed by input character */
zapsetup();
/* this makes it hit us last, so that we can see the action first */
- for (i = 0; i <= 8; i++) {
+ for (i = 0; i <= N_DIRS; i++) {
g.bhitpos.x = x = obj->ox + xdir[i];
g.bhitpos.y = y = obj->oy + ydir[i];
if (!isok(x, y))
(void) memset((genericptr_t) keys_used, 0, sizeof keys_used);
(void) memset((genericptr_t) pfx_seen, 0, sizeof pfx_seen);
- keys_used[(uchar) g.Cmd.move_NW] = keys_used[(uchar) g.Cmd.move_N]
- = keys_used[(uchar) g.Cmd.move_NE] = keys_used[(uchar) g.Cmd.move_W]
- = keys_used[(uchar) g.Cmd.move_E] = keys_used[(uchar) g.Cmd.move_SW]
- = keys_used[(uchar) g.Cmd.move_S] = keys_used[(uchar) g.Cmd.move_SE]
- = TRUE;
+ for (i = 0; i < N_DIRS; i++)
+ keys_used[(uchar) g.Cmd.move[i]] = TRUE;
if (!iflags.num_pad) {
- keys_used[(uchar) highc(g.Cmd.move_NW)]
- = keys_used[(uchar) highc(g.Cmd.move_N)]
- = keys_used[(uchar) highc(g.Cmd.move_NE)]
- = keys_used[(uchar) highc(g.Cmd.move_W)]
- = keys_used[(uchar) highc(g.Cmd.move_E)]
- = keys_used[(uchar) highc(g.Cmd.move_SW)]
- = keys_used[(uchar) highc(g.Cmd.move_S)]
- = keys_used[(uchar) highc(g.Cmd.move_SE)] = TRUE;
- keys_used[(uchar) C(g.Cmd.move_NW)]
- = keys_used[(uchar) C(g.Cmd.move_N)]
- = keys_used[(uchar) C(g.Cmd.move_NE)]
- = keys_used[(uchar) C(g.Cmd.move_W)]
- = keys_used[(uchar) C(g.Cmd.move_E)]
- = keys_used[(uchar) C(g.Cmd.move_SW)]
- = keys_used[(uchar) C(g.Cmd.move_S)]
- = keys_used[(uchar) C(g.Cmd.move_SE)] = TRUE;
+ for (i = 0; i < N_DIRS; i++) {
+ keys_used[(uchar) highc(g.Cmd.move[i])] = TRUE;
+ keys_used[(uchar) C(g.Cmd.move[i])] = TRUE;
+ }
} else {
/* num_pad */
keys_used[(uchar) M('1')] = keys_used[(uchar) M('2')]
: (!g.Cmd.phone_layout ? ndir : ndir_phone_layout);
g.Cmd.alphadirchars = !g.Cmd.num_pad ? g.Cmd.dirchars : sdir;
- g.Cmd.move_W = g.Cmd.dirchars[0];
- g.Cmd.move_NW = g.Cmd.dirchars[1];
- g.Cmd.move_N = g.Cmd.dirchars[2];
- g.Cmd.move_NE = g.Cmd.dirchars[3];
- g.Cmd.move_E = g.Cmd.dirchars[4];
- g.Cmd.move_SE = g.Cmd.dirchars[5];
- g.Cmd.move_S = g.Cmd.dirchars[6];
- g.Cmd.move_SW = g.Cmd.dirchars[7];
+ for (i = 0; i < N_DIRS; i++)
+ g.Cmd.move[i] = g.Cmd.dirchars[i];
if (!initial) {
for (i = 0; i < 8; i++) {
{
register int dd;
- for (dd = 0; dd < 8; dd++)
+ for (dd = 0; dd < N_DIRS; dd++)
if (x == xdir[dd] && y == ydir[dd])
return dd;
- return -1;
+ return DIR_ERR;
}
/* convert a direction code into an x,y pair */
void
dtoxy(coord *cc, int dd)
{
- cc->x = xdir[dd];
- cc->y = ydir[dd];
- return;
+ if (dd > DIR_ERR && dd < N_DIRS_Z) {
+ cc->x = xdir[dd];
+ cc->y = ydir[dd];
+ }
}
/* also sets u.dz, but returns false for <> */
centerchar = ' ';
if (nodiag) {
- Sprintf(buf, " %c ", g.Cmd.move_N);
+ Sprintf(buf, " %c ", g.Cmd.move[DIR_N]);
putstr(win, 0, buf);
putstr(win, 0, " | ");
Sprintf(buf, " %c- %c -%c",
- g.Cmd.move_W, centerchar, g.Cmd.move_E);
+ g.Cmd.move[DIR_W], centerchar, g.Cmd.move[DIR_E]);
putstr(win, 0, buf);
putstr(win, 0, " | ");
- Sprintf(buf, " %c ", g.Cmd.move_S);
+ Sprintf(buf, " %c ", g.Cmd.move[DIR_S]);
putstr(win, 0, buf);
} else {
Sprintf(buf, " %c %c %c",
- g.Cmd.move_NW, g.Cmd.move_N, g.Cmd.move_NE);
+ g.Cmd.move[DIR_NW], g.Cmd.move[DIR_N], g.Cmd.move[DIR_NE]);
putstr(win, 0, buf);
putstr(win, 0, " \\ | / ");
Sprintf(buf, " %c- %c -%c",
- g.Cmd.move_W, centerchar, g.Cmd.move_E);
+ g.Cmd.move[DIR_W], centerchar, g.Cmd.move[DIR_E]);
putstr(win, 0, buf);
putstr(win, 0, " / | \\ ");
Sprintf(buf, " %c %c %c",
- g.Cmd.move_SW, g.Cmd.move_S, g.Cmd.move_SE);
+ g.Cmd.move[DIR_SW], g.Cmd.move[DIR_S], g.Cmd.move[DIR_SE]);
putstr(win, 0, buf);
};
}
void
confdir(void)
{
- register int x = NODIAG(u.umonnum) ? 2 * rn2(4) : rn2(8);
+ register int x = NODIAG(u.umonnum) ? dirs_ord[rn2(4)] : rn2(N_DIRS);
u.dx = xdir[x];
u.dy = ydir[x];
const char *
directionname(int dir)
{
- static NEARDATA const char *const dirnames[] = {
+ static NEARDATA const char *const dirnames[N_DIRS_Z] = {
"west", "northwest", "north", "northeast", "east",
"southeast", "south", "southwest", "down", "up",
};
- if (dir < 0 || dir >= SIZE(dirnames))
+ if (dir < 0 || dir >= N_DIRS_Z)
return "invalid";
return dirnames[dir];
}
const char disclosure_options[] = "iavgco";
/* x/y/z deltas for the 10 movement directions (8 compass pts, 2 up/down) */
-const schar xdir[10] = { -1, -1, 0, 1, 1, 1, 0, -1, 0, 0 };
-const schar ydir[10] = { 0, -1, -1, -1, 0, 1, 1, 1, 0, 0 };
-const schar zdir[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, -1 };
+const schar xdir[N_DIRS_Z] = { -1, -1, 0, 1, 1, 1, 0, -1, 0, 0 };
+const schar ydir[N_DIRS_Z] = { 0, -1, -1, -1, 0, 1, 1, 1, 0, 0 };
+const schar zdir[N_DIRS_Z] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, -1 };
+/* redordered directions, cardinals first */
+const schar dirs_ord[N_DIRS] =
+ { DIR_W, DIR_N, DIR_E, DIR_S, DIR_NW, DIR_NE, DIR_SE, DIR_SW };
NEARDATA struct flag flags;
NEARDATA boolean has_strong_rngseed = FALSE;
&& (trap_with_u = t_at(u.ux, u.uy))
&& is_pit(trap->ttyp)
&& !conjoined_pits(trap, trap_with_u, FALSE)) {
- int idx;
+ int idx = xytod(u.dx, u.dy);
- for (idx = 0; idx < 8; idx++) {
- if (xdir[idx] == u.dx && ydir[idx] == u.dy)
- break;
- }
- /* idx is valid if < 8 */
- if (idx < 8) {
- int adjidx = (idx + 4) % 8;
+ if (idx != DIR_ERR) {
+ int adjidx = DIR_180(idx);
trap_with_u->conjoined |= (1 << idx);
trap->conjoined |= (1 << adjidx);
if (u.utrap && u.utraptype == TT_PIT
&& (trap_with_u = t_at(u.ux, u.uy))) {
pitdig = TRUE;
- for (diridx = 0; diridx < 8; diridx++) {
- if (xdir[diridx] == u.dx && ydir[diridx] == u.dy)
- break;
- /* diridx is valid if < 8 */
- }
+ diridx = xytod(u.dx, u.dy);
}
digdepth = rn1(18, 8);
tmp_at(DISP_BEAM, cmap_to_glyph(S_digbeam));
if (pitdig) { /* we are already in a pit if this is true */
coord cc;
struct trap *adjpit = t_at(zx, zy);
- if ((diridx < 8) && !conjoined_pits(adjpit, trap_with_u, FALSE)) {
+
+ if ((diridx != DIR_ERR) && !conjoined_pits(adjpit, trap_with_u, FALSE)) {
digdepth = 0; /* limited to the adjacent location only */
if (!(adjpit && is_pit(adjpit->ttyp))) {
char buf[BUFSZ];
+
cc.x = zx;
cc.y = zy;
if (!adj_pit_checks(&cc, buf)) {
adjpit = t_at(zx, zy);
}
}
- if (adjpit
- && is_pit(adjpit->ttyp)) {
- int adjidx = (diridx + 4) % 8;
+ if (adjpit && is_pit(adjpit->ttyp)) {
+ int adjidx = DIR_180(diridx);
+
trap_with_u->conjoined |= (1 << diridx);
adjpit->conjoined |= (1 << adjidx);
flow_x = zx;
(t.tx == u.ux && t.ty == u.uy)
? "Suddenly %s flows in from the adjacent pit!"
: (char *) 0);
- for (idx = 0; idx < 8; ++idx) {
+ for (idx = 0; idx < N_DIRS; ++idx) {
if (t.conjoined & (1 << idx)) {
int x, y;
struct trap *t2;
* called deltrap() which cleaned up the
* conjoined fields on both pits.
*/
- if (t2 && (t2->conjoined & (1 << ((idx + 4) % 8))))
+ if (t2 && (t2->conjoined & (1 << DIR_180(idx))))
#endif
/* recursion */
pit_flow(t2, filltyp);
Sprintf(sbuf,
"Use '%c', '%c', '%c', '%c' to move the cursor to %s.", /* hjkl */
- g.Cmd.move_W, g.Cmd.move_S, g.Cmd.move_N, g.Cmd.move_E, goal);
+ g.Cmd.move[DIR_W], g.Cmd.move[DIR_S],
+ g.Cmd.move[DIR_N], g.Cmd.move[DIR_E], goal);
putstr(tmpwin, 0, sbuf);
Sprintf(sbuf,
"Use 'H', 'J', 'K', 'L' to fast-move the cursor, %s.",
result = pick_chars_def[(int) (cp - pick_chars)].ret;
break;
}
- for (i = 0; i < 8; i++) {
+ for (i = 0; i < N_DIRS; i++) {
int dx, dy;
if (g.Cmd.dirchars[i] == c) {
Strcpy(note, "aborted");
else /* hjkl */
Sprintf(note, "use '%c', '%c', '%c', '%c' or '%s'",
- g.Cmd.move_W, g.Cmd.move_S, g.Cmd.move_N, g.Cmd.move_E,
+ g.Cmd.move[DIR_W], g.Cmd.move[DIR_S],
+ g.Cmd.move[DIR_N], g.Cmd.move[DIR_E],
visctrl(g.Cmd.spkeys[NHKF_GETPOS_PICK]));
pline("Unknown direction: '%s' (%s).", visctrl((char) c),
note);
goto dognext;
i = xytod(nx, ny);
- for (j = (i + 7) % 8; j < (i + 1) % 8; j++) {
+ for (j = DIR_LEFT(i); j < DIR_RIGHT(i); j++) {
dtoxy(&cc, j);
if (goodpos(cc.x, cc.y, mtmp, 0))
goto dognext;
}
- for (j = (i + 6) % 8; j < (i + 2) % 8; j++) {
+ for (j = DIR_LEFT2(i); j < DIR_RIGHT2(i); j++) {
dtoxy(&cc, j);
if (goodpos(cc.x, cc.y, mtmp, 0))
goto dognext;
stmp->obj = otmp;
stmp->ox = sx;
stmp->oy = sy;
- tmp = rn2(8); /* get the direction */
+ tmp = rn2(N_DIRS); /* get the direction */
stmp->dx = xdir[tmp];
stmp->dy = ydir[tmp];
tmp = blastforce - (otmp->owt / 40);
int dir;
int x = travelstepx[set][i];
int y = travelstepy[set][i];
- static int ordered[] = { 0, 2, 4, 6, 1, 3, 5, 7 };
/* no diagonal movement for grid bugs */
- int dirmax = NODIAG(u.umonnum) ? 4 : 8;
+ int dirmax = NODIAG(u.umonnum) ? 4 : N_DIRS;
boolean alreadyrepeated = FALSE;
for (dir = 0; dir < dirmax; ++dir) {
- int nx = x + xdir[ordered[dir]];
- int ny = y + ydir[ordered[dir]];
+ int nx = x + xdir[dirs_ord[dir]];
+ int ny = y + ydir[dirs_ord[dir]];
/*
* When guessing and trying to travel as close as possible
static boolean
door_into_nonjoined(xchar x, xchar y)
{
- xchar tx, ty, diridx;
+ xchar tx, ty, i;
- for (diridx = 0; diridx <= 6; diridx += 2) {
- tx = x + xdir[diridx];
- ty = y + ydir[diridx];
+ for (i = 0; i < 4; i++) {
+ tx = x + xdir[dirs_ord[i]];
+ ty = y + ydir[dirs_ord[i]];
if (!isok(tx, ty) || IS_ROCK(levl[tx][ty].typ))
continue;
struct monst *priest;
struct obj *otmp;
int cnt;
- int px = 0, py = 0, i, si = rn2(8);
+ int px = 0, py = 0, i, si = rn2(N_DIRS);
struct permonst *prim = &mons[sanctum ? PM_HIGH_CLERIC : PM_ALIGNED_CLERIC];
- for (i = 0; i < 8; i++) {
- px = sx + xdir[(i+si) % 8];
- py = sy + ydir[(i+si) % 8];
+ for (i = 0; i < N_DIRS; i++) {
+ px = sx + xdir[DIR_CLAMP(i+si)];
+ py = sy + ydir[DIR_CLAMP(i+si)];
if (pm_good_location(px, py, prim))
break;
}
- if (i == 8)
+ if (i == N_DIRS)
px = sx, py = sy;
if (MON_AT(px, py))
if (ttmp->ttyp == ROLLING_BOULDER_TRAP)
mindist = 2;
distance = rn1(5, 4); /* 4..8 away */
- tmp = rn2(8); /* randomly pick a direction to try first */
+ tmp = rn2(N_DIRS); /* randomly pick a direction to try first */
while (distance >= mindist) {
dx = xdir[tmp];
dy = ydir[tmp];
return FALSE;
dx = sgn(trap2->tx - trap1->tx);
dy = sgn(trap2->ty - trap1->ty);
- for (diridx = 0; diridx < 8; diridx++)
- if (xdir[diridx] == dx && ydir[diridx] == dy)
- break;
- /* diridx is valid if < 8 */
- if (diridx < 8) {
- adjidx = (diridx + 4) % 8;
+ diridx = xytod(dx, dy);
+ if (diridx != DIR_ERR) {
+ adjidx = DIR_180(diridx);
if ((trap1->conjoined & (1 << diridx))
&& (trap2->conjoined & (1 << adjidx)))
return TRUE;
struct trap *t;
if (trap && is_pit(trap->ttyp)) {
- for (diridx = 0; diridx < 8; ++diridx) {
+ for (diridx = 0; diridx < N_DIRS; ++diridx) {
if (trap->conjoined & (1 << diridx)) {
x = trap->tx + xdir[diridx];
y = trap->ty + ydir[diridx];
if (isok(x, y)
&& (t = t_at(x, y)) != 0
&& is_pit(t->ttyp)) {
- adjidx = (diridx + 4) % 8;
+ adjidx = DIR_180(diridx);
t->conjoined &= ~(1 << adjidx);
}
trap->conjoined &= ~(1 << diridx);
if (trap_with_u && adjtrap && u.utrap && u.utraptype == TT_PIT
&& is_pit(trap_with_u->ttyp) && is_pit(adjtrap->ttyp)) {
- int idx;
-
- for (idx = 0; idx < 8; idx++) {
- if (xdir[idx] == u.dx && ydir[idx] == u.dy)
- return TRUE;
- }
+ if (xytod(u.dx, u.dy) != DIR_ERR)
+ return TRUE;
}
return FALSE;
}
if (!trap)
return;
- for (diridx = 0; diridx < 8; ++diridx) {
+ for (diridx = 0; diridx < N_DIRS; ++diridx) {
x = trap->tx + xdir[diridx];
y = trap->ty + ydir[diridx];
if (isok(x, y)) {
with a backswing--that doesn't impact actual play, just spoils the
simulation attempt a bit */
static boolean clockwise = FALSE;
- unsigned i;
+ int i;
coord save_bhitpos;
int count, umort, x = u.ux, y = u.uy;
/* find the direction toward primary target */
- for (i = 0; i < 8; ++i)
- if (xdir[i] == u.dx && ydir[i] == u.dy)
- break;
- if (i == 8) {
+ i = xytod(u.dx, u.dy);
+ if (i == DIR_ERR) {
impossible("hitum_cleave: unknown target direction [%d,%d,%d]?",
u.dx, u.dy, u.dz);
return TRUE; /* target hasn't been killed */
/* adjust direction by two so that loop's increment (for clockwise)
or decrement (for counter-clockwise) will point at the spot next
to primary target */
- i = (i + (clockwise ? 6 : 2)) % 8;
+ i = clockwise ? DIR_LEFT2(i) : DIR_RIGHT2(i);
umort = u.umortality; /* used to detect life-saving */
save_bhitpos = g.bhitpos;
int tx, ty, tmp, dieroll, mhit, attknum, armorpenalty;
/* ++i, wrap 8 to i=0 /or/ --i, wrap -1 to i=7 */
- i = (i + (clockwise ? 1 : 7)) % 8;
+ i = clockwise ? DIR_RIGHT(i) : DIR_LEFT(i);
tx = x + xdir[i], ty = y + ydir[i]; /* current target location */
if (!isok(tx, ty))
if (tryct <= 50)
#else /* new code */
- int i, j, k, dirs[8];
+ int i, j, k, dirs[N_DIRS];
/* instead of picking a random direction up to 50 times, try each
of the eight directions at most once after shuffling their order */
- for (i = 0; i < 8; ++i)
+ for (i = 0; i < N_DIRS; ++i)
dirs[i] = i;
- for (i = 8; i > 0; --i) {
+ for (i = N_DIRS; i > 0; --i) {
j = rn2(i);
k = dirs[j];
dirs[j] = dirs[i - 1];
dirs[i - 1] = k;
}
- for (i = 0; i < 8; ++i) {
+ for (i = 0; i < N_DIRS; ++i) {
nx = ox + xdir[dirs[i]];
ny = oy + ydir[dirs[i]];
if (goodpos(nx, ny, worm, 0)) /* includes an isok() check */
break;
}
- if (i < 8)
+ if (i < N_DIRS)
#endif
{
place_worm_seg(worm, nx, ny);
g.bhitpos.x = u.ux;
g.bhitpos.y = u.uy;
boom = counterclockwise ? S_boomleft : S_boomright;
- for (i = 0; i < 8; i++)
- if (xdir[i] == dx && ydir[i] == dy)
- break;
+ i = xytod(dx, dy);
tmp_at(DISP_FLASH, cmap_to_glyph(boom));
for (ct = 0; ct < 10; ct++) {
- i = (i + 8) % 8; /* 0..7 (8 -> 0, -1 -> 7) */
+ i = DIR_CLAMP(i);
boom = (S_boomleft + S_boomright - boom); /* toggle */
tmp_at(DISP_CHANGE, cmap_to_glyph(boom)); /* change glyph */
dx = xdir[i];
/* ct==0, initial position, we want next delta to be same;
ct==5, opposite position, repeat delta undoes first one */
if (ct % 5 != 0)
- i += (counterclockwise ? -1 : 1);
+ i = counterclockwise ? DIR_LEFT(i) : DIR_RIGHT(i);
}
tmp_at(DISP_END, 0); /* do not leave last symbol */
return (struct monst *) 0;