/* ------------------------------------------------------------------------ * 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; }
/* * 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]", '|'); }
/** * ------------------------------------------------------------------------ * 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 = BIRTH_RESET; /* Prompt for it */ prt(prompt, Term->hgt - 1, Term->wid / 2 - strlen(prompt) / 2); /* Get a key */ ke = inkey(); /* Start over */ if (ke.code == 'S' || ke.code == 's') { next = BIRTH_RESET; } else if (ke.code == KTRL('X')) { quit(NULL); } else if (ke.code == ESCAPE) { next = BIRTH_BACK; } else { cmdq_push(CMD_ACCEPT_CHARACTER); next = BIRTH_COMPLETE; } /* Clear prompt */ clear_from(23); return next; }
/* Display an entry on a command menu */ static void cmd_sub_entry(menu_type *menu, int oid, bool cursor, int row, int col, int width) { byte attr = (cursor ? TERM_L_BLUE : TERM_WHITE); const struct generic_command *commands = menu_priv(menu); (void)width; /* Write the description */ Term_putstr(col, row, -1, attr, commands[oid].desc); /* Include keypress */ Term_addch(attr, ' '); Term_addch(attr, '('); /* KTRL()ing a control character does not alter it at all */ if (KTRL(commands[oid].key) == commands[oid].key) { Term_addch(attr, '^'); Term_addch(attr, UN_KTRL(commands[oid].key)); } else { Term_addch(attr, commands[oid].key); } Term_addch(attr, ')'); }
/** * ------------------------------------------------------------------------ * Quickstart? screen. * ------------------------------------------------------------------------ */ static enum birth_stage textui_birth_quickstart(void) { const char *prompt = "['Y' to use this character, 'N' to start afresh, 'C' to change name or history]"; 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); do { /* Get a key */ struct keypress ke = inkey(); if (ke.code == 'N' || ke.code == 'n') { cmdq_push(CMD_BIRTH_RESET); next = BIRTH_RACE_CHOICE; } else if (ke.code == KTRL('X')) { quit(NULL); } else if (ke.code == 'C' || ke.code == 'c') { next = BIRTH_NAME_CHOICE; } else if (ke.code == 'Y' || ke.code == 'y') { cmdq_push(CMD_ACCEPT_CHARACTER); next = BIRTH_COMPLETE; } } while (next == BIRTH_QUICKSTART); /* Clear prompt */ clear_from(23); return next; }
/* * Handle character death */ void death_screen(void) { bool done = FALSE; const region area = { 51, 2, 0, N_ELEMENTS(death_actions) }; /* Retire in the town in a good state */ if (p_ptr->total_winner) { p_ptr->depth = 0; my_strcpy(p_ptr->died_from, "Ripe Old Age", sizeof(p_ptr->died_from)); p_ptr->exp = p_ptr->max_exp; p_ptr->lev = p_ptr->max_lev; p_ptr->au += 10000000L; display_winner(); } /* Get time of death */ (void)time(&death_time); print_tomb(); death_knowledge(); enter_score(&death_time); /* Flush all input and output */ flush(); message_flush(); /* Display and use the death menu */ if (!death_menu) { death_menu = menu_new_action(death_actions, N_ELEMENTS(death_actions)); death_menu->flags = MN_CASELESS_TAGS; } menu_layout(death_menu, &area); while (!done) { ui_event e = menu_select(death_menu, EVT_KBRD); if (e.type == EVT_KBRD) { if (e.key.code == KTRL('X')) break; } else if (e.type == EVT_SELECT) { done = get_check("Do you want to quit? "); } } /* Save dead player */ if (!savefile_save(savefile)) { msg("death save failed!"); message_flush(); } }
/** * ------------------------------------------------------------------------ * The rolling bit of the roller. * ------------------------------------------------------------------------ */ 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; /* 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 previous roll"); 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(); /* Analyse the command */ if (ch.code == ESCAPE) { /* Back out */ next = BIRTH_BACK; } else if (ch.code == KC_ENTER) { /* 'Enter' accepts the roll */ next = BIRTH_NAME_CHOICE; } else if ((ch.code == ' ') || (ch.code == 'r')) { /* Reroll this character */ cmdq_push(CMD_ROLL_STATS); prev_roll = TRUE; } else if (prev_roll && (ch.code == 'p')) { /* Previous character */ cmdq_push(CMD_PREV_STATS); } else if (ch.code == KTRL('X')) { /* Quit */ quit(NULL); } else if (ch.code == '?') { /* Help XXX */ do_cmd_help(); } else { /* Nothing handled directly here */ bell("Illegal roller command!"); } return next; }
/* ------------------------------------------------------------------------ * 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; }
/* ------------------------------------------------------------------------ * 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; }
/* ------------------------------------------------------------------------ * 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 enum birth_stage point_based_command(void) { static int stat = 0; struct keypress ch; enum birth_stage next = BIRTH_POINTBASED; /* Place cursor just after cost of current stat */ Term_gotoxy(COSTS_COL + 4, COSTS_ROW + stat); /* Get key */ ch = inkey(); if (ch.code == KTRL('X')) { quit(NULL); } else if (ch.code == ESCAPE) { /* Go back a step, or back to the start of this step */ next = BIRTH_BACK; } else if (ch.code == 'r' || ch.code == 'R') { cmdq_push(CMD_RESET_STATS); cmd_set_arg_choice(cmdq_peek(), "choice", FALSE); } else if (ch.code == KC_ENTER) { /* Done */ next = BIRTH_NAME_CHOICE; } else { int dir = target_dir(ch); /* Prev stat, looping round to the bottom when going off the top */ if (dir == 8) stat = (stat + STAT_MAX - 1) % STAT_MAX; /* Next stat, looping round to the top when going off the bottom */ if (dir == 2) stat = (stat + 1) % STAT_MAX; /* Decrease stat (if possible) */ if (dir == 4) { cmdq_push(CMD_SELL_STAT); cmd_set_arg_choice(cmdq_peek(), "choice", stat); } /* Increase stat (if possible) */ if (dir == 6) { cmdq_push(CMD_BUY_STAT); cmd_set_arg_choice(cmdq_peek(), "choice", stat); } } return next; }
/** * Get a command count, with the '0' key. */ static int textui_get_count(void) { int count = 0; while (1) { ui_event_data ke; prt(format("Count: %d", count), 0, 0); ke = inkey_ex(); if (ke.type != EVT_KBRD) continue; if (ke.key == ESCAPE) return -1; /* Simple editing (delete or backspace) */ else if (ke.key == 0x7F || ke.key == KTRL('H')) count = count / 10; /* Actual numeric data */ else if (isdigit((unsigned char) ke.key)) { count = count * 10 + D2I(ke.key); if (count >= 9999) { bell("Invalid repeat count!"); count = 9999; } } /* Anything non-numeric passes straight to command input */ else { /* XXX nasty hardcoding of action menu key */ if (ke.key != '\n' && ke.key != '\r') Term_event_push(&ke); break; } } return count; }
/** * Handle character death */ void death_screen(void) { struct menu *death_menu; bool done = false; const region area = { 51, 2, 0, N_ELEMENTS(death_actions) }; /* Winner */ if (player->total_winner) { display_winner(); } /* Tombstone */ print_tomb(); /* Flush all input and output */ event_signal(EVENT_INPUT_FLUSH); event_signal(EVENT_MESSAGE_FLUSH); /* Display and use the death menu */ death_menu = menu_new_action(death_actions, N_ELEMENTS(death_actions)); death_menu->flags = MN_CASELESS_TAGS; menu_layout(death_menu, &area); while (!done) { ui_event e = menu_select(death_menu, EVT_KBRD, false); if (e.type == EVT_KBRD) { if (e.key.code == KTRL('X')) break; } else if (e.type == EVT_SELECT) { done = get_check("Do you want to quit? "); } } menu_free(death_menu); }
/** * ------------------------------------------------------------------------ * Allowing the player to choose their history. * ------------------------------------------------------------------------ */ static enum birth_stage get_history_command(void) { enum birth_stage next = 0; struct keypress ke; char old_history[240]; /* Save the original history */ my_strcpy(old_history, player->history, sizeof(old_history)); /* Ask for some history */ prt("Accept character history? [y/n]", 0, 0); ke = inkey(); /* Quit, go back, change history, or accept */ if (ke.code == KTRL('X')) { quit(NULL); } else if (ke.code == ESCAPE) { next = BIRTH_BACK; } else if (ke.code == 'N' || ke.code == 'n') { char history[240]; my_strcpy(history, player->history, sizeof(history)); switch (edit_text(history, sizeof(history))) { case -1: next = BIRTH_BACK; case 0: cmdq_push(CMD_HISTORY_CHOICE); cmd_set_arg_string(cmdq_peek(), "history", history); next = BIRTH_HISTORY_CHOICE; } } else { next = BIRTH_FINAL_CONFIRM; } return next; }
/* * Identify a character, allow recall of monsters * * Several "special" responses recall "mulitple" 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 sym, query; char buf[128]; bool all = FALSE; bool uniq = FALSE; bool norm = FALSE; bool kill = TRUE; bool recall = FALSE; u16b why = 0; u16b *who; /* Get a character, or abort */ if (!get_com("Enter character to be identified: ", &sym)) return; /* Find that character info, and describe it */ for (i = 0; ident_info[i]; ++i) { if (sym == ident_info[i][0]) break; } /* Describe */ if (sym == KTRL('A')) { all = TRUE; strcpy(buf, "Full monster list."); } else if (sym == KTRL('U')) { all = uniq = TRUE; strcpy(buf, "Unique monster list."); } else if (sym == KTRL('N')) { all = norm = TRUE; strcpy(buf, "Non-unique monster list."); } else if (sym == KTRL('K')) { all = kill = TRUE; strcpy(buf, "Killed monster list."); } else if (ident_info[i]) { sprintf(buf, "%c - %s.", sym, ident_info[i] + 2); } else { sprintf(buf, "%c - %s.", sym, "Unknown Symbol"); } /* Display the result */ prt(buf, 0, 0); /* Allocate the "who" array */ C_MAKE(who, 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 (!cheat_know && !l_ptr->sights) continue; /* Skip unused monsters */ if (!(r_ptr->hdice)) continue; /* Require non-unique monsters if needed */ if (norm && (r_ptr->flags1 & (RF1_UNIQUE))) continue; /* Require unique monsters if needed */ if (uniq && !(r_ptr->flags1 & (RF1_UNIQUE))) continue; /* Require killed if needed */ if (kill && !(l_ptr->pkills)) continue; /* Collect "appropriate" monsters */ if (all || (r_ptr->d_char == sym)) who[n++] = i; } /* Nothing to recall */ if (!n) { /* XXX XXX Free the "who" array */ FREE(who); return; } /* Prompt */ put_str("Recall details? (k/K/p/P/a/A/y/n): ", 0, 40); /* Query */ query = inkey(); /* Restore */ prt(buf, 0, 0); /* Sort by kills (and level) */ if (query == 'k') { why = 4; query = 'y'; } if (query == 'K') { why = 4+16; query = 'y'; } /* Sort by total kills (and level) */ if (query == 'a') { why = 3; query = 'y'; } if (query == 'A') { why = 3+16; query = 'y'; } /* Sort by level (and experience) */ if (query == 'p') { why = 2; query = 'y'; } if (query == 'P') { why = 2+16; query = 'y'; } /* Catch "escape" */ if (query != 'y') { /* XXX XXX Free the "who" array */ FREE(who); return; } /* Sort if needed */ if (why) { /* Select the sort method */ ang_sort_comp = ang_sort_comp_hook; ang_sort_swap = ang_sort_swap_hook; /* Sort the array */ ang_sort(who, &why, n); } /* Start at the end */ i = n - 1; /* 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(); /* 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 != 'r') break; /* Toggle recall */ recall = !recall; } /* Stop scanning */ if (query == ESCAPE) break; /* Move to "prev" monster */ if (query == '-') { if (++i == n) { i = 0; if (!expand_list) break; } } /* Move to "next" monster */ else { if (i-- == 0) { i = n - 1; if (!expand_list) break; } } } /* Re-display the identity */ prt(buf, 0, 0); /* Free the "who" array */ FREE(who); }
/* * Request a command from the user. * * Note that "caret" ("^") is treated specially, and is used to * allow manual input of control characters. This can be used * on many machines to request repeated tunneling (Ctrl-H) and * on the Macintosh to request "Control-Caret". * * Note that "backslash" is treated specially, and is used to bypass any * keymap entry for the following character. This is useful for macros. */ static ui_event_data textui_get_command(void) { int mode = OPT(rogue_like_commands) ? KEYMAP_MODE_ROGUE : KEYMAP_MODE_ORIG; char tmp[2] = { '\0', '\0' }; ui_event_data ke = EVENT_EMPTY; cptr act = NULL; /* Get command */ while (1) { /* Hack -- no flush needed */ msg_flag = FALSE; /* Activate "command mode" */ inkey_flag = TRUE; /* Get a command */ ke = inkey_ex(); /* Command Count */ if (ke.key == '0') { int count = textui_get_count(); if (count == -1 || !get_com_ex("Command: ", &ke)) continue; else p_ptr->command_arg = count; } /* Allow "keymaps" to be bypassed */ else if (ke.key == '\\') { /* Get a real command */ (void)get_com("Command: ", &ke.key); /* Hack -- bypass keymaps */ if (!inkey_next) inkey_next = ""; } /* Allow "control chars" to be entered */ else if (ke.key == '^') { /* Get a new command and controlify it */ if (get_com("Control: ", &ke.key)) ke.key = KTRL(ke.key); } /* Special case for the arrow keys */ else if (isarrow(ke.key)) { switch (ke.key) { case ARROW_DOWN: ke.key = '2'; break; case ARROW_LEFT: ke.key = '4'; break; case ARROW_RIGHT: ke.key = '6'; break; case ARROW_UP: ke.key = '8'; break; } } /* Erase the message line */ prt("", 0, 0); if (ke.type == EVT_BUTTON) { /* Buttons are always specified in standard keyset */ act = tmp; tmp[0] = ke.key; } else if (ke.type == EVT_KBRD) { /* Look up applicable keymap */ act = keymap_act[mode][(byte)(ke.key)]; } /* Apply keymap if not inside a keymap already */ if (ke.key && act && !inkey_next) { /* Install the keymap */ my_strcpy(request_command_buffer, act, sizeof(request_command_buffer)); /* Start using the buffer */ inkey_next = request_command_buffer; /* Continue */ continue; } /* Done */ break; } return ke; }
/* * Show previous messages to the user -BEN- * * 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 hilite the matching portions of the string. */ void do_cmd_messages(void) { int i, j, k, n, q; char shower[80] = ""; char finder[80] = ""; /* Total messages */ n = message_num(); /* Start on first message */ i = 0; /* Start at leftmost edge */ q = 0; /* Enter "icky" mode */ screen_icky = topline_icky = TRUE; /* Save the screen */ Term_save(); /* Process requests until done */ while (1) { /* Clear screen */ Term_clear(); /* Dump up to 20 lines of messages */ for (j = 0; (j < 20) && (i + j < n); j++) { byte a = TERM_WHITE; cptr str = message_str(i+j); /* Determine color */ message_color(str, &a); /* Apply horizontal scroll */ str = (strlen(str) >= q) ? (str + q) : ""; /* Handle "shower" */ if (shower[0] && strstr(str, shower)) a = TERM_YELLOW; /* Dump the messages, bottom to top */ Term_putstr(0, 21-j, -1, a, str); } /* 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("[Press 'p' for older, 'n' for newer, ..., or ESCAPE]", 23, 0); /* Get a command */ k = inkey(); /* Exit on Escape */ if (k == ESCAPE) break; /* Hack -- Save the old index */ j = i; /* Horizontal scroll */ if (k == '4') { /* Scroll left */ q = (q >= 40) ? (q - 40) : 0; /* Success */ continue; } /* Horizontal scroll */ if (k == '6') { /* Scroll right */ q = q + 40; /* Success */ continue; } /* Hack -- handle show */ if (k == '=') { /* Prompt */ prt("Show: ", 23, 0); /* Get a "shower" string, or continue */ if (!askfor_aux(shower, 80, 0)) continue; /* Okay */ continue; } /* Hack -- handle find */ if (k == '/') { int z; /* Prompt */ prt("Find: ", 23, 0); /* Get a "finder" string, or continue */ if (!askfor_aux(finder, 80, 0)) continue; /* Scan messages */ for (z = i + 1; z < n; z++) { cptr str = message_str(z); /* Handle "shower" */ if (strstr(str, finder)) { /* New location */ i = z; /* Done */ break; } } } /* Recall 1 older message */ if ((k == '8') || (k == '\n') || (k == '\r')) { /* Go newer if legal */ if (i + 1 < n) i += 1; } /* Recall 10 older messages */ if (k == '+') { /* Go older if legal */ if (i + 10 < n) i += 10; } /* Recall 20 older messages */ if ((k == 'p') || (k == KTRL('P')) || (k == ' ')) { /* Go older if legal */ if (i + 20 < n) i += 20; } /* Recall 20 newer messages */ if ((k == 'n') || (k == KTRL('N'))) { /* Go newer (if able) */ i = (i >= 20) ? (i - 20) : 0; } /* Recall 10 newer messages */ if (k == '-') { /* Go newer (if able) */ i = (i >= 10) ? (i - 10) : 0; } /* Recall 1 newer messages */ if (k == '2') { /* Go newer (if able) */ i = (i >= 1) ? (i - 1) : 0; } /* Hack -- Error of some kind */ if (i == j) bell(); } /* Restore the screen */ Term_load(); /* Leave "icky" mode */ screen_icky = topline_icky = FALSE; /* Flush any queued events */ Flush_queue(); }
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; }
/* 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; }
/* * 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. XXX XXX XXX */ void do_cmd_query_symbol(void) { int i, n, r_idx; char sym, query; char buf[128]; bool all = FALSE; bool uniq = FALSE; bool norm = FALSE; bool ride = FALSE; char temp[80] = ""; bool recall = FALSE; u16b why = 0; u16b *who; /* Get a character, or abort */ if (!get_com("Enter character to be identified(^A:All,^U:Uniqs,^N:Non uniqs,^M:Name): ", &sym, FALSE)) return; /* Find that character info, and describe it */ for (i = 0; ident_info[i]; ++i) { if (sym == ident_info[i][0]) break; } /* Describe */ if (sym == KTRL('A')) { all = TRUE; strcpy(buf, "Full monster list."); } else if (sym == KTRL('U')) { all = uniq = TRUE; strcpy(buf, "Unique monster list."); } else if (sym == KTRL('N')) { all = norm = TRUE; strcpy(buf, "Non-unique monster list."); } else if (sym == KTRL('R')) { all = ride = TRUE; strcpy(buf, "Ridable monster list."); } /* XTRA HACK WHATSEARCH */ else if (sym == KTRL('M')) { all = TRUE; if (!get_string("Enter name:",temp, 70)) { temp[0]=0; return; } sprintf(buf, "Monsters with a name \"%s\"",temp); } else if (ident_info[i]) { sprintf(buf, "%c - %s.", sym, ident_info[i] + 2); } else { sprintf(buf, "%c - %s.", sym, "Unknown Symbol"); } /* Display the result */ prt(buf, 0, 0); /* Allocate the "who" array */ C_MAKE(who, max_r_idx, u16b); /* Collect matching monsters */ for (n = 0, i = 1; i < max_r_idx; i++) { monster_race *r_ptr = &r_info[i]; /* Nothing to recall */ if (!(cheat_know || p_ptr->wizard) && !r_ptr->r_sights) continue; /* Require non-unique monsters if needed */ if (norm && (r_ptr->flags1 & (RF1_UNIQUE))) continue; /* Require unique monsters if needed */ if (uniq && !(r_ptr->flags1 & (RF1_UNIQUE))) continue; /* Require ridable monsters if needed */ if (ride && !(r_ptr->flags7 & (RF7_RIDING))) continue; /* XTRA HACK WHATSEARCH */ if (temp[0]) { int xx; char temp2[80]; for (xx=0; temp[xx] && xx<80; xx++) { if (isupper(temp[xx])) temp[xx]=tolower(temp[xx]); } strcpy(temp2, r_name+r_ptr->name); for (xx=0; temp2[xx] && xx<80; xx++) if (isupper(temp2[xx])) temp2[xx]=tolower(temp2[xx]); if (my_strstr(temp2, temp)) who[n++]=i; } /* Collect "appropriate" monsters */ else if (all || (r_ptr->d_char == sym)) who[n++] = i; } /* Nothing to recall */ if (!n) { /* Free the "who" array */ C_KILL(who, max_r_idx, u16b); return; } /* Prompt XXX XXX XXX */ put_str("Recall details? (k/y/n): ", 0, 40); /* Query */ query = inkey(); /* Restore */ prt(buf, 0, 0); why = 2; /* Select the sort method */ ang_sort_comp = ang_sort_comp_hook; ang_sort_swap = ang_sort_swap_hook; /* Sort the array */ ang_sort(who, &why, n); /* Sort by kills (and level) */ if (query == 'k') { why = 4; query = 'y'; } /* Catch "escape" */ if (query != 'y') { /* Free the "who" array */ C_KILL(who, max_r_idx, u16b); return; } /* Sort if needed */ if (why == 4) { /* Select the sort method */ ang_sort_comp = ang_sort_comp_hook; ang_sort_swap = ang_sort_swap_hook; /* Sort the array */ ang_sort(who, &why, n); } /* Start at the end */ i = n - 1; /* 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(); /* Interact */ while (1) { /* Recall */ if (recall) { /* Save the screen */ screen_save(); /* Recall on screen */ screen_roff(who[i], 0); } /* Hack -- Begin the prompt */ roff_top(r_idx); /* Hack -- Complete the prompt */ Term_addstr(-1, TERM_WHITE, " [(r)ecall, ESC]"); /* Command */ query = inkey(); /* Unrecall */ if (recall) { /* Restore */ screen_load(); } /* Normal commands */ if (query != 'r') break; /* Toggle recall */ recall = !recall; } /* Stop scanning */ if (query == ESCAPE) break; /* Move to "prev" monster */ if (query == '-') { if (++i == n) { i = 0; if (!expand_list) break; } } /* Move to "next" monster */ else { if (i-- == 0) { i = n - 1; if (!expand_list) break; } } } /* Free the "who" array */ C_KILL(who, max_r_idx, u16b); /* Re-display the identity */ prt(buf, 0, 0); }
/* 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 = menu_priv(current_menu); ui_event 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 = "?=*\x18"; /* ?, =, *, <ctl-X> */ while (next == BIRTH_RESET) { /* Display the menu, wait for a selection of some sort to be made. */ cx = menu_select(current_menu, EVT_KBRD, FALSE); /* 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_ESCAPE) { next = BIRTH_BACK; } else if (cx.type == EVT_SELECT) { if (current == BIRTH_ROLLER_CHOICE) { cmd_insert(CMD_FINALIZE_OPTIONS); if (current_menu->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); cmd_set_arg_choice(cmd_get_top(), 0, TRUE); next = current + 1; } } else { cmd_insert(choice_command); cmd_set_arg_choice(cmd_get_top(), 0, current_menu->cursor); next = current + 1; } } else if (cx.type == EVT_KBRD) { /* '*' chooses an option at random from those the game's provided. */ if (cx.key.code == '*' && menu_data->allow_random) { current_menu->cursor = randint0(current_menu->count); cmd_insert(choice_command); cmd_set_arg_choice(cmd_get_top(), 0, current_menu->cursor); menu_refresh(current_menu, FALSE); next = current + 1; } else if (cx.key.code == '=') { do_cmd_options_birth(); next = current; } else if (cx.key.code == KTRL('X')) { cmd_insert(CMD_QUIT); next = BIRTH_COMPLETE; } else if (cx.key.code == '?') { do_cmd_help(); } } } return next; }
static void ui_keymap_create(const char *title, int row) { bool done = false; size_t n = 0; struct keypress c; char tmp[1024]; int mode = OPT(rogue_like_commands) ? KEYMAP_MODE_ROGUE : KEYMAP_MODE_ORIG; prt(title, 13, 0); prt("Key: ", 14, 0); c = keymap_get_trigger(); if (c.code == '$') { c_prt(COLOUR_L_RED, "The '$' key is reserved.", 16, 2); prt("Press any key to continue.", 18, 0); inkey(); return; } /* Get an encoded action, with a default response */ while (!done) { struct keypress kp = {EVT_NONE, 0, 0}; int color = COLOUR_WHITE; if (n == 0) color = COLOUR_YELLOW; if (n == KEYMAP_ACTION_MAX) color = COLOUR_L_RED; keypress_to_text(tmp, sizeof(tmp), keymap_buffer, false); c_prt(color, format("Action: %s", tmp), 15, 0); c_prt(COLOUR_L_BLUE, " Press '$' when finished.", 17, 0); c_prt(COLOUR_L_BLUE, " Use 'CTRL-U' to reset.", 18, 0); c_prt(COLOUR_L_BLUE, format("(Maximum keymap length is %d keys.)", KEYMAP_ACTION_MAX), 19, 0); kp = inkey(); if (kp.code == '$') { done = true; continue; } switch (kp.code) { case KC_DELETE: case KC_BACKSPACE: { if (n > 0) { n -= 1; keymap_buffer[n].type = 0; keymap_buffer[n].code = 0; keymap_buffer[n].mods = 0; } break; } case KTRL('U'): { memset(keymap_buffer, 0, sizeof keymap_buffer); n = 0; break; } default: { if (n == KEYMAP_ACTION_MAX) continue; if (n == 0) { memset(keymap_buffer, 0, sizeof keymap_buffer); } keymap_buffer[n++] = kp; break; } } } if (c.code && get_check("Save this keymap? ")) { keymap_add(mode, c, keymap_buffer, true); prt("Keymap added. Press any key to continue.", 17, 0); inkey(); } }
/* * Generic "get choice from menu" function */ int get_player_choice(cptr *choices, int num, int col, int wid, cptr helpfile, void (*hook) (cptr)) { int top = 0, cur = 0; /* int bot = 13; */ int i, dir; char c; char buf[80]; bool done = FALSE; int hgt; /* Autoselect if able */ if (num == 1) done = TRUE; /* Clear */ for (i = TABLE_ROW; i < Term->hgt; i++) { /* Clear */ Term_erase(col, i, Term->wid - wid); } /* Choose */ while (TRUE) { /* * Note to Melkor: What happens when the screen is resized? * There is no 'redraw' hook at this point... * (That is why the original code restricted itself to what * would fit in the smallest possible screen.) -SF- */ hgt = Term->hgt - TABLE_ROW - 1; /* Redraw the list */ for (i = 0; ((i + top < num) && (i <= hgt)); i++) { if (i + top < 26) { strnfmt(buf, 80, "%c) %s", I2A(i + top), choices[i + top]); } else { /* ToDo: Fix the ASCII dependency */ strnfmt(buf, 80, "%c) %s", 'A' + (i + top - 26), choices[i + top]); } /* Clear */ Term_erase(col, i + TABLE_ROW, wid); /* Display */ if (i == (cur - top)) { /* Highlight the current selection */ put_fstr(col, i + TABLE_ROW, CLR_L_BLUE "%s", buf); } else { put_fstr(col, i + TABLE_ROW, buf); } } if (done) return (cur); /* Display auxiliary information if any is available. */ if (hook) hook(choices[cur]); /* Move the cursor */ Term_gotoxy(col, TABLE_ROW + cur - top); c = inkey(); if (c == KTRL('X')) { quit(NULL); } if (c == ESCAPE) { /* Mega Hack - go back. */ return (INVALID_CHOICE); } if (c == '*') { /* Select at random */ cur = randint0(num); /* Move it onto the screen */ if ((cur < top) || (cur > top + hgt)) { top = cur; } /* Done */ done = TRUE; } else if (c == '?') { (void)show_file(helpfile, NULL, 0, 0); } else if (c == '=') { do_cmd_options(OPT_FLAG_BIRTH | OPT_FLAG_SERVER | OPT_FLAG_PLAYER); } else if ((c == '\n') || (c == '\r')) { /* Done */ return (cur); } else if (isdigit(c)) { /* Get a direction from the key */ dir = get_keymap_dir(c); /* Going up? */ if (dir == 8) { if (cur != 0) { /* Move selection */ cur--; } if ((top > 0) && ((cur - top) < 4)) { /* Scroll up */ top--; } } /* Going down? */ if (dir == 2) { if (cur != (num - 1)) { /* Move selection */ cur++; } if ((top + hgt < (num - 1)) && ((top + hgt - cur) < 4)) { /* Scroll down */ top++; } } } else if (isalpha(c)) { int choice; if (islower(c)) { choice = A2I(c); } else { choice = c - 'A' + 26; } /* Validate input */ if ((choice > -1) && (choice < num)) { cur = choice; /* Move it onto the screen */ if ((cur < top) || (cur > top + hgt)) { top = cur; } /* Done */ done = TRUE; } else { /* Invalid input */ bell("Illegal birth choice!"); } } } return (INVALID_CHOICE); }
static int context_menu_player_2(int mx, int my) { menu_type *m; region r; int selected; char *labels; bool allowed = TRUE; int mode = OPT(rogue_like_commands) ? KEYMAP_MODE_ROGUE : KEYMAP_MODE_ORIG; unsigned char cmdkey; m = menu_dynamic_new(); if (!m) { return 0; } labels = string_make(lower_case); m->selections = labels; menu_dynamic_add_label(m, "Knowledge", '~', MENU_VALUE_KNOWLEDGE, labels); menu_dynamic_add_label(m, "Show Map", 'M', MENU_VALUE_MAP, labels); menu_dynamic_add_label(m, "^Show Messages", 'P', MENU_VALUE_MESSAGES, labels); menu_dynamic_add_label(m, "Show Monster List", '[', MENU_VALUE_MONSTERS, labels); menu_dynamic_add_label(m, "Show Object List", ']', MENU_VALUE_OBJECTS, labels); ADD_LABEL("Toggle Searching", CMD_TOGGLE_SEARCH, MN_ROW_VALID); /* Squelch toggle has different keys, but we don't have a way to look them up (see cmd-process.c). */ cmdkey = (mode == KEYMAP_MODE_ORIG) ? 'K' : 'O'; menu_dynamic_add_label(m, "Toggle Squelched", cmdkey, MENU_VALUE_TOGGLE_SQUELCHED, labels); ADD_LABEL("Squelch an item", CMD_DESTROY, MN_ROW_VALID); menu_dynamic_add_label(m, "Options", '=', MENU_VALUE_OPTIONS, labels); menu_dynamic_add_label(m, "Commands", '?', MENU_VALUE_HELP, labels); /* work out display region */ r.width = (int)menu_dynamic_longest_entry(m) + 3 + 2; /* +3 for tag, 2 for pad */ if (mx > Term->wid - r.width - 1) { r.col = Term->wid - r.width - 1; } else { r.col = mx + 1; } r.page_rows = m->count; if (my > Term->hgt - r.page_rows - 1) { if (my - r.page_rows - 1 <= 0) { /* menu has too many items, so put in upper right corner */ r.row = 1; r.col = Term->wid - r.width - 1; } else { r.row = Term->hgt - r.page_rows - 1; } } else { r.row = my + 1; } /* Hack -- no flush needed */ msg_flag = FALSE; screen_save(); menu_layout(m, &r); region_erase_bordered(&r); prt("(Enter to select, ESC) Command:", 0, 0); selected = menu_dynamic_select(m); menu_dynamic_free(m); string_free(labels); screen_load(); /* Check the command to see if it is allowed. */ switch (selected) { case -1: /* User cancelled the menu. */ return 3; case MENU_VALUE_KNOWLEDGE: case MENU_VALUE_MAP: case MENU_VALUE_MESSAGES: case MENU_VALUE_TOGGLE_SQUELCHED: case MENU_VALUE_HELP: case MENU_VALUE_MONSTERS: case MENU_VALUE_OBJECTS: case MENU_VALUE_OPTIONS: case CMD_TOGGLE_SEARCH: allowed = TRUE; break; case CMD_DESTROY: cmdkey = cmd_lookup_key(selected, mode); allowed = key_confirm_command(cmdkey); break; default: /* Invalid command; prevent anything from happening. */ bell("Invalid context menu command."); allowed = FALSE; break; } if (!allowed) return 1; /* Perform the command. */ switch (selected) { case MENU_VALUE_KNOWLEDGE: Term_keypress('~', 0); break; case MENU_VALUE_MAP: Term_keypress('M', 0); break; case MENU_VALUE_MESSAGES: Term_keypress(KTRL('p'), 0); break; case CMD_DESTROY: case CMD_TOGGLE_SEARCH: cmdkey = cmd_lookup_key(selected, mode); Term_keypress(cmdkey, 0); break; case MENU_VALUE_TOGGLE_SQUELCHED: /* Squelch toggle has different keys, but we don't have a way to look them up (see cmd-process.c). */ cmdkey = (mode == KEYMAP_MODE_ORIG) ? 'K' : 'O'; Term_keypress(cmdkey, 0); break; case MENU_VALUE_HELP: context_menu_command(mx, my); break; case MENU_VALUE_MONSTERS: Term_keypress('[', 0); break; case MENU_VALUE_OBJECTS: Term_keypress(']', 0); break; case MENU_VALUE_OPTIONS: Term_keypress('=', 0); break; default: break; } return 1; }
static enum birth_stage roller_command(bool first_call) { char prompt[80] = ""; size_t promptlen = 0; ui_event_data ke; char ch; enum birth_stage next = BIRTH_ROLLER; /* Used to keep track of whether we've rolled a character before or not. */ static bool prev_roll = FALSE; /* Display the player - a bit cheaty, but never mind. */ display_player(0, TRUE); if (first_call) prev_roll = FALSE; /* Add buttons */ button_kill_all(); button_add("[ESCAPE]", ESCAPE); button_add("[ACCEPT]", '\r'); button_add("[REROLL]", 'r'); if (prev_roll) button_add("[PREV]", 'p'); button_add("[HELP]", '?'); button_add("[QUIT]", '\x18'); /* CTRL-X */ clear_from(Term->hgt - 2); handle_stuff(); event_signal(EVENT_MOUSEBUTTONS); /* Prepare a prompt (must squeeze everything in) */ strnfcat(prompt, sizeof (prompt), &promptlen, "['r' to reroll"); if (prev_roll) strnfcat(prompt, sizeof(prompt), &promptlen, ", 'p' for prev"); strnfcat(prompt, sizeof (prompt), &promptlen, " or 'Enter' to accept]"); /* Prompt for it */ prt(prompt, Term->hgt - (mouse_buttons ? 2 : 1), Term->wid / 2 - promptlen / 2); /* Prompt and get a command */ ke = inkey_ex(); ch = ke.key; if (ch == ESCAPE) { button_kill('r'); button_kill('p'); next = BIRTH_BACK; } /* 'Enter' accepts the roll */ if ((ch == '\r') || (ch == '\n')) { next = BIRTH_NAME_CHOICE; } /* Reroll this character */ else if ((ch == ' ') || (ch == 'r')) { cmd_insert(CMD_ROLL_STATS); prev_roll = TRUE; } /* Previous character */ else if (prev_roll && (ch == 'p')) { cmd_insert(CMD_PREV_STATS); } /* Quit */ else if (ch == KTRL('X')) { cmd_insert(CMD_QUIT); next = BIRTH_COMPLETE; } /* Help XXX */ else if (ch == '?') { do_cmd_help(); } /* Nothing handled directly here */ else { bell("Illegal roller command!"); } /* Kill buttons */ button_kill_all(); handle_stuff(); event_signal(EVENT_MOUSEBUTTONS); return next; }
static enum birth_stage point_based_command(void) { static int stat = 0; char ch; enum birth_stage next = BIRTH_POINTBASED; ui_event_data ke; /* Add buttons */ button_kill_all(); button_add("[ESCAPE]", ESCAPE); button_add("[ACCEPT]", '\r'); button_add("[RESET STATS]", 'r'); button_add("[UP]", '8'); button_add("[DOWN]", '2'); button_add("[DEC_STAT]", '4'); button_add("[INC_STAT]", '6'); button_add("[QUIT]", '\x18'); /* CTRL-X */ clear_from(Term->hgt - 2); handle_stuff(); event_signal(EVENT_MOUSEBUTTONS); /* point_based_display();*/ /* Place cursor just after cost of current stat */ Term_gotoxy(COSTS_COL + 4, COSTS_ROW + stat); /* Get key */ /* Prompt and get a command */ ke = inkey_ex(); ch = ke.key; if (ch == KTRL('X')) { cmd_insert(CMD_QUIT); next = BIRTH_COMPLETE; } /* Go back a step, or back to the start of this step */ else if (ch == ESCAPE) { next = BIRTH_BACK; } else if (ch == 'r' || ch == 'R') { cmd_insert(CMD_RESET_STATS, FALSE); } /* Done */ else if ((ch == '\r') || (ch == '\n')) { next = BIRTH_NAME_CHOICE; } else { ch = target_dir(ch); /* Prev stat, looping round to the bottom when going off the top */ if (ch == 8) stat = (stat + A_MAX - 1) % A_MAX; /* Next stat, looping round to the top when going off the bottom */ if (ch == 2) stat = (stat + 1) % A_MAX; /* Decrease stat (if possible) */ if (ch == 4) { cmd_insert(CMD_SELL_STAT, stat); } /* Increase stat (if possible) */ if (ch == 6) { cmd_insert(CMD_BUY_STAT, stat); } } button_kill_all(); event_signal(EVENT_MOUSEBUTTONS); return next; }
int context_menu_player_2(int mx, int my) { menu_type *m; rect_region r; int selected; char *labels; m = menu_dynamic_new(); if (!m) { return 0; } labels = (char*)string_make(lower_case); m->selections = labels; menu_dynamic_add_label(m, "Knowledge", '~', 1, labels); menu_dynamic_add_label(m, "Show Map", 'M', 2, labels); menu_dynamic_add_label(m, "^Show Messages", 'P', 3, labels); menu_dynamic_add_label(m, "Show Monster List", '[', 9, labels); menu_dynamic_add_label(m, "Show Object List", ']', 10, labels); menu_dynamic_add_label(m, "Toggle Searching", 'S', 4, labels); if (player_has_pets()) { menu_dynamic_add_label(m, "Pet Commands", 'p', 5, labels); } menu_dynamic_add_label(m, "Destroy an item", 'k', 6, labels); menu_dynamic_add_label(m, "Options", '=', 8, labels); menu_dynamic_add_label(m, "Commands", '?', 7, labels); menu_dynamic_add_label(m, "Back", ' ', 11, labels); /* work out display region */ r.width = menu_dynamic_longest_entry(m) + 3 + 2; /* +3 for tag, 2 for pad */ if (mx > Term->wid - r.width - 1) { r.col = Term->wid - r.width - 1; } else { r.col = mx + 1; } r.page_rows = m->count; if (my > Term->hgt - r.page_rows - 1) { if (my - r.page_rows - 1 <= 0) { /* menu has too many items, so put in upper right corner */ r.row = 1; r.col = Term->wid - r.width - 1; } else { r.row = Term->hgt - r.page_rows - 1; } } else { r.row = my + 1; } /* Hack -- no flush needed */ msg_flag = FALSE; screen_save(); button_backup_all(TRUE); menu_layout(m, &r); rect_region_erase_bordered(&r); prtf(0, 0, "($UEnter to select$Y\n$V, $UESC$Y%c$V) Command:", ESCAPE); selected = menu_dynamic_select(m); menu_dynamic_free(m); string_free(labels); button_restore(); screen_load(); if (selected == 1) { /* show knowledge screen */ Term_keypress('~');//,0); } else if (selected == 2) { /* Toggle show map */ p_ptr->cmd.cmd = 'M'; repeat_check(); do_cmd_view_map(); } else if (selected == 3) { /* Toggle show messages */ Term_keypress(KTRL('p'));//,0);/*XXX should be ('p', KC_MOD_CONTROL);*/ } else if (selected == 4) { /* Toggle search mode */ Term_keypress('S');//,0); } else if (selected == 5) { /* show pet menu */ p_ptr->cmd.cmd = 'p'; repeat_check(); do_cmd_pet(); } else if (selected == 6) { /* destroy/squelch an item */ Term_keypress('k');//,0); } else if (selected == 7) { /* show the commands */ context_menu_command(mx,my); } else if (selected == 8) { /* show options screen */ Term_keypress('=');//,0); } else if (selected == 9) { /* show the monster list */ p_ptr->cmd.dir = 5; do_cmd_list_monster(0); //Term_keypress('[');//,0); } else if (selected == 10) { /* show the object list */ p_ptr->cmd.dir = 5; do_cmd_list_object(0); //Term_keypress(']');//,0); } else if (selected == 11) { /* show the previous menu again */ return 2; } return 1; }
/* * Request a command from the user. * * Note that "caret" ("^") is treated specially, and is used to * allow manual input of control characters. This can be used * on many machines to request repeated tunneling (Ctrl-H) and * on the Macintosh to request "Control-Caret". * * Note that "backslash" is treated specially, and is used to bypass any * keymap entry for the following character. This is useful for macros. */ static ui_event textui_get_command(int *count) { int mode = OPT(rogue_like_commands) ? KEYMAP_MODE_ROGUE : KEYMAP_MODE_ORIG; struct keypress tmp[2] = { { 0 }, { 0 } }; ui_event ke = EVENT_EMPTY; const struct keypress *act = NULL; /* Get command */ while (1) { /* Hack -- no flush needed */ msg_flag = FALSE; /* Activate "command mode" */ inkey_flag = TRUE; /* Get a command */ ke = inkey_ex(); if (ke.type == EVT_KBRD) { bool keymap_ok = TRUE; switch (ke.key.code) { case '0': { int c = textui_get_count(); if (c == -1 || !get_com_ex("Command: ", &ke)) continue; else *count = c; break; } case '\\': { /* Allow keymaps to be bypassed */ (void)get_com_ex("Command: ", &ke); keymap_ok = FALSE; break; } case '^': { /* Allow "control chars" to be entered */ if (get_com("Control: ", &ke.key)) ke.key.code = KTRL(ke.key.code); break; } } /* Find any relevant keymap */ if (keymap_ok) act = keymap_find(mode, ke.key); } /* Erase the message line */ prt("", 0, 0); if (ke.type == EVT_BUTTON) { /* Buttons are always specified in standard keyset */ act = tmp; tmp[0] = ke.key; } /* Apply keymap if not inside a keymap already */ if (ke.key.code && act && !inkey_next) { size_t n = 0; while (act[n].type) n++; /* Make room for the terminator */ n += 1; /* Install the keymap */ memcpy(request_command_buffer, act, n * sizeof(struct keypress)); /* Start using the buffer */ inkey_next = request_command_buffer; /* Continue */ continue; } /* Done */ break; } return ke; }
{ "Fuel your light source", { 'F' }, CMD_REFILL, NULL, player_can_refuel_prereq }, { "Use an item", { 'U', 'X' }, CMD_USE } }; /** * General actions */ struct cmd_info cmd_action[] = { { "Search for traps/doors", { 's' }, CMD_SEARCH }, { "Disarm a trap or chest", { 'D' }, CMD_DISARM }, { "Rest for a while", { 'R' }, CMD_NULL, textui_cmd_rest }, { "Look around", { 'l', 'x' }, CMD_NULL, do_cmd_look }, { "Target monster or location", { '*' }, CMD_NULL, textui_target }, { "Target closest monster", { '\'' }, CMD_NULL, textui_target_closest }, { "Dig a tunnel", { 'T', KTRL('T') }, CMD_TUNNEL }, { "Go up staircase", {'<' }, CMD_GO_UP }, { "Go down staircase", { '>' }, CMD_GO_DOWN }, { "Toggle search mode", { 'S', '#' }, CMD_TOGGLE_SEARCH }, { "Open a door or a chest", { 'o' }, CMD_OPEN }, { "Close a door", { 'c' }, CMD_CLOSE }, { "Fire at nearest target", { 'h', KC_TAB }, CMD_NULL, do_cmd_fire_at_nearest }, { "Throw an item", { 'v' }, CMD_THROW }, { "Walk into a trap", { 'W', '-' }, CMD_JUMP, NULL }, }; /** * Item management commands */ struct cmd_info cmd_item_manage[] = {
static int show_command_list(struct cmd_info cmd_list[], int size, int mx, int my) { menu_type *m; region r; int selected; int i; char cmd_name[80]; char key[3]; int mode = OPT(rogue_like_commands) ? KEYMAP_MODE_ROGUE : KEYMAP_MODE_ORIG; m = menu_dynamic_new(); if (!m) { return 0; } m->selections = lower_case; key[2] = '\0'; for (i=0; i < size; ++i) { if (KTRL(cmd_list[i].key[mode]) == cmd_list[i].key[mode]) { key[0] = '^'; key[1] = UN_KTRL(cmd_list[i].key[mode]); } else { key[0] = cmd_list[i].key[mode]; key[1] = '\0'; } strnfmt(cmd_name, 80, "%s (%s)", cmd_list[i].desc, key[mode]); menu_dynamic_add(m, cmd_name, i+1); } /* work out display region */ r.width = menu_dynamic_longest_entry(m) + 3 + 2; /* +3 for tag, 2 for pad */ if (mx > Term->wid - r.width - 1) { r.col = Term->wid - r.width - 1; } else { r.col = mx + 1; } r.page_rows = m->count; if (my > Term->hgt - r.page_rows - 1) { if (my - r.page_rows - 1 <= 0) { /* menu has too many items, so put in upper right corner */ r.row = 1; r.col = Term->wid - r.width - 1; } else { r.row = Term->hgt - r.page_rows - 1; } } else { r.row = my + 1; } screen_save(); menu_layout(m, &r); region_erase_bordered(&r); prt("(Enter to select, ESC) Command:", 0, 0); selected = menu_dynamic_select(m); menu_dynamic_free(m); screen_load(); if ((selected > 0) && (selected < size+1)) { /* execute the command */ Term_keypress(cmd_list[selected-1].key[mode], 0); } return 1; }