Fix some issues found with fuzz testing

Mostly to do with relocating monsters when the level is already full,
and unsticking a monster if it gets relocated.
This commit is contained in:
Pasi Kallinen
2016-12-07 17:53:08 +02:00
parent daff7653f8
commit b8d8556eff
5 changed files with 34 additions and 10 deletions
+1
View File
@@ -1351,6 +1351,7 @@ E void FDECL(unstuck, (struct monst *));
E void FDECL(killed, (struct monst *)); E void FDECL(killed, (struct monst *));
E void FDECL(xkilled, (struct monst *, int)); E void FDECL(xkilled, (struct monst *, int));
E void FDECL(mon_to_stone, (struct monst *)); E void FDECL(mon_to_stone, (struct monst *));
E void FDECL(m_into_limbo, (struct monst *));
E void FDECL(mnexto, (struct monst *)); E void FDECL(mnexto, (struct monst *));
E void FDECL(maybe_mnexto, (struct monst *)); E void FDECL(maybe_mnexto, (struct monst *));
E boolean FDECL(mnearto, (struct monst *, XCHAR_P, XCHAR_P, BOOLEAN_P)); E boolean FDECL(mnearto, (struct monst *, XCHAR_P, XCHAR_P, BOOLEAN_P));
+5 -3
View File
@@ -430,9 +430,10 @@ boolean with_you;
mtmp->mx = 0; /*(already is 0)*/ mtmp->mx = 0; /*(already is 0)*/
mtmp->my = xyflags; mtmp->my = xyflags;
if (xlocale) if (xlocale) {
(void) mnearto(mtmp, xlocale, ylocale, FALSE); if (!mnearto(mtmp, xlocale, ylocale, FALSE))
else { goto fail_mon_placement;
} else {
if (!rloc(mtmp, TRUE)) { if (!rloc(mtmp, TRUE)) {
/* /*
* Failed to place migrating monster, * Failed to place migrating monster,
@@ -440,6 +441,7 @@ boolean with_you;
* Dump the monster's cargo and leave the monster dead. * Dump the monster's cargo and leave the monster dead.
*/ */
struct obj *obj; struct obj *obj;
fail_mon_placement:
while ((obj = mtmp->minvent) != 0) { while ((obj = mtmp->minvent) != 0) {
obj_extract_self(obj); obj_extract_self(obj);
obj_no_longer_held(obj); obj_no_longer_held(obj);
+1
View File
@@ -744,6 +744,7 @@ register struct attack *mattk;
if (cansee(dx, dy)) if (cansee(dx, dy))
pline("%s is regurgitated!", Monnam(mdef)); pline("%s is regurgitated!", Monnam(mdef));
remove_monster(dx,dy);
place_monster(magr, ax, ay); place_monster(magr, ax, ay);
place_monster(mdef, dx, dy); place_monster(mdef, dx, dy);
newsym(ax, ay); newsym(ax, ay);
+21 -5
View File
@@ -2029,6 +2029,8 @@ struct monst *mdef;
/* hero is thrown from his steed when it disappears */ /* hero is thrown from his steed when it disappears */
if (mdef == u.usteed) if (mdef == u.usteed)
dismount_steed(DISMOUNT_GENERIC); dismount_steed(DISMOUNT_GENERIC);
/* stuck to you? release */
unstuck(mdef);
/* drop special items like the Amulet so that a dismissed Kop or nurse /* drop special items like the Amulet so that a dismissed Kop or nurse
can't remove them from the game */ can't remove them from the game */
mdrop_special_objs(mdef); mdrop_special_objs(mdef);
@@ -2449,6 +2451,16 @@ struct monst *mtmp;
return TRUE; return TRUE;
} }
/* drop monster into "limbo" - that is, migrate to the current level */
void
m_into_limbo(mtmp)
struct monst *mtmp;
{
unstuck(mtmp);
mdrop_special_objs(mtmp);
migrate_to_level(mtmp, ledger_no(&u.uz), MIGR_APPROX_XY, NULL);
}
/* make monster mtmp next to you (if possible); /* make monster mtmp next to you (if possible);
might place monst on far side of a wall or boulder */ might place monst on far side of a wall or boulder */
void void
@@ -2465,7 +2477,11 @@ struct monst *mtmp;
return; return;
} }
if (!enexto(&mm, u.ux, u.uy, mtmp->data)) if (!enexto(&mm, u.ux, u.uy, mtmp->data)) {
m_into_limbo(mtmp);
return;
}
if (!isok(mm.x, mm.y))
return; return;
rloc_to(mtmp, mm.x, mm.y); rloc_to(mtmp, mm.x, mm.y);
if (!in_mklev && (mtmp->mstrategy & STRAT_APPEARMSG)) { if (!in_mklev && (mtmp->mstrategy & STRAT_APPEARMSG)) {
@@ -2534,6 +2550,8 @@ boolean move_other; /* make sure mtmp gets to x, y! so move m_at(x, y) */
*/ */
if (!enexto(&mm, newx, newy, mtmp->data)) if (!enexto(&mm, newx, newy, mtmp->data))
return FALSE; return FALSE;
if (!isok(mm.x,mm.y))
return FALSE;
newx = mm.x; newx = mm.x;
newy = mm.y; newy = mm.y;
} }
@@ -2545,12 +2563,10 @@ boolean move_other; /* make sure mtmp gets to x, y! so move m_at(x, y) */
othermon->mx = othermon->my = 0; othermon->mx = othermon->my = 0;
(void) mnearto(othermon, x, y, FALSE); (void) mnearto(othermon, x, y, FALSE);
if (othermon->mx == 0 && othermon->my == 0) { if (othermon->mx == 0 && othermon->my == 0) {
/* reloc failed, dump monster into "limbo" /* reloc failed */
(aka migrate to current level) */
othermon->mx = oldx; othermon->mx = oldx;
othermon->my = oldy; othermon->my = oldy;
mdrop_special_objs(othermon); m_into_limbo(othermon);
migrate_to_level(othermon, ledger_no(&u.uz), MIGR_APPROX_XY, NULL);
} }
} }
+6 -2
View File
@@ -380,7 +380,10 @@ register struct monst *mtmp;
if (!rn2(3 + mtmp->mhp / 10)) if (!rn2(3 + mtmp->mhp / 10))
(void) rloc(mtmp, TRUE); (void) rloc(mtmp, TRUE);
} else if (sx && (mtmp->mx != sx || mtmp->my != sy)) { } else if (sx && (mtmp->mx != sx || mtmp->my != sy)) {
(void) mnearto(mtmp, sx, sy, TRUE); if (!mnearto(mtmp, sx, sy, TRUE)) {
m_into_limbo(mtmp);
return 0;
}
} }
/* if you're not around, cast healing spells */ /* if you're not around, cast healing spells */
if (distu(mtmp->mx, mtmp->my) > (BOLT_LIM * BOLT_LIM)) if (distu(mtmp->mx, mtmp->my) > (BOLT_LIM * BOLT_LIM))
@@ -433,7 +436,8 @@ register struct monst *mtmp;
return 0; return 0;
} }
} else { /* a monster has it - 'port beside it. */ } else { /* a monster has it - 'port beside it. */
(void) mnearto(mtmp, tx, ty, FALSE); if (!mnearto(mtmp, tx, ty, FALSE))
m_into_limbo(mtmp);
return 0; return 0;
} }
} }