diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index 97f20955e..c261e6c66 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -1007,6 +1007,8 @@ attempting to move up or down when poly'd into a holder and holding a monster rejected the move; release the monster instead thowing a non-weapon while engulfed by an ochre jelly reported that the item vanished into the jelly's "currents" +if a pet gelatinous cube eats a container, treat it the same as when a hostile + one does: the container is destroyed but its conters are engulfed Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/include/extern.h b/include/extern.h index 20e7ecc65..54f4270b1 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1527,6 +1527,7 @@ extern int pm_to_cham(int); extern int minliquid(struct monst *); extern boolean movemon_singlemon(struct monst *); extern int movemon(void); +extern void meatbox(struct monst *, struct obj *); extern int meatmetal(struct monst *); extern int meatobj(struct monst *); extern int meatcorpse(struct monst *); diff --git a/src/dogmove.c b/src/dogmove.c index 2d8bc924e..6f487bed4 100644 --- a/src/dogmove.c +++ b/src/dogmove.c @@ -306,6 +306,9 @@ dog_eat(struct monst *mtmp, Strcpy(objnambuf, xname(obj)); iflags.suppress_price--; } + /* some monsters that eat items could eat a container with contents */ + if (Has_contents(obj)) + meatbox(mtmp, obj); /* It's a reward if it's DOGFOOD and the player dropped/threw it. We know the player had it if invlet is set. -dlc */ if (dogfood(mtmp, obj) == DOGFOOD && obj->invlet) diff --git a/src/mon.c b/src/mon.c index ae3aa2801..cf51f083a 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1083,6 +1083,38 @@ movemon(void) return g.somebody_can_move; } +/* dispose of contents of an eaten container; used for pets and other mons */ +void +meatbox(struct monst *mon, struct obj *otmp) +{ + boolean engulf_contents = (mon->data == &mons[PM_GELATINOUS_CUBE]); + int x = mon->mx, y = mon->my; + struct obj *cobj; + + if (!Has_contents(otmp) || !isok(x, y)) + return; + + /* contents of eaten containers become engulfed or dropped onto + the floor; this is arbitrary, but otherwise g-cubes are too + powerful */ + if (!engulf_contents && cansee(x, y)) { + pline("%s contents spill out onto the %s.", + s_suffix(The(distant_name(otmp, xname))), + surface(x, y)); + } + while ((cobj = otmp->cobj) != 0) { + obj_extract_self(cobj); + if (otmp->otyp == ICE_BOX) + removed_from_icebox(cobj); + if (engulf_contents) { + (void) mpickobj(mon, cobj); + } else { + if (!flooreffects(cobj, x, y, "")) + place_object(cobj, x, y); + } + } +} + #define mstoning(obj) \ (ofood(obj) && (touch_petrifies(&mons[(obj)->corpsenm]) \ || (obj)->corpsenm == PM_MEDUSA)) @@ -1151,6 +1183,10 @@ meatmetal(struct monst *mtmp) if (mtmp->mhp > mtmp->mhpmax) mtmp->mhp = mtmp->mhpmax; } + /* Currently there shouldn't be any metal object with + contents, but just in case... */ + if (Has_contents(otmp)) + meatbox(mtmp, otmp); if (otmp == uball) { unpunish(); delobj(otmp); @@ -1305,20 +1341,8 @@ meatobj(struct monst* mtmp) /* for gelatinous cubes */ if (mtmp->mhp > mtmp->mhpmax) mtmp->mhp = mtmp->mhpmax; } - if (Has_contents(otmp)) { - register struct obj *otmp3; - - /* contents of eaten containers become engulfed; this - is arbitrary, but otherwise g-cubes are too powerful */ - while ((otmp3 = otmp->cobj) != 0) { - obj_extract_self(otmp3); - if (otmp->otyp == ICE_BOX && otmp3->otyp == CORPSE) { - otmp3->age = g.moves - otmp3->age; - start_corpse_timeout(otmp3); - } - (void) mpickobj(mtmp, otmp3); - } - } + if (Has_contents(otmp)) + meatbox(mtmp, otmp); /* possibility of being turned to stone or into slime can't reach here (don't touch for cockatrice corpse, engulf rather than eat for tin, cockatrice egg, or glob of green slime) */