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:
37
src/dog.c
37
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 */
|
||||
|
||||
Reference in New Issue
Block a user