Exemple #1
0
/*
 * Ask the user to respond with a character. Options is a constant string,
 * e.g. "yns"; len is the length of the constant string, and fallback should
 * be the default answer if the user hits escape or an invalid key.
 *
 * Example: get_char("Study? ", "yns", 3, 'n')
 *     This prompts "Study? [yns]" and defaults to 'n'.
 *
 */
char get_char(const char *prompt, const char *options, size_t len, char fallback)
{
	size_t i;
	struct keypress key;
	char button[4], buf[80];
	bool repeat = FALSE;
  
	/* Paranoia XXX XXX XXX */
	message_flush();

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

	/* Hack - kill the repeat button */
	if (button_kill('n')) repeat = TRUE;
	
	/* Make some buttons */
	for (i = 0; i < len; i++)
	{
		strnfmt(button, 4, "[%c]", options[i]);
		button_add(button, options[i]);
	}
	redraw_stuff(p_ptr);
  
	/* Prompt for it */
	prt(buf, 0, 0);

	/* Get an acceptable answer */
	key = inkey();

	/* Lowercase answer if necessary */
	if (key.code >= 'A' && key.code <= 'Z') key.code += 32;

	/* See if key is in our options string */
	if (!strchr(options, (char)key.code))
		key.code = fallback;

	/* Kill the buttons */
	for (i = 0; i < len; i++) button_kill(options[i]);

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

	/* Success */
	return key.code;
}
Exemple #2
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);
}
/**
 * Interact with specialty abilities -BR-
 */
void do_cmd_specialty(void)
{
    ui_event_data answer;

    /* Might want to gain a new ability or browse old ones */
    if (p_ptr->new_specialties > 0) {
	/* Buttons */
	button_add("l", 'l');
	button_add("v", 'v');

	/* Interact and choose. */
	while (get_com_ex
	       ("View abilities or Learn specialty (l/v/ESC)?", &answer)) {
	    /* New ability */
	    if ((answer.key == 'L') || (answer.key == 'l')) {
		gain_specialty();
		break;
	    }

	    /* View Current */
	    if ((answer.key == 'V') || (answer.key == 'v')) {
		view_specialties();
		break;
	    }

	    /* Exit */
	    else if (answer.key == ESCAPE)
		break;


	}
	button_kill('l');
	button_kill('v');
    }

    /* View existing specialties is the only option */
    else {
	view_specialties();
	return;
    }

    return;
}
Exemple #4
0
/**
 * Hack -- save a screen dump to a file
 */
void do_cmd_save_screen(void)
{
    ui_event ke;
    msg("Dump type [(t)ext; (h)tml; (f)orum embedded html]:");
    button_add("f", 'f');
    button_add("h", 'h');
    button_add("t", 't');
    ke = inkey_ex();
    switch(ke.key.code) 
    {
    case ESCAPE:
	break;
    case 't': do_cmd_save_screen_text();
	break;
    case 'h': do_cmd_save_screen_html(0);
	break;
    case 'f': do_cmd_save_screen_html(1);
	break;
    }
    button_kill('f');
    button_kill('t');
    button_kill('h');
    message_flush();
}
Exemple #5
0
/*
 * 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_data target_set_interactive_aux(int y, int x, int mode, cptr info, bool list_floor_objects)
{
	s16b this_o_idx, next_o_idx = 0;
	s16b this_x_idx, next_x_idx = 0;

	cptr s1, s2, s3;

	bool floored;

	u16b feat;

	ui_event_data query;

	char out_val[256];

	char coords[20];

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

	/* Repeat forever */
	while (1)
	{
		int i;

		char feat_name[80];
		/* Terrain suffix for monsters and objects */
		char terrain_suffix[200];

		/* Temporary array of visible effects */
		s16b x_seen[50];
		u16b size_x_seen = 0;

		/* Paranoia */
		query.key = ' ';

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


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

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

		/* Feature (apply "mimic") */
		feat = f_info[cave_feat[y][x]].f_mimic;

		/* Require knowledge about grid, or ability to see grid */
		if (!(cave_info[y][x] & (CAVE_MARK)) && !player_can_see_bold(y,x))
		{
			/* Forget feature */
			feat = FEAT_NONE;
		}

		else
		{
			/* Hack -- track the current feature */
			feature_kind_track(feat);

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

		/* Pick a prefix */
		if (*s2 && (!feat_ff1_match(feat, FF1_MOVE) ||
			!feat_ff1_match(feat, FF1_LOS) ||
			feat_ff1_match(feat, FF1_SHOP | FF1_DOOR) ||
			feat_ff2_match(feat, FF2_SHALLOW | FF2_DEEP) ||
			feat_ff3_match(feat, FF3_NEED_TREE)))
		{
			s3 = "in ";
		}

		/* Get a default name */
		if (feat <= FEAT_NONE)
		{
			my_strcpy(feat_name, "an unknown grid", sizeof(feat_name));
		}
		/* Get the real name */
		else
		{
			feature_desc(feat_name, sizeof (feat_name), feat, TRUE, FALSE);
		}

		/* List all effects in the grid */
		for (this_x_idx = cave_x_idx[y][x]; this_x_idx; this_x_idx = next_x_idx)
		{
			effect_type *x_ptr;

			/* Get the effect */
			x_ptr = &x_list[this_x_idx];

			/* Get the next effect */
			next_x_idx = x_ptr->next_x_idx;

			/* Describe it, if not hidden */
			if (!(x_ptr->x_flags & (EF1_HIDDEN)) && x_ptr->x_f_idx)
			{
				/* Check for available space */
				if (size_x_seen < N_ELEMENTS(x_seen))
				{
					x_seen[size_x_seen++] = x_ptr->x_f_idx;
				}
			}
		}

		/* Prepare the terrain suffix for monsters and objects */
		my_strcpy(terrain_suffix, format(" %s%s", s3, feat_name), sizeof(terrain_suffix));

		/* Concat the collected effect names */
		for (i = 0; i < size_x_seen; i++)
		{
			char x_name[80];

			/* Obtain an object description */
			feature_desc(x_name, sizeof(x_name), x_seen[i], TRUE, TRUE);

			/* First effect */
			if (i == 0)
			{
				if ((feat == FEAT_NONE) || !feat_ff1_match(feat, FF1_MOVE) ||
					cave_any_trap_bold(y, x))
				{
					/* Basic info */
					my_strcat(terrain_suffix, format(" with %s", x_name),
						sizeof(terrain_suffix));
				}
				else
				{
					/* Basic info */
					my_strcat(terrain_suffix, format(" beneath %s", x_name),
						sizeof(terrain_suffix));
				}
			}

			/* Basic info */
			else if (i < (size_x_seen - 1))
			{
				my_strcat(terrain_suffix, format(", %s", x_name), sizeof(terrain_suffix));
			}

			/* Basic info */
			else
			{
				my_strcat(terrain_suffix, format(" and %s", x_name), sizeof(terrain_suffix));
			}
		}

		/* Ignore the terrain suffix if certain things happen */
		if ((size_x_seen == 0) && (feat <= FEAT_FLOOR))
		{
			terrain_suffix[0] = '\0';
		}

		/* Hack -- hallucination */
		if (p_ptr->timed[TMD_IMAGE])
		{
			cptr 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, name, info, coords, y, x);
			}
			else
			{
				strnfmt(out_val, sizeof(out_val),
						"%s%s%s [%s], %s.", s1, s2, name, info, coords);
			}

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

			query = inkey_ex();

			/* Stop on everything but "return" */
			if ((query.key != '\n') && (query.key != '\r')) break;

			/* Repeat forever */
			continue;
		}

		/* Actual monsters */
		if (cave_m_idx[y][x] > 0)
		{
			monster_type *m_ptr = &mon_list[cave_m_idx[y][x]];
			monster_race *r_ptr = &r_info[m_ptr->r_idx];

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

				char m_name[80];

				if (m_ptr->mimic_k_idx)
				{
					/*get the description*/
					mimic_desc_object(m_name, sizeof(m_name), m_ptr->mimic_k_idx);
				}

				else
				{
					/* Get the monster name ("a kobold") */
					monster_desc(m_name, sizeof(m_name), m_ptr, 0x08);

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

					/* Hack -- health bar for this monster */
					health_track(cave_m_idx[y][x]);

					/*Track the feature*/
					feature_kind_track(cave_feat[y][x]);

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

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

				/* Interact */
				while (1)
				{
					if (recall)	button_add("[CLEAR_RECALL]", 'r');
					else 		button_add("[RECALL]", 'r');
					if (cave_o_idx[y][x] > 0)button_add("[VIEW_FLOOR]", 'f');
					event_signal(EVENT_MOUSEBUTTONS);

					/* Recall, but not mimics */
					if ((recall) && (!(m_ptr->mimic_k_idx)))
					{
						/* Save screen */
						screen_save();

						/* Recall on screen */
						screen_roff(m_ptr->r_idx);

						/* Hack -- Complete the prompt (again) */
						Term_addstr(-1, TERM_WHITE, format(" [r,%s]", info));

						/* Command */
						query = inkey_ex();

						/* Load screen */
						screen_load();
					}

					/* Normal */
					else
					{

						/* Basic info */
						strnfmt(out_val, sizeof(out_val),
							"%s%s%s", s1, s2, m_name);

						/* Describe the monster, unless a mimic */
						if (!(m_ptr->mimic_k_idx))
						{
							char buf[80];

							look_mon_desc(buf, sizeof(buf), cave_m_idx[y][x]);

							/* Monster state, terrain suffix, options  */
							my_strcat(out_val, format(" (%s)%s [r,%s]",
								buf, terrain_suffix, info),
								sizeof(out_val));
						}

						/* Mimics */
						else
						{
							/* Terrain suffix, options */
							my_strcat(out_val,
								format("%s [I,%s]", terrain_suffix,
								info), sizeof(out_val));
						}

						/* Wizards want coordinates */
						if (p_ptr->wizard)
						{
							my_strcat(out_val, format(" (%d:%d)", y, x),
								sizeof(out_val));
						}

						prt(out_val, 0, 0);

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

						/* Command */
						query = inkey_ex();
					}

					button_kill('r');
					button_kill('f');
					event_signal(EVENT_MOUSEBUTTONS);

					/* Handle fake object recall */
					if (m_ptr->mimic_k_idx)
					{
						object_type body;
						object_type *o_ptr = &body;

						/* Validate input first */
						if (query.key != 'I') break;

						/* Paranoia */
						object_wipe(o_ptr);

						/* Prepare */
						object_prep(o_ptr, m_ptr->mimic_k_idx);

						/* Fake history */
						object_history(o_ptr, ORIGIN_FLOOR, 0);

						/* Clear prompt. Place cursor */
						prt("", 0, 0);

						/* Show the fake info - EXPERIMENTAL */
						object_info_screen(o_ptr);
					}
					/* Regular monsters */
					else
					{
						/* Normal commands */
						if (query.key != 'r') break;

						/* Toggle recall */
						recall = !recall;
					}
				}

				/* Stop on everything but "return"/"space", or floor */
				if ((query.key != '\n') && (query.key != '\r') &&
					(query.key != ' ') && (query.key != 'f')) break;

				/* continue with 'f' only if there are floor items....*/
				if ((query.key == 'f') && (!cave_o_idx[y][x])) break;

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

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

				/* Hack -- take account of gender */
				if (r_ptr->flags1 & (RF1_FEMALE)) s1 = "She is ";
				else if (r_ptr->flags1 & (RF1_MALE)) s1 = "He is ";

				/* Use a preposition */
				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 = &o_list[this_o_idx];

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

					/*Don't let the player see certain objects (used for vault treasure)*/
					if ((o_ptr->ident & (IDENT_HIDE_CARRY)) && (!p_ptr->wizard) &&
						(!cheat_peek))	 continue;

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

					/* Describe the object */
					strnfmt(out_val, sizeof(out_val),
						"%s%s%s [%s]", s1, s2, o_name, info);

					/* Wizards want coordinates */
					if (p_ptr->wizard)
					{
						my_strcat(out_val, format(" (%d:%d)", y, x), sizeof(out_val));
					}

					prt(out_val, 0, 0);
					move_cursor_relative(y, x);
					query = inkey_ex();

					/* Stop on everything but "return"/"space" */
					if ((query.key != '\n') && (query.key != '\r') && (query.key != ' ')) break;

					/* Sometimes stop at "space" key */
					if ((query.key == ' ') && !(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 */
		floored = FALSE;

		/* Scan all objects in the grid */
		if (TRUE)
		{
			int floor_list[MAX_FLOOR_STACK];
			int floor_num;

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

			/* Scan for floor objects */
			floor_num = scan_floor(floor_list, MAX_FLOOR_STACK, y, x, 0x02);

			/* Actual pile */
			if (floor_num > 1)
			{
				/* Floored */
				floored = TRUE;

				/* Describe */
				while (1)
				{
					/* Basic info */
					strnfmt(out_val, sizeof(out_val),
						"%s%sa pile of %d objects%s [r,%s]", s1, s2,
						floor_num, terrain_suffix, info);

					/* Wizards want coordinates */
					if (p_ptr->wizard)
					{
						my_strcat(out_val, format(" (%d:%d)", y, x), sizeof(out_val));
					}

					prt(out_val, 0, 0);

					if (list_floor_objects)
					{
						/* Save screen */
						screen_save();

						/* Display */
						show_floor(floor_list, floor_num, (OLIST_WEIGHT | OLIST_GOLD));
					}
					move_cursor_relative(y, x);
					query = inkey_ex();

					if (list_floor_objects)
					{
						screen_load();
					}

					/* Display objects */
					if (query.key == 'r')
					{
						int pos;

						pos = query.key - 'a';
						if (0 <= pos && pos < floor_num)
						{
							track_object(-floor_list[pos]);
							handle_stuff();
						}
					}

					/* Done */
					break;
				}

				/* Stop on everything but "return"/"space" */
				if ((query.key != '\n') && (query.key != '\r') && (query.key != ' ')) break;

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

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

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

		/* Scan all objects in the grid */
		for (this_o_idx = cave_o_idx[y][x]; this_o_idx; this_o_idx = next_o_idx)
		{
			object_type *o_ptr;

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

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

			/* Skip objects if floored */
			if (floored) continue;

			/* Describe it */
			if (o_ptr->marked)
			{
				char o_name[80];

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

				/* Basic info */
				strnfmt(out_val, sizeof(out_val), "%s%s%s%s [I,%s]",
					s1, s2, o_name, terrain_suffix, info);

				/* Wizards want coordinates */
				if (p_ptr->wizard)
				{
					my_strcat(out_val, format(" (%d:%d)", y, x),
						sizeof(out_val));
				}

				/* Show object. Handle object recall */
				while (TRUE)
				{
					/* Print the prompt */
					prt(out_val, 0, 0);

					/* Move cursor to that location */
					move_cursor_relative(y, x);

					/* Read input key */
					query = inkey_ex();

					/* No object recall */
					if (query.key != 'I') break;

					/* Object recall. Clear the first line */
					prt("", 0, 0);

					/* Do it */
					object_info_screen(o_ptr);
				}

				/* Stop on everything but "return"/"space" */
				if ((query.key != '\n') && (query.key != '\r') && (query.key != ' ')) break;

				/* Sometimes stop at "space" key */
				if ((query.key == ' ') && !(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;

		/* Display terrain */
		if (TRUE)
		{
			u16b temp_feat;
			bool enable_recall;
			bool show_recall = FALSE;
			char temp_name[80];

			/*
			 * Display terrain and effects
			 */
			for (i = 0; i <= size_x_seen; i++)
			{
				/* Hack - This is the mark for the feature stored in cave_feat */
				if (i == size_x_seen)
				{
				       	temp_feat = feat;

					/* Just copy the feature name */
					my_strcpy(temp_name, feat_name, sizeof(temp_name));
				}
				/* Any other value is an effect stored x_list */
				else
				{
					temp_feat = x_seen[i];

					/* Get the effect's name */
					feature_desc(temp_name, sizeof(temp_name), temp_feat, TRUE, TRUE);
				}

				/* Don't display feature recall if the grid is unknown */
				enable_recall = (temp_feat != FEAT_NONE);

				/* Handle recall */
				while (TRUE)
				{

					/* Handle recall mode */
					if (show_recall && enable_recall)
					{
						/* Save screen */
						screen_save();

						/* Recall feature on screen */
						screen_feature_roff(temp_feat);
					}

					/* Display a message */
					strnfmt(out_val, sizeof(out_val),
						"%s%s%s [%s%s]%s", s1, s2, temp_name,
						(enable_recall ? "r,": ""), info,
						(i < size_x_seen) ? " (more)": "");

					/* Wizards want coordinates */
					if (p_ptr->wizard)
					{
						my_strcat(out_val, format(" (%d:%d)", y, x), sizeof(out_val));
					}

					/*Track this feature*/
					feature_kind_track(temp_feat);

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

					prt(out_val, 0, 0);
					move_cursor_relative(y, x);
					query = inkey_ex();

					/* Load screen if necessary */
					if (show_recall && enable_recall)
					{
						screen_load();
					}

					/* Stop on everything but the recall command, if enabled */
					if (!enable_recall || (query.key != 'r')) break;

					/* Toggle recall */
					show_recall = !show_recall;
				}

				/* Stop on everything but "return"/"space" */
				if ((query.key != '\n') && (query.key != '\r') && (query.key != ' ')) break;
			}
		}

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

		/* Stop on everything but "return" */
		if ((query.key != '\n') && (query.key != '\r')) break;
	}

	/* Keep going */
	return (query);
}
Exemple #6
0
/*
 * Handle "target" and "look".
 *
 * Note that this code can be called from "get_aim_dir()".
 *
 * Currently, when "flag" is true, that is, when
 * "interesting" grids are being used, and a directional key is used, we
 * only scroll by a single panel, in the direction requested, and check
 * for any interesting grids on that panel.  The "correct" solution would
 * actually involve scanning a larger set of grids, including ones in
 * panels which are adjacent to the one currently scanned, but this is
 * overkill for this function.  XXX XXX
 *
 * Hack -- targetting/observing an "outer border grid" may induce
 * problems, so this is not currently allowed.
 *
 * The player can use the direction keys to move among "interesting"
 * grids in a heuristic manner, or the "space", "+", and "-" keys to
 * move through the "interesting" grids in a sequential manner, or
 * can enter "location" mode, and use the direction keys to move one
 * grid at a time in any direction.  The "t" (set target) command will
 * only target a monster (as opposed to a location) if the monster is
 * target_able and the "interesting" mode is being used.
 *
 * The current grid is described using the "look" method above, and
 * a new command may be entered at any time, but note that if the
 * "TARGET_LOOK" bit flag is set (or if we are in "location" mode,
 * where "space" has no obvious meaning) then "space" will scan
 * through the description of the current grid until done, instead
 * of immediately jumping to the next "interesting" grid.  This
 * allows the "target" command to retain its old semantics.
 *
 * The "*", "+", and "-" keys may always be used to jump immediately
 * to the next (or previous) interesting grid, in the proper mode.
 *
 * The "return" key may always be used to scan through a complete
 * grid description (forever).
 *
 * This command will cancel any old target, even if used from
 * inside the "look" command.
 *
 * 'mode' is one of TARGET_LOOK or TARGET_KILL.
 * 'x' and 'y' are the initial position of the target to be highlighted,
 * or -1 if no location is specified.
 * Returns TRUE if a target has been successfully set, FALSE otherwise.
 */
bool target_set_interactive(int mode, int x, int y)
{
	int py = p_ptr->py;
	int px = p_ptr->px;

	int i, d, m, t, bd;
	int wid, hgt, help_prompt_loc;

	bool done = FALSE;
	bool flag = TRUE;
	bool help = FALSE;
	bool list_floor_objects = auto_display_lists;

	u16b path_n;
	u16b path_g[PATH_SIZE];
	u16b path_gx[PATH_SIZE];

	ui_event_data query;

	char info[80];

	/* These are used for displaying the path to the target */
	char path_char[MAX_RANGE];
	byte path_attr[MAX_RANGE];

	/* If we haven't been given an initial location, start on the
	   player. */
	if (x == -1 || y == -1)
	{
		x = p_ptr->px;
		y = p_ptr->py;
	}
    /* If we /have/ been given an initial location, make sure we
	   honour it by going into "free targeting" mode. */
	else
	{
		flag = FALSE;
	}


	/* Cancel target */
	target_set_monster(0);

	/* make some buttons */
	button_backup_all();
	button_kill_all();
	button_add("[ESCAPE]", ESCAPE);
	button_add("[NEXT]", '+');
	button_add("[PREV]", '-');
	button_add("[PLAYER]", 'p');
	button_add("[PATHFIND]", 'g');
	button_add("[TARGET]", 't');

	/* health_track(0); */

	  /* All grids are selectable */
	if (mode & (TARGET_GRID))
	{
		/* Disable other modes */
		mode &= ~(TARGET_LOOK | TARGET_KILL | TARGET_TRAP);

		/* Disable interesting grids */
		flag = FALSE;
	}

	/* Calculate the window location for the help prompt */
	Term_get_size(&wid, &hgt);
	help_prompt_loc = hgt - (mouse_buttons ? 2 : 1);

	/* Display the help prompt */
	prt("'?' - help", help_prompt_loc, 0);

	/* Prepare the "temp" array */
	target_set_interactive_prepare(mode);

	/* Start near the player */
	m = 0;

	/* Interact */
	while (!done)
	{
		button_kill('l');
		button_kill('?');
		if (list_floor_objects)
		{
			button_add("[HIDE_OBJLIST]", 'l');
		}
		else button_add("[SHOW_OBJLIST]", 'l');
		if (help)
		{
			button_add("[HIDE_HELP]", '?');
		}
		else button_add("[SHOW_HELP]",'?');

		/* Interesting grids */
		if (flag && temp_n)
		{
			bool path_drawn = FALSE;
			int yy, xx;

			y = temp_y[m];
			x = temp_x[m];

			button_add("[SCAN]",'o');

			/* Update help */
			if (help)
			{
				bool good_target = ((cave_m_idx[y][x] > 0) && target_able(cave_m_idx[y][x]));
				target_display_help(good_target, !(flag && temp_n));
			}

			/* Dummy pointers to send to project_path */
			yy = y;
			xx = x;

			/* Allow targets for monsters....or traps, if applicable */
			if (((cave_m_idx[y][x] > 0) && target_able(cave_m_idx[y][x])) ||
				((mode & (TARGET_TRAP)) && target_able_trap(y, x)))
			{
				strcpy(info, "q,t,r,l,p,o,+,-,<dir>");
			}

			/* Dis-allow target */
			else
			{
				strcpy(info, "q,p,l,o,+,-,<dir>");
			}

			/* Adjust panel if needed */
			if (adjust_panel(y, x))
			{
				/* Handle stuff */
				handle_stuff();
			}

			/* Find the path. */
			path_n = project_path(path_g, path_gx, MAX_RANGE, py, px, &yy, &xx, PROJECT_THRU);

			/* Draw the path in "target" mode. If there is one */
			if ((mode & (TARGET_KILL)) && (cave_info[y][x] & (CAVE_FIRE)))
			{
				path_drawn = draw_path(path_n, path_g, path_char, path_attr, py, px, y, x);
			}
			event_signal(EVENT_MOUSEBUTTONS);

			/* Describe and Prompt */
			query = target_set_interactive_aux(y, x, mode, info, list_floor_objects);

			/* Remove the path */
			if (path_drawn) load_path(path_n, path_g, path_char, path_attr);

			/* Cancel tracking */
			/* health_track(0); */

			/* Assume no "direction" */
			d = 0;

			/* Analyze */
			switch (query.key)
			{
				case ESCAPE:
				case 'q':
				{
					done = TRUE;
					break;
				}

				case ' ':
				case '*':
				case '+':
				{
					if (++m == temp_n) m = 0;
					break;
				}

				case '-':
				{
					if (m-- == 0)  m = temp_n - 1;
					break;
				}

				case 'p':
				{
					/* Recenter around player */
					verify_panel();

					/* Handle stuff */
					handle_stuff();

					y = py;
					x = px;
				}

				case 'o':
				{
					flag = FALSE;
					break;
				}

				case 'm':
				{
					break;
				}

				/* If we click, move the target location to the click and
				   switch to "free targetting" mode by unsetting 'flag'.
				   This means we get some info about wherever we've picked. */
				case DEFINED_XFF:
				{
					x = KEY_GRID_X(query);
					y = KEY_GRID_Y(query);
					flag = FALSE;
					break;
				}

				case 't':
				case '5':
				case '0':
				case '.':
				{
					int m_idx = cave_m_idx[y][x];

					if ((m_idx > 0) && target_able(m_idx))
					{
						health_track(m_idx);
						target_set_monster(m_idx);
						done = TRUE;
					}
					else if ((mode & (TARGET_TRAP)) && target_able_trap(y, x))
 					{
 						target_set_location(y, x);
 						done = TRUE;
 					}
					else if (mode & (TARGET_PROBE))
					{
					 	target_set_location(y, x);
					 	done = TRUE;
					}
					else
					{
						bell("Illegal target!");
					}
					break;
				}

				case 'g':
				{
					cmd_insert(CMD_PATHFIND, y, x);
					done = TRUE;
					break;
				}

				case 'l':
				{
					list_floor_objects = (!list_floor_objects);
				}

				case '?':
				{
					help = !help;

					/* Redraw main window */
					p_ptr->redraw |= (PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIP);
					Term_clear();
					handle_stuff();
					if (!help)
						prt("'?' - help", help_prompt_loc, 0);

					break;
				}

				default:
				{
					/* Extract direction */
					d = target_dir(query.key);

					/* Oops */
					if (!d) bell("Illegal command for target mode!");

					break;
				}
			}

			/* Hack -- move around */
			if (d)
			{
				int old_y = temp_y[m];
				int old_x = temp_x[m];

				/* Find a new monster */
				i = target_pick(old_y, old_x, ddy[d], ddx[d]);

				/* Scroll to find interesting grid */
				if (i < 0)
				{
					int old_wy = Term->offset_y;
					int old_wx = Term->offset_x;

					/* Change if legal */
					if (change_panel(d))
					{
						/* Recalculate interesting grids */
						target_set_interactive_prepare(mode);

						/* Find a new monster */
						i = target_pick(old_y, old_x, ddy[d], ddx[d]);

						/* Restore panel if needed */
						if ((i < 0) && modify_panel(Term, old_wy, old_wx))
						{
							/* Recalculate interesting grids */
							target_set_interactive_prepare(mode);
						}

						/* Handle stuff */
						handle_stuff();
					}
				}

				/* Use interesting grid if found */
				if (i >= 0) m = i;
			}
		}

		/* Arbitrary grids */
		else
		{
			bool path_drawn = FALSE;

			/* Dummy pointers to send to project_path */
			int yy = y;
			int xx = x;

			/* Don't need this button any more */
			button_kill('o');

			/* Update help */
			if (help)
			{
				bool good_target = ((cave_m_idx[y][x] > 0) && target_able(cave_m_idx[y][x]));
				target_display_help(good_target, !(flag && temp_n));
			}

			/* Default prompt */
			if (!(mode & (TARGET_GRID)))
			{
				strcpy(info, "q,t,l,p,m,+,-,<dir>");
			}

			/* Disable monster selection */
			else
			{
				strcpy(info, "q,t,l.p,+,-,<dir>");
			}

			/* Find the path. */
			path_n = project_path(path_g, path_gx, MAX_RANGE, py, px, &yy, &xx, PROJECT_THRU);

			/* Draw the path in "target" mode. If there is one */
			if ((mode & (TARGET_KILL)) && (cave_info[y][x] & (CAVE_FIRE)))
			{
				/* Save target info */
				path_drawn = draw_path(path_n, path_g, path_char, path_attr, py, px, y, x);
			}

			event_signal(EVENT_MOUSEBUTTONS);

			/* Describe and Prompt (enable "TARGET_LOOK") */
			query = target_set_interactive_aux(y, x, (mode | TARGET_LOOK), info, list_floor_objects);

			/* Remove the path */
			if (path_drawn)  load_path(path_n, path_g, path_char, path_attr);

			/* Cancel tracking */
			/* health_track(0); */

			/* Assume no direction */
			d = 0;

			/* Analyze the keypress */
			switch (query.key)
			{
				case ESCAPE:
				case 'q':
				{
					done = TRUE;
					break;
				}

				case ' ':
				case '*':
				case '+':
				case '-':
				{
					break;
				}

				case 'p':
				{
					/* Recenter around player */
					verify_panel();

					/* Handle stuff */
					handle_stuff();

					y = py;
					x = px;
				}

				case 'o':
				{
					break;
				}

				case 'm':
				{
					/* Monster selection is disabled */
					if (mode & (TARGET_GRID)) break;

					flag = TRUE;

					m = 0;
					bd = 999;

					/* Pick a nearby monster */
					for (i = 0; i < temp_n; i++)
					{
						t = distance(y, x, temp_y[i], temp_x[i]);

						/* Pick closest */
						if (t < bd)
						{
							m = i;
							bd = t;
						}
					}

					/* Nothing interesting */
					if (bd == 999) flag = FALSE;

					break;
				}

				case '\xff':
				{
					/* We only target if we click somewhere where the cursor
					   is already (i.e. a double-click without a time limit) */
					if (KEY_GRID_X(query) == x && KEY_GRID_Y(query) == y)
					{
						/* Make an attempt to target the monster on the given
						   square rather than the square itself (it seems this
						   is the more likely intention of clicking on a
						   monster). */
						int m_idx = cave_m_idx[y][x];

						if ((m_idx > 0) && target_able(m_idx))
						{
							health_track(m_idx);
							target_set_monster(m_idx);
						}
						else
						{
							/* There is no monster, or it isn't targettable,
							   so target the location instead. */
							target_set_location(y, x);
						}

						done = TRUE;
					}
					else
					{
						/* Just move the cursor for now - another click will
						   target. */
						x = KEY_GRID_X(query);
						y = KEY_GRID_Y(query);
					}
					break;
				}

				case 't':
				case '5':
				case '0':
				case '.':
				{
					target_set_location(y, x);
					done = TRUE;
					break;
				}

				case 'g':
				{
					cmd_insert(CMD_PATHFIND, y, x);
					done = TRUE;
					break;
				}

				case 'l':
				{
					list_floor_objects = (!list_floor_objects);
				}

				case '?':
				{
					help = !help;

					/* Redraw main window */
					p_ptr->redraw |= (PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIP);
					Term_clear();
					handle_stuff();
					if (!help)
						prt("'?' - help.", help_prompt_loc, 0);

					break;
				}


				default:
				{
					/* Extract a direction */
					d = target_dir(query.key);

					/* Oops */
					if (!d) bell("Illegal command for target mode!");

					break;
				}
			}

			/* Handle "direction" */
			if (d)
			{
				int dungeon_hgt = p_ptr->cur_map_hgt;
				int dungeon_wid = p_ptr->cur_map_wid;

				/* Move */
				x += ddx[d];
				y += ddy[d];

				/* Slide into legality */
				if (x >= dungeon_wid - 1) x--;
				else if (x <= 0) x++;

				/* Slide into legality */
				if (y >= dungeon_hgt - 1) y--;
				else if (y <= 0) y++;

				/* Adjust panel if needed */
				if (adjust_panel(y, x))
				{
					/* Handle stuff */
					handle_stuff();

					/* Recalculate interesting grids */
					target_set_interactive_prepare(mode);

				}
			}
		}
	}

	/* Forget */
	temp_n = 0;

	/* Redraw as necessary */
	if (help)
	{
		p_ptr->redraw |= (PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIP);
		Term_clear();
	}
	else
	{
		prt("", 0, 0);
		prt("", help_prompt_loc, 0);
		p_ptr->redraw |= (PR_DEPTH | PR_STATUS);
	}



	/* Recenter around player */
	verify_panel();

	/* Restore buttons */
	button_restore();

	/* Handle stuff */
	handle_stuff();

	/* Failure to set target */
	if (!p_ptr->target_set) return (FALSE);

	/* Success */
	return (TRUE);
}
Exemple #7
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);
}
Exemple #8
0
static enum birth_stage roller_command(bool first_call)
{
	char prompt[80] = "";
	size_t promptlen = 0;

	struct keypress 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);

	if (first_call)
		prev_roll = FALSE;

	/* Add buttons */
	button_add("[ESC]", ESCAPE);
	button_add("[Enter]", '\r');
	button_add("[r]", 'r');
	if (prev_roll) button_add("[p]", 'p');
	clear_from(Term->hgt - 2);
	redraw_stuff(p_ptr);

	/* 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 - 1, Term->wid / 2 - promptlen / 2);
	
	/* Prompt and get a command */
	ch = inkey();

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

		next = BIRTH_BACK;
	}

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

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

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

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

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

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

	/* Kill buttons */
	button_kill(ESCAPE);
	button_kill('\r');
	button_kill('r');
	button_kill('p');
	redraw_stuff(p_ptr);

	return next;
}
Exemple #9
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 #10
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 #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
/**
 * 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 #13
0
/*
 * Identify a character, allow recall of monsters
 *
 * Several "special" responses recall "multiple" monsters:
 *   ^A (all monsters)
 *   ^U (all unique monsters)
 *   ^N (all non-unique monsters)
 *
 * The responses may be sorted in several ways, see below.
 *
 * Note that the player ghosts are ignored, since they do not exist.
 */
void do_cmd_query_symbol(void)
{
	int i, n, r_idx;
	char buf[128];

	struct keypress sym;
	struct keypress query;

	bool all = FALSE;
	bool uniq = FALSE;
	bool norm = FALSE;

	bool recall = FALSE;

	u16b *who;

	/* Get a character, or abort */
	if (!get_com("Enter character to be identified, or control+[ANU]: ", &sym))
		return;

	/* Describe */
	if (sym.code == KTRL('A'))
	{
		all = TRUE;
		my_strcpy(buf, "Full monster list.", sizeof(buf));
	}
	else if (sym.code == KTRL('U'))
	{
		all = uniq = TRUE;
		my_strcpy(buf, "Unique monster list.", sizeof(buf));
	}
	else if (sym.code == KTRL('N'))
	{
		all = norm = TRUE;
		my_strcpy(buf, "Non-unique monster list.", sizeof(buf));
	}
	else
	{
		lookup_symbol(sym, buf, sizeof(buf));
	}

	/* Display the result */
	prt(buf, 0, 0);

	/* Allocate the "who" array */
	who = C_ZNEW(z_info->r_max, u16b);

	/* Collect matching monsters */
	for (n = 0, i = 1; i < z_info->r_max - 1; i++)
	{
		monster_race *r_ptr = &r_info[i];
		monster_lore *l_ptr = &l_list[i];

		/* Nothing to recall */
		if (!OPT(cheat_know) && !l_ptr->sights) continue;

		/* Require non-unique monsters if needed */
		if (norm && rf_has(r_ptr->flags, RF_UNIQUE)) continue;

		/* Require unique monsters if needed */
		if (uniq && !rf_has(r_ptr->flags, RF_UNIQUE)) continue;

		/* Collect "appropriate" monsters */
		if (all || (r_ptr->d_char == (char)sym.code)) who[n++] = i;
	}

	/* Nothing to recall */
	if (!n)
	{
		/* XXX XXX Free the "who" array */
		FREE(who);

		return;
	}

	/* Buttons */
	button_add("[y]", 'y');
	button_add("[k]", 'k');
	/* Don't collide with the repeat button */
	button_add("[n]", 'q'); 
	redraw_stuff(p_ptr);

	/* Prompt */
	put_str("Recall details? (y/k/n): ", 0, 40);

	/* Query */
	query = inkey();

	/* Restore */
	prt(buf, 0, 0);

	/* Buttons */
	button_kill('y');
	button_kill('k');
	button_kill('q');
	redraw_stuff(p_ptr);

	/* Interpret the response */
	if (query.code == 'k')
	{
		/* Sort by kills (and level) */
		sort(who, n, sizeof(*who), cmp_pkill);
	}
	else if (query.code == 'y' || query.code == 'p')
	{
		/* Sort by level; accept 'p' as legacy */
		sort(who, n, sizeof(*who), cmp_level);
	}
	else
	{
		/* Any unsupported response is "nope, no history please" */
	
		/* XXX XXX Free the "who" array */
		FREE(who);

		return;
	}

	/* Start at the end */
	i = n - 1;

	/* Button */
	button_add("[r]", 'r');
	button_add("[-]", '-');
	button_add("[+]", '+');
	redraw_stuff(p_ptr);

	/* Scan the monster memory */
	while (1)
	{
		/* Extract a race */
		r_idx = who[i];

		/* Hack -- Auto-recall */
		monster_race_track(r_idx);

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

		/* Hack -- Begin the prompt */
		roff_top(r_idx);

		/* Hack -- Complete the prompt */
		Term_addstr(-1, TERM_WHITE, " [(r)ecall, ESC]");

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

				/* Recall on screen */
				screen_roff(who[i]);

				/* Hack -- Complete the prompt (again) */
				Term_addstr(-1, TERM_WHITE, " [(r)ecall, ESC]");
			}

			/* Command */
			query = inkey();

			/* Unrecall */
			if (recall)
			{
				/* Load screen */
				screen_load();
			}

			/* Normal commands */
			if (query.code != 'r') break;

			/* Toggle recall */
			recall = !recall;
		}

		/* Stop scanning */
		if (query.code == ESCAPE) break;

		/* Move to "prev" monster */
		if (query.code == '-')
		{
			if (++i == n)
				i = 0;
		}

		/* Move to "next" monster */
		else
		{
			if (i-- == 0)
				i = n - 1;
		}
	}

	/* Button */
	button_kill('r');
	button_kill('-');
	button_kill('+');
	redraw_stuff(p_ptr);

	/* Re-display the identity */
	prt(buf, 0, 0);

	/* Free the "who" array */
	FREE(who);
}