Esempio n. 1
0
/* TRUE iff monster is resistant to light-induced blindness */
boolean
resists_blnd(const struct monst * mon)
{
    const struct permonst *ptr = mon->data;
    boolean is_you = (mon == &youmonst);
    struct obj *o;

    if (is_you ? Blind
        : (mon->mblinded || !mon->mcansee || !haseyes(ptr) ||
           /* BUG: temporary sleep sets mfrozen, but since paralysis does too,
              we can't check it */
           mon->msleeping))
        return TRUE;
    /* yellow light, Archon; !dust vortex, !cobra, !raven */
    if (dmgtype_fromattack(ptr, AD_BLND, AT_EXPL) ||
        dmgtype_fromattack(ptr, AD_BLND, AT_GAZE))
        return TRUE;
    o = is_you ? uwep : MON_WEP(mon);
    if (o && o->oartifact && defends(AD_BLND, o))
        return TRUE;
    o = is_you ? invent : mon->minvent;
    for (; o; o = o->nobj)
        if (o->oartifact && protects(AD_BLND, o))
            return TRUE;
    return FALSE;
}
Esempio n. 2
0
/* returns TRUE if monster can track well */
boolean can_track(const struct permonst *ptr)
{
	if (uwep && uwep->oartifact == ART_EXCALIBUR)
		return TRUE;
	else
		return (boolean)haseyes(ptr);
}
Esempio n. 3
0
boolean
inside_gas_cloud(void *p1, void *p2)
{
    struct region *reg;
    struct monst *mtmp;
    long dam;

    reg = (struct region *)p1;
    dam = (long)reg->arg;
    if (p2 == NULL) {   /* This means *YOU* Bozo! */
        if (nonliving(youmonst.data) || u.uinvulnerable)
            return FALSE;
        /* If you will unblind next turn, extend the blindness so that you do
         * not get a "You can see again!" message immediately before being
         * blinded again. */
        if (!Blind || Blinded == 1)
            make_blinded(2L, FALSE);
        if (Breathless)
            return FALSE;
        if (!Poison_resistance) {
            pline("Something is burning your %s!", makeplural(body_part(LUNG)));
            pline("You cough and spit blood!");
            losehp(rnd(dam) + 5, killer_msg(DIED, "a gas cloud"));
            return FALSE;
        } else {
            pline("You cough!");
            return FALSE;
        }
    } else {    /* A monster is inside the cloud */
        mtmp = (struct monst *)p2;

        /* Non living and non breathing monsters are not concerned */
        if (!nonliving(mtmp->data) && !breathless(mtmp->data)) {
            if (cansee(mtmp->mx, mtmp->my))
                pline("%s coughs!", Monnam(mtmp));
            setmangry(mtmp);
            if (haseyes(mtmp->data) && mtmp->mcansee) {
                mtmp->mblinded = 1;
                mtmp->mcansee = 0;
            }
            if (resists_poison(mtmp))
                return FALSE;
            mtmp->mhp -= rnd(dam) + 5;
            if (mtmp->mhp <= 0) {
                if (heros_fault(reg))
                    killed(mtmp);
                else
                    monkilled(mtmp, "gas cloud", AD_DRST);
                if (DEADMONSTER(mtmp)) {   /* not lifesaved */
                    return TRUE;
                }
            }
        }
    }
    return FALSE;       /* Monster is still alive */
}
Esempio n. 4
0
static void
chest_shatter_msg(struct obj *otmp)
{
    const char *disposition;
    const char *thing;
    long save_Blinded;

    if (otmp->oclass == POTION_CLASS) {
        pline(msgc_itemloss, "You %s %s shatter!", Blind ? "hear" : "see",
              an(bottlename()));
        if (!breathless(youmonst.data) || haseyes(youmonst.data))
            potionbreathe(&youmonst, otmp);
        return;
    }
    /* We have functions for distant and singular names, but not one
       which does _both_...
       TODO: fix this blindness kludge (it doesn't even work -- see eoto) */
    save_Blinded = property_timeout(&youmonst, BLINDED);
    set_property(&youmonst, BLINDED, 1, TRUE);
    thing = singular(otmp, xname);
    if (save_Blinded)
        set_property(&youmonst, BLINDED, save_Blinded, TRUE);

    switch (objects[otmp->otyp].oc_material) {
    case PAPER:
        disposition = "is torn to shreds";
        break;
    case WAX:
        disposition = "is crushed";
        break;
    case VEGGY:
        disposition = "is pulped";
        break;
    case FLESH:
        disposition = "is mashed";
        break;
    case GLASS:
        disposition = "shatters";
        break;
    case WOOD:
        disposition = "splinters to fragments";
        break;
    default:
        disposition = "is destroyed";
        break;
    }
    pline(msgc_itemloss, "%s %s!", An(thing), disposition);
}
Esempio n. 5
0
/* Note: may return TRUE when mdef is blind (e.g. new cream-pie attack) */
boolean
can_blnd(struct monst * magr,   /* NULL == no specific aggressor */
         struct monst * mdef, uchar aatyp, struct obj * obj)
{       /* aatyp == AT_WEAP, AT_SPIT */
    boolean is_you = (mdef == &youmonst);
    boolean check_visor = FALSE;
    struct obj *o;
    const char *s;

    /* no eyes protect against all attacks for now */
    if (!haseyes(mdef->data))
        return FALSE;

    switch (aatyp) {
    case AT_EXPL:
    case AT_BOOM:
    case AT_GAZE:
    case AT_MAGC:
    case AT_BREA:      /* assumed to be lightning */
        /* light-based attacks may be cancelled or resisted */
        if (magr && magr->mcan)
            return FALSE;
        return !resists_blnd(mdef);

    case AT_WEAP:
    case AT_SPIT:
    case AT_NONE:
        /* an object is used (thrown/spit/other) */
        if (obj && (obj->otyp == CREAM_PIE)) {
            if (is_you && Blindfolded)
                return FALSE;
        } else if (obj && (obj->otyp == BLINDING_VENOM)) {
            /* all ublindf, including LENSES, protect, cream-pies too */
            if (is_you && (ublindf || u.ucreamed))
                return FALSE;
            check_visor = TRUE;
        } else if (obj && (obj->otyp == POT_BLINDNESS)) {
            return TRUE;        /* no defense */
        } else
            return FALSE;       /* other objects cannot cause blindness yet */
        if ((magr == &youmonst) && Engulfed)
            return FALSE;       /* can't affect eyes while inside monster */
        break;

    case AT_ENGL:
        if (is_you && (Blindfolded || u_helpless(hm_asleep) || u.ucreamed))
            return FALSE;
        if (!is_you && mdef->msleeping)
            return FALSE;
        break;

    case AT_CLAW:
        /* e.g. raven: all ublindf, including LENSES, protect */
        if (is_you && ublindf)
            return FALSE;
        if ((magr == &youmonst) && Engulfed)
            return FALSE;       /* can't affect eyes while inside monster */
        check_visor = TRUE;
        break;

    case AT_TUCH:
    case AT_STNG:
        /* some physical, blind-inducing attacks can be cancelled */
        if (magr && magr->mcan)
            return FALSE;
        break;

    default:
        break;
    }

    /* check if wearing a visor (only checked if visor might help) */
    if (check_visor) {
        o = (mdef == &youmonst) ? invent : mdef->minvent;
        for (; o; o = o->nobj)
            if ((o->owornmask & W_MASK(os_armh)) &&
                (s = OBJ_DESCR(objects[o->otyp])) != NULL &&
                !strcmp(s, "visored helmet"))
                return FALSE;
    }

    return TRUE;
}
Esempio n. 6
0
int dogaze(void)
{
	struct monst *mtmp;
	int looked = 0;
	char qbuf[QBUFSZ];
	int i;
	uchar adtyp = 0;

	for (i = 0; i < NATTK; i++) {
	    if (youmonst.data->mattk[i].aatyp == AT_GAZE) {
		adtyp = youmonst.data->mattk[i].adtyp;
		break;
	    }
	}
	if (adtyp != AD_CONF && adtyp != AD_FIRE) {
	    impossible("gaze attack %d?", adtyp);
	    return 0;
	}


	if (Blind) {
	    pline("You can't see anything to gaze at.");
	    return 0;
	}
	if (u.uen < 15) {
	    pline("You lack the energy to use your special gaze!");
	    return 0;
	}
	u.uen -= 15;
	iflags.botl = 1;

	for (mtmp = level->monlist; mtmp; mtmp = mtmp->nmon) {
	    if (DEADMONSTER(mtmp)) continue;
	    if (canseemon(mtmp) && couldsee(mtmp->mx, mtmp->my)) {
		looked++;
		if (Invis && !perceives(mtmp->data))
		    pline("%s seems not to notice your gaze.", Monnam(mtmp));
		else if (mtmp->minvis && !See_invisible)
		    pline("You can't see where to gaze at %s.", Monnam(mtmp));
		else if (mtmp->m_ap_type == M_AP_FURNITURE
			|| mtmp->m_ap_type == M_AP_OBJECT) {
		    looked--;
		    continue;
		} else if (flags.safe_dog && !Confusion && !Hallucination
		  && mtmp->mtame) {
		    pline("You avoid gazing at %s.", y_monnam(mtmp));
		} else {
		    if (flags.confirm && mtmp->mpeaceful && !Confusion
							&& !Hallucination) {
			sprintf(qbuf, "Really %s %s?",
			    (adtyp == AD_CONF) ? "confuse" : "attack",
			    mon_nam(mtmp));
			if (yn(qbuf) != 'y') continue;
			setmangry(mtmp);
		    }
		    if (!mtmp->mcanmove || mtmp->mstun || mtmp->msleeping ||
				    !mtmp->mcansee || !haseyes(mtmp->data)) {
			looked--;
			continue;
		    }
		    /* No reflection check for consistency with when a monster
		     * gazes at *you*--only medusa gaze gets reflected then.
		     */
		    if (adtyp == AD_CONF) {
			if (!mtmp->mconf)
			    pline("Your gaze confuses %s!", mon_nam(mtmp));
			else
			    pline("%s is getting more and more confused.",
							Monnam(mtmp));
			mtmp->mconf = 1;
		    } else if (adtyp == AD_FIRE) {
			int dmg = dice(2,6);
			pline("You attack %s with a fiery gaze!", mon_nam(mtmp));
			if (resists_fire(mtmp)) {
			    pline("The fire doesn't burn %s!", mon_nam(mtmp));
			    dmg = 0;
			}
			if ((int) u.ulevel > rn2(20))
			    destroy_mitem(mtmp, SCROLL_CLASS, AD_FIRE);
			if ((int) u.ulevel > rn2(20))
			    destroy_mitem(mtmp, POTION_CLASS, AD_FIRE);
			if ((int) u.ulevel > rn2(25))
			    destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE);
			if (dmg && !DEADMONSTER(mtmp)) mtmp->mhp -= dmg;
			if (mtmp->mhp <= 0) killed(mtmp);
		    }
		    /* For consistency with passive() in uhitm.c, this only
		     * affects you if the monster is still alive.
		     */
		    if (!DEADMONSTER(mtmp) &&
			  (mtmp->data==&mons[PM_FLOATING_EYE]) && !mtmp->mcan) {
			if (!Free_action) {
			    pline("You are frozen by %s gaze!",
					     s_suffix(mon_nam(mtmp)));
			    nomul((u.ulevel > 6 || rn2(4)) ?
				    -dice((int)mtmp->m_lev+1,
					    (int)mtmp->data->mattk[0].damd)
				    : -200, "frozen by a monster's gaze");
			    return 1;
			} else
			    pline("You stiffen momentarily under %s gaze.",
				    s_suffix(mon_nam(mtmp)));
		    }
		    /* Technically this one shouldn't affect you at all because
		     * the Medusa gaze is an active monster attack that only
		     * works on the monster's turn, but for it to *not* have an
		     * effect would be too weird.
		     */
		    if (!DEADMONSTER(mtmp) &&
			    (mtmp->data == &mons[PM_MEDUSA]) && !mtmp->mcan) {
			pline(
			 "Gazing at the awake %s is not a very good idea.",
			    l_monnam(mtmp));
			/* as if gazing at a sleeping anything is fruitful... */
			pline("You turn to stone...");
			killer_format = KILLED_BY;
			killer = "deliberately meeting Medusa's gaze";
			done(STONING);
		    }
		}
	    }
	}
	if (!looked) pline("You gaze at no place in particular.");
	return 1;
}
Esempio n. 7
0
/* Returns an object slot mask giving all the reasons why the given
   player/monster might have the given property, limited by "reasons", an object
   slot mask (W_EQUIP, INTRINSIC, and ANY_PROPERTY are the most likely values
   here, but you can specify slots individually if you like). */
unsigned
m_has_property(const struct monst *mon, enum youprop property,
               unsigned reasons, boolean even_if_blocked)
{
    unsigned rv = 0;
    struct obj *otmp;

    /* The general case for equipment */
    rv |= mworn_extrinsic(mon, property);

    if (mon == &youmonst) {
        /* Intrinsics */
        if (u.uintrinsic[property] & TIMEOUT)
            rv |= W_MASK(os_timeout);
        rv |= u.uintrinsic[property] & (INTRINSIC | I_SPECIAL);

        /* Birth options */
        if (property == BLINDED && flags.permablind)
            rv |= W_MASK(os_birthopt);
        if (property == HALLUC && flags.permahallu)
            rv |= W_MASK(os_birthopt);
        if (property == UNCHANGING && flags.polyinit_mnum != -1)
            rv |= W_MASK(os_birthopt);

    } else {
        /* Monster tempraries are boolean flags.

           TODO: Monsters with no eyes are not considered blind. This doesn't
           make much sense. However, changing it would be a major balance
           change (due to Elbereth), and so it has been left alone for now. */
        if (property == BLINDED && (!mon->mcansee || mon->mblinded))
            rv |= W_MASK(os_timeout);
        if (property == FAST && mon->mspeed == MFAST)
            rv |= (mon->permspeed == FAST ?
                   W_MASK(os_polyform) : W_MASK(os_outside));
        if (property == INVIS && mon->perminvis && !pm_invisible(mon->data))
            rv |= W_MASK(os_outside);
        if (property == STUNNED && mon->mstun)
            rv |= W_MASK(os_timeout);
        if (property == CONFUSION && mon->mconf)
            rv |= W_MASK(os_timeout);
    }


    /* Polyform / monster intrinsic */
    /* TODO: Change the monster data code into something that doesn't require a
       giant switch statement or ternary chain to get useful information from
       it. We use a ternary chain here because it cuts down on repetitive code
       and so is easier to read. */
    if (property == FIRE_RES     ? resists_fire(mon)                     :
        property == COLD_RES     ? resists_cold(mon)                     :
        property == SLEEP_RES    ? resists_sleep(mon)                    :
        property == DISINT_RES   ? resists_disint(mon)                   :
        property == SHOCK_RES    ? resists_elec(mon)                     :
        property == POISON_RES   ? resists_poison(mon)                   :
        property == DRAIN_RES    ? resists_drli(mon)                     :
        property == SICK_RES     ? mon->data->mlet == S_FUNGUS ||
                                   mon->data == &mons[PM_GHOUL]          :
        property == ANTIMAGIC    ? resists_magm(mon)                     :
        property == ACID_RES     ? resists_acid(mon)                     :
        property == STONE_RES    ? resists_ston(mon)                     :
        property == STUNNED      ? u.umonnum == PM_STALKER ||
                                   mon->data->mlet == S_BAT              :
        property == BLINDED      ? !haseyes(mon->data)                   :
        property == HALLUC       ? Upolyd && dmgtype(mon->data, AD_HALU) :
        property == SEE_INVIS    ? perceives(mon->data)                  :
        property == TELEPAT      ? telepathic(mon->data)                 :
        property == INFRAVISION  ? infravision(mon->data)                :
        /* Note: This one assumes that there's no way to permanently turn
           visible when you're in stalker form (i.e. mummy wrappings only). */
        property == INVIS        ? pm_invisible(mon->data)               :
        property == TELEPORT     ? can_teleport(mon->data)               :
        property == LEVITATION   ? is_floater(mon->data)                 :
        property == FLYING       ? is_flyer(mon->data)                   :
        property == SWIMMING     ? is_swimmer(mon->data)                 :
        property == PASSES_WALLS ? passes_walls(mon->data)               :
        property == REGENERATION ? regenerates(mon->data)                :
        property == REFLECTING   ? mon->data == &mons[PM_SILVER_DRAGON]  :
        property == TELEPORT_CONTROL  ? control_teleport(mon->data)      :
        property == MAGICAL_BREATHING ? amphibious(mon->data)            :
        0)
        rv |= W_MASK(os_polyform);

    if (mon == &youmonst) {
        /* External circumstances */
        if (property == BLINDED && u_helpless(hm_unconscious))
            rv |= W_MASK(os_circumstance);

        /* Riding */
        if (property == FLYING && u.usteed && is_flyer(u.usteed->data))
            rv |= W_MASK(os_saddle);
        if (property == SWIMMING && u.usteed && is_swimmer(u.usteed->data))
            rv |= W_MASK(os_saddle);
    }

    /* Overrides */
    if (!even_if_blocked) {
        if (property == BLINDED) {
            for (otmp = m_minvent(mon); otmp; otmp = otmp->nobj)
                if (otmp->oartifact == ART_EYES_OF_THE_OVERWORLD &&
                    otmp->owornmask & W_MASK(os_tool))
                    rv &= (unsigned)(W_MASK(os_circumstance) |
                                     W_MASK(os_birthopt));
        }

        if (property == WWALKING && Is_waterlevel(m_mz(mon)))
            rv &= (unsigned)(W_MASK(os_birthopt));
        if (mworn_blocked(mon, property))
            rv &= (unsigned)(W_MASK(os_birthopt));
    }

    return rv & reasons;
}
Esempio n. 8
0
/*
 * Called during pet revival or pet life-saving.
 * If you killed the pet, it revives wild.
 * If you abused the pet a lot while alive, it revives wild.
 * If you abused the pet at all while alive, it revives untame.
 * If the pet wasn't abused and was very tame, it might revive tame.
 */
void
wary_dog(struct monst *mtmp, boolean was_dead)
{
    struct edog *edog;
    boolean quietly = was_dead;

    mtmp->meating = 0;
    if (!mtmp->mtame)
        return;
    edog = !mtmp->isminion ? EDOG(mtmp) : 0;

    /* if monster was starving when it died, undo that now */
    if (edog && edog->mhpmax_penalty) {
        mtmp->mhpmax += edog->mhpmax_penalty;
        mtmp->mhp += edog->mhpmax_penalty;      /* heal it */
        edog->mhpmax_penalty = 0;
    }

    if (edog && (edog->killed_by_u == 1 || edog->abuse > 2)) {
        msethostility(mtmp, TRUE, FALSE);
        if (edog->abuse >= 0 && edog->abuse < 10)
            if (!rn2_on_rng(edog->abuse + 1, rng_dog_untame))
                msethostility(mtmp, FALSE, FALSE);
        if (!quietly && cansee(mtmp->mx, mtmp->my)) {
            if (haseyes(youmonst.data)) {
                if (haseyes(mtmp->data))
                    pline("%s %s to look you in the %s.", Monnam(mtmp),
                          mtmp->mpeaceful ? "seems unable" : "refuses",
                          body_part(EYE));
                else
                    pline("%s avoids your gaze.", Monnam(mtmp));
            }
        }
    } else {
        /* chance it goes wild anyway - Pet Semetary */
        if (rn2_on_rng(mtmp->mtame, rng_dog_untame) == mtmp->mtame - 1)
            msethostility(mtmp, TRUE, FALSE);
    }
    if (!mtmp->mtame) {
        newsym(mtmp->mx, mtmp->my);
        /* a life-saved monster might be leashed; don't leave it that way if
           it's no longer tame */
        if (mtmp->mleashed)
            m_unleash(mtmp, TRUE);
    }

    /* if its still a pet, start a clean pet-slate now */
    if (edog && mtmp->mtame) {
        edog->revivals++;
        edog->killed_by_u = 0;
        edog->abuse = 0;
        if (was_dead || edog->hungrytime < moves + 500L)
            edog->hungrytime = moves + 500L;
        if (was_dead) {
            edog->droptime = 0L;
            edog->dropdist = 10000;
            edog->whistletime = 0L;
            edog->apport = 5;
        }       /* else lifesaved, so retain current values */
    }
}
Esempio n. 9
0
void
ustatusline(void)
{
    const char *info = "";

    if (Sick) {
        info = msgcat(info, ", dying from");
        if (u.usick_type & SICK_VOMITABLE)
            info = msgcat(info, " food poisoning");
        if (u.usick_type & SICK_NONVOMITABLE) {
            if (u.usick_type & SICK_VOMITABLE)
                info = msgcat(info, " and");
            info = msgcat(info, " illness");
        }
    }
    if (Stoned)
        info = msgcat(info, ", solidifying");
    if (Slimed)
        info = msgcat(info, ", becoming slimy");
    if (Strangled)
        info = msgcat(info, ", being strangled");
    if (Vomiting)
        info = msgcat(info, ", nauseated");    /* !"nauseous" */
    if (Confusion)
        info = msgcat(info, ", confused");
    if (Blind) {
        info = msgcat(info, ", blind");
        if (u.ucreamed) {
            if ((long)u.ucreamed < Blinded || Blindfolded ||
                !haseyes(youmonst.data))
                info = msgcat(info, ", cover");
            info = msgcat(info, "ed by sticky goop");
        }       /* note: "goop" == "glop"; variation is intentional */
    }
    if (Stunned)
        info = msgcat(info, ", stunned");
    if (!u.usteed && Wounded_legs) {
        const char *what = body_part(LEG);

        if (LWounded_legs && RWounded_legs)
            what = makeplural(what);
        info = msgcat_many(info, ", injured ", what, NULL);
    }
    if (Glib)
        info = msgcat_many(info, ", slippery ",
                           makeplural(body_part(HAND)), NULL);
    if (u.utrap)
        info = msgcat(info, ", trapped");
    if (Fast)
        info = msgcat(info, Very_fast ? ", very fast" : ", fast");
    if (u.uundetected)
        info = msgcat(info, ", concealed");
    if (Invis)
        info = msgcat(info, ", invisible");
    if (u.ustuck) {
        if (sticks(youmonst.data))
            info = msgcat(info, ", holding ");
        else
            info = msgcat(info, ", held by ");
        info = msgcat(info, mon_nam(u.ustuck));
    }

    pline("Status of %s (%s%s):  Level %d  HP %d(%d)  Def %d%s.", u.uplname,
          (u.ualign.record >= 20) ? "piously " :
          (u.ualign.record > 13) ? "devoutly " :
          (u.ualign.record > 8) ? "fervently " :
          (u.ualign.record > 3) ? "stridently " :
          (u.ualign.record == 3) ? "" :
          (u.ualign.record >= 1) ? "haltingly " :
          (u.ualign.record == 0) ? "nominally " : "insufficiently ",
          align_str(u.ualign.type), Upolyd ? mons[u.umonnum].mlevel : u.ulevel,
          Upolyd ? u.mh : u.uhp, Upolyd ? u.mhmax : u.uhpmax,
          10 - get_player_ac(), info);
}
Esempio n. 10
0
int dogaze(void) {
        struct monst *mtmp;
        int looked = 0;
        char qbuf[QBUFSZ];
        int i;
        unsigned char adtyp = 0;

        for (i = 0; i < NATTK; i++) {
            if(youmonst.data->mattk[i].aatyp == AT_GAZE) {
                adtyp = youmonst.data->mattk[i].adtyp;
                break;
            }
        }
        if (adtyp != AD_CONF && adtyp != AD_FIRE) {
            impossible("gaze attack %d?", adtyp);
            return 0;
        }


        if (Blind()) {
            You_cant("see anything to gaze at.");
            return 0;
        }
        if (u.uen < 15) {
            You("lack the energy to use your special gaze!");
            return(0);
        }
        u.uen -= 15;

        for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
            if (DEADMONSTER(mtmp)) continue;
            if (canseemon(mtmp) && couldsee(mtmp->mx, mtmp->my)) {
                looked++;
                if (Invis && !perceives(mtmp->data)) {
                    message_monster(MSG_M_SEEMS_NOT_NOTICE_GAZE, mtmp);
                } else if (mtmp->minvis && !See_invisible()) {
                    message_monster(MSG_YOU_CANT_SEE_WHERE_GAZE_M, mtmp);
                } else if (mtmp->m_ap_type == M_AP_FURNITURE || mtmp->m_ap_type == M_AP_OBJECT) {
                    looked--;
                    continue;
                } else if (flags.safe_dog && !Confusion() && !Hallucination() && mtmp->mtame) {
                    message_monster(MSG_YOU_AVOID_GAZING_AT_M, mtmp);
                } else {
                    if (flags.confirm && mtmp->mpeaceful && !Confusion()
                                                        && !Hallucination()) {
                        sprintf(qbuf, "Really %s %s?",
                            (adtyp == AD_CONF) ? "confuse" : "attack", "TODO: mon_nam(mtmp)");
                        if (yn(qbuf) != 'y') continue;
                        setmangry(mtmp);
                    }
                    if (!mtmp->mcanmove || mtmp->mstun || mtmp->msleeping ||
                                    !mtmp->mcansee || !haseyes(mtmp->data))
                    {
                        looked--;
                        continue;
                    }
                    /* No reflection check for consistency with when a monster
                     * gazes at *you*--only medusa gaze gets reflected then.
                     */
                    if (adtyp == AD_CONF) {
                        if (!mtmp->mconf) {
                            message_monster(MSG_GAZE_CONFUSES_M, mtmp);
                        } else {
                            message_monster(MSG_M_GETTING_MORE_CONFUSED, mtmp);
                        }
                        mtmp->mconf = 1;
                    } else if (adtyp == AD_FIRE) {
                        int dmg = d(2,6);
                        message_monster(MSG_ATTACK_M_WITH_FIERY_GAZE, mtmp);
                        if (resists_fire(mtmp)) {
                            message_monster(MSG_FIRE_DOES_NOT_BURN_M, mtmp);
                            dmg = 0;
                        }
                        if((int) u.ulevel > rn2(20))
                            (void) destroy_mitem(mtmp, SCROLL_CLASS, AD_FIRE);
                        if((int) u.ulevel > rn2(20))
                            (void) destroy_mitem(mtmp, POTION_CLASS, AD_FIRE);
                        if((int) u.ulevel > rn2(25))
                            (void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE);
                        if (dmg && !DEADMONSTER(mtmp)) mtmp->mhp -= dmg;
                        if (mtmp->mhp <= 0) killed(mtmp);
                    }
                    /* For consistency with passive() in uhitm.c, this only
                     * affects you if the monster is still alive.
                     */
                    if (!DEADMONSTER(mtmp) &&
                          (mtmp->data==&mons[PM_FLOATING_EYE]) && !mtmp->mcan) {
                        if (!Free_action) {
                            message_monster(MSG_YOU_ARE_FROZEN_BY_M_GAZE, mtmp);
                            nomul((u.ulevel > 6 || rn2(4)) ?
                                    -d((int)mtmp->m_lev+1,
                                            (int)mtmp->data->mattk[0].damd)
                                    : -200);
                            return 1;
                        } else {
                            message_monster(MSG_STIFFEN_MOMENTARILY_UNDER_M_GAZE, mtmp);
                        }
                    }
                    /* Technically this one shouldn't affect you at all because
                     * the Medusa gaze is an active monster attack that only
                     * works on the monster's turn, but for it to *not* have an
                     * effect would be too weird.
                     */
                    if (!DEADMONSTER(mtmp) && (mtmp->data == &mons[PM_MEDUSA]) && !mtmp->mcan) {
                        message_monster(MSG_GAZING_AT_AWAKE_MEDUSA_BAD_IDEA, mtmp);
                        /* as if gazing at a sleeping anything is fruitful... */
                        You("turn to stone...");
                        killer = killed_by_const(KM_DELIBERATELY_MEETING_MEDUSA_GAZE);
                        done(KM_STONING);
                    }
                }
            }
        }
        if (!looked) You("gaze at no place in particular.");
        return 1;
}