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 rejected the move; release the monster instead
thowing a non-weapon while engulfed by an ochre jelly reported that the item thowing a non-weapon while engulfed by an ochre jelly reported that the item
vanished into the jelly's "currents" 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 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 int minliquid(struct monst *);
extern boolean movemon_singlemon(struct monst *); extern boolean movemon_singlemon(struct monst *);
extern int movemon(void); extern int movemon(void);
extern void meatbox(struct monst *, struct obj *);
extern int meatmetal(struct monst *); extern int meatmetal(struct monst *);
extern int meatobj(struct monst *); extern int meatobj(struct monst *);
extern int meatcorpse(struct monst *); extern int meatcorpse(struct monst *);

View File

@@ -306,6 +306,9 @@ dog_eat(struct monst *mtmp,
Strcpy(objnambuf, xname(obj)); Strcpy(objnambuf, xname(obj));
iflags.suppress_price--; 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. /* 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 */ We know the player had it if invlet is set. -dlc */
if (dogfood(mtmp, obj) == DOGFOOD && obj->invlet) if (dogfood(mtmp, obj) == DOGFOOD && obj->invlet)

View File

@@ -1083,6 +1083,38 @@ movemon(void)
return g.somebody_can_move; 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) \ #define mstoning(obj) \
(ofood(obj) && (touch_petrifies(&mons[(obj)->corpsenm]) \ (ofood(obj) && (touch_petrifies(&mons[(obj)->corpsenm]) \
|| (obj)->corpsenm == PM_MEDUSA)) || (obj)->corpsenm == PM_MEDUSA))
@@ -1151,6 +1183,10 @@ meatmetal(struct monst *mtmp)
if (mtmp->mhp > mtmp->mhpmax) if (mtmp->mhp > mtmp->mhpmax)
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) { if (otmp == uball) {
unpunish(); unpunish();
delobj(otmp); delobj(otmp);
@@ -1305,20 +1341,8 @@ meatobj(struct monst* mtmp) /* for gelatinous cubes */
if (mtmp->mhp > mtmp->mhpmax) if (mtmp->mhp > mtmp->mhpmax)
mtmp->mhp = mtmp->mhpmax; mtmp->mhp = mtmp->mhpmax;
} }
if (Has_contents(otmp)) { if (Has_contents(otmp))
register struct obj *otmp3; meatbox(mtmp, otmp);
/* 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);
}
}
/* possibility of being turned to stone or into slime can't /* possibility of being turned to stone or into slime can't
reach here (don't touch for cockatrice corpse, engulf rather reach here (don't touch for cockatrice corpse, engulf rather
than eat for tin, cockatrice egg, or glob of green slime) */ than eat for tin, cockatrice egg, or glob of green slime) */