MCPcopy Create free account
hub / github.com/NetHack/NetHack / mhitm_knockback

Function mhitm_knockback

src/uhitm.c:5246–5420  ·  view source on GitHub ↗

monster hits another monster hard enough to knock it back? */

Source from the content-addressed store, hash-verified

5244
5245/* monster hits another monster hard enough to knock it back? */
5246boolean
5247mhitm_knockback(
5248 struct monst *magr, /* attacker; might be hero */
5249 struct monst *mdef, /* defender; might be hero (only if magr isn't) */
5250 struct attack *mattk, /* attack type and damage info */
5251 int *hitflags, /* modified if magr or mdef dies */
5252 boolean weapon_used) /* True: via weapon hit */
5253{
5254 char magrbuf[BUFSZ], mdefbuf[BUFSZ];
5255 struct obj *otmp;
5256 const char *knockedhow;
5257 coordxy dx, dy, defx, defy;
5258 int knockdistance = rn2(3) ? 1 : 2; /* 67%: 1 step, 33%: 2 steps */
5259 int chance = 6; /* 1/6 chance of attack knocking back a monster */
5260 boolean u_agr = (magr == &gy.youmonst);
5261 boolean u_def = (mdef == &gy.youmonst);
5262 boolean was_u = FALSE, dismount = FALSE;
5263 struct obj *wep = weapon_used ? (u_agr ? uwep : MON_WEP(magr))
5264 : (struct obj *) 0;
5265
5266 if (wep && is_art(wep, ART_OGRESMASHER))
5267 chance = 2;
5268
5269 if (rn2(chance))
5270 return FALSE;
5271
5272 /* only certain attacks qualify for knockback */
5273 if (!((mattk->adtyp == AD_PHYS)
5274 && (mattk->aatyp == AT_CLAW
5275 || mattk->aatyp == AT_KICK
5276 || mattk->aatyp == AT_BUTT
5277 || mattk->aatyp == AT_WEAP)))
5278 return FALSE;
5279
5280 /* don't knockback if attacker also wants to grab or engulf */
5281 if (attacktype(magr->data, AT_ENGL)
5282 || attacktype(magr->data, AT_HUGS)
5283 || sticks(magr->data))
5284 return FALSE;
5285
5286 /* decide where the first step will place the target; not accurate
5287 for being knocked out of saddle but doesn't need to be; used for
5288 test_move() and for message before actual hurtle */
5289 defx = u_def ? u.ux : mdef->mx;
5290 defy = u_def ? u.uy : mdef->my;
5291 dx = sgn(defx - (u_agr ? u.ux : magr->mx));
5292 dy = sgn(defy - (u_agr ? u.uy : magr->my));
5293
5294 /* can't move most targets into or out of a doorway diagonally */
5295 if (u_def) {
5296 if (!test_move(defx, defy, dx, dy, TEST_MOVE))
5297 return FALSE;
5298 } else {
5299 /* subset of test_move() */
5300 if (!isok(defx + dx, defy + dy))
5301 return FALSE;
5302 if (IS_DOOR(levl[defx][defy].typ)
5303 && (defx - magr->mx && defy - magr->my)

Callers 4

hmon_hitmonFunction · 0.85
hmonasFunction · 0.85
mdamagemFunction · 0.85
hitmuFunction · 0.85

Calls 15

rn2Function · 0.85
is_artFunction · 0.85
attacktypeFunction · 0.85
sticksFunction · 0.85
sgnFunction · 0.85
test_moveFunction · 0.85
isokFunction · 0.85
doorless_doorFunction · 0.85
which_armorFunction · 0.85
m_is_steadfastFunction · 0.85
y_monnamFunction · 0.85
YouFunction · 0.85

Tested by

no test coverage detected