Пример #1
0
static void dynamic_display(menu_type *m, int oid, bool cursor,
		int row, int col, int width)
{
	struct menu_entry *entry;
	byte color = curs_attrs[CURS_KNOWN][0 != cursor];

	for (entry = menu_priv(m); oid; oid--) {
		entry = entry->next;
		assert(entry);
	}

	/*if ((entry->text[0] == '$')
		&& (entry->text[1] >= 'A') && (entry->text[1] < 'P'))
	{*/
		/* if the entry starts with a custom color, use it */
		/*Term_putstr(col, row, width, entry->text[1]-'A', entry->text+2);*/
	if (entry->text[0] == '$') {
		if (entry->text[1] != '$') {
			color = curs_attrs[CURS_UNKNOWN][0 != cursor];
		}
		Term_putstr(col, row, width, color, entry->text+1);
	} else {
		Term_putstr(col, row, width, color, entry->text);
	}
}
Пример #2
0
void display_panel(const data_panel *panel, int count, bool left_adj, const region *bounds)
{
	int i;
	char buffer[50];
	int col = bounds->col;
	int row = bounds->row;
	int w = bounds->width;
	int offset = 0;
	if (left_adj)
	{
		for (i = 0; i < count; i++)
		{
			int len = panel[i].label ? strlen(panel[i].label) : 0;
			if (offset < len) offset = len;
		}
		offset += 2;
	}

	for (i = 0; i < count; i++, row++)
	{
		int len;
		if (!panel[i].label) continue;
		Term_putstr(col, row, strlen(panel[i].label), TERM_WHITE, panel[i].label);

		strnfmt(buffer, sizeof(buffer), panel[i].fmt, panel[i].value[0], panel[i].value[1]);

		len = strlen(buffer);
		len = len < w - offset ? len : w - offset - 1;
		if (left_adj)
			Term_putstr(col+offset, row, len, panel[i].color, buffer);
		else
			Term_putstr(col+w-len, row, len, panel[i].color, buffer);
	}
}
Пример #3
0
/*
 * Get the Sex.
 */
static bool get_sex(void)
{
	char query2;
	int loopagain = TRUE;
	
	// Set the default sex info to female
	if (p_ptr->psex == SEX_UNDEFINED)
	{
		p_ptr->psex = SEX_FEMALE;
		sp_ptr = &sex_info[SEX_FEMALE];
	}
	
	while (loopagain == TRUE)
	{
		/* Display the player */
		display_player(0);

		// Highlight the relevant feature
		c_put_str(TERM_YELLOW, sp_ptr->title, 3, 8);
		
		/* Prompt */
		Term_putstr(QUESTION_COL, INSTRUCT_ROW + 1, -1, TERM_SLATE,
					"Enter accept sex");
		Term_putstr(QUESTION_COL, INSTRUCT_ROW + 2, -1, TERM_SLATE,
					"Space change sex");
		
		/* Hack - highlight the key names */
		Term_putstr(QUESTION_COL, INSTRUCT_ROW + 1, - 1, TERM_L_WHITE, "Enter");
		Term_putstr(QUESTION_COL, INSTRUCT_ROW + 2, - 1, TERM_L_WHITE, "Space");
		
		/* Move the cursor */
		Term_gotoxy(0, INSTRUCT_ROW + 1);
				
		/* Query */
		query2 = inkey();
		
		if ((query2 == '\r') || (query2 == '\n'))
		{
			/* got a sex*/
			loopagain = FALSE;
			
			p_ptr->redraw |= (PR_MISC);
		}
		
		else if (query2 == ESCAPE)  return (FALSE);
		
		else if (((query2 == 'Q') || (query2 == 'q')) && (turn == 0)) quit (NULL);

		else
		{
			if (p_ptr->psex == SEX_FEMALE)	p_ptr->psex = SEX_MALE;
			else							p_ptr->psex = SEX_FEMALE;
			
			sp_ptr = &sex_info[p_ptr->psex];
		}
	}
	
	return (TRUE);
}
Пример #4
0
/**
 * 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 = KEYPRESS_NULL;

    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, COLOUR_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, COLOUR_WHITE, buf);

        /* Not the first time round anymore */
        firsttime = false;
    }

    /* Done */
    return (ch.code != ESCAPE);
}
Пример #5
0
/*
 * Handle signal -- abort, kill, etc
 */
static void handle_signal_abort(int sig)
{
	/* Disable handler */
	(void)(*signal_aux)(sig, SIG_IGN);


	/* Nothing to save, just quit */
	if (!character_generated || character_saved) quit(NULL);


	/* Clear the bottom line */
	Term_erase(0, 23, 255);

	/* Give a warning */
	Term_putstr(0, 23, -1, TERM_RED,
	            "A gruesome software bug LEAPS out at you!");

	/* Message */
	Term_putstr(45, 23, -1, TERM_RED, "Panic save...");

	/* Flush output */
	Term_fresh();

	/* Panic Save
	p_ptr->panic_save = 1; */

	/* Panic save */
	my_strcpy(p_ptr->died_from, "(panic save)", sizeof(p_ptr->died_from));

	/* Forbid suspend */
	signals_ignore_tstp();

	/* Attempt to save */
	if (old_save())
	{
		Term_putstr(45, 23, -1, TERM_RED, "Panic save succeeded!");
	}

	/* Save failed */
	else
	{
		Term_putstr(45, 23, -1, TERM_RED, "Panic save failed!");
	}

	/* Flush output */
	Term_fresh();

	/* Quit */
	quit("software bug");
}
Пример #6
0
/**
 * Redraw the "monster mana bar"
 *
 * The "monster mana bar" provides visual feedback on the "mana"
 * of the monster currently being "tracked".  It follows the lead of the 
 * monster health bar for who to track.
 */
static void prt_mana(int row, int col)
{
    byte attr = TERM_SLATE;

    /* Not tracking */
    if (!p_ptr->health_who) {
	/* Erase the health bar */
	Term_erase(col, row, 12);
    }

    /* Tracking an unseen, hallucinatory, or dead monster */
    else if ((!m_list[p_ptr->health_who].ml) ||	/* Unseen */
	     (p_ptr->timed[TMD_IMAGE]) ||	/* Hallucination */
	     (m_list[p_ptr->health_who].hp < 0)) {	/* Dead (?) */
	/* The monster mana is "unknown" */
	Term_putstr(col, row, 12, attr, "[----------]");
    }

    /* Tracking a visible monster */
    else {
	int pct, len;

	monster_type *m_ptr = &m_list[p_ptr->health_who];
	monster_race *r_ptr = &r_info[m_ptr->r_idx];

	/* no mana, stop here */
	if (!r_ptr->mana) {
	    /* Erase the mana bar */
	    Term_erase(col, row, 12);

	    return;
	}

	attr = monster_mana_attr();

	/* Extract the "percent" of mana */
	pct = 100L * m_ptr->mana / r_ptr->mana;

	/* Convert percent into "mana" */
	len = (pct < 10) ? 1 : (pct < 90) ? (pct / 10 + 1) : 10;

	/* Default to "unknown" */
	Term_putstr(col, row, 12, TERM_WHITE, "[----------]");

	/* Dump the current "mana" (use '*' symbols) */
	Term_putstr(col + 1, row, len, attr, "**********");
    }
}
Пример #7
0
/*! 
 * @brief スナイパーの技能リストを表示する
 * @return なし
 */
void display_snipe_list(void)
{
	int             i;
	int             y = 1;
	int             x = 1;
	int             plev = p_ptr->lev;
	snipe_power     spell;
	char            psi_desc[80];

	/* Display a list of spells */
	prt("", y, x);
#ifdef JP
	put_str("名前", y, x + 5);
	put_str("Lv   MP", y, x + 35);
#else
	put_str("Name", y, x + 5);
	put_str("Lv Mana", y, x + 35);
#endif

	/* Dump the spells */
	for (i = 0; i < MAX_SNIPE_POWERS; i++)
	{
		/* Access the available spell */
		spell = snipe_powers[i];
		if (spell.min_lev > plev) continue;
		if (spell.mana_cost > (int)p_ptr->concent) continue;

		/* Dump the spell */
		sprintf(psi_desc, "  %c) %-30s%2d %4d",
			I2A(i), spell.name, spell.min_lev, spell.mana_cost);

		Term_putstr(x, y + i + 1, -1, TERM_WHITE, psi_desc);
	}
	return;
}
Пример #8
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 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, ')');
}
Пример #9
0
/* ------------------------------------------------------------------------
 * MN_STRINGS HELPER FUNCTIONS
 *
 * MN_STRINGS is the type of menu iterator that displays a simple list of 
 * strings - no action is associated, as selection will just return the index.
 * ------------------------------------------------------------------------ */
static void display_string(menu_type *m, int oid, bool cursor,
		int row, int col, int width)
{
	char **items = menu_priv(m);
	byte color = curs_attrs[CURS_KNOWN][0 != cursor];
	Term_putstr(col, row, width, color, items[oid]);
}
Пример #10
0
/* Modal display of menu */
static void display_menu_row(menu_type *menu, int pos, int top,
                             bool cursor, int row, int col, int width)
{
	int flags = menu->flags;
	char sel = 0;
	int oid = pos;

	if (menu->filter_list)
		oid = menu->filter_list[oid];

	if (menu->row_funcs->valid_row && menu->row_funcs->valid_row(menu, oid) == 2)
		return;

	if (!(flags & MN_NO_TAGS))
	{
		if (flags & MN_REL_TAGS)
			sel = menu->skin->get_tag(menu, pos);
		else if (menu->selections && !(flags & MN_PVT_TAGS))
			sel = menu->selections[pos];
		else if (menu->row_funcs->get_tag)
			sel = menu->row_funcs->get_tag(menu, oid);
	}

	if (sel)
	{
		/* TODO: CHECK FOR VALID */
		byte color = curs_attrs[CURS_KNOWN][0 != (cursor)];
		Term_putstr(col, row, 3, color, format("%c) ", sel));
		col += 3;
		width -= 3;
	}

	menu->row_funcs->display_row(menu, oid, cursor, row, col, width);
}
Пример #11
0
/**
* Display an entry on a command menu
*/
static void show_display(menu_type * menu, int oid, bool cursor, int row,
			 int col, int width)
{
    byte attr = (cursor ? TERM_L_BLUE : TERM_WHITE);

    /* Write the description */
    Term_putstr(col + 4, row, -1, attr, comm_descr[oid]);
}
Пример #12
0
/**
 * Redraw the "monster health bar"
 *
 * The "monster health bar" provides visual feedback on the "health"
 * of the monster currently being "tracked".  There are several ways
 * to "track" a monster, including targetting it, attacking it, and
 * affecting it (and nobody else) with a ranged attack.  When nothing
 * is being tracked, we clear the health bar.  If the monster being
 * tracked is not currently visible, a special health bar is shown.
 */
static void prt_health(int row, int col)
{
    byte attr = monster_health_attr();

    /* Not tracking */
    if (!p_ptr->health_who) {
	/* Erase the health bar */
	Term_erase(col, row, 12);
    }

    /* Tracking an unseen, hallucinatory, or dead monster */
    else if ((!m_list[p_ptr->health_who].ml) ||	/* Unseen */
	     (p_ptr->timed[TMD_IMAGE]) ||	/* Hallucination */
	     (m_list[p_ptr->health_who].hp < 0)) {	/* Dead (?) */
	/* The monster health is "unknown" */
	Term_putstr(col, row, 12, attr, "[----------]");
    }

    /* Tracking a visible monster */
    else {
	int pct, len;

	monster_type *m_ptr = &m_list[p_ptr->health_who];

	/* Extract the "percent" of health */
	pct = 100L * m_ptr->hp / m_ptr->maxhp;

	/* Convert percent into "health" */
	len = (pct < 10) ? 1 : (pct < 90) ? (pct / 10 + 1) : 10;

	/* Default to "unknown" */
	Term_putstr(col, row, 12, TERM_WHITE, "[----------]");

	/* Dump the current "health" (handle monster stunning, confusion) */
	if (m_ptr->confused)
	    Term_putstr(col + 1, row, len, attr, "cccccccccc");
	else if (m_ptr->stunned)
	    Term_putstr(col + 1, row, len, attr, "ssssssssss");
	else
	    Term_putstr(col + 1, row, len, attr, "**********");
    }
}
Пример #13
0
/* Display an event, with possible preference overrides */
static void display_action_aux(menu_action *act, byte color, int row, int col, int wid)
{
	/* TODO: add preference support */
	/* TODO: wizard mode should show more data */
	Term_erase(col, row, wid);

	/*if (act->name)
		Term_putstr(col, row, wid, color, act->name);*/
	if (act->text)
		Term_putstr(col, row, wid, color, act->text);
}
Пример #14
0
static void display_panel(const struct panel *p, bool left_adj,
		const region *bounds)
{
	size_t i;
	int col = bounds->col;
	int row = bounds->row;
	int w = bounds->width;
	int offset = 0;

	region_erase(bounds);

	if (left_adj) {
		for (i = 0; i < p->len; i++) {
			struct panel_line *pl = &p->lines[i];

			int len = pl->label ? strlen(pl->label) : 0;
			if (offset < len) offset = len;
		}
		offset += 2;
	}

	for (i = 0; i < p->len; i++, row++) {
		int len;
		struct panel_line *pl = &p->lines[i];

		if (!pl->label)
			continue;

		Term_putstr(col, row, strlen(pl->label), COLOUR_WHITE, pl->label);

		len = strlen(pl->value);
		len = len < w - offset ? len : w - offset - 1;

		if (left_adj)
			Term_putstr(col+offset, row, len, pl->attr, pl->value);
		else
			Term_putstr(col+w-len, row, len, pl->attr, pl->value);
	}
}
Пример #15
0
/*
 * Hack -- flush
 */
static void msg_flush(int x)
{
	byte a = TERM_L_BLUE;

	/* Pause for response */
	Term_putstr(x, 0, -1, a, "-more-");

	if (!OPT(auto_more))
		anykey();

	/* Clear the line */
	Term_erase(0, 0, 255);
}
Пример #16
0
/*
 * Display additional information about each house during the selection.
 */
static void house_aux_hook(birth_menu c_str)
{
	int house_idx, i, adj;
	char s[128];
	byte attr;

	/* Extract the proper house index from the string. */
	for (house_idx = 0; house_idx < z_info->c_max; house_idx++)
	{
		if (!strcmp(c_str.name, c_name + c_info[house_idx].name)) break;
	}

	if (house_idx == z_info->c_max) return;

	/* Display relevant details. */
	for (i = 0; i < A_MAX; i++)
	{
		/*dump potential total stats*/
		strnfmt(s, sizeof(s), "%s", stat_names[i]);
		Term_putstr(TOTAL_AUX_COL, TABLE_ROW + i, -1, TERM_WHITE, s);

		adj = c_info[house_idx].h_adj[i] + rp_ptr->r_adj[i];
		strnfmt(s, sizeof(s), "%+d", adj);
		
		if (adj < 0)		attr = TERM_RED;
		else if (adj == 0)	attr = TERM_L_DARK;
		else if (adj == 1)	attr = TERM_GREEN;
		else if (adj == 2)	attr = TERM_L_GREEN;
		else				attr = TERM_L_BLUE;
		
		Term_putstr(TOTAL_AUX_COL + 4, TABLE_ROW + i, -1, attr, s);
	}

	/* Display the race flags */
	
	Term_putstr(TOTAL_AUX_COL, TABLE_ROW + A_MAX + 1, -1, TERM_WHITE, "                    ");
	Term_putstr(TOTAL_AUX_COL, TABLE_ROW + A_MAX + 2, -1, TERM_WHITE, "                    ");
	Term_putstr(TOTAL_AUX_COL, TABLE_ROW + A_MAX + 3, -1, TERM_WHITE, "                    ");
	Term_putstr(TOTAL_AUX_COL, TABLE_ROW + A_MAX + 4, -1, TERM_WHITE, "                    ");
	Term_putstr(TOTAL_AUX_COL, TABLE_ROW + A_MAX + 5, -1, TERM_WHITE, "                    ");
	
	print_rh_flags(p_ptr->prace,house_idx,TOTAL_AUX_COL,TABLE_ROW + A_MAX + 1);
	
}
Пример #17
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, ')');
}
Пример #18
0
void display_snipe_list(void)
{
    int             i;
    int             y = 1;
    int             x = 1;
    int             plev = p_ptr->lev;
    snipe_power     spell;
    char            desc[80];

    prt("", y, x);
    put_str("Name", y, x + 5);
    put_str("Lv Mana", y, x + 35);

    for (i = 0; i < MAX_SNIPE_POWERS; i++)
    {
        spell = snipe_powers[i];
        if (spell.min_lev > plev) continue;
        if (spell.mana_cost > (int)p_ptr->concent) continue;
        sprintf(desc, "  %c) %-30s%2d %4d",
            I2A(i), spell.name, spell.min_lev, spell.mana_cost);
        Term_putstr(x, y + i + 1, -1, TERM_WHITE, desc);
    }
    return;
}
Пример #19
0
/*
 * Display additional information about each race during the selection.
 */
static void race_aux_hook(birth_menu r_str)
{
	int race, i, adj;
	char s[50];
	byte attr;

	/* Extract the proper race index from the string. */
	for (race = 0; race < z_info->p_max; race++)
	{
		if (!strcmp(r_str.name, p_name + p_info[race].name)) break;
	}

	if (race == z_info->p_max) return;

	/* Display the stats */
	for (i = 0; i < A_MAX; i++)
	{
		/*dump the stats*/
		strnfmt(s, sizeof(s), "%s", stat_names[i]);
		Term_putstr(RACE_AUX_COL, TABLE_ROW + i, -1, TERM_WHITE, s);
		
		adj = p_info[race].r_adj[i];
		strnfmt(s, sizeof(s), "%+d", adj);
		
		if (adj < 0)		attr = TERM_RED;
		else if (adj == 0)	attr = TERM_L_DARK;
		else if (adj == 1)	attr = TERM_GREEN;
		else if (adj == 2)	attr = TERM_L_GREEN;
		else				attr = TERM_L_BLUE;
		
		Term_putstr(RACE_AUX_COL + 4, TABLE_ROW + i, -1, attr, s);
	}

	/* Display the race flags */
	
	Term_putstr(RACE_AUX_COL, TABLE_ROW + A_MAX + 1, -1, TERM_WHITE, "                    ");
	Term_putstr(RACE_AUX_COL, TABLE_ROW + A_MAX + 2, -1, TERM_WHITE, "                    ");
	Term_putstr(RACE_AUX_COL, TABLE_ROW + A_MAX + 3, -1, TERM_WHITE, "                    ");
	Term_putstr(RACE_AUX_COL, TABLE_ROW + A_MAX + 4, -1, TERM_WHITE, "                    ");
	
	print_rh_flags(race, 0, RACE_AUX_COL, TABLE_ROW + A_MAX + 1);
	
}
Пример #20
0
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);
}
Пример #21
0
/**
 * Hack -- change name
 */
void do_cmd_change_name(void)
{
	ui_event ke;
	int mode = 0;

	const char *p;

	bool more = true;

	/* Prompt */
	p = "['c' to change name, 'f' to file, 'h' to change mode, or ESC]";

	/* Save screen */
	screen_save();

	/* Forever */
	while (more) {
		/* Display the player */
		display_player(mode);

		/* Prompt */
		Term_putstr(2, 23, -1, COLOUR_WHITE, p);

		/* Query */
		ke = inkey_ex();

		if ((ke.type == EVT_KBRD)||(ke.type == EVT_BUTTON)) {
			switch (ke.key.code) {
				case ESCAPE: more = false; break;
				case 'c': {
					if(arg_force_name)
						msg("You are not allowed to change your name!");
					else {
					char namebuf[32] = "";

					/* Set player name */
					if (get_character_name(namebuf, sizeof namebuf))
						my_strcpy(player->full_name, namebuf,
								  sizeof(player->full_name));
					}

					break;
				}

				case 'f': {
					char buf[1024];
					char fname[80];

					/* Get the filesystem-safe name and append .txt */
					player_safe_name(fname, sizeof(fname), player->full_name, false);
					my_strcat(fname, ".txt", sizeof(fname));

					if (get_file(fname, buf, sizeof buf)) {
						if (dump_save(buf))
							msg("Character dump successful.");
						else
							msg("Character dump failed!");
					}
					break;
				}
				
				case 'h':
				case ARROW_LEFT:
				case ' ':
					mode = (mode + 1) % INFO_SCREENS;
					break;

				case 'l':
				case ARROW_RIGHT:
					mode = (mode - 1) % INFO_SCREENS;
					break;
			}
		} else if (ke.type == EVT_MOUSE) {
			if (ke.mouse.button == 1) {
				/* Flip through the screens */			
				mode = (mode + 1) % INFO_SCREENS;
			} else if (ke.mouse.button == 2) {
				/* exit the screen */
				more = false;
			} else {
				/* Flip backwards through the screens */			
				mode = (mode - 1) % INFO_SCREENS;
			}
		}

		/* Flush messages */
		event_signal(EVENT_MESSAGE_FLUSH);
	}

	/* Load screen */
	screen_load();
}
Пример #22
0
/*
 * Handle signals -- simple (interrupt and quit)
 *
 * This function was causing a *huge* number of problems, so it has
 * been simplified greatly.  We keep a global variable which counts
 * the number of times the user attempts to kill the process, and
 * we commit suicide if the user does this a certain number of times.
 *
 * We attempt to give "feedback" to the user as he approaches the
 * suicide thresh-hold, but without penalizing accidental keypresses.
 *
 * To prevent messy accidents, we should reset this global variable
 * whenever the user enters a keypress, or something like that.
 */
static void handle_signal_simple(int sig)
{
	/* Protect errno from library calls in signal handler */
	int save_errno = errno;

	/* Disable handler */
	(void)(*signal_aux)(sig, SIG_IGN);


	/* Nothing to save, just quit */
	if (!character_generated || character_saved) quit(NULL);


	/* Count the signals */
	signal_count++;


	/* Terminate dead characters */
	if (p_ptr->is_dead)
	{
		/* Mark the savefile */
		my_strcpy(p_ptr->died_from, "Abortion", sizeof(p_ptr->died_from));

		close_game();

		/* Quit */
		quit("interrupt");
	}

	/* Allow suicide (after 5) */
	else if (signal_count >= 5)
	{
		/* Cause of "death" */
		my_strcpy(p_ptr->died_from, "Interrupting", sizeof(p_ptr->died_from));

		/* Commit suicide */
		p_ptr->is_dead = TRUE;

		/* Stop playing */
		p_ptr->playing = FALSE;

		/* Leaving */
		p_ptr->leaving = TRUE;

		/* Close stuff */
		close_game();

		/* Quit */
		quit("interrupt");
	}

	/* Give warning (after 4) */
	else if (signal_count >= 4)
	{
		/* Make a noise */
		Term_xtra(TERM_XTRA_NOISE, 0);

		/* Clear the top line */
		Term_erase(0, 0, 255);

		/* Display the cause */
		Term_putstr(0, 0, -1, TERM_WHITE, "Contemplating suicide!");

		/* Flush */
		Term_fresh();
	}

	/* Give warning (after 2) */
	else if (signal_count >= 2)
	{
		/* Make a noise */
		Term_xtra(TERM_XTRA_NOISE, 0);
	}

	/* Restore handler */
	(void)(*signal_aux)(sig, handle_signal_simple);

	/* Restore errno */
	errno = save_errno;
}
Пример #23
0
/**
 * Modify the "window" options
 */
static void do_cmd_options_win(const char *name, int row)
{
	int i, j, d;
	int y = 0;
	int x = 0;
	ui_event ke;
	u32b new_flags[ANGBAND_TERM_MAX];

	/* Set new flags to the old values */
	for (j = 0; j < ANGBAND_TERM_MAX; j++)
		new_flags[j] = window_flag[j];

	/* Clear screen */
	screen_save();
	clear_from(0);

	/* Interact */
	while (1) {
		/* Prompt */
		prt("Window flags (<dir> to move, 't'/Enter to toggle, or ESC)", 0, 0);

		/* Display the windows */
		for (j = 0; j < ANGBAND_TERM_MAX; j++) {
			byte a = COLOUR_WHITE;

			const char *s = angband_term_name[j];

			/* Use color */
			if (j == x) a = COLOUR_L_BLUE;

			/* Window name, staggered, centered */
			Term_putstr(35 + j * 5 - strlen(s) / 2, 2 + j % 2, -1, a, s);
		}

		/* Display the options */
		for (i = 0; i < PW_MAX_FLAGS; i++) {
			byte a = COLOUR_WHITE;

			const char *str = window_flag_desc[i];

			/* Use color */
			if (i == y) a = COLOUR_L_BLUE;

			/* Unused option */
			if (!str) str = "(Unused option)";

			/* Flag name */
			Term_putstr(0, i + 5, -1, a, str);

			/* Display the windows */
			for (j = 0; j < ANGBAND_TERM_MAX; j++) {
				char c = '.';

				a = COLOUR_WHITE;

				/* Use color */
				if ((i == y) && (j == x)) a = COLOUR_L_BLUE;

				/* Active flag */
				if (new_flags[j] & (1L << i)) c = 'X';

				/* Flag value */
				Term_putch(35 + j * 5, i + 5, a, c);
			}
		}

		/* Place Cursor */
		Term_gotoxy(35 + x * 5, y + 5);

		/* Get key */
		ke = inkey_ex();

		/* Mouse or keyboard interaction */
		if (ke.type == EVT_MOUSE) {
			int choicey = ke.mouse.y - 5;
			int choicex = (ke.mouse.x - 35)/5;

			if (ke.mouse.button == 2)
				break;

			if ((choicey >= 0) && (choicey < PW_MAX_FLAGS)
				&& (choicex > 0) && (choicex < ANGBAND_TERM_MAX)
				&& !(ke.mouse.x % 5)) {
				if ((choicey == y) && (choicex == x)) {
					/* Toggle flag (off) */
					if (new_flags[x] & (1L << y))
						new_flags[x] &= ~(1L << y);
					/* Toggle flag (on) */
					else
						new_flags[x] |= (1L << y);
				} else {
					y = choicey;
					x = (ke.mouse.x - 35)/5;
				}
			}
		} else if (ke.type == EVT_KBRD) {
			if (ke.key.code == ESCAPE || ke.key.code == 'q')
				break;

			/* Toggle */
			else if (ke.key.code == '5' || ke.key.code == 't' ||
					ke.key.code == KC_ENTER) {
				/* Hack -- ignore the main window */
				if (x == 0)
					bell("Cannot set main window flags!");

				/* Toggle flag (off) */
				else if (new_flags[x] & (1L << y))
					new_flags[x] &= ~(1L << y);

				/* Toggle flag (on) */
				else
					new_flags[x] |= (1L << y);

				/* Continue */
				continue;
			}

			/* Extract direction */
			d = target_dir(ke.key);

			/* Move */
			if (d != 0) {
				x = (x + ddx[d] + 8) % ANGBAND_TERM_MAX;
				y = (y + ddy[d] + 16) % PW_MAX_FLAGS;
			}
		}
	}

	/* Notice changes */
	subwindows_set_flags(new_flags, ANGBAND_TERM_MAX);

	screen_load();
}
Пример #24
0
/*
 * Display a string on the screen using an attribute.
 *
 * At the given location, using the given attribute, if allowed,
 * add the given string.  Do not clear the line.
 */
void c_put_str(byte attr, const char *str, int row, int col)
{
	/* Position cursor, Dump the attr/text */
	Term_putstr(col, row, -1, attr, str);
}
Пример #25
0
static void colors_modify(const char *title, int row)
{
	int i;

	static byte a = 0;

	/* Prompt */
	prt("Command: Modify colors", 8, 0);

	/* Hack -- query until done */
	while (1) {
		const char *name;
		char index;

		struct keypress cx;

		/* Clear */
		clear_from(10);

		/* Exhibit the normal colors */
		for (i = 0; i < BASIC_COLORS; i++) {
			/* Exhibit this color */
			Term_putstr(i*3, 20, -1, a, "##");

			/* Exhibit character letter */
			Term_putstr(i*3, 21, -1, (byte)i,
						format(" %c", color_table[i].index_char));

			/* Exhibit all colors */
			Term_putstr(i*3, 22, -1, (byte)i, format("%2d", i));
		}

		/* Describe the color */
		name = ((a < BASIC_COLORS) ? color_table[a].name : "undefined");
		index = ((a < BASIC_COLORS) ? color_table[a].index_char : '?');

		/* Describe the color */
		Term_putstr(5, 10, -1, COLOUR_WHITE,
					format("Color = %d, Name = %s, Index = %c",
						   a, name, index));

		/* Label the Current values */
		Term_putstr(5, 12, -1, COLOUR_WHITE,
				format("K = 0x%02x / R,G,B = 0x%02x,0x%02x,0x%02x",
				   angband_color_table[a][0],
				   angband_color_table[a][1],
				   angband_color_table[a][2],
				   angband_color_table[a][3]));

		/* Prompt */
		Term_putstr(0, 14, -1, COLOUR_WHITE,
				"Command (n/N/k/K/r/R/g/G/b/B): ");

		/* Get a command */
		cx = inkey();

		/* All done */
		if (cx.code == ESCAPE) break;

		/* Analyze */
		if (cx.code == 'n')
			a = (byte)(a + 1);
		if (cx.code == 'N')
			a = (byte)(a - 1);
		if (cx.code == 'k')
			angband_color_table[a][0] = (byte)(angband_color_table[a][0] + 1);
		if (cx.code == 'K')
			angband_color_table[a][0] = (byte)(angband_color_table[a][0] - 1);
		if (cx.code == 'r')
			angband_color_table[a][1] = (byte)(angband_color_table[a][1] + 1);
		if (cx.code == 'R')
			angband_color_table[a][1] = (byte)(angband_color_table[a][1] - 1);
		if (cx.code == 'g')
			angband_color_table[a][2] = (byte)(angband_color_table[a][2] + 1);
		if (cx.code == 'G')
			angband_color_table[a][2] = (byte)(angband_color_table[a][2] - 1);
		if (cx.code == 'b')
			angband_color_table[a][3] = (byte)(angband_color_table[a][3] + 1);
		if (cx.code == 'B')
			angband_color_table[a][3] = (byte)(angband_color_table[a][3] - 1);

		/* Hack -- react to changes */
		Term_xtra(TERM_XTRA_REACT, 0);

		/* Hack -- redraw */
		Term_redraw();
	}
}
Пример #26
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;
}
Пример #27
0
/*
 * Output a message to the top line of the screen.
 *
 * Break long messages into multiple pieces (40-72 chars).
 *
 * Allow multiple short messages to "share" the top line.
 *
 * Prompt the user to make sure he has a chance to read them.
 *
 * These messages are memorized for later reference (see above).
 *
 * We could do a "Term_fresh()" to provide "flicker" if needed.
 *
 * The global "msg_flag" variable can be cleared to tell us to "erase" any
 * "pending" messages still on the screen, instead of using "msg_flush()".
 * This should only be done when the user is known to have read the message.
 *
 * We must be very careful about using the "msg("%s", )" functions without
 * explicitly calling the special "msg("%s", NULL)" function, since this may
 * result in the loss of information if the screen is cleared, or if anything
 * is displayed on the top line.
 *
 * Hack -- Note that "msg("%s", NULL)" will clear the top line even if no
 * messages are pending.
 */
static void msg_print_aux(u16b type, const char *msg)
{
	int n;
	char *t;
	char buf[1024];
	byte color;
	int w, h;

	if (!Term)
		return;

	/* Obtain the size */
	(void)Term_get_size(&w, &h);

	/* Hack -- Reset */
	if (!msg_flag) message_column = 0;

	/* Message Length */
	n = (msg ? strlen(msg) : 0);

	/* Hack -- flush when requested or needed */
	if (message_column && (!msg || ((message_column + n) > (w - 8))))
	{
		/* Flush */
		msg_flush(message_column);

		/* Forget it */
		msg_flag = FALSE;

		/* Reset */
		message_column = 0;
	}


	/* No message */
	if (!msg) return;

	/* Paranoia */
	if (n > 1000) return;


	/* Memorize the message (if legal) */
	if (character_generated && !(p_ptr->is_dead))
		message_add(msg, type);

	/* Window stuff */
	p_ptr->redraw |= (PR_MESSAGE);

	/* Copy it */
	my_strcpy(buf, msg, sizeof(buf));

	/* Analyze the buffer */
	t = buf;

	/* Get the color of the message */
	color = message_type_color(type);

	/* Split message */
	while (n > w - 1)
	{
		char oops;

		int check, split;

		/* Default split */
		split = w - 8;

		/* Find the rightmost split point */
		for (check = (w / 2); check < w - 8; check++)
			if (t[check] == ' ') split = check;

		/* Save the split character */
		oops = t[split];

		/* Split the message */
		t[split] = '\0';

		/* Display part of the message */
		Term_putstr(0, 0, split, color, t);

		/* Flush it */
		msg_flush(split + 1);

		/* Restore the split character */
		t[split] = oops;

		/* Insert a space */
		t[--split] = ' ';

		/* Prepare to recurse on the rest of "buf" */
		t += split; n -= split;
	}

	/* Display the tail of the message */
	Term_putstr(message_column, 0, n, color, t);

	/* Remember the message */
	msg_flag = TRUE;

	/* Remember the position */
	message_column += n + 1;

	/* Send refresh event */
	event_signal(EVENT_MESSAGE);
}
Пример #28
0
/*
 * 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();
}
Пример #29
0
/*
 * As above, but in "white"
 */
void put_str(const char *str, int row, int col)
{
	/* Spawn */
	Term_putstr(col, row, -1, TERM_WHITE, str);
}
Пример #30
0
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);
}