]> granicus.if.org Git - nethack/commitdiff
buglist - full level triggers impossible() from migrating mons
authornethack.allison <nethack.allison>
Sat, 13 Sep 2003 05:30:43 +0000 (05:30 +0000)
committernethack.allison <nethack.allison>
Sat, 13 Sep 2003 05:30:43 +0000 (05:30 +0000)
<email deleted> wrote:
> If more monsters fall through a trap door than can fit on the
> level below, when you go down the stairs, you get the following
> message:
>  "Program in disorder - perhaps you'd better #quit.
>  rloc(): couldn't relocate monster"
> This message seems to appear once for every monster-too-many that
> fell through the hole. I originally found this while
> intentionally completely filling a level with black puddings
> (there was a trap door I didn't know about). I also confirmed it
> in a wiz-mode test using gremlins and water.

[confirmed: moveloop -> deferred_goto -> goto_level ->
 losedogs -> mon_arrive -> rloc -> impossible]

This patch:
- causes rloc() to return TRUE if successful,
  or FALSE if it wasn't.
- adds code to mon_arrive() in dog.c to deal with
  the failed rloc()
- allows the x,y parameters to mkcorpstat() to
  be 0,0 in order to trigger random placement of the
  corpse on the level
- if you define DEBUG_MIGRATING_MONS when you build cmd.c
  then you'll have a debug-mode command #migratemons to
  store the number of random monsters that you specify
  on the migrating monsters chain.

24 files changed:
doc/fixes34.3
include/extern.h
src/apply.c
src/cmd.c
src/dig.c
src/do.c
src/dog.c
src/dothrow.c
src/mhitm.c
src/mhitu.c
src/minion.c
src/mkmaze.c
src/mkobj.c
src/mon.c
src/monmove.c
src/mplayer.c
src/muse.c
src/priest.c
src/shknam.c
src/steal.c
src/steed.c
src/teleport.c
src/vault.c
src/wizard.c

index c61444444f0ffa15aa9705330ca76a696742d6c0..8c4b0ce8ade1ca0a811e0da93d5fe17eab01c417 100644 (file)
@@ -19,6 +19,8 @@ Master Kaen's death message was not appropriate
 missing fountain tag in minend-3
 do not pacify shopkeeper when the hero enters a shop if that hero previously
        angered the shopkeeper without ever visibly entering the shop
+attempting to place migrating monsters onto a monster-saturated level no
+       longer triggers impossible()
 
 
 Platform- and/or Interface-Specific Fixes
index e77a2aa4aecd21e231a62ccc98ee53db20c8fee4..7b518d07ad0de3b4f1715b4dca71dfdf811622c2 100644 (file)
@@ -1940,7 +1940,7 @@ E void FDECL(domagicportal, (struct trap *));
 E void FDECL(tele_trap, (struct trap *));
 E void FDECL(level_tele_trap, (struct trap *));
 E void FDECL(rloc_to, (struct monst *,int,int));
-E void FDECL(rloc, (struct monst *));
+E boolean FDECL(rloc, (struct monst *, BOOLEAN_P));
 E boolean FDECL(tele_restrict, (struct monst *));
 E void FDECL(mtele_trap, (struct monst *, struct trap *,int));
 E int FDECL(mlevel_tele_trap, (struct monst *, struct trap *,BOOLEAN_P,int));
index 6c25551c599cdade1889730498194a27f1c7cb18..f3f9d881c3e91ec60c79cd742fca012828b2022a 100644 (file)
@@ -711,7 +711,7 @@ struct obj *obj;
                setnotworn(obj); /* in case mirror was wielded */
                freeinv(obj);
                (void) mpickobj(mtmp,obj);
-               if (!tele_restrict(mtmp)) rloc(mtmp);
+               if (!tele_restrict(mtmp)) (void) rloc(mtmp, FALSE);
        } else if (!is_unicorn(mtmp->data) && !humanoid(mtmp->data) &&
                        (!mtmp->minvis || perceives(mtmp->data)) && rn2(5)) {
                if (vis)
index 8c532b4cee4be48fa7f6f57c73db34c1f2846ff8..522a2c5b89ae3db0d391c75209a5c1915921f099 100644 (file)
--- a/src/cmd.c
+++ b/src/cmd.c
@@ -126,6 +126,9 @@ STATIC_PTR int NDECL(wiz_show_wmodes);
 #if defined(__BORLANDC__) && !defined(_WIN32)
 extern void FDECL(show_borlandc_stats, (winid));
 #endif
+#ifdef DEBUG_MIGRATING_MONS
+STATIC_PTR int NDECL(wiz_migrate_mons);
+#endif
 STATIC_DCL void FDECL(count_obj, (struct obj *, long *, long *, BOOLEAN_P, BOOLEAN_P));
 STATIC_DCL void FDECL(obj_chain, (winid, const char *, struct obj *, long *, long *));
 STATIC_DCL void FDECL(mon_invent_chain, (winid, const char *, struct monst *, long *, long *));
@@ -1492,6 +1495,9 @@ struct ext_func_tab extcmdlist[] = {
         */
        {(char *)0, (char *)0, donull, TRUE},
        {(char *)0, (char *)0, donull, TRUE},
+#ifdef DEBUG_MIGRATING_MONS
+       {(char *)0, (char *)0, donull, TRUE},
+#endif
        {(char *)0, (char *)0, donull, TRUE},
        {(char *)0, (char *)0, donull, TRUE},
        {(char *)0, (char *)0, donull, TRUE},
@@ -1514,6 +1520,9 @@ struct ext_func_tab extcmdlist[] = {
 static const struct ext_func_tab debug_extcmdlist[] = {
        {"levelchange", "change experience level", wiz_level_change, TRUE},
        {"lightsources", "show mobile light sources", wiz_light_sources, TRUE},
+#ifdef DEBUG_MIGRATING_MONS
+       {"migratemons", "migrate n random monsters", wiz_migrate_mons, TRUE},
+#endif
        {"monpolycontrol", "control monster polymorphs", wiz_mon_polycontrol, TRUE},
        {"panic", "test panic routine (fatal to game)", wiz_panic, TRUE},
        {"polyself", "polymorph self", wiz_polyself, TRUE},
@@ -1742,6 +1751,35 @@ sanity_check()
        timer_sanity_check();
 }
 
+#ifdef DEBUG_MIGRATING_MONS
+static int
+wiz_migrate_mons()
+{
+       int mcount = 0;
+       char inbuf[BUFSZ];
+       struct permonst *ptr;
+       struct monst *mtmp;
+       d_level tolevel;
+       getlin("How many random monsters to migrate? [0]", inbuf);
+       if (*inbuf == '\033') return 0;
+       mcount = atoi(inbuf);
+       if (mcount < 0 || mcount > (COLNO * ROWNO) || Is_botlevel(&u.uz))
+               return 0;
+       while (mcount > 0) {
+               if (Is_stronghold(&u.uz))
+                   assign_level(&tolevel, &valley_level);
+               else
+                   get_level(&tolevel, depth(&u.uz) + 1);
+               ptr = rndmonst();
+               mtmp = makemon(ptr, 0, 0, NO_MM_FLAGS);
+               if (mtmp) migrate_to_level(mtmp, ledger_no(&tolevel),
+                               MIGR_RANDOM, (coord *)0);
+               mcount--;
+       }
+       return 0;
+}
+#endif
+
 #endif /* WIZARD */
 
 #define unctrl(c)      ((c) <= C('z') ? (0x60 | (c)) : (c))
index 09365c5fc2f9a401fcd537855b9800eb9846d247..dff8a766d56604ca4053ebd92091fb1f4aeefdf9 100644 (file)
--- a/src/dig.c
+++ b/src/dig.c
@@ -59,7 +59,7 @@ mkcavepos(x, y, dist, waslit, rockit)
        if(IS_ROCK(lev->typ)) return;
        if(t_at(x, y)) return; /* don't cover the portal */
        if ((mtmp = m_at(x, y)) != 0)   /* make sure crucial monsters survive */
-           if(!passes_walls(mtmp->data)) rloc(mtmp);
+           if(!passes_walls(mtmp->data)) (void) rloc(mtmp, FALSE);
     } else if(lev->typ == ROOM) return;
 
     unblock_point(x,y);        /* make sure vision knows this location is open */
index 50e3989be928411a23352856489c834a4153fefc..dd9fb971c462323cb283daa10766ac467e7f1bd8 100644 (file)
--- a/src/do.c
+++ b/src/do.c
@@ -1212,7 +1212,7 @@ boolean at_stairs, falling, portal;
 
            if ((mtmp = m_at(u.ux, u.uy)) != 0) {
                impossible("mnexto failed (do.c)?");
-               rloc(mtmp);
+               (void) rloc(mtmp, FALSE);
            }
        }
 
index 86ca0b58bfa212f280bb0ac7286187216805ee9e..536a19a38e2fa6799c204d2206a3f8cc438458db 100644 (file)
--- a/src/dog.c
+++ b/src/dog.c
@@ -356,8 +356,41 @@ boolean with_you;
        mtmp->my = xyflags;
        if (xlocale)
            (void) mnearto(mtmp, xlocale, ylocale, FALSE);
-       else
-           rloc(mtmp);
+       else {
+           if (!rloc(mtmp,TRUE)) {
+               /*
+                * Failed to place migrating monster,
+                * probably because the level is full.
+                * Dump the monster's cargo and leave the monster dead.
+                */
+               struct obj *obj, *corpse;
+               while ((obj = mtmp->minvent) != 0) {
+                   obj_extract_self(obj);
+                   obj_no_longer_held(obj);
+                   if (obj->owornmask & W_WEP)
+                       setmnotwielded(mtmp,obj);
+                   obj->owornmask = 0L;
+                   if (xlocale && ylocale)
+                           place_object(obj, xlocale, ylocale);
+                   else {
+                       rloco(obj);
+                       get_obj_location(obj, &xlocale, &ylocale, 0);
+                   }
+               }
+               corpse = mkcorpstat(CORPSE, (struct monst *)0, mtmp->data,
+                               xlocale, ylocale, FALSE);
+#ifndef GOLDOBJ
+               if (mtmp->mgold) {
+                   if (xlocale == 0 && ylocale == 0 && corpse) {
+                       (void) get_obj_location(corpse, &xlocale, &ylocale, 0);
+                       (void) mkgold(mtmp->mgold, xlocale, ylocale);
+                   }
+                   mtmp->mgold = 0L;
+               }
+#endif
+               mongone(mtmp);
+           }
+       }
 }
 
 /* heal monster for time spent elsewhere */
index e43b590ed5e730f98a1140a26777d8a022e2b619..0900c9e1ae0484223fddcd93fe44e8cdb376d99e 100644 (file)
@@ -1470,7 +1470,7 @@ register struct obj *obj;
 
 nopick:
        if(!Blind) pline("%s", buf);
-       if (!tele_restrict(mon)) rloc(mon);
+       if (!tele_restrict(mon)) (void) rloc(mon, FALSE);
        return(ret);
 }
 
index 630e9faef38e13587b7258ebacb9624e710185e4..0a3e9ef100046bee46ef9e7b2c8ac0d5bef1fcf8 100644 (file)
@@ -839,7 +839,7 @@ mdamagem(magr, mdef, mattk)
                       we'll get "it" in the suddenly disappears message */
                    if (vis) Strcpy(mdef_Monnam, Monnam(mdef));
                    mdef->mstrategy &= ~STRAT_WAITFORU;
-                   rloc(mdef);
+                   (void) rloc(mdef, FALSE);
                    if (vis && !canspotmon(mdef)
 #ifdef STEED
                        && mdef != u.usteed
@@ -967,7 +967,7 @@ mdamagem(magr, mdef, mattk)
                    pline("%s steals some gold from %s.", buf, mon_nam(mdef));
                }
                if (!tele_restrict(magr)) {
-                   rloc(magr);
+                   (void) rloc(magr, FALSE);
                    if (vis && !canspotmon(magr))
                        pline("%s suddenly disappears!", buf);
                }
@@ -1034,7 +1034,7 @@ mdamagem(magr, mdef, mattk)
                                                        0 : MM_AGR_DIED));
                        if (magr->data->mlet == S_NYMPH &&
                            !tele_restrict(magr)) {
-                           rloc(magr);
+                           (void) rloc(magr, FALSE);
                            if (vis && !canspotmon(magr))
                                pline("%s suddenly disappears!", buf);
                        }
index 67810f9f7fb874d729f8a76241e1ecd3ac9776d3..4939a2169d8301a3589c1b279628b2b84c3279ee 100644 (file)
@@ -1232,7 +1232,7 @@ dopois:
                        pline("%s %s.", Monnam(mtmp), mtmp->minvent ?
                    "brags about the goods some dungeon explorer provided" :
                    "makes some remarks about how difficult theft is lately");
-                       if (!tele_restrict(mtmp)) rloc(mtmp);
+                       if (!tele_restrict(mtmp)) (void) rloc(mtmp, FALSE);
                        return 3;
                } else if (mtmp->mcan) {
                    if (!Blind) {
@@ -1242,7 +1242,7 @@ dopois:
                            flags.female ? "unaffected" : "uninterested");
                    }
                    if(rn2(3)) {
-                       if (!tele_restrict(mtmp)) rloc(mtmp);
+                       if (!tele_restrict(mtmp)) (void) rloc(mtmp, FALSE);
                        return 3;
                    }
                    break;
@@ -1255,7 +1255,7 @@ dopois:
                        break;
                  default:
                        if (!is_animal(mtmp->data) && !tele_restrict(mtmp))
-                           rloc(mtmp);
+                           (void) rloc(mtmp, FALSE);
                        if (is_animal(mtmp->data) && *buf) {
                            if (canseemon(mtmp))
                                pline("%s tries to %s away with %s.",
@@ -1359,7 +1359,7 @@ dopois:
                        mongone(mtmp);
                        return 2;
                    } else if (!rn2(33)) {
-                       if (!tele_restrict(mtmp)) rloc(mtmp);
+                       if (!tele_restrict(mtmp)) (void) rloc(mtmp, FALSE);
                        monflee(mtmp, d(3, 6), TRUE, FALSE);
                        return 3;
                    }
@@ -2219,7 +2219,7 @@ register struct monst *mon;
        if (uarm || uarmc) {
                verbalize("You're such a %s; I wish...",
                                flags.female ? "sweet lady" : "nice guy");
-               if (!tele_restrict(mon)) rloc(mon);
+               if (!tele_restrict(mon)) (void) rloc(mon, FALSE);
                return 1;
        }
        if (u.ualign.type == A_CHAOTIC)
@@ -2351,7 +2351,7 @@ register struct monst *mon;
 #endif
        }
        if (!rn2(25)) mon->mcan = 1; /* monster is worn out */
-       if (!tele_restrict(mon)) rloc(mon);
+       if (!tele_restrict(mon)) (void) rloc(mon, FALSE);
        return 1;
 }
 
index 50d23ce5deade06da5e952e9d9acc37aa467a8cf..af472567f4032feac71b234d720fa8321d40f612 100644 (file)
@@ -161,7 +161,7 @@ register struct monst *mtmp;
        if (youmonst.data->mlet == S_DEMON) {   /* Won't blackmail their own. */
            pline("%s says, \"Good hunting, %s.\"",
                  Amonnam(mtmp), flags.female ? "Sister" : "Brother");
-           if (!tele_restrict(mtmp)) rloc(mtmp);
+           if (!tele_restrict(mtmp)) (void) rloc(mtmp, FALSE);
            return(1);
        }
 #ifndef GOLDOBJ
index 3f81832f9c4525992c35985f217fb045ca44085a..12aaee69946d2f309b0e4483ba18134bb1677f7a 100644 (file)
@@ -308,7 +308,7 @@ d_level *lev;
        /* "something" means the player in this case */
        if(MON_AT(x, y)) {
            /* move the monster if no choice, or just try again */
-           if(oneshot) rloc(m_at(x,y));
+           if(oneshot) (void) rloc(m_at(x,y), FALSE);
            else return(FALSE);
        }
        u_on_newpos(x, y);
index b6fc2ec77cda71234c274ccaacf9acff85768f28..04b8a6f9cc1a1624487def51e61fdd8e437dc488 100644 (file)
@@ -894,7 +894,11 @@ boolean init;
 
        if (objtype != CORPSE && objtype != STATUE)
            impossible("making corpstat type %d", objtype);
-       otmp = mksobj_at(objtype, x, y, init, FALSE);
+       if (x == 0 && y == 0) {         /* special case - random placement */
+               otmp = mksobj(objtype, init, FALSE);
+               if (otmp) rloco(otmp);
+       } else
+               otmp = mksobj_at(objtype, x, y, init, FALSE);
        if (otmp) {
            if (mtmp) {
                struct obj *otmp2;
index a4dede164cf84610960708e0244162c7c01756f7..d0a1794fdc26b07afb027061f1fb04b4b13a6b65 100644 (file)
--- a/src/mon.c
+++ b/src/mon.c
@@ -428,7 +428,7 @@ register struct monst *mtmp;
            if (mtmp->mhp > 0) {
                (void) fire_damage(mtmp->minvent, FALSE, FALSE,
                                                mtmp->mx, mtmp->my);
-               rloc(mtmp);
+               (void) rloc(mtmp, FALSE);
                return 0;
            }
            return (1);
@@ -451,7 +451,7 @@ register struct monst *mtmp;
            }
            mondead(mtmp);
            if (mtmp->mhp > 0) {
-               rloc(mtmp);
+               (void) rloc(mtmp, FALSE);
                water_damage(mtmp->minvent, FALSE, FALSE);
                return 0;
            }
index 048acc70e5fbd0f1035b5537e398540f5f36c98d..e5b67184516264b634a2530713c33a767bce4d98 100644 (file)
@@ -327,7 +327,7 @@ register struct monst *mtmp;
        /* some monsters teleport */
        if (mtmp->mflee && !rn2(40) && can_teleport(mdat) && !mtmp->iswiz &&
            !level.flags.noteleport) {
-               rloc(mtmp);
+               (void) rloc(mtmp, FALSE);
                return(0);
        }
        if (mdat->msound == MS_SHRIEK && !um_dist(mtmp->mx, mtmp->my, 1))
@@ -370,7 +370,7 @@ register struct monst *mtmp;
 
                        if (is_demon(youmonst.data)) {
                          /* "Good hunting, brother" */
-                           if (!tele_restrict(mtmp)) rloc(mtmp);
+                           if (!tele_restrict(mtmp)) (void) rloc(mtmp, FALSE);
                        } else {
                            mtmp->minvis = mtmp->perminvis = 0;
                            /* Why?  For the same reason in real demon talk */
@@ -680,7 +680,7 @@ register int after;
        if(ptr == &mons[PM_TENGU] && !rn2(5) && !mtmp->mcan &&
           !tele_restrict(mtmp)) {
            if(mtmp->mhp < 7 || mtmp->mpeaceful || rn2(2))
-               rloc(mtmp);
+               (void) rloc(mtmp, FALSE);
            else
                mnexto(mtmp);
            mmoved = 1;
@@ -1014,7 +1014,7 @@ not_special:
            if (mtmp->wormno) worm_move(mtmp);
        } else {
            if(is_unicorn(ptr) && rn2(2) && !tele_restrict(mtmp)) {
-               rloc(mtmp);
+               (void) rloc(mtmp, FALSE);
                return(1);
            }
            if(mtmp->wormno) worm_nomove(mtmp);
index 255a54b9958e10007f7c43e1bd3e72f2a6efec58..8a0d08cc0a564dd23abeb010db47fb916c5261fc 100644 (file)
@@ -121,7 +121,7 @@ register boolean special;
                return((struct monst *)0);
 
        if(MON_AT(x, y))
-               rloc(m_at(x, y)); /* insurance */
+               (void) rloc(m_at(x, y), FALSE); /* insurance */
 
        if(!In_endgame(&u.uz)) special = FALSE;
 
index 5de3adede2a890ffbacd1b48916d994e9b866594..ed8b560287f87e2a86e8273f84f5466def3fddeb 100644 (file)
@@ -592,7 +592,7 @@ mon_tele:
                    return 2;
                }
                if (oseen && how) makeknown(how);
-               rloc(mtmp);
+               (void) rloc(mtmp, FALSE);
                return 2;
        case MUSE_WAN_TELEPORTATION:
                zap_oseen = oseen;
@@ -1148,7 +1148,7 @@ register struct obj *otmp;
                            mtmp->msleeping = 0;
                            if(mtmp->m_ap_type) seemimic(mtmp);
                        } else if (!tele_restrict(mtmp))
-                           rloc(mtmp);
+                           (void) rloc(mtmp, FALSE);
                }
                break;
        case WAN_CANCELLATION:
index 5d7359afe8cb16727f2fc4c32ee62f386f92be49..5405fc2330ec8e045131bb7eee2f92d08a5710b2 100644 (file)
@@ -186,7 +186,7 @@ boolean sanctum;   /* is it the seat of the high priest? */
        int cnt;
 
        if(MON_AT(sx+1, sy))
-               rloc(m_at(sx+1, sy)); /* insurance */
+               (void) rloc(m_at(sx+1, sy), FALSE); /* insurance */
 
        priest = makemon(&mons[sanctum ? PM_HIGH_PRIEST : PM_ALIGNED_PRIEST],
                         sx + 1, sy, NO_MM_FLAGS);
@@ -532,7 +532,7 @@ boolean peaceful;
        if (ptr != &mons[PM_ALIGNED_PRIEST] && ptr != &mons[PM_ANGEL])
                return((struct monst *)0);
        
-       if (MON_AT(x, y)) rloc(m_at(x, y));     /* insurance */
+       if (MON_AT(x, y)) (void) rloc(m_at(x, y), FALSE);       /* insurance */
 
        if (!(roamer = makemon(ptr, x, y, NO_MM_FLAGS)))
                return((struct monst *)0);
index 7182de6bf0d57cd32729c6434862267491e35dd6..1975605139394767b46f4dbfb52fd1c819f5c852 100644 (file)
@@ -389,7 +389,7 @@ struct mkroom       *sroom;
            return(-1);
        }
 
-       if(MON_AT(sx, sy)) rloc(m_at(sx, sy)); /* insurance */
+       if(MON_AT(sx, sy)) (void) rloc(m_at(sx, sy), FALSE); /* insurance */
 
        /* now initialize the shopkeeper monster structure */
        if(!(shk = makemon(&mons[PM_SHOPKEEPER], sx, sy, NO_MM_FLAGS)))
index 8cf92e53e361c117b8752ed15f4dd9ce7856657f..f03e3d808599671467ae96442dc39937cbcf9978 100644 (file)
@@ -49,7 +49,7 @@ register struct monst *mtmp;
            pline("%s quickly snatches some gold from between your %s!",
                    Monnam(mtmp), makeplural(body_part(FOOT)));
            if(!u.ugold || !rn2(5)) {
-               if (!tele_restrict(mtmp)) rloc(mtmp);
+               if (!tele_restrict(mtmp)) (void) rloc(mtmp, FALSE);
                /* do not set mtmp->mavenge here; gold on the floor is fair game */
                monflee(mtmp, 0, FALSE, FALSE);
            }
@@ -57,7 +57,7 @@ register struct monst *mtmp;
            u.ugold -= (tmp = somegold());
            Your("purse feels lighter.");
            mtmp->mgold += tmp;
-       if (!tele_restrict(mtmp)) rloc(mtmp);
+       if (!tele_restrict(mtmp)) (void) rloc(mtmp, FALSE);
            mtmp->mavenge = 1;
            monflee(mtmp, 0, FALSE, FALSE);
            flags.botl = 1;
@@ -118,7 +118,7 @@ register struct monst *mtmp;
            pline("%s quickly snatches some gold from between your %s!",
                    Monnam(mtmp), makeplural(body_part(FOOT)));
            if(!ygold || !rn2(5)) {
-               if (!tele_restrict(mtmp)) rloc(mtmp);
+               if (!tele_restrict(mtmp)) (void) rloc(mtmp, FALSE);
                monflee(mtmp, 0, FALSE, FALSE);
            }
        } else if(ygold) {
@@ -129,7 +129,7 @@ register struct monst *mtmp;
             freeinv(ygold);
             add_to_minv(mtmp, ygold);
            Your("purse feels lighter.");
-           if (!tele_restrict(mtmp)) rloc(mtmp);
+           if (!tele_restrict(mtmp)) (void) rloc(mtmp, FALSE);
            monflee(mtmp, 0, FALSE, FALSE);
            flags.botl = 1;
        }
@@ -161,7 +161,7 @@ stealarm()
                        /* Implies seduction, "you gladly hand over ..."
                           so we don't set mavenge bit here. */
                        monflee(mtmp, 0, FALSE, FALSE);
-                       if (!tele_restrict(mtmp)) rloc(mtmp);
+                       if (!tele_restrict(mtmp)) (void) rloc(mtmp, FALSE);
                        break;
                    }
                }
@@ -499,7 +499,7 @@ struct monst *mtmp;
        (void) mpickobj(mtmp,otmp);     /* may merge and free otmp */
        pline("%s stole %s!", Monnam(mtmp), doname(otmp));
        if (can_teleport(mtmp->data) && !tele_restrict(mtmp))
-           rloc(mtmp);
+           (void) rloc(mtmp, FALSE);
     }
 }
 
index f09cb5da9af43a6fb7fe02651878df5dd90abd26..07fab84a9559e7fb68bade70e819ab0464014207 100644 (file)
@@ -535,7 +535,7 @@ dismount_steed(reason)
            if (enexto(&cc, u.ux, u.uy, mtmp->data))
                rloc_to(mtmp, cc.x, cc.y);
            else        /* evidently no room nearby; move steed elsewhere */
-               rloc(mtmp);
+               (void) rloc(mtmp, FALSE);
            return;
        }
        if (!DEADMONSTER(mtmp)) {
index 1d8aecc5d660e632f8d9e0b15993f81d6735c206..02e93a37311388f545b858f45569754baf3b7b29 100644 (file)
@@ -953,16 +953,18 @@ register int x, y;
 }
 
 /* place a monster at a random location, typically due to teleport */
-void
-rloc(mtmp)
+/* return TRUE if successful, FALSE if not */
+boolean
+rloc(mtmp, suppress_impossible)
 struct monst *mtmp;    /* mx==0 implies migrating monster arrival */
+boolean suppress_impossible;
 {
        register int x, y, trycount;
 
 #ifdef STEED
        if (mtmp == u.usteed) {
            tele();
-           return;
+           return TRUE;
        }
 #endif
 
@@ -996,11 +998,13 @@ struct monst *mtmp;       /* mx==0 implies migrating monster arrival */
                    goto found_xy;
 
        /* level either full of monsters or somehow faulty */
-       impossible("rloc(): couldn't relocate monster");
-       return;
+       if (!suppress_impossible)
+               impossible("rloc(): couldn't relocate monster");
+       return FALSE;
 
  found_xy:
        rloc_to(mtmp, x, y);
+       return TRUE;
 }
 
 STATIC_OVL void
@@ -1015,7 +1019,7 @@ struct monst *mtmp;
                rloc_to(mtmp, c.x, c.y);
                return;
        }
-       rloc(mtmp);
+       (void) rloc(mtmp, FALSE);
 }
 
 boolean
@@ -1049,7 +1053,7 @@ int in_sight;
             * the guard isn't going to come for it...
             */
            if (trap->once) mvault_tele(mtmp);
-           else rloc(mtmp);
+           else (void) rloc(mtmp, FALSE);
 
            if (in_sight) {
                if (canseemon(mtmp))
@@ -1253,12 +1257,12 @@ boolean give_feedback;
            if (give_feedback)
                You("are no longer inside %s!", mon_nam(mtmp));
            unstuck(mtmp);
-           rloc(mtmp);
+           (void) rloc(mtmp, FALSE);
        } else if (is_rider(mtmp->data) && rn2(13) &&
                   enexto(&cc, u.ux, u.uy, mtmp->data))
            rloc_to(mtmp, cc.x, cc.y);
        else
-           rloc(mtmp);
+           (void) rloc(mtmp, FALSE);
        return TRUE;
 }
 
index 0fcbd69ffc6dfaa2fc270befd636941f29f3ae0b..ce5ce5b3a2ef13db0f44e8490ef4292ae8603f97 100644 (file)
@@ -42,7 +42,7 @@ register boolean forceshow;
                        if(mtmp->isgd) return(FALSE);
                        else if(!in_fcorridor(grd, u.ux, u.uy)) {
                            if(mtmp->mtame) yelp(mtmp);
-                           rloc(mtmp);
+                           (void) rloc(mtmp, FALSE);
                        }
                }
                levl[fcx][fcy].typ = EGD(grd)->fakecorr[fcbeg].ftyp;
@@ -380,7 +380,7 @@ struct monst *grd;
                if (!IS_WALL(levl[x][y].typ) && !in_fcorridor(grd, x, y)) {
                    if ((mon = m_at(x, y)) != 0 && mon != grd) {
                        if (mon->mtame) yelp(mon);
-                       rloc(mon);
+                       (void) rloc(mon, FALSE);
                    }
                    if ((gold = g_at(x, y)) != 0) {
                        move_gold(gold, EGD(grd)->vroom);
@@ -461,7 +461,7 @@ register struct monst *grd;
               (grd_in_vault ||
                (in_fcorridor(grd, grd->mx, grd->my) &&
                 !in_fcorridor(grd, u.ux, u.uy)))) {
-               rloc(grd);
+               (void) rloc(grd, FALSE);
                wallify_vault(grd);
                (void) clear_fcorr(grd, TRUE);
                goto letknow;
@@ -507,7 +507,7 @@ register struct monst *grd;
                if (u_carry_gold) {     /* player teleported */
                    m = grd->mx;
                    n = grd->my;
-                   rloc(grd);
+                   (void) rloc(grd, FALSE);
                    levl[m][n].typ = egrd->fakecorr[0].ftyp;
                    newsym(m,n);
                    grd->mpeaceful = 0;
@@ -583,7 +583,7 @@ letknow:
                    /* just for insurance... */
                    if (MON_AT(m, n) && m != grd->mx && n != grd->my) {
                        verbalize("Out of my way, scum!");
-                       rloc(m_at(m, n));
+                       (void) rloc(m_at(m, n), FALSE);
                    }
                    remove_monster(grd->mx, grd->my);
                    newsym(grd->mx, grd->my);
index 0eba36785a8fdb79fefd286b14156489a0f167b8..09c3494ad469959449e4e84feff0bc97b95891cc 100644 (file)
@@ -303,7 +303,7 @@ tactics(mtmp)
                mtmp->mavenge = 1; /* covetous monsters attack while fleeing */
                if (In_W_tower(mtmp->mx, mtmp->my, &u.uz) ||
                        (mtmp->iswiz && !xupstair && !mon_has_amulet(mtmp))) {
-                   if (!rn2(3 + mtmp->mhp/10)) rloc(mtmp);
+                   if (!rn2(3 + mtmp->mhp/10)) (void) rloc(mtmp, FALSE);
                } else if (xupstair &&
                         (mtmp->mx != xupstair || mtmp->my != yupstair)) {
                    (void) mnearto(mtmp, xupstair, yupstair, TRUE);