]> granicus.if.org Git - nethack/commitdiff
Show legal polearm hit positions
authorPasi Kallinen <paxed@alt.org>
Sat, 28 Mar 2015 11:32:24 +0000 (13:32 +0200)
committerPasi Kallinen <paxed@alt.org>
Sat, 28 Mar 2015 11:32:24 +0000 (13:32 +0200)
User can press $ to display valid positions when asked
for a position to pick, and the positions will be hilighted

doc/fixes35.0
include/extern.h
src/apply.c
src/do_name.c

index 601be2ee0a73416697b1ff787a28dcfa3dcc24ee..e6d5e13686761e3af7d12af29d397b89246a8d82 100644 (file)
@@ -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
index d6347207c4b317125e672986499c72d328326714..1cee0f651dfd9c63ab068b1e67bea8b0cb9f8a3f 100644 (file)
@@ -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));
index 4d689971007e6b4e54e25a36ef7f6368e148dffe..ae7565f17b9b6ff61b8c226e542bb2a3b422066c 100644 (file)
@@ -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 */
 
index 0f837c9d49080f2e2ed3a316226f711f27de091d..b5c2bb71101cfbca308a3d9ee12449f5e33f2333 100644 (file)
@@ -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;
 }