boolean carni = carnivorous(mon->data);
boolean herbi = herbivorous(mon->data);
struct permonst *fptr = &mons[obj->corpsenm];
+ boolean starving;
if (is_quest_artifact(obj) || obj_resists(obj, 0, 95))
return (obj->cursed ? TABU : APPORT);
/* Ghouls only eat old corpses... yum! */
if (mon->data == &mons[PM_GHOUL])
- return (obj->otyp == CORPSE && obj->age+50 <= monstermoves) ?
- DOGFOOD : TABU;
+ return (obj->otyp == CORPSE &&
+ peek_at_iced_corpse_age(obj) + 50L <= monstermoves) ?
+ DOGFOOD : TABU;
if (!carni && !herbi)
return (obj->cursed ? UNDEF : APPORT);
+ /* a starving pet will eat almost anything */
+ starving = (mon->mtame && !mon->isminion &&
+ EDOG(mon)->mhpmax_penalty);
+
switch (obj->otyp) {
case TRIPE_RATION:
case MEATBALL:
return POISON;
return (carni ? CADAVER : MANFOOD);
case CORPSE:
- if ((peek_at_iced_corpse_age(obj)+50 <= monstermoves
+ if ((peek_at_iced_corpse_age(obj) + 50L <= monstermoves
&& obj->corpsenm != PM_LIZARD
&& obj->corpsenm != PM_LICHEN
&& mon->data->mlet != S_FUNGUS) ||
else return (carni ? CADAVER : MANFOOD);
case CLOVE_OF_GARLIC:
return (is_undead(mon->data) ? TABU :
- (herbi ? ACCFOOD : MANFOOD));
+ ((herbi || starving) ? ACCFOOD : MANFOOD));
case TIN:
return (metallivorous(mon->data) ? ACCFOOD : MANFOOD);
case APPLE:
case CARROT:
- return (herbi ? DOGFOOD : MANFOOD);
+ return (herbi ? DOGFOOD : starving ? ACCFOOD : MANFOOD);
case BANANA:
return ((mon->data->mlet == S_YETI) ? DOGFOOD :
- (herbi ? ACCFOOD : MANFOOD));
+ ((herbi || starving) ? ACCFOOD : MANFOOD));
default:
+ if (starving) return ACCFOOD;
return (obj->otyp > SLIME_MOLD ?
(carni ? ACCFOOD : MANFOOD) :
(herbi ? ACCFOOD : MANFOOD));
}
default:
if (obj->otyp == AMULET_OF_STRANGULATION ||
- obj->otyp == RIN_SLOW_DIGESTION)
- return (TABU);
+ obj->otyp == RIN_SLOW_DIGESTION)
+ return TABU;
if (hates_silver(mon->data) &&
objects[obj->otyp].oc_material == SILVER)
return(TABU);
-/* SCCS Id: @(#)dogmove.c 3.4 2002/04/06 */
+/* SCCS Id: @(#)dogmove.c 3.4 2002/09/10 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
You_feel("worried about %s.", y_monnam(mtmp));
stop_occupation();
} else if (monstermoves > edog->hungrytime + 750 || mtmp->mhp < 1) {
- dog_died:
+ dog_died:
if (mtmp->mleashed
#ifdef STEED
&& mtmp != u.usteed
)
Your("leash goes slack.");
else if (cansee(mtmp->mx, mtmp->my))
- pline("%s dies%s.", Monnam(mtmp),
- (mtmp->mhp >= 1) ? "" : " from hunger");
+ pline("%s starves.", Monnam(mtmp));
else
You_feel("%s for a moment.",
Hallucination ? "bummed" : "sad");
&& obj->otyp != SCR_MAIL
#endif
){
- if (dogfood(mtmp, obj) <= CADAVER)
+ int edible = dogfood(mtmp, obj);
+
+ if (edible <= CADAVER ||
+ /* starving pet is more aggressive about eating */
+ (edog->mhpmax_penalty && edible == ACCFOOD))
return dog_eat(mtmp, obj, omx, omy, FALSE);
if(can_carry(mtmp, obj) && !obj->cursed &&
int after, udist, whappr;
{
register int omx, omy;
- boolean in_masters_sight;
+ boolean in_masters_sight, dog_has_minvent;
register struct obj *obj;
xchar otyp;
int appr;
-
#ifdef STEED
/* Steeds don't move on their own will */
if (mtmp == u.usteed)
omy = mtmp->my;
in_masters_sight = couldsee(omx, omy);
+ dog_has_minvent = (DROPPABLES(mtmp) != 0);
if (!edog || mtmp->mleashed) { /* he's not going anywhere... */
gtyp = APPORT;
gtyp = UNDEF; /* no goal as yet */
gx = gy = 0; /* suppress 'used before set' message */
- if ((min_x = omx - SQSRCHRADIUS) < 0) min_x = 0;
+ if ((min_x = omx - SQSRCHRADIUS) < 1) min_x = 1;
if ((max_x = omx + SQSRCHRADIUS) >= COLNO) max_x = COLNO - 1;
if ((min_y = omy - SQSRCHRADIUS) < 0) min_y = 0;
if ((max_y = omy + SQSRCHRADIUS) >= ROWNO) max_y = ROWNO - 1;
ny = obj->oy;
if (nx >= min_x && nx <= max_x && ny >= min_y && ny <= max_y) {
otyp = dogfood(mtmp, obj);
+ /* skip inferior goals */
if (otyp > gtyp || otyp == UNDEF)
continue;
- if (cursed_object_at(nx, ny))
+ /* avoid cursed items unless starving */
+ if (cursed_object_at(nx, ny) &&
+ !(edog->mhpmax_penalty && otyp < MANFOOD))
continue;
if (otyp < MANFOOD &&
can_reach_food(mtmp, mtmp->mx, mtmp->my, nx, ny)) {
gtyp = otyp;
}
} else if(gtyp == UNDEF && in_masters_sight &&
- !mtmp->minvent &&
+ !dog_has_minvent &&
(!levl[omx][omy].lit || levl[u.ux][u.uy].lit) &&
(otyp == MANFOOD || m_cansee(mtmp, nx, ny)) &&
edog->apport > rn2(8) &&
if (udist > 1) {
if (!IS_ROOM(levl[u.ux][u.uy].typ) || !rn2(4) ||
whappr ||
- (mtmp->minvent && rn2(edog->apport)))
+ (dog_has_minvent && rn2(edog->apport)))
appr = 1;
}
/* if you have dog food it'll follow you more closely */