Beispiel #1
0
/**
 * Verify something with the user
 *
 * The "prompt" should take the form "Query? "
 *
 * Note that "[y/n]" is appended to the prompt.
 */
bool textui_get_check(const char *prompt)
{
    ui_event ke;

    char buf[80];

    /* Paranoia */
    event_signal(EVENT_MESSAGE_FLUSH);

    /* Hack -- Build a "useful" prompt */
    strnfmt(buf, 78, "%.70s[y/n] ", prompt);

    /* Prompt for it */
    prt(buf, 0, 0);
    ke = inkey_m();

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

    /* Normal negation */
    if (ke.type == EVT_MOUSE) {
        if ((ke.mouse.button != 1) && (ke.mouse.y != 0))
            return (false);
    } else {
        if ((ke.key.code != 'Y') && (ke.key.code != 'y'))
            return (false);
    }

    /* Success */
    return (true);
}
Beispiel #2
0
bool get_com_ex(const char *prompt, ui_event *command)
{
    ui_event ke;

    /* Paranoia XXX XXX XXX */
    event_signal(EVENT_MESSAGE_FLUSH);

    /* Display a prompt */
    prt(prompt, 0, 0);

    /* Get a key */
    ke = inkey_m();

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

    /* Save the command */
    *command = ke;

    /* Done */
    if ((ke.type == EVT_KBRD && ke.key.code != ESCAPE) ||
            (ke.type == EVT_MOUSE))
        return true;
    else
        return false;
}
/**
 * Display the object name of the selected object and allow for full object
 * recall. Returns an event that occurred display.
 *
 * This will only work for a single object on the ground and not a pile. This
 * loop is similar to the monster recall loop in target_set_interactive_aux().
 * The out_val array size needs to match the size that is passed in (since
 * this code was extracted from there).
 *
 * \param o_ptr is the object to describe.
 * \param y is the cave row of the object.
 * \param x is the cave column of the object.
 * \param out_val is the string that holds the name of the object and is
 * returned to the caller.
 * \param s1 is part of the output string.
 * \param s2 is part of the output string.
 * \param s3 is part of the output string.
 * \param coords is part of the output string
 */
static ui_event target_recall_loop_object(object_type *o_ptr, int y, int x,
										  char out_val[TARGET_OUT_VAL_SIZE],
										  const char *s1, const char *s2,
										  const char *s3, char *coords)
{
	bool recall = FALSE;
	ui_event press;

	while (1) {
		if (recall) {
			display_object_recall_interactive(o_ptr);
			press = inkey_m();
		} else {
			char o_name[80];

			/* Obtain an object description */
			object_desc(o_name, sizeof(o_name), o_ptr,
						ODESC_PREFIX | ODESC_FULL);

			/* Describe the object */
			if (player->wizard) {
				strnfmt(out_val, TARGET_OUT_VAL_SIZE,
						"%s%s%s%s, %s (%d:%d, cost=%d, when=%d).", s1, s2, s3,
						o_name, coords, y, x, (int)cave->squares[y][x].cost,
						(int)cave->squares[y][x].when);
			} else {
				strnfmt(out_val, TARGET_OUT_VAL_SIZE,
						"%s%s%s%s, %s.", s1, s2, s3, o_name, coords);
			}

			prt(out_val, 0, 0);
			move_cursor_relative(y, x);
			press = inkey_m();
		}

		if ((press.type == EVT_MOUSE) && (press.mouse.button == 1) &&
			(KEY_GRID_X(press) == x) && (KEY_GRID_Y(press) == y))
			recall = !recall;
		else if ((press.type == EVT_KBRD) && (press.key.code == 'r'))
			recall = !recall;
		else
			break;
	}

	return press;
}
Beispiel #4
0
/*
 * Verify something with the user
 *
 * The "prompt" should take the form "Query? "
 *
 * Note that "[y/n]" is appended to the prompt.
 */
bool get_check(const char *prompt)
{
	//struct keypress ke;
	ui_event ke;

	char buf[80];

	bool repeat = FALSE;
  
	/* Paranoia XXX XXX XXX */
	message_flush();

	/* Hack -- Build a "useful" prompt */
	strnfmt(buf, 78, "%.70s[y/n] ", prompt);

	/* Hack - kill the repeat button */
	if (button_kill('n')) repeat = TRUE;
	
	/* Make some buttons */
	button_add("[y]", 'y');
	button_add("[n]", 'n');
	redraw_stuff(p_ptr);
  
	/* Prompt for it */
	prt(buf, 0, 0);
	ke = inkey_m();

	/* Kill the buttons */
	button_kill('y');
	button_kill('n');

	/* Hack - restore the repeat button */
	if (repeat) button_add("[Rpt]", 'n');
	redraw_stuff(p_ptr);
  
	/* Erase the prompt */
	prt("", 0, 0);

	/* Normal negation */
	if (ke.type == EVT_MOUSE) {
		if ((ke.mouse.button != 1) && (ke.mouse.y != 0)) return (FALSE);
	} else
	if ((ke.key.code != 'Y') && (ke.key.code != 'y')) return (FALSE);

	/* Success */
	return (TRUE);
}
Beispiel #5
0
bool get_com_ex(const char *prompt, ui_event *command)
{
	ui_event ke;

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

	/* Display a prompt */
	prt(prompt, 0, 0);

	/* Get a key */
	ke = inkey_m();

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

	/* Save the command */
	*command = ke;

	/* Done */
	if ((ke.type == EVT_KBRD && ke.key.code != ESCAPE) || (ke.type == EVT_MOUSE))
	  return TRUE;
	return FALSE;
}
Beispiel #6
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)
{
	int py = p_ptr->py;
	int px = p_ptr->px;
	unsigned char cmdkey = cmd_lookup_key(cmd,
			OPT(rogue_like_commands) ? KEYMAP_MODE_ROGUE : KEYMAP_MODE_ORIG);

	//struct keypress which;
	ui_event press;

	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 is_harmless = ((mode & IS_HARMLESS) ? TRUE : FALSE);
	bool quiver_tags = ((mode & QUIVER_TAGS) ? TRUE : FALSE);

	int 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;

	/* Hack - Only shift the command key if it actually needs to be shifted. */
	if (cmdkey < 0x20)
		cmdkey = UN_KTRL(cmdkey);

	/* 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;

	if (mode & SHOW_EMPTY)
		olist_mode |= OLIST_SEMPTY;

	/* 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, 0x0B);

	/* 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) && allow_equip)
			p_ptr->command_wrk = USE_EQUIP;
		else if ((p_ptr->command_wrk == USE_INVEN) && allow_inven)
			p_ptr->command_wrk = USE_INVEN;
		else if ((p_ptr->command_wrk == USE_FLOOR) && allow_floor)
			p_ptr->command_wrk = USE_FLOOR;

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

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

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

		/* Use floor if allowed */
		else if (use_floor && allow_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 < 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);

		/* Viewing inventory */
		if (p_ptr->command_wrk == USE_INVEN)
		{
			int nmode = olist_mode;

			/* Show the quiver counts in certain cases, like the 'i' command */
			if (mode & SHOW_QUIVER)
				nmode |= OLIST_QUIVER;

			/* Redraw if needed */
			if (show_list)
				show_inven(nmode);

			/* 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(p_ptr);

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

		/* if we have a prompt header, show the part that we just built */
		if (pmt) {
			/* 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();
		press = inkey_m();

		/* Parse it */
		if (press.type == EVT_MOUSE) {
			if (press.mouse.button == 2) {
				done = TRUE;
			} else
			if (press.mouse.button == 1) {
				k = -1;
				if (p_ptr->command_wrk == USE_INVEN) {
					if (press.mouse.y == 0) {
						if (use_equip) {
							p_ptr->command_wrk = USE_EQUIP;
						} else
						if (allow_floor) {
							p_ptr->command_wrk = USE_FLOOR;
						}
					} else
					if ((press.mouse.y <= i2-i1+1) ){
					//&& (press.mouse.x > Term->wid - 1 - max_len - ex_width)) {
						//k = label_to_inven(index_to_label(i1+press.mouse.y-1));
						/* get the item index, allowing for skipped indices */
						for (j = i1; j <= i2; j++) {
							if (get_item_okay(j)) {
								if (press.mouse.y == 1) {
									k = j;
									break;
								}
								press.mouse.y--;
							}
						}
					}
				} else
				if (p_ptr->command_wrk == USE_EQUIP) {
					if (press.mouse.y == 0) {
						if (allow_floor) {
							p_ptr->command_wrk = USE_FLOOR;
						} else
						if (use_inven) {
							p_ptr->command_wrk = USE_INVEN;
						}
					} else
					if (press.mouse.y <= e2-e1+1) {
						if (olist_mode & OLIST_SEMPTY) {
							/* If we are showing empties, just set the object (empty objects will just keep the loop going) */
							k = label_to_equip(index_to_label(e1+press.mouse.y-1));
						}
						else {
							/* get the item index, allowing for skipped indices */
							for (j = e1; j <= e2; j++) {
								/* skip the quiver slot which is a blank line in the list */
								if (j == 36) {
									press.mouse.y--;
								} else
									if (get_item_okay(j)) {
										if (press.mouse.y == 1) {
											k = j;
											break;
										}
										press.mouse.y--;
									}
							}
						}
					}
				} else
				if (p_ptr->command_wrk == USE_FLOOR) {
					if (press.mouse.y == 0) {
						if (use_inven) {
							p_ptr->command_wrk = USE_INVEN;
						} else
						if (use_equip) {
							p_ptr->command_wrk = USE_EQUIP;
						}
					} else
					if ((press.mouse.y <= floor_num) && (press.mouse.y >= 1)) {
						/* Special index */
						k = 0 - floor_list[press.mouse.y-1];
						/* get the item index, allowing for skipped indices */
						for (j = f1; j <= f2; j++) {
							if (get_item_okay(0 - floor_list[j])) {
								if (press.mouse.y == 1) {
									k = 0 - floor_list[j];
									break;
								}
								press.mouse.y--;
							}
						}
						/* check the bounds the item number */
						if (k < 0) {
							/* Allow player to "refuse" certain actions */
							if (!get_item_allow(k, cmdkey, cmd, is_harmless))
							{
								done = TRUE;
							}

							/* Accept that choice */
							(*cp) = k;
							item = TRUE;
							done = TRUE;
						} else {
							/* set k to a value that will be invalid below */
							k = -1;
						}
					}
				}
				if (k >= 0) {
					/* Validate the item */
					if (!get_item_okay(k)) {
						bell("Illegal object choice (normal)!");
					}

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

					/* Accept that choice */
					(*cp) = k;
					item = TRUE;
					done = TRUE;
				} else
				if (press.mouse.y == 0) {
					/* Hack -- Fix screen */
					if (show_list) {
						/* Load screen */
						screen_load();

						/* Save screen */
						screen_save();
					}
				}
			}
		} else
		//switch (which.code)
		switch (press.key.code)
		{
			case ESCAPE:
			case ' ':
			{
				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, cmd, 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, cmd, 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.code, cmd, quiver_tags))
				if (!get_tag(&k, press.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, cmd, 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, cmd, 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.code) ? TRUE : FALSE);
				verify = (isupper((unsigned char)press.key.code) ? TRUE : FALSE);

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

				/* Convert letter to inventory index */
				if (p_ptr->command_wrk == USE_INVEN)
				{
					//k = label_to_inven(which.code);
					k = label_to_inven(press.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.code);
					k = label_to_equip(press.key.code);

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

				/* Convert letter to floor index */
				else
				{
					//k = (islower((unsigned char)which.code) ? A2I((unsigned char)which.code) : -1);
					k = (islower((unsigned char)press.key.code) ? A2I((unsigned char)press.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, cmd, 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(p_ptr);
 
	/* 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("%s", str);

	/* Result */
	return (item);
}
Beispiel #7
0
/* 
 * Run multiple menus at the same time.
 *
 * If popup is true, the screen is saved before the menu is drawn, and
 * restored afterwards. Each time a popup menu is redrawn, it resets the
 * screen before redrawing.
 */
ui_event menu_select_multi(int *active, menu_type **menus, int num, int notify, bool popup)
{
	ui_event in = EVENT_EMPTY;
	ui_event out = EVENT_EMPTY;
	bool no_act = FALSE;
	int i;

	assert(menus != NULL);
	assert(active != NULL);
	assert(num > 1);
	assert(*active < num);
	for (i = 0; i < num; i++) {
		assert(menus[i]->active.width != 0 && menus[i]->active.page_rows != 0);
	}

	notify |= (EVT_SELECT | EVT_ESCAPE);
	if (popup) {
		screen_save();
		button_backup_all(TRUE);
	}

	/* Stop on first unhandled event */
	//while (!(in.type & notify))
	//while (!(in & notify))
	while (!(in == EVT_SELECT) && !(in == EVT_ESCAPE))
	{
		out = EVENT_EMPTY;

		if (popup) {
			button_restore();
			screen_load();
			screen_save();
			button_backup_all(TRUE);
		}
		no_act = (menus[*active]->flags & MN_NO_ACTION) ? TRUE : FALSE;

		/* refresh all of the menus except the active one */
		for (i = 0; i < num; i++) {
			if (i != *active) {
				menu_refresh(menus[i], FALSE);
			}
		}
		/* refresh the active menu */
		menu_refresh(menus[*active], FALSE);

		//in = inkey_ex();
		in = inkey_m();

		/* Handle mouse & keyboard commands */
		//if (in.type == EVT_MOUSE) {
		if (in & 0x80) {
			//if (!no_act && menu_handle_action(menu, &in)) {
			//	continue;
			//}
			//menu_handle_mouse(menu, &in, &out);
			if (in == EVT_RESIZE) {
				/* resize all of the menus */
				for (i = 0; i < num; i++) {
					menu_calc_size(menus[i]);
					if (menus[i]->row_funcs->resize)
						menus[i]->row_funcs->resize(menus[i]);
				}
			} else {
				int mx,my;
				char p;

				/* check which menu the click was in */
				Term_peekmousepress(&p, &mx, &my);
				if (!rect_region_inside(&(menus[*active]->active), my, mx) ) {
					for (i = 0; i < num; i++) {
						if (rect_region_inside(&(menus[i]->active), my, mx)) {
							no_act = (menus[i]->flags & MN_NO_ACTION) ? TRUE : FALSE;
							*active = i;
						}
					}
				}

				/* handle the click in the active one */
				if (!no_act && menu_handle_action(menus[*active], &in)) {
					continue;
				}
				menu_handle_mouse(menus[*active], &in, &out);
			}
		//} else if (in.type == EVT_KBRD) {
		} else {
			/* see if we need to move between menus */
			/* handle the key press */
			if (!no_act && menus[*active]->cmd_keys &&
					//strchr(menu->cmd_keys, (char)in.key.code) &&
					strchr(menus[*active]->cmd_keys, (char)in) &&
					menu_handle_action(menus[*active], &in))
			{
				continue;
			}

			menu_handle_keypress(menus[*active], &in, &out);
		}// else if (in.type == EVT_RESIZE) {
		//	menu_calc_size(menu);
		//	if (menu->row_funcs->resize)
		//		menu->row_funcs->resize(menu);
		//}

		/* XXX should redraw menu here if cursor has moved */

		/* if we requested it, send move events out */
		if ((out == EVT_SELECT) && (menus[*active]->flags & MN_HANDLE_MOVE)
			&& !no_act && menu_handle_action(menus[*active], &out))
			continue;

		/* If we've selected an item, then send that event out */
		//if (out.type == EVT_SELECT && !no_act && menu_handle_action(menu, &out))
		if ((out == EVT_SELECT) && !no_act && menu_handle_action(menus[*active], &out))
			continue;

		/* needed because EVT_* types are composed of multiple flags where in
		 * angband they are one flag of an int, so the (notify & out) and
		 * (!(in & notify)) is only true for particular EVT_* values */
		/* Notify about the outgoing type */
		//if (notify & out.type) {
		//if (notify & out) {
		if ((out == EVT_SELECT) || (out == EVT_ESCAPE)) {
			if (popup) {
				button_restore();
				screen_load();
			}
			return out;
		}
	}

	if (popup) {
		button_restore();
		screen_load();
	}
	return in;
}
Beispiel #8
0
/* 
 * Run a menu.
 *
 * If popup is true, the screen is saved before the menu is drawn, and
 * restored afterwards. Each time a popup menu is redrawn, it resets the
 * screen before redrawing.
 */
ui_event menu_select(menu_type *menu, int notify, bool popup)
{
	ui_event in = EVENT_EMPTY;
	ui_event out = EVENT_EMPTY;
	bool no_act = (menu->flags & MN_NO_ACTION) ? TRUE : FALSE;

	assert(menu->active.width != 0 && menu->active.page_rows != 0);

	notify |= (EVT_SELECT | EVT_ESCAPE);
	if (popup) {
		screen_save();
		button_backup_all(TRUE);
	}

	/* Stop on first unhandled event */
	//while (!(in.type & notify))
	//while (!(in & notify))
	while (!(in == EVT_SELECT) && !(in == EVT_ESCAPE))
	{
		out = EVENT_EMPTY;

		menu_refresh(menu, popup);
		//in = inkey_ex();
		in = inkey_m();

		/* Handle mouse & keyboard commands */
		//if (in.type == EVT_MOUSE) {
		if (in & 0x80) {
			//if (!no_act && menu_handle_action(menu, &in)) {
			//	continue;
			//}
			//menu_handle_mouse(menu, &in, &out);
			if (in == EVT_RESIZE) {
				menu_calc_size(menu);
				if (menu->row_funcs->resize)
					menu->row_funcs->resize(menu);
			} else {
				if (!no_act && menu_handle_action(menu, &in)) {
					continue;
				}
				menu_handle_mouse(menu, &in, &out);
			}
		//} else if (in.type == EVT_KBRD) {
		} else {
			if (!no_act && menu->cmd_keys &&
					//strchr(menu->cmd_keys, (char)in.key.code) &&
					strchr(menu->cmd_keys, (char)in) &&
					menu_handle_action(menu, &in))
				continue;

			menu_handle_keypress(menu, &in, &out);
		}// else if (in.type == EVT_RESIZE) {
		//	menu_calc_size(menu);
		//	if (menu->row_funcs->resize)
		//		menu->row_funcs->resize(menu);
		//}

		/* XXX should redraw menu here if cursor has moved */

		/* if we requested it, send move events out */
		if ((out == EVT_SELECT) && (menu->flags & MN_HANDLE_MOVE)
			&& !no_act && menu_handle_action(menu, &out))
			continue;

		/* If we've selected an item, then send that event out */
		//if (out.type == EVT_SELECT && !no_act && menu_handle_action(menu, &out))
		if ((out == EVT_SELECT) && !no_act && menu_handle_action(menu, &out))
			continue;

		/* needed because EVT_* types are composed of multiple flags where in
		 * angband they are one flag of an int, so the (notify & out) and
		 * (!(in & notify)) is only true for particular EVT_* values */
		/* Notify about the outgoing type */
		//if (notify & out.type) {
		//if (notify & out) {
		if ((out == EVT_SELECT) || (out == EVT_ESCAPE)) {
			if (popup) {
				button_restore();
				screen_load();
			}
			return out;
		}
	}

	if (popup) {
		button_restore();
		screen_load();
	}
	return in;
}
Beispiel #9
0
//static struct keypress target_set_interactive_aux(int y, int x, int mode)
static ui_event target_set_interactive_aux(int y, int x, int mode)
{
	s16b this_o_idx = 0, next_o_idx = 0;

	const char *s1, *s2, *s3;

	bool boring;

	int floor_list[MAX_FLOOR_STACK];
	int floor_num;

	//struct keypress query;
	ui_event press;

	char out_val[256];

	char coords[20];

	const char *name;

	/* Describe the square location */
	coords_desc(coords, sizeof(coords), y, x);

	/* Repeat forever */
	while (1)
	{
		/* Paranoia */
		press.type = EVT_KBRD;
		press.key.code = ' ';
		press.key.mods = 0;

		/* Assume boring */
		boring = TRUE;

		/* Default */
		s1 = "You see ";
		s2 = "";
		s3 = "";


		/* The player */
		if (cave->m_idx[y][x] < 0)
		{
			/* Description */
			s1 = "You are ";

			/* Preposition */
			s2 = "on ";
		}

		/* Hallucination messes things up */
		if (p_ptr->timed[TMD_IMAGE])
		{
			const char *name = "something strange";

			/* Display a message */
			if (p_ptr->wizard)
				strnfmt(out_val, sizeof(out_val), "%s%s%s%s, %s (%d:%d).",
						s1, s2, s3, name, coords, y, x);
			else
				strnfmt(out_val, sizeof(out_val), "%s%s%s%s, %s.",
						s1, s2, s3, name, coords);

			prt(out_val, 0, 0);
			move_cursor_relative(y, x);
			//input = inkey_m();
			//if (
			press.key = inkey();

			/* Stop on everything but "return" */
			if (press.key.code == KC_ENTER)
				continue;

			return press;
		}

		/* Actual monsters */
		if (cave->m_idx[y][x] > 0)
		{
			monster_type *m_ptr = cave_monster_at(cave, y, x);
			const monster_lore *l_ptr = get_lore(m_ptr->race);

			/* Visible */
			if (m_ptr->ml && !m_ptr->unaware)
			{
				bool recall = FALSE;

				char m_name[80];

				/* Not boring */
				boring = FALSE;

				/* Get the monster name ("a kobold") */
				monster_desc(m_name, sizeof(m_name), m_ptr, MDESC_IND2);

				/* Hack -- track this monster race */
				monster_race_track(m_ptr->race);

				/* Hack -- health bar for this monster */
				health_track(p_ptr, m_ptr);

				/* Hack -- handle stuff */
				handle_stuff(p_ptr);

				/* Interact */
				while (1)
				{
					/* Recall */
					if (recall)
					{
						/* Save screen */
						screen_save();

						/* Recall on screen */
						screen_roff(m_ptr->race, l_ptr);

						/* Command */
						press = inkey_m();

						/* Load screen */
						screen_load();
					}

					/* Normal */
					else
					{
						char buf[80];

						/* Describe the monster */
						look_mon_desc(buf, sizeof(buf), cave->m_idx[y][x]);

						/* Describe, and prompt for recall */
						if (p_ptr->wizard)
						{
							strnfmt(out_val, sizeof(out_val),
									"%s%s%s%s (%s), %s (%d:%d).",
									s1, s2, s3, m_name, buf, coords, y, x);
						}
						else
						{
							strnfmt(out_val, sizeof(out_val),
									"%s%s%s%s (%s), %s.",
									s1, s2, s3, m_name, buf, coords);
						}

						prt(out_val, 0, 0);

						/* Place cursor */
						move_cursor_relative(y, x);

						/* Command */
						press = inkey_m();
					}

					/* Normal commands */
				  if ((press.type == EVT_MOUSE) && (press.mouse.button == 1) && (KEY_GRID_X(press) == x) && (KEY_GRID_Y(press) == y))
						recall = !recall;
					else
					if ((press.type == EVT_KBRD) && (press.key.code == 'r'))
						recall = !recall;
					else
						break;
				}

				if (press.type == EVT_MOUSE) {
					/* Stop on right click */
					if (press.mouse.button == 2)
						break;

					/* Sometimes stop at "space" key */
					if (press.mouse.button && !(mode & (TARGET_LOOK))) break;
				} else {
					/* Stop on everything but "return"/"space" */
					if (press.key.code != KC_ENTER && press.key.code != ' ')
						break;

					/* Sometimes stop at "space" key */
					if ((press.key.code == ' ') && !(mode & (TARGET_LOOK))) break;
				}

				/* Take account of gender */
				if (rf_has(m_ptr->race->flags, RF_FEMALE)) s1 = "She is ";
				else if (rf_has(m_ptr->race->flags, RF_MALE)) s1 = "He is ";
				else s1 = "It is ";

				/* Use a verb */
				s2 = "carrying ";

				/* Scan all objects being carried */
				for (this_o_idx = m_ptr->hold_o_idx; this_o_idx; this_o_idx = next_o_idx)
				{
					char o_name[80];

					object_type *o_ptr;

					/* Get the object */
					o_ptr = object_byid(this_o_idx);

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

					/* Obtain an object description */
					object_desc(o_name, sizeof(o_name), o_ptr,
								ODESC_PREFIX | ODESC_FULL);

					/* Describe the object */
					if (p_ptr->wizard)
					{
						strnfmt(out_val, sizeof(out_val),
								"%s%s%s%s, %s (%d:%d).",
								s1, s2, s3, o_name, coords, y, x);
					}
					/* Disabled since monsters now carry their drops
					else
					{
						strnfmt(out_val, sizeof(out_val),
								"%s%s%s%s, %s.", s1, s2, s3, o_name, coords);
					} */

					prt(out_val, 0, 0);
					move_cursor_relative(y, x);
					press = inkey_m();

					if (press.type == EVT_MOUSE) {
						/* Stop on right click */
						if (press.mouse.button == 2)
							break;

						/* Sometimes stop at "space" key */
						if (press.mouse.button && !(mode & (TARGET_LOOK))) break;
					} else {
						/* Stop on everything but "return"/"space" */
						if ((press.key.code != KC_ENTER) && (press.key.code != ' ')) break;

						/* Sometimes stop at "space" key */
						if ((press.key.code == ' ') && !(mode & (TARGET_LOOK))) break;
					}

					/* Change the intro */
					s2 = "also carrying ";
				}

				/* Double break */
				if (this_o_idx) break;

				/* Use a preposition */
				s2 = "on ";
			}
		}

		/* Assume not floored */
		floor_num = scan_floor(floor_list, N_ELEMENTS(floor_list), y, x, 0x0A);

		/* Scan all marked objects in the grid */
		if ((floor_num > 0) &&
		    (!(p_ptr->timed[TMD_BLIND]) || (y == p_ptr->py && x == p_ptr->px)))
		{
			/* Not boring */
			boring = FALSE;

			track_object(-floor_list[0]);
			handle_stuff(p_ptr);

			/* If there is more than one item... */
			if (floor_num > 1) while (1)
			{
				/* Describe the pile */
				if (p_ptr->wizard)
				{
					strnfmt(out_val, sizeof(out_val),
							"%s%s%sa pile of %d objects, %s (%d:%d).",
							s1, s2, s3, floor_num, coords, y, x);
				}
				else
				{
					strnfmt(out_val, sizeof(out_val),
							"%s%s%sa pile of %d objects, %s.",
							s1, s2, s3, floor_num, coords);
				}

				prt(out_val, 0, 0);
				move_cursor_relative(y, x);
				press = inkey_m();

				/* Display objects */
				if (((press.type == EVT_MOUSE) && (press.mouse.button == 1) && (KEY_GRID_X(press) == x) && (KEY_GRID_Y(press) == y))
						|| ((press.type == EVT_KBRD) && (press.key.code == 'r')))
				{
					int rdone = 0;
					int pos;
					while (!rdone)
					{
						/* Save screen */
						screen_save();

						/* Display */
						show_floor(floor_list, floor_num, (OLIST_WEIGHT | OLIST_GOLD));

						/* Describe the pile */
						prt(out_val, 0, 0);
						press = inkey_m();

						/* Load screen */
						screen_load();

						if (press.type == EVT_MOUSE) {
							pos = press.mouse.y-1;
						} else {
							pos = press.key.code - 'a';
						}
						if (0 <= pos && pos < floor_num)
						{
							track_object(-floor_list[pos]);
							handle_stuff(p_ptr);
							continue;
						}
						rdone = 1;
					}

					/* Now that the user's done with the display loop, let's */
					/* the outer loop over again */
					continue;
				}

				/* Done */
				break;
			}
			/* Only one object to display */
			else
			{

				char o_name[80];

				/* Get the single object in the list */
				object_type *o_ptr = object_byid(floor_list[0]);

				/* Not boring */
				boring = FALSE;

				/* Obtain an object description */
				object_desc(o_name, sizeof(o_name), o_ptr,
							ODESC_PREFIX | ODESC_FULL);

				/* Describe the object */
				if (p_ptr->wizard)
				{
					strnfmt(out_val, sizeof(out_val),
							"%s%s%s%s, %s (%d:%d).",
							s1, s2, s3, o_name, coords, y, x);
				}
				else
				{
					strnfmt(out_val, sizeof(out_val),
							"%s%s%s%s, %s.", s1, s2, s3, o_name, coords);
				}

				prt(out_val, 0, 0);
				move_cursor_relative(y, x);
				press = inkey_m();

				/* Stop on everything but "return"/"space" */
				if ((press.key.code != KC_ENTER) && (press.key.code != ' ')) break;

				/* Sometimes stop at "space" key */
				if ((press.key.code == ' ') && !(mode & (TARGET_LOOK))) break;

				/* Change the intro */
				s1 = "It is ";

				/* Plurals */
				if (o_ptr->number != 1) s1 = "They are ";

				/* Preposition */
				s2 = "on ";
			}

		}

		/* Double break */
		if (this_o_idx) break;

		name = cave_apparent_name(cave, p_ptr, y, x);

		/* Terrain feature if needed */
		if (boring || cave_isinteresting(cave, y, x))
		{
			/* Hack -- handle unknown grids */

			/* Pick a prefix */
			if (*s2 && cave_isdoor(cave, y, x)) s2 = "in ";

			/* Pick proper indefinite article */
			s3 = (is_a_vowel(name[0])) ? "an " : "a ";

			/* Hack -- special introduction for store doors */
			if (cave_isshop(cave, y, x))
			{
				s3 = "the entrance to the ";
			}

			/* Display a message */
			if (p_ptr->wizard)
			{
				strnfmt(out_val, sizeof(out_val),
						"%s%s%s%s, %s (%d:%d).", s1, s2, s3, name, coords, y, x);
			}
			else
			{
				strnfmt(out_val, sizeof(out_val),
						"%s%s%s%s, %s.", s1, s2, s3, name, coords);
			}

			prt(out_val, 0, 0);
			move_cursor_relative(y, x);
			press = inkey_m();

			if (press.type == EVT_MOUSE) {
				/* Stop on right click */
				if (press.mouse.button == 2)
					break;
			} else {
				/* Stop on everything but "return"/"space" */
				if ((press.key.code != KC_ENTER) && (press.key.code != ' ')) break;
			}
		}

		/* Stop on everything but "return" */
		if (press.type == EVT_MOUSE) {
				/* Stop on right click */
				if (press.mouse.button != 2)
					break;
		} else {
    			if (press.key.code != KC_ENTER) break;
		}
	}

	/* Keep going */
	return (press);
}
/**
 * Examine a grid, return a keypress.
 *
 * The "mode" argument contains the "TARGET_LOOK" bit flag, which
 * indicates that the "space" key should scan through the contents
 * of the grid, instead of simply returning immediately.  This lets
 * the "look" command get complete information, without making the
 * "target" command annoying.
 *
 * The "info" argument contains the "commands" which should be shown
 * inside the "[xxx]" text.  This string must never be empty, or grids
 * containing monsters will be displayed with an extra comma.
 *
 * Note that if a monster is in the grid, we update both the monster
 * recall info and the health bar info to track that monster.
 *
 * This function correctly handles multiple objects per grid, and objects
 * and terrain features in the same grid, though the latter never happens.
 *
 * This function must handle blindness/hallucination.
 */
static ui_event target_set_interactive_aux(int y, int x, int mode)
{
	struct object *obj = NULL;

	const char *s1, *s2, *s3;

	bool boring;

	int floor_max = z_info->floor_size;
	struct object **floor_list = mem_zalloc(floor_max * sizeof(*floor_list));
	int floor_num;

	ui_event press;

	char out_val[TARGET_OUT_VAL_SIZE];

	char coords[20];

	const char *name;

	/* Describe the square location */
	coords_desc(coords, sizeof(coords), y, x);

	/* Repeat forever */
	while (1) {
		/* Paranoia */
		press.type = EVT_KBRD;
		press.key.code = ' ';
		press.key.mods = 0;

		/* Assume boring */
		boring = TRUE;

		/* Default */
		s1 = "You see ";
		s2 = "";
		s3 = "";


		/* The player */
		if (cave->squares[y][x].mon < 0) {
			/* Description */
			s1 = "You are ";

			/* Preposition */
			s2 = "on ";
		}

		/* Hallucination messes things up */
		if (player->timed[TMD_IMAGE]) {
			const char *name = "something strange";

			/* Display a message */
			if (player->wizard)
				strnfmt(out_val, sizeof(out_val),
						"%s%s%s%s, %s (%d:%d, cost=%d, when=%d).", s1, s2, s3,
						name, coords, y, x, (int)cave->squares[y][x].cost,
						(int)cave->squares[y][x].when);
			else
				strnfmt(out_val, sizeof(out_val), "%s%s%s%s, %s.",
						s1, s2, s3, name, coords);

			prt(out_val, 0, 0);
			move_cursor_relative(y, x);

			press.key = inkey();

			/* Stop on everything but "return" */
			if (press.key.code == KC_ENTER)
				continue;

			mem_free(floor_list);
			return press;
		}

		/* Actual monsters */
		if (cave->squares[y][x].mon > 0) {
			monster_type *m_ptr = square_monster(cave, y, x);
			const monster_lore *l_ptr = get_lore(m_ptr->race);

			/* Visible */
			if (mflag_has(m_ptr->mflag, MFLAG_VISIBLE) &&
				!mflag_has(m_ptr->mflag, MFLAG_UNAWARE)) {
				bool recall = FALSE;

				char m_name[80];

				/* Not boring */
				boring = FALSE;

				/* Get the monster name ("a kobold") */
				monster_desc(m_name, sizeof(m_name), m_ptr, MDESC_IND_VIS);

				/* Hack -- track this monster race */
				monster_race_track(player->upkeep, m_ptr->race);

				/* Hack -- health bar for this monster */
				health_track(player->upkeep, m_ptr);

				/* Hack -- handle stuff */
				handle_stuff(player);

				/* Interact */
				while (1) {
					/* Recall or target */
					if (recall) {
						lore_show_interactive(m_ptr->race, l_ptr);
						press = inkey_m();
					} else {
						char buf[80];

						/* Describe the monster */
						look_mon_desc(buf, sizeof(buf),
									  cave->squares[y][x].mon);

						/* Describe, and prompt for recall */
						if (player->wizard) {
							strnfmt(out_val, sizeof(out_val),
									"%s%s%s%s (%s), %s (%d:%d, cost=%d, when=%d).",
									s1, s2, s3, m_name, buf, coords, y, x,
									(int)cave->squares[y][x].cost,
									(int)cave->squares[y][x].when);
						} else {
							strnfmt(out_val, sizeof(out_val),
									"%s%s%s%s (%s), %s.",
									s1, s2, s3, m_name, buf, coords);
						}

						prt(out_val, 0, 0);

						/* Place cursor */
						move_cursor_relative(y, x);

						/* Command */
						press = inkey_m();
					}

					/* Normal commands */
					if ((press.type == EVT_MOUSE) && (press.mouse.button == 1)
						&& (KEY_GRID_X(press) == x) && (KEY_GRID_Y(press) == y))
						recall = !recall;
					else
					if ((press.type == EVT_KBRD) && (press.key.code == 'r'))
						recall = !recall;
					else
						break;
				}

				if (press.type == EVT_MOUSE) {
					/* Stop on right click */
					if (press.mouse.button == 2)
						break;

					/* Sometimes stop at "space" key */
					if (press.mouse.button && !(mode & (TARGET_LOOK))) break;
				} else {
					/* Stop on everything but "return"/"space" */
					if (press.key.code != KC_ENTER && press.key.code != ' ')
						break;

					/* Sometimes stop at "space" key */
					if ((press.key.code == ' ') && !(mode & (TARGET_LOOK)))
						break;
				}

				/* Take account of gender */
				if (rf_has(m_ptr->race->flags, RF_FEMALE)) s1 = "She is ";
				else if (rf_has(m_ptr->race->flags, RF_MALE)) s1 = "He is ";
				else s1 = "It is ";

				/* Use a verb */
				s2 = "carrying ";

				/* Scan all objects being carried */
				for (obj = m_ptr->held_obj; obj; obj = obj->next) {
					char o_name[80];

					/* Obtain an object description */
					object_desc(o_name, sizeof(o_name), obj,
								ODESC_PREFIX | ODESC_FULL);

					/* Describe the object */
					if (player->wizard) {
						strnfmt(out_val, sizeof(out_val),
								"%s%s%s%s, %s (%d:%d, cost=%d, when=%d).",
								s1, s2, s3, o_name, coords, y, x,
								(int)cave->squares[y][x].cost,
								(int)cave->squares[y][x].when);
					}

					prt(out_val, 0, 0);
					move_cursor_relative(y, x);
					press = inkey_m();

					if (press.type == EVT_MOUSE) {
						/* Stop on right click */
						if (press.mouse.button == 2)
							break;

						/* Sometimes stop at "space" key */
						if (press.mouse.button && !(mode & (TARGET_LOOK)))
							break;
					} else {
						/* Stop on everything but "return"/"space" */
						if ((press.key.code != KC_ENTER) &&
							(press.key.code != ' '))
							break;

						/* Sometimes stop at "space" key */
						if ((press.key.code == ' ') && !(mode & (TARGET_LOOK)))
							break;
					}

					/* Change the intro */
					s2 = "also carrying ";
				}

				/* Double break */
				if (obj) break;

				/* Use a preposition */
				s2 = "on ";
			}
		}

		/* A trap */
		if (square_isvisibletrap(cave, y, x)) {
			struct trap *trap = cave->squares[y][x].trap;

			/* Not boring */
			boring = FALSE;

			/* Interact */
			while (1) {
				/* Change the intro */
				if (cave->squares[y][x].mon < 0) {
					s1 = "You are ";
					s2 = "on ";
				} else {
					s1 = "You see ";
					s2 = "";
				}

				/* Pick proper indefinite article */
				s3 = (is_a_vowel(trap->kind->desc[0])) ? "an " : "a ";

				/* Describe, and prompt for recall */
				if (player->wizard) {
					strnfmt(out_val, sizeof(out_val),
							"%s%s%s%s, %s (%d:%d, cost=%d, when=%d).", s1, s2,
							s3, trap->kind->name, coords, y, x,
							(int)cave->squares[y][x].cost,
							(int)cave->squares[y][x].when);
				} else {
					strnfmt(out_val, sizeof(out_val), "%s%s%s%s, %s.", 
							s1, s2, s3, trap->kind->desc, coords);
				}

				prt(out_val, 0, 0);

				/* Place cursor */
				move_cursor_relative(y, x);

				/* Command */
				press = inkey_m();
		
				/* Stop on everything but "return"/"space" */
				if ((press.key.code != KC_ENTER) && (press.key.code != ' '))
					break;
		
				/* Sometimes stop at "space" key */
				if ((press.key.code == ' ') && !(mode & (TARGET_LOOK)))
					break;
			}
		}
	
		/* Double break */
		if (square_isvisibletrap(cave, y, x))
			break;
	
		/* Assume not floored */
		floor_num = scan_floor(floor_list, floor_max, y, x, 0x0A, NULL);

		/* Scan all marked objects in the grid */
		if ((floor_num > 0) &&
		    (!(player->timed[TMD_BLIND]) ||
			 (y == player->py && x == player->px))) {
			/* Not boring */
			boring = FALSE;

			track_object(player->upkeep, floor_list[0]);
			handle_stuff(player);

			/* If there is more than one item... */
			if (floor_num > 1)
				while (1) {
					/* Describe the pile */
					if (player->wizard) {
						strnfmt(out_val, sizeof(out_val),
								"%s%s%sa pile of %d objects, %s (%d:%d, cost=%d, when=%d).",
								s1, s2, s3, floor_num, coords, y, x,
								(int)cave->squares[y][x].cost,
								(int)cave->squares[y][x].when);
					} else {
						strnfmt(out_val, sizeof(out_val),
								"%s%s%sa pile of %d objects, %s.",
								s1, s2, s3, floor_num, coords);
					}

					prt(out_val, 0, 0);
					move_cursor_relative(y, x);
					press = inkey_m();

					/* Display objects */
					if (((press.type == EVT_MOUSE) && (press.mouse.button == 1)
						 && (KEY_GRID_X(press) == x) && 
						 (KEY_GRID_Y(press) == y)) ||
						((press.type == EVT_KBRD) && (press.key.code == 'r'))) {
						int rdone = 0;
						int pos;
						while (!rdone) {
							/* Save screen */
							screen_save();

							/* Display */
							show_floor(floor_list, floor_num,
									   (OLIST_WEIGHT | OLIST_GOLD), NULL);

							/* Describe the pile */
							prt(out_val, 0, 0);
							press = inkey_m();

							/* Load screen */
							screen_load();

							if (press.type == EVT_MOUSE) {
								pos = press.mouse.y-1;
							} else {
								pos = press.key.code - 'a';
							}
							if (0 <= pos && pos < floor_num) {
								track_object(player->upkeep, floor_list[pos]);
								handle_stuff(player);
								continue;
							}
							rdone = 1;
						}

						/* Now that the user's done with the display loop,
						 * let's do the outer loop over again */
						continue;
					}

					/* Done */
					break;
				}
			/* Only one object to display */
			else {
				/* Get the single object in the list */
				struct object *obj = floor_list[0];

				/* Allow user to recall an object */
				press = target_recall_loop_object(obj, y, x, out_val, s1, s2,
												  s3, coords);

				/* Stop on everything but "return"/"space" */
				if ((press.key.code != KC_ENTER) && (press.key.code != ' '))
					break;

				/* Sometimes stop at "space" key */
				if ((press.key.code == ' ') && !(mode & (TARGET_LOOK))) break;

				/* Plurals */
				s1 = VERB_AGREEMENT(obj->number, "It is ", "They are ");

				/* Preposition */
				s2 = "on ";
			}

		}

		/* Double break */
		if (obj) break;

		name = square_apparent_name(cave, player, y, x);

		/* Terrain feature if needed */
		if (boring || square_isinteresting(cave, y, x)) {
			/* Hack -- handle unknown grids */

			/* Pick a prefix */
			if (*s2 && square_isdoor(cave, y, x)) s2 = "in ";

			/* Pick proper indefinite article */
			s3 = (is_a_vowel(name[0])) ? "an " : "a ";

			/* Hack -- special introduction for store doors */
			if (square_isshop(cave, y, x))
				s3 = "the entrance to the ";

			/* Display a message */
			if (player->wizard) {
				strnfmt(out_val, sizeof(out_val),
						"%s%s%s%s, %s (%d:%d, cost=%d, when=%d).", s1, s2, s3,
						name, coords, y, x, (int)cave->squares[y][x].cost,
						(int)cave->squares[y][x].when);
			} else {
				strnfmt(out_val, sizeof(out_val),
						"%s%s%s%s, %s.", s1, s2, s3, name, coords);
			}

			prt(out_val, 0, 0);
			move_cursor_relative(y, x);
			press = inkey_m();

			if (press.type == EVT_MOUSE) {
				/* Stop on right click */
				if (press.mouse.button == 2)
					break;
			} else {
				/* Stop on everything but "return"/"space" */
				if ((press.key.code != KC_ENTER) && (press.key.code != ' '))
					break;
			}
		}

		/* Stop on everything but "return" */
		if (press.type == EVT_MOUSE) {
				/* Stop on right click */
				if (press.mouse.button != 2)
					break;
		} else {
    			if (press.key.code != KC_ENTER) break;
		}
	}

	mem_free(floor_list);

	/* Keep going */
	return (press);
}