B01004 No mimic corpse effect on pet (trunk only)
Make a mimic effect that lasts only as long as the pet is still consuming the corpse.
This commit is contained in:
@@ -422,6 +422,7 @@ E int FDECL(dog_move, (struct monst *,int));
|
||||
#ifdef USE_TRAMPOLI
|
||||
E void FDECL(wantdoor, (int,int,genericptr_t));
|
||||
#endif
|
||||
E void FDECL(finish_meating,(struct monst *));
|
||||
|
||||
/* ### dokick.c ### */
|
||||
|
||||
|
||||
@@ -436,7 +436,7 @@ long nmv; /* number of moves */
|
||||
if (mtmp->mstun && rn2(imv + 1) > 10/2) mtmp->mstun = 0;
|
||||
|
||||
/* might finish eating or be able to use special ability again */
|
||||
if (imv > mtmp->meating) mtmp->meating = 0;
|
||||
if (imv > mtmp->meating) finish_meating(mtmp);
|
||||
else mtmp->meating -= imv;
|
||||
if (imv > mtmp->mspec_used) mtmp->mspec_used = 0;
|
||||
else mtmp->mspec_used -= imv;
|
||||
@@ -837,7 +837,8 @@ boolean was_dead;
|
||||
struct edog *edog;
|
||||
boolean quietly = was_dead;
|
||||
|
||||
mtmp->meating = 0;
|
||||
finish_meating(mtmp);
|
||||
|
||||
if (!mtmp->mtame) return;
|
||||
edog = !mtmp->isminion ? EDOG(mtmp) : 0;
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ STATIC_DCL struct obj *FDECL(DROPPABLES, (struct monst *));
|
||||
STATIC_DCL boolean FDECL(can_reach_location,(struct monst *,XCHAR_P,XCHAR_P,
|
||||
XCHAR_P,XCHAR_P));
|
||||
STATIC_DCL boolean FDECL(could_reach_item,(struct monst *, XCHAR_P,XCHAR_P));
|
||||
STATIC_DCL void FDECL(quickmimic, (struct monst *));
|
||||
|
||||
STATIC_OVL struct obj *
|
||||
DROPPABLES(mon)
|
||||
@@ -124,10 +125,17 @@ boolean devour;
|
||||
register struct edog *edog = EDOG(mtmp);
|
||||
boolean poly = FALSE, grow = FALSE, heal = FALSE;
|
||||
int nutrit;
|
||||
boolean deadmimic = FALSE;
|
||||
|
||||
if(edog->hungrytime < monstermoves)
|
||||
edog->hungrytime = monstermoves;
|
||||
nutrit = dog_nutrition(mtmp, obj);
|
||||
|
||||
deadmimic = (obj->otyp == CORPSE &&
|
||||
(obj->corpsenm == PM_SMALL_MIMIC ||
|
||||
obj->corpsenm == PM_LARGE_MIMIC ||
|
||||
obj->corpsenm == PM_GIANT_MIMIC));
|
||||
|
||||
poly = polyfodder(obj);
|
||||
grow = mlevelgain(obj);
|
||||
heal = mhealup(obj);
|
||||
@@ -192,11 +200,13 @@ boolean devour;
|
||||
(void) newcham(mtmp, (struct permonst *)0, FALSE,
|
||||
cansee(mtmp->mx, mtmp->my));
|
||||
}
|
||||
|
||||
/* limit "instant" growth to prevent potential abuse */
|
||||
if (grow && (int) mtmp->m_lev < (int)mtmp->data->mlevel + 15) {
|
||||
if (!grow_up(mtmp, (struct monst *)0)) return 2;
|
||||
}
|
||||
if (heal) mtmp->mhp = mtmp->mhpmax;
|
||||
if (deadmimic) quickmimic(mtmp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -853,4 +863,79 @@ genericptr_t distance;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static struct qmchoices {
|
||||
int mndx; /* type of pet, 0 means any */
|
||||
char mlet; /* symbol of pet, 0 means any */
|
||||
unsigned mappearance; /* mimic this */
|
||||
uchar m_ap_type; /* what is the thing it is mimicing? */
|
||||
} qm[] = {
|
||||
/* Things that some pets might be thinking about at the time */
|
||||
{PM_LITTLE_DOG, 0, PM_KITTEN, M_AP_MONSTER},
|
||||
{PM_LARGE_DOG, 0, PM_LARGE_CAT, M_AP_MONSTER},
|
||||
{PM_KITTEN, 0, PM_LITTLE_DOG, M_AP_MONSTER},
|
||||
{PM_LARGE_CAT, 0, PM_LARGE_DOG, M_AP_MONSTER},
|
||||
{PM_HOUSECAT, 0, PM_DOG, M_AP_MONSTER},
|
||||
{PM_DOG, 0, PM_HOUSECAT, M_AP_MONSTER},
|
||||
{PM_HOUSECAT, 0, PM_GIANT_RAT, M_AP_MONSTER},
|
||||
#ifdef SINKS
|
||||
{0, S_DOG, SINK, M_AP_FURNITURE}, /* sorry, no fire hydrants in NetHack */
|
||||
#endif
|
||||
{0, 0, TRIPE_RATION, M_AP_OBJECT}, /* leave this at end */
|
||||
};
|
||||
|
||||
void
|
||||
finish_meating(mtmp)
|
||||
struct monst *mtmp;
|
||||
{
|
||||
mtmp->meating = 0;
|
||||
if (mtmp->m_ap_type && mtmp->mappearance && !mtmp->cham) {
|
||||
/* was eating a mimic and now appearance needs resetting */
|
||||
mtmp->m_ap_type = 0;
|
||||
mtmp->mappearance = 0;
|
||||
newsym(mtmp->mx, mtmp->my);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC_OVL void
|
||||
quickmimic(mtmp)
|
||||
struct monst *mtmp;
|
||||
{
|
||||
int idx = 0, trycnt = 5;
|
||||
char buf[BUFSZ];
|
||||
|
||||
if (Protection_from_shape_changers || Blind || !mtmp->meating) return;
|
||||
|
||||
do {
|
||||
idx = rn2(SIZE(qm));
|
||||
if (qm[idx].mndx != 0 && monsndx(mtmp->data) == qm[idx].mndx)
|
||||
break;
|
||||
if (qm[idx].mlet != 0 && mtmp->data->mlet == qm[idx].mlet)
|
||||
break;
|
||||
if (qm[idx].mndx == 0 && qm[idx].mlet == 0)
|
||||
break;
|
||||
} while (--trycnt > 0);
|
||||
if (trycnt == 0) idx = SIZE(qm)-1;
|
||||
if (!idx) return; /* impossible */
|
||||
|
||||
Strcpy(buf, mon_nam(mtmp));
|
||||
|
||||
mtmp->m_ap_type = qm[idx].m_ap_type;
|
||||
mtmp->mappearance = qm[idx].mappearance;
|
||||
|
||||
newsym(mtmp->mx,mtmp->my);
|
||||
You("see %s appear where %s was!",
|
||||
(mtmp->m_ap_type == M_AP_FURNITURE) ?
|
||||
an(defsyms[mtmp->mappearance].explanation) :
|
||||
(mtmp->m_ap_type == M_AP_OBJECT &&
|
||||
OBJ_DESCR(objects[mtmp->mappearance])) ?
|
||||
an(OBJ_DESCR(objects[mtmp->mappearance])) :
|
||||
(mtmp->m_ap_type == M_AP_OBJECT &&
|
||||
OBJ_NAME(objects[mtmp->mappearance])) ?
|
||||
an(OBJ_NAME(objects[mtmp->mappearance])) :
|
||||
(mtmp->m_ap_type == M_AP_MONSTER) ?
|
||||
an(mons[mtmp->mappearance].mname) : something, buf);
|
||||
display_nhwindow(WIN_MAP, TRUE);
|
||||
}
|
||||
|
||||
/*dogmove.c*/
|
||||
|
||||
@@ -250,7 +250,7 @@ register struct obj *gold;
|
||||
long value = gold->quan * objects[gold->otyp].oc_cost;
|
||||
#endif
|
||||
mtmp->msleeping = 0;
|
||||
mtmp->meating = 0;
|
||||
finish_meating(mtmp);
|
||||
if(!rn2(4)) setmangry(mtmp); /* not always pleasing */
|
||||
|
||||
/* greedy monsters catch gold */
|
||||
|
||||
@@ -2098,7 +2098,7 @@ wakeup(mtmp)
|
||||
register struct monst *mtmp;
|
||||
{
|
||||
mtmp->msleeping = 0;
|
||||
mtmp->meating = 0; /* assume there's no salvagable food left */
|
||||
finish_meating(mtmp);
|
||||
setmangry(mtmp);
|
||||
if(mtmp->m_ap_type) seemimic(mtmp);
|
||||
else if (context.forcefight && !context.mon_moving && mtmp->mundetected) {
|
||||
|
||||
@@ -141,7 +141,10 @@ boolean digest_meal;
|
||||
(moves % 20 == 0 || regenerates(mon->data))) mon->mhp++;
|
||||
if (mon->mspec_used) mon->mspec_used--;
|
||||
if (digest_meal) {
|
||||
if (mon->meating) mon->meating--;
|
||||
if (mon->meating) {
|
||||
mon->meating--;
|
||||
if (mon->meating <= 0) finish_meating(mon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -603,6 +606,7 @@ register int after;
|
||||
|
||||
if (mtmp->meating) {
|
||||
mtmp->meating--;
|
||||
if (mtmp->meating <= 0) finish_meating(mtmp);
|
||||
return 3; /* still eating */
|
||||
}
|
||||
if (hides_under(ptr) && OBJ_AT(mtmp->mx, mtmp->my) && rn2(10))
|
||||
|
||||
15
src/pline.c
15
src/pline.c
@@ -305,6 +305,21 @@ register struct monst *mtmp;
|
||||
}
|
||||
else if (mtmp->mpeaceful) Strcat(info, ", peaceful");
|
||||
if (mtmp->meating) Strcat(info, ", eating");
|
||||
if (mtmp->meating && !mtmp->cham &&
|
||||
mtmp->mappearance && mtmp->m_ap_type) {
|
||||
Sprintf(eos(info), ", mimicing %s",
|
||||
(mtmp->m_ap_type == M_AP_FURNITURE) ?
|
||||
an(defsyms[mtmp->mappearance].explanation) :
|
||||
(mtmp->m_ap_type == M_AP_OBJECT &&
|
||||
OBJ_DESCR(objects[mtmp->mappearance])) ?
|
||||
an(OBJ_DESCR(objects[mtmp->mappearance])) :
|
||||
(mtmp->m_ap_type == M_AP_OBJECT &&
|
||||
OBJ_NAME(objects[mtmp->mappearance])) ?
|
||||
an(OBJ_NAME(objects[mtmp->mappearance])) :
|
||||
(mtmp->m_ap_type == M_AP_MONSTER) ?
|
||||
an(mons[mtmp->mappearance].mname) :
|
||||
something);
|
||||
}
|
||||
if (mtmp->mcan) Strcat(info, ", cancelled");
|
||||
if (mtmp->mconf) Strcat(info, ", confused");
|
||||
if (mtmp->mblinded || !mtmp->mcansee)
|
||||
|
||||
Reference in New Issue
Block a user