/** * Extract a direction (or zero) from a character */ int target_dir(struct keypress ch) { return target_dir_allow(ch, FALSE); }
/** * Request a "movement" direction (1,2,3,4,6,7,8,9) from the user. * * Return true if a direction was chosen, otherwise return false. * * This function should be used for all "repeatable" commands, such as * run, walk, open, close, bash, disarm, spike, tunnel, etc, as well * as all commands which must reference a grid adjacent to the player, * and which may not reference the grid under the player. * * Directions "5" and "0" are illegal and will not be accepted. * * This function tracks and uses the "global direction", and uses * that as the "desired direction", if it is set. */ bool textui_get_rep_dir(int *dp, bool allow_5) { int dir = 0; ui_event ke; /* Initialize */ (*dp) = 0; /* Get a direction */ while (!dir) { /* Paranoia*/ event_signal(EVENT_MESSAGE_FLUSH); /* Get first keypress - the first test is to avoid displaying the * prompt for direction if there's already a keypress queued up * and waiting - this just avoids a flickering prompt if there is * a "lazy" movement delay. */ inkey_scan = SCAN_INSTANT; ke = inkey_ex(); inkey_scan = SCAN_OFF; if (ke.type == EVT_NONE || (ke.type == EVT_KBRD && target_dir(ke.key) == 0)) { prt("Direction or <click> (Escape to cancel)? ", 0, 0); ke = inkey_ex(); } /* Check mouse coordinates, or get keypresses until a dir is chosen */ if (ke.type == EVT_MOUSE) { if (ke.mouse.button == 1) { int y = KEY_GRID_Y(ke); int x = KEY_GRID_X(ke); struct loc from = loc(player->px, player->py); struct loc to = loc(x, y); dir = pathfind_direction_to(from, to); } else if (ke.mouse.button == 2) { /* Clear the prompt */ prt("", 0, 0); return (false); } } else if (ke.type == EVT_KBRD) { int keypresses_handled = 0; while (ke.type == EVT_KBRD && ke.key.code != 0) { int this_dir; if (ke.key.code == ESCAPE) { /* Clear the prompt */ prt("", 0, 0); return (false); } /* XXX Ideally show and move the cursor here to indicate the currently "Pending" direction. XXX */ this_dir = target_dir_allow(ke.key, allow_5); if (this_dir) dir = dir_transitions[dir][this_dir]; if (op_ptr->lazymove_delay == 0 || ++keypresses_handled > 1) break; inkey_scan = op_ptr->lazymove_delay; ke = inkey_ex(); } /* 5 is equivalent to "escape" */ if (dir == 5 && !allow_5) { /* Clear the prompt */ prt("", 0, 0); return (false); } } /* Oops */ if (!dir) bell("Illegal repeatable direction!"); } /* Clear the prompt */ prt("", 0, 0); /* Save direction */ (*dp) = dir; /* Success */ return (true); }