bool target_set_closest(int mode) { int y, x, m_idx; monster_type *m_ptr; char m_name[80]; bool visibility; struct point_set *targets; /* Cancel old target */ target_set_monster(0); /* Get ready to do targetting */ targets = target_set_interactive_prepare(mode); /* If nothing was prepared, then return */ if (point_set_size(targets) < 1) { msg("No Available Target."); point_set_dispose(targets); return FALSE; } /* Find the first monster in the queue */ y = targets->pts[0].y; x = targets->pts[0].x; m_idx = cave->m_idx[y][x]; /* Target the monster, if possible */ if ((m_idx <= 0) || !target_able(m_idx)) { msg("No Available Target."); point_set_dispose(targets); return FALSE; } /* Target the monster */ m_ptr = cave_monster(cave, m_idx); monster_desc(m_name, sizeof(m_name), m_ptr, 0x00); if (!(mode & TARGET_QUIET)) msg("%^s is targeted.", m_name); Term_fresh(); /* Set up target information */ monster_race_track(m_ptr->r_idx); health_track(p_ptr, cave->m_idx[y][x]); target_set_monster(m_idx); /* Visual cue */ Term_get_cursor(&visibility); (void)Term_set_cursor(TRUE); move_cursor_relative(y, x); Term_redraw_section(x, y, x, y); /* TODO: what's an appropriate amount of time to spend highlighting */ Term_xtra(TERM_XTRA_DELAY, 150); (void)Term_set_cursor(visibility); point_set_dispose(targets); return TRUE; }
/** * Target closest monster. * * XXX: Move to using CMD_TARGET_CLOSEST at some point instead of invoking * target_set_closest() directly. */ void textui_target_closest(void) { if (target_set_closest(TARGET_KILL)) { bool visibility; int x, y; target_get(&x, &y); /* Visual cue */ Term_fresh(); Term_get_cursor(&visibility); (void)Term_set_cursor(TRUE); move_cursor_relative(y, x); Term_redraw_section(x, y, x, y); /* TODO: what's an appropriate amount of time to spend highlighting */ Term_xtra(TERM_XTRA_DELAY, 150); (void)Term_set_cursor(visibility); } }
/* * Get a keypress from the user. * * This function recognizes a few "global parameters". These are variables * which, if set to TRUE before calling this function, will have an effect * on this function, and which are always reset to FALSE by this function * before this function returns. Thus they function just like normal * parameters, except that most calls to this function can ignore them. * * If "inkey_xtra" is TRUE, then all pending keypresses will be flushed. * This is set by flush(), which doesn't actually flush anything itself * but uses that flag to trigger delayed flushing. * * If "inkey_scan" is TRUE, then we will immediately return "zero" if no * keypress is available, instead of waiting for a keypress. * * If "inkey_flag" is TRUE, then we are waiting for a command in the main * map interface, and we shouldn't show a cursor. * * If we are waiting for a keypress, and no keypress is ready, then we will * refresh (once) the window which was active when this function was called. * * Note that "back-quote" is automatically converted into "escape" for * convenience on machines with no "escape" key. * * If "angband_term[0]" is not active, we will make it active during this * function, so that the various "main-xxx.c" files can assume that input * is only requested (via "Term_inkey()") when "angband_term[0]" is active. * * Mega-Hack -- This function is used as the entry point for clearing the * "signal_count" variable, and of the "character_saved" variable. * * Mega-Hack -- Note the use of "inkey_hack" to allow the "Borg" to steal * control of the keyboard from the user. */ ui_event inkey_ex(void) { bool cursor_state; ui_event kk; ui_event ke = EVENT_EMPTY; bool done = FALSE; term *old = Term; /* Delayed flush */ if (inkey_xtra) { Term_flush(); inkey_next = NULL; inkey_xtra = FALSE; } /* Hack -- Use the "inkey_next" pointer */ if (inkey_next && inkey_next->code) { /* Get next character, and advance */ ke.key = *inkey_next++; /* Cancel the various "global parameters" */ inkey_flag = FALSE; inkey_scan = 0; /* Accept result */ return (ke); } /* Forget pointer */ inkey_next = NULL; #ifdef ALLOW_BORG /* Mega-Hack -- Use the special hook */ if (inkey_hack) { ke.key = (*inkey_hack)(inkey_xtra); if (ke.key.type != EVT_NONE) { /* Cancel the various "global parameters" */ inkey_flag = FALSE; inkey_scan = 0; ke.type = EVT_KBRD; /* Accept result */ return (ke); } } #endif /* ALLOW_BORG */ /* Get the cursor state */ (void)Term_get_cursor(&cursor_state); /* Show the cursor if waiting, except sometimes in "command" mode */ if (!inkey_scan && (!inkey_flag || character_icky)) (void)Term_set_cursor(TRUE); /* Hack -- Activate main screen */ Term_activate(term_screen); /* Get a key */ while (ke.type == EVT_NONE) { /* Hack -- Handle "inkey_scan == SCAN_INSTANT */ if (inkey_scan == SCAN_INSTANT && (0 != Term_inkey(&kk, FALSE, FALSE))) break; /* Hack -- Flush output once when no key ready */ if (!done && (0 != Term_inkey(&kk, FALSE, FALSE))) { /* Hack -- activate proper term */ Term_activate(old); /* Flush output */ Term_fresh(); /* Hack -- activate main screen */ Term_activate(term_screen); /* Mega-Hack -- reset saved flag */ character_saved = FALSE; /* Mega-Hack -- reset signal counter */ signal_count = 0; /* Only once */ done = TRUE; } /* Get a key (see above) */ ke = inkey_aux(inkey_scan); /* Handle mouse buttons */ if ((ke.type == EVT_MOUSE) && (OPT(mouse_buttons))) { /* Check to see if we've hit a button */ /* Assuming text buttons here for now - this would have to * change for GUI buttons */ char key = button_get_key(ke.mouse.x, ke.mouse.y); if (key) { /* Rewrite the event */ /* XXXmacro button implementation needs updating */ ke.type = EVT_BUTTON; ke.key.code = key; ke.key.mods = 0; /* Done */ break; } } /* Treat back-quote as escape */ if (ke.key.code == '`') ke.key.code = ESCAPE; } /* Hack -- restore the term */ Term_activate(old); /* Restore the cursor */ Term_set_cursor(cursor_state); /* Cancel the various "global parameters" */ inkey_flag = FALSE; inkey_scan = 0; /* Return the keypress */ return (ke); }
/** * Get a keypress from the user. * * This function recognizes a few "global parameters". These are variables * which, if set to true before calling this function, will have an effect * on this function, and which are always reset to false by this function * before this function returns. Thus they function just like normal * parameters, except that most calls to this function can ignore them. * * If "inkey_xtra" is true, then all pending keypresses will be flushed. * This is set by flush(), which doesn't actually flush anything itself * but uses that flag to trigger delayed flushing. * * If "inkey_scan" is true, then we will immediately return "zero" if no * keypress is available, instead of waiting for a keypress. * * If "inkey_flag" is true, then we are waiting for a command in the main * map interface, and we shouldn't show a cursor. * * If we are waiting for a keypress, and no keypress is ready, then we will * refresh (once) the window which was active when this function was called. * * Note that "back-quote" is automatically converted into "escape" for * convenience on machines with no "escape" key. * * If "angband_term[0]" is not active, we will make it active during this * function, so that the various "main-xxx.c" files can assume that input * is only requested (via "Term_inkey()") when "angband_term[0]" is active. * * Mega-Hack -- This function is used as the entry point for clearing the * "signal_count" variable, and of the "character_saved" variable. * * Mega-Hack -- Note the use of "inkey_hack" to allow the "Borg" to steal * control of the keyboard from the user. */ ui_event inkey_ex(void) { bool cursor_state; ui_event kk; ui_event ke = EVENT_EMPTY; bool done = false; term *old = Term; /* Delayed flush */ if (inkey_xtra) { Term_flush(); inkey_next = NULL; inkey_xtra = false; } /* Hack -- Use the "inkey_next" pointer */ while (inkey_next && inkey_next->code) { /* Get next character, and advance */ ke.key = *inkey_next++; /* Cancel the various "global parameters" */ inkey_flag = false; inkey_scan = 0; /* Peek at the key, and see if we want to skip more prompts */ if (ke.key.code == '(') { keymap_auto_more = true; /* Since we are not returning this char, make sure the * next key below works well */ if (!inkey_next || !inkey_next->code) { ke.type = EVT_NONE; break; } continue; } else if (ke.key.code == ')') { keymap_auto_more = false; /* Since we are not returning this char, make sure the * next key below works well */ if (!inkey_next || !inkey_next->code) { ke.type = EVT_NONE; break; } continue; } /* Accept result */ return (ke); } /* make sure that the flag to skip more prompts is off */ keymap_auto_more = false; /* Forget pointer */ inkey_next = NULL; /* Get the cursor state */ (void)Term_get_cursor(&cursor_state); /* Show the cursor if waiting, except sometimes in "command" mode */ if (!inkey_scan && (!inkey_flag || screen_save_depth || (OPT(show_target) && target_sighted()))) (void)Term_set_cursor(true); /* Hack -- Activate main screen */ Term_activate(term_screen); /* Get a key */ while (ke.type == EVT_NONE) { /* Hack -- Handle "inkey_scan == SCAN_INSTANT */ if (inkey_scan == SCAN_INSTANT && (0 != Term_inkey(&kk, false, false))) break; /* Hack -- Flush output once when no key ready */ if (!done && (0 != Term_inkey(&kk, false, false))) { /* Hack -- activate proper term */ Term_activate(old); /* Flush output */ Term_fresh(); /* Hack -- activate main screen */ Term_activate(term_screen); /* Mega-Hack -- reset saved flag */ character_saved = false; /* Mega-Hack -- reset signal counter */ signal_count = 0; /* Only once */ done = true; } /* Get a key (see above) */ ke = inkey_aux(inkey_scan); if (inkey_scan && ke.type == EVT_NONE) /* The keypress timed out. We need to stop here. */ break; /* Treat back-quote as escape */ if (ke.key.code == '`') ke.key.code = ESCAPE; } /* Hack -- restore the term */ Term_activate(old); /* Restore the cursor */ Term_set_cursor(cursor_state); /* Cancel the various "global parameters" */ inkey_flag = false; inkey_scan = 0; /* Return the keypress */ return (ke); }