From: Pasi Kallinen Date: Sat, 28 Mar 2015 11:32:24 +0000 (+0200) Subject: Show legal polearm hit positions X-Git-Tag: NetHack-3.6.0_RC01~530 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2fce0074b3948aea4b2356e803d7658b44eed9fb;p=nethack Show legal polearm hit positions User can press $ to display valid positions when asked for a position to pick, and the positions will be hilighted --- diff --git a/doc/fixes35.0 b/doc/fixes35.0 index 601be2ee0..e6d5e1368 100644 --- a/doc/fixes35.0 +++ b/doc/fixes35.0 @@ -887,6 +887,7 @@ show object symbols in menu headings in menus where those object symbols act as menu accelerators, toggleable via "menu_objsyms" option show t-shirt text at end of game inventory disclose hitting with a polearm remembers the position of the last monster you hit +allow showing legal polearm positions when asked for location to hit Platform- and/or Interface-Specific Fixes diff --git a/include/extern.h b/include/extern.h index d6347207c..1cee0f651 100644 --- a/include/extern.h +++ b/include/extern.h @@ -364,6 +364,7 @@ E void NDECL(heal_legs); /* ### do_name.c ### */ E int FDECL(getpos, (coord *,BOOLEAN_P,const char *)); +E void FDECL(getpos_sethilite, (void (*f)(int) )); E void FDECL(new_mname, (struct monst *,int)); E void FDECL(free_mname, (struct monst *)); E void FDECL(new_oname, (struct obj *,int)); diff --git a/src/apply.c b/src/apply.c index 4d6899710..ae7565f17 100644 --- a/src/apply.c +++ b/src/apply.c @@ -2553,6 +2553,32 @@ int min_range, max_range; return TRUE; } +int polearm_range_min = -1; +int polearm_range_max = -1; + +void +display_polearm_positions(state) +int state; +{ + if (state == 0) { + tmp_at(DISP_BEAM, cmap_to_glyph(S_flashbeam)); + } else if (state == 1) { + int x,y, dx,dy; + for (dx = -4; dx <= 4; dx++) + for (dy = -4; dy <= 4; dy++) { + x = dx + (int)u.ux; + y = dy + (int)u.uy; + if (isok(x, y) && + distu(x, y) >= polearm_range_min && + distu(x, y) <= polearm_range_max) { + tmp_at(x, y); + } + } + } else { + tmp_at(DISP_END, 0); + } +} + /* Distance attacks by pole-weapons */ STATIC_OVL int use_pole(obj) @@ -2595,15 +2621,21 @@ use_pole(obj) else if (P_SKILL(typ) == P_SKILLED) max_range = 5; else max_range = 8; /* (P_SKILL(typ) >= P_EXPERT) */ + polearm_range_min = min_range; + polearm_range_max = max_range; + /* Prompt for a location */ pline(where_to_hit); - if (hitm && !DEADMONSTER(hitm) && cansee(hitm->mx, hitm->my)) { + cc.x = u.ux; + cc.y = u.uy; + if (!find_poleable_mon(&cc, min_range, max_range) && + hitm && !DEADMONSTER(hitm) && cansee(hitm->mx, hitm->my) && + distu(hitm->mx,hitm->my) <= max_range && + distu(hitm->mx,hitm->my) >= min_range) { cc.x = hitm->mx; cc.y = hitm->my; - } else if (!find_poleable_mon(&cc, min_range, max_range)) { - cc.x = u.ux; - cc.y = u.uy; } + getpos_sethilite(display_polearm_positions); if (getpos(&cc, TRUE, "the spot to hit") < 0) return res; /* ESC; uses turn iff polearm became wielded */ diff --git a/src/do_name.c b/src/do_name.c index 0f837c9d4..b5c2bb711 100644 --- a/src/do_name.c +++ b/src/do_name.c @@ -25,6 +25,17 @@ nextmbuf() return bufs[bufidx]; } +/* function for getpos() to highlight desired map locations. + * parameter value 0 = initialize, 1 = highlight, 2 = done + */ +void (*getpos_hilitefunc)(int) = NULL; +void +getpos_sethilite(f) +void (*f)(int); +{ + getpos_hilitefunc = f; +} + /* the response for '?' help request in getpos() */ STATIC_OVL void getpos_help(force, goal) @@ -41,6 +52,8 @@ const char *goal; putstr(tmpwin, 0, "Use [HJKL] to move the cursor 8 units at a time."); putstr(tmpwin, 0, "Or enter a background symbol (ex. <)."); putstr(tmpwin, 0, "Use @ to move the cursor on yourself."); + if (getpos_hilitefunc != NULL) + putstr(tmpwin, 0, "Use $ to display valid locations."); putstr(tmpwin, 0, "Use # to toggle automatic description."); /* disgusting hack; the alternate selection characters work for any getpos call, but they only matter for dowhatis (and doquickwhatis) */ @@ -69,6 +82,7 @@ const char *goal; boolean show_goal_msg = FALSE; static const char pick_chars[] = ".,;:"; const char *cp; + boolean hilite_state = FALSE; if (!goal) goal = "desired location"; if (flags.verbose) { @@ -92,7 +106,7 @@ const char *goal; curs(WIN_MAP, cx, cy); flush_screen(0); show_goal_msg = FALSE; - } else if (auto_msg && !msg_given) { + } else if (auto_msg && !msg_given && !hilite_state) { coord cc; int sym = 0; char tmpbuf[BUFSZ]; @@ -110,6 +124,13 @@ const char *goal; c = nh_poskey(&tx, &ty, &sidx); + if (hilite_state) { + (*getpos_hilitefunc)(2); + hilite_state = FALSE; + curs(WIN_MAP, cx, cy); + flush_screen(0); + } + if (auto_msg) msg_given = FALSE; @@ -174,6 +195,13 @@ const char *goal; /* update message window to reflect that we're still targetting */ show_goal_msg = TRUE; msg_given = TRUE; + } else if ((c == '$') && (getpos_hilitefunc != NULL)) { + if (!hilite_state) { + (*getpos_hilitefunc)(0); + (*getpos_hilitefunc)(1); + hilite_state = TRUE; + } + goto nxtc; } else if (c == '#') { auto_msg = !auto_msg; pline("Automatic description %sis %s.", @@ -269,6 +297,7 @@ const char *goal; if (msg_given) clear_nhwindow(WIN_MESSAGE); ccp->x = cx; ccp->y = cy; + getpos_hilitefunc = NULL; return result; }