/** * Study a book to gain a new spell */ void textui_obj_study(void) { int item; char q[80]; char s[80]; if (mp_ptr->spell_realm == REALM_NONE) { msg("You cannot read books!"); return; } strnfmt(q, sizeof(q), "Study which %s?", magic_desc[mp_ptr->spell_realm][BOOK_NOUN]); strnfmt(s, sizeof(s), " You have no %ss that you can study.", magic_desc[mp_ptr->spell_realm][BOOK_LACK]); item_tester_hook = obj_can_study; if (!get_item(&item, q, s, CMD_STUDY_BOOK, (USE_INVEN | USE_FLOOR))) return; track_object(item); handle_stuff(p_ptr); if (mp_ptr->spell_book != TV_PRAYER_BOOK) { int spell = get_spell(object_from_item_idx(item), "study", spell_okay_to_study); if (spell >= 0) { cmd_insert(CMD_STUDY_SPELL); cmd_set_arg_choice(cmd_get_top(), 0, spell); } } else { cmd_insert(CMD_STUDY_BOOK); cmd_set_arg_item(cmd_get_top(), 0, item); } }
/** * Front-end command which fires at the nearest target with default ammo. */ void textui_cmd_fire_at_nearest(void) { /* the direction '5' means 'use the target' */ int i, dir = 5, item = -1; /* Require a usable launcher */ if (!p_ptr->inventory[INVEN_BOW].tval || !p_ptr->state.ammo_tval) { msg("You have nothing to fire with."); return; } /* Find first eligible ammo in the quiver */ for (i = QUIVER_START; i < QUIVER_END; i++) { if (p_ptr->inventory[i].tval != p_ptr->state.ammo_tval) continue; item = i; break; } /* Require usable ammo */ if (item < 0) { msg("You have no ammunition in the quiver to fire"); return; } /* Require foe */ if (!target_set_closest(TARGET_KILL | TARGET_QUIET)) return; /* Fire! */ cmd_insert(CMD_FIRE); cmd_set_arg_item(cmd_get_top(), 0, item); cmd_set_arg_target(cmd_get_top(), 1, dir); }
void textui_obj_wield(object_type *o_ptr, int item) { int slot = wield_slot(o_ptr); /* Usually if the slot is taken we'll just replace the item in the slot, * but in some cases we need to ask the user which slot they actually * want to replace */ if (p_ptr->inventory[slot].k_idx) { if (o_ptr->tval == TV_RING) { cptr q = "Replace which ring? "; cptr s = "Error in obj_wield, please report"; item_tester_hook = obj_is_ring; if (!get_item(&slot, q, s, CMD_WIELD, USE_EQUIP)) return; } if (obj_is_ammo(o_ptr) && !object_similar(&p_ptr->inventory[slot], o_ptr, OSTACK_QUIVER)) { cptr q = "Replace which ammunition? "; cptr s = "Error in obj_wield, please report"; item_tester_hook = obj_is_ammo; if (!get_item(&slot, q, s, CMD_WIELD, USE_EQUIP)) return; } } cmd_insert(CMD_WIELD); cmd_set_arg_item(cmd_get_top(), 0, item); cmd_set_arg_number(cmd_get_top(), 1, slot); }
/** * Handle a textui mouseclick. */ static void textui_process_click(ui_event_data e) { int x, y; if (!OPT(mouse_movement)) return; y = KEY_GRID_Y(e); x = KEY_GRID_X(e); /* Check for a valid location */ if (!in_bounds_fully(y, x)) return; /* XXX show context menu here */ if ((p_ptr->py == y) && (p_ptr->px == x)) textui_cmd_rest(); else /* if (e.mousebutton == 1) */ { if (p_ptr->timed[TMD_CONFUSED]) { cmd_insert(CMD_WALK); } else { cmd_insert(CMD_PATHFIND); cmd_set_arg_point(cmd_get_top(), 0, y, x); } } #if 0 else if (e.mousebutton == 2)
/** * Cast a spell from a book. */ void textui_obj_cast(void) { int item; int spell; const char *verb = magic_desc[mp_ptr->spell_realm][SPELL_VERB]; char q[80]; char s[80]; if (mp_ptr->spell_realm == REALM_NONE) { msg("You cannot read books!"); return; } strnfmt(q, sizeof(q), "Use which %s?", magic_desc[mp_ptr->spell_realm][BOOK_NOUN]); strnfmt(s, sizeof(s), " You have no %ss that you can use.", magic_desc[mp_ptr->spell_realm][BOOK_LACK]); item_tester_hook = obj_can_cast_from; if (!get_item(&item, q, s, CMD_CAST, (USE_INVEN | USE_FLOOR))) return; /* Track the object kind */ track_object(item); /* Ask for a spell */ spell = get_spell(object_from_item_idx(item), verb, spell_okay_to_cast); if (spell >= 0) { cmd_insert(CMD_CAST); cmd_set_arg_choice(cmd_get_top(), 0, spell); } }
void textui_cmd_rest(void) { /* Prompt for time if needed */ if (p_ptr->command_arg <= 0) { cptr p = "Rest (0-9999, '!' for HP or SP, '*' for HP and SP, '&' as needed): "; char out_val[5] = "& "; /* Ask for duration */ if (!get_string(p, out_val, sizeof(out_val))) return; /* Rest until done */ if (out_val[0] == '&') { cmd_insert(CMD_REST); cmd_set_arg_choice(cmd_get_top(), 0, REST_COMPLETE); } /* Rest a lot */ else if (out_val[0] == '*') { cmd_insert(CMD_REST); cmd_set_arg_choice(cmd_get_top(), 0, REST_ALL_POINTS); } /* Rest until HP or SP filled */ else if (out_val[0] == '!') { cmd_insert(CMD_REST); cmd_set_arg_choice(cmd_get_top(), 0, REST_SOME_POINTS); } /* Rest some */ else { int turns = atoi(out_val); if (turns <= 0) return; if (turns > 9999) turns = 9999; cmd_insert(CMD_REST); cmd_set_arg_choice(cmd_get_top(), 0, turns); } } }
void textui_obj_inscribe(object_type *o_ptr, int item) { char o_name[80]; char tmp[80] = ""; object_desc(o_name, sizeof(o_name), o_ptr, ODESC_PREFIX | ODESC_FULL); msg_format("Inscribing %s.", o_name); message_flush(); /* Use old inscription */ if (o_ptr->note) strnfmt(tmp, sizeof(tmp), "%s", quark_str(o_ptr->note)); /* Get a new inscription (possibly empty) */ if (get_string("Inscription: ", tmp, sizeof(tmp))) { cmd_insert(CMD_INSCRIBE); cmd_set_arg_item(cmd_get_top(), 0, item); cmd_set_arg_string(cmd_get_top(), 1, tmp); } }
/** * Handle user input from a command menu */ static bool show_action(menu_type * menu, const ui_event * e, int oid) { /* Handle enter and mouse */ if (e->type == EVT_SELECT) { cmd_insert(comm_code[oid]); if (comm_code[oid] == CMD_NULL) Term_keypress(comm[oid],0); cmd_set_arg_item(cmd_get_top(), 0, item); } return FALSE; }
/** * Front-end 'throw' command. */ void textui_cmd_throw(void) { int item, dir; const char *q, *s; /* Get an item */ q = "Throw which item? "; s = "You have nothing to throw."; if (!get_item(&item, q, s, CMD_THROW, (USE_EQUIP | USE_INVEN | USE_FLOOR))) return; if (item >= INVEN_WIELD && item < QUIVER_START) { msg("You cannot throw wielded items."); return; } /* Get a direction (or cancel) */ if (!get_aim_dir(&dir)) return; cmd_insert(CMD_THROW); cmd_set_arg_item(cmd_get_top(), 0, item); cmd_set_arg_target(cmd_get_top(), 1, dir); }
/* ------------------------------------------------------------------------ * Asking for the player's chosen name. * ------------------------------------------------------------------------ */ static enum birth_stage get_name_command(void) { enum birth_stage next; char name[32]; if (get_name(name, sizeof(name))) { cmd_insert(CMD_NAME_CHOICE); cmd_set_arg_string(cmd_get_top(), 0, name); next = BIRTH_FINAL_CONFIRM; } else { next = BIRTH_BACK; } return next; }
} else if (selected == CMD_CAST) { if (obj_can_browse(o_ptr)) { /* copied from textui_obj_cast */ const char *verb = ((p_ptr->class->spell_book == TV_MAGIC_BOOK) ? "cast" : "recite"); int spell = get_spell(o_ptr, verb, spell_okay_to_cast); if (spell >= 0) { cmd_insert(CMD_CAST); cmd_set_arg_choice(cmd_get_top(), 0, spell); } } } else { cmd_insert(selected); cmd_set_arg_item(cmd_get_top(), 0, slot); /* If we're in a store, we need to change the "drop" command to "stash". */ if (selected == CMD_DROP && store_in_store) { game_command *gc = cmd_get_top(); gc->command = CMD_STASH; } } return 1; } /* pick the context menu options appropiate for a store */ int context_menu_store(struct store *store, const int oid, int mx, int my) { menu_type *m;
/* * 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); }
/** * Bring up objects to act on */ void do_cmd_show_obj(void) { cptr q, s; int j, item; object_type *o_ptr; char o_name[120]; byte out_color; bool accepted = FALSE; /* No restrictions */ item_tester_tval = 0; item_tester_hook = NULL; /* See what's available */ q = "Pick an item to use:"; s = "You have no items to hand."; if (!get_item(&item, q, s, CMD_NULL, (USE_INVEN | USE_EQUIP | USE_FLOOR))) return; /* Got it */ if (item >= 0) { o_ptr = &p_ptr->inventory[item]; } /* Get the item (on the floor) */ else { o_ptr = &o_list[0 - item]; } /* Is it really an item? */ if (!o_ptr->k_idx) return; /* No commands yet */ poss = 0; /* Describe the object */ object_desc(o_name, sizeof(o_name), o_ptr, ODESC_FULL); /* Hack -- enforce max length */ o_name[Term->wid - 3] = '\0'; /* Acquire inventory color. Apply spellbook hack. */ out_color = proc_list_color_hack(o_ptr); /* Wear/wield */ if ((wield_slot(o_ptr) >= INVEN_WIELD) && (!SCHANGE) && (item < INVEN_WIELD)) { comm[poss] = 'w'; comm_code[poss] = CMD_WIELD; comm_descr[poss++] = "Wield"; } /* Take off equipment */ if ((item >= INVEN_WIELD) && (item < INVEN_TOTAL) && (!SCHANGE)) { comm[poss] = 't'; comm_code[poss] = CMD_TAKEOFF; comm_descr[poss++] = "Take off"; } /* Drop an item */ if ((item >= 0) && ((item < INVEN_WIELD) || (!SCHANGE))) { comm[poss] = 'd'; comm_code[poss] = CMD_DROP; comm_descr[poss++] = "Drop"; } /* Destroy an item */ if (item < INVEN_WIELD) { comm[poss] = 'k'; comm_code[poss] = CMD_DESTROY; comm_descr[poss++] = "Destroy"; } /* Identify an object */ comm[poss] = 'I'; comm_code[poss] = CMD_NULL; comm_descr[poss++] = "Inspect"; /* Pick up an object */ if ((item < 0) && inven_carry_okay(o_ptr)) { comm[poss] = 'g'; comm_code[poss] = CMD_PICKUP; comm_descr[poss++] = "Pick up"; } /* Book learnin' */ if (mp_ptr->spell_book == o_ptr->tval) { if (p_ptr->new_spells) { comm[poss] = 'G'; comm_code[poss] = CMD_STUDY_SPELL; comm_descr[poss++] = "Gain a spell"; } comm[poss] = 'b'; comm_code[poss] = CMD_BROWSE_SPELL; comm_descr[poss++] = "Browse"; comm[poss] = 'm'; comm_code[poss] = CMD_CAST; comm_descr[poss++] = "Cast a spell"; } /* Inscribe an object */ comm[poss] = '{'; comm_code[poss] = CMD_INSCRIBE; comm_descr[poss++] = "Inscribe"; /* Uninscribe an object */ if (o_ptr->note) { comm[poss] = '}'; comm_code[poss] = CMD_UNINSCRIBE; comm_descr[poss++] = "Uninscribe"; } /* Activate equipment */ if ((o_ptr->effect) && (item >= INVEN_WIELD)) { comm[poss] = 'A'; comm_code[poss] = CMD_ACTIVATE; comm_descr[poss++] = "Activate"; } /* Eat some food */ if (o_ptr->tval == TV_FOOD) { comm[poss] = 'E'; comm_code[poss] = CMD_EAT; comm_descr[poss++] = "Eat"; } if ((item < INVEN_WIELD) && ((o_ptr->tval == TV_LIGHT) || (o_ptr->tval == TV_FLASK))) { object_type *o1_ptr = &p_ptr->inventory[INVEN_LIGHT]; if (((o1_ptr->sval == SV_LIGHT_LANTERN) && ((o_ptr->tval == TV_FLASK) || ((o_ptr->tval == TV_LIGHT) && (o_ptr->sval == SV_LIGHT_LANTERN)))) || ((o1_ptr->sval == SV_LIGHT_TORCH) && (o_ptr->tval == TV_LIGHT) && (o_ptr->sval == SV_LIGHT_TORCH))) { comm[poss] = 'F'; comm_code[poss] = CMD_REFILL; comm_descr[poss++] = "Refuel"; } } /* Fire an item */ if (p_ptr->state.ammo_tval == o_ptr->tval) { comm[poss] = 'f'; comm_code[poss] = CMD_FIRE; comm_descr[poss++] = "Fire"; } /* Throw an item */ if ((item < INVEN_WIELD) || (!SCHANGE)) { comm[poss] = 'v'; comm_code[poss] = CMD_THROW; comm_descr[poss++] = "Throw"; } /* Aim a wand */ if (o_ptr->tval == TV_WAND) { comm[poss] = 'a'; comm_code[poss] = CMD_USE_WAND; comm_descr[poss++] = "Aim"; } /* Zap a rod */ if (o_ptr->tval == TV_ROD) { comm[poss] = 'z'; comm_code[poss] = CMD_USE_ROD; comm_descr[poss++] = "Zap"; } /* Quaff a potion */ if (o_ptr->tval == TV_POTION) { comm[poss] = 'q'; comm_code[poss] = CMD_QUAFF; comm_descr[poss++] = "Quaff"; } /* Read a scroll */ if (o_ptr->tval == TV_SCROLL) { comm[poss] = 'r'; comm_code[poss] = CMD_READ_SCROLL; comm_descr[poss++] = "Read"; } /* Use a staff */ if (o_ptr->tval == TV_STAFF) { comm[poss] = 'u'; comm_code[poss] = CMD_USE_STAFF; comm_descr[poss++] = "Use"; } /* Set up the screen */ screen_save(); /* Prompt */ put_str("Choose a command, or ESC:", 0, 0); /* Clear the line */ prt("", 1, 0); /* Display the item */ c_put_str(out_color, o_name, 1, 0); /* Hack - delete exact graphics rows */ if (tile_height > 1) { j = poss + 2; while ((j % tile_height) && (j <= SCREEN_ROWS)) prt("", ++j, 0); } /* Get a choice */ accepted = show_cmd_menu(TRUE); /* Load de screen */ screen_load(); /* Now set the item if valid */ if (accepted) cmd_set_arg_item(cmd_get_top(), 0, item); }
static enum birth_stage point_based_command(void) { static int stat = 0; struct keypress ch; enum birth_stage next = BIRTH_POINTBASED; /* point_based_display();*/ /* Place cursor just after cost of current stat */ Term_gotoxy(COSTS_COL + 4, COSTS_ROW + stat); /* Get key */ ch = inkey(); if (ch.code == KTRL('X')) { cmd_insert(CMD_QUIT); next = BIRTH_COMPLETE; } /* Go back a step, or back to the start of this step */ else if (ch.code == ESCAPE) { next = BIRTH_BACK; } else if (ch.code == 'r' || ch.code == 'R') { cmd_insert(CMD_RESET_STATS); cmd_set_arg_choice(cmd_get_top(), 0, FALSE); } /* Done */ else if ((ch.code == '\r') || (ch.code == '\n')) { next = BIRTH_NAME_CHOICE; } else { int dir = target_dir(ch); /* Prev stat, looping round to the bottom when going off the top */ if (dir == 8) stat = (stat + A_MAX - 1) % A_MAX; /* Next stat, looping round to the top when going off the bottom */ if (dir == 2) stat = (stat + 1) % A_MAX; /* Decrease stat (if possible) */ if (dir == 4) { cmd_insert(CMD_SELL_STAT); cmd_set_arg_choice(cmd_get_top(), 0, stat); } /* Increase stat (if possible) */ if (dir == 6) { cmd_insert(CMD_BUY_STAT); cmd_set_arg_choice(cmd_get_top(), 0, stat); } } return next; }
/* Allow the user to select from the current menu, and return the corresponding command to the game. Some actions are handled entirely by the UI (displaying help text, for instance). */ static enum birth_stage menu_question(enum birth_stage current, menu_type *current_menu, cmd_code choice_command) { struct birthmenu_data *menu_data = menu_priv(current_menu); ui_event cx; enum birth_stage next = BIRTH_RESET; /* Print the question currently being asked. */ clear_question(); Term_putstr(QUESTION_COL, QUESTION_ROW, -1, TERM_YELLOW, menu_data->hint); current_menu->cmd_keys = "?=*\x18"; /* ?, =, *, <ctl-X> */ while (next == BIRTH_RESET) { /* Display the menu, wait for a selection of some sort to be made. */ cx = menu_select(current_menu, EVT_KBRD, FALSE); /* As all the menus are displayed in "hierarchical" style, we allow use of "back" (left arrow key or equivalent) to step back in the proces as well as "escape". */ if (cx.type == EVT_ESCAPE) { next = BIRTH_BACK; } else if (cx.type == EVT_SELECT) { if (current == BIRTH_ROLLER_CHOICE) { cmd_insert(CMD_FINALIZE_OPTIONS); if (current_menu->cursor) { /* Do a first roll of the stats */ cmd_insert(CMD_ROLL_STATS); next = current + 2; } else { /* * Make sure we've got a point-based char to play with. * We call point_based_start here to make sure we get * an update on the points totals before trying to * display the screen. The call to CMD_RESET_STATS * forces a rebuying of the stats to give us up-to-date * totals. This is, it should go without saying, a hack. */ point_based_start(); cmd_insert(CMD_RESET_STATS); cmd_set_arg_choice(cmd_get_top(), 0, TRUE); next = current + 1; } } else { cmd_insert(choice_command); cmd_set_arg_choice(cmd_get_top(), 0, current_menu->cursor); next = current + 1; } } else if (cx.type == EVT_KBRD) { /* '*' chooses an option at random from those the game's provided. */ if (cx.key.code == '*' && menu_data->allow_random) { current_menu->cursor = randint0(current_menu->count); cmd_insert(choice_command); cmd_set_arg_choice(cmd_get_top(), 0, current_menu->cursor); menu_refresh(current_menu, FALSE); next = current + 1; } else if (cx.key.code == '=') { do_cmd_options_birth(); next = current; } else if (cx.key.code == KTRL('X')) { cmd_insert(CMD_QUIT); next = BIRTH_COMPLETE; } else if (cx.key.code == '?') { do_cmd_help(); } } } return next; }
/* pick the context menu options appropiate for the item */ int context_menu_object(const object_type *o_ptr, const int slot) { menu_type *m; region r; int selected; char *labels; char header[120]; textblock *tb; region area = { 0, 0, 0, 0 }; bool allowed = TRUE; int mode = OPT(rogue_like_commands) ? KEYMAP_MODE_ROGUE : KEYMAP_MODE_ORIG; unsigned char cmdkey; m = menu_dynamic_new(); if (!m || !o_ptr) { return 0; } object_desc(header, sizeof(header), o_ptr, ODESC_PREFIX | ODESC_BASE); labels = string_make(lower_case); m->selections = labels; /* 'I' is used for inspect in both keymaps. */ menu_dynamic_add_label(m, "Inspect", 'I', MENU_VALUE_INSPECT, labels); if (obj_can_browse(o_ptr)) { if (obj_can_cast_from(o_ptr) && player_can_cast(p_ptr, FALSE)) { ADD_LABEL("Cast", CMD_CAST, MN_ROW_VALID); } if (obj_can_study(o_ptr) && player_can_study(p_ptr, FALSE)) { cmd_code study_cmd = player_has(PF_CHOOSE_SPELLS) ? CMD_STUDY_SPELL : CMD_STUDY_BOOK; /* Hack - Use the STUDY_BOOK command key so that we get the correct command key. */ cmdkey = cmd_lookup_key_unktrl(CMD_STUDY_BOOK, mode); menu_dynamic_add_label(m, "Study", cmdkey, study_cmd, labels); } if (player_can_read(p_ptr, FALSE)) { ADD_LABEL("Browse", CMD_BROWSE_SPELL, MN_ROW_VALID); } } else if (obj_is_useable(o_ptr)) { if (obj_is_wand(o_ptr)) { menu_row_validity_t valid = (obj_has_charges(o_ptr)) ? MN_ROW_VALID : MN_ROW_INVALID; ADD_LABEL("Aim", CMD_USE_WAND, valid); } else if (obj_is_rod(o_ptr)) { menu_row_validity_t valid = (obj_can_zap(o_ptr)) ? MN_ROW_VALID : MN_ROW_INVALID; ADD_LABEL("Zap", CMD_USE_ROD, valid); } else if (obj_is_staff(o_ptr)) { menu_row_validity_t valid = (obj_has_charges(o_ptr)) ? MN_ROW_VALID : MN_ROW_INVALID; ADD_LABEL("Use", CMD_USE_STAFF, valid); } else if (obj_is_scroll(o_ptr)) { menu_row_validity_t valid = (player_can_read(p_ptr, FALSE)) ? MN_ROW_VALID : MN_ROW_INVALID; ADD_LABEL("Read", CMD_READ_SCROLL, valid); } else if (obj_is_potion(o_ptr)) { ADD_LABEL("Quaff", CMD_QUAFF, MN_ROW_VALID); } else if (obj_is_food(o_ptr)) { ADD_LABEL("Eat", CMD_EAT, MN_ROW_VALID); } else if (obj_is_activatable(o_ptr)) { menu_row_validity_t valid = (slot >= INVEN_WIELD && obj_can_activate(o_ptr)) ? MN_ROW_VALID : MN_ROW_INVALID; ADD_LABEL("Activate", CMD_ACTIVATE, valid); } else if (obj_can_fire(o_ptr)) { ADD_LABEL("Fire", CMD_FIRE, MN_ROW_VALID); } else { ADD_LABEL("Use", CMD_USE_ANY, MN_ROW_VALID); } } if (obj_can_refill(o_ptr)) { ADD_LABEL("Refill", CMD_REFILL, MN_ROW_VALID); } if (slot >= INVEN_WIELD && obj_can_takeoff(o_ptr)) { ADD_LABEL("Take off", CMD_TAKEOFF, MN_ROW_VALID); } else if (slot < INVEN_WIELD && obj_can_wear(o_ptr)) { //if (obj_is_armor(o_ptr)) { // menu_dynamic_add(m, "Wear", 2); //} else { // menu_dynamic_add(m, "Wield", 2); //} ADD_LABEL("Equip", CMD_WIELD, MN_ROW_VALID); } if (slot >= 0) { if (!store_in_store || cave_shopnum(cave, p_ptr->py, p_ptr->px) == STORE_HOME) { ADD_LABEL("Drop", CMD_DROP, MN_ROW_VALID); if (o_ptr->number > 1) { /* 'D' is used for squelch in rogue keymap, so we'll just swap letters. */ cmdkey = (mode == KEYMAP_MODE_ORIG) ? 'D' : 'k'; menu_dynamic_add_label(m, "Drop All", cmdkey, MENU_VALUE_DROP_ALL, labels); } } } else { menu_row_validity_t valid = (inven_carry_okay(o_ptr)) ? MN_ROW_VALID : MN_ROW_INVALID; ADD_LABEL("Pick up", CMD_PICKUP, valid); } ADD_LABEL("Throw", CMD_THROW, MN_ROW_VALID); ADD_LABEL("Inscribe", CMD_INSCRIBE, MN_ROW_VALID); if (obj_has_inscrip(o_ptr)) { ADD_LABEL("Uninscribe", CMD_UNINSCRIBE, MN_ROW_VALID); } ADD_LABEL( (object_is_squelched(o_ptr) ? "Unignore" : "Ignore"), CMD_DESTROY, MN_ROW_VALID); /* work out display region */ r.width = (int)menu_dynamic_longest_entry(m) + 3 + 2; /* +3 for tag, 2 for pad */ r.col = Term->wid - r.width - 1; r.row = 1; r.page_rows = m->count; area.width = -(r.width + 2); /* Hack -- no flush needed */ msg_flag = FALSE; screen_save(); /* Display info */ tb = object_info(o_ptr, OINFO_NONE); object_desc(header, sizeof(header), o_ptr, ODESC_PREFIX | ODESC_FULL); textui_textblock_place(tb, area, format("%s", header)); textblock_free(tb); menu_layout(m, &r); region_erase_bordered(&r); prt(format("(Enter to select, ESC) Command for %s:", header), 0, 0); selected = menu_dynamic_select(m); menu_dynamic_free(m); string_free(labels); screen_load(); cmdkey = cmd_lookup_key(selected, mode); switch (selected) { case -1: /* User cancelled the menu. */ return 3; case MENU_VALUE_INSPECT: /* copied from textui_obj_examine */ /* Display info */ tb = object_info(o_ptr, OINFO_NONE); object_desc(header, sizeof(header), o_ptr, ODESC_PREFIX | ODESC_FULL); textui_textblock_show(tb, area, format("%s", header)); textblock_free(tb); return 2; case MENU_VALUE_DROP_ALL: /* Drop entire stack with confirmation. */ if (get_check(format("Drop %s? ", header))) { cmd_insert(store_in_store ? CMD_STASH : CMD_DROP); cmd_set_arg_item(cmd_get_top(), 0, slot); cmd_set_arg_number(cmd_get_top(), 1, o_ptr->number); } return 1; case CMD_STUDY_SPELL: /* Hack - Use the STUDY_BOOK command key so that get_item_allow() works properly. */ cmdkey = cmd_lookup_key(CMD_STUDY_BOOK, mode); /* Fall through. */ case CMD_BROWSE_SPELL: case CMD_STUDY_BOOK: case CMD_CAST: case CMD_DESTROY: case CMD_WIELD: case CMD_TAKEOFF: case CMD_INSCRIBE: case CMD_UNINSCRIBE: case CMD_PICKUP: case CMD_DROP: case CMD_REFILL: case CMD_THROW: case CMD_USE_WAND: case CMD_USE_ROD: case CMD_USE_STAFF: case CMD_READ_SCROLL: case CMD_QUAFF: case CMD_EAT: case CMD_ACTIVATE: case CMD_FIRE: case CMD_USE_ANY: /* Check for inscriptions that trigger confirmation. */ allowed = key_confirm_command(cmdkey) && get_item_allow(slot, cmdkey, selected, FALSE); break; default: /* Invalid command; prevent anything from happening. */ bell("Invalid context menu command."); allowed = FALSE; break; } if (!allowed) return 1; if (selected == CMD_DESTROY) { /* squelch or unsquelch the item */ textui_cmd_destroy_menu(slot); } else if (selected == CMD_BROWSE_SPELL) { /* browse a spellbook */ /* copied from textui_spell_browse */ textui_book_browse(o_ptr); return 2; } else if (selected == CMD_STUDY_SPELL) { /* study a spell book */ /* copied from textui_obj_study */ int spell = get_spell(o_ptr, "study", spell_okay_to_study); if (spell >= 0) { cmd_insert(CMD_STUDY_SPELL); cmd_set_arg_choice(cmd_get_top(), 0, spell); } } else if (selected == CMD_CAST) { if (obj_can_browse(o_ptr)) { /* copied from textui_obj_cast */ const char *verb = ((p_ptr->class->spell_book == TV_MAGIC_BOOK) ? "cast" : "recite"); int spell = get_spell(o_ptr, verb, spell_okay_to_cast); if (spell >= 0) { cmd_insert(CMD_CAST); cmd_set_arg_choice(cmd_get_top(), 0, spell); } } } else {
/* * 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); }
/* pick the context menu options appropiate for an item available in a store */ int context_menu_store_item(struct store *store, const int oid, int mx, int my) { menu_type *m; rect_region r; int selected; char *labels; object_type *o_ptr; char header[120]; /* Get the actual object */ o_ptr = &store->stock[oid]; m = menu_dynamic_new(); if (!m || !store) { return 0; } object_desc(header, sizeof(header), o_ptr, ODESC_PREFIX | ODESC_BASE); labels = string_make(lower_case); m->selections = labels; menu_dynamic_add_label(m, "Examine", 'x', 4, labels); if (store->sidx == STORE_HOME) { menu_dynamic_add_label(m, "Take", 'p', 6, labels); if (o_ptr->number > 1) { menu_dynamic_add_label(m, "Take One", 'o', 5, labels); } } else { menu_dynamic_add_label(m, "Buy", 'p', 6, labels); if (o_ptr->number > 1) { menu_dynamic_add_label(m, "Buy One", 'o', 5, labels); } } /* work out display region */ r.width = menu_dynamic_longest_entry(m) + 3 + 2; /* +3 for tag, 2 for pad */ if (mx > Term->wid - r.width - 1) { r.col = Term->wid - r.width - 1; } else { r.col = mx + 1; } r.page_rows = m->count; if (my > Term->hgt - r.page_rows - 1) { if (my - r.page_rows - 1 <= 0) { /* menu has too many items, so put in upper right corner */ r.row = 1; r.col = Term->wid - r.width - 1; } else { r.row = Term->hgt - r.page_rows - 1; } } else { r.row = my + 1; } /* Hack -- no flush needed */ msg_flag = FALSE; screen_save(); button_backup_all(TRUE); menu_layout(m, &r); region_erase_bordered(&r); prt(format("(Enter to select, ESC) Command for %s:", header), 0, 0); selected = menu_dynamic_select(m); menu_dynamic_free(m); string_free(labels); button_restore(); screen_load(); if (selected == 4) { Term_keypress('x', 0); } else if (selected == 5) { if (store->sidx == STORE_HOME) { cmd_insert(CMD_RETRIEVE); } else { cmd_insert(CMD_BUY); } cmd_set_arg_choice(cmd_get_top(), 0, oid); cmd_set_arg_number(cmd_get_top(), 1, 1); } else if (selected == 6) { Term_keypress('p', 0); } return 1; }
/** * Handle a textui mouseclick. */ static void textui_process_click(ui_event e) { int x, y; if (!OPT(mouse_movement)) return; y = KEY_GRID_Y(e); x = KEY_GRID_X(e); /* Check for a valid location */ if (!cave_in_bounds_fully(cave, y, x)) return; /* XXX show context menu here */ if ((p_ptr->py == y) && (p_ptr->px == x)) { if (e.mouse.mods & KC_MOD_SHIFT) { /* shift-click - cast magic */ if (e.mouse.button == 1) { textui_obj_cast(); } else if (e.mouse.button == 2) { Term_keypress('i',0); } } else if (e.mouse.mods & KC_MOD_CONTROL) { /* ctrl-click - use feature / use inventory item */ /* switch with default */ if (e.mouse.button == 1) { if (cave_isupstairs(cave, p_ptr->py, p_ptr->px)) cmd_insert(CMD_GO_UP); else if (cave_isdownstairs(cave, p_ptr->py, p_ptr->px)) cmd_insert(CMD_GO_DOWN); } else if (e.mouse.button == 2) { cmd_insert(CMD_USE_UNAIMED); } } else if (e.mouse.mods & KC_MOD_ALT) { /* alt-click - Search or show char screen */ /* XXX call a platform specific hook */ if (e.mouse.button == 1) { cmd_insert(CMD_SEARCH); } else if (e.mouse.button == 2) { Term_keypress('C',0); } } else { if (e.mouse.button == 1) { if (cave->o_idx[y][x]) { cmd_insert(CMD_PICKUP); } else { cmd_insert(CMD_HOLD); } } else if (e.mouse.button == 2) { // show a context menu context_menu_player(e.mouse.x, e.mouse.y); } } } else if (e.mouse.button == 1) { if (p_ptr->timed[TMD_CONFUSED]) { cmd_insert(CMD_WALK); } else { if (e.mouse.mods & KC_MOD_SHIFT) { /* shift-click - run */ cmd_insert(CMD_RUN); cmd_set_arg_direction(cmd_get_top(), 0, coords_to_dir(y,x)); /*if ((y-p_ptr->py >= -1) && (y-p_ptr->py <= 1) && (x-p_ptr->px >= -1) && (x-p_ptr->px <= 1)) { cmd_insert(CMD_JUMP); cmd_set_arg_direction(cmd_get_top(), 0, coords_to_dir(y,x)); } else { cmd_insert(CMD_RUN); cmd_set_arg_direction(cmd_get_top(), 0, coords_to_dir(y,x)); }*/ } else if (e.mouse.mods & KC_MOD_CONTROL) { /* control-click - alter */ cmd_insert(CMD_ALTER); cmd_set_arg_direction(cmd_get_top(), 0, coords_to_dir(y,x)); } else if (e.mouse.mods & KC_MOD_ALT) { /* alt-click - look */ if (target_set_interactive(TARGET_LOOK, x, y)) { msg("Target Selected."); } //cmd_insert(CMD_LOOK); //cmd_set_arg_point(cmd_get_top(), 0, y, x); } else { /* pathfind does not work well on trap detection borders, * so if the click is next to the player, force a walk step */ if ((y-p_ptr->py >= -1) && (y-p_ptr->py <= 1) && (x-p_ptr->px >= -1) && (x-p_ptr->px <= 1)) { cmd_insert(CMD_WALK); cmd_set_arg_direction(cmd_get_top(), 0, coords_to_dir(y,x)); } else { cmd_insert(CMD_PATHFIND); cmd_set_arg_point(cmd_get_top(), 0, y, x); } } } } else if (e.mouse.button == 2) { struct monster *m = cave_monster_at(cave, y, x); if (m && target_able(m)) { /* Set up target information */ monster_race_track(m->race); health_track(p_ptr, m); target_set_monster(m); } else { target_set_location(y,x); } if (e.mouse.mods & KC_MOD_SHIFT) { /* shift-click - cast spell at target */ if (textui_obj_cast_ret() >= 0) { cmd_set_arg_target(cmd_get_top(), 1, DIR_TARGET); } } else if (e.mouse.mods & KC_MOD_CONTROL) { /* control-click - fire at target */ cmd_insert(CMD_USE_AIMED); cmd_set_arg_target(cmd_get_top(), 1, DIR_TARGET); } else if (e.mouse.mods & KC_MOD_ALT) { /* alt-click - throw at target */ cmd_insert(CMD_THROW); cmd_set_arg_target(cmd_get_top(), 1, DIR_TARGET); } else { //msg("Target set."); /* see if the click was adjacent to the player */ if ((y-p_ptr->py >= -1) && (y-p_ptr->py <= 1) && (x-p_ptr->px >= -1) && (x-p_ptr->px <= 1)) { context_menu_cave(cave,y,x,1,e.mouse.x, e.mouse.y); } else { context_menu_cave(cave,y,x,0,e.mouse.x, e.mouse.y); } } } }
/* pick the context menu options appropiate for a store */ int context_menu_store(struct store *store, const int oid, int mx, int my) { menu_type *m; rect_region r; int selected; char *labels; object_type *o_ptr; m = menu_dynamic_new(); if (!m || !store) { return 0; } /* Get the actual object */ o_ptr = &store->stock[oid]; labels = string_make(lower_case); m->selections = labels; menu_dynamic_add_label(m, "Inspect Inventory", 'I', 1, labels); if (store->sidx == STORE_HOME) { /*menu_dynamic_add(m, "Stash One", 2);*/ menu_dynamic_add_label(m, "Stash", 'd', 3, labels); menu_dynamic_add_label(m, "Examine", 'x', 4, labels); menu_dynamic_add_label(m, "Take", 'p', 6, labels); if (o_ptr->number > 1) { menu_dynamic_add_label(m, "Take One", 'o', 5, labels); } } else { /*menu_dynamic_add(m, "Sell One", 2);*/ menu_dynamic_add_label(m, "Sell", 'd', 3, labels); menu_dynamic_add_label(m, "Examine", 'x', 4, labels); menu_dynamic_add_label(m, "Buy", 'p', 6, labels); if (o_ptr->number > 1) { menu_dynamic_add_label(m, "Buy One", 'o', 5, labels); } } menu_dynamic_add_label(m, "Exit", '`', 7, labels); /* work out display region */ r.width = menu_dynamic_longest_entry(m) + 3 + 2; /* +3 for tag, 2 for pad */ if (mx > Term->wid - r.width - 1) { r.col = Term->wid - r.width - 1; } else { r.col = mx + 1; } r.page_rows = m->count; if (my > Term->hgt - r.page_rows - 1) { if (my - r.page_rows - 1 <= 0) { /* menu has too many items, so put in upper right corner */ r.row = 1; r.col = Term->wid - r.width - 1; } else { r.row = Term->hgt - r.page_rows - 1; } } else { r.row = my + 1; } /* Hack -- no flush needed */ msg_flag = FALSE; screen_save(); button_backup_all(TRUE); menu_layout(m, &r); region_erase_bordered(&r); prt("(Enter to select, ESC) Command:", 0, 0); selected = menu_dynamic_select(m); menu_dynamic_free(m); string_free(labels); button_restore(); screen_load(); if (selected == 1) { Term_keypress('I', 0); } else if (selected == 2) { Term_keypress('s', 0); /* oid is store item we do not know item we want to sell here */ /*if (store->sidx == STORE_HOME) { cmd_insert(CMD_STASH); } else { cmd_insert(CMD_SELL); } cmd_set_arg_item(cmd_get_top(), 0, oid); cmd_set_arg_number(cmd_get_top(), 1, 1);*/ } else if (selected == 3) { Term_keypress('s', 0); } else if (selected == 4) { Term_keypress('x', 0); } else if (selected == 5) { if (store->sidx == STORE_HOME) { cmd_insert(CMD_RETRIEVE); } else { cmd_insert(CMD_BUY); } cmd_set_arg_choice(cmd_get_top(), 0, oid); cmd_set_arg_number(cmd_get_top(), 1, 1); } else if (selected == 6) { Term_keypress('p', 0); } else if (selected == 7) { Term_keypress(ESCAPE, 0); } return 1; }
int context_menu_cave(struct cave *c, int y, int x, int adjacent, int mx, int my) { menu_type *m; region r; int selected; char *labels; bool allowed = TRUE; int mode = OPT(rogue_like_commands) ? KEYMAP_MODE_ROGUE : KEYMAP_MODE_ORIG; unsigned char cmdkey; m = menu_dynamic_new(); if (!m) { return 0; } labels = string_make(lower_case); m->selections = labels; /* Looking has different keys, but we don't have a way to look them up (see cmd-process.c). */ cmdkey = (mode == KEYMAP_MODE_ORIG) ? 'l' : 'x'; menu_dynamic_add_label(m, "Look At", cmdkey, MENU_VALUE_LOOK, labels); if (c->m_idx[y][x]) { /* '/' is used for recall in both keymaps. */ menu_dynamic_add_label(m, "Recall Info", '/', MENU_VALUE_RECALL, labels); } ADD_LABEL("Use Item On", CMD_USE_ANY, MN_ROW_VALID); if (player_can_cast(p_ptr, FALSE)) { ADD_LABEL("Cast On", CMD_CAST, MN_ROW_VALID); } if (adjacent) { ADD_LABEL((c->m_idx[y][x]) ? "Attack" : "Alter", CMD_ALTER, MN_ROW_VALID); if (c->o_idx[y][x]) { s16b o_idx = chest_check(y,x, CHEST_ANY); if (o_idx) { object_type *o_ptr = object_byid(o_idx); if (!squelch_item_ok(o_ptr)) { if (object_is_known(o_ptr)) { if (is_locked_chest(o_ptr)) { ADD_LABEL("Disarm Chest", CMD_DISARM, MN_ROW_VALID); ADD_LABEL("Open Chest", CMD_OPEN, MN_ROW_VALID); } else { ADD_LABEL("Open Disarmed Chest", CMD_OPEN, MN_ROW_VALID); } } else { ADD_LABEL("Open Chest", CMD_OPEN, MN_ROW_VALID); } } } } if (cave_istrap(c, y, x)) { ADD_LABEL("Disarm", CMD_DISARM, MN_ROW_VALID); ADD_LABEL("Jump Onto", CMD_JUMP, MN_ROW_VALID); } if (cave_isopendoor(c, y, x)) { ADD_LABEL("Close", CMD_CLOSE, MN_ROW_VALID); } else if (cave_iscloseddoor(c, y, x)) { ADD_LABEL("Open", CMD_OPEN, MN_ROW_VALID); ADD_LABEL("Lock", CMD_DISARM, MN_ROW_VALID); } else if (cave_isdiggable(c, y, x)) { ADD_LABEL("Tunnel", CMD_TUNNEL, MN_ROW_VALID); } ADD_LABEL("Search", CMD_SEARCH, MN_ROW_VALID); ADD_LABEL("Walk Towards", CMD_WALK, MN_ROW_VALID); } else { /* ',' is used for squelch in rogue keymap, so we'll just swap letters. */ cmdkey = (mode == KEYMAP_MODE_ORIG) ? ',' : '.'; menu_dynamic_add_label(m, "Pathfind To", cmdkey, CMD_PATHFIND, labels); ADD_LABEL("Walk Towards", CMD_WALK, MN_ROW_VALID); ADD_LABEL("Run Towards", CMD_RUN, MN_ROW_VALID); } if (player_can_fire(p_ptr, FALSE)) { ADD_LABEL("Fire On", CMD_FIRE, MN_ROW_VALID); } ADD_LABEL("Throw To", CMD_THROW, MN_ROW_VALID); /* work out display region */ r.width = (int)menu_dynamic_longest_entry(m) + 3 + 2; /* +3 for tag, 2 for pad */ if (mx > Term->wid - r.width - 1) { r.col = Term->wid - r.width - 1; } else { r.col = mx + 1; } r.page_rows = m->count; if (my > Term->hgt - r.page_rows - 1) { if (my - r.page_rows - 1 <= 0) { /* menu has too many items, so put in upper right corner */ r.row = 1; r.col = Term->wid - r.width - 1; } else { r.row = Term->hgt - r.page_rows - 1; } } else { r.row = my + 1; } /* Hack -- no flush needed */ msg_flag = FALSE; screen_save(); menu_layout(m, &r); region_erase_bordered(&r); if (p_ptr->timed[TMD_IMAGE]) { prt("(Enter to select command, ESC to cancel) You see something strange:", 0, 0); } else if (c->m_idx[y][x]) { char m_name[80]; monster_type *m_ptr = cave_monster_at(c, y, x); /* Get the monster name ("a kobold") */ monster_desc(m_name, sizeof(m_name), m_ptr, MDESC_IND_VIS); prt(format("(Enter to select command, ESC to cancel) You see %s:", m_name), 0, 0); } else if (c->o_idx[y][x] && !squelch_item_ok(object_byid(c->o_idx[y][x]))) { char o_name[80]; /* Get the single object in the list */ object_type *o_ptr = object_byid(c->o_idx[y][x]); /* Obtain an object description */ object_desc(o_name, sizeof (o_name), o_ptr, ODESC_PREFIX | ODESC_FULL); prt(format("(Enter to select command, ESC to cancel) You see %s:", o_name), 0, 0); } else { /* Feature (apply mimic) */ const char *name = cave_apparent_name(c, p_ptr, y, x); /* Hack -- special introduction for store doors */ if (cave_isshop(cave, y, x)) { prt(format("(Enter to select command, ESC to cancel) You see the entrance to the %s:", name), 0, 0); } else { prt(format("(Enter to select command, ESC to cancel) You see %s %s:", (is_a_vowel(name[0])) ? "an" : "a", name), 0, 0); } } selected = menu_dynamic_select(m); menu_dynamic_free(m); string_free(labels); screen_load(); cmdkey = cmd_lookup_key(selected, mode); /* Check the command to see if it is allowed. */ switch (selected) { case -1: /* User cancelled the menu. */ return 3; case MENU_VALUE_LOOK: case MENU_VALUE_RECALL: case CMD_PATHFIND: allowed = TRUE; break; case CMD_SEARCH: case CMD_ALTER: case CMD_DISARM: case CMD_JUMP: case CMD_CLOSE: case CMD_OPEN: case CMD_TUNNEL: case CMD_WALK: case CMD_RUN: case CMD_CAST: case CMD_FIRE: case CMD_THROW: case CMD_USE_ANY: /* Only check for ^ inscriptions, since we don't have an object selected (if we need one). */ allowed = key_confirm_command(cmdkey); break; default: /* Invalid command; prevent anything from happening. */ bell("Invalid context menu command."); allowed = FALSE; break; } if (!allowed) return 1; /* Perform the command. */ switch (selected) { case MENU_VALUE_LOOK: /* look at the spot */ if (target_set_interactive(TARGET_LOOK, x, y)) { msg("Target Selected."); } break; case MENU_VALUE_RECALL: { /* recall monster Info */ monster_type *m_ptr = cave_monster_at(c, y, x); if (m_ptr) { monster_lore *lore = get_lore(m_ptr->race); lore_show_interactive(m_ptr->race, lore); } } break; case CMD_SEARCH: cmd_insert(selected); break; case CMD_PATHFIND: cmd_insert(selected); cmd_set_arg_point(cmd_get_top(), 0, x, y); break; case CMD_ALTER: case CMD_DISARM: case CMD_JUMP: case CMD_CLOSE: case CMD_OPEN: case CMD_TUNNEL: case CMD_WALK: case CMD_RUN: cmd_insert(selected); cmd_set_arg_direction(cmd_get_top(), 0, coords_to_dir(y,x)); break; case CMD_CAST: if (textui_obj_cast_ret() >= 0) { cmd_set_arg_target(cmd_get_top(), 1, DIR_TARGET); } break; case CMD_FIRE: case CMD_THROW: case CMD_USE_ANY: cmd_insert(selected); cmd_set_arg_target(cmd_get_top(), 1, DIR_TARGET); break; default: break; } return 1; }
/* * 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); }
void textui_cmd_destroy(void) { int item; object_type *o_ptr; char out_val[160]; menu_type *m; region r; int selected; /* Get an item */ const char *q = "Ignore which item? "; const char *s = "You have nothing to ignore."; if (!get_item(&item, q, s, CMD_DESTROY, USE_INVEN | USE_EQUIP | USE_FLOOR)) return; o_ptr = object_from_item_idx(item); m = menu_dynamic_new(); m->selections = lower_case; /* Basic ignore option */ if (!o_ptr->ignore) { menu_dynamic_add(m, "This item only", IGNORE_THIS_ITEM); } else { menu_dynamic_add(m, "Unignore this item", UNIGNORE_THIS_ITEM); } /* Flavour-aware squelch */ if (squelch_tval(o_ptr->tval) && (!o_ptr->artifact || !object_flavor_is_aware(o_ptr))) { bool squelched = kind_is_squelched_aware(o_ptr->kind) || kind_is_squelched_unaware(o_ptr->kind); char tmp[70]; object_desc(tmp, sizeof(tmp), o_ptr, ODESC_BASE | ODESC_PLURAL); if (!squelched) { strnfmt(out_val, sizeof out_val, "All %s", tmp); menu_dynamic_add(m, out_val, IGNORE_THIS_FLAVOR); } else { strnfmt(out_val, sizeof out_val, "Unignore all %s", tmp); menu_dynamic_add(m, out_val, UNIGNORE_THIS_FLAVOR); } } /* Quality squelching */ if (object_was_sensed(o_ptr) || object_was_worn(o_ptr) || object_is_known_not_artifact(o_ptr)) { byte value = squelch_level_of(o_ptr); int type = squelch_type_of(o_ptr); if (object_is_jewelry(o_ptr) && squelch_level_of(o_ptr) != SQUELCH_BAD) value = SQUELCH_MAX; if (value != SQUELCH_MAX && type != TYPE_MAX) { strnfmt(out_val, sizeof out_val, "All %s %s", quality_values[value].name, quality_choices[type].name); menu_dynamic_add(m, out_val, IGNORE_THIS_QUALITY); } } /* work out display region */ r.width = menu_dynamic_longest_entry(m) + 3 + 2; /* +3 for tag, 2 for pad */ r.col = 80 - r.width; r.row = 1; r.page_rows = m->count; screen_save(); menu_layout(m, &r); region_erase_bordered(&r); prt("(Enter to select, ESC) Ignore:", 0, 0); selected = menu_dynamic_select(m); screen_load(); if (selected == IGNORE_THIS_ITEM) { cmd_insert(CMD_DESTROY); cmd_set_arg_item(cmd_get_top(), 0, item); } else if (selected == UNIGNORE_THIS_ITEM) { o_ptr->ignore = FALSE; } else if (selected == IGNORE_THIS_FLAVOR) { object_squelch_flavor_of(o_ptr); } else if (selected == UNIGNORE_THIS_FLAVOR) { kind_squelch_clear(o_ptr->kind); } else if (selected == IGNORE_THIS_QUALITY) { byte value = squelch_level_of(o_ptr); int type = squelch_type_of(o_ptr); squelch_level[type] = value; } p_ptr->notice |= PN_SQUELCH; menu_dynamic_free(m); }