pet fodder
Allow starving pets to consume items they wouldn't ordinarily
eat. Carnivores will eat fruits and vegetables--such as they are--
and herbivores will eat assorted rations. Even though eating such
rations doesn't violate vegetarian conduct for the character, horses
would never eat them.
This change should allow players to keep mundane steeds alive
much longer. The new behavior doesn't kick in until the pet has
been classified as starving though; it doesn't affect ones who are
merely hungry.
This also gives the reason why a starving pet has died instead
of just saying "<pet> dies" whenever it starved with hit points left.
This commit is contained in:
@@ -242,6 +242,8 @@ make sure corpses and statues which remember monster attributes don't keep
|
|||||||
ones that were conferred by no longer worn items (mainly speed boots)
|
ones that were conferred by no longer worn items (mainly speed boots)
|
||||||
elevate the trouble priority of any cursed item which is preventing removal
|
elevate the trouble priority of any cursed item which is preventing removal
|
||||||
of a ring of levitation
|
of a ring of levitation
|
||||||
|
starving pets will eat more aggressively
|
||||||
|
when a pet starves to death, say so instead of just "Fido dies."
|
||||||
|
|
||||||
|
|
||||||
Platform- and/or Interface-Specific Fixes
|
Platform- and/or Interface-Specific Fixes
|
||||||
|
|||||||
@@ -596,6 +596,7 @@ register struct obj *obj;
|
|||||||
boolean carni = carnivorous(mon->data);
|
boolean carni = carnivorous(mon->data);
|
||||||
boolean herbi = herbivorous(mon->data);
|
boolean herbi = herbivorous(mon->data);
|
||||||
struct permonst *fptr = &mons[obj->corpsenm];
|
struct permonst *fptr = &mons[obj->corpsenm];
|
||||||
|
boolean starving;
|
||||||
|
|
||||||
if (is_quest_artifact(obj) || obj_resists(obj, 0, 95))
|
if (is_quest_artifact(obj) || obj_resists(obj, 0, 95))
|
||||||
return (obj->cursed ? TABU : APPORT);
|
return (obj->cursed ? TABU : APPORT);
|
||||||
@@ -609,12 +610,17 @@ register struct obj *obj;
|
|||||||
|
|
||||||
/* Ghouls only eat old corpses... yum! */
|
/* Ghouls only eat old corpses... yum! */
|
||||||
if (mon->data == &mons[PM_GHOUL])
|
if (mon->data == &mons[PM_GHOUL])
|
||||||
return (obj->otyp == CORPSE && obj->age+50 <= monstermoves) ?
|
return (obj->otyp == CORPSE &&
|
||||||
DOGFOOD : TABU;
|
peek_at_iced_corpse_age(obj) + 50L <= monstermoves) ?
|
||||||
|
DOGFOOD : TABU;
|
||||||
|
|
||||||
if (!carni && !herbi)
|
if (!carni && !herbi)
|
||||||
return (obj->cursed ? UNDEF : APPORT);
|
return (obj->cursed ? UNDEF : APPORT);
|
||||||
|
|
||||||
|
/* a starving pet will eat almost anything */
|
||||||
|
starving = (mon->mtame && !mon->isminion &&
|
||||||
|
EDOG(mon)->mhpmax_penalty);
|
||||||
|
|
||||||
switch (obj->otyp) {
|
switch (obj->otyp) {
|
||||||
case TRIPE_RATION:
|
case TRIPE_RATION:
|
||||||
case MEATBALL:
|
case MEATBALL:
|
||||||
@@ -627,7 +633,7 @@ register struct obj *obj;
|
|||||||
return POISON;
|
return POISON;
|
||||||
return (carni ? CADAVER : MANFOOD);
|
return (carni ? CADAVER : MANFOOD);
|
||||||
case CORPSE:
|
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_LIZARD
|
||||||
&& obj->corpsenm != PM_LICHEN
|
&& obj->corpsenm != PM_LICHEN
|
||||||
&& mon->data->mlet != S_FUNGUS) ||
|
&& mon->data->mlet != S_FUNGUS) ||
|
||||||
@@ -640,24 +646,25 @@ register struct obj *obj;
|
|||||||
else return (carni ? CADAVER : MANFOOD);
|
else return (carni ? CADAVER : MANFOOD);
|
||||||
case CLOVE_OF_GARLIC:
|
case CLOVE_OF_GARLIC:
|
||||||
return (is_undead(mon->data) ? TABU :
|
return (is_undead(mon->data) ? TABU :
|
||||||
(herbi ? ACCFOOD : MANFOOD));
|
((herbi || starving) ? ACCFOOD : MANFOOD));
|
||||||
case TIN:
|
case TIN:
|
||||||
return (metallivorous(mon->data) ? ACCFOOD : MANFOOD);
|
return (metallivorous(mon->data) ? ACCFOOD : MANFOOD);
|
||||||
case APPLE:
|
case APPLE:
|
||||||
case CARROT:
|
case CARROT:
|
||||||
return (herbi ? DOGFOOD : MANFOOD);
|
return (herbi ? DOGFOOD : starving ? ACCFOOD : MANFOOD);
|
||||||
case BANANA:
|
case BANANA:
|
||||||
return ((mon->data->mlet == S_YETI) ? DOGFOOD :
|
return ((mon->data->mlet == S_YETI) ? DOGFOOD :
|
||||||
(herbi ? ACCFOOD : MANFOOD));
|
((herbi || starving) ? ACCFOOD : MANFOOD));
|
||||||
default:
|
default:
|
||||||
|
if (starving) return ACCFOOD;
|
||||||
return (obj->otyp > SLIME_MOLD ?
|
return (obj->otyp > SLIME_MOLD ?
|
||||||
(carni ? ACCFOOD : MANFOOD) :
|
(carni ? ACCFOOD : MANFOOD) :
|
||||||
(herbi ? ACCFOOD : MANFOOD));
|
(herbi ? ACCFOOD : MANFOOD));
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
if (obj->otyp == AMULET_OF_STRANGULATION ||
|
if (obj->otyp == AMULET_OF_STRANGULATION ||
|
||||||
obj->otyp == RIN_SLOW_DIGESTION)
|
obj->otyp == RIN_SLOW_DIGESTION)
|
||||||
return (TABU);
|
return TABU;
|
||||||
if (hates_silver(mon->data) &&
|
if (hates_silver(mon->data) &&
|
||||||
objects[obj->otyp].oc_material == SILVER)
|
objects[obj->otyp].oc_material == SILVER)
|
||||||
return(TABU);
|
return(TABU);
|
||||||
|
|||||||
+17
-11
@@ -1,4 +1,4 @@
|
|||||||
/* 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. */
|
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
|
|
||||||
@@ -232,7 +232,7 @@ register struct edog *edog;
|
|||||||
You_feel("worried about %s.", y_monnam(mtmp));
|
You_feel("worried about %s.", y_monnam(mtmp));
|
||||||
stop_occupation();
|
stop_occupation();
|
||||||
} else if (monstermoves > edog->hungrytime + 750 || mtmp->mhp < 1) {
|
} else if (monstermoves > edog->hungrytime + 750 || mtmp->mhp < 1) {
|
||||||
dog_died:
|
dog_died:
|
||||||
if (mtmp->mleashed
|
if (mtmp->mleashed
|
||||||
#ifdef STEED
|
#ifdef STEED
|
||||||
&& mtmp != u.usteed
|
&& mtmp != u.usteed
|
||||||
@@ -240,8 +240,7 @@ register struct edog *edog;
|
|||||||
)
|
)
|
||||||
Your("leash goes slack.");
|
Your("leash goes slack.");
|
||||||
else if (cansee(mtmp->mx, mtmp->my))
|
else if (cansee(mtmp->mx, mtmp->my))
|
||||||
pline("%s dies%s.", Monnam(mtmp),
|
pline("%s starves.", Monnam(mtmp));
|
||||||
(mtmp->mhp >= 1) ? "" : " from hunger");
|
|
||||||
else
|
else
|
||||||
You_feel("%s for a moment.",
|
You_feel("%s for a moment.",
|
||||||
Hallucination ? "bummed" : "sad");
|
Hallucination ? "bummed" : "sad");
|
||||||
@@ -290,7 +289,11 @@ int udist;
|
|||||||
&& obj->otyp != SCR_MAIL
|
&& obj->otyp != SCR_MAIL
|
||||||
#endif
|
#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);
|
return dog_eat(mtmp, obj, omx, omy, FALSE);
|
||||||
|
|
||||||
if(can_carry(mtmp, obj) && !obj->cursed &&
|
if(can_carry(mtmp, obj) && !obj->cursed &&
|
||||||
@@ -327,12 +330,11 @@ struct edog *edog;
|
|||||||
int after, udist, whappr;
|
int after, udist, whappr;
|
||||||
{
|
{
|
||||||
register int omx, omy;
|
register int omx, omy;
|
||||||
boolean in_masters_sight;
|
boolean in_masters_sight, dog_has_minvent;
|
||||||
register struct obj *obj;
|
register struct obj *obj;
|
||||||
xchar otyp;
|
xchar otyp;
|
||||||
int appr;
|
int appr;
|
||||||
|
|
||||||
|
|
||||||
#ifdef STEED
|
#ifdef STEED
|
||||||
/* Steeds don't move on their own will */
|
/* Steeds don't move on their own will */
|
||||||
if (mtmp == u.usteed)
|
if (mtmp == u.usteed)
|
||||||
@@ -343,6 +345,7 @@ int after, udist, whappr;
|
|||||||
omy = mtmp->my;
|
omy = mtmp->my;
|
||||||
|
|
||||||
in_masters_sight = couldsee(omx, omy);
|
in_masters_sight = couldsee(omx, omy);
|
||||||
|
dog_has_minvent = (DROPPABLES(mtmp) != 0);
|
||||||
|
|
||||||
if (!edog || mtmp->mleashed) { /* he's not going anywhere... */
|
if (!edog || mtmp->mleashed) { /* he's not going anywhere... */
|
||||||
gtyp = APPORT;
|
gtyp = APPORT;
|
||||||
@@ -357,7 +360,7 @@ int after, udist, whappr;
|
|||||||
gtyp = UNDEF; /* no goal as yet */
|
gtyp = UNDEF; /* no goal as yet */
|
||||||
gx = gy = 0; /* suppress 'used before set' message */
|
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 ((max_x = omx + SQSRCHRADIUS) >= COLNO) max_x = COLNO - 1;
|
||||||
if ((min_y = omy - SQSRCHRADIUS) < 0) min_y = 0;
|
if ((min_y = omy - SQSRCHRADIUS) < 0) min_y = 0;
|
||||||
if ((max_y = omy + SQSRCHRADIUS) >= ROWNO) max_y = ROWNO - 1;
|
if ((max_y = omy + SQSRCHRADIUS) >= ROWNO) max_y = ROWNO - 1;
|
||||||
@@ -368,9 +371,12 @@ int after, udist, whappr;
|
|||||||
ny = obj->oy;
|
ny = obj->oy;
|
||||||
if (nx >= min_x && nx <= max_x && ny >= min_y && ny <= max_y) {
|
if (nx >= min_x && nx <= max_x && ny >= min_y && ny <= max_y) {
|
||||||
otyp = dogfood(mtmp, obj);
|
otyp = dogfood(mtmp, obj);
|
||||||
|
/* skip inferior goals */
|
||||||
if (otyp > gtyp || otyp == UNDEF)
|
if (otyp > gtyp || otyp == UNDEF)
|
||||||
continue;
|
continue;
|
||||||
if (cursed_object_at(nx, ny))
|
/* avoid cursed items unless starving */
|
||||||
|
if (cursed_object_at(nx, ny) &&
|
||||||
|
!(edog->mhpmax_penalty && otyp < MANFOOD))
|
||||||
continue;
|
continue;
|
||||||
if (otyp < MANFOOD &&
|
if (otyp < MANFOOD &&
|
||||||
can_reach_food(mtmp, mtmp->mx, mtmp->my, nx, ny)) {
|
can_reach_food(mtmp, mtmp->mx, mtmp->my, nx, ny)) {
|
||||||
@@ -380,7 +386,7 @@ int after, udist, whappr;
|
|||||||
gtyp = otyp;
|
gtyp = otyp;
|
||||||
}
|
}
|
||||||
} else if(gtyp == UNDEF && in_masters_sight &&
|
} else if(gtyp == UNDEF && in_masters_sight &&
|
||||||
!mtmp->minvent &&
|
!dog_has_minvent &&
|
||||||
(!levl[omx][omy].lit || levl[u.ux][u.uy].lit) &&
|
(!levl[omx][omy].lit || levl[u.ux][u.uy].lit) &&
|
||||||
(otyp == MANFOOD || m_cansee(mtmp, nx, ny)) &&
|
(otyp == MANFOOD || m_cansee(mtmp, nx, ny)) &&
|
||||||
edog->apport > rn2(8) &&
|
edog->apport > rn2(8) &&
|
||||||
@@ -404,7 +410,7 @@ int after, udist, whappr;
|
|||||||
if (udist > 1) {
|
if (udist > 1) {
|
||||||
if (!IS_ROOM(levl[u.ux][u.uy].typ) || !rn2(4) ||
|
if (!IS_ROOM(levl[u.ux][u.uy].typ) || !rn2(4) ||
|
||||||
whappr ||
|
whappr ||
|
||||||
(mtmp->minvent && rn2(edog->apport)))
|
(dog_has_minvent && rn2(edog->apport)))
|
||||||
appr = 1;
|
appr = 1;
|
||||||
}
|
}
|
||||||
/* if you have dog food it'll follow you more closely */
|
/* if you have dog food it'll follow you more closely */
|
||||||
|
|||||||
Reference in New Issue
Block a user