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));
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,
* 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);
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);
/* 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);
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
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)) {
*/
if (!enexto(&mm, newx, newy, mtmp->data))
return FALSE;
+ if (!isok(mm.x,mm.y))
+ return FALSE;
newx = mm.x;
newy = mm.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);
}
}
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))
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;
}
}