/* * Place the cursor at the collect position for visual mode */ static void place_visual_list_cursor(int col, int row, byte a, byte c, byte attr_top, byte char_left) { int i = a - attr_top; int j = c - char_left; int x = col + actual_width(j); int y = row + actual_height(i); /* Place the cursor */ Term_gotoxy(x, y); }
/** * Show quiver missiles in full inventory */ static void item_menu_browser(int oid, void *data, const region *local_area) { char tmp_val[80]; int count, j, i = num_obj; int quiver_slots = (player->upkeep->quiver_cnt + z_info->quiver_slot_size - 1) / z_info->quiver_slot_size; /* Set up to output below the menu */ text_out_hook = text_out_to_screen; text_out_wrap = 0; text_out_indent = local_area->col - 1; text_out_pad = 1; prt("", local_area->row + local_area->page_rows, MAX(0, local_area->col - 1)); Term_gotoxy(local_area->col, local_area->row + local_area->page_rows); /* If we're printing pack slots the quiver takes up */ if (olist_mode & OLIST_QUIVER && player->upkeep->command_wrk == USE_INVEN) { /* Quiver may take multiple lines */ for (j = 0; j < quiver_slots; j++, i++) { const char *fmt = "in Quiver: %d missile%s\n"; char letter = I2A(i); /* Number of missiles in this "slot" */ if (j == quiver_slots - 1) count = player->upkeep->quiver_cnt - (z_info->quiver_slot_size * (quiver_slots - 1)); else count = z_info->quiver_slot_size; /* Print the (disabled) label */ strnfmt(tmp_val, sizeof(tmp_val), "%c) ", letter); text_out_c(COLOUR_SLATE, tmp_val, local_area->row + i, local_area->col); /* Print the count */ strnfmt(tmp_val, sizeof(tmp_val), fmt, count, count == 1 ? "" : "s"); text_out_c(COLOUR_L_UMBER, tmp_val, local_area->row + i, local_area->col + 3); } } /* Always print a blank line */ prt("", local_area->row + i, MAX(0, local_area->col - 1)); /* Blank out whole tiles */ while ((tile_height > 1) && ((local_area->row + i) % tile_height != 0)) { i++; prt("", local_area->row + i, MAX(0, local_area->col - 1)); } text_out_pad = 0; text_out_indent = 0; }
/* * Move to a location and, using an attr, add a char */ errr Term_putch(int x, int y, byte a, char c) { errr res; /* Move first */ if ((res = Term_gotoxy(x, y)) != 0) return (res); /* Then add the char */ if ((res = Term_addch(a, c)) != 0) return (res); /* Success */ return (0); }
/* * Move to a location and, using an attr, add a string */ errr Term_putstr(int x, int y, int n, byte a, cptr s) { errr res; /* Move first */ if ((res = Term_gotoxy(x, y)) != 0) return (res); /* Then add the string */ if ((res = Term_addstr(n, a, s)) != 0) return (res); /* Success */ return (0); }
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; }
/* * Display a "small-scale" map of the dungeon. * * Note that the "player" is always displayed on the map. */ void do_cmd_view_map(void) { int cy, cx; byte w, h; const char *prompt = "Hit any key to continue"; if (Term->view_map_hook) { (*(Term->view_map_hook))(Term); return; } /* Save screen */ screen_save(); /* Note */ prt("Please wait...", 0, 0); /* Flush */ Term_fresh(); /* Clear the screen */ Term_clear(); /* store the tile multipliers */ w = tile_width; h = tile_height; tile_width = 1; tile_height = 1; /* Display the map */ display_map(&cy, &cx); /* Show the prompt */ put_str(prompt, Term->hgt - 1, Term->wid / 2 - strlen(prompt) / 2); /* Highlight the player */ Term_gotoxy(cx, cy); /* Get any key */ (void)anykey(); /* Restore the tile multipliers */ tile_width = w; tile_height = h; /* Load screen */ screen_load(); }
/** * Show spell long description when browsing */ static void curse_menu_browser(int oid, void *data, const region *loc) { int *choice = data; /* Redirect output to the screen */ text_out_hook = text_out_to_screen; text_out_wrap = 0; text_out_indent = loc->col - 1; text_out_pad = 1; Term_gotoxy(loc->col, loc->row + loc->page_rows); text_out("\n%s\n", curses[choice[oid]].desc); /* XXX */ text_out_pad = 0; text_out_indent = 0; }
/* Show the birth instructions on an otherwise blank screen */ static void print_menu_instructions(void) { /* Clear screen */ Term_clear(); /* Output to the screen */ text_out_hook = text_out_to_screen; /* Indent output */ text_out_indent = QUESTION_COL; Term_gotoxy(QUESTION_COL, HEADER_ROW); /* Display some helpful information */ text_out_e(BIRTH_MENU_HELPTEXT); /* Reset text_out() indentation */ text_out_indent = 0; }
/* * Hack -- Display the "name" and "attr/chars" of a monster race */ static void roff_top(int r_idx) { monster_race *r_ptr = &r_info[r_idx]; byte a1, a2; char c1, c2; /* Get the chars */ c1 = r_ptr->d_char; c2 = r_ptr->x_char; /* Get the attrs */ a1 = r_ptr->d_attr; a2 = r_ptr->x_attr; /* Clear the top line */ Term_erase(0, 0, 255); /* Reset the cursor */ Term_gotoxy(0, 0); /* A title (use "The" for non-uniques) */ if (!(r_ptr->flags1 & RF1_UNIQUE)) { Term_addstr(-1, TERM_WHITE, "The "); } /* Dump the name */ Term_addstr(-1, TERM_WHITE, (r_name + r_ptr->name)); /* Append the "standard" attr/char info */ Term_addstr(-1, TERM_WHITE, " ('"); Term_addch(a1, c1); Term_addstr(-1, TERM_WHITE, "')"); /* Append the "optional" attr/char info */ Term_addstr(-1, TERM_WHITE, "/('"); Term_addch(a2, c2); if (use_bigtile && (a2 & 0x80)) Term_addch(255, -1); Term_addstr(-1, TERM_WHITE, "'):"); }
/* * Display glyph and colours */ static void display_glyphs(int col, int row, int height, int width, byte a, wchar_t c) { int i; int x, y; /* Clear the display lines */ for (i = 0; i < height; i++) Term_erase(col, row + i, width); /* Prompt */ prt("Choose colour:", row + height / 2, col); Term_locate(&x, &y); for (i = 0; i < MAX_COLORS; i++) big_pad(x + i, y, i, c); /* Place the cursor */ Term_gotoxy(x + a, y); }
/** * Move the cursor to a given map location. */ static void move_cursor_relative_map(int y, int x) { int ky, kx; term *old; int j; /* Scan windows */ for (j = 0; j < ANGBAND_TERM_MAX; j++) { term *t = angband_term[j]; /* No window */ if (!t) continue; /* No relevant flags */ if (!(window_flag[j] & (PW_MAPS))) continue; /* Location relative to panel */ ky = y - t->offset_y; if (tile_height > 1) ky = tile_height * ky; /* Verify location */ if ((ky < 0) || (ky >= t->hgt)) continue; /* Location relative to panel */ kx = x - t->offset_x; if (tile_width > 1) kx = tile_width * kx; /* Verify location */ if ((kx < 0) || (kx >= t->wid)) continue; /* Go there */ old = Term; Term_activate(t); (void)Term_gotoxy(kx, ky); Term_activate(old); } }
/** * Show spell long description when browsing */ static void gain_spec_menu_browser(int oid, void *data, const region *loc) { struct spec_menu_data *d = data; /* Redirect output to the screen */ text_out_hook = text_out_to_screen; text_out_wrap = 0; text_out_indent = loc->col - 1; text_out_pad = 1; clear_from(loc->row + loc->page_rows); Term_gotoxy(loc->col, loc->row + loc->page_rows); text_out_to_screen(TERM_DEEP_L_BLUE, (char *) abilities[d->specialties[oid]].desc); /* XXX */ text_out_pad = 0; text_out_indent = 0; }
/** * Show spell long description when browsing */ static void spell_menu_browser(int oid, void *data, const region * loc) { struct spell_menu_data *d = data; int spell = d->spells[oid]; const magic_type *s_ptr = &mp_ptr->info[spell]; /* Redirect output to the screen */ text_out_hook = text_out_to_screen; text_out_wrap = 0; text_out_indent = loc->col - 1; text_out_pad = 1; Term_gotoxy(loc->col, loc->row + loc->page_rows); text_out_c(TERM_DEEP_L_BLUE, format("\n%s\n", s_info[s_ptr->index].text)); /* XXX */ text_out_pad = 0; text_out_indent = 0; }
/** * Show spell long description when browsing */ static void curse_menu_browser(int oid, void *data, const region *loc) { struct curse_menu_data *choice = data; char buf[80]; /* Redirect output to the screen */ text_out_hook = text_out_to_screen; text_out_wrap = 0; text_out_indent = loc->col - 1; text_out_pad = 1; Term_gotoxy(loc->col, loc->row + loc->page_rows); my_strcpy(buf, curses[choice[oid].index].desc, sizeof(buf)); my_strcap(buf); text_out(" %s.\n", buf); /* XXX */ text_out_pad = 0; text_out_indent = 0; }
/** * Show spell long description when browsing */ static void spell_menu_browser(int oid, void *data, const region *loc) { struct spell_menu_data *d = data; int spell_index = d->spells[oid]; if (d->show_description) { /* Redirect output to the screen */ text_out_hook = text_out_to_screen; text_out_wrap = 0; text_out_indent = loc->col - 1; text_out_pad = 1; Term_gotoxy(loc->col, loc->row + loc->page_rows); text_out("\n%s\n", spell_by_index(spell_index)->text); /* XXX */ text_out_pad = 0; text_out_indent = 0; } }
/** * Show specialty long description when browsing */ static void view_spec_menu_browser(int oid, void *data, const region *loc) { ability *choices = data; /* Redirect output to the screen */ text_out_hook = text_out_to_screen; text_out_wrap = 0; text_out_indent = loc->col - 1; text_out_pad = 1; clear_from(loc->row + loc->page_rows); Term_gotoxy(loc->col, loc->row + loc->page_rows); if (choices[oid].index == PF_MAX) text_out_c(TERM_L_BLUE, "\n%s\n", race_other_desc); else text_out_c(TERM_L_BLUE, "\n%s\n", (char *)choices[oid].desc); /* XXX */ text_out_pad = 0; text_out_indent = 0; }
/** * Show quiver missiles in full inventory */ static void item_menu_browser(int oid, void *data, const region *area) { char tmp_val[80]; int count, j, i = num_obj; int quiver_slots = (player->upkeep->quiver_cnt + z_info->stack_size - 1) / z_info->stack_size; /* Set up to output below the menu */ text_out_hook = text_out_to_screen; text_out_wrap = 0; text_out_indent = area->col - 1; text_out_pad = 1; prt("", area->row + area->page_rows, MAX(0, area->col - 1)); Term_gotoxy(area->col, area->row + area->page_rows); /* Quiver may take multiple lines */ for (j = 0; j < quiver_slots; j++, i++) { const char *fmt = "in Quiver: %d missile%s\n"; char letter = I2A(i); /* Number of missiles in this "slot" */ if (j == quiver_slots - 1) count = player->upkeep->quiver_cnt - (z_info->stack_size * (quiver_slots - 1)); else count = z_info->stack_size; /* Print the (disabled) label */ strnfmt(tmp_val, sizeof(tmp_val), "%c) ", letter); text_out_c(COLOUR_SLATE, tmp_val, area->row + i, area->col); /* Print the count */ strnfmt(tmp_val, sizeof(tmp_val), fmt, count, count == 1 ? "" : "s"); text_out_c(COLOUR_L_UMBER, tmp_val, area->row + i, area->col + 3); } text_out_pad = 0; text_out_indent = 0; }
static void mon_lore(int oid) { /* Update the monster recall window */ monster_race_track(default_join[oid].oid); handle_stuff(p_ptr); /* Save the screen */ screen_save(); /* Describe */ text_out_hook = text_out_to_screen; /* Recall monster */ roff_top(default_join[oid].oid); Term_gotoxy(0, 2); describe_monster(default_join[oid].oid, FALSE); text_out_c(TERM_L_BLUE, "\n[Press any key to continue]\n"); (void) anykey(); /* Load the screen */ screen_load(); }
static void class_help(int i, void *db, const region *l) { int j; /* Output to the screen */ text_out_hook = text_out_to_screen; /* Indent output */ text_out_indent = CLASS_AUX_COL; Term_gotoxy(CLASS_AUX_COL, TABLE_ROW); for (j = 0; j < A_MAX; j++) { text_out_e("%s%+d%+8d%+8d\n", stat_names_reduced[j], p_info[p_ptr->prace].r_adj[j], c_info[i].c_adj[j], (p_info[p_ptr->prace].r_adj[j] + c_info[i].c_adj[j])); } text_out_e("Hit die: %6d%8d\n", c_info[i].c_mhp, p_info[p_ptr->prace].r_mhp + c_info[i].c_mhp); text_out_e("Experience: %3d%%%7d%%", c_info[i].c_exp, + (p_info[p_ptr->prace].r_exp + c_info[i].c_exp)); /* Reset text_out() indentation */ text_out_indent = 0; }
static void race_help(int i, void *db, const region *l) { int j; /* Output to the screen */ text_out_hook = text_out_to_screen; /* Indent output */ text_out_indent = RACE_AUX_COL; Term_gotoxy(RACE_AUX_COL, TABLE_ROW); for (j = 0; j < A_MAX; j++) { text_out_e("%s%+d\n", stat_names_reduced[j], p_info[i].r_adj[j]); } text_out_e("Hit die: %d\n", p_info[i].r_mhp); text_out_e("Experience: %d%%\n", p_info[i].r_exp); text_out_e("Infravision: %d ft", p_info[i].infra * 10); /* Reset text_out() indentation */ text_out_indent = 0; }
/* * Hack -- describe the given monster race in the current "term" window */ void display_roff(int r_idx) { int y; /* Erase the window */ for (y = 0; y < Term->hgt; y++) { /* Erase the line */ Term_erase(0, y, 255); } /* Begin recall */ Term_gotoxy(0, 1); /* Output to the screen */ text_out_hook = text_out_to_screen; /* Recall monster */ describe_monster(r_idx, FALSE); /* Describe monster */ roff_top(r_idx); }
void display_player_xtra_info(void) { size_t i; for (i = 0; i < N_ELEMENTS(panels); i++) { struct panel *p = panels[i].panel(); display_panel(p, panels[i].align_left, &panels[i].bounds); panel_free(p); } /* Indent output by 1 character, and wrap at column 72 */ text_out_wrap = 72; text_out_indent = 1; /* History */ Term_gotoxy(text_out_indent, 19); text_out_to_screen(COLOUR_WHITE, player->history); /* Reset text_out() vars */ text_out_wrap = 0; text_out_indent = 0; return; }
static void display_columns(menu_type *menu, int cursor, int *top, rect_region *loc) { int c, r; int w, h; int n = menu->filter_list ? menu->filter_count : menu->count; int col = loc->col; int row = loc->row; int rows_per_page = loc->page_rows; int cols = (n + rows_per_page - 1) / rows_per_page; int colw = 23; Term_get_size(&w, &h); if (menu->column_width > 0) { colw = menu->column_width; } else if ((colw * cols) > (w - col)) colw = (w - col) / cols; for (c = 0; c < cols; c++) { for (r = 0; r < rows_per_page; r++) { int pos = c * rows_per_page + r; bool is_cursor = (pos == cursor); if (pos < n) display_menu_row(menu, pos, 0, is_cursor, row + r, col + c * colw, colw); } } if (menu->cursor >= 0) Term_gotoxy(col + (cursor / rows_per_page) * colw, row + (cursor % rows_per_page) - *top); }
/* Display current view of a skin */ static void display_scrolling(menu_type *menu, int cursor, int *top, rect_region *loc) { int col = loc->col; int row = loc->row; int rows_per_page = loc->page_rows; int n = menu->filter_list ? menu->filter_count : menu->count; int i; /* Keep a certain distance from the top when possible */ if ((cursor <= *top) && (*top > 0)) *top = cursor - 1; /* Keep a certain distance from the bottom when possible */ if (cursor >= *top + (rows_per_page - 1)) *top = cursor - (rows_per_page - 1) + 1; /* Limit the top to legal places */ *top = MIN(*top, n - rows_per_page); *top = MAX(*top, 0); for (i = 0; i < rows_per_page; i++) { /* Blank all lines */ Term_erase(col, row + i, loc->width); if (i < n) { /* Redraw the line if it's within the number of menu items */ bool is_curs = (i == cursor - *top); display_menu_row(menu, i + *top, *top, is_curs, row + i, col, loc->width); } } if (menu->cursor >= 0) Term_gotoxy(col, row + cursor - *top); }
/* * Hack -- describe the given monster race in the current "term" window */ void display_roff(const int r_idx, const monster_lore *l_ptr) { monster_race *r_ptr = &r_info[r_idx]; int y; /* Erase the window */ for (y = 0; y < Term->hgt; y++) { /* Erase the line */ Term_erase(0, y, 255); } /* Begin recall */ Term_gotoxy(0, 1); /* Output to the screen */ text_out_hook = text_out_to_screen; /* Recall monster */ describe_monster_race(r_ptr, l_ptr, FALSE); /* Describe monster */ roff_top(r_idx, 0); }
/* * Do glyph picker command -- Change glyphs */ static bool glyph_command(ui_event ke, bool * glyph_picker_ptr, int height, int width, byte * cur_attr_ptr, wchar_t * cur_char_ptr, int col, int row) { static byte attr_old = 0; static char char_old = 0; /* Get mouse movement */ if (ke.type == EVT_MOUSE) { byte a = *cur_attr_ptr; int mx = logical_width(ke.mouse.x - col); if (ke.mouse.y != row + height / 2) return FALSE; if ((mx >= 0) && (mx < MAX_COLORS) && (ke.mouse.button == 1)) { /* Set the visual */ *cur_attr_ptr = a = mx - 14; /* Accept change */ remove_tiles(col, row, glyph_picker_ptr, width, height); return TRUE; } else { return FALSE; } } if (ke.type != EVT_KBRD) return FALSE; switch (ke.key.code) { case ESCAPE: { if (*glyph_picker_ptr) { /* Cancel change */ *cur_attr_ptr = attr_old; *cur_char_ptr = char_old; remove_tiles(col, row, glyph_picker_ptr, width, height); return TRUE; } break; } case KC_ENTER: { if (*glyph_picker_ptr) { /* Accept change */ remove_tiles(col, row, glyph_picker_ptr, width, height); return TRUE; } break; } case 'V': case 'v': { if (!*glyph_picker_ptr) { *glyph_picker_ptr = TRUE; attr_old = *cur_attr_ptr; char_old = *cur_char_ptr; } else { /* Cancel change */ *cur_attr_ptr = attr_old; *cur_char_ptr = char_old; remove_tiles(col, row, glyph_picker_ptr, width, height); } return TRUE; } case 'i': case 'I': { if (*glyph_picker_ptr) { char code_point[6]; bool res = FALSE; /* Ask the user for a code point */ Term_gotoxy(col, row + height / 2 + 2); res = get_string("(up to 5 hex digits):", code_point, 5); /* Process input */ if (res) { unsigned long int point = strtoul(code_point, (char **) NULL, 16); *cur_char_ptr = (wchar_t) point; return TRUE; } } break; } default: { int d = target_dir(ke.key); byte a = *cur_attr_ptr; if (!*glyph_picker_ptr) break; /* Horizontal only */ if (ddy[d] != 0) break; /* Horizontal movement */ if (ddx[d] != 0) { a += ddx[d] + BASIC_COLORS; a = a % BASIC_COLORS; *cur_attr_ptr = a; } /* We need to always eat the input even if it is clipped, * otherwise it will be interpreted as a change object * selection command with messy results. */ return TRUE; } } /* Glyph picker command is not used */ return FALSE; }
/* * Print some (colored) text to the screen at the current cursor position, * automatically "wrapping" existing text (at spaces) when necessary to * avoid placing any text into the last column, and clearing every line * before placing any text in that line. Also, allow "newline" to force * a "wrap" to the next line. Advance the cursor as needed so sequential * calls to this function will work correctly. * * Once this function has been called, the cursor should not be moved * until all the related "text_out()" calls to the window are complete. * * This function will correctly handle any width up to the maximum legal * value of 256, though it works best for a standard 80 character width. */ void text_out_to_screen(byte a, const char *str) { int x, y; int wid, h; int wrap; const wchar_t *s; wchar_t buf[1024]; /* Obtain the size */ (void)Term_get_size(&wid, &h); /* Obtain the cursor */ (void)Term_locate(&x, &y); /* Copy to a rewriteable string */ Term_mbstowcs(buf, str, 1024); /* Use special wrapping boundary? */ if ((text_out_wrap > 0) && (text_out_wrap < wid)) wrap = text_out_wrap; else wrap = wid; /* Process the string */ for (s = buf; *s; s++) { wchar_t ch; /* Force wrap */ if (*s == L'\n') { /* Wrap */ x = text_out_indent; y++; /* Clear line, move cursor */ Term_erase(x, y, 255); x += text_out_pad; Term_gotoxy(x, y); continue; } /* Clean up the char */ ch = (iswprint(*s) ? *s : L' '); /* Wrap words as needed */ if ((x >= wrap - 1) && (ch != L' ')) { int i, n = 0; byte av[256]; wchar_t cv[256]; /* Wrap word */ if (x < wrap) { /* Scan existing text */ for (i = wrap - 2; i >= 0; i--) { /* Grab existing attr/char */ Term_what(i, y, &av[i], &cv[i]); /* Break on space */ if (cv[i] == L' ') break; /* Track current word */ n = i; } } /* Special case */ if (n == 0) n = wrap; /* Clear line */ Term_erase(n, y, 255); /* Wrap */ x = text_out_indent; y++; /* Clear line, move cursor */ Term_erase(x, y, 255); x += text_out_pad; Term_gotoxy(x, y); /* Wrap the word (if any) */ for (i = n; i < wrap - 1; i++) { /* Dump */ Term_addch(av[i], cv[i]); /* Advance (no wrap) */ if (++x > wrap) x = wrap; } } /* Dump */ Term_addch(a, ch); /* Advance */ if (++x > wrap) x = wrap; } }
/* * Get some input at the cursor location. * * The buffer is assumed to have been initialized to a default string. * Note that this string is often "empty" (see below). * * The default buffer is displayed in yellow until cleared, which happens * on the first keypress, unless that keypress is Return. * * Normal chars clear the default and append the char. * Backspace clears the default or deletes the final char. * Return accepts the current buffer contents and returns TRUE. * Escape clears the buffer and the window and returns FALSE. * * Note that 'len' refers to the size of the buffer. The maximum length * of the input is 'len-1'. * * 'keypress_h' is a pointer to a function to handle keypresses, altering * the input buffer, cursor position and suchlike as required. See * 'askfor_aux_keypress' (the default handler if you supply NULL for * 'keypress_h') for an example. */ bool askfor_aux(char *buf, size_t len, bool (*keypress_h)(char *, size_t, size_t *, size_t *, struct keypress, bool)) { int y, x; size_t k = 0; /* Cursor position */ size_t nul = 0; /* Position of the null byte in the string */ struct keypress ch = { 0 }; bool done = FALSE; bool firsttime = TRUE; if (keypress_h == NULL) { keypress_h = askfor_aux_keypress; } /* Locate the cursor */ Term_locate(&x, &y); /* Paranoia */ if ((x < 0) || (x >= 80)) x = 0; /* Restrict the length */ if (x + len > 80) len = 80 - x; /* Truncate the default entry */ buf[len-1] = '\0'; /* Get the position of the null byte */ nul = strlen(buf); /* Display the default answer */ Term_erase(x, y, (int)len); Term_putstr(x, y, -1, TERM_YELLOW, buf); /* Process input */ while (!done) { /* Place cursor */ Term_gotoxy(x + k, y); /* Get a key */ ch = inkey(); /* Let the keypress handler deal with the keypress */ done = keypress_h(buf, len, &k, &nul, ch, firsttime); /* Update the entry */ Term_erase(x, y, (int)len); Term_putstr(x, y, -1, TERM_WHITE, buf); /* Not the first time round anymore */ firsttime = FALSE; } /* Done */ return (ch.code != ESCAPE); }
static void display_resistance_panel(const struct player_flag_record *rec, size_t size, const region *bounds) { size_t i; int j; int col = bounds->col; int row = bounds->row; int res_cols = 5 + 2 + player->body.count; Term_putstr(col, row++, res_cols, COLOUR_WHITE, " abcdefghijkl@"); for (i = 0; i < size - 3; i++, row++) { byte name_attr = COLOUR_WHITE; Term_gotoxy(col + 6, row); /* Repeated extraction of flags is inefficient but more natural */ for (j = 0; j <= player->body.count; j++) { bitflag f[OF_SIZE]; byte attr = COLOUR_WHITE | (j % 2) * 8; /* alternating columns */ char sym = '.'; bool res = false, imm = false, vul = false, rune = false; bool timed = false; bool known = false; /* Object or player info? */ if (j < player->body.count) { int index = 0; struct object *obj = slot_object(player, j); struct curse_data *curse = obj ? obj->curses : NULL; while (obj) { /* Wipe flagset */ of_wipe(f); /* Get known properties */ object_flags_known(obj, f); if (rec[i].element != -1) { known = object_element_is_known(obj, rec[i].element); } else if (rec[i].flag != -1) { known = object_flag_is_known(obj, rec[i].flag); } else { known = true; } /* Get resistance, immunity and vulnerability info */ if (rec[i].mod != -1) { if (obj->modifiers[rec[i].mod] != 0) { res = true; } rune = (player->obj_k->modifiers[rec[i].mod] == 1); } else if (rec[i].flag != -1) { if (of_has(f, rec[i].flag)) { res = true; } rune = of_has(player->obj_k->flags, rec[i].flag); } else if (rec[i].element != -1) { if (known) { if (obj->el_info[rec[i].element].res_level == 3) { imm = true; } if (obj->el_info[rec[i].element].res_level == 1) { res = true; } if (obj->el_info[rec[i].element].res_level == -1) { vul = true; } } rune = (player->obj_k->el_info[rec[i].element].res_level == 1); } /* Move to any unprocessed curse object */ if (curse) { index++; obj = NULL; while (index < z_info->curse_max) { if (curse[index].power) { obj = curses[index].obj; break; } else { index++; } } } else { obj = NULL; } } } else { player_flags(player, f); known = true; /* Timed flags only in the player column */ if (rec[i].tmd_flag >= 0) { timed = player->timed[rec[i].tmd_flag] ? true : false; /* There has to be one special case... */ if ((rec[i].tmd_flag == TMD_AFRAID) && (player->timed[TMD_TERROR])) timed = true; } /* Set which (if any) symbol and color are used */ if (rec[i].mod != -1) { int k; /* Shape modifiers */ for (k = 0; k < OBJ_MOD_MAX; k++) { res = (player->shape->modifiers[i] > 0); vul = (player->shape->modifiers[i] > 0); } /* Messy special cases */ if (rec[i].mod == OBJ_MOD_INFRA) res |= (player->race->infra > 0); if (rec[i].mod == OBJ_MOD_TUNNEL) res |= (player->race->r_skills[SKILL_DIGGING] > 0); } else if (rec[i].flag != -1) { res = of_has(f, rec[i].flag); res |= (of_has(player->shape->flags, rec[i].flag) && of_has(player->obj_k->flags, rec[i].flag)); } else if (rec[i].element != -1) { int el = rec[i].element; imm = (player->race->el_info[el].res_level == 3) || ((player->shape->el_info[el].res_level == 3) && (player->obj_k->el_info[el].res_level)); res = (player->race->el_info[el].res_level == 1) || ((player->shape->el_info[el].res_level == 1) && (player->obj_k->el_info[el].res_level)); vul = (player->race->el_info[el].res_level == -1) || ((player->shape->el_info[el].res_level == -1) && (player->obj_k->el_info[el].res_level)); } } /* Colour the name appropriately */ if (imm) { name_attr = COLOUR_GREEN; } else if (res && (name_attr != COLOUR_GREEN)) { name_attr = COLOUR_L_BLUE; } else if (vul && (name_attr != COLOUR_GREEN)) { name_attr = COLOUR_RED; } /* Set the symbols and print them */ if (vul) { sym = '-'; } else if (imm) { sym = '*'; } else if (res) { sym = '+'; } else if (timed) { sym = '!'; attr = COLOUR_L_GREEN; } else if ((j < player->body.count) && slot_object(player, j) && !known && !rune) { sym = '?'; } Term_addch(attr, sym); } /* Check if the rune is known */ if (((rec[i].mod >= 0) && (player->obj_k->modifiers[rec[i].mod] == 0)) || ((rec[i].flag >= 0) && !of_has(player->obj_k->flags, rec[i].flag)) || ((rec[i].element >= 0) && (player->obj_k->el_info[rec[i].element].res_level == 0))) { name_attr = COLOUR_SLATE; } Term_putstr(col, row, 6, name_attr, format("%5s:", rec[i].name)); } Term_putstr(col, row++, res_cols, COLOUR_WHITE, " abcdefghijkl@"); /* Equippy */ display_player_equippy(row++, col + 6); }
static void display_resistance_panel(const struct player_flag_record *rec, size_t size, const region *bounds) { size_t i; int j; int col = bounds->col; int row = bounds->row; int res_cols = 5 + 2 + player->body.count; Term_putstr(col, row++, res_cols, COLOUR_WHITE, " abcdefghijkl@"); for (i = 0; i < size - 3; i++, row++) { byte name_attr = COLOUR_WHITE; Term_gotoxy(col + 6, row); /* Repeated extraction of flags is inefficient but more natural */ for (j = 0; j <= player->body.count; j++) { struct object *obj; bitflag f[OF_SIZE]; byte attr = COLOUR_WHITE | (j % 2) * 8; /* alternating columns */ char sym = '.'; bool res = false, imm = false, vul = false, rune = false; bool timed = false; bool known = false; /* Wipe flagset */ of_wipe(f); /* Get the object or player info */ obj = j < player->body.count ? slot_object(player, j) : NULL; if (j < player->body.count && obj) { /* Get known properties */ object_flags_known(obj, f); if (rec[i].element != -1) known = object_element_is_known(obj, rec[i].element); else if (rec[i].flag != -1) known = object_flag_is_known(obj, rec[i].flag); else known = true; } else if (j == player->body.count) { player_flags(player, f); known = true; /* Timed flags only in the player column */ if (rec[i].tmd_flag >= 0) { timed = player->timed[rec[i].tmd_flag] ? true : false; /* There has to be one special case... */ if ((rec[i].tmd_flag == TMD_AFRAID) && (player->timed[TMD_TERROR])) timed = true; } } /* Set which (if any) symbol and color are used */ if (rec[i].mod != -1) { if (j != player->body.count) res = (obj && (obj->modifiers[rec[i].mod] != 0)); else { /* Messy special cases */ if (rec[i].mod == OBJ_MOD_INFRA) res = (player->race->infra > 0); if (rec[i].mod == OBJ_MOD_TUNNEL) res = (player->race->r_skills[SKILL_DIGGING] > 0); } rune = (player->obj_k->modifiers[rec[i].mod] == 1); } else if (rec[i].flag != -1) { res = of_has(f, rec[i].flag); rune = of_has(player->obj_k->flags, rec[i].flag); } else if (rec[i].element != -1) { if (j != player->body.count) { imm = obj && known && (obj->el_info[rec[i].element].res_level == 3); res = obj && known && (obj->el_info[rec[i].element].res_level == 1); vul = obj && known && (obj->el_info[rec[i].element].res_level == -1); } else { imm = player->race->el_info[rec[i].element].res_level == 3; res = player->race->el_info[rec[i].element].res_level == 1; vul = player->race->el_info[rec[i].element].res_level == -1; } rune = (player->obj_k->el_info[rec[i].element].res_level == 1); } /* Set the symbols and print them */ if (imm) name_attr = COLOUR_GREEN; else if (!rune) name_attr = COLOUR_SLATE; else if (res && (name_attr != COLOUR_GREEN)) name_attr = COLOUR_L_BLUE; if (vul) sym = '-'; else if (imm) sym = '*'; else if (res) sym = '+'; else if (timed) { sym = '!'; attr = COLOUR_L_GREEN; } else if ((j < player->body.count) && obj && !known && !rune) sym = '?'; Term_addch(attr, sym); } Term_putstr(col, row, 6, name_attr, format("%5s:", rec[i].name)); } Term_putstr(col, row++, res_cols, COLOUR_WHITE, " abcdefghijkl@"); /* Equippy */ display_player_equippy(row++, col + 6); }