/* ------------------------------------------------------------------------ * Quickstart? screen. * ------------------------------------------------------------------------ */ static enum birth_stage get_quickstart_command(void) { const char *prompt = "['Y' to use this character, 'N' to start afresh, 'C' to change name]"; enum birth_stage next = BIRTH_QUICKSTART; /* Prompt for it */ prt("New character based on previous one:", 0, 0); prt(prompt, Term->hgt - 1, Term->wid / 2 - strlen(prompt) / 2); /* Buttons */ button_kill_all(); button_add("[Y]", 'y'); button_add("[N]", 'n'); button_add("[C]", 'c'); redraw_stuff(p_ptr); do { /* Get a key */ struct keypress ke = inkey(); if (ke.code == 'N' || ke.code == 'n') { cmd_insert(CMD_BIRTH_RESET); next = BIRTH_SEX_CHOICE; } else if (ke.code == KTRL('X')) { cmd_insert(CMD_QUIT); next = BIRTH_COMPLETE; } else if (ke.code == 'C' || ke.code == 'c') { next = BIRTH_NAME_CHOICE; } else if (ke.code == 'Y' || ke.code == 'y') { cmd_insert(CMD_ACCEPT_CHARACTER); next = BIRTH_COMPLETE; } } while (next == BIRTH_QUICKSTART); /* Buttons */ button_kill_all(); redraw_stuff(p_ptr); /* Clear prompt */ clear_from(23); return next; }
void display_popup_win (INPUT_POPUP *ipu, const char* label) { widget_list *wok; widget_list *wno; if(ipu->popup_win < 0) { Uint32 flags = ELW_WIN_DEFAULT & ~ELW_CLOSE_BOX; ipu->popup_win = create_window (win_prompt, ipu->parent, 0, ipu->x, ipu->y, ipu->popup_x_len, ipu->popup_y_len, flags); // clear the buffer init_text_message (&ipu->popup_text, ipu->maxlen); set_text_message_color (&ipu->popup_text, 0.77f, 0.57f, 0.39f); // Label ipu->popup_label = label_add (ipu->popup_win, NULL, label, 5, 5); widget_set_color (ipu->popup_win, ipu->popup_label, 0.77f, 0.57f, 0.39f); // Input ipu->popup_field = text_field_add_extended (ipu->popup_win, 101, NULL, 5, 28, ipu->popup_x_len - 10, 28*ipu->rows, ipu->text_flags, 1.0f, 0.77f, 0.57f, 0.39f, &ipu->popup_text, 1, FILTER_ALL, 5, 5); widget_set_color (ipu->popup_win, ipu->popup_field, 0.77f, 0.57f, 0.39f); // Accept ipu->popup_ok = button_add (ipu->popup_win, NULL, button_okay, 0, 0); widget_set_OnClick (ipu->popup_win, ipu->popup_ok, popup_ok_button_handler); widget_set_color (ipu->popup_win, ipu->popup_ok, 0.77f, 0.57f, 0.39f); // Reject ipu->popup_no = button_add (ipu->popup_win, NULL, button_cancel, 0, 0); widget_set_OnClick (ipu->popup_win, ipu->popup_no, popup_cancel_button_handler); widget_set_color (ipu->popup_win, ipu->popup_no, 0.77f, 0.57f, 0.39f); // align the buttons wok = widget_find(ipu->popup_win, ipu->popup_ok); wno = widget_find(ipu->popup_win, ipu->popup_no); widget_move(ipu->popup_win, ipu->popup_ok, (ipu->popup_x_len - wok->len_x - wno->len_x)/3, ipu->popup_y_len - (wok->len_y + 5)); widget_move(ipu->popup_win, ipu->popup_no, wok->len_x + 2*(ipu->popup_x_len - wok->len_x - wno->len_x)/3, ipu->popup_y_len - (wno->len_y + 5)); set_window_handler (ipu->popup_win, ELW_HANDLER_KEYPRESS, popup_keypress_handler); if ((ipu->popup_win > -1) && (ipu->popup_win < windows_list.num_windows)) windows_list.window[ipu->popup_win].data = ipu; } else { if ((ipu->parent > -1) && (ipu->parent < windows_list.num_windows)) { window_info *win = &windows_list.window[ipu->parent]; move_window(ipu->popup_win, ipu->parent, 0, win->pos_x+ipu->x, win->pos_y+ipu->y); } text_field_clear(ipu->popup_win, ipu->popup_field); label_set_text (ipu->popup_win, ipu->popup_label, label); show_window (ipu->popup_win); select_window (ipu->popup_win); } }
/* ------------------------------------------------------------------------ * Quickstart? screen. * ------------------------------------------------------------------------ */ static enum birth_stage get_quickstart_command(void) { const char *prompt = "['Y' to use this character, 'N' to start afresh, 'C' to change name]"; ui_event_data ke; enum birth_stage next = BIRTH_QUICKSTART; /* Prompt for it */ prt("New character based on previous one:", 0, 0); prt(prompt, Term->hgt - (mouse_buttons ? 2 : 1), Term->wid / 2 - strlen(prompt) / 2); /* Buttons */ button_kill_all(); button_add("[YES]", 'y'); button_add("[START_OVER]", 'n'); button_add("[CHANGE_NAME]", 'c'); redraw_stuff(); event_signal(EVENT_MOUSEBUTTONS); do { /* Get a key */ ke = inkey_ex(); if (ke.key == 'N' || ke.key == 'n') { cmd_insert(CMD_BIRTH_RESET, TRUE); next = BIRTH_SEX_CHOICE; } else if (ke.key == KTRL('X')) { cmd_insert(CMD_QUIT); next = BIRTH_COMPLETE; } else if (ke.key == 'C' || ke.key == 'c') { next = BIRTH_NAME_CHOICE; } else if (ke.key == 'Y' || ke.key == 'y') { cmd_insert(CMD_ACCEPT_CHARACTER); next = BIRTH_COMPLETE; } } while (next == BIRTH_QUICKSTART); /* Buttons */ button_kill_all(); handle_stuff(); event_signal(EVENT_MOUSEBUTTONS); /* Clear prompt */ clear_from(23); return next; }
void fill_notepad_window() { int i, tmp; widget_list *wnew; widget_list *wsave; int note_tabs_width = notepad_win_x_len; int note_tabs_height = notepad_win_y_len - 5; note_button_scroll_height = note_tabs_height - 55 - 20; // -20 for the tab tags note_button_width = (note_tabs_width - note_button_scroll_width - note_button_x_space - 15) / 2; set_window_handler(notepad_win, ELW_HANDLER_DISPLAY, &display_notepad_handler); set_window_handler(notepad_win, ELW_HANDLER_CLICK, &click_buttonwin_handler); note_tabcollection_id = tab_collection_add (notepad_win, NULL, 0, 5, note_tabs_width, note_tabs_height, 20); widget_set_size (notepad_win, note_tabcollection_id, 0.7); widget_set_color (notepad_win, note_tabcollection_id, 0.77f, 0.57f, 0.39f); main_note_tab_id = tab_add (notepad_win, note_tabcollection_id, tab_main, 0, 0, 0); widget_set_color (notepad_win, main_note_tab_id, 0.77f, 0.57f, 0.39f); set_window_handler(main_note_tab_id, ELW_HANDLER_CLICK, &click_buttonwin_handler); // Add Category new_note_button_id = button_add(main_note_tab_id, NULL, button_new_category, 0, 0); widget_set_OnClick(main_note_tab_id, new_note_button_id, notepad_add_category); widget_set_color(main_note_tab_id, new_note_button_id, 0.77f, 0.57f, 0.39f); // Save Notes save_notes_button_id = button_add(main_note_tab_id, NULL, button_save_notes, 0, 0); widget_set_OnClick(main_note_tab_id, save_notes_button_id, click_save_handler); widget_set_color(main_note_tab_id, save_notes_button_id, 0.77f, 0.57f, 0.39f); // align the buttons wnew = widget_find(main_note_tab_id, new_note_button_id); wsave = widget_find(main_note_tab_id, save_notes_button_id); tmp = (notepad_win_x_len - note_button_scroll_width)/2; widget_move(main_note_tab_id, new_note_button_id, (tmp - wnew->len_x)/2, 10); widget_move(main_note_tab_id, save_notes_button_id, tmp + (tmp - wsave->len_x)/2, 10); notepad_load_file (); init_ipu (&popup_str, main_note_tab_id, NOTE_NAME_LEN*DEFAULT_FONT_X_LEN, 100, NOTE_NAME_LEN, 1, NULL, notepad_add_continued); popup_str.x = (notepad_win_x_len - popup_str.popup_x_len) / 2; popup_str.y = (notepad_win_y_len - popup_str.popup_y_len) / 2; note_button_scroll_id = vscrollbar_add (main_note_tab_id, NULL, note_tabs_width - note_button_scroll_width - 5, 50, note_button_scroll_width, note_button_scroll_height); widget_set_OnClick (main_note_tab_id, note_button_scroll_id, note_button_scroll_handler); widget_set_OnDrag (main_note_tab_id, note_button_scroll_id, note_button_scroll_handler); // Add the note selection buttons and their scroll bar for(i = 0; i < nr_notes; i++) note_button_add (i, i); update_note_button_scrollbar (0); }
/* ------------------------------------------------------------------------ * Final confirmation of character. * ------------------------------------------------------------------------ */ static enum birth_stage get_confirm_command(void) { const char *prompt = "['ESC' to step back, 'S' to start over, or any other key to continue]"; ui_event_data ke; enum birth_stage next; /* Prompt for it */ prt(prompt, Term->hgt - (mouse_buttons ? 2 : 1), Term->wid / 2 - strlen(prompt) / 2); /* Buttons */ button_kill_all(); button_add("[CONTINUE]", 'q'); button_add("[BACK]", ESCAPE); button_add("[START OVER]", 'S'); handle_stuff(); event_signal(EVENT_MOUSEBUTTONS); /* Get a key */ ke = inkey_ex(); /* Start over */ if (ke.key == 'S' || ke.key == 's') { next = BIRTH_RESET; } else if (ke.key == KTRL('X')) { cmd_insert(CMD_QUIT); next = BIRTH_COMPLETE; } else if (ke.key == ESCAPE) { next = BIRTH_BACK; } else { cmd_insert(CMD_ACCEPT_CHARACTER); next = BIRTH_COMPLETE; } /* Buttons */ button_kill_all(); handle_stuff(); event_signal(EVENT_MOUSEBUTTONS); /* Clear prompt */ clear_from(23); return next; }
/* * Ask the user to respond with a character. Options is a constant string, * e.g. "yns"; len is the length of the constant string, and fallback should * be the default answer if the user hits escape or an invalid key. * * Example: get_char("Study? ", "yns", 3, 'n') * This prompts "Study? [yns]" and defaults to 'n'. * */ char get_char(const char *prompt, const char *options, size_t len, char fallback) { size_t i; struct keypress key; char button[4], buf[80]; bool repeat = FALSE; /* Paranoia XXX XXX XXX */ message_flush(); /* Hack -- Build a "useful" prompt */ strnfmt(buf, 78, "%.70s[%s] ", prompt, options); /* Hack - kill the repeat button */ if (button_kill('n')) repeat = TRUE; /* Make some buttons */ for (i = 0; i < len; i++) { strnfmt(button, 4, "[%c]", options[i]); button_add(button, options[i]); } redraw_stuff(p_ptr); /* Prompt for it */ prt(buf, 0, 0); /* Get an acceptable answer */ key = inkey(); /* Lowercase answer if necessary */ if (key.code >= 'A' && key.code <= 'Z') key.code += 32; /* See if key is in our options string */ if (!strchr(options, (char)key.code)) key.code = fallback; /* Kill the buttons */ for (i = 0; i < len; i++) button_kill(options[i]); /* Hack - restore the repeat button */ if (repeat) button_add("[Rpt]", 'n'); redraw_stuff(p_ptr); /* Erase the prompt */ prt("", 0, 0); /* Success */ return key.code; }
/* ------------------------------------------------------------------------ * Final confirmation of character. * ------------------------------------------------------------------------ */ static enum birth_stage get_confirm_command(void) { const char *prompt = "['ESC' to step back, 'S' to start over, or any other key to continue]"; struct keypress ke; enum birth_stage next; /* Prompt for it */ prt(prompt, Term->hgt - 1, Term->wid / 2 - strlen(prompt) / 2); /* Buttons */ button_kill_all(); button_add("[Continue]", 'q'); button_add("[ESC]", ESCAPE); button_add("[S]", 'S'); redraw_stuff(p_ptr); /* Get a key */ ke = inkey(); /* Start over */ if (ke.code == 'S' || ke.code == 's') { next = BIRTH_RESET; } else if (ke.code == KTRL('X')) { cmd_insert(CMD_QUIT); next = BIRTH_COMPLETE; } else if (ke.code == ESCAPE) { next = BIRTH_BACK; } else { cmd_insert(CMD_ACCEPT_CHARACTER); next = BIRTH_COMPLETE; } /* Buttons */ button_kill_all(); redraw_stuff(p_ptr); /* Clear prompt */ clear_from(23); return next; }
static void open_note_tab_continued(int id) { int tf_x = 10; int tf_y = 45; int tf_width = notepad_win_x_len - 20; int tf_height = notepad_win_y_len - 80; int tab; note_list[id].window = tab_add (notepad_win, note_tabcollection_id, note_list[id].name, 0, 1, 0); widget_set_color (notepad_win, note_list[id].window, 0.77f, 0.57f, 0.39f); // input text field note_list[id].input = text_field_add_extended(note_list[id].window, note_widget_id++, NULL, tf_x, tf_y, tf_width, tf_height, TEXT_FIELD_BORDER|TEXT_FIELD_EDITABLE|TEXT_FIELD_CAN_GROW|TEXT_FIELD_SCROLLBAR, note_zoom, 0.77f, 0.57f, 0.39f, ¬e_list[id].text, 1, FILTER_ALL, 5, 5); // remove button note_list[id].button = button_add (note_list[id].window, NULL, button_remove_category, 20, 8); widget_set_OnClick(note_list[id].window, note_list[id].button, notepad_remove_category); widget_set_color(note_list[id].window, note_list[id].button, 0.77f, 0.57f, 0.39f); widget_set_OnMouseover(note_list[id].window, note_list[id].button, mouseover_remove_handler); set_window_handler (note_list[id].window, ELW_HANDLER_DESTROY, note_tab_destroy); tab = tab_collection_get_tab_nr (notepad_win, note_tabcollection_id, note_list[id].window); tab_collection_select_tab (notepad_win, note_tabcollection_id, tab); }
/* * Verify something with the user * * The "prompt" should take the form "Query? " * * Note that "[y/n]" is appended to the prompt. */ bool get_check(const char *prompt) { //struct keypress ke; ui_event ke; char buf[80]; bool repeat = FALSE; /* Paranoia XXX XXX XXX */ message_flush(); /* Hack -- Build a "useful" prompt */ strnfmt(buf, 78, "%.70s[y/n] ", prompt); /* Hack - kill the repeat button */ if (button_kill('n')) repeat = TRUE; /* Make some buttons */ button_add("[y]", 'y'); button_add("[n]", 'n'); redraw_stuff(p_ptr); /* Prompt for it */ prt(buf, 0, 0); ke = inkey_m(); /* Kill the buttons */ button_kill('y'); button_kill('n'); /* Hack - restore the repeat button */ if (repeat) button_add("[Rpt]", 'n'); redraw_stuff(p_ptr); /* Erase the prompt */ prt("", 0, 0); /* Normal negation */ if (ke.type == EVT_MOUSE) { if ((ke.mouse.button != 1) && (ke.mouse.y != 0)) return (FALSE); } else if ((ke.key.code != 'Y') && (ke.key.code != 'y')) return (FALSE); /* Success */ return (TRUE); }
/** * 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; }
/* * Re-set and add the basic buttons * More are added in process_player depending on the * situation. */ void basic_buttons(void) { button_kill_all(); /* Make basic mouse buttons */ (void) button_add("[MENU]", KTRL('H')); (void) button_add("[HELP]", '?'); (void) button_add("[OPT]", '='); (void) button_add("[REPEAT]", KTRL('V')); if ((p_ptr->chp < p_ptr->mhp) || (p_ptr->csp < p_ptr->msp)) button_add("[REST]", 'R'); if ((cp_ptr->spell_book) && (p_ptr->csp)) button_add("[CAST]", 'm'); (void) button_add("[ITEM_MENU]", '|'); }
/** * Hack -- save a screen dump to a file */ void do_cmd_save_screen(void) { ui_event ke; msg("Dump type [(t)ext; (h)tml; (f)orum embedded html]:"); button_add("f", 'f'); button_add("h", 'h'); button_add("t", 't'); ke = inkey_ex(); switch(ke.key.code) { case ESCAPE: break; case 't': do_cmd_save_screen_text(); break; case 'h': do_cmd_save_screen_html(0); break; case 'f': do_cmd_save_screen_html(1); break; } button_kill('f'); button_kill('t'); button_kill('h'); message_flush(); }
/* * Restore the buttons from backup */ void button_restore(void) { int i = 0; /* Remove the current lot */ button_kill_all(); /* Get all the previous buttons, copy them back */ while (button_backup[i].key) { /* Add them all back, forget the backups */ button_add(button_backup[i].label, button_backup[i].key); button_backup[i].key = '\0'; i++; } }
char* setparsed(char *c, char **v) { char type[2], *argv[2]; unsigned int i; if(!v[0] || !v[1]) return "Nothing to parse."; if(isalpha(c[0])) { argv[0] = v[1]; argv[1] = NULL; return var_set(v[0], argv); } else if(c[0] != '<') return "Invalid first char."; if(strstr(v[0], "Button")) return button_add(v[0], v[1]); memset(&type, '-', sizeof(type)); for(i = 0; v[i] && i < LEN(type); i++) type[i] = (c[i + 2] == '\'' ? 'c' : (isdigit(c[i + 2]) ? 'i' : (c[i + 2] == '<' ? 'm' : (isalpha(c[i + 2]) ? 'n' : '-')))); for(i = 0; i < LEN(argv); i++) argv[i] = v[i + 2]; return key_add(v[0], v[1], &argv, &type); }
/** * Make the correct prompt for items, handle mouse buttons */ void item_prompt(int mode) { char tmp_val[160]; char out_val[160]; bool use_inven = ((mode & USE_INVEN) ? TRUE : FALSE); bool use_equip = ((mode & USE_EQUIP) ? TRUE : FALSE); bool can_squelch = ((mode & CAN_SQUELCH) && !show_list ? TRUE : FALSE); bool allow_floor = (f1 <= f2); /* Viewing inventory */ if (p_ptr->command_wrk == USE_INVEN) { /* 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("[-]", '-'); } /* Indicate that squelched items can be selected */ if (can_squelch) { my_strcat(out_val, " ! for squelched,", sizeof(out_val)); button_add("[!]", '!'); } } /* Viewing equipment */ else if (p_ptr->command_wrk == USE_EQUIP) { /* 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 { /* 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("[/]", '/'); } /* Indicate that squelched items can be selected */ if (can_squelch) { my_strcat(out_val, " ! for squelched,", sizeof(out_val)); button_add("[!]", '!'); } } /* Finish the prompt */ my_strcat(out_val, " ESC", sizeof(out_val)); /* Build the prompt */ strnfmt(tmp_val, sizeof(tmp_val), "(%s) %s", out_val, prompt); /* Show the prompt */ prt(tmp_val, 0, 0); }
static enum birth_stage roller_command(bool first_call) { char prompt[80] = ""; size_t promptlen = 0; struct keypress 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); if (first_call) prev_roll = FALSE; /* Add buttons */ button_add("[ESC]", ESCAPE); button_add("[Enter]", '\r'); button_add("[r]", 'r'); if (prev_roll) button_add("[p]", 'p'); clear_from(Term->hgt - 2); redraw_stuff(p_ptr); /* 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 - 1, Term->wid / 2 - promptlen / 2); /* Prompt and get a command */ ch = inkey(); if (ch.code == ESCAPE) { button_kill('r'); button_kill('p'); next = BIRTH_BACK; } /* 'Enter' accepts the roll */ if ((ch.code == '\r') || (ch.code == '\n')) { next = BIRTH_NAME_CHOICE; } /* Reroll this character */ else if ((ch.code == ' ') || (ch.code == 'r')) { cmd_insert(CMD_ROLL_STATS); prev_roll = TRUE; } /* Previous character */ else if (prev_roll && (ch.code == 'p')) { cmd_insert(CMD_PREV_STATS); } /* Quit */ else if (ch.code == KTRL('X')) { cmd_insert(CMD_QUIT); next = BIRTH_COMPLETE; } /* Help XXX */ else if (ch.code == '?') { do_cmd_help(); } /* Nothing handled directly here */ else { bell("Illegal roller command!"); } /* Kill buttons */ button_kill(ESCAPE); button_kill('\r'); button_kill('r'); button_kill('p'); redraw_stuff(p_ptr); return next; }
/** * 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(); }
/** * 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(); }
/* * Handle "target" and "look". * * Note that this code can be called from "get_aim_dir()". * * Currently, when "flag" is true, that is, when * "interesting" grids are being used, and a directional key is used, we * only scroll by a single panel, in the direction requested, and check * for any interesting grids on that panel. The "correct" solution would * actually involve scanning a larger set of grids, including ones in * panels which are adjacent to the one currently scanned, but this is * overkill for this function. XXX XXX * * Hack -- targetting/observing an "outer border grid" may induce * problems, so this is not currently allowed. * * The player can use the direction keys to move among "interesting" * grids in a heuristic manner, or the "space", "+", and "-" keys to * move through the "interesting" grids in a sequential manner, or * can enter "location" mode, and use the direction keys to move one * grid at a time in any direction. The "t" (set target) command will * only target a monster (as opposed to a location) if the monster is * target_able and the "interesting" mode is being used. * * The current grid is described using the "look" method above, and * a new command may be entered at any time, but note that if the * "TARGET_LOOK" bit flag is set (or if we are in "location" mode, * where "space" has no obvious meaning) then "space" will scan * through the description of the current grid until done, instead * of immediately jumping to the next "interesting" grid. This * allows the "target" command to retain its old semantics. * * The "*", "+", and "-" keys may always be used to jump immediately * to the next (or previous) interesting grid, in the proper mode. * * The "return" key may always be used to scan through a complete * grid description (forever). * * This command will cancel any old target, even if used from * inside the "look" command. * * 'mode' is one of TARGET_LOOK or TARGET_KILL. * 'x' and 'y' are the initial position of the target to be highlighted, * or -1 if no location is specified. * Returns TRUE if a target has been successfully set, FALSE otherwise. */ bool target_set_interactive(int mode, int x, int y) { int py = p_ptr->py; int px = p_ptr->px; int i, d, m, t, bd; int wid, hgt, help_prompt_loc; bool done = FALSE; bool flag = TRUE; bool help = FALSE; bool list_floor_objects = auto_display_lists; u16b path_n; u16b path_g[PATH_SIZE]; u16b path_gx[PATH_SIZE]; ui_event_data query; char info[80]; /* These are used for displaying the path to the target */ char path_char[MAX_RANGE]; byte path_attr[MAX_RANGE]; /* If we haven't been given an initial location, start on the player. */ if (x == -1 || y == -1) { x = p_ptr->px; y = p_ptr->py; } /* If we /have/ been given an initial location, make sure we honour it by going into "free targeting" mode. */ else { flag = FALSE; } /* Cancel target */ target_set_monster(0); /* make some buttons */ button_backup_all(); button_kill_all(); button_add("[ESCAPE]", ESCAPE); button_add("[NEXT]", '+'); button_add("[PREV]", '-'); button_add("[PLAYER]", 'p'); button_add("[PATHFIND]", 'g'); button_add("[TARGET]", 't'); /* health_track(0); */ /* All grids are selectable */ if (mode & (TARGET_GRID)) { /* Disable other modes */ mode &= ~(TARGET_LOOK | TARGET_KILL | TARGET_TRAP); /* Disable interesting grids */ flag = FALSE; } /* Calculate the window location for the help prompt */ Term_get_size(&wid, &hgt); help_prompt_loc = hgt - (mouse_buttons ? 2 : 1); /* Display the help prompt */ prt("'?' - help", help_prompt_loc, 0); /* Prepare the "temp" array */ target_set_interactive_prepare(mode); /* Start near the player */ m = 0; /* Interact */ while (!done) { button_kill('l'); button_kill('?'); if (list_floor_objects) { button_add("[HIDE_OBJLIST]", 'l'); } else button_add("[SHOW_OBJLIST]", 'l'); if (help) { button_add("[HIDE_HELP]", '?'); } else button_add("[SHOW_HELP]",'?'); /* Interesting grids */ if (flag && temp_n) { bool path_drawn = FALSE; int yy, xx; y = temp_y[m]; x = temp_x[m]; button_add("[SCAN]",'o'); /* Update help */ if (help) { bool good_target = ((cave_m_idx[y][x] > 0) && target_able(cave_m_idx[y][x])); target_display_help(good_target, !(flag && temp_n)); } /* Dummy pointers to send to project_path */ yy = y; xx = x; /* Allow targets for monsters....or traps, if applicable */ if (((cave_m_idx[y][x] > 0) && target_able(cave_m_idx[y][x])) || ((mode & (TARGET_TRAP)) && target_able_trap(y, x))) { strcpy(info, "q,t,r,l,p,o,+,-,<dir>"); } /* Dis-allow target */ else { strcpy(info, "q,p,l,o,+,-,<dir>"); } /* Adjust panel if needed */ if (adjust_panel(y, x)) { /* Handle stuff */ handle_stuff(); } /* Find the path. */ path_n = project_path(path_g, path_gx, MAX_RANGE, py, px, &yy, &xx, PROJECT_THRU); /* Draw the path in "target" mode. If there is one */ if ((mode & (TARGET_KILL)) && (cave_info[y][x] & (CAVE_FIRE))) { path_drawn = draw_path(path_n, path_g, path_char, path_attr, py, px, y, x); } event_signal(EVENT_MOUSEBUTTONS); /* Describe and Prompt */ query = target_set_interactive_aux(y, x, mode, info, list_floor_objects); /* Remove the path */ if (path_drawn) load_path(path_n, path_g, path_char, path_attr); /* Cancel tracking */ /* health_track(0); */ /* Assume no "direction" */ d = 0; /* Analyze */ switch (query.key) { case ESCAPE: case 'q': { done = TRUE; break; } case ' ': case '*': case '+': { if (++m == temp_n) m = 0; break; } case '-': { if (m-- == 0) m = temp_n - 1; break; } case 'p': { /* Recenter around player */ verify_panel(); /* Handle stuff */ handle_stuff(); y = py; x = px; } case 'o': { flag = FALSE; break; } case 'm': { break; } /* If we click, move the target location to the click and switch to "free targetting" mode by unsetting 'flag'. This means we get some info about wherever we've picked. */ case DEFINED_XFF: { x = KEY_GRID_X(query); y = KEY_GRID_Y(query); flag = FALSE; break; } case 't': case '5': case '0': case '.': { int m_idx = cave_m_idx[y][x]; if ((m_idx > 0) && target_able(m_idx)) { health_track(m_idx); target_set_monster(m_idx); done = TRUE; } else if ((mode & (TARGET_TRAP)) && target_able_trap(y, x)) { target_set_location(y, x); done = TRUE; } else if (mode & (TARGET_PROBE)) { target_set_location(y, x); done = TRUE; } else { bell("Illegal target!"); } break; } case 'g': { cmd_insert(CMD_PATHFIND, y, x); done = TRUE; break; } case 'l': { list_floor_objects = (!list_floor_objects); } case '?': { help = !help; /* Redraw main window */ p_ptr->redraw |= (PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIP); Term_clear(); handle_stuff(); if (!help) prt("'?' - help", help_prompt_loc, 0); break; } default: { /* Extract direction */ d = target_dir(query.key); /* Oops */ if (!d) bell("Illegal command for target mode!"); break; } } /* Hack -- move around */ if (d) { int old_y = temp_y[m]; int old_x = temp_x[m]; /* Find a new monster */ i = target_pick(old_y, old_x, ddy[d], ddx[d]); /* Scroll to find interesting grid */ if (i < 0) { int old_wy = Term->offset_y; int old_wx = Term->offset_x; /* Change if legal */ if (change_panel(d)) { /* Recalculate interesting grids */ target_set_interactive_prepare(mode); /* Find a new monster */ i = target_pick(old_y, old_x, ddy[d], ddx[d]); /* Restore panel if needed */ if ((i < 0) && modify_panel(Term, old_wy, old_wx)) { /* Recalculate interesting grids */ target_set_interactive_prepare(mode); } /* Handle stuff */ handle_stuff(); } } /* Use interesting grid if found */ if (i >= 0) m = i; } } /* Arbitrary grids */ else { bool path_drawn = FALSE; /* Dummy pointers to send to project_path */ int yy = y; int xx = x; /* Don't need this button any more */ button_kill('o'); /* Update help */ if (help) { bool good_target = ((cave_m_idx[y][x] > 0) && target_able(cave_m_idx[y][x])); target_display_help(good_target, !(flag && temp_n)); } /* Default prompt */ if (!(mode & (TARGET_GRID))) { strcpy(info, "q,t,l,p,m,+,-,<dir>"); } /* Disable monster selection */ else { strcpy(info, "q,t,l.p,+,-,<dir>"); } /* Find the path. */ path_n = project_path(path_g, path_gx, MAX_RANGE, py, px, &yy, &xx, PROJECT_THRU); /* Draw the path in "target" mode. If there is one */ if ((mode & (TARGET_KILL)) && (cave_info[y][x] & (CAVE_FIRE))) { /* Save target info */ path_drawn = draw_path(path_n, path_g, path_char, path_attr, py, px, y, x); } event_signal(EVENT_MOUSEBUTTONS); /* Describe and Prompt (enable "TARGET_LOOK") */ query = target_set_interactive_aux(y, x, (mode | TARGET_LOOK), info, list_floor_objects); /* Remove the path */ if (path_drawn) load_path(path_n, path_g, path_char, path_attr); /* Cancel tracking */ /* health_track(0); */ /* Assume no direction */ d = 0; /* Analyze the keypress */ switch (query.key) { case ESCAPE: case 'q': { done = TRUE; break; } case ' ': case '*': case '+': case '-': { break; } case 'p': { /* Recenter around player */ verify_panel(); /* Handle stuff */ handle_stuff(); y = py; x = px; } case 'o': { break; } case 'm': { /* Monster selection is disabled */ if (mode & (TARGET_GRID)) break; flag = TRUE; m = 0; bd = 999; /* Pick a nearby monster */ for (i = 0; i < temp_n; i++) { t = distance(y, x, temp_y[i], temp_x[i]); /* Pick closest */ if (t < bd) { m = i; bd = t; } } /* Nothing interesting */ if (bd == 999) flag = FALSE; break; } case '\xff': { /* We only target if we click somewhere where the cursor is already (i.e. a double-click without a time limit) */ if (KEY_GRID_X(query) == x && KEY_GRID_Y(query) == y) { /* Make an attempt to target the monster on the given square rather than the square itself (it seems this is the more likely intention of clicking on a monster). */ int m_idx = cave_m_idx[y][x]; if ((m_idx > 0) && target_able(m_idx)) { health_track(m_idx); target_set_monster(m_idx); } else { /* There is no monster, or it isn't targettable, so target the location instead. */ target_set_location(y, x); } done = TRUE; } else { /* Just move the cursor for now - another click will target. */ x = KEY_GRID_X(query); y = KEY_GRID_Y(query); } break; } case 't': case '5': case '0': case '.': { target_set_location(y, x); done = TRUE; break; } case 'g': { cmd_insert(CMD_PATHFIND, y, x); done = TRUE; break; } case 'l': { list_floor_objects = (!list_floor_objects); } case '?': { help = !help; /* Redraw main window */ p_ptr->redraw |= (PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIP); Term_clear(); handle_stuff(); if (!help) prt("'?' - help.", help_prompt_loc, 0); break; } default: { /* Extract a direction */ d = target_dir(query.key); /* Oops */ if (!d) bell("Illegal command for target mode!"); break; } } /* Handle "direction" */ if (d) { int dungeon_hgt = p_ptr->cur_map_hgt; int dungeon_wid = p_ptr->cur_map_wid; /* Move */ x += ddx[d]; y += ddy[d]; /* Slide into legality */ if (x >= dungeon_wid - 1) x--; else if (x <= 0) x++; /* Slide into legality */ if (y >= dungeon_hgt - 1) y--; else if (y <= 0) y++; /* Adjust panel if needed */ if (adjust_panel(y, x)) { /* Handle stuff */ handle_stuff(); /* Recalculate interesting grids */ target_set_interactive_prepare(mode); } } } } /* Forget */ temp_n = 0; /* Redraw as necessary */ if (help) { p_ptr->redraw |= (PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIP); Term_clear(); } else { prt("", 0, 0); prt("", help_prompt_loc, 0); p_ptr->redraw |= (PR_DEPTH | PR_STATUS); } /* Recenter around player */ verify_panel(); /* Restore buttons */ button_restore(); /* Handle stuff */ handle_stuff(); /* Failure to set target */ if (!p_ptr->target_set) return (FALSE); /* Success */ return (TRUE); }
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; }
/* Allow the user to select from the current menu, and return the corresponding command to the game. Some actions are handled entirely by the UI (displaying help text, for instance). */ static enum birth_stage menu_question(enum birth_stage current, menu_type *current_menu, cmd_code choice_command) { struct birthmenu_data *menu_data = current_menu->menu_data; int cursor = current_menu->cursor; ui_event_data cx; enum birth_stage next = BIRTH_RESET; /* Print the question currently being asked. */ clear_question(); Term_putstr(QUESTION_COL, QUESTION_ROW, -1, TERM_YELLOW, menu_data->hint); current_menu->cmd_keys = "?=*\r\n\x18"; /* ?, ,= *, \n, <ctl-X> */ while (next == BIRTH_RESET) { button_kill_all(); button_add("[ENTER]", '\r'); if (menu_data->allow_random) button_add("[RANDOM]", '*'); button_add("[ESCAPE]", ESCAPE); button_add("[OPTIONS]", '='); button_add("[HELP]", '?'); button_add("[QUIT]", '\x18'); /* CTRL-X */ event_signal(EVENT_MOUSEBUTTONS); /* Display the menu, wait for a selection of some sort to be made. */ cx = menu_select(current_menu, &cursor, EVT_CMD); /* As all the menus are displayed in "hierarchical" style, we allow use of "back" (left arrow key or equivalent) to step back in the proces as well as "escape". */ if (cx.type == EVT_BACK || cx.type == EVT_ESCAPE || cx.key == ESCAPE) { next = BIRTH_BACK; } /* '\xff' or DEFINED_XFF is a mouse selection, '\r' a keyboard one. */ else if (cx.key == DEFINED_XFF || cx.key == '\r') { if (current == BIRTH_ROLLER_CHOICE) { if (cursor) { /* Do a first roll of the stats */ cmd_insert(CMD_ROLL_STATS); next = current + 2; } else { /* * Make sure we've got a point-based char to play with. * We call point_based_start here to make sure we get * an update on the points totals before trying to * display the screen. The call to CMD_RESET_STATS * forces a rebuying of the stats to give us up-to-date * totals. This is, it should go without saying, a hack. */ point_based_start(); cmd_insert(CMD_RESET_STATS, TRUE); next = current + 1; } } else { cmd_insert(choice_command, cursor); next = current + 1; } } /* '*' chooses an option at random from those the game's provided. */ else if (cx.key == '*' && menu_data->allow_random) { current_menu->cursor = randint0(current_menu->count); cmd_insert(choice_command, current_menu->cursor); menu_refresh(current_menu); next = current + 1; } else if (cx.key == '=') { do_cmd_options(); next = current; } else if (cx.key == KTRL('X')) { cmd_insert(CMD_QUIT); next = BIRTH_COMPLETE; } else if (cx.key == '?') { do_cmd_help(); } } 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(); }
/* * 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) { int py = p_ptr->py; int px = p_ptr->px; unsigned char cmdkey = cmd_lookup_key(cmd, OPT(rogue_like_commands) ? KEYMAP_MODE_ROGUE : KEYMAP_MODE_ORIG); //struct keypress which; ui_event press; 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 is_harmless = ((mode & IS_HARMLESS) ? TRUE : FALSE); bool quiver_tags = ((mode & QUIVER_TAGS) ? TRUE : FALSE); int 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; /* Hack - Only shift the command key if it actually needs to be shifted. */ if (cmdkey < 0x20) cmdkey = UN_KTRL(cmdkey); /* 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; if (mode & SHOW_EMPTY) olist_mode |= OLIST_SEMPTY; /* 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, 0x0B); /* 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) && allow_equip) p_ptr->command_wrk = USE_EQUIP; else if ((p_ptr->command_wrk == USE_INVEN) && allow_inven) p_ptr->command_wrk = USE_INVEN; else if ((p_ptr->command_wrk == USE_FLOOR) && allow_floor) p_ptr->command_wrk = USE_FLOOR; /* If we are using the quiver then start on equipment */ else if (quiver_tags && allow_equip) p_ptr->command_wrk = USE_EQUIP; /* Use inventory if allowed */ else if (use_inven && allow_inven) p_ptr->command_wrk = USE_INVEN; /* Use equipment if allowed */ else if (use_equip && allow_equip) p_ptr->command_wrk = USE_EQUIP; /* Use floor if allowed */ else if (use_floor && allow_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 < 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); /* Viewing inventory */ if (p_ptr->command_wrk == USE_INVEN) { int nmode = olist_mode; /* Show the quiver counts in certain cases, like the 'i' command */ if (mode & SHOW_QUIVER) nmode |= OLIST_QUIVER; /* Redraw if needed */ if (show_list) show_inven(nmode); /* 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(p_ptr); /* Finish the prompt */ my_strcat(out_val, " ESC", sizeof(out_val)); /* if we have a prompt header, show the part that we just built */ if (pmt) { /* 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(); press = inkey_m(); /* Parse it */ if (press.type == EVT_MOUSE) { if (press.mouse.button == 2) { done = TRUE; } else if (press.mouse.button == 1) { k = -1; if (p_ptr->command_wrk == USE_INVEN) { if (press.mouse.y == 0) { if (use_equip) { p_ptr->command_wrk = USE_EQUIP; } else if (allow_floor) { p_ptr->command_wrk = USE_FLOOR; } } else if ((press.mouse.y <= i2-i1+1) ){ //&& (press.mouse.x > Term->wid - 1 - max_len - ex_width)) { //k = label_to_inven(index_to_label(i1+press.mouse.y-1)); /* get the item index, allowing for skipped indices */ for (j = i1; j <= i2; j++) { if (get_item_okay(j)) { if (press.mouse.y == 1) { k = j; break; } press.mouse.y--; } } } } else if (p_ptr->command_wrk == USE_EQUIP) { if (press.mouse.y == 0) { if (allow_floor) { p_ptr->command_wrk = USE_FLOOR; } else if (use_inven) { p_ptr->command_wrk = USE_INVEN; } } else if (press.mouse.y <= e2-e1+1) { if (olist_mode & OLIST_SEMPTY) { /* If we are showing empties, just set the object (empty objects will just keep the loop going) */ k = label_to_equip(index_to_label(e1+press.mouse.y-1)); } else { /* get the item index, allowing for skipped indices */ for (j = e1; j <= e2; j++) { /* skip the quiver slot which is a blank line in the list */ if (j == 36) { press.mouse.y--; } else if (get_item_okay(j)) { if (press.mouse.y == 1) { k = j; break; } press.mouse.y--; } } } } } else if (p_ptr->command_wrk == USE_FLOOR) { if (press.mouse.y == 0) { if (use_inven) { p_ptr->command_wrk = USE_INVEN; } else if (use_equip) { p_ptr->command_wrk = USE_EQUIP; } } else if ((press.mouse.y <= floor_num) && (press.mouse.y >= 1)) { /* Special index */ k = 0 - floor_list[press.mouse.y-1]; /* get the item index, allowing for skipped indices */ for (j = f1; j <= f2; j++) { if (get_item_okay(0 - floor_list[j])) { if (press.mouse.y == 1) { k = 0 - floor_list[j]; break; } press.mouse.y--; } } /* check the bounds the item number */ if (k < 0) { /* Allow player to "refuse" certain actions */ if (!get_item_allow(k, cmdkey, cmd, is_harmless)) { done = TRUE; } /* Accept that choice */ (*cp) = k; item = TRUE; done = TRUE; } else { /* set k to a value that will be invalid below */ k = -1; } } } if (k >= 0) { /* Validate the item */ if (!get_item_okay(k)) { bell("Illegal object choice (normal)!"); } /* Allow player to "refuse" certain actions */ if (!get_item_allow(k, cmdkey, cmd, is_harmless)) { done = TRUE; } /* Accept that choice */ (*cp) = k; item = TRUE; done = TRUE; } else if (press.mouse.y == 0) { /* Hack -- Fix screen */ if (show_list) { /* Load screen */ screen_load(); /* Save screen */ screen_save(); } } } } else //switch (which.code) switch (press.key.code) { case ESCAPE: case ' ': { 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, cmd, 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, cmd, 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.code, cmd, quiver_tags)) if (!get_tag(&k, press.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, cmd, 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, cmd, 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.code) ? TRUE : FALSE); verify = (isupper((unsigned char)press.key.code) ? TRUE : FALSE); /* Lowercase */ //which.code = tolower((unsigned char)which.code); press.key.code = tolower((unsigned char)press.key.code); /* Convert letter to inventory index */ if (p_ptr->command_wrk == USE_INVEN) { //k = label_to_inven(which.code); k = label_to_inven(press.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.code); k = label_to_equip(press.key.code); if (k < 0) { bell("Illegal object choice (equip)!"); break; } } /* Convert letter to floor index */ else { //k = (islower((unsigned char)which.code) ? A2I((unsigned char)which.code) : -1); k = (islower((unsigned char)press.key.code) ? A2I((unsigned char)press.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, cmd, 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(p_ptr); /* 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("%s", str); /* Result */ return (item); }
/* * 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); }
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; }
/** * 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; } } } }
/* * Examine a grid, return a keypress. * * The "mode" argument contains the "TARGET_LOOK" bit flag, which * indicates that the "space" key should scan through the contents * of the grid, instead of simply returning immediately. This lets * the "look" command get complete information, without making the * "target" command annoying. * * The "info" argument contains the "commands" which should be shown * inside the "[xxx]" text. This string must never be empty, or grids * containing monsters will be displayed with an extra comma. * * Note that if a monster is in the grid, we update both the monster * recall info and the health bar info to track that monster. * * This function correctly handles multiple objects per grid, and objects * and terrain features in the same grid, though the latter never happens. * * This function must handle blindness/hallucination. */ static ui_event_data target_set_interactive_aux(int y, int x, int mode, cptr info, bool list_floor_objects) { s16b this_o_idx, next_o_idx = 0; s16b this_x_idx, next_x_idx = 0; cptr s1, s2, s3; bool floored; u16b feat; ui_event_data query; char out_val[256]; char coords[20]; /* Describe the square location */ coords_desc(coords, sizeof(coords), y, x); /* Repeat forever */ while (1) { int i; char feat_name[80]; /* Terrain suffix for monsters and objects */ char terrain_suffix[200]; /* Temporary array of visible effects */ s16b x_seen[50]; u16b size_x_seen = 0; /* Paranoia */ query.key = ' '; /* Default */ s1 = "You see "; s2 = ""; s3 = "on "; /* The player */ if (cave_m_idx[y][x] < 0) { /* Description */ s1 = "You are "; /* Preposition */ s2 = "on "; } /* Feature (apply "mimic") */ feat = f_info[cave_feat[y][x]].f_mimic; /* Require knowledge about grid, or ability to see grid */ if (!(cave_info[y][x] & (CAVE_MARK)) && !player_can_see_bold(y,x)) { /* Forget feature */ feat = FEAT_NONE; } else { /* Hack -- track the current feature */ feature_kind_track(feat); /* Window stuff */ p_ptr->redraw |= (PR_FEATURE); } /* Pick a prefix */ if (*s2 && (!feat_ff1_match(feat, FF1_MOVE) || !feat_ff1_match(feat, FF1_LOS) || feat_ff1_match(feat, FF1_SHOP | FF1_DOOR) || feat_ff2_match(feat, FF2_SHALLOW | FF2_DEEP) || feat_ff3_match(feat, FF3_NEED_TREE))) { s3 = "in "; } /* Get a default name */ if (feat <= FEAT_NONE) { my_strcpy(feat_name, "an unknown grid", sizeof(feat_name)); } /* Get the real name */ else { feature_desc(feat_name, sizeof (feat_name), feat, TRUE, FALSE); } /* List all effects in the grid */ for (this_x_idx = cave_x_idx[y][x]; this_x_idx; this_x_idx = next_x_idx) { effect_type *x_ptr; /* Get the effect */ x_ptr = &x_list[this_x_idx]; /* Get the next effect */ next_x_idx = x_ptr->next_x_idx; /* Describe it, if not hidden */ if (!(x_ptr->x_flags & (EF1_HIDDEN)) && x_ptr->x_f_idx) { /* Check for available space */ if (size_x_seen < N_ELEMENTS(x_seen)) { x_seen[size_x_seen++] = x_ptr->x_f_idx; } } } /* Prepare the terrain suffix for monsters and objects */ my_strcpy(terrain_suffix, format(" %s%s", s3, feat_name), sizeof(terrain_suffix)); /* Concat the collected effect names */ for (i = 0; i < size_x_seen; i++) { char x_name[80]; /* Obtain an object description */ feature_desc(x_name, sizeof(x_name), x_seen[i], TRUE, TRUE); /* First effect */ if (i == 0) { if ((feat == FEAT_NONE) || !feat_ff1_match(feat, FF1_MOVE) || cave_any_trap_bold(y, x)) { /* Basic info */ my_strcat(terrain_suffix, format(" with %s", x_name), sizeof(terrain_suffix)); } else { /* Basic info */ my_strcat(terrain_suffix, format(" beneath %s", x_name), sizeof(terrain_suffix)); } } /* Basic info */ else if (i < (size_x_seen - 1)) { my_strcat(terrain_suffix, format(", %s", x_name), sizeof(terrain_suffix)); } /* Basic info */ else { my_strcat(terrain_suffix, format(" and %s", x_name), sizeof(terrain_suffix)); } } /* Ignore the terrain suffix if certain things happen */ if ((size_x_seen == 0) && (feat <= FEAT_FLOOR)) { terrain_suffix[0] = '\0'; } /* Hack -- hallucination */ if (p_ptr->timed[TMD_IMAGE]) { cptr name = "something strange"; /* Display a message */ if (p_ptr->wizard) { strnfmt(out_val, sizeof(out_val), "%s%s%s, [%s] %s (%d:%d).", s1, s2, name, info, coords, y, x); } else { strnfmt(out_val, sizeof(out_val), "%s%s%s [%s], %s.", s1, s2, name, info, coords); } prt(out_val, 0, 0); move_cursor_relative(y, x); query = inkey_ex(); /* Stop on everything but "return" */ if ((query.key != '\n') && (query.key != '\r')) break; /* Repeat forever */ continue; } /* Actual monsters */ if (cave_m_idx[y][x] > 0) { monster_type *m_ptr = &mon_list[cave_m_idx[y][x]]; monster_race *r_ptr = &r_info[m_ptr->r_idx]; /* Visible */ if (m_ptr->ml) { bool recall = FALSE; char m_name[80]; if (m_ptr->mimic_k_idx) { /*get the description*/ mimic_desc_object(m_name, sizeof(m_name), m_ptr->mimic_k_idx); } else { /* Get the monster name ("a kobold") */ monster_desc(m_name, sizeof(m_name), m_ptr, 0x08); /* Hack -- track this monster race */ monster_race_track(m_ptr->r_idx); /* Hack -- health bar for this monster */ health_track(cave_m_idx[y][x]); /*Track the feature*/ feature_kind_track(cave_feat[y][x]); /* Window stuff */ p_ptr->redraw |= (PR_FEATURE); /* Hack -- handle stuff */ handle_stuff(); } /* Interact */ while (1) { if (recall) button_add("[CLEAR_RECALL]", 'r'); else button_add("[RECALL]", 'r'); if (cave_o_idx[y][x] > 0)button_add("[VIEW_FLOOR]", 'f'); event_signal(EVENT_MOUSEBUTTONS); /* Recall, but not mimics */ if ((recall) && (!(m_ptr->mimic_k_idx))) { /* Save screen */ screen_save(); /* Recall on screen */ screen_roff(m_ptr->r_idx); /* Hack -- Complete the prompt (again) */ Term_addstr(-1, TERM_WHITE, format(" [r,%s]", info)); /* Command */ query = inkey_ex(); /* Load screen */ screen_load(); } /* Normal */ else { /* Basic info */ strnfmt(out_val, sizeof(out_val), "%s%s%s", s1, s2, m_name); /* Describe the monster, unless a mimic */ if (!(m_ptr->mimic_k_idx)) { char buf[80]; look_mon_desc(buf, sizeof(buf), cave_m_idx[y][x]); /* Monster state, terrain suffix, options */ my_strcat(out_val, format(" (%s)%s [r,%s]", buf, terrain_suffix, info), sizeof(out_val)); } /* Mimics */ else { /* Terrain suffix, options */ my_strcat(out_val, format("%s [I,%s]", terrain_suffix, info), sizeof(out_val)); } /* Wizards want coordinates */ if (p_ptr->wizard) { my_strcat(out_val, format(" (%d:%d)", y, x), sizeof(out_val)); } prt(out_val, 0, 0); /* Place cursor */ move_cursor_relative(y, x); /* Command */ query = inkey_ex(); } button_kill('r'); button_kill('f'); event_signal(EVENT_MOUSEBUTTONS); /* Handle fake object recall */ if (m_ptr->mimic_k_idx) { object_type body; object_type *o_ptr = &body; /* Validate input first */ if (query.key != 'I') break; /* Paranoia */ object_wipe(o_ptr); /* Prepare */ object_prep(o_ptr, m_ptr->mimic_k_idx); /* Fake history */ object_history(o_ptr, ORIGIN_FLOOR, 0); /* Clear prompt. Place cursor */ prt("", 0, 0); /* Show the fake info - EXPERIMENTAL */ object_info_screen(o_ptr); } /* Regular monsters */ else { /* Normal commands */ if (query.key != 'r') break; /* Toggle recall */ recall = !recall; } } /* Stop on everything but "return"/"space", or floor */ if ((query.key != '\n') && (query.key != '\r') && (query.key != ' ') && (query.key != 'f')) break; /* continue with 'f' only if there are floor items....*/ if ((query.key == 'f') && (!cave_o_idx[y][x])) break; /* Sometimes stop at "space" key */ if ((query.key == ' ') && !(mode & (TARGET_LOOK))) break; /* Change the intro */ s1 = "It is "; /* Hack -- take account of gender */ if (r_ptr->flags1 & (RF1_FEMALE)) s1 = "She is "; else if (r_ptr->flags1 & (RF1_MALE)) s1 = "He is "; /* Use a preposition */ s2 = "carrying "; /* Scan all objects being carried */ for (this_o_idx = m_ptr->hold_o_idx; this_o_idx; this_o_idx = next_o_idx) { char o_name[80]; object_type *o_ptr; /* Get the object */ o_ptr = &o_list[this_o_idx]; /* Get the next object */ next_o_idx = o_ptr->next_o_idx; /*Don't let the player see certain objects (used for vault treasure)*/ if ((o_ptr->ident & (IDENT_HIDE_CARRY)) && (!p_ptr->wizard) && (!cheat_peek)) continue; /* Obtain an object description */ object_desc(o_name, sizeof(o_name), o_ptr, ODESC_PREFIX | ODESC_FULL); /* Describe the object */ strnfmt(out_val, sizeof(out_val), "%s%s%s [%s]", s1, s2, o_name, info); /* Wizards want coordinates */ if (p_ptr->wizard) { my_strcat(out_val, format(" (%d:%d)", y, x), sizeof(out_val)); } prt(out_val, 0, 0); move_cursor_relative(y, x); query = inkey_ex(); /* Stop on everything but "return"/"space" */ if ((query.key != '\n') && (query.key != '\r') && (query.key != ' ')) break; /* Sometimes stop at "space" key */ if ((query.key == ' ') && !(mode & (TARGET_LOOK))) break; /* Change the intro */ s2 = "also carrying "; } /* Double break */ if (this_o_idx) break; /* Use a preposition */ s2 = "on "; } } /* Assume not floored */ floored = FALSE; /* Scan all objects in the grid */ if (TRUE) { int floor_list[MAX_FLOOR_STACK]; int floor_num; track_object(-floor_list[0]); handle_stuff(); /* Scan for floor objects */ floor_num = scan_floor(floor_list, MAX_FLOOR_STACK, y, x, 0x02); /* Actual pile */ if (floor_num > 1) { /* Floored */ floored = TRUE; /* Describe */ while (1) { /* Basic info */ strnfmt(out_val, sizeof(out_val), "%s%sa pile of %d objects%s [r,%s]", s1, s2, floor_num, terrain_suffix, info); /* Wizards want coordinates */ if (p_ptr->wizard) { my_strcat(out_val, format(" (%d:%d)", y, x), sizeof(out_val)); } prt(out_val, 0, 0); if (list_floor_objects) { /* Save screen */ screen_save(); /* Display */ show_floor(floor_list, floor_num, (OLIST_WEIGHT | OLIST_GOLD)); } move_cursor_relative(y, x); query = inkey_ex(); if (list_floor_objects) { screen_load(); } /* Display objects */ if (query.key == 'r') { int pos; pos = query.key - 'a'; if (0 <= pos && pos < floor_num) { track_object(-floor_list[pos]); handle_stuff(); } } /* Done */ break; } /* Stop on everything but "return"/"space" */ if ((query.key != '\n') && (query.key != '\r') && (query.key != ' ')) break; /* Sometimes stop at "space" key */ if ((query.key == ' ') && !(mode & (TARGET_LOOK))) break; /* Change the intro */ s1 = "It is "; /* Preposition */ s2 = "on "; } } /* Scan all objects in the grid */ for (this_o_idx = cave_o_idx[y][x]; this_o_idx; this_o_idx = next_o_idx) { object_type *o_ptr; /* Get the object */ o_ptr = &o_list[this_o_idx]; /* Get the next object */ next_o_idx = o_ptr->next_o_idx; /* Skip objects if floored */ if (floored) continue; /* Describe it */ if (o_ptr->marked) { char o_name[80]; /* Obtain an object description */ object_desc(o_name, sizeof(o_name), o_ptr, ODESC_PREFIX | ODESC_FULL); /* Basic info */ strnfmt(out_val, sizeof(out_val), "%s%s%s%s [I,%s]", s1, s2, o_name, terrain_suffix, info); /* Wizards want coordinates */ if (p_ptr->wizard) { my_strcat(out_val, format(" (%d:%d)", y, x), sizeof(out_val)); } /* Show object. Handle object recall */ while (TRUE) { /* Print the prompt */ prt(out_val, 0, 0); /* Move cursor to that location */ move_cursor_relative(y, x); /* Read input key */ query = inkey_ex(); /* No object recall */ if (query.key != 'I') break; /* Object recall. Clear the first line */ prt("", 0, 0); /* Do it */ object_info_screen(o_ptr); } /* Stop on everything but "return"/"space" */ if ((query.key != '\n') && (query.key != '\r') && (query.key != ' ')) break; /* Sometimes stop at "space" key */ if ((query.key == ' ') && !(mode & (TARGET_LOOK))) break; /* Change the intro */ s1 = "It is "; /* Plurals */ if (o_ptr->number != 1) s1 = "They are "; /* Preposition */ s2 = "on "; } } /* Double break */ if (this_o_idx) break; /* Display terrain */ if (TRUE) { u16b temp_feat; bool enable_recall; bool show_recall = FALSE; char temp_name[80]; /* * Display terrain and effects */ for (i = 0; i <= size_x_seen; i++) { /* Hack - This is the mark for the feature stored in cave_feat */ if (i == size_x_seen) { temp_feat = feat; /* Just copy the feature name */ my_strcpy(temp_name, feat_name, sizeof(temp_name)); } /* Any other value is an effect stored x_list */ else { temp_feat = x_seen[i]; /* Get the effect's name */ feature_desc(temp_name, sizeof(temp_name), temp_feat, TRUE, TRUE); } /* Don't display feature recall if the grid is unknown */ enable_recall = (temp_feat != FEAT_NONE); /* Handle recall */ while (TRUE) { /* Handle recall mode */ if (show_recall && enable_recall) { /* Save screen */ screen_save(); /* Recall feature on screen */ screen_feature_roff(temp_feat); } /* Display a message */ strnfmt(out_val, sizeof(out_val), "%s%s%s [%s%s]%s", s1, s2, temp_name, (enable_recall ? "r,": ""), info, (i < size_x_seen) ? " (more)": ""); /* Wizards want coordinates */ if (p_ptr->wizard) { my_strcat(out_val, format(" (%d:%d)", y, x), sizeof(out_val)); } /*Track this feature*/ feature_kind_track(temp_feat); /* Hack -- handle stuff */ handle_stuff(); prt(out_val, 0, 0); move_cursor_relative(y, x); query = inkey_ex(); /* Load screen if necessary */ if (show_recall && enable_recall) { screen_load(); } /* Stop on everything but the recall command, if enabled */ if (!enable_recall || (query.key != 'r')) break; /* Toggle recall */ show_recall = !show_recall; } /* Stop on everything but "return"/"space" */ if ((query.key != '\n') && (query.key != '\r') && (query.key != ' ')) break; } } /* Hack -- handle stuff */ handle_stuff(); /* Stop on everything but "return" */ if ((query.key != '\n') && (query.key != '\r')) break; } /* Keep going */ return (query); }
/* * Identify a character, allow recall of monsters * * Several "special" responses recall "multiple" monsters: * ^A (all monsters) * ^U (all unique monsters) * ^N (all non-unique monsters) * * The responses may be sorted in several ways, see below. * * Note that the player ghosts are ignored, since they do not exist. */ void do_cmd_query_symbol(void) { int i, n, r_idx; char buf[128]; struct keypress sym; struct keypress query; bool all = FALSE; bool uniq = FALSE; bool norm = FALSE; bool recall = FALSE; u16b *who; /* Get a character, or abort */ if (!get_com("Enter character to be identified, or control+[ANU]: ", &sym)) return; /* Describe */ if (sym.code == KTRL('A')) { all = TRUE; my_strcpy(buf, "Full monster list.", sizeof(buf)); } else if (sym.code == KTRL('U')) { all = uniq = TRUE; my_strcpy(buf, "Unique monster list.", sizeof(buf)); } else if (sym.code == KTRL('N')) { all = norm = TRUE; my_strcpy(buf, "Non-unique monster list.", sizeof(buf)); } else { lookup_symbol(sym, buf, sizeof(buf)); } /* Display the result */ prt(buf, 0, 0); /* Allocate the "who" array */ who = C_ZNEW(z_info->r_max, u16b); /* Collect matching monsters */ for (n = 0, i = 1; i < z_info->r_max - 1; i++) { monster_race *r_ptr = &r_info[i]; monster_lore *l_ptr = &l_list[i]; /* Nothing to recall */ if (!OPT(cheat_know) && !l_ptr->sights) continue; /* Require non-unique monsters if needed */ if (norm && rf_has(r_ptr->flags, RF_UNIQUE)) continue; /* Require unique monsters if needed */ if (uniq && !rf_has(r_ptr->flags, RF_UNIQUE)) continue; /* Collect "appropriate" monsters */ if (all || (r_ptr->d_char == (char)sym.code)) who[n++] = i; } /* Nothing to recall */ if (!n) { /* XXX XXX Free the "who" array */ FREE(who); return; } /* Buttons */ button_add("[y]", 'y'); button_add("[k]", 'k'); /* Don't collide with the repeat button */ button_add("[n]", 'q'); redraw_stuff(p_ptr); /* Prompt */ put_str("Recall details? (y/k/n): ", 0, 40); /* Query */ query = inkey(); /* Restore */ prt(buf, 0, 0); /* Buttons */ button_kill('y'); button_kill('k'); button_kill('q'); redraw_stuff(p_ptr); /* Interpret the response */ if (query.code == 'k') { /* Sort by kills (and level) */ sort(who, n, sizeof(*who), cmp_pkill); } else if (query.code == 'y' || query.code == 'p') { /* Sort by level; accept 'p' as legacy */ sort(who, n, sizeof(*who), cmp_level); } else { /* Any unsupported response is "nope, no history please" */ /* XXX XXX Free the "who" array */ FREE(who); return; } /* Start at the end */ i = n - 1; /* Button */ button_add("[r]", 'r'); button_add("[-]", '-'); button_add("[+]", '+'); redraw_stuff(p_ptr); /* Scan the monster memory */ while (1) { /* Extract a race */ r_idx = who[i]; /* Hack -- Auto-recall */ monster_race_track(r_idx); /* Hack -- Handle stuff */ handle_stuff(p_ptr); /* Hack -- Begin the prompt */ roff_top(r_idx); /* Hack -- Complete the prompt */ Term_addstr(-1, TERM_WHITE, " [(r)ecall, ESC]"); /* Interact */ while (1) { /* Recall */ if (recall) { /* Save screen */ screen_save(); /* Recall on screen */ screen_roff(who[i]); /* Hack -- Complete the prompt (again) */ Term_addstr(-1, TERM_WHITE, " [(r)ecall, ESC]"); } /* Command */ query = inkey(); /* Unrecall */ if (recall) { /* Load screen */ screen_load(); } /* Normal commands */ if (query.code != 'r') break; /* Toggle recall */ recall = !recall; } /* Stop scanning */ if (query.code == ESCAPE) break; /* Move to "prev" monster */ if (query.code == '-') { if (++i == n) i = 0; } /* Move to "next" monster */ else { if (i-- == 0) i = n - 1; } } /* Button */ button_kill('r'); button_kill('-'); button_kill('+'); redraw_stuff(p_ptr); /* Re-display the identity */ prt(buf, 0, 0); /* Free the "who" array */ FREE(who); }