/* * Prompts for a keypress * * The "prompt" should take the form "Command: " * * Returns TRUE unless the character is "Escape" */ bool get_com(const char *prompt, struct keypress *command) { ui_event ke; bool result; result = get_com_ex(prompt, &ke); *command = ke.key; return result; }
/** * Prompts for a keypress * * The "prompt" should take the form "Command: " * ------- * Warning - this function assumes that the entered command is an ASCII * character, and so should be used with great caution - NRM * ------- * Returns true unless the character is "Escape" */ bool textui_get_com(const char *prompt, char *command) { ui_event ke; bool result; result = get_com_ex(prompt, &ke); *command = (char)ke.key.code; return result; }
/** * Interact with specialty abilities -BR- */ void do_cmd_specialty(void) { ui_event_data answer; /* Might want to gain a new ability or browse old ones */ if (p_ptr->new_specialties > 0) { /* Buttons */ button_add("l", 'l'); button_add("v", 'v'); /* Interact and choose. */ while (get_com_ex ("View abilities or Learn specialty (l/v/ESC)?", &answer)) { /* New ability */ if ((answer.key == 'L') || (answer.key == 'l')) { gain_specialty(); break; } /* View Current */ if ((answer.key == 'V') || (answer.key == 'v')) { view_specialties(); break; } /* Exit */ else if (answer.key == ESCAPE) break; } button_kill('l'); button_kill('v'); } /* View existing specialties is the only option */ else { view_specialties(); return; } return; }
/* * Get an "aiming direction" (1,2,3,4,6,7,8,9 or 5) from the user. * * Return TRUE if a direction was chosen, otherwise return FALSE. * * The direction "5" is special, and means "use current target". * * This function tracks and uses the "global direction", and uses * that as the "desired direction", if it is set. * * Note that "Force Target", if set, will pre-empt user interaction, * if there is a usable target already set. * * Currently this function applies confusion directly. */ bool get_aim_dir(int *dp) { /* Global direction */ int dir = 0; ui_event_data ke; cptr p; /* Initialize */ (*dp) = 0; /* Hack -- auto-target if requested */ if (OPT(use_old_target) && target_okay() && !dir) dir = 5; /* Ask until satisfied */ while (!dir) { /* Choose a prompt */ if (!target_okay()) p = "Direction ('*' or <click> to target, \"'\" for closest, Escape to cancel)? "; else p = "Direction ('5' for target, '*' or <click> to re-target, Escape to cancel)? "; /* Get a command (or Cancel) */ if (!get_com_ex(p, &ke)) break; if (ke.type == EVT_MOUSE) { if (target_set_interactive (TARGET_KILL, KEY_GRID_X(ke), KEY_GRID_Y(ke))) dir = 5; } else if (ke.type == EVT_KBRD) { if (ke.key == '*') { /* Set new target, use target if legal */ if (target_set_interactive(TARGET_KILL, -1, -1)) dir = 5; } else if (ke.key == '\'') { /* Set to closest target */ if (target_set_closest(TARGET_KILL)) dir = 5; } else if (ke.key == 't' || ke.key == '5' || ke.key == '0' || ke.key == '.') { if (target_okay()) dir = 5; } else { /* Possible direction */ int keypresses_handled = 0; while (ke.key != 0) { int this_dir; /* XXX Ideally show and move the cursor here to indicate * the currently "Pending" direction. XXX */ this_dir = target_dir(ke.key); if (this_dir) dir = dir_transitions[dir][this_dir]; else break; if (lazymove_delay == 0 || ++keypresses_handled > 1) break; /* See if there's a second keypress within the defined * period of time. */ inkey_scan = lazymove_delay; ke = inkey_ex(); } } } /* Error */ if (!dir) bell("Illegal aim direction!"); } /* No direction */ if (!dir) return (FALSE); /* Save direction */ (*dp) = dir; /* Check for confusion */ if (p_ptr->timed[TMD_CONFUSED]) { /* Random direction */ dir = ddd[randint0(8)]; } /* Notice confusion */ if ((*dp) != dir) { /* Warn the user */ msg_print("You are confused."); } /* Save direction */ (*dp) = dir; /* A "valid" direction was entered */ return (TRUE); }
/* * Request a command from the user. * * Note that "caret" ("^") is treated specially, and is used to * allow manual input of control characters. This can be used * on many machines to request repeated tunneling (Ctrl-H) and * on the Macintosh to request "Control-Caret". * * Note that "backslash" is treated specially, and is used to bypass any * keymap entry for the following character. This is useful for macros. */ static ui_event textui_get_command(int *count) { int mode = OPT(rogue_like_commands) ? KEYMAP_MODE_ROGUE : KEYMAP_MODE_ORIG; struct keypress tmp[2] = { { 0 }, { 0 } }; ui_event ke = EVENT_EMPTY; const struct keypress *act = NULL; /* Get command */ while (1) { /* Hack -- no flush needed */ msg_flag = FALSE; /* Activate "command mode" */ inkey_flag = TRUE; /* Get a command */ ke = inkey_ex(); if (ke.type == EVT_KBRD) { bool keymap_ok = TRUE; switch (ke.key.code) { case '0': { int c = textui_get_count(); if (c == -1 || !get_com_ex("Command: ", &ke)) continue; else *count = c; break; } case '\\': { /* Allow keymaps to be bypassed */ (void)get_com_ex("Command: ", &ke); keymap_ok = FALSE; break; } case '^': { /* Allow "control chars" to be entered */ if (get_com("Control: ", &ke.key)) ke.key.code = KTRL(ke.key.code); break; } } /* Find any relevant keymap */ if (keymap_ok) act = keymap_find(mode, ke.key); } /* Erase the message line */ prt("", 0, 0); if (ke.type == EVT_BUTTON) { /* Buttons are always specified in standard keyset */ act = tmp; tmp[0] = ke.key; } /* Apply keymap if not inside a keymap already */ if (ke.key.code && act && !inkey_next) { size_t n = 0; while (act[n].type) n++; /* Make room for the terminator */ n += 1; /* Install the keymap */ memcpy(request_command_buffer, act, n * sizeof(struct keypress)); /* Start using the buffer */ inkey_next = request_command_buffer; /* Continue */ continue; } /* Done */ break; } return ke; }
/* * Request a command from the user. * * Note that "caret" ("^") is treated specially, and is used to * allow manual input of control characters. This can be used * on many machines to request repeated tunneling (Ctrl-H) and * on the Macintosh to request "Control-Caret". * * Note that "backslash" is treated specially, and is used to bypass any * keymap entry for the following character. This is useful for macros. */ static ui_event_data textui_get_command(void) { int mode = OPT(rogue_like_commands) ? KEYMAP_MODE_ROGUE : KEYMAP_MODE_ORIG; char tmp[2] = { '\0', '\0' }; ui_event_data ke = EVENT_EMPTY; cptr act = NULL; /* Get command */ while (1) { /* Hack -- no flush needed */ msg_flag = FALSE; /* Activate "command mode" */ inkey_flag = TRUE; /* Get a command */ ke = inkey_ex(); /* Command Count */ if (ke.key == '0') { int count = textui_get_count(); if (count == -1 || !get_com_ex("Command: ", &ke)) continue; else p_ptr->command_arg = count; } /* Allow "keymaps" to be bypassed */ else if (ke.key == '\\') { /* Get a real command */ (void)get_com("Command: ", &ke.key); /* Hack -- bypass keymaps */ if (!inkey_next) inkey_next = ""; } /* Allow "control chars" to be entered */ else if (ke.key == '^') { /* Get a new command and controlify it */ if (get_com("Control: ", &ke.key)) ke.key = KTRL(ke.key); } /* Special case for the arrow keys */ else if (isarrow(ke.key)) { switch (ke.key) { case ARROW_DOWN: ke.key = '2'; break; case ARROW_LEFT: ke.key = '4'; break; case ARROW_RIGHT: ke.key = '6'; break; case ARROW_UP: ke.key = '8'; break; } } /* Erase the message line */ prt("", 0, 0); if (ke.type == EVT_BUTTON) { /* Buttons are always specified in standard keyset */ act = tmp; tmp[0] = ke.key; } else if (ke.type == EVT_KBRD) { /* Look up applicable keymap */ act = keymap_act[mode][(byte)(ke.key)]; } /* Apply keymap if not inside a keymap already */ if (ke.key && act && !inkey_next) { /* Install the keymap */ my_strcpy(request_command_buffer, act, sizeof(request_command_buffer)); /* Start using the buffer */ inkey_next = request_command_buffer; /* Continue */ continue; } /* Done */ break; } return ke; }
int get_spell(int *sn, cptr p, cptr prompt, int *bn, bool known) { int i, num = 0; bool flag, redraw; char choice; event_type ke; char out_val[160]; int book = (*bn); int book_over = 0; int book_start = book; /* HACK -- spellcasting mode -- spell already selected */ if (spellcasting_spell > -1) { (*sn) = spellcasting_spell; spellcasting = FALSE; spellcasting_spell = -1; return (TRUE); } /* Assume no spells available */ (*sn) = -2; /* Check for available spells */ num = count_spells_in_book(book, &book_over); /* No "okay" spells */ if (!num) return (FALSE); /* Assume cancelled */ (*sn) = -1; /* Nothing chosen yet */ flag = FALSE; /* No redraw yet */ redraw = FALSE; /* Show the list */ if (auto_showlist) { /* Show list */ redraw = TRUE; /* Save the screen */ Term_save(); /* Display a list of spells */ print_spells(book); } /* Build a prompt (accept all spells) */ strnfmt(out_val, 78, "(%s %c-%c, *=List, ESC=exit) %s", p, I2A(0), I2A(num - 1), prompt); /* Get a spell from the user */ while (!flag && get_com_ex(out_val, &choice, &ke)) { /* Hack -- mouse */ if (choice == '\xff' && ke.index == 1) { choice = 'a' + ke.mousey - 2; } /* Enter by name */ if (choice == '@' || choice == '"') { int _sn, _bn; if (choice == '"') prompt_quote_hack = TRUE; /* XXX Lookup item by name */ if (get_spell_by_name(&_bn, &_sn, TRUE, FALSE, FALSE)) { book = _bn; i = _sn; flag = TRUE; } else { bell(); } continue; } /* Flip page */ if (choice == '/') { int book_new = book; int tmp = 0; /* End of list */ if (!(num = count_spells_in_book(book + book_over, &tmp))) { /* Set 0 */ book_new = book_start; tmp = 0; num = count_spells_in_book(book_new, &tmp); book_over = tmp; } /* Next book available */ else { /* Advance */ book_new = book + book_over; book_over = tmp; } /* Notice flip! */ if (book_new != book) { /* Set */ book = book_new; /* Re-Build a prompt (accept all spells) */ strnfmt(out_val, 78, "(%s %c-%c, *=List, ESC=exit) %s", p, I2A(0), I2A(num - 1), prompt); /* Must redraw list */ if (redraw) { /* Restore the screen */ Term_load(); Term_save(); /* Display a list of spells */ print_spells(book); } } /* Ask again */ continue; } /* Request redraw */ if ((choice == ' ') || (choice == '*') || (choice == '?')) { /* Show the list */ if (!redraw) { /* Show list */ redraw = TRUE; /* Save the screen */ Term_save(); /* Display a list of spells */ print_spells(book); } /* Hide the list */ else { /* Hide list */ redraw = FALSE; /* Restore the screen */ Term_load(); /* The screen is OK now */ section_icky_row = 0; section_icky_col = 0; /* Flush any events */ Flush_queue(); } /* Ask again */ continue; } /* hack for CAPITAL prayers (heal other) */ if (isupper(choice)) { i = (choice - 'A'); if (i >= num) i = -1; else if (!(spell_flag[(book * SPELLS_PER_BOOK + i)] & PY_SPELL_PROJECT)) i = -1; if (i != -1) i += SPELL_PROJECTED; } /* lowercase */ else if (islower(choice)) { i = A2I(choice); if (i >= num) i = -1; } /* not a letter */ else i = -1; /* Totally Illegal */ if (i < 0) { bell(); continue; } /* Stop the loop */ flag = TRUE; } /* Restore the screen */ if (redraw) { Term_load(); /* The screen is OK now */ section_icky_row = 0; section_icky_col = 0; /* Flush any events */ Flush_queue(); } /* Abort if needed */ if (!flag) return (FALSE); /* Save the choice */ (*sn) = i; (*bn) = book; /* Success */ return (TRUE); }
/** * Get an "aiming direction" (1,2,3,4,6,7,8,9 or 5) from the user. * * Return true if a direction was chosen, otherwise return false. * * The direction "5" is special, and means "use current target". * * This function tracks and uses the "global direction", and uses * that as the "desired direction", if it is set. * * Note that "Force Target", if set, will pre-empt user interaction, * if there is a usable target already set. */ bool textui_get_aim_dir(int *dp) { /* Global direction */ int dir = 0; ui_event ke; const char *p; /* Initialize */ (*dp) = 0; /* Hack -- auto-target if requested */ if (OPT(use_old_target) && target_okay() && !dir) dir = 5; /* Ask until satisfied */ while (!dir) { /* Choose a prompt */ if (!target_okay()) p = "Direction ('*' or <click> to target, \"'\" for closest, Escape to cancel)? "; else p = "Direction ('5' for target, '*' or <click> to re-target, Escape to cancel)? "; /* Get a command (or Cancel) */ if (!get_com_ex(p, &ke)) break; if (ke.type == EVT_MOUSE) { if (ke.mouse.button == 1) { if (target_set_interactive(TARGET_KILL, KEY_GRID_X(ke), KEY_GRID_Y(ke))) dir = 5; } else if (ke.mouse.button == 2) { break; } } else if (ke.type == EVT_KBRD) { if (ke.key.code == '*') { /* Set new target, use target if legal */ if (target_set_interactive(TARGET_KILL, -1, -1)) dir = 5; } else if (ke.key.code == '\'') { /* Set to closest target */ if (target_set_closest(TARGET_KILL)) dir = 5; } else if (ke.key.code == 't' || ke.key.code == '5' || ke.key.code == '0' || ke.key.code == '.') { if (target_okay()) dir = 5; } else { /* Possible direction */ int keypresses_handled = 0; while (ke.key.code != 0) { int this_dir; /* XXX Ideally show and move the cursor here to indicate * the currently "Pending" direction. XXX */ this_dir = target_dir(ke.key); if (this_dir) dir = dir_transitions[dir][this_dir]; else break; if (op_ptr->lazymove_delay == 0 || ++keypresses_handled > 1) break; /* See if there's a second keypress within the defined * period of time. */ inkey_scan = op_ptr->lazymove_delay; ke = inkey_ex(); } } } /* Error */ if (!dir) bell("Illegal aim direction!"); } /* No direction */ if (!dir) return (false); /* Save direction */ (*dp) = dir; /* A "valid" direction was entered */ return (true); }