fix #H6422 - hmonas against shades
I did much of this quite some time ago, as prequisite for a different bug report about monsters vs shades, then set it aside. It ended up being more complicated than I anticipated. When deciding whether various non-weapon attacks might hit a shade, hmonas() was not checking for blessed or silver armor that should have been applicable. It did check boots when kicking, but not gloves or rings (when no gloves) when touching, or outermost of cloak/suit/shirt when hugging, or helmet when head-butting. (The last one is actually moot because nothing with a head-butt attack is able to wear a helm.) The problem was more general than just whether attacks might hit and hurt shades. Various undead and/or demons are also affected by blessed and/or silver attack but weren't for non-weapon attacks by poly'd hero. At least two unrelated bugs are fixed: a rope golem's AT_HUGS attack gives feedback about choking but was fully effective against monsters which fail the can_be_strangled() test. And it was possible to hug a long worm's tail, rendering the entire worm immobile. The report also suggested that all artifacts be able to hit shades for full effect, but by the time shades are encountered everyone has an artifact so that would nullify a shade's most interesting ability. TODO: monster against hero and monster against other monster need to have similar changes.
This commit is contained in:
35
src/dokick.c
35
src/dokick.c
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 dokick.c $NHDT-Date: 1547086527 2019/01/10 02:15:27 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.129 $ */
|
||||
/* NetHack 3.6 dokick.c $NHDT-Date: 1548209738 2019/01/23 02:15:38 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.130 $ */
|
||||
/* Copyright (c) Izchak Miller, Mike Stephenson, Steve Linhart, 1989. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -28,15 +28,15 @@ STATIC_DCL void FDECL(drop_to, (coord *, SCHAR_P));
|
||||
|
||||
static const char kick_passes_thru[] = "kick passes harmlessly through";
|
||||
|
||||
/* kicking damage when not poly'd into a form with a kick attack */
|
||||
STATIC_OVL void
|
||||
kickdmg(mon, clumsy)
|
||||
register struct monst *mon;
|
||||
register boolean clumsy;
|
||||
struct monst *mon;
|
||||
boolean clumsy;
|
||||
{
|
||||
register int mdx, mdy;
|
||||
register int dmg = (ACURRSTR + ACURR(A_DEX) + ACURR(A_CON)) / 15;
|
||||
int kick_skill = P_NONE;
|
||||
int blessed_foot_damage = 0;
|
||||
int mdx, mdy;
|
||||
int dmg = (ACURRSTR + ACURR(A_DEX) + ACURR(A_CON)) / 15;
|
||||
int specialdmg, kick_skill = P_NONE;
|
||||
boolean trapkilled = FALSE;
|
||||
|
||||
if (uarmf && uarmf->otyp == KICKING_BOOTS)
|
||||
@@ -50,15 +50,13 @@ register boolean clumsy;
|
||||
if (thick_skinned(mon->data))
|
||||
dmg = 0;
|
||||
|
||||
/* attacking a shade is useless */
|
||||
/* attacking a shade is normally useless */
|
||||
if (mon->data == &mons[PM_SHADE])
|
||||
dmg = 0;
|
||||
|
||||
if ((is_undead(mon->data) || is_demon(mon->data) || is_vampshifter(mon))
|
||||
&& uarmf && uarmf->blessed)
|
||||
blessed_foot_damage = 1;
|
||||
specialdmg = special_dmgval(&youmonst, mon, W_ARMF, (long *) 0);
|
||||
|
||||
if (mon->data == &mons[PM_SHADE] && !blessed_foot_damage) {
|
||||
if (mon->data == &mons[PM_SHADE] && !specialdmg) {
|
||||
pline_The("%s.", kick_passes_thru);
|
||||
/* doesn't exercise skill or abuse alignment or frighten pet,
|
||||
and shades have no passive counterattack */
|
||||
@@ -90,8 +88,7 @@ register boolean clumsy;
|
||||
/* a good kick exercises your dex */
|
||||
exercise(A_DEX, TRUE);
|
||||
}
|
||||
if (blessed_foot_damage)
|
||||
dmg += rnd(4);
|
||||
dmg += specialdmg; /* for blessed (or hypothetically, silver) boots */
|
||||
if (uarmf)
|
||||
dmg += uarmf->spe;
|
||||
dmg += u.udaminc; /* add ring(s) of increase damage */
|
||||
@@ -189,7 +186,7 @@ xchar x, y;
|
||||
*/
|
||||
if (Upolyd && attacktype(youmonst.data, AT_KICK)) {
|
||||
struct attack *uattk;
|
||||
int sum, kickdieroll, armorpenalty,
|
||||
int sum, kickdieroll, armorpenalty, specialdmg,
|
||||
attknum = 0,
|
||||
tmp = find_roll_to_hit(mon, AT_KICK, (struct obj *) 0, &attknum,
|
||||
&armorpenalty);
|
||||
@@ -205,14 +202,16 @@ xchar x, y;
|
||||
if (uattk->aatyp != AT_KICK)
|
||||
continue;
|
||||
|
||||
if (mon->data == &mons[PM_SHADE] && (!uarmf || !uarmf->blessed)) {
|
||||
kickdieroll = rnd(20);
|
||||
specialdmg = special_dmgval(&youmonst, mon, W_ARMF, (long *) 0);
|
||||
if (mon->data == &mons[PM_SHADE] && !specialdmg) {
|
||||
/* doesn't matter whether it would have hit or missed,
|
||||
and shades have no passive counterattack */
|
||||
Your("%s %s.", kick_passes_thru, mon_nam(mon));
|
||||
break; /* skip any additional kicks */
|
||||
} else if (tmp > (kickdieroll = rnd(20))) {
|
||||
} else if (tmp > kickdieroll) {
|
||||
You("kick %s.", mon_nam(mon));
|
||||
sum = damageum(mon, uattk);
|
||||
sum = damageum(mon, uattk, specialdmg);
|
||||
(void) passive(mon, uarmf, (boolean) (sum > 0),
|
||||
(sum != 2), AT_KICK, FALSE);
|
||||
if (sum == 2)
|
||||
|
||||
Reference in New Issue
Block a user