示例#1
0
/*
 * Prompts for a keypress
 *
 * The "prompt" should take the form "Command: "
 *
 * Returns TRUE unless the character is "Escape"
 */
bool get_com(const char *prompt, struct keypress *command)
{
	ui_event ke;
	bool result;

	result = get_com_ex(prompt, &ke);
	*command = ke.key;

	return result;
}
示例#2
0
/**
 * Prompts for a keypress
 *
 * The "prompt" should take the form "Command: "
 * -------
 * Warning - this function assumes that the entered command is an ASCII
 *           character, and so should be used with great caution - NRM
 * -------
 * Returns true unless the character is "Escape"
 */
bool textui_get_com(const char *prompt, char *command)
{
    ui_event ke;
    bool result;

    result = get_com_ex(prompt, &ke);
    *command = (char)ke.key.code;

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

    ui_event_data ke;

    cptr p;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	ui_event ke = EVENT_EMPTY;

	const struct keypress *act = NULL;



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

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

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

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

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

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

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

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

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

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

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

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

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

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

			/* Continue */
			continue;
		}

		/* Done */
		break;
	}

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

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

	ui_event_data ke = EVENT_EMPTY;

	cptr act = NULL;



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

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

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


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

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

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

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

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

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

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


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

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

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

			/* Continue */
			continue;
		}

		/* Done */
		break;
	}

	return ke;
}
示例#7
0
int get_spell(int *sn, cptr p, cptr prompt, int *bn, bool known)
{
	int		i, num = 0;
	bool		flag, redraw;
	char		choice;
	event_type	ke;
	char		out_val[160];
	int			book = (*bn);
	int			book_over = 0;
	int			book_start = book;

	/* HACK -- spellcasting mode -- spell already selected */
	if (spellcasting_spell > -1)
	{
		(*sn) = spellcasting_spell;
		spellcasting = FALSE;
		spellcasting_spell = -1;
		return (TRUE);
	}

	/* Assume no spells available */
	(*sn) = -2;

	/* Check for available spells */
	num = count_spells_in_book(book, &book_over);

	/* No "okay" spells */
	if (!num) return (FALSE);

	/* Assume cancelled */
	(*sn) = -1;

	/* Nothing chosen yet */
	flag = FALSE;

	/* No redraw yet */
	redraw = FALSE;

	/* Show the list */
	if (auto_showlist)
	{
		/* Show list */
		redraw = TRUE;

		/* Save the screen */
		Term_save();

		/* Display a list of spells */
		print_spells(book);
	}

	/* Build a prompt (accept all spells) */
	strnfmt(out_val, 78, "(%s %c-%c, *=List, ESC=exit) %s",
		p, I2A(0), I2A(num - 1), prompt);

	/* Get a spell from the user */
	while (!flag && get_com_ex(out_val, &choice, &ke))
	{
		/* Hack -- mouse */
		if (choice == '\xff' && ke.index == 1)
		{
			choice = 'a' + ke.mousey - 2;
		}

		/* Enter by name */
		if (choice == '@' || choice == '"')
		{
			int _sn, _bn;
			if (choice == '"') prompt_quote_hack = TRUE;
			/* XXX Lookup item by name */
			if (get_spell_by_name(&_bn, &_sn, TRUE, FALSE, FALSE))
			{
				book = _bn;
				i = _sn;
				flag = TRUE;
			}
			else
			{
				bell();
			}
			continue;
		}

		/* Flip page */
		if (choice == '/')
		{
			int book_new = book; 
			int tmp = 0;
			
			/* End of list */
			if (!(num = count_spells_in_book(book + book_over, &tmp)))
			{
				/* Set 0 */ 
				book_new = book_start;
				tmp = 0;
				num = count_spells_in_book(book_new, &tmp);
				book_over = tmp;
			}
			/* Next book available */
			else
			{
				/* Advance */
				book_new = book + book_over;
				book_over = tmp;
			}
			/* Notice flip! */
			if (book_new != book)
			{
				/* Set */
				book = book_new;
				
				/* Re-Build a prompt (accept all spells) */
				strnfmt(out_val, 78, "(%s %c-%c, *=List, ESC=exit) %s",
					p, I2A(0), I2A(num - 1), prompt);

				/* Must redraw list */
				if (redraw)
				{
					/* Restore the screen */
					Term_load();
					Term_save();
	
					/* Display a list of spells */
					print_spells(book);
				}
			}
			/* Ask again */
			continue;
		}
		/* Request redraw */
		if ((choice == ' ') || (choice == '*') || (choice == '?'))
		{
			/* Show the list */
			if (!redraw)
			{
				/* Show list */
				redraw = TRUE;

				/* Save the screen */
				Term_save();

				/* Display a list of spells */
				print_spells(book);
			}

			/* Hide the list */
			else
			{
				/* Hide list */
				redraw = FALSE;

				/* Restore the screen */
				Term_load();

				/* The screen is OK now */
				section_icky_row = 0;
				section_icky_col = 0;

				/* Flush any events */
				Flush_queue();
			}

			/* Ask again */
			continue;
		}

		/* hack for CAPITAL prayers (heal other) */
		if (isupper(choice))
		{
			i = (choice - 'A');
			if (i >= num) i = -1;
			else if (!(spell_flag[(book * SPELLS_PER_BOOK + i)] & PY_SPELL_PROJECT)) i = -1;
			if (i != -1)
				i += SPELL_PROJECTED;
		}
		/* lowercase */
		else if (islower(choice))
		{
			i = A2I(choice);
			if (i >= num) i = -1;
		}
		/* not a letter */
		else i = -1;

		/* Totally Illegal */
		if (i < 0)
		{
			bell();
			continue;
		}

		/* Stop the loop */
		flag = TRUE;
	}

	/* Restore the screen */
	if (redraw)
	{
		Term_load();

		/* The screen is OK now */
		section_icky_row = 0;
		section_icky_col = 0;

		/* Flush any events */
		Flush_queue();
	}


	/* Abort if needed */
	if (!flag) return (FALSE);

	/* Save the choice */
	(*sn) = i;
	(*bn) = book;

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

    ui_event ke;

    const char *p;

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

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

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

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

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

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

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

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

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

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

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

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

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

    /* A "valid" direction was entered */
    return (true);
}