From b8d8556eff8eb133c56f27421a905a30d9a7e975 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Wed, 7 Dec 2016 17:53:03 +0200 Subject: [PATCH] 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. --- include/extern.h | 1 + src/dog.c | 8 +++++--- src/mhitm.c | 1 + src/mon.c | 26 +++++++++++++++++++++----- src/wizard.c | 8 ++++++-- 5 files changed, 34 insertions(+), 10 deletions(-) diff --git a/include/extern.h b/include/extern.h index 300af5e0..3ab3e6ce 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1351,6 +1351,7 @@ E void FDECL(unstuck, (struct monst *)); E void FDECL(killed, (struct monst *)); E void FDECL(xkilled, (struct monst *, int)); 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(maybe_mnexto, (struct monst *)); E boolean FDECL(mnearto, (struct monst *, XCHAR_P, XCHAR_P, BOOLEAN_P)); diff --git a/src/dog.c b/src/dog.c index fba99840..0b9d2ae9 100644 --- a/src/dog.c +++ b/src/dog.c @@ -430,9 +430,10 @@ boolean with_you; mtmp->mx = 0; /*(already is 0)*/ mtmp->my = xyflags; - if (xlocale) - (void) mnearto(mtmp, xlocale, ylocale, FALSE); - else { + if (xlocale) { + if (!mnearto(mtmp, xlocale, ylocale, FALSE)) + goto fail_mon_placement; + } else { if (!rloc(mtmp, TRUE)) { /* * Failed to place migrating monster, @@ -440,6 +441,7 @@ boolean with_you; * Dump the monster's cargo and leave the monster dead. */ struct obj *obj; +fail_mon_placement: while ((obj = mtmp->minvent) != 0) { obj_extract_self(obj); obj_no_longer_held(obj); diff --git a/src/mhitm.c b/src/mhitm.c index 2b67b47b..39407c3a 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -744,6 +744,7 @@ register struct attack *mattk; if (cansee(dx, dy)) pline("%s is regurgitated!", Monnam(mdef)); + remove_monster(dx,dy); place_monster(magr, ax, ay); place_monster(mdef, dx, dy); newsym(ax, ay); diff --git a/src/mon.c b/src/mon.c index f387655e..23ebcdb4 100644 --- a/src/mon.c +++ b/src/mon.c @@ -2029,6 +2029,8 @@ struct monst *mdef; /* hero is thrown from his steed when it disappears */ if (mdef == u.usteed) dismount_steed(DISMOUNT_GENERIC); + /* stuck to you? release */ + unstuck(mdef); /* drop special items like the Amulet so that a dismissed Kop or nurse can't remove them from the game */ mdrop_special_objs(mdef); @@ -2449,6 +2451,16 @@ struct monst *mtmp; 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); might place monst on far side of a wall or boulder */ void @@ -2465,7 +2477,11 @@ struct monst *mtmp; 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; rloc_to(mtmp, mm.x, mm.y); 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)) return FALSE; + if (!isok(mm.x,mm.y)) + return FALSE; newx = mm.x; 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; (void) mnearto(othermon, x, y, FALSE); if (othermon->mx == 0 && othermon->my == 0) { - /* reloc failed, dump monster into "limbo" - (aka migrate to current level) */ + /* reloc failed */ othermon->mx = oldx; othermon->my = oldy; - mdrop_special_objs(othermon); - migrate_to_level(othermon, ledger_no(&u.uz), MIGR_APPROX_XY, NULL); + m_into_limbo(othermon); } } diff --git a/src/wizard.c b/src/wizard.c index 6ab8e57b..3f58433c 100644 --- a/src/wizard.c +++ b/src/wizard.c @@ -380,7 +380,10 @@ register struct monst *mtmp; if (!rn2(3 + mtmp->mhp / 10)) (void) rloc(mtmp, TRUE); } 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 (distu(mtmp->mx, mtmp->my) > (BOLT_LIM * BOLT_LIM)) @@ -433,7 +436,8 @@ register struct monst *mtmp; return 0; } } 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; } } -- 2.11.4.GIT