buglist - full level triggers impossible() from migrating mons

<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.
This commit is contained in:
nethack.allison
2003-09-13 05:30:43 +00:00
parent 32b2af4abf
commit cc830fb311
24 changed files with 134 additions and 53 deletions

View File

@@ -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 */