-/* NetHack 3.6 do_name.c $NHDT-Date: 1452064740 2016/01/06 07:19:00 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.84 $ */
+/* NetHack 3.6 do_name.c $NHDT-Date: 1452465671 2016/01/10 22:41:11 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.88 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
int *cnt_p;
boolean do_mons;
{
- int x, y, pass, glyph, idx;
- boolean wantedloc;
+ int x, y, pass, glyph, idx,
+ tail = (do_mons ? monnum_to_glyph(PM_LONG_WORM_TAIL) : 0),
+ boulder = (!do_mons ? objnum_to_glyph(BOULDER) : 0),
+ rock = (!do_mons ? objnum_to_glyph(ROCK) : 0);
+ /*
+ * We always include the hero's location even if there is no monster
+ * (invisible hero without see invisible) or object (usual case)
+ * displayed there. That way, the count will always be at least 1,
+ * and player has a visual indicator (cursor returns to hero's spot)
+ * highlighting when successive 'm's or 'o's have cycled all the way
+ * through all monsters or objects.
+ *
+ * Hero's spot will always sort to array[0] because it will always
+ * be the shortest distance (namely, 0 units) away from <u.ux,u.uy>.
+ */
*cnt_p = idx = 0;
for (pass = 0; pass < 2; pass++) {
- if (pass) {
- /* *cnt_p + 1: always allocate a non-zero amount */
- *arr_p = (coord *) alloc(sizeof (coord) * (*cnt_p + 1));
- if (!*cnt_p) {
- /* needed for caller's mon[0].x,.y==u.ux,.uy check */
- (*arr_p)[0].x = (*arr_p)[0].y = 0;
- break;
- }
- }
for (x = 1; x < COLNO; x++)
for (y = 0; y < ROWNO; y++) {
+ /* TODO: if glyph is a pile glyph, convert to ordinary one
+ * in order to keep tail/boulder/rock check simple.
+ */
glyph = glyph_at(x, y);
/* unlike '/M', this skips monsters revealed by
- * warning glyphs and remembered invisible ones;
- * TODO: skip worm tails, boulders and rocks
- */
- wantedloc = (do_mons && glyph_is_monster(glyph)
- || !do_mons && glyph_is_object(glyph));
- if (!wantedloc) continue;
- if (!pass) {
- ++*cnt_p;
- } else {
- (*arr_p)[idx].x = x;
- (*arr_p)[idx].y = y;
- ++idx;
+ warning glyphs and remembered invisible ones */
+ if ((x == u.ux && y == u.uy)
+ || (do_mons ? (glyph_is_monster(glyph) && glyph != tail)
+ : (glyph_is_object(glyph)
+ && glyph != boulder && glyph != rock))) {
+ if (!pass) {
+ ++*cnt_p;
+ } else {
+ (*arr_p)[idx].x = x;
+ (*arr_p)[idx].y = y;
+ ++idx;
+ }
}
}
+
+ if (!pass) /* end of first pass */
+ *arr_p = (coord *) alloc(sizeof (coord) * *cnt_p);
+ else /* end of second pass */
+ qsort(*arr_p, *cnt_p, sizeof (coord), cmp_coord_distu);
} /* pass */
- if (*cnt_p)
- qsort(*arr_p, *cnt_p, sizeof (coord), cmp_coord_distu);
}
int
show_goal_msg = TRUE;
msg_given = TRUE;
goto nxtc;
- } else if (c == '@') {
+ } else if (c == '@') { /* return to hero's spot */
+ /* reset 'm','M' and 'o','O'; otherwise, there's no way for player
+ to achieve that except by manually cycling through all spots */
+ monidx = objidx = 0;
cx = u.ux;
cy = u.uy;
goto nxtc;
- } else if (c == 'm' || c == 'M') {
+ } else if (c == 'm' || c == 'M') { /* nearest or farthest monster */
if (!monarr) {
gather_locs(&monarr, &moncount, TRUE);
- /* when hero is first element (always, unless unseen),
- we want first increment to reach 1 (nearest aside
- from hero) or first decrement to reach moncount-1
- (farthest); if hero is not first element, we want
- first increment to end up with 0 (nearest monster),
- first decrement should still choose moncount-1 */
- monidx = (monarr[0].x == u.ux && monarr[0].y == u.uy) ? 0
- : (c == 'm') ? -1 : 0;
+ monidx = 0; /* monarr[0] is hero's spot */
}
- if (moncount) {
- if (c == 'm') {
- monidx = (monidx + 1) % moncount;
- } else {
- if (--monidx < 0)
- monidx = moncount - 1;
- }
- cx = monarr[monidx].x;
- cy = monarr[monidx].y;
- goto nxtc;
+ if (c == 'm') {
+ monidx = (monidx + 1) % moncount;
+ } else {
+ if (--monidx < 0)
+ monidx = moncount - 1;
}
- } else if (c == 'o' || c == 'O') {
+ cx = monarr[monidx].x;
+ cy = monarr[monidx].y;
+ goto nxtc;
+ } else if (c == 'o' || c == 'O') { /* nearest or farthest object */
if (!objarr) {
gather_locs(&objarr, &objcount, FALSE);
- /* ready for first increment to change to zero
- or first decrement to change to objcount-1 */
- objidx = (c == 'o') ? -1 : 0;
+ objidx = 0; /* objarr[0] is hero's spot */
}
- if (objcount) {
- if (c == 'o') {
- objidx = (objidx + 1) % objcount;
- } else {
- if (--objidx < 0)
- objidx = objcount - 1;
- }
- cx = objarr[objidx].x;
- cy = objarr[objidx].y;
- goto nxtc;
+ if (c == 'o') {
+ objidx = (objidx + 1) % objcount;
+ } else {
+ if (--objidx < 0)
+ objidx = objcount - 1;
}
+ cx = objarr[objidx].x;
+ cy = objarr[objidx].y;
+ goto nxtc;
} else {
if (!index(quitchars, c)) {
char matching[MAXPCHARS];