/* * Hack -- Display the "name" and "attr/chars" of a monster race */ static void roff_top(const int r_idx, int m_idx) { byte a1, a2; char c1, c2; char desc[80]; monster_race *r_ptr = &r_info[r_idx]; /* Describe the monster */ if (m_idx) { /* Describe the monster */ monster_desc(desc, sizeof(desc), m_idx, 0x80); /* Capitalise the first letter */ if (islower(desc[0])) desc[0] = toupper(desc[0]); } /* Not describing a specific monster, so hack a description */ else { /* Get the name */ race_desc(desc, sizeof(desc), r_idx, 0x400, 1); /* Capitalise the first letter */ if (islower(desc[0])) desc[0] = toupper(desc[0]); } /* 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); /* Dump the name */ Term_addstr(-1, TERM_WHITE, desc); if (!use_dbltile && !use_trptile) { /* 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, "'):"); } }
/* * 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, "'):"); }
/* * Hack -- Display the "name" and "attr/chars" of a monster race */ void roff_top(int r_idx) { monster_race *r_ptr = &r_info[r_idx]; byte a1, a2; char c1, c2; /* Access the chars */ c1 = r_ptr->d_char; c2 = r_ptr->x_char; /* Access 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_add_bigch(a1, c1); Term_addstr(-1, TERM_WHITE, "')"); /* Append the "optional" attr/char info */ Term_addstr(-1, TERM_WHITE, "/('"); Term_add_bigch(a2, c2); Term_addstr(-1, TERM_WHITE, "'):"); /* Wizards get extra info */ if (p_ptr->wizard) { char buf[6]; sprintf(buf, "%d", r_idx); Term_addstr(-1, TERM_WHITE, " ("); Term_addstr(-1, TERM_L_BLUE, buf); Term_addch(TERM_WHITE, ')'); } }
/* 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, ')'); }
/** * Load the attr/char at each point along "path" which is on screen from * "a" and "c". This was saved in draw_path(). */ static void load_path(u16b path_n, u16b *path_g, wchar_t *c, int *a) { int i; for (i = 0; i < path_n; i++) { int y = GRID_Y(path_g[i]); int x = GRID_X(path_g[i]); if (!panel_contains(y, x)) continue; move_cursor_relative(y, x); Term_addch(a[i], c[i]); } Term_fresh(); }
/* * 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); }
/* 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 cmd_info *commands = menu_priv(menu); int mode = OPT(rogue_like_commands) ? KEYMAP_MODE_ROGUE : KEYMAP_MODE_ORIG; struct keypress kp = { EVT_KBRD, commands[oid].key[mode] }; char buf[16]; /* Write the description */ Term_putstr(col, row, -1, attr, commands[oid].desc); /* Include keypress */ Term_addch(attr, ' '); Term_addch(attr, '('); /* Get readable version */ keypress_to_readable(buf, sizeof buf, kp); Term_addstr(-1, attr, buf); Term_addch(attr, ')'); }
/* * Load the attr/char at each point along "path" which is on screen from * "a" and "c". This was saved in draw_path(). */ static void load_path(u16b path_n, u16b *path_g, char *c, byte *a) { int i; for (i = 0; i < path_n; i++) { if (!panel_contains(GRID_Y(path_g[i]), GRID_X(path_g[i]))) continue; move_cursor_relative(GRID_Y(path_g[i]), GRID_X(path_g[i])); (void)Term_addch(a[i], c[i]); } (void)Term_fresh(); }
/** * Hook function - dump a char_attr line to the screen */ void dump_line_screen(char_attr *this_line) { int x = 0; char_attr xa = this_line[0]; /* Erase the row */ Term_erase(0, dump_row, 255); /* Dump the line */ while (xa.pchar != '\0') { /* Add the char/attr */ Term_addch(xa.pattr, xa.pchar); /* Advance */ xa = this_line[++x]; } /* Next row */ dump_row++; }
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); }
/** * Draw a visible path over the squares between (x1,y1) and (x2,y2). * * The path consists of "*", which are white except where there is a * monster, object or feature in the grid. * * This routine has (at least) three weaknesses: * - remembered objects/walls which are no longer present are not shown, * - squares which (e.g.) the player has walked through in the dark are * treated as unknown space. * - walls which appear strange due to hallucination aren't treated correctly. * * The first two result from information being lost from the dungeon arrays, * which requires changes elsewhere */ static int draw_path(u16b path_n, u16b *path_g, wchar_t *c, int *a, int y1, int x1) { int i; bool on_screen; /* No path, so do nothing. */ if (path_n < 1) return 0; /* The starting square is never drawn, but notice if it is being * displayed. In theory, it could be the last such square. */ on_screen = panel_contains(y1, x1); /* Draw the path. */ for (i = 0; i < path_n; i++) { byte colour; /* Find the co-ordinates on the level. */ int y = GRID_Y(path_g[i]); int x = GRID_X(path_g[i]); /* * As path[] is a straight line and the screen is oblong, * there is only section of path[] on-screen. * If the square being drawn is visible, this is part of it. * If none of it has been drawn, continue until some of it * is found or the last square is reached. * If some of it has been drawn, finish now as there are no * more visible squares to draw. */ if (panel_contains(y,x)) on_screen = TRUE; else if (on_screen) break; else continue; /* Find the position on-screen */ move_cursor_relative(y,x); /* This square is being overwritten, so save the original. */ Term_what(Term->scr->cx, Term->scr->cy, a+i, c+i); /* Choose a colour. */ if (cave->m_idx[y][x] && cave_monster_at(cave, y, x)->ml) { /* Visible monsters are red. */ monster_type *m_ptr = cave_monster_at(cave, y, x); /* Mimics act as objects */ if (rf_has(m_ptr->race->flags, RF_UNAWARE)) colour = TERM_YELLOW; else colour = TERM_L_RED; } else if (cave->o_idx[y][x] && object_byid(cave->o_idx[y][x])->marked) /* Known objects are yellow. */ colour = TERM_YELLOW; else if (!cave_ispassable(cave, y,x) && ((cave->info[y][x] & (CAVE_MARK)) || player_can_see_bold(y,x))) /* Known walls are blue. */ colour = TERM_BLUE; else if (!(cave->info[y][x] & (CAVE_MARK)) && !player_can_see_bold(y,x)) /* Unknown squares are grey. */ colour = TERM_L_DARK; else /* Unoccupied squares are white. */ colour = TERM_WHITE; /* Draw the path segment */ (void)Term_addch(colour, L'*'); } return i; }
/** * Draw a visible path over the squares between (x1,y1) and (x2,y2). * * The path consists of "*", which are white except where there is a * monster, object or feature in the grid. * * This routine has (at least) three weaknesses: * - remembered objects/walls which are no longer present are not shown, * - squares which (e.g.) the player has walked through in the dark are * treated as unknown space. * - walls which appear strange due to hallucination aren't treated correctly. * * The first two result from information being lost from the dungeon arrays, * which requires changes elsewhere */ static int draw_path(u16b path_n, struct loc *path_g, wchar_t *c, int *a, int y1, int x1) { int i; bool on_screen; /* No path, so do nothing. */ if (path_n < 1) return 0; /* The starting square is never drawn, but notice if it is being * displayed. In theory, it could be the last such square. */ on_screen = panel_contains(y1, x1); /* Draw the path. */ for (i = 0; i < path_n; i++) { byte colour; /* Find the co-ordinates on the level. */ int y = path_g[i].y; int x = path_g[i].x; struct monster *mon = square_monster(cave, y, x); struct object *obj = square_object(cave, y, x); /* * As path[] is a straight line and the screen is oblong, * there is only section of path[] on-screen. * If the square being drawn is visible, this is part of it. * If none of it has been drawn, continue until some of it * is found or the last square is reached. * If some of it has been drawn, finish now as there are no * more visible squares to draw. */ if (panel_contains(y,x)) on_screen = TRUE; else if (on_screen) break; else continue; /* Find the position on-screen */ move_cursor_relative(y,x); /* This square is being overwritten, so save the original. */ Term_what(Term->scr->cx, Term->scr->cy, a+i, c+i); /* Choose a colour. */ if (mon && mflag_has(mon->mflag, MFLAG_VISIBLE)) { /* Mimics act as objects */ if (rf_has(mon->race->flags, RF_UNAWARE)) colour = COLOUR_YELLOW; else /* Visible monsters are red. */ colour = COLOUR_L_RED; } else if (obj && obj->marked) /* Known objects are yellow. */ colour = COLOUR_YELLOW; else if ((!square_isprojectable(cave, y,x) && square_ismark(cave, y, x)) || square_isseen(cave, y, x)) /* Known walls are blue. */ colour = COLOUR_BLUE; else if (!square_ismark(cave, y, x) && !square_isseen(cave, y, x)) /* Unknown squares are grey. */ colour = COLOUR_L_DARK; else /* Unoccupied squares are white. */ colour = COLOUR_WHITE; /* Draw the path segment */ (void)Term_addch(colour, L'*'); } return i; }
/* * 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 char *s; char buf[1024]; /* We use either ascii or system-specific encoding */ int encoding = (OPT(xchars_to_file)) ? SYSTEM_SPECIFIC : ASCII; /* Obtain the size */ (void)Term_get_size(&wid, &h); /* Obtain the cursor */ (void)Term_locate(&x, &y); /* Copy to a rewriteable string */ my_strcpy(buf, str, 1024); /* Translate it to 7-bit ASCII or system-specific format */ xstr_trans(buf, encoding); /* 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++) { char ch; /* Force wrap */ if (*s == '\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 = (my_isprint((unsigned char)*s) ? *s : ' '); /* Wrap words as needed */ if ((x >= wrap - 1) && (ch != ' ')) { int i, n = 0; byte av[256]; char 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] == ' ') 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; } }
static void display_resistance_panel(const struct player_flag_record *resists, size_t size, const region *bounds) { size_t i, j; int col = bounds->col; int row = bounds->row; Term_putstr(col, row++, RES_COLS, TERM_WHITE, " abcdefghijkl@"); for (i = 0; i < size-3; i++, row++) { byte name_attr = TERM_WHITE; Term_gotoxy(col+6, row); /* repeated extraction of flags is inefficient but more natural */ for (j = INVEN_WIELD; j <= INVEN_TOTAL; j++) { object_type *o_ptr = &p_ptr->inventory[j]; bitflag f[OF_SIZE]; byte attr = TERM_WHITE | (j % 2) * 8; /* alternating columns */ char sym = '.'; bool res, imm, vuln; /* Wipe flagset */ of_wipe(f); if (j < INVEN_TOTAL && o_ptr->kind) { object_flags_known(o_ptr, f); } else if (j == INVEN_TOTAL) { player_flags(f); /* If the race has innate infravision/digging, force the corresponding flag here. If we set it in player_flags(), then all callers of that function will think the infravision is caused by equipment. */ if (p_ptr->race->infra > 0) of_on(f, OF_INFRA); if (p_ptr->race->r_skills[SKILL_DIGGING] > 0) of_on(f, OF_TUNNEL); } res = of_has(f, resists[i].res_flag); imm = of_has(f, resists[i].im_flag); vuln = of_has(f, resists[i].vuln_flag); if (imm) name_attr = TERM_GREEN; else if (res && name_attr == TERM_WHITE) name_attr = TERM_L_BLUE; if (vuln) sym = '-'; else if (imm) sym = '*'; else if (res) sym = '+'; else if ((j < INVEN_TOTAL) && o_ptr->kind && !object_flag_is_known(o_ptr, resists[i].res_flag)) sym = '?'; Term_addch(attr, sym); } Term_putstr(col, row, 6, name_attr, format("%5s:", resists[i].name)); } Term_putstr(col, row++, RES_COLS, TERM_WHITE, " abcdefghijkl@"); /* Equippy */ display_player_equippy(row++, col+6); }
/* * 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; } }
/* * 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 "roff()" 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 roff(cptr str, ...) { int x, y; int w, h; cptr s; byte a = TERM_WHITE; byte da = a; va_list vp; char buf[1024]; /* Begin the Varargs Stuff */ va_start(vp, str); /* Format the args, save the length */ (void)vstrnfmt(buf, 1024, str, &vp); /* End the Varargs Stuff */ va_end(vp); /* Obtain the size */ (void)Term_get_size(&w, &h); /* Obtain the cursor */ (void)Term_locate(&x, &y); /* Process the string */ for (s = buf; *s; s++) { char ch; /* Force wrap */ if (*s == '\n') { /* Wrap */ x = 0; y++; /* Clear line, move cursor */ Term_erase(x, y, 255); continue; } /* Does this character match the escape code? */ if (*s == '$') { /* Scan the next character */ s++; /* Is it a colour specifier? */ if ((*s >= 'A') && (*s <= 'P')) { /* * Save the new colour * * Hack - this depends on ASCII symbols */ a = *s - 'A'; /* Hack -- fake monochrome */ if (!use_color) a = TERM_WHITE; continue; } /* Default colour change? */ else if (*s == 'Q') { /* Save current colour as 'default' */ da = a; continue; } /* Go back to default colour */ else if (*s == 'R') { a = da; continue; } /* * Hack XXX XXX - otherwise, ignore the dollar sign * * This makes "$$" turn into just "$". */ /* Stop if now reach null */ else if (*s == 0) break; } /* Clean up the char */ ch = (isprint(*s) ? *s : ' '); /* Wrap words as needed */ if ((x >= w - 1) && (ch != ' ')) { int i, n = 0; byte av[256]; char cv[256]; /* Wrap word */ if (x < w) { /* Scan existing text */ for (i = w - 2; i >= 0; i--) { /* Grab existing attr/char */ (void)Term_what(i, y, &av[i], &cv[i]); /* Break on space */ if (cv[i] == ' ') break; /* Track current word */ n = i; } } /* Special case */ if (n == 0) n = w; /* Clear line */ Term_erase(n, y, 255); /* Wrap */ x = 0; y++; /* Clear line, move cursor */ Term_erase(x, y, 255); /* Wrap the word (if any) */ for (i = n; i < w - 1; i++) { /* Dump */ Term_addch(av[i], cv[i]); /* Advance (no wrap) */ if (++x > w) x = w; } } /* Dump */ Term_addch(a, ch); /* Advance */ if (++x > w) x = w; } }
static void display_resistance_panel(const struct player_flag_record *resists, size_t size, const region *bounds) { size_t i; int j; int col = bounds->col; int row = bounds->row; Term_putstr(col, row++, RES_COLS, TERM_WHITE, " @abcdefghijklmnopqrstuvwxyz{|}"); for (i = 0; i < size-3; i++, row++) { byte name_attr = TERM_WHITE; Term_gotoxy(col+6, row); /* repeated extraction of flags is inefficient but more natural */ for (j = INVEN_WIELD - 1; j < INVEN_TOTAL; j++) { if (((j >= INVEN_WIELD) && (j < INVEN_WIELD + rp_ptr->melee_slots)) || ((j >= INVEN_BOW) && (j < INVEN_BOW + rp_ptr->range_slots)) || ((j >= INVEN_FINGER) && (j < INVEN_FINGER + rp_ptr->ring_slots)) || ((j >= INVEN_NECK) && (j < INVEN_NECK + rp_ptr->amulet_slots)) || ((j >= INVEN_LIGHT) && (j < INVEN_LIGHT + rp_ptr->light_slots)) || ((j >= INVEN_BODY) && (j < INVEN_BODY + rp_ptr->body_slots)) || ((j >= INVEN_OUTER) && (j < INVEN_OUTER + rp_ptr->cloak_slots)) || ((j >= INVEN_ARM) && (j < INVEN_ARM + rp_ptr->shield_slots)) || ((j >= INVEN_HEAD) && (j < INVEN_HEAD + rp_ptr->helm_slots)) || ((j >= INVEN_HANDS) && (j < INVEN_HANDS + rp_ptr->glove_slots)) || ((j >= INVEN_FEET) && (j < INVEN_FEET + rp_ptr->boot_slots)) || (j == INVEN_WIELD - 1)) { object_type *o_ptr = &p_ptr->inventory[j]; bitflag f[OF_SIZE]; byte attr = TERM_WHITE | (j % 2) * 8; /* alternating columns */ char sym = '.'; bool res, imm, vuln; /* Wipe flagset */ of_wipe(f); if (j < INVEN_WIELD) { player_flags(f); /* If the race has innate infravision/digging, force the corresponding flag here. If we set it in player_flags(), then all callers of that function will think the infravision is caused by equipment. */ if (rp_ptr->infra > 0) of_on(f, OF_INFRA); if (rp_ptr->r_skills[SKILL_DIGGING] > 0) of_on(f, OF_TUNNEL); } else if (j < INVEN_TOTAL && o_ptr->k_idx) { object_flags_known(o_ptr, f); } res = of_has(f, resists[i].res_flag); imm = of_has(f, resists[i].im_flag); vuln = of_has(f, resists[i].vuln_flag); if (imm) name_attr = TERM_GREEN; else if (res && name_attr == TERM_WHITE) name_attr = TERM_L_BLUE; if (vuln) sym = '-'; else if (imm) sym = '*'; else if (res) sym = '+'; else if ((j < INVEN_TOTAL) && o_ptr->k_idx && !object_flag_is_known(o_ptr, resists[i].res_flag)) sym = '?'; Term_addch(attr, sym); } } Term_putstr(col, row, 6, name_attr, format("%5s:", resists[i].name)); } Term_putstr(col, row++, RES_COLS, TERM_WHITE, " @abcdefghijklmnopqrstuvwxyz{|}"); /* Equippy */ display_player_equippy(row++, col+7); }