예제 #1
0
파일: mbcopy.cpp 프로젝트: 0xDEC0DE8/mcsema
int main( int argc, char * argv[] )
{
  if ( argc != 2 )
  {
    std::cout << "Copy files in the current directory to a target directory\n"
              << "Usage: mbcopy <target-dir>\n";
    return 1;
  }

  // For encoding, use Boost UTF-8 codecvt
  std::locale global_loc = std::locale();
  std::locale loc( global_loc, new fs::detail::utf8_codecvt_facet );
  user::mbpath_traits::imbue( loc );

  std::string target_string( argv[1] );
  user::mbpath target_dir( user::mbpath_traits::to_internal( target_string ) );

  if ( !fs::is_directory( target_dir ) )
  {
    std::cout << "Error: " << argv[1] << " is not a directory\n";
    return 1;
  }

  for ( fs::wdirectory_iterator it( L"." );
    it != fs::wdirectory_iterator(); ++it )
  {
    if ( fs::is_regular_file(it->status()) )
    {
      copy_file( *it, target_dir / it->path().filename() );
    }
  }

  return 0;
}
예제 #2
0
///////////////////////////////////////////////////////////////////////////////
// function allowing to deploy the current executable to the remote machine, 
// where it is supposed to be launched. return the directory name the job got 
// deployed
std::string deploy_me(std::string path, std::string target_host)
{
    // construct unique target directory
    std::string targetdir("/tmp/saga_tutorial/");
    targetdir += boost::lexical_cast<std::string>(getuid());
    targetdir += "/";
    targetdir += boost::lexical_cast<std::string>(getpid());
    targetdir += "/";

    // copy the executable to the remote directory
    fs::path exe(path);

    // Create remote directory
    saga::url target_dir(targetdir);
    target_dir.set_scheme("any");         // we rely on adaptor selection
    target_dir.set_host(get_host(target_host));
    saga::filesystem::directory d(target_dir, saga::filesystem::Create|saga::filesystem::CreateParents);

    // copy the executable
    saga::url source(exe.filename());
    saga::filesystem::file f(source);

    saga::url target(targetdir + "/" + exe.filename());
    target.set_scheme("any");            // we rely on adaptor selection
    target.set_host(get_host(target_host));
    f.copy(target);

    return targetdir;
}
예제 #3
0
static enum birth_stage point_based_command(void)
{
	static int stat = 0;
	struct keypress ch;
	enum birth_stage next = BIRTH_POINTBASED;

	/* 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')) {
		quit(NULL);
	} else if (ch.code == ESCAPE) {
		/* Go back a step, or back to the start of this step */
		next = BIRTH_BACK;
	} else if (ch.code == 'r' || ch.code == 'R') {
		cmdq_push(CMD_RESET_STATS);
		cmd_set_arg_choice(cmdq_peek(), "choice", FALSE);
	} else if (ch.code == KC_ENTER) {
		/* Done */
		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 + STAT_MAX - 1) % STAT_MAX;
		
		/* Next stat, looping round to the top when going off the bottom */
		if (dir == 2)
			stat = (stat + 1) % STAT_MAX;
		
		/* Decrease stat (if possible) */
		if (dir == 4) {
			cmdq_push(CMD_SELL_STAT);
			cmd_set_arg_choice(cmdq_peek(), "choice", stat);
		}
		
		/* Increase stat (if possible) */
		if (dir == 6) {
			cmdq_push(CMD_BUY_STAT);
			cmd_set_arg_choice(cmdq_peek(), "choice", stat);
		}
	}

	return next;
}
예제 #4
0
파일: target.c 프로젝트: Dasaan/angband
/*
 * 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);
}
예제 #5
0
/*
 *  Do glyph picker command -- Change glyphs
 */
static bool glyph_command(ui_event ke, bool * glyph_picker_ptr,
						  int height, int width, byte * cur_attr_ptr,
						  wchar_t * cur_char_ptr, int col, int row)
{
	static byte attr_old = 0;
	static char char_old = 0;

	/* Get mouse movement */
	if (ke.type == EVT_MOUSE) {
		byte a = *cur_attr_ptr;

		int mx = logical_width(ke.mouse.x - col);

		if (ke.mouse.y != row + height / 2)
			return FALSE;

		if ((mx >= 0) && (mx < MAX_COLORS) && (ke.mouse.button == 1)) {
			/* Set the visual */
			*cur_attr_ptr = a = mx - 14;

			/* Accept change */
			remove_tiles(col, row, glyph_picker_ptr, width, height);

			return TRUE;
		}

		else {
			return FALSE;
		}
	}

	if (ke.type != EVT_KBRD)
		return FALSE;


	switch (ke.key.code) {
	case ESCAPE:
		{
			if (*glyph_picker_ptr) {
				/* Cancel change */
				*cur_attr_ptr = attr_old;
				*cur_char_ptr = char_old;
				remove_tiles(col, row, glyph_picker_ptr, width, height);

				return TRUE;
			}

			break;
		}

	case KC_ENTER:
		{
			if (*glyph_picker_ptr) {
				/* Accept change */
				remove_tiles(col, row, glyph_picker_ptr, width, height);
				return TRUE;
			}

			break;
		}

	case 'V':
	case 'v':
		{
			if (!*glyph_picker_ptr) {
				*glyph_picker_ptr = TRUE;

				attr_old = *cur_attr_ptr;
				char_old = *cur_char_ptr;
			} else {
				/* Cancel change */
				*cur_attr_ptr = attr_old;
				*cur_char_ptr = char_old;
				remove_tiles(col, row, glyph_picker_ptr, width, height);
			}

			return TRUE;
		}

	case 'i':
	case 'I':
		{
			if (*glyph_picker_ptr) {
				char code_point[6];
				bool res = FALSE;

				/* Ask the user for a code point */
				Term_gotoxy(col, row + height / 2 + 2);
				res = get_string("(up to 5 hex digits):", code_point, 5);

				/* Process input */
				if (res) {
					unsigned long int point =
						strtoul(code_point, (char **) NULL, 16);
					*cur_char_ptr = (wchar_t) point;
					return TRUE;
				}
			}

			break;


		}

	default:
		{
			int d = target_dir(ke.key);
			byte a = *cur_attr_ptr;

			if (!*glyph_picker_ptr)
				break;

			/* Horizontal only */
			if (ddy[d] != 0)
				break;

			/* Horizontal movement */
			if (ddx[d] != 0) {
				a += ddx[d] + BASIC_COLORS;
				a = a % BASIC_COLORS;
				*cur_attr_ptr = a;
			}


			/* We need to always eat the input even if it is clipped,
			 * otherwise it will be interpreted as a change object
			 * selection command with messy results.
			 */
			return TRUE;
		}
	}


	/* Glyph picker command is not used */
	return FALSE;
}
예제 #6
0
/*
 *  Do tile picker command -- Change tiles
 */
static bool tile_picker_command(ui_event ke, bool * tile_picker_ptr,
								int height, int width, byte * attr_top_ptr,
								byte * char_left_ptr, byte * cur_attr_ptr,
								byte * cur_char_ptr, int col, int row,
								int *delay)
{
	static byte attr_old = 0;
	static char char_old = 0;

	/* These are the distance we want to maintain between the cursor and
	 * borders. */
	int frame_left = logical_width(10);
	int frame_right = logical_width(10);
	int frame_top = logical_height(4);
	int frame_bottom = logical_height(4);

	/* Get mouse movement */
	if (ke.type == EVT_MOUSE) {
		int eff_width = actual_width(width);
		int eff_height = actual_height(height);
		byte a = *cur_attr_ptr;
		byte c = *cur_char_ptr;

		int my = logical_height(ke.mouse.y - row);
		int mx = logical_width(ke.mouse.x - col);

		if ((my >= 0) && (my < eff_height) && (mx >= 0) && (mx < eff_width)
			&& ((ke.mouse.button == 1) || (a != *attr_top_ptr + my)
				|| (c != *char_left_ptr + mx))) {
			/* Set the visual */
			*cur_attr_ptr = a = *attr_top_ptr + my;
			*cur_char_ptr = c = *char_left_ptr + mx;

			/* Move the frame */
			if (*char_left_ptr > MAX(0, (int) c - frame_left))
				(*char_left_ptr)--;
			if (*char_left_ptr + eff_width <=
				MIN(255, (int) c + frame_right))
				(*char_left_ptr)++;
			if (*attr_top_ptr > MAX(0, (int) a - frame_top))
				(*attr_top_ptr)--;
			if (*attr_top_ptr + eff_height <=
				MIN(255, (int) a + frame_bottom))
				(*attr_top_ptr)++;

			/* Delay */
			*delay = 100;

			/* Accept change */
			if (ke.mouse.button)
				remove_tiles(col, row, tile_picker_ptr, width, height);

			return TRUE;
		}

		/* Cancel change */
		else if (ke.mouse.button == 2) {
			*cur_attr_ptr = attr_old;
			*cur_char_ptr = char_old;
			remove_tiles(col, row, tile_picker_ptr, width, height);

			return TRUE;
		}

		else {
			return FALSE;
		}
	}

	if (ke.type != EVT_KBRD)
		return FALSE;


	switch (ke.key.code) {
	case ESCAPE:
		{
			if (*tile_picker_ptr) {
				/* Cancel change */
				*cur_attr_ptr = attr_old;
				*cur_char_ptr = char_old;
				remove_tiles(col, row, tile_picker_ptr, width, height);

				return TRUE;
			}

			break;
		}

	case KC_ENTER:
		{
			if (*tile_picker_ptr) {
				/* Accept change */
				remove_tiles(col, row, tile_picker_ptr, width, height);
				return TRUE;
			}

			break;
		}

	case 'V':
	case 'v':
		{
			/* No visual mode without graphics, for now - NRM */
			if (current_graphics_mode != NULL)
				if (current_graphics_mode->grafID == 0)
					break;

			if (!*tile_picker_ptr) {
				*tile_picker_ptr = TRUE;
				bigcurs = TRUE;

				*attr_top_ptr =
					(byte) MAX(0, (int) *cur_attr_ptr - frame_top);
				*char_left_ptr =
					(char) MAX(0, (int) *cur_char_ptr - frame_left);

				attr_old = *cur_attr_ptr;
				char_old = *cur_char_ptr;
			} else {
				/* Cancel change */
				*cur_attr_ptr = attr_old;
				*cur_char_ptr = char_old;
				remove_tiles(col, row, tile_picker_ptr, width, height);
			}

			return TRUE;
		}

	case 'C':
	case 'c':
		{
			/* Set the tile */
			attr_idx = *cur_attr_ptr;
			char_idx = *cur_char_ptr;

			return TRUE;
		}

	case 'P':
	case 'p':
		{
			if (attr_idx) {
				/* Set the char */
				*cur_attr_ptr = attr_idx;
				*attr_top_ptr =
					(byte) MAX(0, (int) *cur_attr_ptr - frame_top);
			}

			if (char_idx) {
				/* Set the char */
				*cur_char_ptr = char_idx;
				*char_left_ptr =
					(char) MAX(0, (int) *cur_char_ptr - frame_left);
			}

			return TRUE;
		}

	default:
		{
			int d = target_dir(ke.key);
			byte a = *cur_attr_ptr;
			byte c = *cur_char_ptr;

			if (!*tile_picker_ptr)
				break;

			bigcurs = TRUE;

			/* Restrict direction */
			if ((a == 0) && (ddy[d] < 0))
				d = 0;
			if ((c == 0) && (ddx[d] < 0))
				d = 0;
			if ((a == 255) && (ddy[d] > 0))
				d = 0;
			if ((c == 255) && (ddx[d] > 0))
				d = 0;

			a += ddy[d];
			c += ddx[d];

			/* Set the tile */
			*cur_attr_ptr = a;
			*cur_char_ptr = c;

			/* Move the frame */
			if (ddx[d] < 0 &&
				*char_left_ptr > MAX(0, (int) c - frame_left))
				(*char_left_ptr)--;
			if ((ddx[d] > 0) &&
				*char_left_ptr + (width / tile_width) <=
				MIN(255, (int) c + frame_right))
				(*char_left_ptr)++;

			if (ddy[d] < 0 && *attr_top_ptr > MAX(0, (int) a - frame_top))
				(*attr_top_ptr)--;
			if (ddy[d] > 0 &&
				*attr_top_ptr + (height / tile_height) <=
				MIN(255, (int) a + frame_bottom))
				(*attr_top_ptr)++;

			/* We need to always eat the input even if it is clipped,
			 * otherwise it will be interpreted as a change object
			 * selection command with messy results.
			 */
			return TRUE;
		}
	}


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

    ui_event_data ke;

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

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

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

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

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

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

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

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

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

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

		    return (FALSE);
		}

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

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

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

		inkey_scan = lazymove_delay;
		ke = inkey_ex();
	    }

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

		return (FALSE);
	    }
	}

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

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

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

    /* Success */
    return (TRUE);
}
예제 #8
0
/**
 * Modify the "window" options
 */
static void do_cmd_options_win(const char *name, int row)
{
	int i, j, d;
	int y = 0;
	int x = 0;
	ui_event ke;
	u32b new_flags[ANGBAND_TERM_MAX];

	/* Set new flags to the old values */
	for (j = 0; j < ANGBAND_TERM_MAX; j++)
		new_flags[j] = window_flag[j];

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

	/* Interact */
	while (1) {
		/* Prompt */
		prt("Window flags (<dir> to move, 't'/Enter to toggle, or ESC)", 0, 0);

		/* Display the windows */
		for (j = 0; j < ANGBAND_TERM_MAX; j++) {
			byte a = COLOUR_WHITE;

			const char *s = angband_term_name[j];

			/* Use color */
			if (j == x) a = COLOUR_L_BLUE;

			/* Window name, staggered, centered */
			Term_putstr(35 + j * 5 - strlen(s) / 2, 2 + j % 2, -1, a, s);
		}

		/* Display the options */
		for (i = 0; i < PW_MAX_FLAGS; i++) {
			byte a = COLOUR_WHITE;

			const char *str = window_flag_desc[i];

			/* Use color */
			if (i == y) a = COLOUR_L_BLUE;

			/* Unused option */
			if (!str) str = "(Unused option)";

			/* Flag name */
			Term_putstr(0, i + 5, -1, a, str);

			/* Display the windows */
			for (j = 0; j < ANGBAND_TERM_MAX; j++) {
				char c = '.';

				a = COLOUR_WHITE;

				/* Use color */
				if ((i == y) && (j == x)) a = COLOUR_L_BLUE;

				/* Active flag */
				if (new_flags[j] & (1L << i)) c = 'X';

				/* Flag value */
				Term_putch(35 + j * 5, i + 5, a, c);
			}
		}

		/* Place Cursor */
		Term_gotoxy(35 + x * 5, y + 5);

		/* Get key */
		ke = inkey_ex();

		/* Mouse or keyboard interaction */
		if (ke.type == EVT_MOUSE) {
			int choicey = ke.mouse.y - 5;
			int choicex = (ke.mouse.x - 35)/5;

			if (ke.mouse.button == 2)
				break;

			if ((choicey >= 0) && (choicey < PW_MAX_FLAGS)
				&& (choicex > 0) && (choicex < ANGBAND_TERM_MAX)
				&& !(ke.mouse.x % 5)) {
				if ((choicey == y) && (choicex == x)) {
					/* Toggle flag (off) */
					if (new_flags[x] & (1L << y))
						new_flags[x] &= ~(1L << y);
					/* Toggle flag (on) */
					else
						new_flags[x] |= (1L << y);
				} else {
					y = choicey;
					x = (ke.mouse.x - 35)/5;
				}
			}
		} else if (ke.type == EVT_KBRD) {
			if (ke.key.code == ESCAPE || ke.key.code == 'q')
				break;

			/* Toggle */
			else if (ke.key.code == '5' || ke.key.code == 't' ||
					ke.key.code == KC_ENTER) {
				/* Hack -- ignore the main window */
				if (x == 0)
					bell("Cannot set main window flags!");

				/* Toggle flag (off) */
				else if (new_flags[x] & (1L << y))
					new_flags[x] &= ~(1L << y);

				/* Toggle flag (on) */
				else
					new_flags[x] |= (1L << y);

				/* Continue */
				continue;
			}

			/* Extract direction */
			d = target_dir(ke.key);

			/* Move */
			if (d != 0) {
				x = (x + ddx[d] + 8) % ANGBAND_TERM_MAX;
				y = (y + ddy[d] + 16) % PW_MAX_FLAGS;
			}
		}
	}

	/* Notice changes */
	subwindows_set_flags(new_flags, ANGBAND_TERM_MAX);

	screen_load();
}
예제 #9
0
파일: target.c 프로젝트: EpicMan/angband
/*
 * 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);
}
예제 #10
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". Also DIR_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, bool target_trap)
{
    /* Global direction */
    int dir = 0;
    int old_dir;

    bool done = FALSE;

    int mode = TARGET_QUIET;

    if (target_trap) mode |= TARGET_TRAP;
    else mode |= TARGET_KILL;

    if (*dp == DIR_CLOSEST)
    {
        if (target_set_closest(mode))
        {
            return(TRUE);
        }
    }

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

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

    else ui_update_message_label(color_string("Please select a target.", TERM_L_RED));

    ui_targeting_show(MODE_TARGETING_AIMING);

    /* Ask until satisfied */
    while (!dir && !done)
    {
        ui_show_cursor(p_ptr->py, p_ptr->px);        

        /* Get a command (or Cancel) */
        UserInput input = ui_get_input();

        // Paranoia
        if (input.mode == INPUT_MODE_NONE) break;

        if ((input.key == Qt::Key_Escape) || (input.key == Qt::Key_X))
        {
            break;
        }
        // Do nothing
        if (input.mode == INPUT_MODE_MOUSE_WHEEL)
        {
            continue;
        }

        // Skip interactive mode and directly choose target.
        if (input.mode == INPUT_MODE_MOUSE_DOUBLE_CLICK)
        {
            if (set_selected_target(mode, input.y, input.x)) dir = DIR_TARGET;
            else if (set_selected_target(TARGET_GRID, input.y, input.x)) dir = DIR_TARGET;
            continue;
        }

        if (input.mode == INPUT_MODE_MOUSE_SINGLE_CLICK)
        {
            /* Calculate approximate angle */
            if (target_set_interactive(mode, input.x, input.y)) dir = DIR_TARGET;
            else done = TRUE;
            continue;
        }

        /* Analyze */
        switch (input.key)
        {
            case Qt::Key_M:
            case Qt::Key_Asterisk:
            {
                /* Set new target, use target if legal */
                int mode = TARGET_KILL;
                if (target_trap) mode |= TARGET_TRAP;
                if (target_set_interactive(mode, -1, -1)) dir = DIR_TARGET;
                else done = TRUE;
                continue;
            }
            case Qt::Key_C:
            case Qt::Key_Comma:
            {
                /* Set to closest target */
                if (target_set_closest(TARGET_KILL))
                {
                    dir = DIR_CLOSEST;
                    continue;
                }
                break;
            }
            case Qt::Key_Question:
            {
                do_cmd_list_targeting_commands();
                continue;
            }
            case Qt::Key_H:
            case Qt::Key_5:
            case Qt::Key_Period:
            case Qt::Key_Clear:
            {
                /* Use current target, if set and legal */
                if (target_okay()) dir = DIR_TARGET;
                break;
            }
            default:
            {
                /* Possible direction */
                dir = target_dir(input);
                break;
            }
        }

        /* Error */
        if (!dir) color_message("Illegal aim direction!", TERM_ORANGE);
    }

    ui_targeting_hide();

    ui_show_cursor(-1, -1);

    ui_clear_message_label();

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

    /* Save the direction */
    old_dir = dir;

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

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

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

    /* A "valid" direction was entered */
    return (TRUE);
}
예제 #11
0
/*
 * Generic "get choice from menu" function
 */
static int get_player_choice(birth_menu *choices, int num, int def, int col, int wid, void (*hook)(birth_menu))
{
	int top = 0, next;
	int i, dir;
	char c;
	char buf[300];
	bool done = FALSE;
	int hgt;
	byte attr;
	int cur = (def) ? def : 0; 

	/* Autoselect if able */
	//if (num == 1) done = TRUE;

	/* Clear */
	for (i = TABLE_ROW; i < DESCRIPTION_ROW + 4; i++)
	{
		/* Clear */
		Term_erase(col, i, Term->wid - wid);
	}

	/* Choose */
	while (TRUE)
	{
		hgt = Term->hgt - TABLE_ROW - 1;

		/* Redraw the list */
		for (i = 0; ((i + top < num) && (i <= hgt)); i++)
		{
			if (i + top < 26)
			{
				strnfmt(buf, sizeof(buf), "%c) %s", I2A(i + top), choices[i + top].name);
			}
			else
			{
				/* ToDo: Fix the ASCII dependency */
				strnfmt(buf, sizeof(buf), "%c) %s", 'A' + (i + top - 26), choices[i + top].name);
			}

			/* Clear */
			Term_erase(col, i + TABLE_ROW, wid);

			/* Display */
			if (i == (cur - top))
			{
				/* Highlight the current selection */
				if (choices[i + top].ghost) attr = TERM_BLUE;
				else attr = TERM_L_BLUE;
			}
			else
			{
				if (choices[i + top].ghost) attr = TERM_SLATE;
				else attr = TERM_WHITE;
			}

			Term_putstr(col, i + TABLE_ROW, wid, attr, buf);
		}

		Term_erase(0, DESCRIPTION_ROW + 0, 255);
		Term_erase(0, DESCRIPTION_ROW + 1, 255);
		Term_erase(0, DESCRIPTION_ROW + 2, 255);
		Term_erase(0, DESCRIPTION_ROW + 3, 255);
		Term_erase(0, DESCRIPTION_ROW + 4, 255);
		
		if (choices[cur+top].text != NULL)
		{

			/* Indent output by 2 character, and wrap at column 70 */
			text_out_wrap = 70;
			text_out_indent = 2;

			/* History */
			Term_gotoxy(text_out_indent, DESCRIPTION_ROW);
			text_out_to_screen(TERM_L_WHITE, choices[cur+top].text);

			/* Reset text_out() vars */
			text_out_wrap = 0;
			text_out_indent = 0;
		}
		
		else
		{
			/* Extra info */
//			Term_putstr(QUESTION_COL, DESCRIPTION_ROW, -1, TERM_L_WHITE,
//						"Your sex has no gameplay effect.");
			
		}

		if (done) return (cur);

		/* Display auxiliary information if any is available. */
		if (hook) hook(choices[cur]);


		/* Move the cursor */
		put_str("", TABLE_ROW + cur - top, col);

		hide_cursor = TRUE;
		c = inkey();
		hide_cursor = FALSE;

		/* Exit the game */
		if ((c == 'Q') || (c == 'q'))	quit(NULL);

		/* Hack - go back */
		if ((c == ESCAPE)|| (c == '4')) return (INVALID_CHOICE);

		/* Make a choice */
		if ((c == '\n') || (c == '\r') || (c == '6')) return (cur);

		/* Random choice */
		if (c == '*')
		{
			/* Ensure legal choice */
			do { cur = rand_int(num); } while (choices[cur].ghost);

			/* Done */
			done = TRUE;
		}

		/* Alphabetic choice */
		else if (isalpha(c))
		{

			/* Options */
			if ((c == 'O') || (c == 'o'))
			{
				do_cmd_options();
			}

			else
			{
				int choice;

				if (islower(c)) choice = A2I(c);
				else choice = c - 'A' + 26;
				
				/* Validate input */
				if ((choice > -1) && (choice < num) && !(choices[choice].ghost))
				{
					cur = choice;
					
					/* Done */
					done = TRUE;
				}
				else if (choices[choice].ghost)
				{
					bell("Your race cannot choose that house.");
				}
				else
				{
					bell("Illegal response to question!");
				}
			}
		}

		/* Move */
		else if (isdigit(c))
		{
			/* Get a direction from the key */
			dir = target_dir(c);

			/* Going up? */
			if (dir == 8)
			{
				next = -1;
				for (i = 0; i < cur; i++)
				{
					if (!(choices[i].ghost))
					{
						next = i;
					}
				}
				
				/* Move selection */
				if (next != -1) cur = next;
				/* if (cur != 0) cur--; */

				/* Scroll up */
				if ((top > 0) && ((cur - top) < 4))	top--;		
			}

			/* Going down? */
			if (dir == 2)
			{
				next = -1;
				for (i = num - 1; i > cur; i--)
				{
					if (!(choices[i].ghost))
					{
						next = i;
					}
				}
				
				/* Move selection */
				if (next != -1) cur = next;
				/* if (cur != (num - 1)) cur++; */

				/* Scroll down */
				if ((top + hgt < (num - 1)) && ((top + hgt - cur) < 4)) top++;
			}
		}

		/* Invalid input */
		else bell("Illegal response to question!");

		/* If choice is off screen, move it to the top */
		if ((cur < top) || (cur > top + hgt)) top = cur;
	}

	return (INVALID_CHOICE);
}
예제 #12
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);
}
예제 #13
0
파일: cmd3.c 프로젝트: fph/mortsil
/*
 * Allow the player to examine other sectors on the map
 */
void do_cmd_locate(void)
{
	int dir, y1, x1, y2, x2;

	/* Start at current panel */
	y2 = y1 = p_ptr->wy;
	x2 = x1 = p_ptr->wx;

	/* Show panels until done */
	while (TRUE)
	{
		/* Assume no direction */
		dir = 0;

		/* Get a direction */
		while (!dir)
		{
			char command;

			/* Get a command (or Cancel) */
			if (!get_com("Shift viewpoint in which direction? ", &command)) break;

			/* Extract direction */
			dir = target_dir(command);

			/* Error */
			if (!dir) bell("Illegal direction for look (around dungeon)!");
		}

		/* No direction */
		if (!dir) break;

		/* Apply the motion */
		y2 += (ddy[dir] * PANEL_HGT);
		x2 += (ddx[dir] * PANEL_WID);

		/* Verify the row */
		if (y2 > p_ptr->cur_map_hgt - SCREEN_HGT) y2 = p_ptr->cur_map_hgt - SCREEN_HGT;
		if (y2 < 0) y2 = 0;

		/* Verify the col */
		if (x2 > p_ptr->cur_map_wid - SCREEN_WID) x2 = p_ptr->cur_map_wid - SCREEN_WID;
		if (x2 < 0) x2 = 0;

		/* Handle "changes" */
		if ((p_ptr->wy != y2) || (p_ptr->wx != x2))
		{
			/* Update panel */
			p_ptr->wy = y2;
			p_ptr->wx = x2;

			/* Redraw map */
			p_ptr->redraw |= (PR_MAP);

			/* Window stuff */
			p_ptr->window |= (PW_OVERHEAD);

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

	/* Verify panel */
	p_ptr->update |= (PU_PANEL);

	/* Handle stuff */
	handle_stuff();
}
예제 #14
0
static enum birth_stage point_based_command(void)
{
	static int stat = 0;
	char ch;
	enum birth_stage next = BIRTH_POINTBASED;
	ui_event_data ke;

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

	/*	point_based_display();*/

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

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

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

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

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

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

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

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

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

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

	button_kill_all();
	event_signal(EVENT_MOUSEBUTTONS);

	return next;
}
예제 #15
0
/*
 *  Do visual mode command -- Change symbols
 */
static bool visual_mode_command(ui_event_data ke, bool * visual_list_ptr,
				int height, int width, byte * attr_top_ptr,
				byte * char_left_ptr, byte * cur_attr_ptr,
				byte * cur_char_ptr, int col, int row,
				int *delay)
{
    static byte attr_old = 0;
    static char char_old = 0;

    /* These are the distance we want to maintain between the cursor and
     * borders. */
    int frame_left = logical_width(10);
    int frame_right = logical_width(10);
    int frame_top = logical_height(4);
    int frame_bottom = logical_height(4);

    switch (ke.key) {
    case ESCAPE:
	{
	    if (*visual_list_ptr) {
		/* Cancel change */
		*cur_attr_ptr = attr_old;
		*cur_char_ptr = char_old;
		remove_visual_list(col, row, visual_list_ptr, width, height);

		return TRUE;
	    }

	    break;
	}

    case '\n':
    case '\r':
	{
	    if (*visual_list_ptr) {
		/* Accept change */
		remove_visual_list(col, row, visual_list_ptr, width, height);
		return TRUE;
	    }

	    break;
	}

    case 'V':
    case 'v':
	{
	    if (!*visual_list_ptr) {
		*visual_list_ptr = TRUE;
		bigcurs = TRUE;

		*attr_top_ptr = (byte) MAX(0, (int) *cur_attr_ptr - frame_top);
		*char_left_ptr =
		    (char) MAX(0, (int) *cur_char_ptr - frame_left);

		attr_old = *cur_attr_ptr;
		char_old = *cur_char_ptr;
	    } else {
		/* Cancel change */
		*cur_attr_ptr = attr_old;
		*cur_char_ptr = char_old;
		remove_visual_list(col, row, visual_list_ptr, width, height);
	    }

	    return TRUE;
	}

    case 'C':
    case 'c':
	{
	    /* Set the visual */
	    attr_idx = *cur_attr_ptr;
	    char_idx = *cur_char_ptr;

	    return TRUE;
	}

    case 'P':
    case 'p':
	{
	    if (attr_idx) {
		/* Set the char */
		*cur_attr_ptr = attr_idx;
		*attr_top_ptr = (byte) MAX(0, (int) *cur_attr_ptr - frame_top);
	    }

	    if (char_idx) {
		/* Set the char */
		*cur_char_ptr = char_idx;
		*char_left_ptr =
		    (char) MAX(0, (int) *cur_char_ptr - frame_left);
	    }

	    return TRUE;
	}

    default:
	{
	    if (*visual_list_ptr) {
		int eff_width = actual_width(width);
		int eff_height = actual_height(height);
		int d = target_dir(ke.key);
		byte a = *cur_attr_ptr;
		byte c = *cur_char_ptr;

		bigcurs = TRUE;

		/* Get mouse movement */
		if (ke.type == EVT_MOUSE) {
		    int my = ke.mousey - row;
		    int mx = ke.mousex - col;

		    my = logical_height(my);
		    mx = logical_width(mx);

		    if ((my >= 0) && (my < eff_height) && (mx >= 0)
			&& (mx < eff_width)
			&& ((ke.index) || (a != *attr_top_ptr + my)
			    || (c != *char_left_ptr + mx))) {
			/* Set the visual */
			*cur_attr_ptr = a = *attr_top_ptr + my;
			*cur_char_ptr = c = *char_left_ptr + mx;

			/* Move the frame */
			if (*char_left_ptr > MAX(0, (int) c - frame_left))
			    (*char_left_ptr)--;
			if (*char_left_ptr + eff_width <=
			    MIN(255, (int) c + frame_right))
			    (*char_left_ptr)++;
			if (*attr_top_ptr > MAX(0, (int) a - frame_top))
			    (*attr_top_ptr)--;
			if (*attr_top_ptr + eff_height <=
			    MIN(255, (int) a + frame_bottom))
			    (*attr_top_ptr)++;

			/* Delay */
			*delay = 100;

			/* Accept change */
			if (ke.index)
			    remove_visual_list(col, row, visual_list_ptr, width,
					       height);

			return TRUE;
		    }

		    /* Cancel change */
		    else if (ke.index) {
			*cur_attr_ptr = attr_old;
			*cur_char_ptr = char_old;
			remove_visual_list(col, row, visual_list_ptr, width,
					   height);

			return TRUE;
		    }
		} else {
		    /* Restrict direction */
		    if ((a == 0) && (ddy[d] < 0))
			d = 0;
		    if ((c == 0) && (ddx[d] < 0))
			d = 0;
		    if ((a == 255) && (ddy[d] > 0))
			d = 0;
		    if ((c == 255) && (ddx[d] > 0))
			d = 0;

		    a += ddy[d];
		    c += ddx[d];

		    /* Set the visual */
		    *cur_attr_ptr = a;
		    *cur_char_ptr = c;

		    /* Move the frame */
		    if ((ddx[d] < 0)
			&& *char_left_ptr > MAX(0, (int) c - frame_left))
			(*char_left_ptr)--;
		    if ((ddx[d] > 0)
			&& *char_left_ptr + eff_width <= MIN(255,
							     (int) c +
							     frame_right))
			(*char_left_ptr)++;

		    if ((ddy[d] < 0)
			&& *attr_top_ptr > MAX(0, (int) a - frame_top))
			(*attr_top_ptr)--;
		    if ((ddy[d] > 0)
			&& *attr_top_ptr + eff_height <= MIN(255,
							     (int) a +
							     frame_bottom))
			(*attr_top_ptr)++;

		    /* We need to always eat the input even if it is clipped,
		     * otherwise it will be interpreted as a change object
		     * selection command with messy results. */
		    return TRUE;
		}
	    }
	}
    }

    /* Visual mode command is not used */
    return FALSE;
}
예제 #16
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 -- targeting/observing an "outer border grid" may induce
 * problems, so this is not currently allowed.
 *
 * The player can use the direction keys to move among "interesting"
 * grids in a heuristic manner, or the "space", "+", and "-" keys to
 * move through the "interesting" grids in a sequential manner, or
 * can enter "location" mode, and use the direction keys to move one
 * grid at a time in any direction.  The "t" (set target) command will
 * only target a monster (as opposed to a location) if the monster is
 * target_able and the "interesting" mode is being used.
 *
 * The current grid is described using the "look" method above, and
 * a new command may be entered at any time, but note that if the
 * "TARGET_LOOK" bit flag is set (or if we are in "location" mode,
 * where "space" has no obvious meaning) then "space" will scan
 * through the description of the current grid until done, instead
 * of immediately jumping to the next "interesting" grid.  This
 * allows the "target" command to retain its old semantics.
 *
 * The "*", "+", and "-" keys may always be used to jump immediately
 * to the next (or previous) interesting grid, in the proper mode.
 *
 * The "return" key may always be used to scan through a complete
 * grid description (forever).
 *
 * This command will cancel any old target, even if used from
 * inside the "look" command.
 *
 * 'mode' is one of TARGET_LOOK or TARGET_KILL.
 * 'x' and 'y' are the initial position of the target to be highlighted,
 * or -1 if no location is specified.
 * Returns TRUE if a target has been successfully set, FALSE otherwise.
 */
bool target_set_interactive(int mode, int x, int y)
{
    int py = p_ptr->py;
    int px = p_ptr->px;

    int i, d, target_count;

    bool done = FALSE;
    bool interactive = TRUE;

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

    /* Cancel target */
    target_set_monster(0, FALSE);

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

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

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

    /* If we haven't been given an initial location, start on the
       player. */
    if ((x == -1 || y == -1) && target_grids.size())
    {
        x = p_ptr->px;
        y = p_ptr->py;
        ui_targeting_show(MODE_TARGETING_INTERACTIVE);
        ui_update_message_label(color_string("Interactive Target Mode", TERM_L_RED));
    }
    /*
     * If we /have/ been given an initial location, make sure we
     * honour it by going into "free targeting" mode.
     */
    else
    {
        if (x == -1 || y == -1)
        {
            x = p_ptr->px;
            y = p_ptr->py;
        }

        interactive = FALSE;
        ui_targeting_show(MODE_TARGETING_MANUAL);
        ui_update_message_label(color_string("Manual Target Mode", TERM_L_RED));
    }


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

    /* Interact */
    while (!done)
    {
        /* Interesting grids */
        if (interactive && target_grids.size())
        {
            bool path_drawn = FALSE;
            int yy, xx;

            y = target_grids[target_count].y;
            x = target_grids[target_count].x;

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

            /* Adjust panel if needed */
            ui_ensure(y, x);

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

            /* Draw the path in "target" mode. If there is one */
            if ((mode & (TARGET_KILL)) && (dungeon_info[y][x].projectable()))
            {
                path_drawn = ui_draw_path(path_n, path_g, y, x);
            }

            ui_show_cursor(y, x);

            /* Describe and Prompt */
            describe_grid_brief(y, x);

            UserInput input = ui_get_input();

            /* Remove the path */
            if (path_drawn) ui_destroy_path();

            ui_show_cursor(-1, -1);

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

            // Use the mouse wheel to go through targets
            if (input.mode == INPUT_MODE_MOUSE_WHEEL)
            {
                if (input.key == Qt::Key_Plus)
                {
                    if (++target_count == target_grids.size()) target_count = 0;
                }
                else if (input.key == Qt::Key_Minus)
                {
                    if (target_count-- == 0)  target_count = target_grids.size() - 1;
                }
                continue;
            }

            // double-click - automatically target if appropriate
            if (input.mode == INPUT_MODE_MOUSE_DOUBLE_CLICK)
            {
                if (!set_selected_target(mode, y, x))
                {
                    target_set_location(y, x);
                }

                done = TRUE;
                continue;

            }

            /*
             * If we click, move the target location to the click and
             * switch to "free targeting" mode by unsetting 'flag'.
             * This means we get some info about wherever we've picked.
             */
            if (input.mode == INPUT_MODE_MOUSE_SINGLE_CLICK)
            {
                // If clicking twice on the same square, accept
                if (input.x == x && input.y == y)
                {
                    if (set_selected_target(mode, y, x)) done = TRUE;
                    continue;
                }

                x = input.x;
                y = input.y;
                ui_update_message_label(color_string("Interactive Target Mode", TERM_L_RED));
                ui_targeting_show(MODE_TARGETING_MANUAL);
                interactive = FALSE;
                continue;
            }

            /* Analyze */
            switch (input.key)
            {
                case Qt::Key_Escape:
                case Qt::Key_X:
                {
                    done = TRUE;
                    break;
                }
                case Qt::Key_C:
                case Qt::Key_Comma:
                {
                    /* Set to closest target */
                    if (target_set_closest(TARGET_KILL)) done = TRUE;
                    break;
                }
                case Qt::Key_Space:
                case Qt::Key_Plus:
                {
                    if (++target_count == target_grids.size()) target_count = 0;
                    break;
                }

                case Qt::Key_Minus:
                {
                    if (target_count-- == 0)  target_count = target_grids.size() - 1;
                    break;
                }
                case Qt::Key_Exclam:
                case Qt::Key_L:
                {
                    GridDialog(y, x);
                    break;
                }
                case Qt::Key_Asterisk:
                case Qt::Key_M:
                {
                    ui_update_message_label(color_string("Manual Target Mode", TERM_L_RED));
                    ui_targeting_show(MODE_TARGETING_MANUAL);
                    interactive = FALSE;
                    break;
                }
                case Qt::Key_Question:
                {
                    do_cmd_list_targeting_commands();
                    break;
                }
                case Qt::Key_H:
                case Qt::Key_5:
                case Qt::Key_Period:
                case Qt::Key_Clear:
                {
                    if (set_selected_target(mode, y, x)) done = TRUE;
                    break;
                }

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

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

                    break;
                }
            }

            /* Hack -- move around */
            if (d)
            {
                int old_y = target_grids[target_count].y;
                int old_x = target_grids[target_count].x;

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

                /* Scroll to find interesting grid */
                if (i < 0)
                {
                    QRect vis = visible_dungeon();

                    int old_wy = vis.y();
                    int old_wx = vis.x();

                    /* Change if legal */
                    if (ui_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) && ui_modify_panel(old_wy, old_wx))
                        {
                            /* Recalculate interesting grids */
                            target_set_interactive_prepare(mode);
                        }
                    }
                }

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

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

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

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

            /* Draw the path in "target" mode. If there is one */
            if ((mode & (TARGET_KILL)) && (dungeon_info[y][x].projectable()))
            {
                /* Save target info */
                path_drawn = ui_draw_path(path_n, path_g, y, x);
            }

            describe_grid_brief(y, x);

            ui_show_cursor(y, x);

            UserInput input = ui_get_input();

            /* Remove the path */
            if (path_drawn) ui_destroy_path();

            ui_show_cursor(y, x);

            /* Assume no direction */
            d = 0;

             if (input.mode == INPUT_MODE_MOUSE_WHEEL) continue;

            // double-click - automatically target if appropriate
            if (input.mode == INPUT_MODE_MOUSE_DOUBLE_CLICK)
            {

                if (set_selected_target(mode, y, x)) done = TRUE;
                else
                {
                    message(QString("Illegal target!"));
                }
                break;
            }

            if (input.mode == INPUT_MODE_MOUSE_SINGLE_CLICK)
            {
                /* We only target if we click somewhere where the cursor
                   is already (i.e. a double-click without a time limit) */
                if (input.x == x && input.y == y)
                {
                    target_set_location(y, x);
                    done = TRUE;
                }
                else
                {
                    /* Just move the cursor for now - another click will
                       target. */
                    x = input.x;
                    y = input.y;
                }
                continue;
            }

            /* Analyze the keypress */
            switch (input.key)
            {
                case Qt::Key_Escape:
                case Qt::Key_X:
                {
                    done = TRUE;
                    continue;
                }
                case Qt::Key_Asterisk:
                case Qt::Key_M:
                {
                    if (((mode & (TARGET_GRID)) != TARGET_GRID) && target_grids.size())
                    {
                        ui_update_message_label(color_string("Interactive Target Mode", TERM_L_RED));
                        ui_targeting_show(MODE_TARGETING_INTERACTIVE);
                        interactive = TRUE;
                    }
                    break;
                }
                case Qt::Key_copyright:
                case Qt::Key_C:
                case Qt::Key_Comma:
                {
                    /* Set to closest target */
                    if (target_set_closest(TARGET_KILL)) done = TRUE;
                    break;
                }
                case Qt::Key_Exclam:
                case Qt::Key_L:
                {
                    GridDialog(y, x);
                    break;
                }

                case Qt::Key_Ampersand:
                case Qt::Key_P:
                {
                    /* Recenter around player */
                    ui_center(py, px);

                    y = py;
                    x = px;

                    break;
                }

                case Qt::Key_H:
                case Qt::Key_5:
                case Qt::Key_Period:
                case Qt::Key_Clear:
                {
                    target_set_location(y, x);
                    done = TRUE;
                    break;
                }

                case Qt::Key_Question:
                {
                    do_cmd_list_targeting_commands();
                    break;
                }
                default:
                {
                    /* Extract a direction */
                    d = target_dir(input);

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

                    break;
                }
            }

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

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

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

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

                /* Adjust panel if needed */
                if (ui_adjust_panel(y, x))
                {
                    /* Recalculate interesting grids */
                    target_set_interactive_prepare(mode);
                }
            }
        }
    }

    /* Forget */
    target_grids.clear();

    ui_targeting_hide();

    /* Recenter around player */
    ui_ensure(py, px);

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

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

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


    if (!dir)
    {
        ui_update_message_label(color_string("Please select a direction.", TERM_L_RED));

        ui_targeting_show(MODE_TARGETING_DIRECTION);
    }

    /* Get a direction */
    while (!dir)
    {
        UserInput input = ui_get_input();

        if (input.mode == INPUT_MODE_KEY)
        {
            if ((input.key == Qt::Key_Escape) || (input.key == Qt::Key_X)) dir = DIR_TARGET;

            else if (input.key == Qt::Key_Question)
            {
                do_cmd_list_targeting_commands();
                continue;
            }

            else dir = target_dir(input);
        }

        // Do nothing
        else  if (input.mode == INPUT_MODE_MOUSE_WHEEL)
        {
            continue;
        }
        /* Check mouse coordinates */
        else if ((input.mode == INPUT_MODE_MOUSE_SINGLE_CLICK) ||
                 (input.mode == INPUT_MODE_MOUSE_DOUBLE_CLICK))
        {
            /* Calculate approximate angle */
            dir = ui_get_dir_from_slope(p_ptr->py, p_ptr->px, input.y, input.x);
        }
    }

    ui_targeting_hide();

    if (!dir) color_message("Illegal direction", TERM_ORANGE);

    ui_clear_message_label();

    if (dir == DIR_TARGET) return false;

    /* Save desired direction */
    p_ptr->player_args.direction = dir;

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

    /* Success */
    return (TRUE);
}
예제 #18
0
/*
 * Allow the player to examine other sectors on the map
 */
void do_cmd_locate(void)
{
	int dir, y1, x1, y2, x2;

	char tmp_val[80];

	char out_val[160];


	/* Start at current panel */
	y1 = p_ptr->wy;
	x1 = p_ptr->wx;

	/* Show panels until done */
	while (1)
	{
		/* Get the current panel */
		y2 = p_ptr->wy;
		x2 = p_ptr->wx;
		
		/* Describe the location */
		if ((y2 == y1) && (x2 == x1))
		{
			tmp_val[0] = '\0';
		}
		else
		{
			sprintf(tmp_val, "%s%s of",
			        ((y2 < y1) ? " north" : (y2 > y1) ? " south" : ""),
			        ((x2 < x1) ? " west" : (x2 > x1) ? " east" : ""));
		}

		/* Prepare to ask which way to look */
		sprintf(out_val,
		        "Map sector [%d,%d], which is%s your sector.  Direction?",
		        (y2 / PANEL_HGT), (x2 / PANEL_WID), tmp_val);

		/* More detail */
		if (center_player)
		{
			sprintf(out_val,
		        	"Map sector [%d(%02d),%d(%02d)], which is%s your sector.  Direction?",
		        	(y2 / PANEL_HGT), (y2 % PANEL_HGT),
		        	(x2 / PANEL_WID), (x2 % PANEL_WID), tmp_val);
		}

		/* Assume no direction */
		dir = 0;

		/* Get a direction */
		while (!dir)
		{
			char command;

			/* Get a command (or Cancel) */
			if (!get_com(out_val, &command)) break;

			/* Extract direction */
			dir = target_dir(command);

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

		/* No direction */
		if (!dir) break;

		/* Apply the motion */
		change_panel(dir);

		/* Handle stuff */
		handle_stuff();
	}

	/* Verify panel */
	verify_panel();
}
예제 #19
0
//	IK
int mmdpiPmxIk::ik_execute( MMDPI_BONE_INFO_PTR bone, MMDPI_PMX_BONE_INFO_PTR pbone, int bone_index )
{
	const int	_ik_range_ = 255;
	const float	bottom_noise = 1e-8f;

	if( pbone[ bone_index ].ik_flag == 0 )
		return -1;
	
	MMDPI_PMX_BONE_INFO_PTR		npb	= &pbone[ bone_index ];
	MMDPI_BONE_INFO_PTR			nb	= &bone[ bone_index ];

	int			ik_link_num = ( signed )npb->ik_link_num;
	uint		_iteration_num_ = npb->ik_loop_num;	//	

	_iteration_num_ = ( _iteration_num_ > _ik_range_ )? _ik_range_ : _iteration_num_ ;

	mmdpiVector4d	v0( 0, 0, 0, 1 );

	mmdpiVector4d	effect_pos_base	= mmdpiBone::get_local_matrix( nb ) * v0;	//	Effector

	for( uint j = 0; j < _iteration_num_; j ++ )
	{
		float	rotation_distance = 0;	//	移動した距離
	
		for( int i = 0; i < ik_link_num; i ++ )
		{		
			mmdpiMatrix		rotation_matrix;

			MMDPI_PMX_IK_INFO_PTR	my_ik = ( i < 0 )? 0x00 : &npb->ik_link[ i ];
			dword					attention_index = ( my_ik )? my_ik->ik_bone_index : npb->ik_target_bone_index ;

			MMDPI_BONE_INFO_PTR		target_bone		= &bone[ attention_index ];
			mmdpiVector4d			target_pos_base	= mmdpiBone::get_local_matrix( &bone[ npb->ik_target_bone_index ] ) * v0;	// Target
			
			mmdpiMatrix		attention_localmat	= mmdpiBone::get_local_matrix( target_bone );
			mmdpiMatrix		inv_coord			= attention_localmat.get_inverse();

			mmdpiVector4d	effect_pos		= effect_pos_base;		//	Effector
			mmdpiVector4d	target_pos		= target_pos_base;		//	Target

			//effect_pos.w		= 1;
			//target_pos.w		= 1;
			
			effect_pos.normalize();
			target_pos.normalize();

			effect_pos		 = inv_coord * ( effect_pos );
			target_pos		 = inv_coord * ( target_pos );

			mmdpiVector4d	diff_pos = effect_pos - target_pos;
			if( diff_pos.dot( diff_pos ) < bottom_noise )
				continue;

			mmdpiVector3d effect_dir( effect_pos.x, effect_pos.y, effect_pos.z );
			mmdpiVector3d target_dir( target_pos.x, target_pos.y, target_pos.z );

			effect_dir.normalize();
			target_dir.normalize();

			float	p = effect_dir.dot( target_dir );
			if( 1 < p )
				p = 1;	// arccos error!

			float	angle = acos( p );
			if( angle > npb->ik_radius_range ) 
				angle = npb->ik_radius_range;
			if( angle < -npb->ik_radius_range ) 
				angle = -npb->ik_radius_range;

			mmdpiVector3d	axis;
			axis = effect_dir.cross( target_dir );
			
			//	回転軸制御(ボーン指定)
			if( npb->const_axis_flag )
			{
				for( int k = 0; k < 3; k ++ )
					axis[ k ] = npb->axis_vector[ k ];
			}
			
			if( axis.dot( axis ) < bottom_noise )	//	axis is zero vector.
				continue;			
			axis.normalize();
			
			//	Rotation matrix create.
			rotation_matrix.rotation( axis.x, axis.y, axis.z, angle );
			
			//	回転軸制御(IK上限)
			if( my_ik && my_ik->rotate_limit_flag )
			{
				rotation_range( &rotation_matrix,
					( mmdpiVector3d_ptr )my_ik->top, 
					( mmdpiVector3d_ptr )my_ik->bottom,
					npb->ik_radius_range );
			}
			
			//	反映
			target_bone->bone_mat = rotation_matrix * target_bone->bone_mat;
			
			//	移動した距離を計算
			rotation_distance += fabs( angle );
		}

		////	インバースキネマティクスの補完が必要なくなった(反映する距離が小さい場合)
		//if( rotation_distance < 1e-4f )
		//	return 0;
	}

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

	ui_event ke;

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

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

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

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

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

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

				return (FALSE);
			}
		}

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

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

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

					return (FALSE);
				}

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

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

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

				inkey_scan = lazymove_delay; 
				ke = inkey_ex();
			}

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

				return (FALSE);
			}
		}

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

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

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

	/* Success */
	return (TRUE);
}
예제 #21
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);
}
예제 #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 py = p_ptr->py;
	int px = p_ptr->px;

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

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

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

	ui_event_data query;

	char info[80];

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

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


	/* Cancel target */
	target_set_monster(0);

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

	/* health_track(0); */

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

					/* Handle stuff */
					handle_stuff();

					y = py;
					x = px;
				}

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

				case 'm':
				{
					break;
				}

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

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

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

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

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

				case '?':
				{
					help = !help;

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

					break;
				}

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

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

					break;
				}
			}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

			event_signal(EVENT_MOUSEBUTTONS);

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

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

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

			/* Assume no direction */
			d = 0;

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

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

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

					/* Handle stuff */
					handle_stuff();

					y = py;
					x = px;
				}

				case 'o':
				{
					break;
				}

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

					flag = TRUE;

					m = 0;
					bd = 999;

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

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

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

					break;
				}

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

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

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

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

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

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

				case '?':
				{
					help = !help;

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

					break;
				}


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

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

					break;
				}
			}

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

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

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

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

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

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

				}
			}
		}
	}

	/* Forget */
	temp_n = 0;

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



	/* Recenter around player */
	verify_panel();

	/* Restore buttons */
	button_restore();

	/* Handle stuff */
	handle_stuff();

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

	/* Success */
	return (TRUE);
}
예제 #23
0
파일: target.c 프로젝트: konijn/angband
/*
 * 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);
}