Esempio n. 1
0
/**
 * Extract a direction (or zero) from a character
 */
int target_dir(struct keypress ch)
{
	return target_dir_allow(ch, FALSE);
}
Esempio n. 2
0
/**
 * 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);
}