-/* SCCS Id: @(#)apply.c 3.5 2008/10/14 */
+/* SCCS Id: @(#)apply.c 3.5 2009/02/21 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
}
if (!getdir((char *)0)) return res;
- if (Stunned || (Confusion && !rn2(5))) confdir();
- rx = u.ux + u.dx;
- ry = u.uy + u.dy;
- mtmp = m_at(rx, ry);
+ if (u.uswallow) {
+ mtmp = u.ustuck;
+ rx = mtmp->mx;
+ ry = mtmp->my;
+ } else {
+ if (Stunned || (Confusion && !rn2(5))) confdir();
+ rx = u.ux + u.dx;
+ ry = u.uy + u.dy;
+ if (!isok(rx, ry)) {
+ You("miss.");
+ return res;
+ }
+ mtmp = m_at(rx, ry);
+ }
/* fake some proficiency checks */
proficient = 0;
use_pole(obj)
struct obj *obj;
{
- int res = 0, typ, max_range = 4, min_range = 4;
+ int res = 0, typ, max_range, min_range, glyph;
coord cc;
struct monst *mtmp;
-
/* Are you allowed to use the pole? */
if (u.uswallow) {
pline(not_enough_room);
cc.x = u.ux;
cc.y = u.uy;
if (getpos(&cc, TRUE, "the spot to hit") < 0)
- return 0; /* user pressed ESC */
+ return res; /* ESC; uses turn iff polearm became wielded */
- /* Calculate range */
+ glyph = glyph_at(cc.x, cc.y);
+ /*
+ * Calculate allowable range (pole's reach is always 2 steps):
+ * unskilled and basic: orthogonal direction, 4..4;
+ * skilled: as basic, plus knight's jump position, 4..5;
+ * expert: as skilled, plus diagonal, 4..8.
+ * ...9...
+ * .85458.
+ * .52125.
+ * 9410149
+ * .52125.
+ * .85458.
+ * ...9...
+ * (Note: no roles in nethack can become expert or better
+ * for polearm skill; Yeoman in slash'em can become expert.)
+ */
+ min_range = 4;
typ = uwep_skill_type();
if (typ == P_NONE || P_SKILL(typ) <= P_BASIC) max_range = 4;
else if (P_SKILL(typ) == P_SKILLED) max_range = 5;
- else max_range = 8;
+ else max_range = 8; /* (P_SKILL(typ) >= P_EXPERT) */
if (distu(cc.x, cc.y) > max_range) {
pline("Too far!");
return (res);
pline("Too close!");
return (res);
} else if (!cansee(cc.x, cc.y) &&
- ((mtmp = m_at(cc.x, cc.y)) == (struct monst *)0 ||
- !canseemon(mtmp))) {
+ !glyph_is_monster(glyph) &&
+ !glyph_is_invisible(glyph) &&
+ !glyph_is_statue(glyph)) {
You(cant_see_spot);
return (res);
} else if (!couldsee(cc.x, cc.y)) { /* Eyes of the Overworld */
}
/* Attack the monster there */
- if ((mtmp = m_at(cc.x, cc.y)) != (struct monst *)0) {
- bhitpos = cc;
+ bhitpos = cc;
+ if ((mtmp = m_at(bhitpos.x, bhitpos.y)) != (struct monst *)0) {
if (attack_checks(mtmp, uwep)) return res;
check_caitiff(mtmp);
+ notonhead = (bhitpos.x != mtmp->mx || bhitpos.y != mtmp->my);
(void) thitmonst(mtmp, uwep);
- } else
- /* Now you know that nothing is there... */
- pline(nothing_happens);
+ } else if (glyph_is_statue(glyph) && /* might be hallucinatory */
+ sobj_at(STATUE, bhitpos.x, bhitpos.y)) {
+ struct trap *t = t_at(bhitpos.x, bhitpos.y);
+
+ if (t && t->ttyp == STATUE_TRAP &&
+ activate_statue_trap(t, t->tx, t->ty, FALSE)) {
+ ; /* feedback has been give by animate_statue() */
+ } else {
+ /* Since statues look like monsters now, we say something
+ different from "you miss" or "there's nobody there".
+ Note: we only do this when a statue is displayed here,
+ because the player is probably attempting to attack it;
+ other statues obscured by anything are just ignored. */
+ pline("Thump! Your blow bounces harmlessly off the statue.");
+ wake_nearto(bhitpos.x, bhitpos.y, 25);
+ }
+ } else {
+ /* no monster here and no statue seen or remembered here */
+ if (glyph_is_invisible(glyph)) {
+ /* now you know that nothing is there... */
+ unmap_object(bhitpos.x, bhitpos.y);
+ newsym(bhitpos.x, bhitpos.y);
+ }
+ You("miss; there is no one there to hit.");
+ }
+ u_wipe_engr(2); /* same as for melee or throwing */
return (1);
}
}
STATIC_OVL int
-use_grapple (obj)
+use_grapple(obj)
struct obj *obj;
{
int res = 0, typ, max_range = 4, tohit;
cc.x = u.ux;
cc.y = u.uy;
if (getpos(&cc, TRUE, "the spot to hit") < 0)
- return 0; /* user pressed ESC */
+ return res; /* ESC; uses turn iff grapnel became wielded */
- /* Calculate range */
+ /* Calculate range; unlike use_pole(), there's no minimum for range */
typ = uwep_skill_type();
if (typ == P_NONE || P_SKILL(typ) <= P_BASIC) max_range = 4;
else if (P_SKILL(typ) == P_SKILLED) max_range = 5;
destroy_nhwindow(tmpwin);
}
+ /* possibly scuff engraving at your feet;
+ any engraving at the target location is unaffected */
+ if (tohit == 2 || !rn2(2)) u_wipe_engr(rnd(2));
+
/* What did you hit? */
switch (tohit) {
case 0: /* Trap */
case 2: /* Monster */
bhitpos = cc;
if ((mtmp = m_at(cc.x, cc.y)) == (struct monst *)0) break;
+ notonhead = (bhitpos.x != mtmp->mx || bhitpos.y != mtmp->my);
save_confirm = flags.confirm;
if (verysmall(mtmp->data) && !rn2(4) &&
enexto(&cc, u.ux, u.uy, (struct permonst *)0)) {
-/* SCCS Id: @(#)uhitm.c 3.5 2007/12/19 */
+/* SCCS Id: @(#)uhitm.c 3.5 2009/02/21 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
* not stay there, so the player will have suddenly forgotten
* the square's contents for no apparent reason.
if (!canspotmon(mtmp) &&
- !glyph_is_invisible(levl[u.ux+u.dx][u.uy+u.dy].glyph))
- map_invisible(u.ux+u.dx, u.uy+u.dy);
+ !glyph_is_invisible(levl[bhitpos.x][bhitpos.y].glyph))
+ map_invisible(bhitpos.x, bhitpos.y);
*/
return FALSE;
}
* the screen, so you know something is there.
*/
if (!canspotmon(mtmp) &&
- !glyph_is_warning(glyph_at(u.ux+u.dx,u.uy+u.dy)) &&
- !glyph_is_invisible(levl[u.ux+u.dx][u.uy+u.dy].glyph) &&
+ !glyph_is_warning(glyph_at(bhitpos.x,bhitpos.y)) &&
+ !glyph_is_invisible(levl[bhitpos.x][bhitpos.y].glyph) &&
!(!Blind && mtmp->mundetected && hides_under(mtmp->data))) {
pline("Wait! There's %s there you can't see!",
something);
- map_invisible(u.ux+u.dx, u.uy+u.dy);
+ map_invisible(bhitpos.x, bhitpos.y);
/* if it was an invisible mimic, treat it as if we stumbled
* onto a visible mimic
*/
if (mtmp->m_ap_type && !Protection_from_shape_changers &&
!sensemon(mtmp) &&
- !glyph_is_warning(glyph_at(u.ux+u.dx,u.uy+u.dy))) {
+ !glyph_is_warning(glyph_at(bhitpos.x,bhitpos.y))) {
/* If a hidden mimic was in a square where a player remembers
* some (probably different) unseen monster, the player is in
* luck--he attacks it even though it's hidden.
}
if (mtmp->mundetected && !canseemon(mtmp) &&
- !glyph_is_warning(glyph_at(u.ux+u.dx,u.uy+u.dy)) &&
+ !glyph_is_warning(glyph_at(bhitpos.x,bhitpos.y)) &&
(hides_under(mtmp->data) || mtmp->data->mlet == S_EEL)) {
mtmp->mundetected = mtmp->msleeping = 0;
newsym(mtmp->mx, mtmp->my);
/* possibly set in attack_checks;
examined in known_hitum, called via hitum or hmonas below */
override_confirmation = FALSE;
+ /* attack_checks() used to use <u.ux+u.dx,u.uy+u.dy> directly, now
+ it uses bhitpos instead; it might map an invisible monster there */
+ bhitpos.x = u.ux + u.dx;
+ bhitpos.y = u.uy + u.dy;
if (attack_checks(mtmp, uwep)) return(TRUE);
if (Upolyd) {