From 6d33acd2af10b9bca1cf795c55a4db49ac53e16d Mon Sep 17 00:00:00 2001 From: "nethack.rankin" Date: Sat, 5 May 2007 04:32:19 +0000 Subject: [PATCH] using #monster to breath at self (trunk only) When testing the monster-breath-at-self patch I noticed that trying to cure green slime by having hero breathe at self didn't work. The code was calling buzz() with arguments that produced an attack directed against the hero's location, but there was a chance for it to miss outright and when it didn't, reflection would block it. This makes breathing at yourself with `#monster' comparable to zapping a wand or casting a spell at yourself: it always hits. --- doc/fixes35.0 | 1 + include/extern.h | 1 + src/polyself.c | 2 ++ src/zap.c | 23 +++++++++++++++++------ 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/doc/fixes35.0 b/doc/fixes35.0 index f964901c6..a8820da66 100644 --- a/doc/fixes35.0 +++ b/doc/fixes35.0 @@ -226,6 +226,7 @@ touching a pile of objects while blind affects hero even when the pile is explosion while engulfed only affects engulfer and hero, not adjacent monsters eliminate case-sensitivity when converting words from singular to plural and vice versa, so some failing wishes like "Gauntlets of Power" now work +breath attack directed at self by poly'd hero always hits Platform- and/or Interface-Specific Fixes diff --git a/include/extern.h b/include/extern.h index 28d4acc97..bfd9aac5c 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2624,6 +2624,7 @@ E int FDECL(zappable, (struct obj *)); E void FDECL(zapnodir, (struct obj *)); E int NDECL(dozap); E int FDECL(zapyourself, (struct obj *,BOOLEAN_P)); +E void FDECL(ubreatheu, (struct attack *)); E boolean FDECL(cancel_monst, (struct monst *,struct obj *, BOOLEAN_P,BOOLEAN_P,BOOLEAN_P)); E void FDECL(weffects, (struct obj *)); diff --git a/src/polyself.c b/src/polyself.c index 7bc84c426..fe7989023 100644 --- a/src/polyself.c +++ b/src/polyself.c @@ -848,6 +848,8 @@ dobreathe() mattk = attacktype_fordmg(youmonst.data, AT_BREA, AD_ANY); if (!mattk) impossible("bad breath attack?"); /* mouthwash needed... */ + else if (!u.dx && !u.dy && !u.dz) + ubreatheu(mattk); else buzz((int) (20 + mattk->adtyp-1), (int)mattk->damn, u.ux, u.uy, u.dx, u.dy); diff --git a/src/zap.c b/src/zap.c index f4fcbc5a1..5351e9dc5 100644 --- a/src/zap.c +++ b/src/zap.c @@ -2343,6 +2343,17 @@ boolean ordinary; return(damage); } +/* called when poly'd hero uses breath attack against self */ +void +ubreatheu(mattk) +struct attack *mattk; +{ + int dtyp = 20 + mattk->adtyp - 1; /* breath by hero */ + const char *fltxt = flash_types[dtyp]; /* blast of */ + + zhitu(dtyp, mattk->damn, fltxt, u.ux, u.uy); +} + boolean flashburn(duration) long duration; @@ -3379,9 +3390,9 @@ int type, nd; const char *fltxt; xchar sx, sy; { - int dam = 0; + int dam = 0, abstyp = abs(type); - switch (abs(type) % 10) { + switch (abstyp % 10) { case ZT_MAGIC_MISSILE: if (Antimagic) { shieldeff(sx, sy); @@ -3425,7 +3436,7 @@ xchar sx, sy; } break; case ZT_DEATH: - if (abs(type) == ZT_BREATH(ZT_DEATH)) { + if (abstyp == ZT_BREATH(ZT_DEATH)) { if (Disint_resistance) { You("are not disintegrated."); break; @@ -3477,6 +3488,7 @@ xchar sx, sy; break; case ZT_ACID: if (Acid_resistance) { + pline_The("acid doesn't hurt."); dam = 0; } else { pline_The("acid burns!"); @@ -3492,9 +3504,8 @@ xchar sx, sy; break; } - if (Half_spell_damage && dam && - type < 0 && (type > -20 || type < -29)) /* !Breath */ - dam = (dam + 1) / 2; + if (dam && Half_spell_damage && abstyp >= 20 && abstyp <= 29) + dam = (dam + 1) / 2; /* half-damage for breath attack */ losehp(dam, fltxt, KILLED_BY_AN); return; }