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