in src/dokick.c [20:123]
STATIC_DCL boolean FDECL(maybe_kick_monster, (struct monst *,
XCHAR_P, XCHAR_P));
STATIC_DCL void FDECL(kick_monster, (struct monst *, XCHAR_P, XCHAR_P));
STATIC_DCL int FDECL(kick_object, (XCHAR_P, XCHAR_P, char *));
STATIC_DCL int FDECL(really_kick_object, (XCHAR_P, XCHAR_P));
STATIC_DCL char *FDECL(kickstr, (char *, const char *));
STATIC_DCL void FDECL(otransit_msg, (struct obj *, BOOLEAN_P, long));
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)
struct monst *mon;
boolean clumsy;
{
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)
dmg += 5;
/* excessive wt affects dex, so it affects dmg */
if (clumsy)
dmg /= 2;
/* kicking a dragon or an elephant will not harm it */
if (thick_skinned(mon->data))
dmg = 0;
/* attacking a shade is normally useless */
if (mon->data == &mons[PM_SHADE])
dmg = 0;
specialdmg = special_dmgval(&youmonst, mon, W_ARMF, (long *) 0);
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 */
return;
}
if (M_AP_TYPE(mon))
seemimic(mon);
check_caitiff(mon);
/* squeeze some guilt feelings... */
if (mon->mtame) {
abuse_dog(mon);
if (mon->mtame)
monflee(mon, (dmg ? rnd(dmg) : 1), FALSE, FALSE);
else
mon->mflee = 0;
}
if (dmg > 0) {
/* convert potential damage to actual damage */
dmg = rnd(dmg);
if (martial()) {
if (dmg > 1)
kick_skill = P_MARTIAL_ARTS;
dmg += rn2(ACURR(A_DEX) / 2 + 1);
}
/* a good kick exercises your dex */
exercise(A_DEX, TRUE);
}
dmg += specialdmg; /* for blessed (or hypothetically, silver) boots */
if (uarmf)
dmg += uarmf->spe;
dmg += u.udaminc; /* add ring(s) of increase damage */
if (dmg > 0)
mon->mhp -= dmg;
if (!DEADMONSTER(mon) && martial() && !bigmonst(mon->data) && !rn2(3)
&& mon->mcanmove && mon != u.ustuck && !mon->mtrapped) {
/* see if the monster has a place to move into */
mdx = mon->mx + u.dx;
mdy = mon->my + u.dy;
if (goodpos(mdx, mdy, mon, 0)) {
pline("%s reels from the blow.", Monnam(mon));
if (m_in_out_region(mon, mdx, mdy)) {
remove_monster(mon->mx, mon->my);
newsym(mon->mx, mon->my);
place_monster(mon, mdx, mdy);
newsym(mon->mx, mon->my);
set_apparxy(mon);
if (mintrap(mon) == 2)
trapkilled = TRUE;
}
}
}
(void) passive(mon, uarmf, TRUE, !DEADMONSTER(mon), AT_KICK, FALSE);
if (DEADMONSTER(mon) && !trapkilled)
killed(mon);
/* may bring up a dialog, so put this after all messages */
if (kick_skill != P_NONE) /* exercise proficiency */
use_skill(kick_skill, 1);
}