diff --git a/src/shknam.c b/src/shknam.c index f675d2416..45c9aca39 100644 --- a/src/shknam.c +++ b/src/shknam.c @@ -13,6 +13,7 @@ static int shkveg(void); static void mkveggy_at(int, int); static void mkshobj_at(const struct shclass *, int, int, boolean); static void nameshk(struct monst *, const char *const *); +static int good_shopdoor(struct mkroom *, coordxy *, coordxy *); static int shkinit(const struct shclass *, struct mkroom *); #define VEGETARIAN_CLASS (MAXOCLASSES + 1) @@ -569,47 +570,66 @@ free_eshk(struct monst* mtmp) mtmp->isshk = 0; } +/* find a door in room sroom which is good for shop entrance. + returns -1 if no good door found, or the gd.doors index + and the door coordinates in sx, sy */ +static int +good_shopdoor(struct mkroom *sroom, coordxy *sx, coordxy *sy) +{ + int i; + + for (i = 0; i < sroom->doorct; i++) { + int di = sroom->fdoor + i; + + *sx = gd.doors[di].x; + *sy = gd.doors[di].y; + + /* check that the shopkeeper placement is sane */ + if (sroom->irregular) { + int rmno = (int) ((sroom - gr.rooms) + ROOMOFFSET); + + if (isok(*sx - 1, *sy) && !levl[*sx - 1][*sy].edge + && (int) levl[*sx - 1][*sy].roomno == rmno) + (*sx)--; + else if (isok(*sx + 1, *sy) && !levl[*sx + 1][*sy].edge + && (int) levl[*sx + 1][*sy].roomno == rmno) + (*sx)++; + else if (isok(*sx, *sy - 1) && !levl[*sx][*sy - 1].edge + && (int) levl[*sx][*sy - 1].roomno == rmno) + (*sy)--; + else if (isok(*sx, *sy + 1) && !levl[*sx][*sy + 1].edge + && (int) levl[*sx][*sy + 1].roomno == rmno) + (*sy)++; + else + continue; + } else if (*sx == sroom->lx - 1) { + (*sx)++; + } else if (*sx == sroom->hx + 1) { + (*sx)--; + } else if (*sy == sroom->ly - 1) { + (*sy)++; + } else if (*sy == sroom->hy + 1) { + (*sy)--; + } else { + continue; + } + return di; + } + return -1; +} + /* create a new shopkeeper in the given room */ static int shkinit(const struct shclass* shp, struct mkroom* sroom) { - register int sh, sx, sy; + int sh; + coordxy sx, sy; struct monst *shk; struct eshk *eshkp; /* place the shopkeeper in the given room */ - sh = sroom->fdoor; - sx = gd.doors[sh].x; - sy = gd.doors[sh].y; - - /* check that the shopkeeper placement is sane */ - if (sroom->irregular) { - int rmno = (int) ((sroom - gr.rooms) + ROOMOFFSET); - - if (isok(sx - 1, sy) && !levl[sx - 1][sy].edge - && (int) levl[sx - 1][sy].roomno == rmno) - sx--; - else if (isok(sx + 1, sy) && !levl[sx + 1][sy].edge - && (int) levl[sx + 1][sy].roomno == rmno) - sx++; - else if (isok(sx, sy - 1) && !levl[sx][sy - 1].edge - && (int) levl[sx][sy - 1].roomno == rmno) - sy--; - else if (isok(sx, sy + 1) && !levl[sx][sy + 1].edge - && (int) levl[sx][sy + 1].roomno == rmno) - sy++; - else - goto shk_failed; - } else if (sx == sroom->lx - 1) { - sx++; - } else if (sx == sroom->hx + 1) { - sx--; - } else if (sy == sroom->ly - 1) { - sy++; - } else if (sy == sroom->hy + 1) { - sy--; - } else { - shk_failed: + sh = good_shopdoor(sroom, &sx, &sy); + if (sh < 0) { #ifdef DEBUG /* Said to happen sometimes, but I have never seen it. */ /* Supposedly fixed by fdoor change in mklev.c */