Exemple #1
0
/*
 * Get an "aiming direction" (1,2,3,4,6,7,8,9 or 5) from the user.
 *
 * Return TRUE if a direction was chosen, otherwise return FALSE.
 *
 * The direction "5" is special, and means "use current target".
 *
 * This function tracks and uses the "global direction", and uses
 * that as the "desired direction", if it is set.
 *
 * Note that "Force Target", if set, will pre-empt user interaction,
 * if there is a usable target already set.
 *
 * Currently this function applies confusion directly.
 */
bool get_aim_dir(int *dp)
{
	/* Global direction */
	int dir = 0;

	ui_event ke;

	const char *p;

	/* Initialize */
	(*dp) = 0;

	/* Hack -- auto-target if requested */
	if (OPT(use_old_target) && target_okay() && !dir)
		dir = 5;

	/* Ask until satisfied */
	while (!dir) {
		/* Choose a prompt */
		if (!target_okay())
			p = "Direction ('*' or <click> to target, \"'\" for closest, Escape to cancel)? ";
		else
			p = "Direction ('5' for target, '*' or <click> to re-target, Escape to cancel)? ";

		/* Get a command (or Cancel) */
		if (!get_com_ex(p, &ke))
			break;

		if (ke.type == EVT_MOUSE) {
			if (target_set_interactive
				(TARGET_KILL, KEY_GRID_X(ke), KEY_GRID_Y(ke)))
				dir = 5;
		} else if (ke.type == EVT_KBRD) {
			if (ke.key.code == '*') {
				/* Set new target, use target if legal */
				if (target_set_interactive(TARGET_KILL, -1, -1))
					dir = 5;
			} else if (ke.key.code == '\'') {
				/* Set to closest target */
				if (target_set_closest(TARGET_KILL))
					dir = 5;
			} else if (ke.key.code == 't' || ke.key.code == '5'
					   || ke.key.code == '0' || ke.key.code == '.') {
				if (target_okay())
					dir = 5;
			} else {
				/* Possible direction */
				int keypresses_handled = 0;

				while (ke.key.code != 0) {
					int this_dir;

					/* XXX Ideally show and move the cursor here to indicate
					 * the currently "Pending" direction. XXX */
					this_dir = target_dir(ke.key);

					if (this_dir)
						dir = dir_transitions[dir][this_dir];
					else
						break;

					if (lazymove_delay == 0 || ++keypresses_handled > 1)
						break;

					/* See if there's a second keypress within the defined
					 * period of time. */
					inkey_scan = lazymove_delay;
					ke = inkey_ex();
				}
			}
		}

		/* Error */
		if (!dir)
			bell("Illegal aim direction!");
	}

	/* No direction */
	if (!dir)
		return (FALSE);

	/* Save direction */
	(*dp) = dir;

	/* Check for confusion */
	if (p_ptr->timed[TMD_CONFUSED]) {
		/* Random direction */
		dir = ddd[randint0(8)];
	}

	/* Notice confusion */
	if ((*dp) != dir) {
		/* Warn the user */
		msg("You are confused.");
	}

	/* Save direction */
	(*dp) = dir;

	/* A "valid" direction was entered */
	return (TRUE);
}
Exemple #2
0
/*
 * Let the user select an item, save its "index"
 *
 * Return TRUE only if an acceptable item was chosen by the user.
 *
 * The selected item must satisfy the "item_tester_hook()" function,
 * if that hook is set, and the "item_tester_tval", if that value is set.
 *
 * All "item_tester" restrictions are cleared before this function returns.
 *
 * The user is allowed to choose acceptable items from the equipment,
 * inventory, or floor, respectively, if the proper flag was given,
 * and there are any acceptable items in that location.
 *
 * The equipment or inventory are displayed (even if no acceptable
 * items are in that location) if the proper flag was given.
 *
 * If there are no acceptable items available anywhere, and "str" is
 * not NULL, then it will be used as the text of a warning message
 * before the function returns.
 *
 * Note that the user must press "-" to specify the item on the floor,
 * and there is no way to "examine" the item on the floor, while the
 * use of "capital" letters will "examine" an inventory/equipment item,
 * and prompt for its use.
 *
 * If a legal item is selected from the inventory, we save it in "cp"
 * directly (0 to 35), and return TRUE.
 *
 * If a legal item is selected from the floor, we save it in "cp" as
 * a negative (-1 to -511), and return TRUE.
 *
 * If no item is available, we do nothing to "cp", and we display a
 * warning message, using "str" if available, and return FALSE.
 *
 * If no item is selected, we do nothing to "cp", and return FALSE.
 *
 * Global "p_ptr->command_wrk" is used to choose between equip/inven/floor
 * listings.  It is equal to USE_INVEN or USE_EQUIP or USE_FLOOR, except
 * when this function is first called, when it is equal to zero, which will
 * cause it to be set to USE_INVEN.
 *
 * We always erase the prompt when we are done, leaving a blank line,
 * or a warning message, if appropriate, if no items are available.
 *
 * Note that only "acceptable" floor objects get indexes, so between two
 * commands, the indexes of floor objects may change.  XXX XXX XXX
 */
bool get_item(int *cp, cptr pmt, cptr str, cmd_code cmd, int mode)
{
	int py = p_ptr->py;
	int px = p_ptr->px;
	unsigned char cmdkey = cmd_lookup_key(cmd);

	ui_event_data which;

	int j, k;

	int i1, i2;
	int e1, e2;
	int f1, f2;

	bool done, item;

	bool oops = FALSE;

	bool use_inven = ((mode & USE_INVEN) ? TRUE : FALSE);
	bool use_equip = ((mode & USE_EQUIP) ? TRUE : FALSE);
	bool use_floor = ((mode & USE_FLOOR) ? TRUE : FALSE);
	bool use_quiver = ((mode & QUIVER_TAGS) ? TRUE : FALSE);
	bool is_harmless = ((mode & IS_HARMLESS) ? TRUE : FALSE);
	bool quiver_tags = ((mode & QUIVER_TAGS) ? TRUE : FALSE);

	olist_detail_t olist_mode = 0;

	bool allow_inven = FALSE;
	bool allow_equip = FALSE;
	bool allow_floor = FALSE;

	bool toggle = FALSE;

	char tmp_val[160];
	char out_val[160];

	int floor_list[MAX_FLOOR_STACK];
	int floor_num;

	bool show_list = TRUE;


	/* Object list display modes */
	if (mode & SHOW_FAIL)
		olist_mode |= (OLIST_FAIL);
	else
		olist_mode |= (OLIST_WEIGHT);
	if (mode & SHOW_PRICES)
		olist_mode |= (OLIST_PRICE);

	/* Paranoia XXX XXX XXX */
	message_flush();


	/* Not done */
	done = FALSE;

	/* No item selected */
	item = FALSE;


	/* Full inventory */
	i1 = 0;
	i2 = INVEN_PACK - 1;

	/* Forbid inventory */
	if (!use_inven) i2 = -1;

	/* Restrict inventory indexes */
	while ((i1 <= i2) && (!get_item_okay(i1))) i1++;
	while ((i1 <= i2) && (!get_item_okay(i2))) i2--;

	/* Accept inventory */
	if (i1 <= i2) allow_inven = TRUE;


	/* Full equipment */
	e1 = INVEN_WIELD;
	e2 = ALL_INVEN_TOTAL - 1;

	/* Forbid equipment */
	if (!use_equip) e2 = -1;

	/* Restrict equipment indexes */
	while ((e1 <= e2) && (!get_item_okay(e1))) e1++;
	while ((e1 <= e2) && (!get_item_okay(e2))) e2--;

	/* Accept equipment */
	if (e1 <= e2) allow_equip = TRUE;


	/* Scan all non-gold objects in the grid */
	floor_num = scan_floor(floor_list, N_ELEMENTS(floor_list), py, px, 0x03);

	/* Full floor */
	f1 = 0;
	f2 = floor_num - 1;

	/* Forbid floor */
	if (!use_floor) f2 = -1;

	/* Restrict floor indexes */
	while ((f1 <= f2) && (!get_item_okay(0 - floor_list[f1]))) f1++;
	while ((f1 <= f2) && (!get_item_okay(0 - floor_list[f2]))) f2--;

	/* Accept floor */
	if (f1 <= f2) allow_floor = TRUE;


	/* Require at least one legal choice */
	if (!allow_inven && !allow_equip && !allow_floor)
	{
		/* Oops */
		oops = TRUE;
		done = TRUE;
	}

	/* Analyze choices */
	else
	{
		/* Hack -- Start on equipment if requested */
		if ((p_ptr->command_wrk == USE_EQUIP) && use_equip)
			p_ptr->command_wrk = USE_EQUIP;

		/* If we are using the quiver then start on equipment */
		else if (use_quiver)
			p_ptr->command_wrk = USE_EQUIP;

		/* Use inventory if allowed */
		else if (use_inven)
			p_ptr->command_wrk = USE_INVEN;

		/* Use equipment if allowed */
		else if (use_equip)
			p_ptr->command_wrk = USE_EQUIP;

		/* Use floor if allowed */
		else if (use_floor)
			p_ptr->command_wrk = USE_FLOOR;

		/* Hack -- Use (empty) inventory */
		else
			p_ptr->command_wrk = USE_INVEN;
	}


	/* Start out in "display" mode */
	if (show_list)
	{
		/* Save screen */
		screen_save();
	}


	/* Repeat until done */
	while (!done)
	{
		int ni = 0;
		int ne = 0;

		/* Scan windows */
		for (j = 0; j < REPOSBAND_TERM_MAX; j++)
		{
			/* Unused */
			if (!reposband_term[j]) continue;

			/* Count windows displaying inven */
			if (op_ptr->window_flag[j] & (PW_INVEN)) ni++;

			/* Count windows displaying equip */
			if (op_ptr->window_flag[j] & (PW_EQUIP)) ne++;
		}

		/* Toggle if needed */
		if (((p_ptr->command_wrk == USE_EQUIP) && ni && !ne) ||
		    ((p_ptr->command_wrk == USE_INVEN) && !ni && ne))
		{
			/* Toggle */
			toggle_inven_equip();

			/* Track toggles */
			toggle = !toggle;
		}

		/* Redraw */
		p_ptr->redraw |= (PR_INVEN | PR_EQUIP);

		/* Redraw windows */
		redraw_stuff();

		/* Viewing inventory */
		if (p_ptr->command_wrk == USE_INVEN)
		{
			/* Redraw if needed */
			if (show_list) show_inven(olist_mode);

			/* Begin the prompt */
			strnfmt(out_val, sizeof(out_val), "Inven:");

			/* List choices */
			if (i1 <= i2)
			{
				/* Build the prompt */
				strnfmt(tmp_val, sizeof(tmp_val), " %c-%c,",
				        index_to_label(i1), index_to_label(i2));

				/* Append */
				my_strcat(out_val, tmp_val, sizeof(out_val));
			}

			/* Indicate ability to "view" */
			if (!show_list)
			{
				my_strcat(out_val, " * to see,", sizeof(out_val));
				button_add("[*]", '*');
			}

			/* Indicate legality of "toggle" */
			if (use_equip)
			{
				my_strcat(out_val, " / for Equip,", sizeof(out_val));
				button_add("[/]", '/');
			}

			/* Indicate legality of the "floor" */
			if (allow_floor)
			{
				my_strcat(out_val, " - for floor,", sizeof(out_val));
				button_add("[-]", '-');
			}
		}

		/* Viewing equipment */
		else if (p_ptr->command_wrk == USE_EQUIP)
		{
			/* Redraw if needed */
			if (show_list) show_equip(olist_mode);

			/* Begin the prompt */
			strnfmt(out_val, sizeof(out_val), "Equip:");

			/* List choices */
			if (e1 <= e2)
			{
				/* Build the prompt */
				strnfmt(tmp_val, sizeof(tmp_val), " %c-%c,",
				        index_to_label(e1), index_to_label(e2));

				/* Append */
				my_strcat(out_val, tmp_val, sizeof(out_val));
			}

			/* Indicate ability to "view" */
			if (!show_list)
			{
				my_strcat(out_val, " * to see,", sizeof(out_val));
				button_add("[*]", '*');
			}

			/* Indicate legality of "toggle" */
			if (use_inven)
			{
				my_strcat(out_val, " / for Inven,", sizeof(out_val));
				button_add("[/]", '/');
			}

			/* Indicate legality of the "floor" */
			if (allow_floor)
			{
				my_strcat(out_val, " - for floor,", sizeof(out_val));
				button_add("[!]", '!');
			}
		}

		/* Viewing floor */
		else
		{
			/* Redraw if needed */
			if (show_list) show_floor(floor_list, floor_num, olist_mode);

			/* Begin the prompt */
			strnfmt(out_val, sizeof(out_val), "Floor:");

			/* List choices */
			if (f1 <= f2)
			{
				/* Build the prompt */
				strnfmt(tmp_val, sizeof(tmp_val), " %c-%c,", I2A(f1), I2A(f2));

				/* Append */
				my_strcat(out_val, tmp_val, sizeof(out_val));
			}

			/* Indicate ability to "view" */
			if (!show_list)
			{
				my_strcat(out_val, " * to see,", sizeof(out_val));
				button_add("[*]", '*');
			}

			/* Append */
			if (use_inven)
			{
				my_strcat(out_val, " / for Inven,", sizeof(out_val));
				button_add("[/]", '/');
			}

			/* Append */
			else if (use_equip)
			{
				my_strcat(out_val, " / for Equip,", sizeof(out_val));
				button_add("[/]", '/');
			}
		}

		redraw_stuff();

		/* Finish the prompt */
		my_strcat(out_val, " ESC", sizeof(out_val));

		/* Build the prompt */
		strnfmt(tmp_val, sizeof(tmp_val), "(%s) %s", out_val, pmt);

		/* Show the prompt */
		prt(tmp_val, 0, 0);


		/* Get a key */
		which = inkey_ex();

		/* Parse it */
		switch (which.key)
		{
			case ESCAPE:
			{
				done = TRUE;
				break;
			}

			case '/':
			{
				/* Toggle to inventory */
				if (use_inven && (p_ptr->command_wrk != USE_INVEN))
				{
					p_ptr->command_wrk = USE_INVEN;
				}

				/* Toggle to equipment */
				else if (use_equip && (p_ptr->command_wrk != USE_EQUIP))
				{
					p_ptr->command_wrk = USE_EQUIP;
				}

				/* No toggle allowed */
				else
				{
					bell("Cannot switch item selector!");
					break;
				}


				/* Hack -- Fix screen */
				if (show_list)
				{
					/* Load screen */
					screen_load();

					/* Save screen */
					screen_save();
				}

				/* Need to redraw */
				break;
			}

			case '-':
			{
				/* Paranoia */
				if (!allow_floor)
				{
					bell("Cannot select floor!");
					break;
				}

				/* There is only one item */
				if (floor_num == 1)
				{
					/* Auto-select */
					if (p_ptr->command_wrk == (USE_FLOOR))
					{
						/* Special index */
						k = 0 - floor_list[0];

						/* Allow player to "refuse" certain actions */
						if (!get_item_allow(k, cmdkey, is_harmless))
						{
							done = TRUE;
							break;
						}

						/* Accept that choice */
						(*cp) = k;
						item = TRUE;
						done = TRUE;

						break;
					}
				}

				/* Hack -- Fix screen */
				if (show_list)
				{
					/* Load screen */
					screen_load();

					/* Save screen */
					screen_save();
				}

				p_ptr->command_wrk = (USE_FLOOR);

#if 0
				/* Check each legal object */
				for (i = 0; i < floor_num; ++i)
				{
					/* Special index */
					k = 0 - floor_list[i];

					/* Skip non-okay objects */
					if (!get_item_okay(k)) continue;

					/* Allow player to "refuse" certain actions */
					if (!get_item_allow(k, cmdkey, is_harmless)) continue;

					/* Accept that choice */
					(*cp) = k;
					item = TRUE;
					done = TRUE;
					break;
				}
#endif

				break;
			}

			case '0':
			case '1': case '2': case '3':
			case '4': case '5': case '6':
			case '7': case '8': case '9':
			{
				/* Look up the tag */
				if (!get_tag(&k, which.key, cmd, quiver_tags))
				{
					bell("Illegal object choice (tag)!");
					break;
				}

				/* Hack -- Validate the item */
				if ((k < INVEN_WIELD) ? !allow_inven : !allow_equip)
				{
					bell("Illegal object choice (tag)!");
					break;
				}

				/* Validate the item */
				if (!get_item_okay(k))
				{
					bell("Illegal object choice (tag)!");
					break;
				}

				/* Allow player to "refuse" certain actions */
				if (!get_item_allow(k, cmdkey, is_harmless))
				{
					done = TRUE;
					break;
				}

				/* Accept that choice */
				(*cp) = k;
				item = TRUE;
				done = TRUE;
				break;
			}

			case '\n':
			case '\r':
			{
				/* Choose "default" inventory item */
				if (p_ptr->command_wrk == USE_INVEN)
				{
					if (i1 != i2)
					{
						bell("Illegal object choice (default)!");
						break;
					}

					k = i1;
				}

				/* Choose the "default" slot (0) of the quiver */
				else if (quiver_tags)
					k = e1;

				/* Choose "default" equipment item */
				else if (p_ptr->command_wrk == USE_EQUIP)
				{
					if (e1 != e2)
					{
						bell("Illegal object choice (default)!");
						break;
					}

					k = e1;
				}

				/* Choose "default" floor item */
				else
				{
					if (f1 != f2)
					{
						bell("Illegal object choice (default)!");
						break;
					}

					k = 0 - floor_list[f1];
				}

				/* Validate the item */
				if (!get_item_okay(k))
				{
					bell("Illegal object choice (default)!");
					break;
				}

				/* Allow player to "refuse" certain actions */
				if (!get_item_allow(k, cmdkey, is_harmless))
				{
					done = TRUE;
					break;
				}

				/* Accept that choice */
				(*cp) = k;
				item = TRUE;
				done = TRUE;
				break;
			}

			default:
			{
				bool verify;

				/* Note verify */
				verify = (isupper((unsigned char)which.key) ? TRUE : FALSE);

				/* Lowercase */
				which.key = tolower((unsigned char)which.key);

				/* Convert letter to inventory index */
				if (p_ptr->command_wrk == USE_INVEN)
				{
					k = label_to_inven(which.key);

					if (k < 0)
					{
						bell("Illegal object choice (inven)!");
						break;
					}
				}

				/* Convert letter to equipment index */
				else if (p_ptr->command_wrk == USE_EQUIP)
				{
					k = label_to_equip(which.key);

					if (k < 0)
					{
						bell("Illegal object choice (equip)!");
						break;
					}
				}

				/* Convert letter to floor index */
				else
				{
					k = (islower((unsigned char)which.key) ? A2I(which.key) : -1);

					if (k < 0 || k >= floor_num)
					{
						bell("Illegal object choice (floor)!");
						break;
					}

					/* Special index */
					k = 0 - floor_list[k];
				}

				/* Validate the item */
				if (!get_item_okay(k))
				{
					bell("Illegal object choice (normal)!");
					break;
				}

				/* Verify the item */
				if (verify && !verify_item("Try", k))
				{
					done = TRUE;
					break;
				}

				/* Allow player to "refuse" certain actions */
				if (!get_item_allow(k, cmdkey, is_harmless))
				{
					done = TRUE;
					break;
				}

				/* Accept that choice */
				(*cp) = k;
				item = TRUE;
				done = TRUE;
				break;
			}
		}
	}


	/* Fix the screen if necessary */
	if (show_list)
	{
		/* Load screen */
		screen_load();

		/* Hack -- Cancel "display" */
		show_list = FALSE;
	}


	/* Kill buttons */
	button_kill('*');
	button_kill('/');
	button_kill('-');
	button_kill('!');
	redraw_stuff();
 
	/* Forget the item_tester_tval restriction */
	item_tester_tval = 0;

	/* Forget the item_tester_hook restriction */
	item_tester_hook = NULL;


	/* Toggle again if needed */
	if (toggle) toggle_inven_equip();

	/* Update */
	p_ptr->redraw |= (PR_INVEN | PR_EQUIP);
	redraw_stuff();


	/* Clear the prompt line */
	prt("", 0, 0);

	/* Warning if needed */
	if (oops && str) msg_print(str);

	/* Result */
	return (item);
}
Exemple #3
0
/*
 * Request a command from the user.
 *
 * Note that "caret" ("^") is treated specially, and is used to
 * allow manual input of control characters.  This can be used
 * on many machines to request repeated tunneling (Ctrl-H) and
 * on the Macintosh to request "Control-Caret".
 *
 * Note that "backslash" is treated specially, and is used to bypass any
 * keymap entry for the following character.  This is useful for macros.
 */
static ui_event textui_get_command(int *count)
{
	int mode = OPT(rogue_like_commands) ? KEYMAP_MODE_ROGUE : KEYMAP_MODE_ORIG;

	struct keypress tmp[2] = { { 0 }, { 0 } };

	ui_event ke = EVENT_EMPTY;

	const struct keypress *act = NULL;



	/* Get command */
	while (1)
	{
		/* Hack -- no flush needed */
		msg_flag = FALSE;

		/* Activate "command mode" */
		inkey_flag = TRUE;

		/* Get a command */
		ke = inkey_ex();

		if (ke.type == EVT_KBRD) {
			bool keymap_ok = TRUE;
			switch (ke.key.code) {
				case '0': {
					int c = textui_get_count();

					if (c == -1 || !get_com_ex("Command: ", &ke))
						continue;
					else
						*count = c;
					break;
				}

				case '\\': {
					/* Allow keymaps to be bypassed */
					(void)get_com_ex("Command: ", &ke);
					keymap_ok = FALSE;
					break;
				}

				case '^': {
					/* Allow "control chars" to be entered */
					if (get_com("Control: ", &ke.key))
						ke.key.code = KTRL(ke.key.code);
					break;
				}
			}

			/* Find any relevant keymap */
			if (keymap_ok)
				act = keymap_find(mode, ke.key);
		}

		/* Erase the message line */
		prt("", 0, 0);

		if (ke.type == EVT_BUTTON)
		{
			/* Buttons are always specified in standard keyset */
			act = tmp;
			tmp[0] = ke.key;
		}

		/* Apply keymap if not inside a keymap already */
		if (ke.key.code && act && !inkey_next)
		{
			size_t n = 0;
			while (act[n].type)
				n++;

			/* Make room for the terminator */
			n += 1;

			/* Install the keymap */
			memcpy(request_command_buffer, act, n * sizeof(struct keypress));

			/* Start using the buffer */
			inkey_next = request_command_buffer;

			/* Continue */
			continue;
		}

		/* Done */
		break;
	}

	return ke;
}
Exemple #4
0
static enum birth_stage roller_command(bool first_call)
{
	char prompt[80] = "";
	size_t promptlen = 0;

	ui_event_data ke;
	char ch;

	enum birth_stage next = BIRTH_ROLLER;

	/* Used to keep track of whether we've rolled a character before or not. */
	static bool prev_roll = FALSE;

   	/* Display the player - a bit cheaty, but never mind. */
	display_player(0, TRUE);

	if (first_call)
		prev_roll = FALSE;

	/* Add buttons */
	button_kill_all();
	button_add("[ESCAPE]", ESCAPE);
	button_add("[ACCEPT]", '\r');
	button_add("[REROLL]", 'r');
	if (prev_roll) button_add("[PREV]", 'p');
	button_add("[HELP]", '?');
	button_add("[QUIT]", '\x18');  /* CTRL-X */
	clear_from(Term->hgt - 2);
	handle_stuff();
	event_signal(EVENT_MOUSEBUTTONS);

	/* Prepare a prompt (must squeeze everything in) */
	strnfcat(prompt, sizeof (prompt), &promptlen, "['r' to reroll");
	if (prev_roll)
		strnfcat(prompt, sizeof(prompt), &promptlen, ", 'p' for prev");
	strnfcat(prompt, sizeof (prompt), &promptlen, " or 'Enter' to accept]");

	/* Prompt for it */
	prt(prompt, Term->hgt - (mouse_buttons ? 2 : 1), Term->wid / 2 - promptlen / 2);

	/* Prompt and get a command */
	ke = inkey_ex();
	ch = ke.key;

	if (ch == ESCAPE)
	{
		button_kill('r');
		button_kill('p');

		next = BIRTH_BACK;
	}

	/* 'Enter' accepts the roll */
	if ((ch == '\r') || (ch == '\n'))
	{
		next = BIRTH_NAME_CHOICE;
	}

	/* Reroll this character */
	else if ((ch == ' ') || (ch == 'r'))
	{
		cmd_insert(CMD_ROLL_STATS);
		prev_roll = TRUE;
	}

	/* Previous character */
	else if (prev_roll && (ch == 'p'))
	{
		cmd_insert(CMD_PREV_STATS);
	}

	/* Quit */
	else if (ch == KTRL('X'))
	{
		cmd_insert(CMD_QUIT);
		next = BIRTH_COMPLETE;
	}

	/* Help XXX */
	else if (ch == '?')
	{
		do_cmd_help();
	}

	/* Nothing handled directly here */
	else
	{
		bell("Illegal roller command!");
	}

	/* Kill buttons */
	button_kill_all();
	handle_stuff();
	event_signal(EVENT_MOUSEBUTTONS);

	return next;
}
Exemple #5
0
static enum birth_stage point_based_command(void)
{
	static int stat = 0;
	char ch;
	enum birth_stage next = BIRTH_POINTBASED;
	ui_event_data ke;

	/* Add buttons */
	button_kill_all();
	button_add("[ESCAPE]", ESCAPE);
	button_add("[ACCEPT]", '\r');
	button_add("[RESET STATS]", 'r');
	button_add("[UP]", '8');
	button_add("[DOWN]", '2');
	button_add("[DEC_STAT]", '4');
	button_add("[INC_STAT]", '6');
	button_add("[QUIT]", '\x18');  /* CTRL-X */
	clear_from(Term->hgt - 2);
	handle_stuff();
	event_signal(EVENT_MOUSEBUTTONS);

	/*	point_based_display();*/

	/* Place cursor just after cost of current stat */
	Term_gotoxy(COSTS_COL + 4, COSTS_ROW + stat);

	/* Get key */
	/* Prompt and get a command */
	ke = inkey_ex();
	ch = ke.key;

	if (ch == KTRL('X'))
	{
		cmd_insert(CMD_QUIT);
		next = BIRTH_COMPLETE;
	}

	/* Go back a step, or back to the start of this step */
	else if (ch == ESCAPE)
	{
		next = BIRTH_BACK;
	}

	else if (ch == 'r' || ch == 'R')
	{
		cmd_insert(CMD_RESET_STATS, FALSE);
	}

	/* Done */
	else if ((ch == '\r') || (ch == '\n'))
	{
		next = BIRTH_NAME_CHOICE;
	}
	else
	{
		ch = target_dir(ch);

		/* Prev stat, looping round to the bottom when going off the top */
		if (ch == 8)
			stat = (stat + A_MAX - 1) % A_MAX;

		/* Next stat, looping round to the top when going off the bottom */
		if (ch == 2)
			stat = (stat + 1) % A_MAX;

		/* Decrease stat (if possible) */
		if (ch == 4)
		{
			cmd_insert(CMD_SELL_STAT, stat);
		}

		/* Increase stat (if possible) */
		if (ch == 6)
		{
			cmd_insert(CMD_BUY_STAT, stat);
		}
	}

	button_kill_all();
	event_signal(EVENT_MOUSEBUTTONS);

	return next;
}
Exemple #6
0
/**
 * Show previous messages to the user
 *
 * The screen format uses line 0 and 23 for headers and prompts,
 * skips line 1 and 22, and uses line 2 thru 21 for old messages.
 *
 * This command shows you which commands you are viewing, and allows
 * you to "search" for strings in the recall.
 *
 * Note that messages may be longer than 80 characters, but they are
 * displayed using "infinite" length, with a special sub-command to
 * "slide" the virtual display to the left or right.
 *
 * Attempt to only hilight the matching portions of the string.
 */
void do_cmd_messages(void)
{
  ui_event ke;
  
  int i, j, n, q;
  int wid, hgt;
  
  char shower[80];
  char finder[80];
  char p[80];  
  
  /* Wipe finder */
  my_strcpy(finder, "", sizeof(shower));
  
  /* Wipe shower */
  my_strcpy(shower, "", sizeof(finder));
  
  
  /* Total messages */
  n = messages_num();
  
  /* Start on first message */
  i = 0;
  
  /* Start at leftmost edge */
  q = 0;
  
  /* Get size */
  Term_get_size(&wid, &hgt);
  
  /* Prompt */
  strncpy(p, "[Press 'p' for older, 'n' for newer, ..., or ESCAPE]", 80);

  /* Save screen */
  screen_save();
  
  /* Adjust the buttons */
  button_backup_all();
  button_kill_all();
  button_add("ESC", ESCAPE);
  button_add("-", '-');
  button_add("=", '=');
  button_add("/", '/');
  button_add("p", 'p');
  button_add("n", 'n');
  button_add("+", '+');
  button_add("->", '6');
  button_add("<-", '4');
  p_ptr->redraw |= (PR_BUTTONS);

  /* Process requests until done */
  while (1)
    {
      /* Clear screen */
      Term_clear();
      
      /* Dump messages */
      for (j = 0; (j < hgt - 4) && (i + j < n); j++)
	{
	  const char *msg = message_str((s16b)(i+j));
	  byte attr = message_color((s16b)(i+j));
	  
	  /* Apply horizontal scroll */
	  msg = ((int)strlen(msg) >= q) ? (msg + q) : "";
	  
	  /* Dump the messages, bottom to top */
	  Term_putstr(0, hgt - 3 - j, -1, attr, msg);
	  
	  /* Hilight "shower" */
	  if (shower[0])
	    {
	      const char *str = msg;
	      
	      /* Display matches */
	      while ((str = strstr(str, shower)) != NULL)
		{
		  int len = strlen(shower);
		  
		  /* Display the match */
		  Term_putstr(str-msg, hgt - 3 - j, len, TERM_YELLOW, shower);
		  
		  /* Advance */
		  str += len;
		}
	    }
	}
      
      /* Display header XXX XXX XXX */
      prt(format("Message Recall (%d-%d of %d), Offset %d",
		 i, i + j - 1, n, q), 0, 0);
      
      /* Display prompt (not very informative) */
      prt(p, hgt - 1, 0);
      redraw_stuff(p_ptr);
      
      /* Get a command */
      ke = inkey_ex();
      
      /* Exit on Escape */
      if (ke.key.code == ESCAPE) break;
      
      /* Hack -- Save the old index */
      j = i;
      
      /* Horizontal scroll */
      if (ke.key.code == '4')
	{
	  /* Scroll left */
	  q = (q >= wid / 2) ? (q - wid / 2) : 0;
	  
	  /* Success */
	  continue;
	}
      
      /* Horizontal scroll */
      if (ke.key.code == '6')
	{
	  /* Scroll right */
	  q = q + wid / 2;
	  
	  /* Success */
	  continue;
	}
      
      /* Hack -- handle show */
      if (ke.key.code == '=')
	{
	  /* Prompt */
	  prt("Show: ", hgt - 1, 0);
	  
	  /* Get a "shower" string, or continue */
	  if (!askfor_aux(shower, sizeof shower, NULL)) continue;
	  
	  /* Okay */
	  continue;
	}
      
      /* Hack -- handle find */
      if (ke.key.code == '/')
	{
	  s16b z;
	  
	  /* Prompt */
	  prt("Find: ", hgt - 1, 0);
	  
	  /* Get a "finder" string, or continue */
	  if (!askfor_aux(finder, sizeof finder, NULL)) continue;
	  
	  /* Show it */
	  my_strcpy(shower, finder, sizeof(shower));
	  
	  /* Scan messages */
	  for (z = i + 1; z < n; z++)
	    {
	      const char *msg = message_str(z);
	      
	      /* Search for it */
	      if (strstr(msg, finder))
		{
		  /* New location */
		  i = z;
		  
		  /* Done */
		  break;
		}
	    }
	}
      
      /* Recall 20 older messages */
      if ((ke.key.code == 'p') || (ke.key.code == KTRL('P')) || (ke.key.code == ' '))
	{
	  /* Go older if legal */
	  if (i + 20 < n) i += 20;
	}
      
      /* Recall 10 older messages */
      if (ke.key.code == '+')
	{
	  /* Go older if legal */
	  if (i + 10 < n) i += 10;
	}
      
      /* Recall 1 older message */
      if ((ke.key.code == '8') || (ke.key.code == '\n') || (ke.key.code == '\r'))
	{
	  /* Go older if legal */
	  if (i + 1 < n) i += 1;
	}
      
      /* Recall 20 newer messages */
      if ((ke.key.code == 'n') || (ke.key.code == KTRL('N')))
	{
	  /* Go newer (if able) */
	  i = (i >= 20) ? (i - 20) : 0;
	}
      
      /* Recall 10 newer messages */
      if (ke.key.code == '-')
	{
	  /* Go newer (if able) */
	  i = (i >= 10) ? (i - 10) : 0;
	}
      
      /* Recall 1 newer messages */
      if (ke.key.code == '2')
	{
	  /* Go newer (if able) */
	  i = (i >= 1) ? (i - 1) : 0;
	}
      
      /* Scroll forwards or backwards using mouse clicks */
      if (ke.mouse.button)
      {
	  if (ke.mouse.y <= hgt / 2)
	  {
	      /* Go older if legal */
	      if (i + 20 < n) i += 20;
	  }
	  else
	  {
	      /* Go newer (if able) */
	      i = (i >= 20) ? (i - 20) : 0;
	  }
      }
      
      /* Hack -- Error of some kind */
      if (i == j) bell(NULL);
    }
  
  /* Adjust the buttons */
  button_restore();

  /* Load screen */
  screen_load();
}
Exemple #7
0
/**
 * Pick up objects and treasure on the floor, now also used for telekinesis.
 *
 * Called with pickup:
 * 0 to grab gold and describe non-gold objects.
 * 1 to pick up objects either with or without displaying a menu.
 * 2 to pick up objects, forcing a menu for multiple objects.
 * 3 to pick up objects, forcing a menu for any number of objects.
 *
 * Scan the list of objects in that floor grid.   Pick up gold automatically.
 * Pick up objects automatically until pile or backpack space is full if 
 * auto-pickup option is on, carry_query_floor option is not, and menus are 
 * not forced (which the "get" command does). Otherwise, store objects on 
 * floor in an array, and tally both how many there are and can be picked up.
 *
 * If the player is not picking up objects, describe a single object or 
 * indicate the presence of a floor stack.  If player is picking up objects, 
 * name a single object, or indicate a stack of objects, that cannot go in 
 * the backpack.
 *
 * Pick up a single object without menus, unless menus for single items are 
 * forced.  Confirm pickup if that option is on.
 *
 * Pick up multiple objects (unless using autopickup, no confirm) using Tim
 * Baker's menu system.   Recursively call this function (forcing menus for any 
 * number of objects) until objects are gone, backpack is full, or player is 
 * satisfied.
 *
 * Keep track of number of objects picked up (to calculate time spent).
 */
byte py_pickup(int pickup, int y, int x)
{
	s16b this_o_idx, next_o_idx = 0;

	char o_name[120];
	object_type *o_ptr;

	/* Objects picked up.  Used to determine time cost of command. */
	byte objs_picked_up = 0;

	size_t floor_num = 0;
	int floor_list[MAX_FLOOR_STACK + 1], floor_o_idx = 0;

	int can_pickup = 0;
	bool call_function_again = FALSE;
	bool blind = ((p_ptr->timed[TMD_BLIND]) || (no_light()));
	bool domsg = TRUE;
	bool telekinesis = ((y != p_ptr->py) || (x != p_ptr->px));

	/* Always pickup gold, effortlessly */
	if (!telekinesis)
		py_pickup_gold();

	/* Nothing to pick up -- return */
	if (!cave_o_idx[y][x])
		return (objs_picked_up);

	/* Scan the pile of objects */
	for (this_o_idx = cave_o_idx[y][x]; this_o_idx;
		 this_o_idx = next_o_idx) {

		/* Access the object */
		o_ptr = &o_list[this_o_idx];

		/* Access the next object */
		next_o_idx = o_ptr->next_o_idx;

		/* Ordinary pickup */
		if (!telekinesis) {

			/* Ignore all hidden objects and non-objects */
			if (squelch_hide_item(o_ptr) || !o_ptr->k_idx)
				continue;

			/* Hack -- disturb */
			disturb(0, 0);

			/* Automatically pick up some items */
			if (auto_pickup_okay(o_ptr)) {
				/* Pick up the object */
				py_pickup_aux(this_o_idx, TRUE);
				objs_picked_up++;

				/* Check the next object */
				continue;
			}
		}

		/* Tally objects and store them in an array. */

		/* Remember this object index */
		floor_list[floor_num] = this_o_idx;

		/* Count non-gold objects that remain on the floor. */
		floor_num++;

		/* Tally objects that can be picked up. */
		if (inven_carry_okay(o_ptr))
			can_pickup++;
	}

	/* There are no non-gold objects */
	if (!floor_num)
		return (objs_picked_up);

	/* Get hold of the last floor index */
	floor_o_idx = floor_list[floor_num - 1];

	/* Mention the objects if player is not picking them up. */
	if (pickup == 0 || !(can_pickup || telekinesis)) {
		const char *p = "see";

		/* One object */
		if (floor_num == 1) {
			if (!can_pickup)
				p = "have no room for";
			else if (blind)
				p = "feel";

			/* Get the object */
			o_ptr = &o_list[floor_o_idx];

			/* Describe the object.  Less detail if blind. */
			if (blind)
				object_desc(o_name, sizeof(o_name), o_ptr,
							ODESC_PREFIX | ODESC_BASE);
			else
				object_desc(o_name, sizeof(o_name), o_ptr,
							ODESC_PREFIX | ODESC_FULL);

			/* Message */
			message_flush();
			msg("You %s %s.", p, o_name);
		} else {
			/* Optionally, display more information about floor items */
			if (OPT(pickup_detail)) {
				ui_event e;

				if (!can_pickup)
					p = "have no room for the following objects";
				else if (blind)
					p = "feel something on the floor";

				/* Scan all marked objects in the grid */
				floor_num =
					scan_floor(floor_list, N_ELEMENTS(floor_list), y, x,
							   0x03);

				/* Save screen */
				screen_save();

				/* Display objects on the floor */
				show_floor(floor_list, floor_num, (OLIST_WEIGHT));

				/* Display prompt */
				prt(format("You %s: ", p), 0, 0);

				/* Move cursor back to character, if needed */
				if (OPT(highlight_player))
					move_cursor_relative(p_ptr->py, p_ptr->px);

				/* Wait for it.  Use key as next command. */
				e = inkey_ex();
				Term_event_push(&e);

				/* Restore screen */
				screen_load();
			}

			/* Show less detail */
			else {
				message_flush();

				if (!can_pickup)
					msg("You have no room for any of the items on the floor.");
				else
					msg("You %s a pile of %d items.",
						(blind ? "feel" : "see"), floor_num);
			}
		}

		/* Done */
		return (objs_picked_up);
	}

	/* We can pick up objects.  Menus are not requested (yet). */
	if (pickup == 1) {
		/* Scan floor (again) */
		floor_num =
			scan_floor(floor_list, N_ELEMENTS(floor_list), y, x, 0x03);

		/* Use a menu interface for multiple objects, or get single objects */
		if (floor_num > 1)
			pickup = 2;
		else
			this_o_idx = floor_o_idx;
	}


	/* Display a list if requested. */
	if (pickup == 2) {
		const char *q, *s;
		int item;

		/* Get an object or exit. */
		q = "Get which item?";
		s = "You see nothing there.";

		/* Telekinesis */
		if (telekinesis) {
			item_tester_hook = inven_carry_okay;

			if (!get_item(&item, q, s, CMD_PICKUP, USE_TARGET))
				return (objs_picked_up);

			this_o_idx = 0 - item;
		} else {
			/* Restrict the choices */
			item_tester_hook = inven_carry_okay;

			if (!get_item(&item, q, s, CMD_PICKUP, USE_FLOOR))
				return (objs_picked_up);

			this_o_idx = 0 - item;
			call_function_again = TRUE;
		}

		/* With a list, we do not need explicit pickup messages */
		domsg = FALSE;
	}

	/* Pick up object, if legal */
	if (this_o_idx) {
		/* Regular pickup or telekinesis with pack not full */
		if (can_pickup) {
			/* Pick up the object */
			py_pickup_aux(this_o_idx, domsg);
		}
		/* Telekinesis with pack full */
		else {
			/* Access the object */
			o_ptr = &o_list[this_o_idx];

			/* Drop it */
			drop_near(o_ptr, -1, p_ptr->py, p_ptr->px, TRUE);

			/* Delete the old object */
			delete_object_idx(this_o_idx);
		}
	}

	/* Indicate an object picked up. */
	objs_picked_up = 1;

	/* If requested, call this function recursively.  Count objects picked up.
	 * Force the display of a menu in all cases. */
	if (call_function_again)
		objs_picked_up += py_pickup(2, y, x);

	/* Indicate how many objects have been picked up. */
	return (objs_picked_up);
}
Exemple #8
0
/**
 * Display some character info
 */
static void death_info(const char *title, int row)
{
    int i, j, k, which = 0;

    object_type *o_ptr;

    store_type *st_ptr;

    ui_event_data ke;

    bool done = FALSE;

    /* Get the store number of the home */
    if (OPT(adult_dungeon))
	which = NUM_TOWNS_SMALL * 4 + STORE_HOME;
    else {
	for (i = 0; i < NUM_TOWNS; i++) {
	    /* Found the town */
	    if (p_ptr->home == towns[i]) {
		which += (i < NUM_TOWNS_SMALL ? 3 : STORE_HOME);
		break;
	    }
	    /* Next town */
	    else
		which +=
		    (i < NUM_TOWNS_SMALL ? MAX_STORES_SMALL : MAX_STORES_BIG);
	}
    }

    /* Activate the store */
    st_ptr = &store[which];

    screen_save();
    
    /* Display player */
    display_player(0);

    /* Prompt for inventory */
    prt("Hit any key to see more information (ESC to abort): ", 0, 0);

    /* Buttons */
    button_backup_all();
    button_kill_all();
    button_add("ESC", ESCAPE);
    button_add("Continue", 'q');

    /* Allow abort at this point */
    ke = inkey_ex();
    if (ke.key == ESCAPE)
	done = TRUE;

    /* Show equipment and inventory */

    /* Equipment -- if any */
    if ((p_ptr->equip_cnt) && !done) {
	Term_clear();
	item_tester_full = TRUE;
	show_equip(OLIST_WEIGHT);
	prt("You are using: -more-", 0, 0);
	ke = inkey_ex();
	if (ke.key == ESCAPE)
	    done = TRUE;
    }

    /* Inventory -- if any */
    if ((p_ptr->inven_cnt) && !done) {
	Term_clear();
	item_tester_full = TRUE;
	show_inven(OLIST_WEIGHT);
	prt("You are carrying: -more-", 0, 0);
	ke = inkey_ex();
	if (ke.key == ESCAPE)
	    done = TRUE;
    }



    /* Home -- if anything there */
    if ((st_ptr->stock_num) && !done) {
	/* Display contents of the home */
	for (k = 0, i = 0; i < st_ptr->stock_num; k++) {
	    /* Clear screen */
	    Term_clear();

	    /* Show 12 items */
	    for (j = 0; (j < 12) && (i < st_ptr->stock_num); j++, i++) {
		byte attr;

		char o_name[80];
		char tmp_val[80];

		/* Get the object */
		o_ptr = &st_ptr->stock[i];

		/* Print header, clear line */
		sprintf(tmp_val, "%c) ", I2A(j));
		prt(tmp_val, j + 2, 4);

		/* Get the object description */
		object_desc(o_name, sizeof(o_name), o_ptr,
			    ODESC_PREFIX | ODESC_FULL);	

		/* Get the inventory color */
		attr = tval_to_attr[o_ptr->tval & 0x7F];

		/* Display the object */
		c_put_str(attr, o_name, j + 2, 7);
	    }

	    /* Caption */
	    prt(format("Your home contains (page %d): -more-", k + 1), 0, 0);

	    /* Wait for it */
	    ke = inkey_ex();
	    if (ke.key == ESCAPE)
		done = TRUE;
	}
    }
    screen_load();
}
Exemple #9
0
/*
 * Request a command from the user.
 *
 * Note that "caret" ("^") is treated specially, and is used to
 * allow manual input of control characters.  This can be used
 * on many machines to request repeated tunneling (Ctrl-H) and
 * on the Macintosh to request "Control-Caret".
 *
 * Note that "backslash" is treated specially, and is used to bypass any
 * keymap entry for the following character.  This is useful for macros.
 */
static ui_event_data textui_get_command(void)
{
	int mode = OPT(rogue_like_commands) ? KEYMAP_MODE_ROGUE : KEYMAP_MODE_ORIG;

	char tmp[2] = { '\0', '\0' };

	ui_event_data ke = EVENT_EMPTY;

	cptr act = NULL;



	/* Get command */
	while (1)
	{
		/* Hack -- no flush needed */
		msg_flag = FALSE;

		/* Activate "command mode" */
		inkey_flag = TRUE;

		/* Get a command */
		ke = inkey_ex();


		/* Command Count */
		if (ke.key == '0')
		{
			int count = textui_get_count();

			if (count == -1 || !get_com_ex("Command: ", &ke))
				continue;
			else
				p_ptr->command_arg = count;
		}

		/* Allow "keymaps" to be bypassed */
		else if (ke.key == '\\')
		{
			/* Get a real command */
			(void)get_com("Command: ", &ke.key);

			/* Hack -- bypass keymaps */
			if (!inkey_next) inkey_next = "";
		}

		/* Allow "control chars" to be entered */
		else if (ke.key == '^')
		{
			/* Get a new command and controlify it */
			if (get_com("Control: ", &ke.key))
				ke.key = KTRL(ke.key);
		}

		/* Special case for the arrow keys */
		else if (isarrow(ke.key))
		{
			switch (ke.key)
			{
				case ARROW_DOWN:    ke.key = '2'; break;
				case ARROW_LEFT:    ke.key = '4'; break;
				case ARROW_RIGHT:   ke.key = '6'; break;
				case ARROW_UP:      ke.key = '8'; break;
			}
		}

		/* Erase the message line */
		prt("", 0, 0);


		if (ke.type == EVT_BUTTON)
		{
			/* Buttons are always specified in standard keyset */
			act = tmp;
			tmp[0] = ke.key;
		}
		else if (ke.type == EVT_KBRD)
		{
			/* Look up applicable keymap */
			act = keymap_act[mode][(byte)(ke.key)];
		}

		/* Apply keymap if not inside a keymap already */
		if (ke.key && act && !inkey_next)
		{
			/* Install the keymap */
			my_strcpy(request_command_buffer, act,
			          sizeof(request_command_buffer));

			/* Start using the buffer */
			inkey_next = request_command_buffer;

			/* Continue */
			continue;
		}

		/* Done */
		break;
	}

	return ke;
}
Exemple #10
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] = op_ptr->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 = TERM_WHITE;

			const char *s = angband_term_name[j];

			/* Use color */
			if (j == x) a = TERM_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 = TERM_WHITE;

			const char *str = window_flag_desc[i];

			/* Use color */
			if (i == y) a = TERM_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 = TERM_WHITE;

				/* Use color */
				if ((i == y) && (j == x)) a = TERM_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 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;
				}
			}
		}

		/* Allow escape */
		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();
}
Exemple #11
0
/**
 * Save a "bones" file for a dead character.  Now activated and (slightly) 
 * altered.  Allows the inclusion of personalized strings. 
 */
static void make_bones(void)
{
    ang_file *fp;

    char str[1024];
    ui_event_data answer;
    byte choice = 0;

    int i;

    /* Ignore wizards and borgs */
    if (!(p_ptr->noscore & 0x00FF)) {
	/* Ignore people who die in town */
	if (p_ptr->depth) {
	    int level;
	    char tmp[128];

	    /* Slightly more tenacious saving routine. */
	    for (i = 0; i < 5; i++) {
		/* Ghost hovers near level of death. */
		if (i == 0)
		    level = p_ptr->depth;
		else
		    level = p_ptr->depth + 5 - damroll(2, 4);
		if (level < 1)
		    level = randint1(4);

		/* XXX XXX XXX "Bones" name */
		sprintf(tmp, "bone.%03d", level);

		/* Build the filename */
		path_build(str, 1024, ANGBAND_DIR_BONE, tmp);

		/* Attempt to open the bones file */
		fp = file_open(str, MODE_READ, FTYPE_TEXT);

		/* Close it right away */
		if (fp)
		    file_close(fp);

		/* Do not over-write a previous ghost */
		if (fp)
		    continue;

		/* If no file by that name exists, we can make a new one. */
		if (!(fp))
		    break;
	    }

	    /* Failure */
	    if (fp)
		return;

	    /* Try to write a new "Bones File" */
	    fp = file_open(str, MODE_WRITE, FTYPE_TEXT);

	    /* Not allowed to write it? Weird. */
	    if (!fp)
		return;

	    /* Save the info */
	    if (op_ptr->full_name[0] != '\0')
		file_putf(fp, "%s\n", op_ptr->full_name);
	    else
		file_putf(fp, "Anonymous\n");



	    file_putf(fp, "%d\n", p_ptr->psex);
	    file_putf(fp, "%d\n", p_ptr->prace);
	    file_putf(fp, "%d\n", p_ptr->pclass);

	    /* Clear screen */
	    Term_clear();

	    while (1) {
		/* Ask the player if he wants to add a personalized string. */
		prt("Information about your character has been saved", 15, 0);
		prt("in a bones file.  Would you like to give the", 16, 0);
		prt("ghost a special message or description? (yes/no)", 17, 0);
		button_add("Yes", 'y');
		button_add("No", 'n');

		answer = inkey_ex();

		/* Clear last line */
		clear_from(15);
		clear_from(16);

		/* Determine what the personalized string will be used for.  */
		if ((answer.key == 'Y') || (answer.key == 'y')) {
		    prt("Will you add something for your ghost to say,", 15, 0);
		    prt("or add to the monster description?", 16, 0);
		    prt("((M)essage/(D)escription)", 17, 0);

		    /* Buttons */
		    button_kill('y');
		    button_kill('n');
		    button_add("M", 'M');
		    button_add("D", 'D');
		    button_add("ESC", ESCAPE);

		    while (1) {
			answer = inkey_ex();

			clear_from(15);
			clear_from(16);

			if ((answer.key == 'M') || (answer.key == 'm')) {
			    choice = 1;
			    break;
			} else if ((answer.key == 'D') || (answer.key == 'd')) {
			    choice = 2;
			    break;
			} else {
			    choice = 0;
			    break;
			}
		    }
		} else if ((answer.key == 'N') || (answer.key == 'n')
			   || (answer.key == ESCAPE)) {
		    choice = 0;
		    break;
		}

		button_kill_all();

		/* If requested, get the personalized string, and write it and
		 * info on how it should be used in the bones file.  Otherwise,
		 * indicate the absence of such a string. */
		if (choice)
		    file_putf(fp, "%d:%s\n", choice,
			      get_personalized_string(choice));
		else
		    file_putf(fp, "0: \n");

		/* Close and save the Bones file */
		file_close(fp);

		return;
	    }
	}
    }
}
Exemple #12
0
/*
 * Request a "movement" direction (1,2,3,4,6,7,8,9) from the user.
 *
 * Return TRUE if a direction was chosen, otherwise return FALSE.
 *
 * This function should be used for all "repeatable" commands, such as
 * run, walk, open, close, bash, disarm, spike, tunnel, etc, as well
 * as all commands which must reference a grid adjacent to the player,
 * and which may not reference the grid under the player.
 *
 * Directions "5" and "0" are illegal and will not be accepted.
 *
 * This function tracks and uses the "global direction", and uses
 * that as the "desired direction", if it is set.
 */
bool get_rep_dir(int *dp)
{
	int dir = 0;

	ui_event ke;

	/* Initialize */
	(*dp) = 0;

	/* Get a direction */
	while (!dir)
	{
		/* Paranoia XXX XXX XXX */
		message_flush();

		/* Get first keypress - the first test is to avoid displaying the
		   prompt for direction if there's already a keypress queued up
		   and waiting - this just avoids a flickering prompt if there is
		   a "lazy" movement delay. */
		inkey_scan = SCAN_INSTANT;
		ke = inkey_ex();
		inkey_scan = SCAN_OFF;

		if (ke.type == EVT_NONE ||
				(ke.type == EVT_KBRD && target_dir(ke.key) == 0))
		{
			prt("Direction or <click> (Escape to cancel)? ", 0, 0);
			ke = inkey_ex();
		}

		/* Check mouse coordinates */
		if (ke.type == EVT_MOUSE) {
			if (ke.mouse.button == 1) {
				int y = KEY_GRID_Y(ke);
				int x = KEY_GRID_X(ke);
				struct loc from = loc(p_ptr->px, p_ptr->py);
				struct loc to = loc(x, y);

				dir = pathfind_direction_to(from, to);
			} else
			if (ke.mouse.button == 2) {
				/* Clear the prompt */
				prt("", 0, 0);

				return (FALSE);
			}
		}

		/* Get other keypresses until a direction is chosen. */
		else if (ke.type == EVT_KBRD)
		{
			int keypresses_handled = 0;

			while (ke.type == EVT_KBRD && ke.key.code != 0)
			{
				int this_dir;

				if (ke.key.code == ESCAPE) 
				{
					/* Clear the prompt */
					prt("", 0, 0);

					return (FALSE);
				}

				/* XXX Ideally show and move the cursor here to indicate 
				   the currently "Pending" direction. XXX */
				this_dir = target_dir(ke.key);

				if (this_dir)
					dir = dir_transitions[dir][this_dir];

				if (lazymove_delay == 0 || ++keypresses_handled > 1)
					break;

				inkey_scan = lazymove_delay; 
				ke = inkey_ex();
			}

			/* 5 is equivalent to "escape" */
			if (dir == 5)
			{
				/* Clear the prompt */
				prt("", 0, 0);

				return (FALSE);
			}
		}

		/* Oops */
		if (!dir) bell("Illegal repeatable direction!");
	}

	/* Clear the prompt */
	prt("", 0, 0);

	/* Save direction */
	(*dp) = dir;

	/* Success */
	return (TRUE);
}
Exemple #13
0
/**
 * Let the user select an item, save its "index"
 *
 * Return TRUE only if an acceptable item was chosen by the user.
 *
 * The selected item must satisfy the "item_tester_hook()" function,
 * if that hook is set, and the "item_tester_tval", if that value is set.
 *
 * All "item_tester" restrictions are cleared before this function returns.
 *
 * The user is allowed to choose acceptable items from the equipment,
 * inventory, or floor, respectively, if the proper flag was given,
 * and there are any acceptable items in that location.
 *
 * The equipment or inventory are displayed (even if no acceptable
 * items are in that location) if the proper flag was given.
 *
 * If there are no acceptable items available anywhere, and "str" is
 * not NULL, then it will be used as the text of a warning message
 * before the function returns.
 *
 * Note that the user must press "-" to specify the item on the floor,
 * and there is no way to "examine" the item on the floor, while the
 * use of "capital" letters will "examine" an inventory/equipment item,
 * and prompt for its use.
 *
 * If a legal item is selected from the inventory, we save it in "cp"
 * directly (0 to 35), and return TRUE.
 *
 * If a legal item is selected from the floor, we save it in "cp" as
 * a negative (-1 to -511), and return TRUE.
 *
 * If no item is available, we do nothing to "cp", and we display a
 * warning message, using "str" if available, and return FALSE.
 *
 * If no item is selected, we do nothing to "cp", and return FALSE.
 *
 * Global "p_ptr->command_wrk" is used to choose between equip/inven/floor
 * listings.  It is equal to USE_INVEN or USE_EQUIP or USE_FLOOR, except
 * when this function is first called, when it is equal to zero, which will
 * cause it to be set to USE_INVEN.
 *
 * We always erase the prompt when we are done, leaving a blank line,
 * or a warning message, if appropriate, if no items are available.
 *
 * Note that only "acceptable" floor objects get indexes, so between two
 * commands, the indexes of floor objects may change.  XXX XXX XXX
 */
bool get_item(int *cp, const char *pmt, const char *str, cmd_code cmd, int mode)
{
    s16b py = p_ptr->py;
    s16b px = p_ptr->px;
    unsigned char cmdkey = cmd_lookup_key(cmd, KEYMAP_MODE_ORIG);

    bool done, item;
    int j, k;

    bool oops = FALSE;
    bool toggle = FALSE;

    bool use_inven = ((mode & USE_INVEN) ? TRUE : FALSE);
    bool use_equip = ((mode & USE_EQUIP) ? TRUE : FALSE);
    bool use_floor = ((mode & (USE_FLOOR | USE_TARGET)) ? TRUE : FALSE);
    bool use_quiver = ((mode & QUIVER_TAGS) ? TRUE : FALSE);
    bool can_squelch = ((mode & CAN_SQUELCH) ? TRUE : FALSE);
    bool is_harmless = ((mode & IS_HARMLESS) ? TRUE : FALSE);
    bool quiver_tags = ((mode & QUIVER_TAGS) ? TRUE : FALSE);

    bool allow_inven = FALSE;
    bool allow_equip = FALSE;
    bool allow_floor = FALSE;

    int floor_num;
    ui_event which;
    
    prompt = pmt;
    olist_mode = 0;
    item_mode = mode;
    item_cmd = cmd;

    /* Not done */
    done = FALSE;

    /* No item selected */
    item = FALSE;
    *cp = 0;

    /* Object list display modes */
    if (mode & SHOW_FAIL)
	olist_mode |= (OLIST_FAIL);
    else
	olist_mode |= (OLIST_WEIGHT);
    if (mode & SHOW_PRICES)
	olist_mode |= (OLIST_PRICE);

    show_list  = OPT(show_lists) ? TRUE : FALSE; 

    /* Set target for telekinesis */
    if (mode & (USE_TARGET))
    {
	target_get(&px, &py);
	if (!(px && py))
	    return FALSE;
    }
    
    /* Full inventory */
    i1 = 0;
    i2 = INVEN_PACK - 1;

    /* Forbid inventory */
    if (!use_inven)
	i2 = -1;

    /* Restrict inventory indexes */
    while ((i1 <= i2) && (!get_item_okay(i1)))
	i1++;
    while ((i1 <= i2) && (!get_item_okay(i2)))
	i2--;

    /* Accept inventory */
    if (i1 <= i2)
	allow_inven = TRUE;


    /* Full equipment */
    e1 = INVEN_WIELD;
    e2 = ALL_INVEN_TOTAL - 1;

    /* Forbid equipment */
    if (!use_equip)
	e2 = -1;

    /* Restrict equipment indexes */
    while ((e1 <= e2) && (!get_item_okay(e1)))
	e1++;
    while ((e1 <= e2) && (!get_item_okay(e2)))
	e2--;

    /* Accept equipment */
    if (e1 <= e2)
	allow_equip = TRUE;

    /* Reject quiver */
    if (e2 < QUIVER_START)
	use_quiver = FALSE;

    /* Scan all non-gold objects in the grid */
    floor_num = scan_floor(floor_list, N_ELEMENTS(floor_list), py, px, 0x03);

    /* Full floor */
    f1 = 0;
    f2 = floor_num - 1;

    /* Forbid floor */
    if (!use_floor)
	f2 = -1;

    /* Restrict floor indexes */
    while ((f1 <= f2) && (!get_item_okay(0 - floor_list[f1])))
	f1++;
    while ((f1 <= f2) && (!get_item_okay(0 - floor_list[f2])))
	f2--;

    /* Accept floor */
    if (f1 <= f2)
	allow_floor = TRUE;

    /* Require at least one legal choice */
    if (!allow_inven && !allow_equip && !allow_floor) {
	/* Oops */
	oops = TRUE;
	done = TRUE;
    }

    /* Analyze choices, prepare for initial menu */
    else {
	/* Hack -- Start on equipment if requested */
	if ((p_ptr->command_wrk == USE_EQUIP) && use_equip){
	    p_ptr->command_wrk = USE_EQUIP;
	    build_obj_list(INVEN_WIELD, e2, NULL, olist_mode);
	}

	/* If we are using the quiver then start on equipment */
	else if (use_quiver){
	    p_ptr->command_wrk = USE_EQUIP;
	    build_obj_list(INVEN_WIELD, e2, NULL, olist_mode);
	}

	/* Use inventory if allowed */
	else if (use_inven){
	    p_ptr->command_wrk = USE_INVEN;
	    build_obj_list(0, i2, NULL, olist_mode);
	}

	/* Use equipment if allowed */
	else if (use_equip){
	    p_ptr->command_wrk = USE_EQUIP;
	    build_obj_list(INVEN_WIELD, e2, NULL, olist_mode);
	}

	/* Use floor if allowed */
	else if (use_floor){
	    p_ptr->command_wrk = USE_FLOOR;
	    build_obj_list(0, f2, floor_list, olist_mode);
	}

	/* Hack -- Use (empty) inventory */
	else {
	    p_ptr->command_wrk = USE_INVEN;
	    build_obj_list(0, i2, NULL, olist_mode);
	}
    }

    /* Clear all current messages */
    msg_flag = FALSE;

    /* Start out in "display" mode */
    if (show_list) {
	/* Save screen */
	screen_save();
    }

    /* Repeat until done */
    while (!done) {
	static bool refresh;
	int ni = 0;
	int ne = 0;

	/* Scan windows */
	for (j = 0; j < ANGBAND_TERM_MAX; j++) {
	    /* Unused */
	    if (!angband_term[j])
		continue;

	    /* Count windows displaying inven */
	    if (op_ptr->window_flag[j] & (PW_INVEN))
		ni++;

	    /* Count windows displaying equip */
	    if (op_ptr->window_flag[j] & (PW_EQUIP))
		ne++;
	}

	/* Toggle if needed */
	if (((p_ptr->command_wrk == USE_EQUIP) && ni && !ne)
	    || ((p_ptr->command_wrk == USE_INVEN) && !ni && ne)) {
	    /* Toggle */
	    toggle_inven_equip();

	    /* Track toggles */
	    toggle = !toggle;
	}

	/* Redraw */
	p_ptr->redraw |= (PR_INVEN | PR_EQUIP);

	/* Redraw windows */
	redraw_stuff(p_ptr);

	/* Change the list if needed */
	if (refresh) {
	    /* Rebuild object list */
	    if (p_ptr->command_wrk == USE_INVEN) 
		build_obj_list(0, i2, NULL, olist_mode);
	    else if (p_ptr->command_wrk == USE_EQUIP) 
		build_obj_list(INVEN_WIELD, e2, NULL, olist_mode);
	    else 
		build_obj_list(0, f2, floor_list, mode);

	    refresh = FALSE;
	}

	/* Show the prompt */
	item_prompt(mode);

	redraw_stuff(p_ptr);

	/* Menu if requested */
	if (show_list) 
	{
	    which = item_menu(cmd, mode);
	    if (which.type == EVT_ESCAPE)
		which.key.code = ESCAPE;
	}

	/* Get a key */
	else which = inkey_ex();

	/* Parse it */
	switch (which.key.code) 
	{
	    case ESCAPE:
	    {
		done = TRUE;
		break;
	    }

    	    case '*':
	    case '?':
	    case ' ':
	    {
		if (!OPT(show_lists)) 
		{
		    /* Save screen */
		    screen_save();
		    
		    /* Flip flag */
		    show_list = TRUE;
		}
		
		refresh = TRUE;
		break;
	    }

	    case '/':
	    {
		/* Toggle to inventory */
		if (use_inven && (p_ptr->command_wrk != USE_INVEN)) 
		{
		    p_ptr->command_wrk = USE_INVEN;
		    refresh = TRUE;
		}

		/* Toggle to equipment */
		else if (use_equip && (p_ptr->command_wrk != USE_EQUIP)) 
		{
		    p_ptr->command_wrk = USE_EQUIP;
		    refresh = TRUE;
		}

		/* No toggle allowed */
		else 
		{
		    bell("Cannot switch item selector!");
		    break;
		}

		/* Need to redraw */
		break;
	    }

	    case '-':
	    {
		/* Paranoia */
		if (!allow_floor) {
		    bell("Cannot select floor!");
		    break;
		}

		/* There is only one item */
		if (OPT(pickup_single) && (floor_num == 1)) 
		{
		    /* Fall through */
		} 
		else 
		{
		    p_ptr->command_wrk = (USE_FLOOR);
		    refresh = TRUE;
		    break;
		}
	    }
	    case '.':
	    {
		/* 
		 * If we are allow to use the floor, select
		 * the top item. -BR-
		 */
		if (allow_floor) {
		    int k;

		    /* Special index */
		    k = 0 - floor_list[0];

		    /* Allow player to "refuse" certain actions */
		    if (!get_item_allow(k, cmdkey, is_harmless)) {
			done = TRUE;
			break;
		    }

		    /* Accept that choice */
		    (*cp) = k;
		    item = TRUE;
		    done = TRUE;
		}

		break;
	    }

	    case '0':
	    case '1':
	    case '2':
	    case '3':
	    case '4':
	    case '5':
	    case '6':
	    case '7':
	    case '8':
	    case '9':
	    {
		/* Look up the tag */
		if (!get_tag(&k, which.key.code, cmd, quiver_tags)) 
		{
		    bell("Illegal object choice (tag)!");
		    break;
		}

		/* Hack -- Validate the item */
		if ((k < INVEN_WIELD) ? !allow_inven : !allow_equip) 
		{
		    bell("Illegal object choice (tag)!");
		    break;
		}

		/* Validate the item */
		if (!get_item_okay(k)) 
		{
		    bell("Illegal object choice (tag)!");
		    break;
		}

		/* Allow player to "refuse" certain actions */
		if (!get_item_allow(k, cmdkey, is_harmless)) 
		{
		    done = TRUE;
		    break;
		}

		/* Accept that choice */
		(*cp) = k;
		item = TRUE;
		done = TRUE;
		break;
	    }

	    case KC_ENTER:
		{
		    /* Choose "default" inventory item */
		    if (p_ptr->command_wrk == USE_INVEN)
		    {
			if (i1 != i2)
			{
			    bell("Illegal object choice (default)!");
			    break;
			}

			k = i1;
		    }

		    /* Choose the "default" slot (0) of the quiver */
		    else if (quiver_tags)
			k = e1;

		    /* Choose "default" equipment item */
		    else if (p_ptr->command_wrk == USE_EQUIP)
		    {
			if (e1 != e2)
			{
			    bell("Illegal object choice (default)!");
			    break;
			}

			k = e1;
		    }

		    /* Choose "default" floor item */
		    else
		    {
			if (f1 != f2)
			{
			    bell("Illegal object choice (default)!");
			    break;
			}

			k = 0 - floor_list[f1];
		    }

		    /* Validate the item */
		    if (!get_item_okay(k))
		    {
			bell("Illegal object choice (default)!");
			break;
		    }

		    /* Allow player to "refuse" certain actions */
		    if (!get_item_allow(k, cmdkey, is_harmless))
		    {
			done = TRUE;
			break;
		    }

		    /* Accept that choice */
		    (*cp) = k;
		    item = TRUE;
		    done = TRUE;
		    break;
		}

	    case '!':
	    {
		/* Try squelched items */
		if (can_squelch) {
		    (*cp) = ALL_SQUELCHED;
		    item = TRUE;
		    done = TRUE;
		    break;
		}

		/* Just fall through */
	    }

	    default:
	    {
		bool verify;

		/* Note verify */
		verify = (isupper((unsigned char) which.key.code) ? TRUE : FALSE);

		/* Lowercase */
		which.key.code = tolower((unsigned char) which.key.code);

		/* Convert letter to inventory index */
		if (p_ptr->command_wrk == USE_INVEN) {
		    k = label_to_inven(which.key.code);

		    if (k < 0) {
			bell("Illegal object choice (inven)!");
			break;
		    }
		}

		/* Convert letter to equipment index */
		else if (p_ptr->command_wrk == USE_EQUIP) {
		    k = label_to_equip(which.key.code);

		    if (k < 0) {
			bell("Illegal object choice (equip)!");
			break;
		    }
		}

		/* Convert letter to floor index */
		else {
		    k = (islower((unsigned char) which.key.code) ? 
			 A2I((unsigned char)which.key.code) : -1);

		    if (k < 0 || k >= floor_num) {
			bell("Illegal object choice (floor)!");
			break;
		    }

		    /* Special index */
		    k = 0 - floor_list[k];
		}

		/* Validate the item */
		if (!get_item_okay(k)) {
		    bell("Illegal object choice (normal)!");
		    break;
		}

		/* Verify the item */
		if (verify && !verify_item("Try", k)) {
		    done = TRUE;
		    break;
		}

		/* Allow player to "refuse" certain actions */
		if (!get_item_allow(k, cmdkey, is_harmless)) {
		    done = TRUE;
		    break;
		}

		/* Accept that choice */
		(*cp) = k;
		item = TRUE;
		done = TRUE;
		break;
	    }
	}
    }

    /* Fix the screen if necessary */
    if (show_list)
    {
	/* Load screen */
	screen_load();

	/* Hack -- Cancel "display" */
	show_list = FALSE;
    }

    /* Kill buttons */
    button_kill('*');
    button_kill('/');
    button_kill('-');
    button_kill('!');

    /* Forget the item_tester_tval restriction */
    item_tester_tval = 0;

    /* Forget the item_tester_hook restriction */
    item_tester_hook = NULL;

    /* Toggle again if needed */
    if (toggle)
	toggle_inven_equip();

    /* Update */
    p_ptr->redraw |= (PR_INVEN | PR_EQUIP);
    redraw_stuff(p_ptr);

    /* Clear the prompt line */
    prt("", 0, 0);

    /* Warning if needed */
    if (oops && str)
	msg(str);

    /* Result */
    return (item);
}
Exemple #14
0
/*
 * Query the dungeon
 */
static void do_cmd_wiz_query(void)
{
	int py = p_ptr->py;
	int px = p_ptr->px;

	int y, x;

	struct keypress cmd;

	u16b mask = 0x00;


	/* Get a "debug command" */
	if (!get_com("Debug Command Query: ", &cmd)) return;

	/* Extract a flag */
	switch (cmd.code)
	{
		case '0': mask = (1 << 0); break;
		case '1': mask = (1 << 1); break;
		case '2': mask = (1 << 2); break;
		case '3': mask = (1 << 3); break;
		case '4': mask = (1 << 4); break;
		case '5': mask = (1 << 5); break;
		case '6': mask = (1 << 6); break;
		case '7': mask = (1 << 7); break;

		case 'm': mask |= (CAVE_MARK); break;
		case 'g': mask |= (CAVE_GLOW); break;
		case 'r': mask |= (CAVE_ROOM); break;
		case 'i': mask |= (CAVE_VAULT); break;
		case 's': mask |= (CAVE_SEEN); break;
		case 'v': mask |= (CAVE_VIEW); break;
		case 't': mask |= (CAVE_WASSEEN); break;
		case 'w': mask |= (CAVE_WALL); break;
	}

	/* Scan map */
	for (y = Term->offset_y; y < Term->offset_y + SCREEN_HGT; y++)
	{
		for (x = Term->offset_x; x < Term->offset_x + SCREEN_WID; x++)
		{
			byte a = TERM_RED;

			if (!cave_in_bounds_fully(cave, y, x)) continue;

			/* Given mask, show only those grids */
			if (mask && !(cave->info[y][x] & mask)) continue;

			/* Given no mask, show unknown grids */
			if (!mask && (cave->info[y][x] & (CAVE_MARK))) continue;

			/* Color */
			if (cave_ispassable(cave, y, x)) a = TERM_YELLOW;

			/* Display player/floors/walls */
			if ((y == py) && (x == px))
				print_rel(L'@', a, y, x);
			else if (cave_ispassable(cave, y, x))
				print_rel(L'*', a, y, x);
			else
				print_rel(L'#', a, y, x);
		}
	}

	Term_redraw();

	/* Get keypress */
	msg("Press any key.");
	inkey_ex();
	message_flush();

	/* Redraw map */
	prt_map();
}
Exemple #15
0
/*
 * Request a "movement" direction (1,2,3,4,6,7,8,9) from the user.
 *
 * Return TRUE if a direction was chosen, otherwise return FALSE.
 *
 * This function should be used for all "repeatable" commands, such as
 * run, walk, open, close, bash, disarm, spike, tunnel, etc, as well
 * as all commands which must reference a grid adjacent to the player,
 * and which may not reference the grid under the player.
 *
 * Directions "5" and "0" are illegal and will not be accepted.
 *
 * This function tracks and uses the "global direction", and uses
 * that as the "desired direction", if it is set.
 */
bool get_rep_dir(int *dp)
{
	int dir = 0;

	ui_event ke;

	/* Initialize */
	(*dp) = 0;

	/* Get a direction */
	while (!dir) {
		/* Paranoia XXX XXX XXX */
		message_flush();

		/* Get first keypress - the first test is to avoid displaying the
		 * prompt for direction if there's already a keypress queued up and
		 * waiting - this just avoids a flickering prompt if there is a "lazy"
		 * movement delay. */
		inkey_scan = SCAN_INSTANT;
		ke = inkey_ex();
		inkey_scan = SCAN_OFF;

		if (ke.type == EVT_NONE ||
			(ke.type == EVT_KBRD && target_dir(ke.key) == 0)) {
			prt("Direction or <click> (Escape to cancel)? ", 0, 0);
			ke = inkey_ex();
		}

		/* Check mouse coordinates */
		if (ke.type == EVT_MOUSE) {
			/* if (ke.button) */
			{
				int y = KEY_GRID_Y(ke);
				int x = KEY_GRID_X(ke);

				/* Calculate approximate angle */
				int angle =
					get_angle_to_target(p_ptr->py, p_ptr->px, y, x, 0);

				/* Convert angle to direction */
				if (angle < 15)
					dir = 6;
				else if (angle < 33)
					dir = 9;
				else if (angle < 59)
					dir = 8;
				else if (angle < 78)
					dir = 7;
				else if (angle < 104)
					dir = 4;
				else if (angle < 123)
					dir = 1;
				else if (angle < 149)
					dir = 2;
				else if (angle < 168)
					dir = 3;
				else
					dir = 6;
			}
		}

		/* Get other keypresses until a direction is chosen. */
		else {
			int keypresses_handled = 0;

			while (ke.type == EVT_KBRD && ke.key.code != 0) {
				int this_dir;

				if (ke.key.code == ESCAPE) {
					/* Clear the prompt */
					prt("", 0, 0);

					return (FALSE);
				}

				/* XXX Ideally show and move the cursor here to indicate the
				 * currently "Pending" direction. XXX */
				this_dir = target_dir(ke.key);

				if (this_dir) {
					dir = dir_transitions[dir][this_dir];
				}

				if (lazymove_delay == 0 || ++keypresses_handled > 1)
					break;

				inkey_scan = lazymove_delay;
				ke = inkey_ex();
			}

			/* 5 is equivalent to "escape" */
			if (dir == 5) {
				/* Clear the prompt */
				prt("", 0, 0);

				return (FALSE);
			}
		}

		/* Oops */
		if (!dir)
			bell("Illegal repeatable direction!");
	}

	/* Clear the prompt */
	prt("", 0, 0);

	/* Save direction */
	(*dp) = dir;

	/* Success */
	return (TRUE);
}
/*
 * Interactive group by.
 * Recognises inscriptions, graphical symbols, lore
 */
static void display_knowledge(const char *title, int *obj_list, int o_count,
			      group_funcs g_funcs, member_funcs o_funcs,
			      const char *otherfields)
{
    /* maximum number of groups to display */
    int max_group = g_funcs.maxnum < o_count ? g_funcs.maxnum : o_count;

    /* This could (should?) be (void **) */
    int *g_list, *g_offset;

    const char **g_names;

    int g_name_len = 8;		/* group name length, minumum is 8 */

    int grp_cnt = 0;		/* total number groups */

    int g_cur = 0, grp_old = -1;	/* group list positions */
    int o_cur = 0;		/* object list positions */
    int g_o_count = 0;		/* object count for group */
    int oid = -1;		/* object identifiers */

    region title_area = { 0, 0, 0, 4 };
    region group_region = { 0, 6, MISSING, -2 };
    region object_region = { MISSING, 6, 0, -2 };

    /* display state variables */
    bool visual_list = FALSE;
    byte attr_top = 0;
    byte char_left = 0;

    int delay = 0;

    menu_type group_menu;
    menu_type object_menu;
    menu_iter object_iter = { NULL, NULL, display_group_member, NULL, NULL };

    /* Panel state */
    /* These are swapped in parallel whenever the actively browsing " */
    /* changes */
    int *active_cursor = &g_cur, *inactive_cursor = &o_cur;
    menu_type *active_menu = &group_menu, *inactive_menu = &object_menu;
    int panel = 0;

    void *swapspace;
    bool do_swap = FALSE;

    bool flag = FALSE;
    bool redraw = TRUE;

    int browser_rows;
    int wid, hgt;
    int i;
    int prev_g = -1;

    int omode = OPT(rogue_like_commands);
    ui_event_data ke;

    /* Get size */
    Term_get_size(&wid, &hgt);
    browser_rows = hgt - 8;

    /* Disable the roguelike commands for the duration */
    OPT(rogue_like_commands) = FALSE;

    if (g_funcs.gcomp)
	sort(obj_list, o_count, sizeof(*obj_list), g_funcs.gcomp);

    /* Sort everything into group order */
    g_list = C_ZNEW(max_group + 1, int);
    g_offset = C_ZNEW(max_group + 1, int);

    for (i = 0; i < o_count; i++) {
	if (prev_g != g_funcs.group(obj_list[i])) {
	    prev_g = g_funcs.group(obj_list[i]);
	    g_offset[grp_cnt] = i;
	    g_list[grp_cnt++] = prev_g;
	}
    }

    g_offset[grp_cnt] = o_count;
    g_list[grp_cnt] = -1;


    /* The compact set of group names, in display order */
    g_names = C_ZNEW(grp_cnt, const char *);

    for (i = 0; i < grp_cnt; i++) {
	int len;
	g_names[i] = g_funcs.name(g_list[i]);
	len = strlen(g_names[i]);
	if (len > g_name_len)
	    g_name_len = len;
    }

    /* Reasonable max group name len */
    if (g_name_len >= 20)
	g_name_len = 20;

    object_region.col = g_name_len + 3;
    group_region.width = g_name_len;


    /* Leave room for the group summary information */
    if (g_funcs.summary)
	object_region.page_rows = -3;


    /* Set up the two menus */
    menu_init(&group_menu, MN_SKIN_SCROLL, menu_find_iter(MN_ITER_STRINGS));
    menu_setpriv(&group_menu, grp_cnt, g_names);
    menu_layout(&group_menu, &group_region);

    menu_init(&object_menu, MN_SKIN_SCROLL, &object_iter);
    menu_setpriv(&object_menu, 0, &o_funcs);
    menu_layout(&object_menu, &object_region);

    o_funcs.is_visual = FALSE;

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


    /* This is the event loop for a multi-region panel */
    /* Panels are -- text panels, two menus, and visual browser */
    /* with "pop-up menu" for lore */
    while ((!flag) && (grp_cnt)) {
	bool recall = FALSE;

	if (redraw) {
	    /* Print the title bits */
	    region_erase(&title_area);
	    prt(format("Knowledge - %s", title), 2, 0);
	    prt("Group", 4, 0);
	    prt("Name", 4, g_name_len + 3);

	    if (otherfields)
		prt(otherfields, 4, 46);


	    /* Print dividers: horizontal and vertical */
	    for (i = 0; i < 79; i++)
		Term_putch(i, 5, TERM_WHITE, '=');

	    for (i = 0; i < browser_rows; i++)
		Term_putch(g_name_len + 1, 6 + i, TERM_WHITE, '|');


	    /* Reset redraw flag */
	    redraw = FALSE;
	}

	if (g_cur != grp_old) {
	    grp_old = g_cur;
	    o_cur = 0;
	    g_o_count = g_offset[g_cur + 1] - g_offset[g_cur];
	    menu_set_filter(&object_menu, obj_list + g_offset[g_cur],
			    g_o_count);
	    group_menu.cursor = g_cur;
	    object_menu.cursor = 0;
	}

	/* HACK ... */
	if (!visual_list) {
	    /* ... The object menu may be browsing the entire group... */
	    o_funcs.is_visual = FALSE;
	    menu_set_filter(&object_menu, obj_list + g_offset[g_cur],
			    g_o_count);
	    object_menu.cursor = o_cur;
	} else {
	    /* ... or just a single element in the group. */
	    o_funcs.is_visual = TRUE;
	    menu_set_filter(&object_menu, obj_list + o_cur + g_offset[g_cur],
			    1);
	    object_menu.cursor = 0;
	}

	oid = obj_list[g_offset[g_cur] + o_cur];

	/* Print prompt */
	{
	    const char *pedit =
		(!o_funcs.
		 xattr) ? "" : (!(attr_idx | char_idx) ? ", 'c' to copy" :
				", 'c', 'p' to paste");
	    const char *xtra =
		o_funcs.xtra_prompt ? o_funcs.xtra_prompt(oid) : "";
	    const char *pvs = "";

	    if (visual_list)
		pvs = ", ENTER to accept";
	    else if (o_funcs.xattr)
		pvs = ", 'v' for visuals";

	    prt(format("<dir>%s%s%s, ESC", pvs, pedit, xtra), hgt - 1, 0);
	}

	if (do_swap) {
	    do_swap = FALSE;
	    swap(active_menu, inactive_menu);
	    swap(active_cursor, inactive_cursor);
	    panel = 1 - panel;
	}

	if (g_funcs.summary && !visual_list) {
	    g_funcs.summary(g_cur, obj_list, g_o_count, g_offset[g_cur],
			    object_menu.active.row +
			    object_menu.active.page_rows, object_region.col);
	}

	menu_refresh(inactive_menu);
	menu_refresh(active_menu);

	handle_stuff();

	if (visual_list) {
	    bigcurs = TRUE;
	    display_visual_list(g_name_len + 3, 7, browser_rows - 1,
				wid - (g_name_len + 3), attr_top, char_left);
	    place_visual_list_cursor(g_name_len + 3, 7, *o_funcs.xattr(oid),
				     *o_funcs.xchar(oid), attr_top, char_left);
	}

	if (delay) {
	    /* Force screen update */
	    Term_fresh();

	    /* Delay */
	    Term_xtra(TERM_XTRA_DELAY, delay);

	    delay = 0;
	}

	ke = inkey_ex();
	if (!visual_list) {
	    ui_event_data ke0 = EVENT_EMPTY;

	    if (ke.type == EVT_MOUSE)
		menu_handle_mouse(active_menu, &ke, &ke0);
	    else if (ke.type == EVT_KBRD)
		menu_handle_keypress(active_menu, &ke, &ke0);

	    if (ke0.type != EVT_NONE)
		ke = ke0;
	}

	/* XXX Do visual mode command if needed */
	if (o_funcs.xattr && o_funcs.xchar) {
	    if (visual_mode_command
		(ke, &visual_list, browser_rows - 1, wid - (g_name_len + 3),
		 &attr_top, &char_left, o_funcs.xattr(oid),
		 (byte *) o_funcs.xchar(oid), g_name_len + 3, 7, &delay))
		continue;
	}

	switch (ke.type) {
	case EVT_KBRD:
	    {
		if (ke.key == 'r' || ke.key == 'R')
		    recall = TRUE;
		else if (o_funcs.xtra_act)
		    o_funcs.xtra_act(ke.key, oid);

		break;
	    }

	case EVT_MOUSE:
	    {
		/* Change active panels */
		if (region_inside(&inactive_menu->boundary, &ke)) {
		    swap(active_menu, inactive_menu);
		    swap(active_cursor, inactive_cursor);
		    panel = 1 - panel;
		}

		continue;
	    }

	case EVT_ESCAPE:
	    {
		if (panel == 1)
		    do_swap = TRUE;
		else
		    flag = TRUE;

		break;
	    }

	case EVT_SELECT:
	    {
		if (panel == 0)
		    do_swap = TRUE;
		else if (panel == 1 && oid >= 0 && o_cur == active_menu->cursor)
		    recall = TRUE;
		break;
	    }

	case EVT_MOVE:
	    {
		*active_cursor = active_menu->cursor;
		break;
	    }

	default:
	    {
		break;
	    }
	}

	/* Recall on screen */
	if (recall) {
	    if (oid >= 0)
		o_funcs.lore(oid);

	    redraw = TRUE;
	}
    }

    /* Restore roguelike option */
    OPT(rogue_like_commands) = omode;

    /* Prompt */
    if (!grp_cnt)
	prt(format("No %s known.", title), 15, 0);

    FREE(g_names);
    FREE(g_offset);
    FREE(g_list);

    screen_load();
}
Exemple #17
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': {
					char namebuf[32] = "";

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

					break;
				}

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

					strnfmt(fname, sizeof fname, "%s.txt",
							player_safe_name(player, false));

					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();
}
Exemple #18
0
/**
 * Hack -- change name
 */
void do_cmd_change_name(void)
{
  ui_event ke;
  
  int col = 0;
  int last_line = 0;
  int top_line = 0;

  const char *p;

  /* Prompt */
  p = "['c' change name, 'f' to file, scroll, or ESC]";
  
  /* Save screen */
  screen_save();

  /* Adjust the buttons */
  button_backup_all();
  button_kill_all();
  button_add("ESC", ESCAPE);
  button_add("Spc", ' ');
  button_add("-", '-');
  button_add("c", 'c');
  button_add("f", 'f');
  button_add("->", ARROW_RIGHT);
  button_add("<-", ARROW_LEFT);
  p_ptr->redraw |= PR_BUTTONS;

  /* Make the array of lines */
  C_WIPE(dumpline, DUMP_MAX_LINES, char_attr_line);
  last_line = make_dump(dumpline, 2);

  /* Forever */
  while (1)
    {
      /* Display the player */
      display_dump(dumpline, top_line, top_line + Term->hgt - 1, col);

      redraw_stuff(p_ptr);

      /* Clear the bottom line */
      prt("", Term->hgt - 1, 0);
      
      /* Prompt */
      Term_putstr(0, Term->hgt - 1, -1, TERM_WHITE, p);
     
      /* Query */
      ke = inkey_ex();
      
      /* Exit */
      if (ke.key.code == ESCAPE) break;
      
      /* Change name */
      if (ke.key.code == 'c')
        {
	  char namebuf[32] = "";

	  if (get_name(namebuf, sizeof namebuf))
	  {
	      /* Set player name */
	      my_strcpy(op_ptr->full_name, namebuf,
			sizeof(op_ptr->full_name));
	      
	      /* Don't change savefile name. */
	      process_player_name(FALSE);
	  }
	  //(void) get_name(namebuf, sizeof namebuf);
	  (void) make_dump(dumpline, 2);
        }
      
      /* File dump */
      else if (ke.key.code == 'f')
	{
	  char ftmp[80];
	  
	  strnfmt(ftmp, sizeof ftmp, "%s.txt", op_ptr->base_name);
	  
	  if (get_string("File name: ", ftmp, 80))
	    {
	      if (ftmp[0] && (ftmp[0] != ' '))
		{
		  if (file_character(ftmp, dumpline, last_line))
		    msg("Character dump failed!");
		  else
		    msg("Character dump successful.");
		}
	    }
	}
      
      /* Scroll down */
      else if (ke.key.code == ARROW_DOWN)
	{
	  if (top_line + Term->hgt - 2 < last_line)
	    top_line++;
	}
      
      /* Page down */
      else if (ke.key.code == ' ')
	{
	  top_line = MIN(last_line - Term->hgt + 2, 
			 top_line + (Term->hgt - 2));
	}
      
      /* Scroll up */
      else if (ke.key.code == ARROW_UP)
	{
	  if (top_line)
	    top_line--;
	}
      
      /* Page up */
      else if (ke.key.code == '-')
	{
	  top_line -= (Term->hgt - 2) / 2;
	  if (top_line < 0) top_line = 0;
	}
      
      /* Scroll left */
      else if (ke.key.code == ARROW_LEFT)
	{
	  if (col)
	    col--;
	}
      
      /* Scroll right */
      else if (ke.key.code == ARROW_RIGHT)
	{
	  if (col < 32)
	    col++;
	}
      
      
      /* Oops */
      else
	{
	  bell(NULL);
	}
      
      /* Flush messages */
      message_flush();
    }

  /* Adjust the buttons */
  button_restore();

  /* Load screen */
  screen_load();
}