register struct monst *mtmp;
register struct attack *mattk;
{
+ static const char * const reactions[] = {
+ "confused", /* [0] */
+ "stunned", /* [1] */
+ "puzzled", "dazzled", /* [2,3] */
+ "irritated", "inflamed", /* [4,5] */
+ "tired", /* [6] */
+ "dulled", /* [7] */
+ };
+ int react = -1;
+ boolean cancelled = (mtmp->mcan != 0), already = FALSE;
+
+ /* assumes that hero has to see monster's gaze in order to be
+ affected, rather than monster just having to look at hero;
+ when hallucinating, hero's brain doesn't register what
+ it's seeing correctly so the gaze is usually ineffective
+ [this could be taken a lot farther and select a gaze effect
+ appropriate to what's currently being displayed, giving
+ ordinary monsters a gaze attack when hero thinks he or she
+ is facing a gazing creature, but let's not go that far...] */
+ if (Hallucination && rn2(4)) cancelled = TRUE;
+
switch(mattk->adtyp) {
- case AD_STON:
- if (mtmp->mcan || !mtmp->mcansee) {
+ case AD_STON:
+ if (cancelled || !mtmp->mcansee) {
if (!canseemon(mtmp)) break; /* silently */
pline("%s %s.", Monnam(mtmp),
(mtmp->data == &mons[PM_MEDUSA] && mtmp->mcan) ?
"doesn't look all that ugly" :
"gazes ineffectually");
break;
- }
- if (Reflecting && couldsee(mtmp->mx, mtmp->my) &&
+ }
+ if (Reflecting && couldsee(mtmp->mx, mtmp->my) &&
mtmp->data == &mons[PM_MEDUSA]) {
/* hero has line of sight to Medusa and she's not blind */
boolean useeit = canseemon(mtmp);
if (mtmp->mhp > 0) break;
return 2;
- }
- if (canseemon(mtmp) && couldsee(mtmp->mx, mtmp->my) &&
+ }
+ if (canseemon(mtmp) && couldsee(mtmp->mx, mtmp->my) &&
!Stone_resistance) {
You("meet %s gaze.", s_suffix(mon_nam(mtmp)));
stop_occupation();
killer.format = KILLED_BY;
Strcpy(killer.name, mtmp->data->mname);
done(STONING);
- }
- break;
- case AD_CONF:
- if(!mtmp->mcan && canseemon(mtmp) &&
- couldsee(mtmp->mx, mtmp->my) &&
+ }
+ break;
+ case AD_CONF:
+ if (canseemon(mtmp) && couldsee(mtmp->mx, mtmp->my) &&
mtmp->mcansee && !mtmp->mspec_used && rn2(5)) {
+ if (cancelled) {
+ react = 0; /* "confused" */
+ already = (mtmp->mconf != 0);
+ } else {
int conf = d(3,4);
mtmp->mspec_used = mtmp->mspec_used + (conf + rn2(6));
make_confused(HConfusion + conf, FALSE);
stop_occupation();
}
- break;
- case AD_STUN:
- if(!mtmp->mcan && canseemon(mtmp) &&
- couldsee(mtmp->mx, mtmp->my) &&
+ }
+ break;
+ case AD_STUN:
+ if (canseemon(mtmp) && couldsee(mtmp->mx, mtmp->my) &&
mtmp->mcansee && !mtmp->mspec_used && rn2(5)) {
+ if (cancelled) {
+ react = 1; /* "stunned" */
+ already = (mtmp->mstun != 0);
+ } else {
int stun = d(2,6);
mtmp->mspec_used = mtmp->mspec_used + (stun + rn2(6));
make_stunned(HStun + stun, TRUE);
stop_occupation();
}
- break;
- case AD_BLND:
- if (!mtmp->mcan && canseemon(mtmp) && !resists_blnd(&youmonst)
- && distu(mtmp->mx,mtmp->my) <= BOLT_LIM*BOLT_LIM) {
+ }
+ break;
+ case AD_BLND:
+ if (canseemon(mtmp) && !resists_blnd(&youmonst) &&
+ distu(mtmp->mx,mtmp->my) <= BOLT_LIM*BOLT_LIM) {
+ if (cancelled) {
+ react = rn1(2,2); /* "puzzled" || "dazzled" */
+ already = (mtmp->mcansee == 0);
+ /* Archons gaze every round; we don't want cancelled ones
+ giving the "seems puzzled/dazzled" message that often */
+ if (mtmp->mcan && mtmp->data == &mons[PM_ARCHON] && rn2(5))
+ react = -1;
+ } else {
int blnd = d((int)mattk->damn, (int)mattk->damd);
You("are blinded by %s radiance!",
if (!Blind) Your(vision_clears);
else make_stunned((long)d(1,3),TRUE);
}
- break;
- case AD_FIRE:
- if (!mtmp->mcan && canseemon(mtmp) &&
- couldsee(mtmp->mx, mtmp->my) &&
+ }
+ break;
+ case AD_FIRE:
+ if (canseemon(mtmp) && couldsee(mtmp->mx, mtmp->my) &&
mtmp->mcansee && !mtmp->mspec_used && rn2(5)) {
- int dmg = d(2,6);
+ if (cancelled) {
+ react = rn1(2,4); /* "irritated" || "inflamed" */
+ } else {
+ int dmg = d(2,6), lev = (int)mtmp->m_lev;
pline("%s attacks you with a fiery gaze!", Monnam(mtmp));
stop_occupation();
dmg = 0;
}
burn_away_slime();
- if ((int) mtmp->m_lev > rn2(20))
- destroy_item(SCROLL_CLASS, AD_FIRE);
- if ((int) mtmp->m_lev > rn2(20))
- destroy_item(POTION_CLASS, AD_FIRE);
- if ((int) mtmp->m_lev > rn2(25))
- destroy_item(SPBOOK_CLASS, AD_FIRE);
+ if (lev > rn2(20)) destroy_item(SCROLL_CLASS, AD_FIRE);
+ if (lev > rn2(20)) destroy_item(POTION_CLASS, AD_FIRE);
+ if (lev > rn2(25)) destroy_item(SPBOOK_CLASS, AD_FIRE);
if (dmg) mdamageu(mtmp, dmg);
}
- break;
+ }
+ break;
#ifdef PM_BEHOLDER /* work in progress */
- case AD_SLEE:
- if(!mtmp->mcan && canseemon(mtmp) &&
- couldsee(mtmp->mx, mtmp->my) && mtmp->mcansee &&
- multi >= 0 && !rn2(5) && !Sleep_resistance) {
-
+ case AD_SLEE:
+ if (canseemon(mtmp) && couldsee(mtmp->mx, mtmp->my) &&
+ mtmp->mcansee && multi >= 0 && !rn2(5) && !Sleep_resistance) {
+ if (cancelled) {
+ react = 6; /* "tired" */
+ already = (mtmp->mfrozen != 0); /* can't happen... */
+ } else {
fall_asleep(-rnd(10), TRUE);
pline("%s gaze makes you very sleepy...",
s_suffix(Monnam(mtmp)));
}
- break;
- case AD_SLOW:
- if(!mtmp->mcan && canseemon(mtmp) && mtmp->mcansee &&
- (HFast & (INTRINSIC|TIMEOUT)) &&
- !defends(AD_SLOW, uwep) && !rn2(4))
-
+ }
+ break;
+ case AD_SLOW:
+ if (canseemon(mtmp) && couldsee(mtmp->mx, mtmp->my) &&
+ mtmp->mcansee && (HFast & (INTRINSIC|TIMEOUT)) &&
+ !defends(AD_SLOW, uwep) && !rn2(4)) {
+ if (cancelled) {
+ react = 7; /* "dulled" */
+ already = (mtmp->mspeed == MSLOW);
+ } else {
u_slow_down();
stop_occupation();
- break;
-#endif
- default: impossible("Gaze attack %d?", mattk->adtyp);
- break;
+ }
+ }
+ break;
+#endif /* BEHOLDER */
+ default:
+ impossible("Gaze attack %d?", mattk->adtyp);
+ break;
+ }
+ if (react >= 0) {
+ if (Hallucination && rn2(3)) react = rn2(SIZE(reactions));
+ /* cancelled/hallucinatory feedback; monster might look "confused",
+ "stunned",&c but we don't actually set corresponding attribute */
+ pline("%s looks %s%s.", Monnam(mtmp),
+ !rn2(3) ? "" : already ? "quite " :
+ (!rn2(2) ? "a bit " : "somewhat "),
+ reactions[react]);
}
return(0);
}
return 0;
}
-
if (Blind) {
You_cant("see anything to gaze at.");
return 0;
+ } else if (Hallucination) {
+ You_cant("gaze at anything you can see.");
+ return 0;
}
if (u.uen < 15) {
You("lack the energy to use your special gaze!");
|| mtmp->m_ap_type == M_AP_OBJECT) {
looked--;
continue;
- } else if (flags.safe_dog && !Confusion && !Hallucination
- && mtmp->mtame) {
+ } else if (flags.safe_dog && mtmp->mtame && !Confusion) {
You("avoid gazing at %s.", y_monnam(mtmp));
} else {
- if (flags.confirm && mtmp->mpeaceful && !Confusion
- && !Hallucination) {
+ if (flags.confirm && mtmp->mpeaceful && !Confusion) {
Sprintf(qbuf, "Really %s %s?",
(adtyp == AD_CONF) ? "confuse" : "attack",
mon_nam(mtmp));
Monnam(mtmp));
mtmp->mconf = 1;
} else if (adtyp == AD_FIRE) {
- int dmg = d(2,6);
+ int dmg = d(2,6), lev = (int)u.ulevel;
+
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))
+ if (lev > rn2(20))
(void) destroy_mitem(mtmp, SCROLL_CLASS, AD_FIRE);
- if((int) u.ulevel > rn2(20))
+ if (lev > rn2(20))
(void) destroy_mitem(mtmp, POTION_CLASS, AD_FIRE);
- if((int) u.ulevel > rn2(25))
+ if (lev > rn2(25))
(void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE);
- if (dmg && !DEADMONSTER(mtmp)) mtmp->mhp -= dmg;
+ if (dmg) 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 (DEADMONSTER(mtmp)) continue;
+
+ if (mtmp->data == &mons[PM_FLOATING_EYE] && !mtmp->mcan) {
if (!Free_action) {
You("are frozen by %s gaze!",
s_suffix(mon_nam(mtmp)));
* 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) {
+ if (mtmp->data == &mons[PM_MEDUSA] && !mtmp->mcan) {
pline(
"Gazing at the awake %s is not a very good idea.",
l_monnam(mtmp));