/* * 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 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 (target_set_interactive (TARGET_KILL, KEY_GRID_X(ke), KEY_GRID_Y(ke))) dir = 5; } 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 (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("You are confused."); } /* Save direction */ (*dp) = dir; /* A "valid" direction was entered */ return (TRUE); }
/* * Let the user select an item, save its "index" * * Return TRUE only if an acceptable item was chosen by the user. * * The selected item must satisfy the "item_tester_hook()" function, * if that hook is set, and the "item_tester_tval", if that value is set. * * All "item_tester" restrictions are cleared before this function returns. * * The user is allowed to choose acceptable items from the equipment, * inventory, or floor, respectively, if the proper flag was given, * and there are any acceptable items in that location. * * The equipment or inventory are displayed (even if no acceptable * items are in that location) if the proper flag was given. * * If there are no acceptable items available anywhere, and "str" is * not NULL, then it will be used as the text of a warning message * before the function returns. * * Note that the user must press "-" to specify the item on the floor, * and there is no way to "examine" the item on the floor, while the * use of "capital" letters will "examine" an inventory/equipment item, * and prompt for its use. * * If a legal item is selected from the inventory, we save it in "cp" * directly (0 to 35), and return TRUE. * * If a legal item is selected from the floor, we save it in "cp" as * a negative (-1 to -511), and return TRUE. * * If no item is available, we do nothing to "cp", and we display a * warning message, using "str" if available, and return FALSE. * * If no item is selected, we do nothing to "cp", and return FALSE. * * Global "p_ptr->command_wrk" is used to choose between equip/inven/floor * listings. It is equal to USE_INVEN or USE_EQUIP or USE_FLOOR, except * when this function is first called, when it is equal to zero, which will * cause it to be set to USE_INVEN. * * We always erase the prompt when we are done, leaving a blank line, * or a warning message, if appropriate, if no items are available. * * Note that only "acceptable" floor objects get indexes, so between two * commands, the indexes of floor objects may change. XXX XXX XXX */ bool get_item(int *cp, cptr pmt, cptr str, cmd_code cmd, int mode) { int py = p_ptr->py; int px = p_ptr->px; unsigned char cmdkey = cmd_lookup_key(cmd); ui_event_data which; int j, k; int i1, i2; int e1, e2; int f1, f2; bool done, item; bool oops = FALSE; bool use_inven = ((mode & USE_INVEN) ? TRUE : FALSE); bool use_equip = ((mode & USE_EQUIP) ? TRUE : FALSE); bool use_floor = ((mode & USE_FLOOR) ? TRUE : FALSE); bool use_quiver = ((mode & QUIVER_TAGS) ? TRUE : FALSE); bool is_harmless = ((mode & IS_HARMLESS) ? TRUE : FALSE); bool quiver_tags = ((mode & QUIVER_TAGS) ? TRUE : FALSE); olist_detail_t olist_mode = 0; bool allow_inven = FALSE; bool allow_equip = FALSE; bool allow_floor = FALSE; bool toggle = FALSE; char tmp_val[160]; char out_val[160]; int floor_list[MAX_FLOOR_STACK]; int floor_num; bool show_list = TRUE; /* Object list display modes */ if (mode & SHOW_FAIL) olist_mode |= (OLIST_FAIL); else olist_mode |= (OLIST_WEIGHT); if (mode & SHOW_PRICES) olist_mode |= (OLIST_PRICE); /* Paranoia XXX XXX XXX */ message_flush(); /* Not done */ done = FALSE; /* No item selected */ item = FALSE; /* Full inventory */ i1 = 0; i2 = INVEN_PACK - 1; /* Forbid inventory */ if (!use_inven) i2 = -1; /* Restrict inventory indexes */ while ((i1 <= i2) && (!get_item_okay(i1))) i1++; while ((i1 <= i2) && (!get_item_okay(i2))) i2--; /* Accept inventory */ if (i1 <= i2) allow_inven = TRUE; /* Full equipment */ e1 = INVEN_WIELD; e2 = ALL_INVEN_TOTAL - 1; /* Forbid equipment */ if (!use_equip) e2 = -1; /* Restrict equipment indexes */ while ((e1 <= e2) && (!get_item_okay(e1))) e1++; while ((e1 <= e2) && (!get_item_okay(e2))) e2--; /* Accept equipment */ if (e1 <= e2) allow_equip = TRUE; /* Scan all non-gold objects in the grid */ floor_num = scan_floor(floor_list, N_ELEMENTS(floor_list), py, px, 0x03); /* Full floor */ f1 = 0; f2 = floor_num - 1; /* Forbid floor */ if (!use_floor) f2 = -1; /* Restrict floor indexes */ while ((f1 <= f2) && (!get_item_okay(0 - floor_list[f1]))) f1++; while ((f1 <= f2) && (!get_item_okay(0 - floor_list[f2]))) f2--; /* Accept floor */ if (f1 <= f2) allow_floor = TRUE; /* Require at least one legal choice */ if (!allow_inven && !allow_equip && !allow_floor) { /* Oops */ oops = TRUE; done = TRUE; } /* Analyze choices */ else { /* Hack -- Start on equipment if requested */ if ((p_ptr->command_wrk == USE_EQUIP) && use_equip) p_ptr->command_wrk = USE_EQUIP; /* If we are using the quiver then start on equipment */ else if (use_quiver) p_ptr->command_wrk = USE_EQUIP; /* Use inventory if allowed */ else if (use_inven) p_ptr->command_wrk = USE_INVEN; /* Use equipment if allowed */ else if (use_equip) p_ptr->command_wrk = USE_EQUIP; /* Use floor if allowed */ else if (use_floor) p_ptr->command_wrk = USE_FLOOR; /* Hack -- Use (empty) inventory */ else p_ptr->command_wrk = USE_INVEN; } /* Start out in "display" mode */ if (show_list) { /* Save screen */ screen_save(); } /* Repeat until done */ while (!done) { int ni = 0; int ne = 0; /* Scan windows */ for (j = 0; j < REPOSBAND_TERM_MAX; j++) { /* Unused */ if (!reposband_term[j]) continue; /* Count windows displaying inven */ if (op_ptr->window_flag[j] & (PW_INVEN)) ni++; /* Count windows displaying equip */ if (op_ptr->window_flag[j] & (PW_EQUIP)) ne++; } /* Toggle if needed */ if (((p_ptr->command_wrk == USE_EQUIP) && ni && !ne) || ((p_ptr->command_wrk == USE_INVEN) && !ni && ne)) { /* Toggle */ toggle_inven_equip(); /* Track toggles */ toggle = !toggle; } /* Redraw */ p_ptr->redraw |= (PR_INVEN | PR_EQUIP); /* Redraw windows */ redraw_stuff(); /* Viewing inventory */ if (p_ptr->command_wrk == USE_INVEN) { /* Redraw if needed */ if (show_list) show_inven(olist_mode); /* Begin the prompt */ strnfmt(out_val, sizeof(out_val), "Inven:"); /* List choices */ if (i1 <= i2) { /* Build the prompt */ strnfmt(tmp_val, sizeof(tmp_val), " %c-%c,", index_to_label(i1), index_to_label(i2)); /* Append */ my_strcat(out_val, tmp_val, sizeof(out_val)); } /* Indicate ability to "view" */ if (!show_list) { my_strcat(out_val, " * to see,", sizeof(out_val)); button_add("[*]", '*'); } /* Indicate legality of "toggle" */ if (use_equip) { my_strcat(out_val, " / for Equip,", sizeof(out_val)); button_add("[/]", '/'); } /* Indicate legality of the "floor" */ if (allow_floor) { my_strcat(out_val, " - for floor,", sizeof(out_val)); button_add("[-]", '-'); } } /* Viewing equipment */ else if (p_ptr->command_wrk == USE_EQUIP) { /* Redraw if needed */ if (show_list) show_equip(olist_mode); /* Begin the prompt */ strnfmt(out_val, sizeof(out_val), "Equip:"); /* List choices */ if (e1 <= e2) { /* Build the prompt */ strnfmt(tmp_val, sizeof(tmp_val), " %c-%c,", index_to_label(e1), index_to_label(e2)); /* Append */ my_strcat(out_val, tmp_val, sizeof(out_val)); } /* Indicate ability to "view" */ if (!show_list) { my_strcat(out_val, " * to see,", sizeof(out_val)); button_add("[*]", '*'); } /* Indicate legality of "toggle" */ if (use_inven) { my_strcat(out_val, " / for Inven,", sizeof(out_val)); button_add("[/]", '/'); } /* Indicate legality of the "floor" */ if (allow_floor) { my_strcat(out_val, " - for floor,", sizeof(out_val)); button_add("[!]", '!'); } } /* Viewing floor */ else { /* Redraw if needed */ if (show_list) show_floor(floor_list, floor_num, olist_mode); /* Begin the prompt */ strnfmt(out_val, sizeof(out_val), "Floor:"); /* List choices */ if (f1 <= f2) { /* Build the prompt */ strnfmt(tmp_val, sizeof(tmp_val), " %c-%c,", I2A(f1), I2A(f2)); /* Append */ my_strcat(out_val, tmp_val, sizeof(out_val)); } /* Indicate ability to "view" */ if (!show_list) { my_strcat(out_val, " * to see,", sizeof(out_val)); button_add("[*]", '*'); } /* Append */ if (use_inven) { my_strcat(out_val, " / for Inven,", sizeof(out_val)); button_add("[/]", '/'); } /* Append */ else if (use_equip) { my_strcat(out_val, " / for Equip,", sizeof(out_val)); button_add("[/]", '/'); } } redraw_stuff(); /* Finish the prompt */ my_strcat(out_val, " ESC", sizeof(out_val)); /* Build the prompt */ strnfmt(tmp_val, sizeof(tmp_val), "(%s) %s", out_val, pmt); /* Show the prompt */ prt(tmp_val, 0, 0); /* Get a key */ which = inkey_ex(); /* Parse it */ switch (which.key) { case ESCAPE: { done = TRUE; break; } case '/': { /* Toggle to inventory */ if (use_inven && (p_ptr->command_wrk != USE_INVEN)) { p_ptr->command_wrk = USE_INVEN; } /* Toggle to equipment */ else if (use_equip && (p_ptr->command_wrk != USE_EQUIP)) { p_ptr->command_wrk = USE_EQUIP; } /* No toggle allowed */ else { bell("Cannot switch item selector!"); break; } /* Hack -- Fix screen */ if (show_list) { /* Load screen */ screen_load(); /* Save screen */ screen_save(); } /* Need to redraw */ break; } case '-': { /* Paranoia */ if (!allow_floor) { bell("Cannot select floor!"); break; } /* There is only one item */ if (floor_num == 1) { /* Auto-select */ if (p_ptr->command_wrk == (USE_FLOOR)) { /* Special index */ k = 0 - floor_list[0]; /* Allow player to "refuse" certain actions */ if (!get_item_allow(k, cmdkey, is_harmless)) { done = TRUE; break; } /* Accept that choice */ (*cp) = k; item = TRUE; done = TRUE; break; } } /* Hack -- Fix screen */ if (show_list) { /* Load screen */ screen_load(); /* Save screen */ screen_save(); } p_ptr->command_wrk = (USE_FLOOR); #if 0 /* Check each legal object */ for (i = 0; i < floor_num; ++i) { /* Special index */ k = 0 - floor_list[i]; /* Skip non-okay objects */ if (!get_item_okay(k)) continue; /* Allow player to "refuse" certain actions */ if (!get_item_allow(k, cmdkey, is_harmless)) continue; /* Accept that choice */ (*cp) = k; item = TRUE; done = TRUE; break; } #endif break; } case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { /* Look up the tag */ if (!get_tag(&k, which.key, cmd, quiver_tags)) { bell("Illegal object choice (tag)!"); break; } /* Hack -- Validate the item */ if ((k < INVEN_WIELD) ? !allow_inven : !allow_equip) { bell("Illegal object choice (tag)!"); break; } /* Validate the item */ if (!get_item_okay(k)) { bell("Illegal object choice (tag)!"); break; } /* Allow player to "refuse" certain actions */ if (!get_item_allow(k, cmdkey, is_harmless)) { done = TRUE; break; } /* Accept that choice */ (*cp) = k; item = TRUE; done = TRUE; break; } case '\n': case '\r': { /* Choose "default" inventory item */ if (p_ptr->command_wrk == USE_INVEN) { if (i1 != i2) { bell("Illegal object choice (default)!"); break; } k = i1; } /* Choose the "default" slot (0) of the quiver */ else if (quiver_tags) k = e1; /* Choose "default" equipment item */ else if (p_ptr->command_wrk == USE_EQUIP) { if (e1 != e2) { bell("Illegal object choice (default)!"); break; } k = e1; } /* Choose "default" floor item */ else { if (f1 != f2) { bell("Illegal object choice (default)!"); break; } k = 0 - floor_list[f1]; } /* Validate the item */ if (!get_item_okay(k)) { bell("Illegal object choice (default)!"); break; } /* Allow player to "refuse" certain actions */ if (!get_item_allow(k, cmdkey, is_harmless)) { done = TRUE; break; } /* Accept that choice */ (*cp) = k; item = TRUE; done = TRUE; break; } default: { bool verify; /* Note verify */ verify = (isupper((unsigned char)which.key) ? TRUE : FALSE); /* Lowercase */ which.key = tolower((unsigned char)which.key); /* Convert letter to inventory index */ if (p_ptr->command_wrk == USE_INVEN) { k = label_to_inven(which.key); if (k < 0) { bell("Illegal object choice (inven)!"); break; } } /* Convert letter to equipment index */ else if (p_ptr->command_wrk == USE_EQUIP) { k = label_to_equip(which.key); if (k < 0) { bell("Illegal object choice (equip)!"); break; } } /* Convert letter to floor index */ else { k = (islower((unsigned char)which.key) ? A2I(which.key) : -1); if (k < 0 || k >= floor_num) { bell("Illegal object choice (floor)!"); break; } /* Special index */ k = 0 - floor_list[k]; } /* Validate the item */ if (!get_item_okay(k)) { bell("Illegal object choice (normal)!"); break; } /* Verify the item */ if (verify && !verify_item("Try", k)) { done = TRUE; break; } /* Allow player to "refuse" certain actions */ if (!get_item_allow(k, cmdkey, is_harmless)) { done = TRUE; break; } /* Accept that choice */ (*cp) = k; item = TRUE; done = TRUE; break; } } } /* Fix the screen if necessary */ if (show_list) { /* Load screen */ screen_load(); /* Hack -- Cancel "display" */ show_list = FALSE; } /* Kill buttons */ button_kill('*'); button_kill('/'); button_kill('-'); button_kill('!'); redraw_stuff(); /* Forget the item_tester_tval restriction */ item_tester_tval = 0; /* Forget the item_tester_hook restriction */ item_tester_hook = NULL; /* Toggle again if needed */ if (toggle) toggle_inven_equip(); /* Update */ p_ptr->redraw |= (PR_INVEN | PR_EQUIP); redraw_stuff(); /* Clear the prompt line */ prt("", 0, 0); /* Warning if needed */ if (oops && str) msg_print(str); /* Result */ return (item); }
/* * 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; }
static enum birth_stage roller_command(bool first_call) { char prompt[80] = ""; size_t promptlen = 0; ui_event_data ke; char ch; enum birth_stage next = BIRTH_ROLLER; /* Used to keep track of whether we've rolled a character before or not. */ static bool prev_roll = FALSE; /* Display the player - a bit cheaty, but never mind. */ display_player(0, TRUE); if (first_call) prev_roll = FALSE; /* Add buttons */ button_kill_all(); button_add("[ESCAPE]", ESCAPE); button_add("[ACCEPT]", '\r'); button_add("[REROLL]", 'r'); if (prev_roll) button_add("[PREV]", 'p'); button_add("[HELP]", '?'); button_add("[QUIT]", '\x18'); /* CTRL-X */ clear_from(Term->hgt - 2); handle_stuff(); event_signal(EVENT_MOUSEBUTTONS); /* Prepare a prompt (must squeeze everything in) */ strnfcat(prompt, sizeof (prompt), &promptlen, "['r' to reroll"); if (prev_roll) strnfcat(prompt, sizeof(prompt), &promptlen, ", 'p' for prev"); strnfcat(prompt, sizeof (prompt), &promptlen, " or 'Enter' to accept]"); /* Prompt for it */ prt(prompt, Term->hgt - (mouse_buttons ? 2 : 1), Term->wid / 2 - promptlen / 2); /* Prompt and get a command */ ke = inkey_ex(); ch = ke.key; if (ch == ESCAPE) { button_kill('r'); button_kill('p'); next = BIRTH_BACK; } /* 'Enter' accepts the roll */ if ((ch == '\r') || (ch == '\n')) { next = BIRTH_NAME_CHOICE; } /* Reroll this character */ else if ((ch == ' ') || (ch == 'r')) { cmd_insert(CMD_ROLL_STATS); prev_roll = TRUE; } /* Previous character */ else if (prev_roll && (ch == 'p')) { cmd_insert(CMD_PREV_STATS); } /* Quit */ else if (ch == KTRL('X')) { cmd_insert(CMD_QUIT); next = BIRTH_COMPLETE; } /* Help XXX */ else if (ch == '?') { do_cmd_help(); } /* Nothing handled directly here */ else { bell("Illegal roller command!"); } /* Kill buttons */ button_kill_all(); handle_stuff(); event_signal(EVENT_MOUSEBUTTONS); return next; }
static enum birth_stage point_based_command(void) { static int stat = 0; char ch; enum birth_stage next = BIRTH_POINTBASED; ui_event_data ke; /* Add buttons */ button_kill_all(); button_add("[ESCAPE]", ESCAPE); button_add("[ACCEPT]", '\r'); button_add("[RESET STATS]", 'r'); button_add("[UP]", '8'); button_add("[DOWN]", '2'); button_add("[DEC_STAT]", '4'); button_add("[INC_STAT]", '6'); button_add("[QUIT]", '\x18'); /* CTRL-X */ clear_from(Term->hgt - 2); handle_stuff(); event_signal(EVENT_MOUSEBUTTONS); /* point_based_display();*/ /* Place cursor just after cost of current stat */ Term_gotoxy(COSTS_COL + 4, COSTS_ROW + stat); /* Get key */ /* Prompt and get a command */ ke = inkey_ex(); ch = ke.key; if (ch == KTRL('X')) { cmd_insert(CMD_QUIT); next = BIRTH_COMPLETE; } /* Go back a step, or back to the start of this step */ else if (ch == ESCAPE) { next = BIRTH_BACK; } else if (ch == 'r' || ch == 'R') { cmd_insert(CMD_RESET_STATS, FALSE); } /* Done */ else if ((ch == '\r') || (ch == '\n')) { next = BIRTH_NAME_CHOICE; } else { ch = target_dir(ch); /* Prev stat, looping round to the bottom when going off the top */ if (ch == 8) stat = (stat + A_MAX - 1) % A_MAX; /* Next stat, looping round to the top when going off the bottom */ if (ch == 2) stat = (stat + 1) % A_MAX; /* Decrease stat (if possible) */ if (ch == 4) { cmd_insert(CMD_SELL_STAT, stat); } /* Increase stat (if possible) */ if (ch == 6) { cmd_insert(CMD_BUY_STAT, stat); } } button_kill_all(); event_signal(EVENT_MOUSEBUTTONS); return next; }
/** * Show previous messages to the user * * The screen format uses line 0 and 23 for headers and prompts, * skips line 1 and 22, and uses line 2 thru 21 for old messages. * * This command shows you which commands you are viewing, and allows * you to "search" for strings in the recall. * * Note that messages may be longer than 80 characters, but they are * displayed using "infinite" length, with a special sub-command to * "slide" the virtual display to the left or right. * * Attempt to only hilight the matching portions of the string. */ void do_cmd_messages(void) { ui_event ke; int i, j, n, q; int wid, hgt; char shower[80]; char finder[80]; char p[80]; /* Wipe finder */ my_strcpy(finder, "", sizeof(shower)); /* Wipe shower */ my_strcpy(shower, "", sizeof(finder)); /* Total messages */ n = messages_num(); /* Start on first message */ i = 0; /* Start at leftmost edge */ q = 0; /* Get size */ Term_get_size(&wid, &hgt); /* Prompt */ strncpy(p, "[Press 'p' for older, 'n' for newer, ..., or ESCAPE]", 80); /* Save screen */ screen_save(); /* Adjust the buttons */ button_backup_all(); button_kill_all(); button_add("ESC", ESCAPE); button_add("-", '-'); button_add("=", '='); button_add("/", '/'); button_add("p", 'p'); button_add("n", 'n'); button_add("+", '+'); button_add("->", '6'); button_add("<-", '4'); p_ptr->redraw |= (PR_BUTTONS); /* Process requests until done */ while (1) { /* Clear screen */ Term_clear(); /* Dump messages */ for (j = 0; (j < hgt - 4) && (i + j < n); j++) { const char *msg = message_str((s16b)(i+j)); byte attr = message_color((s16b)(i+j)); /* Apply horizontal scroll */ msg = ((int)strlen(msg) >= q) ? (msg + q) : ""; /* Dump the messages, bottom to top */ Term_putstr(0, hgt - 3 - j, -1, attr, msg); /* Hilight "shower" */ if (shower[0]) { const char *str = msg; /* Display matches */ while ((str = strstr(str, shower)) != NULL) { int len = strlen(shower); /* Display the match */ Term_putstr(str-msg, hgt - 3 - j, len, TERM_YELLOW, shower); /* Advance */ str += len; } } } /* Display header XXX XXX XXX */ prt(format("Message Recall (%d-%d of %d), Offset %d", i, i + j - 1, n, q), 0, 0); /* Display prompt (not very informative) */ prt(p, hgt - 1, 0); redraw_stuff(p_ptr); /* Get a command */ ke = inkey_ex(); /* Exit on Escape */ if (ke.key.code == ESCAPE) break; /* Hack -- Save the old index */ j = i; /* Horizontal scroll */ if (ke.key.code == '4') { /* Scroll left */ q = (q >= wid / 2) ? (q - wid / 2) : 0; /* Success */ continue; } /* Horizontal scroll */ if (ke.key.code == '6') { /* Scroll right */ q = q + wid / 2; /* Success */ continue; } /* Hack -- handle show */ if (ke.key.code == '=') { /* Prompt */ prt("Show: ", hgt - 1, 0); /* Get a "shower" string, or continue */ if (!askfor_aux(shower, sizeof shower, NULL)) continue; /* Okay */ continue; } /* Hack -- handle find */ if (ke.key.code == '/') { s16b z; /* Prompt */ prt("Find: ", hgt - 1, 0); /* Get a "finder" string, or continue */ if (!askfor_aux(finder, sizeof finder, NULL)) continue; /* Show it */ my_strcpy(shower, finder, sizeof(shower)); /* Scan messages */ for (z = i + 1; z < n; z++) { const char *msg = message_str(z); /* Search for it */ if (strstr(msg, finder)) { /* New location */ i = z; /* Done */ break; } } } /* Recall 20 older messages */ if ((ke.key.code == 'p') || (ke.key.code == KTRL('P')) || (ke.key.code == ' ')) { /* Go older if legal */ if (i + 20 < n) i += 20; } /* Recall 10 older messages */ if (ke.key.code == '+') { /* Go older if legal */ if (i + 10 < n) i += 10; } /* Recall 1 older message */ if ((ke.key.code == '8') || (ke.key.code == '\n') || (ke.key.code == '\r')) { /* Go older if legal */ if (i + 1 < n) i += 1; } /* Recall 20 newer messages */ if ((ke.key.code == 'n') || (ke.key.code == KTRL('N'))) { /* Go newer (if able) */ i = (i >= 20) ? (i - 20) : 0; } /* Recall 10 newer messages */ if (ke.key.code == '-') { /* Go newer (if able) */ i = (i >= 10) ? (i - 10) : 0; } /* Recall 1 newer messages */ if (ke.key.code == '2') { /* Go newer (if able) */ i = (i >= 1) ? (i - 1) : 0; } /* Scroll forwards or backwards using mouse clicks */ if (ke.mouse.button) { if (ke.mouse.y <= hgt / 2) { /* Go older if legal */ if (i + 20 < n) i += 20; } else { /* Go newer (if able) */ i = (i >= 20) ? (i - 20) : 0; } } /* Hack -- Error of some kind */ if (i == j) bell(NULL); } /* Adjust the buttons */ button_restore(); /* Load screen */ screen_load(); }
/** * Pick up objects and treasure on the floor, now also used for telekinesis. * * Called with pickup: * 0 to grab gold and describe non-gold objects. * 1 to pick up objects either with or without displaying a menu. * 2 to pick up objects, forcing a menu for multiple objects. * 3 to pick up objects, forcing a menu for any number of objects. * * Scan the list of objects in that floor grid. Pick up gold automatically. * Pick up objects automatically until pile or backpack space is full if * auto-pickup option is on, carry_query_floor option is not, and menus are * not forced (which the "get" command does). Otherwise, store objects on * floor in an array, and tally both how many there are and can be picked up. * * If the player is not picking up objects, describe a single object or * indicate the presence of a floor stack. If player is picking up objects, * name a single object, or indicate a stack of objects, that cannot go in * the backpack. * * Pick up a single object without menus, unless menus for single items are * forced. Confirm pickup if that option is on. * * Pick up multiple objects (unless using autopickup, no confirm) using Tim * Baker's menu system. Recursively call this function (forcing menus for any * number of objects) until objects are gone, backpack is full, or player is * satisfied. * * Keep track of number of objects picked up (to calculate time spent). */ byte py_pickup(int pickup, int y, int x) { s16b this_o_idx, next_o_idx = 0; char o_name[120]; object_type *o_ptr; /* Objects picked up. Used to determine time cost of command. */ byte objs_picked_up = 0; size_t floor_num = 0; int floor_list[MAX_FLOOR_STACK + 1], floor_o_idx = 0; int can_pickup = 0; bool call_function_again = FALSE; bool blind = ((p_ptr->timed[TMD_BLIND]) || (no_light())); bool domsg = TRUE; bool telekinesis = ((y != p_ptr->py) || (x != p_ptr->px)); /* Always pickup gold, effortlessly */ if (!telekinesis) py_pickup_gold(); /* Nothing to pick up -- return */ if (!cave_o_idx[y][x]) return (objs_picked_up); /* Scan the pile of objects */ for (this_o_idx = cave_o_idx[y][x]; this_o_idx; this_o_idx = next_o_idx) { /* Access the object */ o_ptr = &o_list[this_o_idx]; /* Access the next object */ next_o_idx = o_ptr->next_o_idx; /* Ordinary pickup */ if (!telekinesis) { /* Ignore all hidden objects and non-objects */ if (squelch_hide_item(o_ptr) || !o_ptr->k_idx) continue; /* Hack -- disturb */ disturb(0, 0); /* Automatically pick up some items */ if (auto_pickup_okay(o_ptr)) { /* Pick up the object */ py_pickup_aux(this_o_idx, TRUE); objs_picked_up++; /* Check the next object */ continue; } } /* Tally objects and store them in an array. */ /* Remember this object index */ floor_list[floor_num] = this_o_idx; /* Count non-gold objects that remain on the floor. */ floor_num++; /* Tally objects that can be picked up. */ if (inven_carry_okay(o_ptr)) can_pickup++; } /* There are no non-gold objects */ if (!floor_num) return (objs_picked_up); /* Get hold of the last floor index */ floor_o_idx = floor_list[floor_num - 1]; /* Mention the objects if player is not picking them up. */ if (pickup == 0 || !(can_pickup || telekinesis)) { const char *p = "see"; /* One object */ if (floor_num == 1) { if (!can_pickup) p = "have no room for"; else if (blind) p = "feel"; /* Get the object */ o_ptr = &o_list[floor_o_idx]; /* Describe the object. Less detail if blind. */ if (blind) object_desc(o_name, sizeof(o_name), o_ptr, ODESC_PREFIX | ODESC_BASE); else object_desc(o_name, sizeof(o_name), o_ptr, ODESC_PREFIX | ODESC_FULL); /* Message */ message_flush(); msg("You %s %s.", p, o_name); } else { /* Optionally, display more information about floor items */ if (OPT(pickup_detail)) { ui_event e; if (!can_pickup) p = "have no room for the following objects"; else if (blind) p = "feel something on the floor"; /* Scan all marked objects in the grid */ floor_num = scan_floor(floor_list, N_ELEMENTS(floor_list), y, x, 0x03); /* Save screen */ screen_save(); /* Display objects on the floor */ show_floor(floor_list, floor_num, (OLIST_WEIGHT)); /* Display prompt */ prt(format("You %s: ", p), 0, 0); /* Move cursor back to character, if needed */ if (OPT(highlight_player)) move_cursor_relative(p_ptr->py, p_ptr->px); /* Wait for it. Use key as next command. */ e = inkey_ex(); Term_event_push(&e); /* Restore screen */ screen_load(); } /* Show less detail */ else { message_flush(); if (!can_pickup) msg("You have no room for any of the items on the floor."); else msg("You %s a pile of %d items.", (blind ? "feel" : "see"), floor_num); } } /* Done */ return (objs_picked_up); } /* We can pick up objects. Menus are not requested (yet). */ if (pickup == 1) { /* Scan floor (again) */ floor_num = scan_floor(floor_list, N_ELEMENTS(floor_list), y, x, 0x03); /* Use a menu interface for multiple objects, or get single objects */ if (floor_num > 1) pickup = 2; else this_o_idx = floor_o_idx; } /* Display a list if requested. */ if (pickup == 2) { const char *q, *s; int item; /* Get an object or exit. */ q = "Get which item?"; s = "You see nothing there."; /* Telekinesis */ if (telekinesis) { item_tester_hook = inven_carry_okay; if (!get_item(&item, q, s, CMD_PICKUP, USE_TARGET)) return (objs_picked_up); this_o_idx = 0 - item; } else { /* Restrict the choices */ item_tester_hook = inven_carry_okay; if (!get_item(&item, q, s, CMD_PICKUP, USE_FLOOR)) return (objs_picked_up); this_o_idx = 0 - item; call_function_again = TRUE; } /* With a list, we do not need explicit pickup messages */ domsg = FALSE; } /* Pick up object, if legal */ if (this_o_idx) { /* Regular pickup or telekinesis with pack not full */ if (can_pickup) { /* Pick up the object */ py_pickup_aux(this_o_idx, domsg); } /* Telekinesis with pack full */ else { /* Access the object */ o_ptr = &o_list[this_o_idx]; /* Drop it */ drop_near(o_ptr, -1, p_ptr->py, p_ptr->px, TRUE); /* Delete the old object */ delete_object_idx(this_o_idx); } } /* Indicate an object picked up. */ objs_picked_up = 1; /* If requested, call this function recursively. Count objects picked up. * Force the display of a menu in all cases. */ if (call_function_again) objs_picked_up += py_pickup(2, y, x); /* Indicate how many objects have been picked up. */ return (objs_picked_up); }
/** * Display some character info */ static void death_info(const char *title, int row) { int i, j, k, which = 0; object_type *o_ptr; store_type *st_ptr; ui_event_data ke; bool done = FALSE; /* Get the store number of the home */ if (OPT(adult_dungeon)) which = NUM_TOWNS_SMALL * 4 + STORE_HOME; else { for (i = 0; i < NUM_TOWNS; i++) { /* Found the town */ if (p_ptr->home == towns[i]) { which += (i < NUM_TOWNS_SMALL ? 3 : STORE_HOME); break; } /* Next town */ else which += (i < NUM_TOWNS_SMALL ? MAX_STORES_SMALL : MAX_STORES_BIG); } } /* Activate the store */ st_ptr = &store[which]; screen_save(); /* Display player */ display_player(0); /* Prompt for inventory */ prt("Hit any key to see more information (ESC to abort): ", 0, 0); /* Buttons */ button_backup_all(); button_kill_all(); button_add("ESC", ESCAPE); button_add("Continue", 'q'); /* Allow abort at this point */ ke = inkey_ex(); if (ke.key == ESCAPE) done = TRUE; /* Show equipment and inventory */ /* Equipment -- if any */ if ((p_ptr->equip_cnt) && !done) { Term_clear(); item_tester_full = TRUE; show_equip(OLIST_WEIGHT); prt("You are using: -more-", 0, 0); ke = inkey_ex(); if (ke.key == ESCAPE) done = TRUE; } /* Inventory -- if any */ if ((p_ptr->inven_cnt) && !done) { Term_clear(); item_tester_full = TRUE; show_inven(OLIST_WEIGHT); prt("You are carrying: -more-", 0, 0); ke = inkey_ex(); if (ke.key == ESCAPE) done = TRUE; } /* Home -- if anything there */ if ((st_ptr->stock_num) && !done) { /* Display contents of the home */ for (k = 0, i = 0; i < st_ptr->stock_num; k++) { /* Clear screen */ Term_clear(); /* Show 12 items */ for (j = 0; (j < 12) && (i < st_ptr->stock_num); j++, i++) { byte attr; char o_name[80]; char tmp_val[80]; /* Get the object */ o_ptr = &st_ptr->stock[i]; /* Print header, clear line */ sprintf(tmp_val, "%c) ", I2A(j)); prt(tmp_val, j + 2, 4); /* Get the object description */ object_desc(o_name, sizeof(o_name), o_ptr, ODESC_PREFIX | ODESC_FULL); /* Get the inventory color */ attr = tval_to_attr[o_ptr->tval & 0x7F]; /* Display the object */ c_put_str(attr, o_name, j + 2, 7); } /* Caption */ prt(format("Your home contains (page %d): -more-", k + 1), 0, 0); /* Wait for it */ ke = inkey_ex(); if (ke.key == ESCAPE) done = TRUE; } } screen_load(); }
/* * 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; }
/* * Modify the "window" options */ static void do_cmd_options_win(const char *name, int row) { int i, j, d; int y = 0; int x = 0; ui_event ke; u32b new_flags[ANGBAND_TERM_MAX]; /* Set new flags to the old values */ for (j = 0; j < ANGBAND_TERM_MAX; j++) { new_flags[j] = op_ptr->window_flag[j]; } /* Clear screen */ screen_save(); clear_from(0); /* Interact */ while (1) { /* Prompt */ prt("Window flags (<dir> to move, 't'/Enter to toggle, or ESC)", 0, 0); /* Display the windows */ for (j = 0; j < ANGBAND_TERM_MAX; j++) { byte a = TERM_WHITE; const char *s = angband_term_name[j]; /* Use color */ if (j == x) a = TERM_L_BLUE; /* Window name, staggered, centered */ Term_putstr(35 + j * 5 - strlen(s) / 2, 2 + j % 2, -1, a, s); } /* Display the options */ for (i = 0; i < PW_MAX_FLAGS; i++) { byte a = TERM_WHITE; const char *str = window_flag_desc[i]; /* Use color */ if (i == y) a = TERM_L_BLUE; /* Unused option */ if (!str) str = "(Unused option)"; /* Flag name */ Term_putstr(0, i + 5, -1, a, str); /* Display the windows */ for (j = 0; j < ANGBAND_TERM_MAX; j++) { char c = '.'; a = TERM_WHITE; /* Use color */ if ((i == y) && (j == x)) a = TERM_L_BLUE; /* Active flag */ if (new_flags[j] & (1L << i)) c = 'X'; /* Flag value */ Term_putch(35 + j * 5, i + 5, a, c); } } /* Place Cursor */ Term_gotoxy(35 + x * 5, y + 5); /* Get key */ ke = inkey_ex(); /* Mouse interaction */ if (ke.type == EVT_MOUSE) { int choicey = ke.mouse.y - 5; int choicex = (ke.mouse.x - 35)/5; if (ke.mouse.button == 2) break; if ((choicey >= 0) && (choicey < PW_MAX_FLAGS) && (choicex > 0) && (choicex < ANGBAND_TERM_MAX) && !(ke.mouse.x % 5)) { if ((choicey == y) && (choicex == x)) { /* Toggle flag (off) */ if (new_flags[x] & (1L << y)) new_flags[x] &= ~(1L << y); /* Toggle flag (on) */ else new_flags[x] |= (1L << y); } else { y = choicey; x = (ke.mouse.x - 35)/5; } } } /* Allow escape */ else if (ke.type == EVT_KBRD) { if (ke.key.code == ESCAPE || ke.key.code == 'q') break; /* Toggle */ else if (ke.key.code == '5' || ke.key.code == 't' || ke.key.code == KC_ENTER) { /* Hack -- ignore the main window */ if (x == 0) bell("Cannot set main window flags!"); /* Toggle flag (off) */ else if (new_flags[x] & (1L << y)) new_flags[x] &= ~(1L << y); /* Toggle flag (on) */ else new_flags[x] |= (1L << y); /* Continue */ continue; } /* Extract direction */ d = target_dir(ke.key); /* Move */ if (d != 0) { x = (x + ddx[d] + 8) % ANGBAND_TERM_MAX; y = (y + ddy[d] + 16) % PW_MAX_FLAGS; } } } /* Notice changes */ subwindows_set_flags(new_flags, ANGBAND_TERM_MAX); screen_load(); }
/** * Save a "bones" file for a dead character. Now activated and (slightly) * altered. Allows the inclusion of personalized strings. */ static void make_bones(void) { ang_file *fp; char str[1024]; ui_event_data answer; byte choice = 0; int i; /* Ignore wizards and borgs */ if (!(p_ptr->noscore & 0x00FF)) { /* Ignore people who die in town */ if (p_ptr->depth) { int level; char tmp[128]; /* Slightly more tenacious saving routine. */ for (i = 0; i < 5; i++) { /* Ghost hovers near level of death. */ if (i == 0) level = p_ptr->depth; else level = p_ptr->depth + 5 - damroll(2, 4); if (level < 1) level = randint1(4); /* XXX XXX XXX "Bones" name */ sprintf(tmp, "bone.%03d", level); /* Build the filename */ path_build(str, 1024, ANGBAND_DIR_BONE, tmp); /* Attempt to open the bones file */ fp = file_open(str, MODE_READ, FTYPE_TEXT); /* Close it right away */ if (fp) file_close(fp); /* Do not over-write a previous ghost */ if (fp) continue; /* If no file by that name exists, we can make a new one. */ if (!(fp)) break; } /* Failure */ if (fp) return; /* Try to write a new "Bones File" */ fp = file_open(str, MODE_WRITE, FTYPE_TEXT); /* Not allowed to write it? Weird. */ if (!fp) return; /* Save the info */ if (op_ptr->full_name[0] != '\0') file_putf(fp, "%s\n", op_ptr->full_name); else file_putf(fp, "Anonymous\n"); file_putf(fp, "%d\n", p_ptr->psex); file_putf(fp, "%d\n", p_ptr->prace); file_putf(fp, "%d\n", p_ptr->pclass); /* Clear screen */ Term_clear(); while (1) { /* Ask the player if he wants to add a personalized string. */ prt("Information about your character has been saved", 15, 0); prt("in a bones file. Would you like to give the", 16, 0); prt("ghost a special message or description? (yes/no)", 17, 0); button_add("Yes", 'y'); button_add("No", 'n'); answer = inkey_ex(); /* Clear last line */ clear_from(15); clear_from(16); /* Determine what the personalized string will be used for. */ if ((answer.key == 'Y') || (answer.key == 'y')) { prt("Will you add something for your ghost to say,", 15, 0); prt("or add to the monster description?", 16, 0); prt("((M)essage/(D)escription)", 17, 0); /* Buttons */ button_kill('y'); button_kill('n'); button_add("M", 'M'); button_add("D", 'D'); button_add("ESC", ESCAPE); while (1) { answer = inkey_ex(); clear_from(15); clear_from(16); if ((answer.key == 'M') || (answer.key == 'm')) { choice = 1; break; } else if ((answer.key == 'D') || (answer.key == 'd')) { choice = 2; break; } else { choice = 0; break; } } } else if ((answer.key == 'N') || (answer.key == 'n') || (answer.key == ESCAPE)) { choice = 0; break; } button_kill_all(); /* If requested, get the personalized string, and write it and * info on how it should be used in the bones file. Otherwise, * indicate the absence of such a string. */ if (choice) file_putf(fp, "%d:%s\n", choice, get_personalized_string(choice)); else file_putf(fp, "0: \n"); /* Close and save the Bones file */ file_close(fp); return; } } } }
/* * 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 get_rep_dir(int *dp) { int dir = 0; ui_event ke; /* Initialize */ (*dp) = 0; /* Get a direction */ while (!dir) { /* Paranoia XXX XXX XXX */ 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 */ 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(p_ptr->px, p_ptr->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); } } /* Get other keypresses until a direction is chosen. */ 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(ke.key); if (this_dir) dir = dir_transitions[dir][this_dir]; if (lazymove_delay == 0 || ++keypresses_handled > 1) break; inkey_scan = lazymove_delay; ke = inkey_ex(); } /* 5 is equivalent to "escape" */ if (dir == 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); }
/** * Let the user select an item, save its "index" * * Return TRUE only if an acceptable item was chosen by the user. * * The selected item must satisfy the "item_tester_hook()" function, * if that hook is set, and the "item_tester_tval", if that value is set. * * All "item_tester" restrictions are cleared before this function returns. * * The user is allowed to choose acceptable items from the equipment, * inventory, or floor, respectively, if the proper flag was given, * and there are any acceptable items in that location. * * The equipment or inventory are displayed (even if no acceptable * items are in that location) if the proper flag was given. * * If there are no acceptable items available anywhere, and "str" is * not NULL, then it will be used as the text of a warning message * before the function returns. * * Note that the user must press "-" to specify the item on the floor, * and there is no way to "examine" the item on the floor, while the * use of "capital" letters will "examine" an inventory/equipment item, * and prompt for its use. * * If a legal item is selected from the inventory, we save it in "cp" * directly (0 to 35), and return TRUE. * * If a legal item is selected from the floor, we save it in "cp" as * a negative (-1 to -511), and return TRUE. * * If no item is available, we do nothing to "cp", and we display a * warning message, using "str" if available, and return FALSE. * * If no item is selected, we do nothing to "cp", and return FALSE. * * Global "p_ptr->command_wrk" is used to choose between equip/inven/floor * listings. It is equal to USE_INVEN or USE_EQUIP or USE_FLOOR, except * when this function is first called, when it is equal to zero, which will * cause it to be set to USE_INVEN. * * We always erase the prompt when we are done, leaving a blank line, * or a warning message, if appropriate, if no items are available. * * Note that only "acceptable" floor objects get indexes, so between two * commands, the indexes of floor objects may change. XXX XXX XXX */ bool get_item(int *cp, const char *pmt, const char *str, cmd_code cmd, int mode) { s16b py = p_ptr->py; s16b px = p_ptr->px; unsigned char cmdkey = cmd_lookup_key(cmd, KEYMAP_MODE_ORIG); bool done, item; int j, k; bool oops = FALSE; bool toggle = FALSE; bool use_inven = ((mode & USE_INVEN) ? TRUE : FALSE); bool use_equip = ((mode & USE_EQUIP) ? TRUE : FALSE); bool use_floor = ((mode & (USE_FLOOR | USE_TARGET)) ? TRUE : FALSE); bool use_quiver = ((mode & QUIVER_TAGS) ? TRUE : FALSE); bool can_squelch = ((mode & CAN_SQUELCH) ? TRUE : FALSE); bool is_harmless = ((mode & IS_HARMLESS) ? TRUE : FALSE); bool quiver_tags = ((mode & QUIVER_TAGS) ? TRUE : FALSE); bool allow_inven = FALSE; bool allow_equip = FALSE; bool allow_floor = FALSE; int floor_num; ui_event which; prompt = pmt; olist_mode = 0; item_mode = mode; item_cmd = cmd; /* Not done */ done = FALSE; /* No item selected */ item = FALSE; *cp = 0; /* Object list display modes */ if (mode & SHOW_FAIL) olist_mode |= (OLIST_FAIL); else olist_mode |= (OLIST_WEIGHT); if (mode & SHOW_PRICES) olist_mode |= (OLIST_PRICE); show_list = OPT(show_lists) ? TRUE : FALSE; /* Set target for telekinesis */ if (mode & (USE_TARGET)) { target_get(&px, &py); if (!(px && py)) return FALSE; } /* Full inventory */ i1 = 0; i2 = INVEN_PACK - 1; /* Forbid inventory */ if (!use_inven) i2 = -1; /* Restrict inventory indexes */ while ((i1 <= i2) && (!get_item_okay(i1))) i1++; while ((i1 <= i2) && (!get_item_okay(i2))) i2--; /* Accept inventory */ if (i1 <= i2) allow_inven = TRUE; /* Full equipment */ e1 = INVEN_WIELD; e2 = ALL_INVEN_TOTAL - 1; /* Forbid equipment */ if (!use_equip) e2 = -1; /* Restrict equipment indexes */ while ((e1 <= e2) && (!get_item_okay(e1))) e1++; while ((e1 <= e2) && (!get_item_okay(e2))) e2--; /* Accept equipment */ if (e1 <= e2) allow_equip = TRUE; /* Reject quiver */ if (e2 < QUIVER_START) use_quiver = FALSE; /* Scan all non-gold objects in the grid */ floor_num = scan_floor(floor_list, N_ELEMENTS(floor_list), py, px, 0x03); /* Full floor */ f1 = 0; f2 = floor_num - 1; /* Forbid floor */ if (!use_floor) f2 = -1; /* Restrict floor indexes */ while ((f1 <= f2) && (!get_item_okay(0 - floor_list[f1]))) f1++; while ((f1 <= f2) && (!get_item_okay(0 - floor_list[f2]))) f2--; /* Accept floor */ if (f1 <= f2) allow_floor = TRUE; /* Require at least one legal choice */ if (!allow_inven && !allow_equip && !allow_floor) { /* Oops */ oops = TRUE; done = TRUE; } /* Analyze choices, prepare for initial menu */ else { /* Hack -- Start on equipment if requested */ if ((p_ptr->command_wrk == USE_EQUIP) && use_equip){ p_ptr->command_wrk = USE_EQUIP; build_obj_list(INVEN_WIELD, e2, NULL, olist_mode); } /* If we are using the quiver then start on equipment */ else if (use_quiver){ p_ptr->command_wrk = USE_EQUIP; build_obj_list(INVEN_WIELD, e2, NULL, olist_mode); } /* Use inventory if allowed */ else if (use_inven){ p_ptr->command_wrk = USE_INVEN; build_obj_list(0, i2, NULL, olist_mode); } /* Use equipment if allowed */ else if (use_equip){ p_ptr->command_wrk = USE_EQUIP; build_obj_list(INVEN_WIELD, e2, NULL, olist_mode); } /* Use floor if allowed */ else if (use_floor){ p_ptr->command_wrk = USE_FLOOR; build_obj_list(0, f2, floor_list, olist_mode); } /* Hack -- Use (empty) inventory */ else { p_ptr->command_wrk = USE_INVEN; build_obj_list(0, i2, NULL, olist_mode); } } /* Clear all current messages */ msg_flag = FALSE; /* Start out in "display" mode */ if (show_list) { /* Save screen */ screen_save(); } /* Repeat until done */ while (!done) { static bool refresh; int ni = 0; int ne = 0; /* Scan windows */ for (j = 0; j < ANGBAND_TERM_MAX; j++) { /* Unused */ if (!angband_term[j]) continue; /* Count windows displaying inven */ if (op_ptr->window_flag[j] & (PW_INVEN)) ni++; /* Count windows displaying equip */ if (op_ptr->window_flag[j] & (PW_EQUIP)) ne++; } /* Toggle if needed */ if (((p_ptr->command_wrk == USE_EQUIP) && ni && !ne) || ((p_ptr->command_wrk == USE_INVEN) && !ni && ne)) { /* Toggle */ toggle_inven_equip(); /* Track toggles */ toggle = !toggle; } /* Redraw */ p_ptr->redraw |= (PR_INVEN | PR_EQUIP); /* Redraw windows */ redraw_stuff(p_ptr); /* Change the list if needed */ if (refresh) { /* Rebuild object list */ if (p_ptr->command_wrk == USE_INVEN) build_obj_list(0, i2, NULL, olist_mode); else if (p_ptr->command_wrk == USE_EQUIP) build_obj_list(INVEN_WIELD, e2, NULL, olist_mode); else build_obj_list(0, f2, floor_list, mode); refresh = FALSE; } /* Show the prompt */ item_prompt(mode); redraw_stuff(p_ptr); /* Menu if requested */ if (show_list) { which = item_menu(cmd, mode); if (which.type == EVT_ESCAPE) which.key.code = ESCAPE; } /* Get a key */ else which = inkey_ex(); /* Parse it */ switch (which.key.code) { case ESCAPE: { done = TRUE; break; } case '*': case '?': case ' ': { if (!OPT(show_lists)) { /* Save screen */ screen_save(); /* Flip flag */ show_list = TRUE; } refresh = TRUE; break; } case '/': { /* Toggle to inventory */ if (use_inven && (p_ptr->command_wrk != USE_INVEN)) { p_ptr->command_wrk = USE_INVEN; refresh = TRUE; } /* Toggle to equipment */ else if (use_equip && (p_ptr->command_wrk != USE_EQUIP)) { p_ptr->command_wrk = USE_EQUIP; refresh = TRUE; } /* No toggle allowed */ else { bell("Cannot switch item selector!"); break; } /* Need to redraw */ break; } case '-': { /* Paranoia */ if (!allow_floor) { bell("Cannot select floor!"); break; } /* There is only one item */ if (OPT(pickup_single) && (floor_num == 1)) { /* Fall through */ } else { p_ptr->command_wrk = (USE_FLOOR); refresh = TRUE; break; } } case '.': { /* * If we are allow to use the floor, select * the top item. -BR- */ if (allow_floor) { int k; /* Special index */ k = 0 - floor_list[0]; /* Allow player to "refuse" certain actions */ if (!get_item_allow(k, cmdkey, is_harmless)) { done = TRUE; break; } /* Accept that choice */ (*cp) = k; item = TRUE; done = TRUE; } break; } case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { /* Look up the tag */ if (!get_tag(&k, which.key.code, cmd, quiver_tags)) { bell("Illegal object choice (tag)!"); break; } /* Hack -- Validate the item */ if ((k < INVEN_WIELD) ? !allow_inven : !allow_equip) { bell("Illegal object choice (tag)!"); break; } /* Validate the item */ if (!get_item_okay(k)) { bell("Illegal object choice (tag)!"); break; } /* Allow player to "refuse" certain actions */ if (!get_item_allow(k, cmdkey, is_harmless)) { done = TRUE; break; } /* Accept that choice */ (*cp) = k; item = TRUE; done = TRUE; break; } case KC_ENTER: { /* Choose "default" inventory item */ if (p_ptr->command_wrk == USE_INVEN) { if (i1 != i2) { bell("Illegal object choice (default)!"); break; } k = i1; } /* Choose the "default" slot (0) of the quiver */ else if (quiver_tags) k = e1; /* Choose "default" equipment item */ else if (p_ptr->command_wrk == USE_EQUIP) { if (e1 != e2) { bell("Illegal object choice (default)!"); break; } k = e1; } /* Choose "default" floor item */ else { if (f1 != f2) { bell("Illegal object choice (default)!"); break; } k = 0 - floor_list[f1]; } /* Validate the item */ if (!get_item_okay(k)) { bell("Illegal object choice (default)!"); break; } /* Allow player to "refuse" certain actions */ if (!get_item_allow(k, cmdkey, is_harmless)) { done = TRUE; break; } /* Accept that choice */ (*cp) = k; item = TRUE; done = TRUE; break; } case '!': { /* Try squelched items */ if (can_squelch) { (*cp) = ALL_SQUELCHED; item = TRUE; done = TRUE; break; } /* Just fall through */ } default: { bool verify; /* Note verify */ verify = (isupper((unsigned char) which.key.code) ? TRUE : FALSE); /* Lowercase */ which.key.code = tolower((unsigned char) which.key.code); /* Convert letter to inventory index */ if (p_ptr->command_wrk == USE_INVEN) { k = label_to_inven(which.key.code); if (k < 0) { bell("Illegal object choice (inven)!"); break; } } /* Convert letter to equipment index */ else if (p_ptr->command_wrk == USE_EQUIP) { k = label_to_equip(which.key.code); if (k < 0) { bell("Illegal object choice (equip)!"); break; } } /* Convert letter to floor index */ else { k = (islower((unsigned char) which.key.code) ? A2I((unsigned char)which.key.code) : -1); if (k < 0 || k >= floor_num) { bell("Illegal object choice (floor)!"); break; } /* Special index */ k = 0 - floor_list[k]; } /* Validate the item */ if (!get_item_okay(k)) { bell("Illegal object choice (normal)!"); break; } /* Verify the item */ if (verify && !verify_item("Try", k)) { done = TRUE; break; } /* Allow player to "refuse" certain actions */ if (!get_item_allow(k, cmdkey, is_harmless)) { done = TRUE; break; } /* Accept that choice */ (*cp) = k; item = TRUE; done = TRUE; break; } } } /* Fix the screen if necessary */ if (show_list) { /* Load screen */ screen_load(); /* Hack -- Cancel "display" */ show_list = FALSE; } /* Kill buttons */ button_kill('*'); button_kill('/'); button_kill('-'); button_kill('!'); /* Forget the item_tester_tval restriction */ item_tester_tval = 0; /* Forget the item_tester_hook restriction */ item_tester_hook = NULL; /* Toggle again if needed */ if (toggle) toggle_inven_equip(); /* Update */ p_ptr->redraw |= (PR_INVEN | PR_EQUIP); redraw_stuff(p_ptr); /* Clear the prompt line */ prt("", 0, 0); /* Warning if needed */ if (oops && str) msg(str); /* Result */ return (item); }
/* * Query the dungeon */ static void do_cmd_wiz_query(void) { int py = p_ptr->py; int px = p_ptr->px; int y, x; struct keypress cmd; u16b mask = 0x00; /* Get a "debug command" */ if (!get_com("Debug Command Query: ", &cmd)) return; /* Extract a flag */ switch (cmd.code) { case '0': mask = (1 << 0); break; case '1': mask = (1 << 1); break; case '2': mask = (1 << 2); break; case '3': mask = (1 << 3); break; case '4': mask = (1 << 4); break; case '5': mask = (1 << 5); break; case '6': mask = (1 << 6); break; case '7': mask = (1 << 7); break; case 'm': mask |= (CAVE_MARK); break; case 'g': mask |= (CAVE_GLOW); break; case 'r': mask |= (CAVE_ROOM); break; case 'i': mask |= (CAVE_VAULT); break; case 's': mask |= (CAVE_SEEN); break; case 'v': mask |= (CAVE_VIEW); break; case 't': mask |= (CAVE_WASSEEN); break; case 'w': mask |= (CAVE_WALL); break; } /* Scan map */ for (y = Term->offset_y; y < Term->offset_y + SCREEN_HGT; y++) { for (x = Term->offset_x; x < Term->offset_x + SCREEN_WID; x++) { byte a = TERM_RED; if (!cave_in_bounds_fully(cave, y, x)) continue; /* Given mask, show only those grids */ if (mask && !(cave->info[y][x] & mask)) continue; /* Given no mask, show unknown grids */ if (!mask && (cave->info[y][x] & (CAVE_MARK))) continue; /* Color */ if (cave_ispassable(cave, y, x)) a = TERM_YELLOW; /* Display player/floors/walls */ if ((y == py) && (x == px)) print_rel(L'@', a, y, x); else if (cave_ispassable(cave, y, x)) print_rel(L'*', a, y, x); else print_rel(L'#', a, y, x); } } Term_redraw(); /* Get keypress */ msg("Press any key."); inkey_ex(); message_flush(); /* Redraw map */ prt_map(); }
/* * 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 get_rep_dir(int *dp) { int dir = 0; ui_event ke; /* Initialize */ (*dp) = 0; /* Get a direction */ while (!dir) { /* Paranoia XXX XXX XXX */ 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 */ if (ke.type == EVT_MOUSE) { /* if (ke.button) */ { int y = KEY_GRID_Y(ke); int x = KEY_GRID_X(ke); /* Calculate approximate angle */ int angle = get_angle_to_target(p_ptr->py, p_ptr->px, y, x, 0); /* Convert angle to direction */ if (angle < 15) dir = 6; else if (angle < 33) dir = 9; else if (angle < 59) dir = 8; else if (angle < 78) dir = 7; else if (angle < 104) dir = 4; else if (angle < 123) dir = 1; else if (angle < 149) dir = 2; else if (angle < 168) dir = 3; else dir = 6; } } /* Get other keypresses until a direction is chosen. */ else { 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(ke.key); if (this_dir) { dir = dir_transitions[dir][this_dir]; } if (lazymove_delay == 0 || ++keypresses_handled > 1) break; inkey_scan = lazymove_delay; ke = inkey_ex(); } /* 5 is equivalent to "escape" */ if (dir == 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); }
/* * Interactive group by. * Recognises inscriptions, graphical symbols, lore */ static void display_knowledge(const char *title, int *obj_list, int o_count, group_funcs g_funcs, member_funcs o_funcs, const char *otherfields) { /* maximum number of groups to display */ int max_group = g_funcs.maxnum < o_count ? g_funcs.maxnum : o_count; /* This could (should?) be (void **) */ int *g_list, *g_offset; const char **g_names; int g_name_len = 8; /* group name length, minumum is 8 */ int grp_cnt = 0; /* total number groups */ int g_cur = 0, grp_old = -1; /* group list positions */ int o_cur = 0; /* object list positions */ int g_o_count = 0; /* object count for group */ int oid = -1; /* object identifiers */ region title_area = { 0, 0, 0, 4 }; region group_region = { 0, 6, MISSING, -2 }; region object_region = { MISSING, 6, 0, -2 }; /* display state variables */ bool visual_list = FALSE; byte attr_top = 0; byte char_left = 0; int delay = 0; menu_type group_menu; menu_type object_menu; menu_iter object_iter = { NULL, NULL, display_group_member, NULL, NULL }; /* Panel state */ /* These are swapped in parallel whenever the actively browsing " */ /* changes */ int *active_cursor = &g_cur, *inactive_cursor = &o_cur; menu_type *active_menu = &group_menu, *inactive_menu = &object_menu; int panel = 0; void *swapspace; bool do_swap = FALSE; bool flag = FALSE; bool redraw = TRUE; int browser_rows; int wid, hgt; int i; int prev_g = -1; int omode = OPT(rogue_like_commands); ui_event_data ke; /* Get size */ Term_get_size(&wid, &hgt); browser_rows = hgt - 8; /* Disable the roguelike commands for the duration */ OPT(rogue_like_commands) = FALSE; if (g_funcs.gcomp) sort(obj_list, o_count, sizeof(*obj_list), g_funcs.gcomp); /* Sort everything into group order */ g_list = C_ZNEW(max_group + 1, int); g_offset = C_ZNEW(max_group + 1, int); for (i = 0; i < o_count; i++) { if (prev_g != g_funcs.group(obj_list[i])) { prev_g = g_funcs.group(obj_list[i]); g_offset[grp_cnt] = i; g_list[grp_cnt++] = prev_g; } } g_offset[grp_cnt] = o_count; g_list[grp_cnt] = -1; /* The compact set of group names, in display order */ g_names = C_ZNEW(grp_cnt, const char *); for (i = 0; i < grp_cnt; i++) { int len; g_names[i] = g_funcs.name(g_list[i]); len = strlen(g_names[i]); if (len > g_name_len) g_name_len = len; } /* Reasonable max group name len */ if (g_name_len >= 20) g_name_len = 20; object_region.col = g_name_len + 3; group_region.width = g_name_len; /* Leave room for the group summary information */ if (g_funcs.summary) object_region.page_rows = -3; /* Set up the two menus */ menu_init(&group_menu, MN_SKIN_SCROLL, menu_find_iter(MN_ITER_STRINGS)); menu_setpriv(&group_menu, grp_cnt, g_names); menu_layout(&group_menu, &group_region); menu_init(&object_menu, MN_SKIN_SCROLL, &object_iter); menu_setpriv(&object_menu, 0, &o_funcs); menu_layout(&object_menu, &object_region); o_funcs.is_visual = FALSE; /* Save screen */ screen_save(); clear_from(0); /* This is the event loop for a multi-region panel */ /* Panels are -- text panels, two menus, and visual browser */ /* with "pop-up menu" for lore */ while ((!flag) && (grp_cnt)) { bool recall = FALSE; if (redraw) { /* Print the title bits */ region_erase(&title_area); prt(format("Knowledge - %s", title), 2, 0); prt("Group", 4, 0); prt("Name", 4, g_name_len + 3); if (otherfields) prt(otherfields, 4, 46); /* Print dividers: horizontal and vertical */ for (i = 0; i < 79; i++) Term_putch(i, 5, TERM_WHITE, '='); for (i = 0; i < browser_rows; i++) Term_putch(g_name_len + 1, 6 + i, TERM_WHITE, '|'); /* Reset redraw flag */ redraw = FALSE; } if (g_cur != grp_old) { grp_old = g_cur; o_cur = 0; g_o_count = g_offset[g_cur + 1] - g_offset[g_cur]; menu_set_filter(&object_menu, obj_list + g_offset[g_cur], g_o_count); group_menu.cursor = g_cur; object_menu.cursor = 0; } /* HACK ... */ if (!visual_list) { /* ... The object menu may be browsing the entire group... */ o_funcs.is_visual = FALSE; menu_set_filter(&object_menu, obj_list + g_offset[g_cur], g_o_count); object_menu.cursor = o_cur; } else { /* ... or just a single element in the group. */ o_funcs.is_visual = TRUE; menu_set_filter(&object_menu, obj_list + o_cur + g_offset[g_cur], 1); object_menu.cursor = 0; } oid = obj_list[g_offset[g_cur] + o_cur]; /* Print prompt */ { const char *pedit = (!o_funcs. xattr) ? "" : (!(attr_idx | char_idx) ? ", 'c' to copy" : ", 'c', 'p' to paste"); const char *xtra = o_funcs.xtra_prompt ? o_funcs.xtra_prompt(oid) : ""; const char *pvs = ""; if (visual_list) pvs = ", ENTER to accept"; else if (o_funcs.xattr) pvs = ", 'v' for visuals"; prt(format("<dir>%s%s%s, ESC", pvs, pedit, xtra), hgt - 1, 0); } if (do_swap) { do_swap = FALSE; swap(active_menu, inactive_menu); swap(active_cursor, inactive_cursor); panel = 1 - panel; } if (g_funcs.summary && !visual_list) { g_funcs.summary(g_cur, obj_list, g_o_count, g_offset[g_cur], object_menu.active.row + object_menu.active.page_rows, object_region.col); } menu_refresh(inactive_menu); menu_refresh(active_menu); handle_stuff(); if (visual_list) { bigcurs = TRUE; display_visual_list(g_name_len + 3, 7, browser_rows - 1, wid - (g_name_len + 3), attr_top, char_left); place_visual_list_cursor(g_name_len + 3, 7, *o_funcs.xattr(oid), *o_funcs.xchar(oid), attr_top, char_left); } if (delay) { /* Force screen update */ Term_fresh(); /* Delay */ Term_xtra(TERM_XTRA_DELAY, delay); delay = 0; } ke = inkey_ex(); if (!visual_list) { ui_event_data ke0 = EVENT_EMPTY; if (ke.type == EVT_MOUSE) menu_handle_mouse(active_menu, &ke, &ke0); else if (ke.type == EVT_KBRD) menu_handle_keypress(active_menu, &ke, &ke0); if (ke0.type != EVT_NONE) ke = ke0; } /* XXX Do visual mode command if needed */ if (o_funcs.xattr && o_funcs.xchar) { if (visual_mode_command (ke, &visual_list, browser_rows - 1, wid - (g_name_len + 3), &attr_top, &char_left, o_funcs.xattr(oid), (byte *) o_funcs.xchar(oid), g_name_len + 3, 7, &delay)) continue; } switch (ke.type) { case EVT_KBRD: { if (ke.key == 'r' || ke.key == 'R') recall = TRUE; else if (o_funcs.xtra_act) o_funcs.xtra_act(ke.key, oid); break; } case EVT_MOUSE: { /* Change active panels */ if (region_inside(&inactive_menu->boundary, &ke)) { swap(active_menu, inactive_menu); swap(active_cursor, inactive_cursor); panel = 1 - panel; } continue; } case EVT_ESCAPE: { if (panel == 1) do_swap = TRUE; else flag = TRUE; break; } case EVT_SELECT: { if (panel == 0) do_swap = TRUE; else if (panel == 1 && oid >= 0 && o_cur == active_menu->cursor) recall = TRUE; break; } case EVT_MOVE: { *active_cursor = active_menu->cursor; break; } default: { break; } } /* Recall on screen */ if (recall) { if (oid >= 0) o_funcs.lore(oid); redraw = TRUE; } } /* Restore roguelike option */ OPT(rogue_like_commands) = omode; /* Prompt */ if (!grp_cnt) prt(format("No %s known.", title), 15, 0); FREE(g_names); FREE(g_offset); FREE(g_list); screen_load(); }
/** * Hack -- change name */ void do_cmd_change_name(void) { ui_event ke; int mode = 0; const char *p; bool more = true; /* Prompt */ p = "['c' to change name, 'f' to file, 'h' to change mode, or ESC]"; /* Save screen */ screen_save(); /* Forever */ while (more) { /* Display the player */ display_player(mode); /* Prompt */ Term_putstr(2, 23, -1, COLOUR_WHITE, p); /* Query */ ke = inkey_ex(); if ((ke.type == EVT_KBRD)||(ke.type == EVT_BUTTON)) { switch (ke.key.code) { case ESCAPE: more = false; break; case 'c': { char namebuf[32] = ""; /* Set player name */ if (get_character_name(namebuf, sizeof namebuf)) my_strcpy(op_ptr->full_name, namebuf, sizeof(op_ptr->full_name)); break; } case 'f': { char buf[1024]; char fname[80]; strnfmt(fname, sizeof fname, "%s.txt", player_safe_name(player, false)); if (get_file(fname, buf, sizeof buf)) { if (dump_save(buf)) msg("Character dump successful."); else msg("Character dump failed!"); } break; } case 'h': case ARROW_LEFT: case ' ': mode = (mode + 1) % INFO_SCREENS; break; case 'l': case ARROW_RIGHT: mode = (mode - 1) % INFO_SCREENS; break; } } else if (ke.type == EVT_MOUSE) { if (ke.mouse.button == 1) { /* Flip through the screens */ mode = (mode + 1) % INFO_SCREENS; } else if (ke.mouse.button == 2) { /* exit the screen */ more = false; } else { /* Flip backwards through the screens */ mode = (mode - 1) % INFO_SCREENS; } } /* Flush messages */ event_signal(EVENT_MESSAGE_FLUSH); } /* Load screen */ screen_load(); }
/** * Hack -- change name */ void do_cmd_change_name(void) { ui_event ke; int col = 0; int last_line = 0; int top_line = 0; const char *p; /* Prompt */ p = "['c' change name, 'f' to file, scroll, or ESC]"; /* Save screen */ screen_save(); /* Adjust the buttons */ button_backup_all(); button_kill_all(); button_add("ESC", ESCAPE); button_add("Spc", ' '); button_add("-", '-'); button_add("c", 'c'); button_add("f", 'f'); button_add("->", ARROW_RIGHT); button_add("<-", ARROW_LEFT); p_ptr->redraw |= PR_BUTTONS; /* Make the array of lines */ C_WIPE(dumpline, DUMP_MAX_LINES, char_attr_line); last_line = make_dump(dumpline, 2); /* Forever */ while (1) { /* Display the player */ display_dump(dumpline, top_line, top_line + Term->hgt - 1, col); redraw_stuff(p_ptr); /* Clear the bottom line */ prt("", Term->hgt - 1, 0); /* Prompt */ Term_putstr(0, Term->hgt - 1, -1, TERM_WHITE, p); /* Query */ ke = inkey_ex(); /* Exit */ if (ke.key.code == ESCAPE) break; /* Change name */ if (ke.key.code == 'c') { char namebuf[32] = ""; if (get_name(namebuf, sizeof namebuf)) { /* Set player name */ my_strcpy(op_ptr->full_name, namebuf, sizeof(op_ptr->full_name)); /* Don't change savefile name. */ process_player_name(FALSE); } //(void) get_name(namebuf, sizeof namebuf); (void) make_dump(dumpline, 2); } /* File dump */ else if (ke.key.code == 'f') { char ftmp[80]; strnfmt(ftmp, sizeof ftmp, "%s.txt", op_ptr->base_name); if (get_string("File name: ", ftmp, 80)) { if (ftmp[0] && (ftmp[0] != ' ')) { if (file_character(ftmp, dumpline, last_line)) msg("Character dump failed!"); else msg("Character dump successful."); } } } /* Scroll down */ else if (ke.key.code == ARROW_DOWN) { if (top_line + Term->hgt - 2 < last_line) top_line++; } /* Page down */ else if (ke.key.code == ' ') { top_line = MIN(last_line - Term->hgt + 2, top_line + (Term->hgt - 2)); } /* Scroll up */ else if (ke.key.code == ARROW_UP) { if (top_line) top_line--; } /* Page up */ else if (ke.key.code == '-') { top_line -= (Term->hgt - 2) / 2; if (top_line < 0) top_line = 0; } /* Scroll left */ else if (ke.key.code == ARROW_LEFT) { if (col) col--; } /* Scroll right */ else if (ke.key.code == ARROW_RIGHT) { if (col < 32) col++; } /* Oops */ else { bell(NULL); } /* Flush messages */ message_flush(); } /* Adjust the buttons */ button_restore(); /* Load screen */ screen_load(); }