-/* SCCS Id: @(#)muse.c 3.5 2006/01/04 */
+/* SCCS Id: @(#)muse.c 3.5 2006/04/11 */
/* Copyright (C) 1990 by Ken Arromdee */
/* NetHack may be freely redistributed. See license for details. */
(struct monst *,int,int FDECL((*),(MONST_P,OBJ_P)),
int FDECL((*),(OBJ_P,OBJ_P)),struct obj *));
STATIC_DCL void FDECL(you_aggravate, (struct monst *));
+STATIC_DCL boolean FDECL(mcould_eat_tin, (struct monst *));
STATIC_DCL void FDECL(mon_consume_unstone, (struct monst *,struct obj *,
BOOLEAN_P,BOOLEAN_P));
}
}
- if (mtmp->mconf) {
- for(obj = mtmp->minvent; obj; obj = obj->nobj) {
+ if (mtmp->mconf || mtmp->mstun) {
+ struct obj *liztin = 0;
+
+ for (obj = mtmp->minvent; obj; obj = obj->nobj) {
if (obj->otyp == CORPSE && obj->corpsenm == PM_LIZARD) {
m.defensive = obj;
m.has_defense = MUSE_LIZARD_CORPSE;
return TRUE;
+ } else if (obj->otyp == TIN && obj->corpsenm == PM_LIZARD) {
+ liztin = obj;
}
}
+ /* confused or stunned monster might not be able to open tin */
+ if (liztin && mcould_eat_tin(mtmp) && rn2(3)) {
+ m.defensive = liztin;
+ /* tin and corpse ultimately end up being handled the same */
+ m.has_defense = MUSE_LIZARD_CORPSE;
+ return TRUE;
+ }
}
/* It so happens there are two unrelated cases when we might want to
boolean by_you;
{
struct obj *obj;
+ boolean tinok;
if (resists_ston(mon)) return FALSE;
if (mon->meating || !mon->mcanmove || mon->msleeping) return FALSE;
- for(obj = mon->minvent; obj; obj = obj->nobj) {
- /* Monsters can also use potions of acid */
- if ((obj->otyp == POT_ACID) || (obj->otyp == CORPSE &&
- (obj->corpsenm == PM_LIZARD || (acidic(&mons[obj->corpsenm]) && obj->corpsenm != PM_GREEN_SLIME)))) {
+ tinok = mcould_eat_tin(mon);
+ for (obj = mon->minvent; obj; obj = obj->nobj) {
+ /* monsters can also use potions of acid */
+ if (obj->otyp == POT_ACID ||
+ ((obj->otyp == CORPSE || (obj->otyp == TIN && tinok)) &&
+ obj->corpsenm == PM_LIZARD ||
+ (acidic(&mons[obj->corpsenm]) &&
+ obj->corpsenm != PM_GREEN_SLIME))) {
mon_consume_unstone(mon, obj, by_you, TRUE);
return TRUE;
}
boolean by_you;
boolean stoning;
{
- int nutrit = (obj->otyp == CORPSE) ? dog_nutrition(mon, obj) : 0;
- /* also sets meating */
+ boolean vis = canseemon(mon),
+ tinned = obj->otyp == TIN,
+ food = obj->otyp == CORPSE || tinned,
+ acid = obj->otyp == POT_ACID || (food && acidic(&mons[obj->corpsenm])),
+ lizard = food && obj->corpsenm == PM_LIZARD;
+ int nutrit = food ? dog_nutrition(mon, obj) : 0; /* also sets meating */
/* give a "<mon> is slowing down" message and also remove
intrinsic speed (comparable to similar effect on the hero) */
- mon_adjust_speed(mon, -3, (struct obj *)0);
+ if (stoning) mon_adjust_speed(mon, -3, (struct obj *)0);
- if (canseemon(mon)) {
+ if (vis) {
long save_quan = obj->quan;
obj->quan = 1L;
- pline("%s %ss %s.", Monnam(mon),
- (obj->otyp == POT_ACID) ? "quaff" : "eat",
- distant_name(obj,doname));
+ pline("%s %s %s.", Monnam(mon),
+ (obj->oclass == POTION_CLASS) ? "quaffs" :
+ (obj->otyp == TIN) ? "opens and eats the contents of" :
+ "eats",
+ distant_name(obj, doname));
obj->quan = save_quan;
} else if (!Deaf)
You_hear("%s.", (obj->otyp == POT_ACID) ? "drinking" : "chewing");
+
m_useup(mon, obj);
- if (((obj->otyp == POT_ACID) || acidic(&mons[obj->corpsenm])) &&
- !resists_acid(mon)) {
+
+ if (acid && !tinned && !resists_acid(mon)) {
mon->mhp -= rnd(15);
- pline("%s has a very bad case of stomach acid.",
- Monnam(mon));
- }
- if (mon->mhp <= 0) {
- pline("%s dies!", Monnam(mon));
- if (by_you) xkilled(mon, 0);
- else mondead(mon);
- return;
+ if (vis)
+ pline("%s has a very bad case of stomach acid.", Monnam(mon));
+ if (mon->mhp <= 0) {
+ pline("%s dies!", Monnam(mon));
+ if (by_you) xkilled(mon, 0);
+ else mondead(mon);
+ return;
+ }
}
- if (stoning && canseemon(mon)) {
+ if (stoning && vis) {
if (Hallucination)
- pline("What a pity - %s just ruined a future piece of art!",
- mon_nam(mon));
+ pline("What a pity - %s just ruined a future piece of art!",
+ mon_nam(mon));
else
pline("%s seems limber!", Monnam(mon));
}
- if (obj->otyp == CORPSE && obj->corpsenm == PM_LIZARD && mon->mconf) {
+ if (lizard && (mon->mconf || mon->mstun)) {
mon->mconf = 0;
- if (canseemon(mon))
+ mon->mstun = 0;
+ if (vis && !is_bat(mon->data) && mon->data != &mons[PM_STALKER])
pline("%s seems steadier now.", Monnam(mon));
}
if (mon->mtame && !mon->isminion && nutrit > 0) {
mon->mlstmv = monstermoves; /* it takes a turn */
}
+STATIC_OVL boolean
+mcould_eat_tin(mon)
+struct monst *mon;
+{
+ struct obj *obj, *mwep;
+
+ /* monkeys who manage to steal tins can't open and eat them
+ even if they happen to also have the appropriate tool */
+ if (is_animal(mon->data)) return FALSE;
+
+ mwep = MON_WEP(mon);
+ /* this is different from the player; tin opener or dagger doesn't
+ have to be wielded, and knife can be used instead of dagger
+ (even so, non-nymphs don't pick up tins, so only nymphs might
+ end up being able to benefit from them) */
+ for (obj = mon->minvent; obj; obj = obj->nobj) {
+ /* if stuck with a cursed weapon, don't check rest of inventory */
+ if (mwep && mwep->cursed && obj != mwep) continue;
+
+ if (obj->otyp == TIN_OPENER ||
+ (obj->oclass == WEAPON_CLASS &&
+ (objects[obj->otyp].oc_skill == P_DAGGER ||
+ objects[obj->otyp].oc_skill == P_KNIFE))) return TRUE;
+ }
+ return FALSE;
+}
+
/*muse.c*/