Fix shopkeeper Kop summons causing segfault

... if it happened on a level with no downstairs, such as the tourist quest.
This commit is contained in:
Pasi Kallinen
2022-01-11 22:55:43 +02:00
parent a8e9e1b488
commit 1f2d16082e
3 changed files with 13 additions and 16 deletions
+1
View File
@@ -3112,6 +3112,7 @@ extern void nethack_enter_windows(void);
extern void amulet(void); extern void amulet(void);
extern int mon_has_amulet(struct monst *); extern int mon_has_amulet(struct monst *);
extern int mon_has_special(struct monst *); extern int mon_has_special(struct monst *);
extern void choose_stairs(xchar *, xchar *, boolean);
extern int tactics(struct monst *); extern int tactics(struct monst *);
extern boolean has_aggravatables(struct monst *); extern boolean has_aggravatables(struct monst *);
extern void aggravate(void); extern void aggravate(void);
+7 -10
View File
@@ -344,14 +344,9 @@ call_kops(register struct monst* shkp, register boolean nearshop)
{ {
coord mm; coord mm;
stairway *stway = g.stairs; xchar sx = 0, sy = 0;
while (stway) { choose_stairs(&sx, &sy, TRUE);
if (!stway->isladder && !stway->up
&& stway->tolev.dnum == u.uz.dnum)
break;
stway = stway->next;
}
if (nearshop) { if (nearshop) {
/* Create swarm around you, if you merely "stepped out" */ /* Create swarm around you, if you merely "stepped out" */
@@ -365,9 +360,11 @@ call_kops(register struct monst* shkp, register boolean nearshop)
if (flags.verbose) if (flags.verbose)
pline_The("Keystone Kops are after you!"); pline_The("Keystone Kops are after you!");
/* Create swarm near down staircase (hinders return to level) */ /* Create swarm near down staircase (hinders return to level) */
mm.x = stway->sx; if (isok(sx, sy)) {
mm.y = stway->sy; mm.x = sx;
makekops(&mm); mm.y = sy;
makekops(&mm);
}
/* Create swarm near shopkeeper (hinders return to shop) */ /* Create swarm near shopkeeper (hinders return to shop) */
mm.x = shkp->mx; mm.x = shkp->mx;
mm.y = shkp->my; mm.y = shkp->my;
+5 -6
View File
@@ -17,7 +17,6 @@ static struct obj *on_ground(short);
static boolean you_have(int); static boolean you_have(int);
static unsigned long target_on(int, struct monst *); static unsigned long target_on(int, struct monst *);
static unsigned long strategy(struct monst *); static unsigned long strategy(struct monst *);
static void choose_stairs(xchar *, xchar *);
/* adding more neutral creatures will tend to reduce the number of monsters /* adding more neutral creatures will tend to reduce the number of monsters
summoned by nasty(); adding more lawful creatures will reduce the number summoned by nasty(); adding more lawful creatures will reduce the number
@@ -311,12 +310,12 @@ strategy(struct monst *mtmp)
return dstrat; return dstrat;
} }
static void void
choose_stairs(xchar *sx, xchar *sy) choose_stairs(xchar *sx, xchar *sy, boolean dir)
{ {
xchar x = 0, y = 0; xchar x = 0, y = 0;
stairway *stway = g.stairs; stairway *stway = g.stairs;
boolean stdir = !builds_up(&u.uz); boolean stdir = dir && !builds_up(&u.uz);
if ((stway = stairway_find_type_dir(FALSE, stdir)) != 0) { if ((stway = stairway_find_type_dir(FALSE, stdir)) != 0) {
x = stway->sx; x = stway->sx;
@@ -335,7 +334,7 @@ choose_stairs(xchar *sx, xchar *sy)
} }
} }
if (x && y) { if (isok(x, y)) {
*sx = x; *sx = x;
*sy = y; *sy = y;
} }
@@ -356,7 +355,7 @@ tactics(struct monst *mtmp)
case STRAT_HEAL: /* hide and recover */ case STRAT_HEAL: /* hide and recover */
mx = mtmp->mx, my = mtmp->my; mx = mtmp->mx, my = mtmp->my;
/* if wounded, hole up on or near the stairs (to block them) */ /* if wounded, hole up on or near the stairs (to block them) */
choose_stairs(&sx, &sy); choose_stairs(&sx, &sy, FALSE);
mtmp->mavenge = 1; /* covetous monsters attack while fleeing */ mtmp->mavenge = 1; /* covetous monsters attack while fleeing */
if (In_W_tower(mx, my, &u.uz) if (In_W_tower(mx, my, &u.uz)
|| (mtmp->iswiz && !sx && !mon_has_amulet(mtmp))) { || (mtmp->iswiz && !sx && !mon_has_amulet(mtmp))) {