diff --git a/doc/fixes37.0 b/doc/fixes37.0 index b74a0cae4..8618ab6dc 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -584,6 +584,9 @@ avoid "Not carrying anything. Never mind." for 'force_invmenu' 'altmeta' option could be toggled On but once On could not be toggled back Off wearing a ring of protection and any amulet behaved as if wearing an amulet of guarding when determining MC value +messaging for genetic engineer attacks had several problems +give genetic engineers teleport capability (as they had in slash'em); 'port + away after polymorphing someone so that they don't just repeat that curses: 'msg_window' option wasn't functional for curses unless the binary also included tty support diff --git a/src/mhitm.c b/src/mhitm.c index e6f990593..6c046c9c0 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -946,9 +946,11 @@ mdamagem(struct monst *magr, struct monst *mdef, int mon_poly(struct monst *magr, struct monst *mdef, int dmg) { + static const char freaky[] = " undergoes a freakish metamorphosis"; + if (mdef == &g.youmonst) { if (Antimagic) { - shieldeff(mdef->mx, mdef->my); + shieldeff(u.ux, u.uy); } else if (Unchanging) { ; /* just take a little damage */ } else { @@ -994,14 +996,27 @@ mon_poly(struct monst *magr, struct monst *mdef, int dmg) monkilled(mdef, "", AD_RBRE); } } else if (newcham(mdef, (struct permonst *) 0, FALSE, FALSE)) { - if (g.vis && canspotmon(mdef)) - pline("%s%s turns into %s.", Before, - !flags.verbose ? "" - : " undergoes a freakish metamorphosis and", - x_monnam(mdef, ARTICLE_A, (char *) 0, - (SUPPRESS_NAME | SUPPRESS_IT - | SUPPRESS_INVISIBLE), FALSE)); + if (g.vis) { /* either seen or adjacent */ + boolean was_seen = !!strcmpi("It", Before), + verbosely = flags.verbose || !was_seen; + + if (canspotmon(mdef)) + pline("%s%s%s turns into %s.", Before, + verbosely ? freaky : "", verbosely ? " and" : "", + x_monnam(mdef, ARTICLE_A, (char *) 0, + (SUPPRESS_NAME | SUPPRESS_IT + | SUPPRESS_INVISIBLE), FALSE)); + else if (was_seen || magr == &g.youmonst) + pline("%s%s%s.", Before, freaky, + !was_seen ? "" : " and disappears"); + } dmg = 0; + if (can_teleport(magr->data)) { + if (magr == &g.youmonst) + tele(); + else if (!tele_restrict(magr)) + (void) rloc(magr, TRUE); + } } else { if (g.vis && flags.verbose) pline1(nothing_happens); diff --git a/src/monst.c b/src/monst.c index b225da061..2c7cb6424 100644 --- a/src/monst.c +++ b/src/monst.c @@ -1760,7 +1760,7 @@ struct permonst _mons2[] = { A(ATTK(AT_CLAW, AD_POLY, 1, 4), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK), SIZ(WT_HUMAN, 20, MS_HUMANOID, MZ_HUMAN), MR_POISON, 0, - M1_HUMANOID | M1_OMNIVORE | M1_POIS, M2_HOSTILE | M2_NASTY, + M1_HUMANOID | M1_OMNIVORE | M1_POIS | M1_TPORT, M2_HOSTILE | M2_NASTY, M3_INFRAVISIBLE, 14, CLR_GREEN), /* * Rust monster or disenchanter diff --git a/src/uhitm.c b/src/uhitm.c index d16b41acc..ee5d3dfa0 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -3087,27 +3087,27 @@ mhitm_ad_conf(struct monst *magr, struct attack *mattk, struct monst *mdef, } void -mhitm_ad_poly(struct monst *magr, - struct attack *mattk UNUSED, /* implied */ - struct monst *mdef, - struct mhitm_data *mhm) +mhitm_ad_poly(struct monst *magr, struct attack *mattk, + struct monst *mdef, struct mhitm_data *mhm) { if (magr == &g.youmonst) { /* uhitm */ int armpro = magic_negation(mdef); - /* since hero can't be cancelled, only defender's armor applies */ - boolean negated = !(rn2(10) >= 3 * armpro); + /* require weaponless attack in order to honor AD_POLY; + since hero can't be cancelled, only defender's armor applies */ + boolean negated = uwep || !(rn2(10) >= 3 * armpro); if (!negated && mhm->damage < mdef->mhp) - mhm->damage = mon_poly(magr, mdef, mhm->damage); + mhm->damage = mon_poly(&g.youmonst, mdef, mhm->damage); } else if (mdef == &g.youmonst) { /* mhitu */ - int armpro = magic_negation(mdef); + int armpro = magic_negation(&g.youmonst); boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro); + hitmsg(magr, mattk); if (uncancelled && Maybe_Half_Phys(mhm->damage) < (Upolyd ? u.mh : u.uhp)) - mhm->damage = mon_poly(magr, mdef, mhm->damage); + mhm->damage = mon_poly(magr, &g.youmonst, mhm->damage); } else { /* mhitm */ if (!magr->mcan && mhm->damage < mdef->mhp) @@ -4414,6 +4414,9 @@ hmonas(struct monst *mon) dhit = 0, attknum = 0; int dieroll, multi_claw = 0; + /* not used here but umpteen mhitm_ad_xxxx() need this */ + g.vis = (canseemon(mon) || distu(mon->mx, mon->my) <= 2); + /* with just one touch/claw/weapon attack, both rings matter; with more than one, alternate right and left when checking whether silver ring causes successful hit */ @@ -4793,6 +4796,8 @@ hmonas(struct monst *mon) if (g.multi < 0) break; /* If paralyzed while attacking, i.e. floating eye */ } + + g.vis = FALSE; /* reset */ /* return value isn't used, but make it match hitum()'s */ return !DEADMONSTER(mon); }