diff --git a/src/mhitm.c b/src/mhitm.c index 8892c0f59..39fe251a7 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -284,6 +284,9 @@ mdisplacem( * Each successive attack has a lower probability of hitting. Some rely on * success of previous attacks. ** this doesn't seem to be implemented -dl ** * + * Attacker has targeted rather than + * mx,mdef->my>; matters for long worms. + * * In the case of exploding monsters, the monster dies as well. */ int @@ -353,7 +356,7 @@ mattackm( /* Set up the visibility of action */ gv.vis = ((cansee(magr->mx, magr->my) && canspotmon(magr)) - || (cansee(mdef->mx, mdef->my) && canspotmon(mdef))); + || (cansee(mdef->mx, mdef->my) && canspotmon(mdef))); /* Set flag indicating monster has moved this turn. Necessary since a * monster might get an attack out of sequence (i.e. before its move) in @@ -371,6 +374,12 @@ mattackm( /* Now perform all attacks for the monster. */ for (i = 0; i < NATTK; i++) { res[i] = M_ATTK_MISS; + + /* target might no longer be there */ + if (i > 0 && (m_at(gb.bhitpos.x, gb.bhitpos.y) != mdef + || DEADMONSTER(magr) || DEADMONSTER(mdef))) + continue; + mattk = getmattk(magr, mdef, i, res, &alt_attk); /* reduce verbosity for mind flayer attacking creature without a head (or worm's tail); this is similar to monster with multiple diff --git a/src/mhitu.c b/src/mhitu.c index ed0b6e098..0357915e8 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -754,6 +754,8 @@ mattacku(struct monst *mtmp) /* if hero was found but isn't anymore, avoid wildmiss now */ if (firstfoundyou && !foundyou) continue; /* set sum[i] to 'miss' but skip other actions */ + if (!u_at(gb.bhitpos.x, gb.bhitpos.y)) + continue; } mon_currwep = (struct obj *) 0; mattk = getmattk(mtmp, &gy.youmonst, i, sum, &alt_attk); diff --git a/src/uhitm.c b/src/uhitm.c index 56a4079ce..90014bcd6 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -5203,7 +5203,7 @@ mhitm_knockback( boolean u_def = (mdef == &gy.youmonst); boolean was_u = FALSE, dismount = FALSE; struct obj *wep = weapon_used ? (u_agr ? uwep : MON_WEP(magr)) - : (struct obj *)0; + : (struct obj *) 0; if (wep && is_art(wep, ART_OGRESMASHER)) chance = 2; @@ -5211,6 +5211,20 @@ mhitm_knockback( if (rn2(chance)) return FALSE; + /* only certain attacks qualify for knockback */ + if (!((mattk->adtyp == AD_PHYS) + && (mattk->aatyp == AT_CLAW + || mattk->aatyp == AT_KICK + || mattk->aatyp == AT_BUTT + || mattk->aatyp == AT_WEAP))) + return FALSE; + + /* don't knockback if attacker also wants to grab or engulf */ + if (attacktype(magr->data, AT_ENGL) + || attacktype(magr->data, AT_HUGS) + || sticks(magr->data)) + return FALSE; + /* decide where the first step will place the target; not accurate for being knocked out of saddle but doesn't need to be; used for test_move() and for message before actual hurtle */ @@ -5257,14 +5271,6 @@ mhitm_knockback( if (wep && (is_flimsy(wep) || !is_blunt_weapon(wep))) return FALSE; - /* only certain attacks qualify for knockback */ - if (!((mattk->adtyp == AD_PHYS) - && (mattk->aatyp == AT_CLAW - || mattk->aatyp == AT_KICK - || mattk->aatyp == AT_BUTT - || mattk->aatyp == AT_WEAP))) - return FALSE; - /* needs a solid physical hit */ if (unsolid(magr->data)) return FALSE; @@ -5388,6 +5394,14 @@ hmonas(struct monst *mon) for (i = 0; i < NATTK; i++) { /* sum[i] = M_ATTK_MISS; -- now done above */ + + /* target might have been knocked back so no longer in range, or an + engulfing vampshifted fog cloud killed and reverted to vampire + that's placed at another spot (hero occupies mon's first spot) */ + if (i > 0 && (m_at(gb.bhitpos.x, gb.bhitpos.y) != mon + || DEADMONSTER(mon))) + continue; + mattk = getmattk(&gy.youmonst, mon, i, sum, &alt_attk); if (gs.skipdrin && mattk->aatyp == AT_TENT && mattk->adtyp == AD_DRIN) continue;