/** * Disarms a trap, or a chest * * Traps must be visible, chests must be known trapped */ void do_cmd_disarm(struct command *cmd) { int y, x, dir; int err; struct object *obj; bool more = false; /* Get arguments */ err = cmd_get_arg_direction(cmd, "direction", &dir); if (err || dir == DIR_UNKNOWN) { int y2, x2; int n_traps, n_chests; n_traps = count_feats(&y2, &x2, square_isknowntrap, true); n_chests = count_chests(&y2, &x2, CHEST_TRAPPED); if (n_traps + n_chests == 1) { dir = coords_to_dir(y2, x2); cmd_set_arg_direction(cmd, "direction", dir); } else if (cmd_get_direction(cmd, "direction", &dir, n_chests > 0)) { /* If there are chests to disarm, 5 is allowed as a direction */ return; } } /* Get location */ y = player->py + ddy[dir]; x = player->px + ddx[dir]; /* Check for chests */ obj = chest_check(y, x, CHEST_TRAPPED); /* Verify legality */ if (!obj && !do_cmd_disarm_test(y, x)) { /* Cancel repeat */ disturb(player, 0); return; } /* Take a turn */ player->upkeep->energy_use = z_info->move_energy; /* Apply confusion */ if (player_confuse_dir(player, &dir, false)) { /* Get location */ y = player->py + ddy[dir]; x = player->px + ddx[dir]; /* Check for chests */ obj = chest_check(y, x, CHEST_TRAPPED); } /* Monster */ if (cave->squares[y][x].mon > 0) { msg("There is a monster in the way!"); py_attack(y, x); } else if (obj) /* Chest */ more = do_cmd_disarm_chest(y, x, obj); else if (square_iscloseddoor(cave, y, x) && !square_islockeddoor(cave, y, x)) /* Door to lock */ more = do_cmd_lock_door(y, x); else /* Disarm trap */ more = do_cmd_disarm_aux(y, x); /* Cancel repeat unless told not to */ if (!more) disturb(player, 0); }
/** * Bring up player actions */ void show_player(void) { int i, j, fy, fx; int adj_grid[9]; bool exist_rock = FALSE; bool exist_door = FALSE; bool exist_open_door = FALSE; bool exist_trap = FALSE; bool exist_mtrap = FALSE; bool exist_floor = FALSE; bool exist_monster = FALSE; feature_type *f_ptr; /* No commands yet */ poss = 0; /* Get surroundings */ get_feats(adj_grid); /* Analyze surroundings */ for (i = 0; i < 8; i++) { int yy = p_ptr->py + ddy_ddd[i]; int xx = p_ptr->px + ddx_ddd[i]; f_ptr = &f_info[adj_grid[i]]; if (cave_visible_trap(yy, xx)) exist_trap = TRUE; if (tf_has(f_ptr->flags, TF_DOOR_CLOSED)) exist_door = TRUE; if (tf_has(f_ptr->flags, TF_ROCK)) exist_rock = TRUE; if (cave_monster_trap(yy, xx)) exist_mtrap = TRUE; if (adj_grid[i] == FEAT_OPEN) exist_open_door = TRUE; if (cave_naked_bold(yy, xx)) exist_floor = TRUE; if (cave_m_idx[yy][xx] > 0) exist_monster = TRUE; } /* In a web? */ if (cave_web(p_ptr->py, p_ptr->px)) exist_trap = TRUE; /* Alter a grid */ if (exist_trap || exist_door || exist_rock || exist_mtrap || exist_open_door || count_chests(&fy, &fx, TRUE) || count_chests(&fy, &fx, FALSE) || (player_has(PF_TRAP) && exist_floor) || (player_has(PF_STEAL) && exist_monster && (!SCHANGE))) { comm[poss] = '+'; comm_code[poss] = CMD_ALTER; comm_descr[poss++] = "Alter"; } /* Dig a tunnel */ if (exist_door || exist_rock) { comm[poss] = 'T'; comm_code[poss] = CMD_TUNNEL; comm_descr[poss++] = "Tunnel"; } /* Begin Running -- Arg is Max Distance */ { comm[poss] = '.'; comm_code[poss] = CMD_RUN; comm_descr[poss++] = "Run"; } /* Hold still for a turn. Pickup objects if auto-pickup is true. */ { comm[poss] = ','; comm_code[poss] = CMD_HOLD; comm_descr[poss++] = "Stand still"; } /* Pick up objects. */ if (cave_o_idx[p_ptr->py][p_ptr->px]) { comm[poss] = 'g'; comm_code[poss] = CMD_PICKUP; comm_descr[poss++] = "Pick up"; } /* Rest -- Arg is time */ { comm[poss] = 'R'; comm_code[poss] = CMD_REST; comm_descr[poss++] = "Rest"; } /* Search for traps/doors */ { comm[poss] = 's'; comm_code[poss] = CMD_SEARCH; comm_descr[poss++] = "Search"; } /* Look around */ { comm[poss] = 'l'; comm_code[poss] = CMD_NULL; comm_descr[poss++] = "Look"; } /* Scroll the map */ { comm[poss] = 'L'; comm_code[poss] = CMD_NULL; comm_descr[poss++] = "Scroll map"; } /* Show the map */ { comm[poss] = 'M'; comm_code[poss] = CMD_NULL; comm_descr[poss++] = "Level map"; } /* Knowledge */ { comm[poss] = '~'; comm_code[poss] = CMD_NULL; comm_descr[poss++] = "Knowledge"; } /* Options */ { comm[poss] = '='; comm_code[poss] = CMD_NULL; comm_descr[poss++] = "Options"; } /* Toggle search mode */ { comm[poss] = 'S'; comm_code[poss] = CMD_TOGGLE_SEARCH; comm_descr[poss++] = "Toggle searching"; } /* Go up staircase */ if ((adj_grid[8] == FEAT_LESS) || ((adj_grid[8] >= FEAT_LESS_NORTH) && (!(adj_grid[8] % 2)))) { comm[poss] = '<'; comm_code[poss] = CMD_GO_UP; comm_descr[poss++] = "Take stair/path"; } /* Go down staircase */ if ((adj_grid[8] == FEAT_MORE) || ((adj_grid[8] >= FEAT_LESS_NORTH) && (adj_grid[8] % 2))) { comm[poss] = '>'; comm_code[poss] = CMD_GO_DOWN; comm_descr[poss++] = "Take stair/path"; } /* Open a door or chest */ if (exist_door || count_chests(&fy, &fx, TRUE) || count_chests(&fy, &fx, FALSE)) { comm[poss] = 'o'; comm_code[poss] = CMD_OPEN; comm_descr[poss++] = "Open"; } /* Close a door */ if (exist_open_door) { comm[poss] = 'c'; comm_code[poss] = CMD_CLOSE; comm_descr[poss++] = "Close"; } /* Jam a door with spikes */ if (exist_door) { comm[poss] = 'j'; comm_code[poss] = CMD_JAM; comm_descr[poss++] = "Jam"; } /* Bash a door */ if (exist_door) { comm[poss] = 'B'; comm_code[poss] = CMD_BASH; comm_descr[poss++] = "Bash"; } /* Disarm a trap or chest */ if (count_chests(&fy, &fx, TRUE) || exist_trap || exist_mtrap) { comm[poss] = 'D'; comm_code[poss] = CMD_DISARM; comm_descr[poss++] = "Disarm"; } /* Shapechange */ if ((SCHANGE) || (player_has(PF_BEARSKIN))) { comm[poss] = ']'; comm_code[poss] = CMD_NULL; comm_descr[poss++] = "Shapechange"; } /* Save screen */ screen_save(); /* Prompt */ put_str("Choose a command, or ESC:", 0, 0); /* Hack - delete exact graphics rows */ if (tile_height > 1) { j = poss + 1; while ((j % tile_height) && (j <= SCREEN_ROWS)) prt("", ++j, 0); } /* Get a choice */ (void) show_cmd_menu(FALSE); /* Load screen */ screen_load(); }
/** * Open a closed/locked/jammed door or a closed/locked chest. * * Unlocking a locked chest is worth one experience point; since doors are * player lockable, there is no experience for unlocking doors. */ void do_cmd_open(struct command *cmd) { int y, x, dir; struct object *obj; bool more = false; int err; struct monster *m; /* Get arguments */ err = cmd_get_arg_direction(cmd, "direction", &dir); if (err || dir == DIR_UNKNOWN) { int y2, x2; int n_closed_doors, n_locked_chests; n_closed_doors = count_feats(&y2, &x2, square_iscloseddoor, false); n_locked_chests = count_chests(&y2, &x2, CHEST_OPENABLE); if (n_closed_doors + n_locked_chests == 1) { dir = coords_to_dir(y2, x2); cmd_set_arg_direction(cmd, "direction", dir); } else if (cmd_get_direction(cmd, "direction", &dir, false)) { return; } } /* Get location */ y = player->py + ddy[dir]; x = player->px + ddx[dir]; /* Check for chest */ obj = chest_check(y, x, CHEST_OPENABLE); /* Check for door */ if (!obj && !do_cmd_open_test(y, x)) { /* Cancel repeat */ disturb(player, 0); return; } /* Take a turn */ player->upkeep->energy_use = z_info->move_energy; /* Apply confusion */ if (player_confuse_dir(player, &dir, false)) { /* Get location */ y = player->py + ddy[dir]; x = player->px + ddx[dir]; /* Check for chest */ obj = chest_check(y, x, CHEST_OPENABLE); } /* Monster */ m = square_monster(cave, y, x); if (m) { /* Mimics surprise the player */ if (is_mimicking(m)) { become_aware(m); /* Mimic wakes up */ mon_clear_timed(m, MON_TMD_SLEEP, MON_TMD_FLG_NOMESSAGE, false); } else { /* Message */ msg("There is a monster in the way!"); /* Attack */ py_attack(y, x); } } else if (obj) { /* Chest */ more = do_cmd_open_chest(y, x, obj); } else { /* Door */ more = do_cmd_open_aux(y, x); } /* Cancel repeat unless we may continue */ if (!more) disturb(player, 0); }
/* * Disarms a trap, a glyph, or a chest. */ void do_cmd_disarm(void) { int py = p_ptr->py; int px = p_ptr->px; int y, x, dir; s16b o_idx; bool more = FALSE; /* Option: Pick a direction -TNB- */ if (easy_disarm) { int num_traps, num_chests; /* Count visible traps */ num_traps = count_feats(&y, &x, is_trap, TRUE); /* Count chests (trapped) */ num_chests = count_chests(&y, &x, TRUE); /* See if there's only one target */ if (num_traps || num_chests) { if (num_traps + num_chests <= 1) p_ptr->command_dir = coords_to_dir(y, x); } } /* Get a direction (or abort) */ if (!get_rep_dir(&dir)) return; /* Get location */ y = py + ddy[dir]; x = px + ddx[dir]; /* Check for chests */ o_idx = chest_check(y, x); /* Verify legality */ if (!o_idx && !do_cmd_disarm_test(y, x)) return; /* Take a turn */ p_ptr->energy_use = 100; /* Apply confusion */ if (confuse_dir(&dir)) { /* Get location */ y = py + ddy[dir]; x = px + ddx[dir]; /* Check for chests */ o_idx = chest_check(y, x); } /* Allow repeated command */ if (p_ptr->command_arg) { /* Set repeat count */ p_ptr->command_rep = p_ptr->command_arg - 1; /* Redraw the state */ p_ptr->redraw |= (PR_STATE); /* Cancel the arg */ p_ptr->command_arg = 0; } /* Monster */ if (cave_m_idx[y][x] > 0) { /* Message */ msg_print("There is a monster in the way!"); /* Attack */ py_attack(y, x); } /* Chest */ else if (o_idx) { /* Disarm the chest */ more = do_cmd_disarm_chest(y, x, o_idx); } /* Disarm trap */ else { /* Disarm the trap */ more = do_cmd_disarm_aux(y, x); } /* Cancel repeat unless told not to */ if (!more) disturb(0, 0); }