Пример #1
0
/**
 * Study a book to gain a new spell
 */
void textui_obj_study(void)
{
	int item;
	char q[80];
	char s[80];

	if (mp_ptr->spell_realm == REALM_NONE) {
		msg("You cannot read books!");
		return;
	}

	strnfmt(q, sizeof(q), "Study which %s?",
			magic_desc[mp_ptr->spell_realm][BOOK_NOUN]);
	strnfmt(s, sizeof(s), " You have no %ss that you can study.",
			magic_desc[mp_ptr->spell_realm][BOOK_LACK]);

	item_tester_hook = obj_can_study;
	if (!get_item(&item, q, s, CMD_STUDY_BOOK, (USE_INVEN | USE_FLOOR)))
		return;

	track_object(item);
	handle_stuff(p_ptr);

	if (mp_ptr->spell_book != TV_PRAYER_BOOK) {
		int spell = get_spell(object_from_item_idx(item),
							  "study", spell_okay_to_study);
		if (spell >= 0) {
			cmd_insert(CMD_STUDY_SPELL);
			cmd_set_arg_choice(cmd_get_top(), 0, spell);
		}
	} else {
		cmd_insert(CMD_STUDY_BOOK);
		cmd_set_arg_item(cmd_get_top(), 0, item);
	}
}
Пример #2
0
/**
 * Front-end command which fires at the nearest target with default ammo.
 */
void textui_cmd_fire_at_nearest(void) {
	/* the direction '5' means 'use the target' */
	int i, dir = 5, item = -1;

	/* Require a usable launcher */
	if (!p_ptr->inventory[INVEN_BOW].tval || !p_ptr->state.ammo_tval) {
		msg("You have nothing to fire with.");
		return;
	}

	/* Find first eligible ammo in the quiver */
	for (i = QUIVER_START; i < QUIVER_END; i++) {
		if (p_ptr->inventory[i].tval != p_ptr->state.ammo_tval) continue;
		item = i;
		break;
	}

	/* Require usable ammo */
	if (item < 0) {
		msg("You have no ammunition in the quiver to fire");
		return;
	}

	/* Require foe */
	if (!target_set_closest(TARGET_KILL | TARGET_QUIET)) return;

	/* Fire! */
	cmd_insert(CMD_FIRE);
	cmd_set_arg_item(cmd_get_top(), 0, item);
	cmd_set_arg_target(cmd_get_top(), 1, dir);
}
Пример #3
0
void textui_obj_wield(object_type *o_ptr, int item)
{
    int slot = wield_slot(o_ptr);

    /* Usually if the slot is taken we'll just replace the item in the slot,
     * but in some cases we need to ask the user which slot they actually
     * want to replace */
    if (p_ptr->inventory[slot].k_idx)
    {
        if (o_ptr->tval == TV_RING)
        {
            cptr q = "Replace which ring? ";
            cptr s = "Error in obj_wield, please report";
            item_tester_hook = obj_is_ring;
            if (!get_item(&slot, q, s, CMD_WIELD, USE_EQUIP)) return;
        }

        if (obj_is_ammo(o_ptr) && !object_similar(&p_ptr->inventory[slot],
                o_ptr, OSTACK_QUIVER))
        {
            cptr q = "Replace which ammunition? ";
            cptr s = "Error in obj_wield, please report";
            item_tester_hook = obj_is_ammo;
            if (!get_item(&slot, q, s, CMD_WIELD, USE_EQUIP)) return;
        }
    }

    cmd_insert(CMD_WIELD);
    cmd_set_arg_item(cmd_get_top(), 0, item);
    cmd_set_arg_number(cmd_get_top(), 1, slot);
}
Пример #4
0
/**
 * Handle a textui mouseclick.
 */
static void textui_process_click(ui_event_data e)
{
	int x, y;

	if (!OPT(mouse_movement)) return;

	y = KEY_GRID_Y(e);
	x = KEY_GRID_X(e);

	/* Check for a valid location */
	if (!in_bounds_fully(y, x)) return;

	/* XXX show context menu here */
	if ((p_ptr->py == y) && (p_ptr->px == x))
		textui_cmd_rest();

	else /* if (e.mousebutton == 1) */
	{
		if (p_ptr->timed[TMD_CONFUSED])
		{
			cmd_insert(CMD_WALK);
		}
		else
		{
			cmd_insert(CMD_PATHFIND);
			cmd_set_arg_point(cmd_get_top(), 0, y, x);
		}
	}

#if 0
	else if (e.mousebutton == 2)
Пример #5
0
/**
 * Cast a spell from a book.
 */
void textui_obj_cast(void)
{
	int item;
	int spell;

	const char *verb = magic_desc[mp_ptr->spell_realm][SPELL_VERB];
	char q[80];
	char s[80];

	if (mp_ptr->spell_realm == REALM_NONE) {
		msg("You cannot read books!");
		return;
	}

	strnfmt(q, sizeof(q), "Use which %s?",
			magic_desc[mp_ptr->spell_realm][BOOK_NOUN]);
	strnfmt(s, sizeof(s), " You have no %ss that you can use.",
			magic_desc[mp_ptr->spell_realm][BOOK_LACK]);

	item_tester_hook = obj_can_cast_from;
	if (!get_item(&item, q, s, CMD_CAST, (USE_INVEN | USE_FLOOR)))
		return;

	/* Track the object kind */
	track_object(item);

	/* Ask for a spell */
	spell =
		get_spell(object_from_item_idx(item), verb, spell_okay_to_cast);
	if (spell >= 0) {
		cmd_insert(CMD_CAST);
		cmd_set_arg_choice(cmd_get_top(), 0, spell);
	}
}
Пример #6
0
void textui_cmd_rest(void)
{
  	/* Prompt for time if needed */
	if (p_ptr->command_arg <= 0)
	{
		cptr p = "Rest (0-9999, '!' for HP or SP, '*' for HP and SP, '&' as needed): ";

		char out_val[5] = "& ";

		/* Ask for duration */
		if (!get_string(p, out_val, sizeof(out_val))) return;

		/* Rest until done */
		if (out_val[0] == '&')
		{
			cmd_insert(CMD_REST);
			cmd_set_arg_choice(cmd_get_top(), 0, REST_COMPLETE);
		}

		/* Rest a lot */
		else if (out_val[0] == '*')
		{
			cmd_insert(CMD_REST);
			cmd_set_arg_choice(cmd_get_top(), 0, REST_ALL_POINTS);
		}

		/* Rest until HP or SP filled */
		else if (out_val[0] == '!')
		{
			cmd_insert(CMD_REST);
			cmd_set_arg_choice(cmd_get_top(), 0, REST_SOME_POINTS);
		}
		
		/* Rest some */
		else
		{
			int turns = atoi(out_val);
			if (turns <= 0) return;
			if (turns > 9999) turns = 9999;
			
			cmd_insert(CMD_REST);
			cmd_set_arg_choice(cmd_get_top(), 0, turns);
		}
	}
}
Пример #7
0
void textui_obj_inscribe(object_type *o_ptr, int item)
{
    char o_name[80];
    char tmp[80] = "";

    object_desc(o_name, sizeof(o_name), o_ptr, ODESC_PREFIX | ODESC_FULL);
    msg_format("Inscribing %s.", o_name);
    message_flush();

    /* Use old inscription */
    if (o_ptr->note)
        strnfmt(tmp, sizeof(tmp), "%s", quark_str(o_ptr->note));

    /* Get a new inscription (possibly empty) */
    if (get_string("Inscription: ", tmp, sizeof(tmp)))
    {
        cmd_insert(CMD_INSCRIBE);
        cmd_set_arg_item(cmd_get_top(), 0, item);
        cmd_set_arg_string(cmd_get_top(), 1, tmp);
    }
}
Пример #8
0
/**
* Handle user input from a command menu
*/
static bool show_action(menu_type * menu, const ui_event * e, int oid)
{
    /* Handle enter and mouse */
    if (e->type == EVT_SELECT) 
    {
	cmd_insert(comm_code[oid]);
	if (comm_code[oid] == CMD_NULL)
	    Term_keypress(comm[oid],0);
	cmd_set_arg_item(cmd_get_top(), 0, item);
    }
    return FALSE;
}
Пример #9
0
/**
 * Front-end 'throw' command.
 */
void textui_cmd_throw(void) {
	int item, dir;
	const char *q, *s;

	/* Get an item */
	q = "Throw which item? ";
	s = "You have nothing to throw.";
	if (!get_item(&item, q, s, CMD_THROW, (USE_EQUIP | USE_INVEN | USE_FLOOR))) return;

	if (item >= INVEN_WIELD && item < QUIVER_START) {
		msg("You cannot throw wielded items.");
		return;
	}

	/* Get a direction (or cancel) */
	if (!get_aim_dir(&dir)) return;

	cmd_insert(CMD_THROW);
	cmd_set_arg_item(cmd_get_top(), 0, item);
	cmd_set_arg_target(cmd_get_top(), 1, dir);
}
Пример #10
0
/* ------------------------------------------------------------------------
 * Asking for the player's chosen name.
 * ------------------------------------------------------------------------ */
static enum birth_stage get_name_command(void)
{
	enum birth_stage next;
	char name[32];

	if (get_name(name, sizeof(name)))
	{	
		cmd_insert(CMD_NAME_CHOICE);
		cmd_set_arg_string(cmd_get_top(), 0, name);
		next = BIRTH_FINAL_CONFIRM;
	}
	else
	{
		next = BIRTH_BACK;
	}

	return next;
}
Пример #11
0
	}
	else if (selected == CMD_CAST) {
		if (obj_can_browse(o_ptr)) {
			/* copied from textui_obj_cast */
			const char *verb = ((p_ptr->class->spell_book == TV_MAGIC_BOOK) ? "cast" : "recite");
			int spell = get_spell(o_ptr, verb, spell_okay_to_cast);

			if (spell >= 0) {
				cmd_insert(CMD_CAST);
				cmd_set_arg_choice(cmd_get_top(), 0, spell);
			}
		}
	}
	else {
		cmd_insert(selected);
		cmd_set_arg_item(cmd_get_top(), 0, slot);

		/* If we're in a store, we need to change the "drop" command to "stash". */
		if (selected == CMD_DROP && store_in_store) {
			game_command *gc = cmd_get_top();
			gc->command = CMD_STASH;
		}
	}

	return 1;
}

/* pick the context menu options appropiate for a store */
int context_menu_store(struct store *store, const int oid, int mx, int my)
{
	menu_type *m;
Пример #12
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 path_n;
	u16b path_g[256];

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

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

	//struct keypress query;
	ui_event press;

	/* These are used for displaying the path to the target */
	wchar_t path_char[MAX_RANGE_LGE];
	int path_attr[MAX_RANGE_LGE];
	struct point_set *targets;

	/* 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 targetting" mode. */
	else
	{
		flag = FALSE;
	}

	/* Cancel target */
	target_set_monster(0);

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

	/* Calculate the window location for the help prompt */
	Term_get_size(&wid, &hgt);
	help_prompt_loc = hgt - 1;
	
	/* Display the help prompt */
	prt("Press '?' for help.", help_prompt_loc, 0);

	/* Prepare the target set */
	targets = target_set_interactive_prepare(mode);

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

	/* Interact */
	while (!done) {
		bool path_drawn = FALSE;
		
		/* Interesting grids */
		if (flag && point_set_size(targets))
		{
			y = targets->pts[m].y;
			x = targets->pts[m].x;

			/* Adjust panel if needed */
			if (adjust_panel_help(y, x, help)) handle_stuff(p_ptr);
		
			/* Update help */
			if (help) {
				bool good_target = target_able(cave_monster_at(cave, y, x));
				target_display_help(good_target, !(flag && point_set_size(targets)));
			}

			/* Find the path. */
			path_n = project_path(path_g, MAX_RANGE, py, px, y, x, PROJECT_THRU);

			/* Draw the path in "target" mode. If there is one */
			if (mode & (TARGET_KILL))
				path_drawn = draw_path(path_n, path_g, path_char, path_attr, py, px);

			/* Describe and Prompt */
			press = target_set_interactive_aux(y, x, mode);

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

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

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


			/* Analyze */
			if (press.type == EVT_MOUSE) {
				if (press.mouse.button == 3) {
					/* give the target selection command */
					press.mouse.button = 2;
					press.mouse.mods = KC_MOD_CONTROL;
				}
				if (press.mouse.button == 2) {
					y = KEY_GRID_Y(press);//.mouse.y;
					x = KEY_GRID_X(press);//.mouse.x;
					if (press.mouse.mods & KC_MOD_CONTROL) {
						/* same as keyboard target selection command below */
						struct monster *m = cave_monster_at(cave, y, x);

						if (target_able(m)) {
							/* Set up target information */
							monster_race_track(m->race);
							health_track(p_ptr, m);
							target_set_monster(m);
							done = TRUE;
						} else {
							bell("Illegal target!");
						}
					} else
					if (press.mouse.mods & KC_MOD_ALT) {
						/* go to spot - same as 'g' command below */
						cmd_insert(CMD_PATHFIND);
						cmd_set_arg_point(cmd_get_top(), 0, y, x);
						done = TRUE;
					} else
					{
						/* cancel look mode */
						done = TRUE;
					}
				} else
				/*if (press.mouse.button == 3) {
				} else*/
				{
					y = KEY_GRID_Y(press);//.mouse.y;
					x = KEY_GRID_X(press);//.mouse.x;
					if (cave->m_idx[y][x] || cave->o_idx[y][x]){// || cave->feat[y][x]&) {
						/* reset the flag, to make sure we stay in this mode if
						 * something is actually there */
						flag = FALSE;
						/* scan the interesting list and see if there in anything here */
						for (i = 0; i < point_set_size(targets); i++) {
							if ((y == targets->pts[i].y) && (x == targets->pts[i].x)) {
								m = i;
								flag = TRUE;
								break;
							}
						}
					} else {
						flag = FALSE;
					}
				}
			} else
			switch (press.key.code)
			{
				case ESCAPE:
				case 'q':
				{
					done = TRUE;
					break;
				}

				case ' ':
				case '*':
				case '+':
				{
					if (++m == point_set_size(targets))
						m = 0;

					break;
				}

				case '-':
				{
					if (m-- == 0)
						m = point_set_size(targets) - 1;

					break;
				}

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

					/* Handle stuff */
					handle_stuff(p_ptr);

					y = p_ptr->py;
					x = p_ptr->px;
				}

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

				case 'm':
				{
					break;
				}

				case 't':
				case '5':
				case '0':
				case '.':
				{
					struct monster *m = cave_monster_at(cave, y, x);

					if (target_able(m))
					{
						health_track(p_ptr, m);
						target_set_monster(m);
						done = TRUE;
					}
					else
					{
						bell("Illegal target!");
					}
					break;
				}

				case 'g':
				{
					cmd_insert(CMD_PATHFIND);
					cmd_set_arg_point(cmd_get_top(), 0, y, x);
					done = TRUE;
					break;
				}
				
				case '?':
				{
					help = !help;
					
					/* Redraw main window */
					p_ptr->redraw |= (PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIP);
					Term_clear();
					handle_stuff(p_ptr);
					if (!help)
						prt("Press '?' for help.", help_prompt_loc, 0);
					
					break;
				}

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

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

					break;
				}
			}

			/* Hack -- move around */
			if (d)
			{
				int old_y = targets->pts[m].y;
				int old_x = targets->pts[m].x;

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

				/* 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 */
						point_set_dispose(targets);
						targets = target_set_interactive_prepare(mode);

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

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

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

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

		/* Arbitrary grids */
		else
		{
			/* Update help */
			if (help) 
			{
				bool good_target = target_able(cave_monster_at(cave, y, x));
				target_display_help(good_target, !(flag && point_set_size(targets)));
			}

			/* Find the path. */
			path_n = project_path(path_g, MAX_RANGE, py, px, y, x, PROJECT_THRU);

			/* Draw the path in "target" mode. If there is one */
			if (mode & (TARGET_KILL))
				path_drawn = draw_path (path_n, path_g, path_char, path_attr, py, px);

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

			/* 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 */
			if (press.type == EVT_MOUSE) {
				if (press.mouse.button == 3) {
					/* give the target selection command */
					press.mouse.button = 2;
					press.mouse.mods = KC_MOD_CONTROL;
				}
				if (press.mouse.button == 2) {
					if (mode & (TARGET_KILL)) {
						if ((y == KEY_GRID_Y(press)) 
								&& (x == KEY_GRID_X(press))) {
							d = -1;
						}
					}
					y = KEY_GRID_Y(press);//.mouse.y;
					x = KEY_GRID_X(press);//.mouse.x;
					if (press.mouse.mods & KC_MOD_CONTROL) {
						/* same as keyboard target selection command below */
						target_set_location(y, x);
						done = TRUE;
					} else
					if (press.mouse.mods & KC_MOD_ALT) {
						/* go to spot - same as 'g' command below */
						cmd_insert(CMD_PATHFIND);
						cmd_set_arg_point(cmd_get_top(), 0, y, x);
						done = TRUE;
					} else
					{
						/* cancel look mode */
						done = TRUE;
						if (d == -1) {
							target_set_location(y, x);
							d = 0;
						}
					}
				} else
				/*if (press.mouse.button == 3) {
				} else*/
				{
					int dungeon_hgt = cave->height;
					int dungeon_wid = cave->width;

					y = KEY_GRID_Y(press);//.mouse.y;
					x = KEY_GRID_X(press);//.mouse.x;
				  
					if (Term) {
						if (press.mouse.y <= 1) {
							/* move the screen north */
							y--;
						} else
						if (press.mouse.y >= (Term->hgt - 2)) {
							/* move the screen south */
							y++;
						} else
						if (press.mouse.x <= COL_MAP) {
							/* move the screen in west */
							x--;
						} else
						if (press.mouse.x >= (Term->wid - 2)) {
							/* move the screen east */
							x++;
						}
					}
          
					if (y < 0) y = 0;
					if (x < 0) x = 0;
					if (y >= dungeon_hgt-1) y = dungeon_hgt-1;
					if (x >= dungeon_wid-1) x = dungeon_wid-1;

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

						/* Recalculate interesting grids */
						point_set_dispose(targets);
						targets = target_set_interactive_prepare(mode);
					}

					if (cave->m_idx[y][x] || cave->o_idx[y][x]) {
						/* scan the interesting list and see if there in anything here */
						for (i = 0; i < point_set_size(targets); i++) {
							if ((y == targets->pts[i].y) && (x == targets->pts[i].x)) {
								m = i;
								flag = TRUE;
								break;
							}
						}
					} else {
						flag = FALSE;
					}
				}
			} else
			switch (press.key.code)
			{
				case ESCAPE:
				case 'q':
				{
					done = TRUE;
					break;
				}

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

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

					/* Handle stuff */
					handle_stuff(p_ptr);

					y = p_ptr->py;
					x = p_ptr->px;
				}

				case 'o':
				{
					break;
				}

				case 'm':
				{
					flag = TRUE;

					m = 0;
					bd = 999;

					/* Pick a nearby monster */
					for (i = 0; i < point_set_size(targets); i++)
					{
						t = distance(y, x, targets->pts[i].y, targets->pts[i].x);

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

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

					break;
				}

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

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

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

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

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

					break;
				}
			}

			/* Handle "direction" */
			if (d)
			{
				int dungeon_hgt = cave->height;
				int dungeon_wid = cave->width;

				/* 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_help(y, x, help))
				{
					/* Handle stuff */
					handle_stuff(p_ptr);

					/* Recalculate interesting grids */
					point_set_dispose(targets);
					targets = target_set_interactive_prepare(mode);
				}
			}
		}
	}

	/* Forget */
	point_set_dispose(targets);

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

	/* Handle stuff */
	handle_stuff(p_ptr);

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

	/* Success */
	return (TRUE);
}
Пример #13
0
/**
 * Bring up objects to act on 
 */
void do_cmd_show_obj(void)
{
    cptr q, s;
    int j, item;
    object_type *o_ptr;

    char o_name[120];
    byte out_color;
    bool accepted = FALSE;

    /* No restrictions */
    item_tester_tval = 0;
    item_tester_hook = NULL;

    /* See what's available */
    q = "Pick an item to use:";
    s = "You have no items to hand.";
    if (!get_item(&item, q, s, CMD_NULL, (USE_INVEN | USE_EQUIP | USE_FLOOR)))
	return;

    /* Got it */
    if (item >= 0) {
	o_ptr = &p_ptr->inventory[item];
    }

    /* Get the item (on the floor) */
    else {
	o_ptr = &o_list[0 - item];
    }

    /* Is it really an item? */
    if (!o_ptr->k_idx)
	return;

    /* No commands yet */
    poss = 0;

    /* Describe the object */
    object_desc(o_name, sizeof(o_name), o_ptr, ODESC_FULL);

    /* Hack -- enforce max length */
    o_name[Term->wid - 3] = '\0';

    /* Acquire inventory color.  Apply spellbook hack. */
    out_color = proc_list_color_hack(o_ptr);

    /* Wear/wield */
    if ((wield_slot(o_ptr) >= INVEN_WIELD) && (!SCHANGE)
	&& (item < INVEN_WIELD)) {
	comm[poss] = 'w';
	comm_code[poss] = CMD_WIELD;
	comm_descr[poss++] = "Wield";
    }

    /* Take off equipment */
    if ((item >= INVEN_WIELD) && (item < INVEN_TOTAL) && (!SCHANGE)) {
	comm[poss] = 't';
	comm_code[poss] = CMD_TAKEOFF;
	comm_descr[poss++] = "Take off";
    }

    /* Drop an item */
    if ((item >= 0) && ((item < INVEN_WIELD) || (!SCHANGE))) {
	comm[poss] = 'd';
	comm_code[poss] = CMD_DROP;
	comm_descr[poss++] = "Drop";
    }


    /* Destroy an item */
    if (item < INVEN_WIELD) {
	comm[poss] = 'k';
	comm_code[poss] = CMD_DESTROY;
	comm_descr[poss++] = "Destroy";
    }


    /* Identify an object */
    comm[poss] = 'I';
    comm_code[poss] = CMD_NULL;
    comm_descr[poss++] = "Inspect";

    /* Pick up an object */
    if ((item < 0) && inven_carry_okay(o_ptr)) {
	comm[poss] = 'g';
	comm_code[poss] = CMD_PICKUP;
	comm_descr[poss++] = "Pick up";
    }

    /* Book learnin' */
    if (mp_ptr->spell_book == o_ptr->tval) {
	if (p_ptr->new_spells) {
	    comm[poss] = 'G';
	    comm_code[poss] = CMD_STUDY_SPELL;
	    comm_descr[poss++] = "Gain a spell";
	}
	comm[poss] = 'b';
	comm_code[poss] = CMD_BROWSE_SPELL;
	comm_descr[poss++] = "Browse";
	comm[poss] = 'm';
	comm_code[poss] = CMD_CAST;
	comm_descr[poss++] = "Cast a spell";
    }

    /* Inscribe an object */
    comm[poss] = '{';
    comm_code[poss] = CMD_INSCRIBE;
    comm_descr[poss++] = "Inscribe";

    /* Uninscribe an object */
    if (o_ptr->note) {
	comm[poss] = '}';
	comm_code[poss] = CMD_UNINSCRIBE;
	comm_descr[poss++] = "Uninscribe";
    }

    /* Activate equipment */
    if ((o_ptr->effect) && (item >= INVEN_WIELD)) {
	comm[poss] = 'A';
	comm_code[poss] = CMD_ACTIVATE;
	comm_descr[poss++] = "Activate";
    }

    /* Eat some food */
    if (o_ptr->tval == TV_FOOD) {
	comm[poss] = 'E';
	comm_code[poss] = CMD_EAT;
	comm_descr[poss++] = "Eat";
    }

    if ((item < INVEN_WIELD)
	&& ((o_ptr->tval == TV_LIGHT) || (o_ptr->tval == TV_FLASK))) {
	object_type *o1_ptr = &p_ptr->inventory[INVEN_LIGHT];

	if (((o1_ptr->sval == SV_LIGHT_LANTERN)
	     && ((o_ptr->tval == TV_FLASK)
		 || ((o_ptr->tval == TV_LIGHT)
		     && (o_ptr->sval == SV_LIGHT_LANTERN))))
	    || ((o1_ptr->sval == SV_LIGHT_TORCH) && (o_ptr->tval == TV_LIGHT)
		&& (o_ptr->sval == SV_LIGHT_TORCH)))
	{
	    comm[poss] = 'F';
	    comm_code[poss] = CMD_REFILL;
	    comm_descr[poss++] = "Refuel";
	}
    }

    /* Fire an item */
    if (p_ptr->state.ammo_tval == o_ptr->tval) {
	comm[poss] = 'f';
	comm_code[poss] = CMD_FIRE;
	comm_descr[poss++] = "Fire";
    }

    /* Throw an item */
    if ((item < INVEN_WIELD) || (!SCHANGE)) {
	comm[poss] = 'v';
	comm_code[poss] = CMD_THROW;
	comm_descr[poss++] = "Throw";
    }

    /* Aim a wand */
    if (o_ptr->tval == TV_WAND) {
	comm[poss] = 'a';
	comm_code[poss] = CMD_USE_WAND;
	comm_descr[poss++] = "Aim";
    }

    /* Zap a rod */
    if (o_ptr->tval == TV_ROD) {
	comm[poss] = 'z';
	comm_code[poss] = CMD_USE_ROD;
	comm_descr[poss++] = "Zap";
    }

    /* Quaff a potion */
    if (o_ptr->tval == TV_POTION) {
	comm[poss] = 'q';
	comm_code[poss] = CMD_QUAFF;
	comm_descr[poss++] = "Quaff";
    }

    /* Read a scroll */
    if (o_ptr->tval == TV_SCROLL) {
	comm[poss] = 'r';
	comm_code[poss] = CMD_READ_SCROLL;
	comm_descr[poss++] = "Read";
    }

    /* Use a staff */
    if (o_ptr->tval == TV_STAFF) {
	comm[poss] = 'u';
	comm_code[poss] = CMD_USE_STAFF;
	comm_descr[poss++] = "Use";
    }

    /* Set up the screen */
    screen_save();

    /* Prompt */
    put_str("Choose a command, or ESC:", 0, 0);

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

    /* Display the item */
    c_put_str(out_color, o_name, 1, 0);

    /* Hack - delete exact graphics rows */
    if (tile_height > 1) {
	j = poss + 2;
	while ((j % tile_height) && (j <= SCREEN_ROWS))
	    prt("", ++j, 0);
    }

    /* Get a choice */
    accepted = show_cmd_menu(TRUE);

    /* Load de screen */
    screen_load();

    /* Now set the item if valid */
    if (accepted)
	cmd_set_arg_item(cmd_get_top(), 0, item);
}
Пример #14
0
static enum birth_stage point_based_command(void)
{
	static int stat = 0;
	struct keypress ch;
	enum birth_stage next = BIRTH_POINTBASED;

/*	point_based_display();*/

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

	/* Get key */
	ch = inkey();
	
	if (ch.code == KTRL('X')) 
	{
		cmd_insert(CMD_QUIT);
		next = BIRTH_COMPLETE;
	}
	
	/* Go back a step, or back to the start of this step */
	else if (ch.code == ESCAPE) 
	{
		next = BIRTH_BACK;
	}

	else if (ch.code == 'r' || ch.code == 'R') 
	{
		cmd_insert(CMD_RESET_STATS);
		cmd_set_arg_choice(cmd_get_top(), 0, FALSE);
	}
	
	/* Done */
	else if ((ch.code == '\r') || (ch.code == '\n')) 
	{
		next = BIRTH_NAME_CHOICE;
	}
	else
	{
		int dir = target_dir(ch);

		/* Prev stat, looping round to the bottom when going off the top */
		if (dir == 8)
			stat = (stat + A_MAX - 1) % A_MAX;
		
		/* Next stat, looping round to the top when going off the bottom */
		if (dir == 2)
			stat = (stat + 1) % A_MAX;
		
		/* Decrease stat (if possible) */
		if (dir == 4)
		{
			cmd_insert(CMD_SELL_STAT);
			cmd_set_arg_choice(cmd_get_top(), 0, stat);
		}
		
		/* Increase stat (if possible) */
		if (dir == 6)
		{
			cmd_insert(CMD_BUY_STAT);
			cmd_set_arg_choice(cmd_get_top(), 0, stat);
		}
	}

	return next;
}
Пример #15
0
/* Allow the user to select from the current menu, and return the 
   corresponding command to the game.  Some actions are handled entirely
   by the UI (displaying help text, for instance). */
static enum birth_stage menu_question(enum birth_stage current, menu_type *current_menu, cmd_code choice_command)
{
	struct birthmenu_data *menu_data = menu_priv(current_menu);
	ui_event cx;

	enum birth_stage next = BIRTH_RESET;
	
	/* Print the question currently being asked. */
	clear_question();
	Term_putstr(QUESTION_COL, QUESTION_ROW, -1, TERM_YELLOW, menu_data->hint);

	current_menu->cmd_keys = "?=*\x18";	 /* ?, =, *, <ctl-X> */

	while (next == BIRTH_RESET)
	{
		/* Display the menu, wait for a selection of some sort to be made. */
		cx = menu_select(current_menu, EVT_KBRD, FALSE);

		/* As all the menus are displayed in "hierarchical" style, we allow
		   use of "back" (left arrow key or equivalent) to step back in 
		   the proces as well as "escape". */
		if (cx.type == EVT_ESCAPE)
		{
			next = BIRTH_BACK;
		}
		else if (cx.type == EVT_SELECT)
		{
			if (current == BIRTH_ROLLER_CHOICE)
			{
				cmd_insert(CMD_FINALIZE_OPTIONS);

				if (current_menu->cursor)
				{
					/* Do a first roll of the stats */
					cmd_insert(CMD_ROLL_STATS);
					next = current + 2;
				}
				else
				{
					/* 
					 * Make sure we've got a point-based char to play with. 
					 * We call point_based_start here to make sure we get
					 * an update on the points totals before trying to
					 * display the screen.  The call to CMD_RESET_STATS
					 * forces a rebuying of the stats to give us up-to-date
					 * totals.  This is, it should go without saying, a hack.
					 */
					point_based_start();
					cmd_insert(CMD_RESET_STATS);
					cmd_set_arg_choice(cmd_get_top(), 0, TRUE);
					next = current + 1;
				}
			}
			else
			{
				cmd_insert(choice_command);
				cmd_set_arg_choice(cmd_get_top(), 0, current_menu->cursor);
				next = current + 1;
			}
		}
		else if (cx.type == EVT_KBRD)
		{
			/* '*' chooses an option at random from those the game's provided. */
			if (cx.key.code == '*' && menu_data->allow_random) 
			{
				current_menu->cursor = randint0(current_menu->count);
				cmd_insert(choice_command);
				cmd_set_arg_choice(cmd_get_top(), 0, current_menu->cursor);

				menu_refresh(current_menu, FALSE);
				next = current + 1;
			}
			else if (cx.key.code == '=') 
			{
				do_cmd_options_birth();
				next = current;
			}
			else if (cx.key.code == KTRL('X')) 
			{
				cmd_insert(CMD_QUIT);
				next = BIRTH_COMPLETE;
			}
			else if (cx.key.code == '?')
			{
				do_cmd_help();
			}
		}
	}
	
	return next;
}
Пример #16
0
/* pick the context menu options appropiate for the item */
int context_menu_object(const object_type *o_ptr, const int slot)
{
	menu_type *m;
	region r;
	int selected;
	char *labels;
	char header[120];

	textblock *tb;
	region area = { 0, 0, 0, 0 };

	bool allowed = TRUE;
	int mode = OPT(rogue_like_commands) ? KEYMAP_MODE_ROGUE : KEYMAP_MODE_ORIG;
	unsigned char cmdkey;

	m = menu_dynamic_new();
	if (!m || !o_ptr) {
		return 0;
	}
	object_desc(header, sizeof(header), o_ptr, ODESC_PREFIX | ODESC_BASE);

	labels = string_make(lower_case);
	m->selections = labels;

	/* 'I' is used for inspect in both keymaps. */
	menu_dynamic_add_label(m, "Inspect", 'I', MENU_VALUE_INSPECT, labels);

	if (obj_can_browse(o_ptr)) {
		if (obj_can_cast_from(o_ptr) && player_can_cast(p_ptr, FALSE)) {
			ADD_LABEL("Cast", CMD_CAST, MN_ROW_VALID);
		}

		if (obj_can_study(o_ptr) && player_can_study(p_ptr, FALSE)) {
			cmd_code study_cmd = player_has(PF_CHOOSE_SPELLS) ? CMD_STUDY_SPELL : CMD_STUDY_BOOK;
			/* Hack - Use the STUDY_BOOK command key so that we get the correct command key. */
			cmdkey = cmd_lookup_key_unktrl(CMD_STUDY_BOOK, mode);
			menu_dynamic_add_label(m, "Study", cmdkey, study_cmd, labels);
		}

		if (player_can_read(p_ptr, FALSE)) {
			ADD_LABEL("Browse", CMD_BROWSE_SPELL, MN_ROW_VALID);
		}
	}
	else if (obj_is_useable(o_ptr)) {
		if (obj_is_wand(o_ptr)) {
			menu_row_validity_t valid = (obj_has_charges(o_ptr)) ? MN_ROW_VALID : MN_ROW_INVALID;
			ADD_LABEL("Aim", CMD_USE_WAND, valid);
		}
		else if (obj_is_rod(o_ptr)) {
			menu_row_validity_t valid = (obj_can_zap(o_ptr)) ? MN_ROW_VALID : MN_ROW_INVALID;
			ADD_LABEL("Zap", CMD_USE_ROD, valid);
		}
		else if (obj_is_staff(o_ptr)) {
			menu_row_validity_t valid = (obj_has_charges(o_ptr)) ? MN_ROW_VALID : MN_ROW_INVALID;
			ADD_LABEL("Use", CMD_USE_STAFF, valid);
		}
		else if (obj_is_scroll(o_ptr)) {
			menu_row_validity_t valid = (player_can_read(p_ptr, FALSE)) ? MN_ROW_VALID : MN_ROW_INVALID;
			ADD_LABEL("Read", CMD_READ_SCROLL, valid);
		}
		else if (obj_is_potion(o_ptr)) {
			ADD_LABEL("Quaff", CMD_QUAFF, MN_ROW_VALID);
		}
		else if (obj_is_food(o_ptr)) {
			ADD_LABEL("Eat", CMD_EAT, MN_ROW_VALID);
		}
		else if (obj_is_activatable(o_ptr)) {
			menu_row_validity_t valid = (slot >= INVEN_WIELD && obj_can_activate(o_ptr)) ? MN_ROW_VALID : MN_ROW_INVALID;
			ADD_LABEL("Activate", CMD_ACTIVATE, valid);
		}
		else if (obj_can_fire(o_ptr)) {
			ADD_LABEL("Fire", CMD_FIRE, MN_ROW_VALID);
		}
		else {
			ADD_LABEL("Use", CMD_USE_ANY, MN_ROW_VALID);
		}
	}

	if (obj_can_refill(o_ptr)) {
		ADD_LABEL("Refill", CMD_REFILL, MN_ROW_VALID);
	}

	if (slot >= INVEN_WIELD && obj_can_takeoff(o_ptr)) {
		ADD_LABEL("Take off", CMD_TAKEOFF, MN_ROW_VALID);
	}
	else if (slot < INVEN_WIELD && obj_can_wear(o_ptr)) {
		//if (obj_is_armor(o_ptr)) {
		//	menu_dynamic_add(m, "Wear", 2);
		//} else {
		// 	menu_dynamic_add(m, "Wield", 2);
		//}
		ADD_LABEL("Equip", CMD_WIELD, MN_ROW_VALID);
	}

	if (slot >= 0) {
		if (!store_in_store || cave_shopnum(cave, p_ptr->py, p_ptr->px) == STORE_HOME) {
			ADD_LABEL("Drop", CMD_DROP, MN_ROW_VALID);

			if (o_ptr->number > 1) {
				/* 'D' is used for squelch in rogue keymap, so we'll just swap letters. */
				cmdkey = (mode == KEYMAP_MODE_ORIG) ? 'D' : 'k';
				menu_dynamic_add_label(m, "Drop All", cmdkey, MENU_VALUE_DROP_ALL, labels);
			}
		}
	}
	else {
		menu_row_validity_t valid = (inven_carry_okay(o_ptr)) ? MN_ROW_VALID : MN_ROW_INVALID;
		ADD_LABEL("Pick up", CMD_PICKUP, valid);
	}

	ADD_LABEL("Throw", CMD_THROW, MN_ROW_VALID);
	ADD_LABEL("Inscribe", CMD_INSCRIBE, MN_ROW_VALID);

	if (obj_has_inscrip(o_ptr)) {
		ADD_LABEL("Uninscribe", CMD_UNINSCRIBE, MN_ROW_VALID);
	}

	ADD_LABEL( (object_is_squelched(o_ptr) ? "Unignore" : "Ignore"), CMD_DESTROY, MN_ROW_VALID);

	/* work out display region */
	r.width = (int)menu_dynamic_longest_entry(m) + 3 + 2; /* +3 for tag, 2 for pad */
	r.col = Term->wid - r.width - 1;
	r.row = 1;
	r.page_rows = m->count;

	area.width = -(r.width + 2);

	/* Hack -- no flush needed */
	msg_flag = FALSE;
	screen_save();

	/* Display info */
	tb = object_info(o_ptr, OINFO_NONE);
	object_desc(header, sizeof(header), o_ptr, ODESC_PREFIX | ODESC_FULL);

	textui_textblock_place(tb, area, format("%s", header));
	textblock_free(tb);

	menu_layout(m, &r);
	region_erase_bordered(&r);

	prt(format("(Enter to select, ESC) Command for %s:", header), 0, 0);
	selected = menu_dynamic_select(m);

	menu_dynamic_free(m);
	string_free(labels);

	screen_load();

	cmdkey = cmd_lookup_key(selected, mode);

	switch (selected) {
		case -1:
			/* User cancelled the menu. */
			return 3;

		case MENU_VALUE_INSPECT:
			/* copied from textui_obj_examine */
			/* Display info */
			tb = object_info(o_ptr, OINFO_NONE);
			object_desc(header, sizeof(header), o_ptr, ODESC_PREFIX | ODESC_FULL);

			textui_textblock_show(tb, area, format("%s", header));
			textblock_free(tb);
			return 2;

		case MENU_VALUE_DROP_ALL:
			/* Drop entire stack with confirmation. */
			if (get_check(format("Drop %s? ", header))) {
				cmd_insert(store_in_store ? CMD_STASH : CMD_DROP);
				cmd_set_arg_item(cmd_get_top(), 0, slot);
				cmd_set_arg_number(cmd_get_top(), 1, o_ptr->number);
			}
			return 1;

		case CMD_STUDY_SPELL:
			/* Hack - Use the STUDY_BOOK command key so that get_item_allow() works properly. */
			cmdkey = cmd_lookup_key(CMD_STUDY_BOOK, mode);
			/* Fall through. */
		case CMD_BROWSE_SPELL:
		case CMD_STUDY_BOOK:
		case CMD_CAST:
		case CMD_DESTROY:
		case CMD_WIELD:
		case CMD_TAKEOFF:
		case CMD_INSCRIBE:
		case CMD_UNINSCRIBE:
		case CMD_PICKUP:
		case CMD_DROP:
		case CMD_REFILL:
		case CMD_THROW:
		case CMD_USE_WAND:
		case CMD_USE_ROD:
		case CMD_USE_STAFF:
		case CMD_READ_SCROLL:
		case CMD_QUAFF:
		case CMD_EAT:
		case CMD_ACTIVATE:
		case CMD_FIRE:
		case CMD_USE_ANY:
			/* Check for inscriptions that trigger confirmation. */
			allowed = key_confirm_command(cmdkey) && get_item_allow(slot, cmdkey, selected, FALSE);
			break;
		default:
			/* Invalid command; prevent anything from happening. */
			bell("Invalid context menu command.");
			allowed = FALSE;
			break;
	}

	if (!allowed)
		return 1;

	if (selected == CMD_DESTROY) {
		/* squelch or unsquelch the item */
		textui_cmd_destroy_menu(slot);
	}
	else if (selected == CMD_BROWSE_SPELL) {
		/* browse a spellbook */
		/* copied from textui_spell_browse */
		textui_book_browse(o_ptr);
		return 2;
	}
	else if (selected == CMD_STUDY_SPELL) {
		/* study a spell book */
		/* copied from textui_obj_study */
		int spell = get_spell(o_ptr, "study", spell_okay_to_study);

		if (spell >= 0) {
			cmd_insert(CMD_STUDY_SPELL);
			cmd_set_arg_choice(cmd_get_top(), 0, spell);
		}
	}
	else if (selected == CMD_CAST) {
		if (obj_can_browse(o_ptr)) {
			/* copied from textui_obj_cast */
			const char *verb = ((p_ptr->class->spell_book == TV_MAGIC_BOOK) ? "cast" : "recite");
			int spell = get_spell(o_ptr, verb, spell_okay_to_cast);

			if (spell >= 0) {
				cmd_insert(CMD_CAST);
				cmd_set_arg_choice(cmd_get_top(), 0, spell);
			}
		}
	}
	else {
Пример #17
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 path_n;
	u16b path_g[256];

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

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

	struct keypress query;

	/* 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 targetting" mode. */
	else
	{
		flag = FALSE;
	}

	/* Cancel target */
	target_set_monster(0);

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

	/* Calculate the window location for the help prompt */
	Term_get_size(&wid, &hgt);
	help_prompt_loc = hgt - 1;
	
	/* Display the help prompt */
	prt("Press '?' for help.", help_prompt_loc, 0);

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

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

	/* Interact */
	while (!done) {
		bool path_drawn = FALSE;
		
		/* Interesting grids */
		if (flag && temp_n)
		{
			y = temp_y[m];
			x = temp_x[m];

			/* Adjust panel if needed */
			if (adjust_panel_help(y, x, help)) handle_stuff();
		
			/* 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));
			}

			/* Find the path. */
			path_n = project_path(path_g, MAX_RANGE, py, px, y, x, PROJECT_THRU);

			/* Draw the path in "target" mode. If there is one */
			if (mode & (TARGET_KILL))
				path_drawn = draw_path(path_n, path_g, path_char, path_attr, py, px);

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

			/* 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.code)
			{
				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 = p_ptr->py;
					x = p_ptr->px;
				}

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

				case 'm':
				{
					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(p_ptr, m_idx);
						target_set_monster(m_idx);
						done = TRUE;
					}
					else
					{
						bell("Illegal target!");
					}
					break;
				}

				case 'g':
				{
					cmd_insert(CMD_PATHFIND);
					cmd_set_arg_point(cmd_get_top(), 0, y, x);
					done = TRUE;
					break;
				}
				
				case '?':
				{
					help = !help;
					
					/* Redraw main window */
					p_ptr->redraw |= (PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIP);
					Term_clear();
					handle_stuff();
					if (!help)
						prt("Press '?' for help.", help_prompt_loc, 0);
					
					break;
				}

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

					/* 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
		{
			/* 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));
			}

			/* Find the path. */
			path_n = project_path(path_g, MAX_RANGE, py, px, y, x, PROJECT_THRU);

			/* Draw the path in "target" mode. If there is one */
			if (mode & (TARGET_KILL))
				path_drawn = draw_path (path_n, path_g, path_char, path_attr, py, px);

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

			/* 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.code)
			{
				case ESCAPE:
				case 'q':
				{
					done = TRUE;
					break;
				}

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

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

					/* Handle stuff */
					handle_stuff();

					y = p_ptr->py;
					x = p_ptr->px;
				}

				case 'o':
				{
					break;
				}

				case 'm':
				{
					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 't':
				case '5':
				case '0':
				case '.':
				{
					target_set_location(y, x);
					done = TRUE;
					break;
				}

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

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

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

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

					break;
				}
			}

			/* Handle "direction" */
			if (d)
			{
				int dungeon_hgt = (p_ptr->depth == 0) ? TOWN_HGT : DUNGEON_HGT;
				int dungeon_wid = (p_ptr->depth == 0) ? TOWN_WID : DUNGEON_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_help(y, x, help))
				{
					/* 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();

	/* Handle stuff */
	handle_stuff();

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

	/* Success */
	return (TRUE);
}
Пример #18
0
/* pick the context menu options appropiate for an item available in a store */
int context_menu_store_item(struct store *store, const int oid, int mx, int my)
{
	menu_type *m;
	rect_region r;
	int selected;
	char *labels;
	object_type *o_ptr;
	char header[120];

	/* Get the actual object */
	o_ptr = &store->stock[oid];


	m = menu_dynamic_new();
	if (!m || !store) {
		return 0;
	}
	object_desc(header, sizeof(header), o_ptr, ODESC_PREFIX | ODESC_BASE);

	labels = string_make(lower_case);
	m->selections = labels;

	menu_dynamic_add_label(m, "Examine", 'x', 4, labels);
	if (store->sidx == STORE_HOME) {
		menu_dynamic_add_label(m, "Take", 'p', 6, labels);
		if (o_ptr->number > 1) {
			menu_dynamic_add_label(m, "Take One", 'o', 5, labels);
		}
	} else {
		menu_dynamic_add_label(m, "Buy", 'p', 6, labels);
		if (o_ptr->number > 1) {
			menu_dynamic_add_label(m, "Buy One", 'o', 5, labels);
		}
	}

	/* work out display region */
	r.width = menu_dynamic_longest_entry(m) + 3 + 2; /* +3 for tag, 2 for pad */
	if (mx > Term->wid - r.width - 1) {
		r.col = Term->wid - r.width - 1;
	} else {
		r.col = mx + 1;
	}
	r.page_rows = m->count;
	if (my > Term->hgt - r.page_rows - 1) {
		if (my - r.page_rows - 1 <= 0) {
			/* menu has too many items, so put in upper right corner */
			r.row = 1;
			r.col = Term->wid - r.width - 1;
		} else {
			r.row = Term->hgt - r.page_rows - 1;
		}
	} else {
		r.row = my + 1;
	}

	/* Hack -- no flush needed */
	msg_flag = FALSE;

	screen_save();
	button_backup_all(TRUE);

	menu_layout(m, &r);
	region_erase_bordered(&r);

	prt(format("(Enter to select, ESC) Command for %s:", header), 0, 0);
	selected = menu_dynamic_select(m);

	menu_dynamic_free(m);
	string_free(labels);

	button_restore();
	screen_load();

	if (selected == 4) {
		Term_keypress('x', 0);
	} else
	if (selected == 5) {
		if (store->sidx == STORE_HOME) {
			cmd_insert(CMD_RETRIEVE);
		} else {
			cmd_insert(CMD_BUY);
		}
		cmd_set_arg_choice(cmd_get_top(), 0, oid);
		cmd_set_arg_number(cmd_get_top(), 1, 1);
	} else
	if (selected == 6) {
		Term_keypress('p', 0);
	}

	return 1;
}
Пример #19
0
/**
 * Handle a textui mouseclick.
 */
static void textui_process_click(ui_event e)
{
	int x, y;

	if (!OPT(mouse_movement)) return;

	y = KEY_GRID_Y(e);
	x = KEY_GRID_X(e);

	/* Check for a valid location */
	if (!cave_in_bounds_fully(cave, y, x)) return;

	/* XXX show context menu here */
	if ((p_ptr->py == y) && (p_ptr->px == x)) {
		if (e.mouse.mods & KC_MOD_SHIFT) {
			/* shift-click - cast magic */
			if (e.mouse.button == 1) {
				textui_obj_cast();
			} else
			if (e.mouse.button == 2) {
				Term_keypress('i',0);
			}
		} else
		if (e.mouse.mods & KC_MOD_CONTROL) {
			/* ctrl-click - use feature / use inventory item */
			/* switch with default */
			if (e.mouse.button == 1) {
				if (cave_isupstairs(cave, p_ptr->py, p_ptr->px))
					cmd_insert(CMD_GO_UP);
				else if (cave_isdownstairs(cave, p_ptr->py, p_ptr->px))
					cmd_insert(CMD_GO_DOWN);
			} else
			if (e.mouse.button == 2) {
				cmd_insert(CMD_USE_UNAIMED);
			}
		} else
		if (e.mouse.mods & KC_MOD_ALT) {
			/* alt-click - Search  or show char screen */
			/* XXX call a platform specific hook */
			if (e.mouse.button == 1) {
 				cmd_insert(CMD_SEARCH);
			} else
			if (e.mouse.button == 2) {
				Term_keypress('C',0);
			}
		} else
		{
			if (e.mouse.button == 1) {
				if (cave->o_idx[y][x]) {
					cmd_insert(CMD_PICKUP);
				} else {
					cmd_insert(CMD_HOLD);
				}
			} else
			if (e.mouse.button == 2) {
				// show a context menu
				context_menu_player(e.mouse.x, e.mouse.y);
			}
		}
	}

	else if (e.mouse.button == 1)
	{
		if (p_ptr->timed[TMD_CONFUSED])
		{
			cmd_insert(CMD_WALK);
		}
		else
		{
			if (e.mouse.mods & KC_MOD_SHIFT) {
				/* shift-click - run */
				cmd_insert(CMD_RUN);
				cmd_set_arg_direction(cmd_get_top(), 0, coords_to_dir(y,x));
				/*if ((y-p_ptr->py >= -1) && (y-p_ptr->py <= 1)
					&& (x-p_ptr->px >= -1) && (x-p_ptr->px <= 1)) {
					cmd_insert(CMD_JUMP);
					cmd_set_arg_direction(cmd_get_top(), 0, coords_to_dir(y,x));
				} else {
				  cmd_insert(CMD_RUN);
				  cmd_set_arg_direction(cmd_get_top(), 0, coords_to_dir(y,x));
				}*/
			} else
			if (e.mouse.mods & KC_MOD_CONTROL) {
				/* control-click - alter */
				cmd_insert(CMD_ALTER);
				cmd_set_arg_direction(cmd_get_top(), 0, coords_to_dir(y,x));
			} else
			if (e.mouse.mods & KC_MOD_ALT) {
				/* alt-click - look */
				if (target_set_interactive(TARGET_LOOK, x, y)) {
					msg("Target Selected.");
				}
				//cmd_insert(CMD_LOOK);
				//cmd_set_arg_point(cmd_get_top(), 0, y, x);
			} else
			{
				/* pathfind does not work well on trap detection borders,
				 * so if the click is next to the player, force a walk step */
				if ((y-p_ptr->py >= -1) && (y-p_ptr->py <= 1)
					&& (x-p_ptr->px >= -1) && (x-p_ptr->px <= 1)) {
					cmd_insert(CMD_WALK);
					cmd_set_arg_direction(cmd_get_top(), 0, coords_to_dir(y,x));
				} else {
					cmd_insert(CMD_PATHFIND);
					cmd_set_arg_point(cmd_get_top(), 0, y, x);
				}
			}
		}
	}

	else if (e.mouse.button == 2)
	{
		struct monster *m = cave_monster_at(cave, y, x);
		if (m && target_able(m)) {
			/* Set up target information */
			monster_race_track(m->race);
			health_track(p_ptr, m);
			target_set_monster(m);
		} else {
			target_set_location(y,x);
		}
		if (e.mouse.mods & KC_MOD_SHIFT) {
			/* shift-click - cast spell at target */
			if (textui_obj_cast_ret() >= 0) {
				cmd_set_arg_target(cmd_get_top(), 1, DIR_TARGET);
			}
		} else
		if (e.mouse.mods & KC_MOD_CONTROL) {
			/* control-click - fire at target */
			cmd_insert(CMD_USE_AIMED);
			cmd_set_arg_target(cmd_get_top(), 1, DIR_TARGET);
		} else
		if (e.mouse.mods & KC_MOD_ALT) {
			/* alt-click - throw at target */
			cmd_insert(CMD_THROW);
			cmd_set_arg_target(cmd_get_top(), 1, DIR_TARGET);
		} else
		{
			//msg("Target set.");
			/* see if the click was adjacent to the player */
			if ((y-p_ptr->py >= -1) && (y-p_ptr->py <= 1)
				&& (x-p_ptr->px >= -1) && (x-p_ptr->px <= 1)) {
				context_menu_cave(cave,y,x,1,e.mouse.x, e.mouse.y);
			} else {
				context_menu_cave(cave,y,x,0,e.mouse.x, e.mouse.y);
			}
		}
	}
}
Пример #20
0
/* pick the context menu options appropiate for a store */
int context_menu_store(struct store *store, const int oid, int mx, int my)
{
	menu_type *m;
	rect_region r;
	int selected;
	char *labels;
	object_type *o_ptr;

	m = menu_dynamic_new();
	if (!m || !store) {
		return 0;
	}

	/* Get the actual object */
	o_ptr = &store->stock[oid];

	labels = string_make(lower_case);
	m->selections = labels;

	menu_dynamic_add_label(m, "Inspect Inventory", 'I', 1, labels);
	if (store->sidx == STORE_HOME) {
		/*menu_dynamic_add(m, "Stash One", 2);*/
		menu_dynamic_add_label(m, "Stash", 'd', 3, labels);
		menu_dynamic_add_label(m, "Examine", 'x', 4, labels);
		menu_dynamic_add_label(m, "Take", 'p', 6, labels);
		if (o_ptr->number > 1) {
			menu_dynamic_add_label(m, "Take One", 'o', 5, labels);
		}
	} else {
		/*menu_dynamic_add(m, "Sell One", 2);*/
		menu_dynamic_add_label(m, "Sell", 'd', 3, labels);
		menu_dynamic_add_label(m, "Examine", 'x', 4, labels);
		menu_dynamic_add_label(m, "Buy", 'p', 6, labels);
		if (o_ptr->number > 1) {
			menu_dynamic_add_label(m, "Buy One", 'o', 5, labels);
		}
	}
	menu_dynamic_add_label(m, "Exit", '`', 7, labels);


	/* work out display region */
	r.width = menu_dynamic_longest_entry(m) + 3 + 2; /* +3 for tag, 2 for pad */
	if (mx > Term->wid - r.width - 1) {
		r.col = Term->wid - r.width - 1;
	} else {
		r.col = mx + 1;
	}
	r.page_rows = m->count;
	if (my > Term->hgt - r.page_rows - 1) {
		if (my - r.page_rows - 1 <= 0) {
			/* menu has too many items, so put in upper right corner */
			r.row = 1;
			r.col = Term->wid - r.width - 1;
		} else {
			r.row = Term->hgt - r.page_rows - 1;
		}
	} else {
		r.row = my + 1;
	}

	/* Hack -- no flush needed */
	msg_flag = FALSE;

	screen_save();
	button_backup_all(TRUE);

	menu_layout(m, &r);
	region_erase_bordered(&r);

	prt("(Enter to select, ESC) Command:", 0, 0);
	selected = menu_dynamic_select(m);

	menu_dynamic_free(m);
	string_free(labels);

	button_restore();
	screen_load();

	if (selected == 1) {
		Term_keypress('I', 0);
	} else
	if (selected == 2) {
		Term_keypress('s', 0);
		/* oid is store item we do not know item we want to sell here */
		/*if (store->sidx == STORE_HOME) {
			cmd_insert(CMD_STASH);
		} else {
			cmd_insert(CMD_SELL);
		}
		cmd_set_arg_item(cmd_get_top(), 0, oid);
		cmd_set_arg_number(cmd_get_top(), 1, 1);*/
	} else
	if (selected == 3) {
		Term_keypress('s', 0);
	} else
	if (selected == 4) {
		Term_keypress('x', 0);
	} else
	if (selected == 5) {
		if (store->sidx == STORE_HOME) {
			cmd_insert(CMD_RETRIEVE);
		} else {
			cmd_insert(CMD_BUY);
		}
		cmd_set_arg_choice(cmd_get_top(), 0, oid);
		cmd_set_arg_number(cmd_get_top(), 1, 1);
	} else
	if (selected == 6) {
		Term_keypress('p', 0);
	} else
	if (selected == 7) {
		Term_keypress(ESCAPE, 0);
	}
	return 1;
}
Пример #21
0
int context_menu_cave(struct cave *c, int y, int x, int adjacent, int mx, int my)
{
	menu_type *m;
	region r;
	int selected;
	char *labels;
	bool allowed = TRUE;
	int mode = OPT(rogue_like_commands) ? KEYMAP_MODE_ROGUE : KEYMAP_MODE_ORIG;
	unsigned char cmdkey;

	m = menu_dynamic_new();
	if (!m) {
		return 0;
	}

	labels = string_make(lower_case);
	m->selections = labels;

	/* Looking has different keys, but we don't have a way to look them up (see cmd-process.c). */
	cmdkey = (mode == KEYMAP_MODE_ORIG) ? 'l' : 'x';
	menu_dynamic_add_label(m, "Look At", cmdkey, MENU_VALUE_LOOK, labels);

	if (c->m_idx[y][x]) {
		/* '/' is used for recall in both keymaps. */
		menu_dynamic_add_label(m, "Recall Info", '/', MENU_VALUE_RECALL, labels);
	}

	ADD_LABEL("Use Item On", CMD_USE_ANY, MN_ROW_VALID);

	if (player_can_cast(p_ptr, FALSE)) {
		ADD_LABEL("Cast On", CMD_CAST, MN_ROW_VALID);
	}

	if (adjacent) {
		ADD_LABEL((c->m_idx[y][x]) ? "Attack" : "Alter", CMD_ALTER, MN_ROW_VALID);

		if (c->o_idx[y][x]) {
			s16b o_idx = chest_check(y,x, CHEST_ANY);
			if (o_idx) {
				object_type *o_ptr = object_byid(o_idx);
				if (!squelch_item_ok(o_ptr)) {
					if (object_is_known(o_ptr)) {
						if (is_locked_chest(o_ptr)) {
							ADD_LABEL("Disarm Chest", CMD_DISARM, MN_ROW_VALID);
							ADD_LABEL("Open Chest", CMD_OPEN, MN_ROW_VALID);
						}
						else {
							ADD_LABEL("Open Disarmed Chest", CMD_OPEN, MN_ROW_VALID);
						}
					}
					else {
						ADD_LABEL("Open Chest", CMD_OPEN, MN_ROW_VALID);
					}
				}
			}
		}

		if (cave_istrap(c, y, x)) {
			ADD_LABEL("Disarm", CMD_DISARM, MN_ROW_VALID);
			ADD_LABEL("Jump Onto", CMD_JUMP, MN_ROW_VALID);
		}

		if (cave_isopendoor(c, y, x)) {
			ADD_LABEL("Close", CMD_CLOSE, MN_ROW_VALID);
		}
		else if (cave_iscloseddoor(c, y, x)) {
			ADD_LABEL("Open", CMD_OPEN, MN_ROW_VALID);
			ADD_LABEL("Lock", CMD_DISARM, MN_ROW_VALID);
		}
		else if (cave_isdiggable(c, y, x)) {
			ADD_LABEL("Tunnel", CMD_TUNNEL, MN_ROW_VALID);
		}

		ADD_LABEL("Search", CMD_SEARCH, MN_ROW_VALID);
		ADD_LABEL("Walk Towards", CMD_WALK, MN_ROW_VALID);
	}
	else {
		/* ',' is used for squelch in rogue keymap, so we'll just swap letters. */
		cmdkey = (mode == KEYMAP_MODE_ORIG) ? ',' : '.';
		menu_dynamic_add_label(m, "Pathfind To", cmdkey, CMD_PATHFIND, labels);

		ADD_LABEL("Walk Towards", CMD_WALK, MN_ROW_VALID);
		ADD_LABEL("Run Towards", CMD_RUN, MN_ROW_VALID);
	}

	if (player_can_fire(p_ptr, FALSE)) {
		ADD_LABEL("Fire On", CMD_FIRE, MN_ROW_VALID);
	}

	ADD_LABEL("Throw To", CMD_THROW, MN_ROW_VALID);

	/* work out display region */
	r.width = (int)menu_dynamic_longest_entry(m) + 3 + 2; /* +3 for tag, 2 for pad */
	if (mx > Term->wid - r.width - 1) {
		r.col = Term->wid - r.width - 1;
	} else {
		r.col = mx + 1;
	}
	r.page_rows = m->count;
	if (my > Term->hgt - r.page_rows - 1) {
		if (my - r.page_rows - 1 <= 0) {
			/* menu has too many items, so put in upper right corner */
			r.row = 1;
			r.col = Term->wid - r.width - 1;
		} else {
			r.row = Term->hgt - r.page_rows - 1;
		}
	} else {
		r.row = my + 1;
	}

	/* Hack -- no flush needed */
	msg_flag = FALSE;
	screen_save();

	menu_layout(m, &r);
	region_erase_bordered(&r);
	if (p_ptr->timed[TMD_IMAGE]) {
		prt("(Enter to select command, ESC to cancel) You see something strange:", 0, 0);
	} else
	if (c->m_idx[y][x]) {
		char m_name[80];
		monster_type *m_ptr = cave_monster_at(c, y, x);

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

		prt(format("(Enter to select command, ESC to cancel) You see %s:", m_name), 0, 0);
	} else
	if (c->o_idx[y][x] && !squelch_item_ok(object_byid(c->o_idx[y][x]))) {
		char o_name[80];

		/* Get the single object in the list */
		object_type *o_ptr = object_byid(c->o_idx[y][x]);

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

		prt(format("(Enter to select command, ESC to cancel) You see %s:", o_name), 0, 0);
	} else
	{
		/* Feature (apply mimic) */
		const char *name = cave_apparent_name(c, p_ptr, y, x);

		/* Hack -- special introduction for store doors */
		if (cave_isshop(cave, y, x)) {
			prt(format("(Enter to select command, ESC to cancel) You see the entrance to the %s:", name), 0, 0);
		} else {
			prt(format("(Enter to select command, ESC to cancel) You see %s %s:",
					(is_a_vowel(name[0])) ? "an" : "a", name), 0, 0);
		}
	}

	selected = menu_dynamic_select(m);

	menu_dynamic_free(m);
	string_free(labels);

	screen_load();

	cmdkey = cmd_lookup_key(selected, mode);

	/* Check the command to see if it is allowed. */
	switch (selected) {
		case -1:
			/* User cancelled the menu. */
			return 3;

		case MENU_VALUE_LOOK:
		case MENU_VALUE_RECALL:
		case CMD_PATHFIND:
			allowed = TRUE;
			break;

		case CMD_SEARCH:
		case CMD_ALTER:
		case CMD_DISARM:
		case CMD_JUMP:
		case CMD_CLOSE:
		case CMD_OPEN:
		case CMD_TUNNEL:
		case CMD_WALK:
		case CMD_RUN:
		case CMD_CAST:
		case CMD_FIRE:
		case CMD_THROW:
		case CMD_USE_ANY:
			/* Only check for ^ inscriptions, since we don't have an object selected (if we need one). */
			allowed = key_confirm_command(cmdkey);
			break;

		default:
			/* Invalid command; prevent anything from happening. */
			bell("Invalid context menu command.");
			allowed = FALSE;
			break;
	}

	if (!allowed)
		return 1;

	/* Perform the command. */
	switch (selected) {
		case MENU_VALUE_LOOK:
			/* look at the spot */
			if (target_set_interactive(TARGET_LOOK, x, y)) {
				msg("Target Selected.");
			}
			break;

		case MENU_VALUE_RECALL: {
			/* recall monster Info */
			monster_type *m_ptr = cave_monster_at(c, y, x);
			if (m_ptr) {
				monster_lore *lore = get_lore(m_ptr->race);
				lore_show_interactive(m_ptr->race, lore);
			}
		}
			break;

		case CMD_SEARCH:
			cmd_insert(selected);
			break;

		case CMD_PATHFIND:
			cmd_insert(selected);
			cmd_set_arg_point(cmd_get_top(), 0, x, y);
			break;

		case CMD_ALTER:
		case CMD_DISARM:
		case CMD_JUMP:
		case CMD_CLOSE:
		case CMD_OPEN:
		case CMD_TUNNEL:
		case CMD_WALK:
		case CMD_RUN:
			cmd_insert(selected);
			cmd_set_arg_direction(cmd_get_top(), 0, coords_to_dir(y,x));
			break;

		case CMD_CAST:
			if (textui_obj_cast_ret() >= 0) {
				cmd_set_arg_target(cmd_get_top(), 1, DIR_TARGET);
			}
			break;

		case CMD_FIRE:
		case CMD_THROW:
		case CMD_USE_ANY:
			cmd_insert(selected);
			cmd_set_arg_target(cmd_get_top(), 1, DIR_TARGET);
			break;

		default:
			break;
	}

	return 1;
}
Пример #22
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 i, d, m, t, bd;
	int wid, hgt, help_prompt_loc;

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

	ui_event_data query;

	/* 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 targetting" mode. */
	else
	{
		flag = FALSE;
	}

	/* Cancel target */
	target_set_monster(0);

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

	/* Calculate the window location for the help prompt */
	Term_get_size(&wid, &hgt);
	help_prompt_loc = hgt - 1;
	
	/* Display the help prompt */
	prt("Press '?' for help.", help_prompt_loc, 0);

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

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

	/* Interact */
	while (!done)
	{
		/* Interesting grids */
		if (flag && temp_n)
		{
			y = temp_y[m];
			x = temp_x[m];


			/* Adjust panel if needed */
			if (adjust_panel_help(y, x, help))
			{
				/* Handle stuff */
				handle_stuff();
			}
		
			/* 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));
			}

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

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

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


			/* 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. */
			if (query.type == EVT_MOUSE)
			{
				x = KEY_GRID_X(query);
				y = KEY_GRID_Y(query);
				flag = FALSE;
				break;
			}
			else
			{

			/* 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 = p_ptr->py;
					x = p_ptr->px;
				}

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

				case 'm':
				{
					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
					{
						bell("Illegal target!");
					}
					break;
				}

				case 'g':
				{
					cmd_insert(CMD_PATHFIND);
					cmd_set_arg_point(cmd_get_top(), 0, y, x);
					done = TRUE;
					break;
				}
				
				case '?':
				{
					help = !help;
					
					/* Redraw main window */
					p_ptr->redraw |= (PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIP);
					Term_clear();
					handle_stuff();
					if (!help)
						prt("Press '?' for 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
		{
			/* 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));
			}

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

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

			/* Assume no direction */
			d = 0;

			if (query.type == EVT_MOUSE)
			{
				/* 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;
			}
			else
			{

			/* 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 = p_ptr->py;
					x = p_ptr->px;
				}

				case 'o':
				{
					break;
				}

				case 'm':
				{
					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 't':
				case '5':
				case '0':
				case '.':
				{
					target_set_location(y, x);
					done = TRUE;
					break;
				}

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

				case '?':
				{
					help = !help;
					
					/* Redraw main window */
					p_ptr->redraw |= (PR_BASIC | PR_EXTRA | PR_MAP | PR_EQUIP);
					Term_clear();
					handle_stuff();
					if (!help)
						prt("Press '?' for 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->depth == 0) ? TOWN_HGT : DUNGEON_HGT;
				int dungeon_wid = (p_ptr->depth == 0) ? TOWN_WID : DUNGEON_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_help(y, x, help))
				{
					/* 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();

	/* Handle stuff */
	handle_stuff();

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

	/* Success */
	return (TRUE);
}
Пример #23
0
void textui_cmd_destroy(void)
{
	int item;
	object_type *o_ptr;

	char out_val[160];

	menu_type *m;
	region r;
	int selected;

	/* Get an item */
	const char *q = "Ignore which item? ";
	const char *s = "You have nothing to ignore.";
	if (!get_item(&item, q, s, CMD_DESTROY, USE_INVEN | USE_EQUIP | USE_FLOOR))
		return;

	o_ptr = object_from_item_idx(item);

	m = menu_dynamic_new();
	m->selections = lower_case;

	/* Basic ignore option */
	if (!o_ptr->ignore) {
		menu_dynamic_add(m, "This item only", IGNORE_THIS_ITEM);
	} else {
		menu_dynamic_add(m, "Unignore this item", UNIGNORE_THIS_ITEM);
	}

	/* Flavour-aware squelch */
	if (squelch_tval(o_ptr->tval) &&
			(!o_ptr->artifact || !object_flavor_is_aware(o_ptr))) {
		bool squelched = kind_is_squelched_aware(o_ptr->kind) ||
				kind_is_squelched_unaware(o_ptr->kind);

		char tmp[70];
		object_desc(tmp, sizeof(tmp), o_ptr, ODESC_BASE | ODESC_PLURAL);
		if (!squelched) {
			strnfmt(out_val, sizeof out_val, "All %s", tmp);
			menu_dynamic_add(m, out_val, IGNORE_THIS_FLAVOR);
		} else {
			strnfmt(out_val, sizeof out_val, "Unignore all %s", tmp);
			menu_dynamic_add(m, out_val, UNIGNORE_THIS_FLAVOR);
		}
	}

	/* Quality squelching */
	if (object_was_sensed(o_ptr) || object_was_worn(o_ptr) ||
			object_is_known_not_artifact(o_ptr)) {
		byte value = squelch_level_of(o_ptr);
		int type = squelch_type_of(o_ptr);

		if (object_is_jewelry(o_ptr) &&
					squelch_level_of(o_ptr) != SQUELCH_BAD)
			value = SQUELCH_MAX;

		if (value != SQUELCH_MAX && type != TYPE_MAX) {
			strnfmt(out_val, sizeof out_val, "All %s %s",
					quality_values[value].name, quality_choices[type].name);

			menu_dynamic_add(m, out_val, IGNORE_THIS_QUALITY);
		}
	}

	/* work out display region */
	r.width = menu_dynamic_longest_entry(m) + 3 + 2; /* +3 for tag, 2 for pad */
	r.col = 80 - r.width;
	r.row = 1;
	r.page_rows = m->count;

	screen_save();
	menu_layout(m, &r);
	region_erase_bordered(&r);

	prt("(Enter to select, ESC) Ignore:", 0, 0);
	selected = menu_dynamic_select(m);

	screen_load();

	if (selected == IGNORE_THIS_ITEM) {
		cmd_insert(CMD_DESTROY);
		cmd_set_arg_item(cmd_get_top(), 0, item);
	} else if (selected == UNIGNORE_THIS_ITEM) {
		o_ptr->ignore = FALSE;
	} else if (selected == IGNORE_THIS_FLAVOR) {
		object_squelch_flavor_of(o_ptr);
	} else if (selected == UNIGNORE_THIS_FLAVOR) {
		kind_squelch_clear(o_ptr->kind);
	} else if (selected == IGNORE_THIS_QUALITY) {
		byte value = squelch_level_of(o_ptr);
		int type = squelch_type_of(o_ptr);

		squelch_level[type] = value;
	}

	p_ptr->notice |= PN_SQUELCH;

	menu_dynamic_free(m);
}