pets eating containers

Apply the patch from entrez that makes pet gelatinous cubes who eat
containers engulf rather than digest the contents, like non-tame
g.cubes.  Unlike the latter, tame ones will immediately drop the
stuff they just engulfed and might subsequently eat it all anyway.
This commit is contained in:
PatR
2022-08-18 01:09:52 -07:00
parent 10101cf1da
commit 2108abd30d
4 changed files with 44 additions and 14 deletions

View File

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

View File

@@ -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 *);

View File

@@ -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)

View File

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