/** * Update the current "run" path * * Return TRUE if the running should be stopped */ static bool run_test(void) { int py = p_ptr->py; int px = p_ptr->px; int prev_dir; int new_dir; int check_dir = 0; int left_dir; int right_dir; int row, col; int i, max, inv; int option, option2; /* No options yet */ option = 0; option2 = 0; /* Where we came from */ prev_dir = p_ptr->run_old_dir; /* Range of newly adjacent grids */ max = (prev_dir & 0x01) + 1; /* Simplistic running for outdoors -NRM- */ if ((stage_map[p_ptr->stage][STAGE_TYPE] != CAVE) && (stage_map[p_ptr->stage][STAGE_TYPE] != TOWN)) { /* Look at every newly adjacent square. */ for (i = -max; i <= max; i++) { s16b this_o_idx, next_o_idx = 0; /* New direction */ new_dir = cycle[chome[prev_dir] + i]; /* New location */ row = py + ddy[new_dir]; col = px + ddx[new_dir]; /* Visible monsters abort running */ if (cave_m_idx[row][col] > 0) { monster_type *m_ptr = &m_list[cave_m_idx[row][col]]; /* Visible monster */ if (m_ptr->ml) return (TRUE); } /* Visible objects abort running */ for (this_o_idx = cave_o_idx[row][col]; this_o_idx; this_o_idx = next_o_idx) { object_type *o_ptr; /* Acquire object */ o_ptr = &o_list[this_o_idx]; /* Acquire next object */ next_o_idx = o_ptr->next_o_idx; /* Visible object */ if (o_ptr->marked && !squelch_hide_item(o_ptr)) return (TRUE); } } /* Assume main direction */ new_dir = p_ptr->run_old_dir; row = py + ddy[new_dir]; col = px + ddx[new_dir]; /* Step if there's a path in the right direction */ if ((cave_feat[row][col] == FEAT_FLOOR) || (cave_feat[row][col] == FEAT_INVIS)) { p_ptr->run_cur_dir = new_dir; return (FALSE); } /* Check to the left */ left_dir = cycle[chome[prev_dir] - 1]; row = py + ddy[left_dir]; col = px + ddx[left_dir]; if ((cave_feat[row][col] == FEAT_FLOOR) || (cave_feat[row][col] == FEAT_INVIS)) option = left_dir; /* Check to the right */ right_dir = cycle[chome[prev_dir] + 1]; row = py + ddy[right_dir]; col = px + ddx[right_dir]; if ((cave_feat[row][col] == FEAT_FLOOR) || (cave_feat[row][col] == FEAT_INVIS)) option2 = right_dir; /* Stop if it's a fork */ if (option && option2) return (TRUE); /* Otherwise step in the secondary direction */ if (option) { p_ptr->run_cur_dir = left_dir; return (FALSE); } else if (option2) { p_ptr->run_cur_dir = right_dir; return (FALSE); } /* No paths, so try grass */ row = py + ddy[new_dir]; col = px + ddx[new_dir]; /* Step if there's grass in the right direction */ if ((cave_feat[row][col] == FEAT_GRASS) || (cave_feat[row][col] == FEAT_GRASS_INVIS)) { p_ptr->run_cur_dir = new_dir; return (FALSE); } /* Check to the left */ row = py + ddy[left_dir]; col = px + ddx[left_dir]; if ((cave_feat[row][col] == FEAT_GRASS) || (cave_feat[row][col] == FEAT_GRASS_INVIS)) option = left_dir; /* Check to the right */ right_dir = cycle[chome[prev_dir] + 1]; row = py + ddy[right_dir]; col = px + ddx[right_dir]; if ((cave_feat[row][col] == FEAT_GRASS) || (cave_feat[row][col] == FEAT_GRASS_INVIS)) option2 = right_dir; /* Stop if it's a fork */ if (option && option2) return (TRUE); /* Otherwise step in the secondary direction */ if (option) { p_ptr->run_cur_dir = left_dir; return (FALSE); } else if (option2) { p_ptr->run_cur_dir = right_dir; return (FALSE); } } /* Look at every newly adjacent square. */ for (i = -max; i <= max; i++) { s16b this_o_idx, next_o_idx = 0; /* New direction */ new_dir = cycle[chome[prev_dir] + i]; /* New location */ row = py + ddy[new_dir]; col = px + ddx[new_dir]; /* Visible monsters abort running */ if (cave_m_idx[row][col] > 0) { monster_type *m_ptr = &m_list[cave_m_idx[row][col]]; /* Visible monster */ if (m_ptr->ml) return (TRUE); } /* Visible objects abort running */ for (this_o_idx = cave_o_idx[row][col]; this_o_idx; this_o_idx = next_o_idx) { object_type *o_ptr; /* Acquire object */ o_ptr = &o_list[this_o_idx]; /* Acquire next object */ next_o_idx = o_ptr->next_o_idx; /* Visible object */ if (o_ptr->marked) return (TRUE); } /* Assume unknown */ inv = TRUE; /* Check memorized grids */ if (cave_info[row][col] & (CAVE_MARK)) { bool notice = TRUE; /* Examine the terrain */ switch (cave_feat[row][col]) { /* Floors */ case FEAT_FLOOR: /* Invis traps */ case FEAT_INVIS: case FEAT_GRASS_INVIS: /* Secret doors */ case FEAT_SECRET: /* Normal veins */ case FEAT_MAGMA: case FEAT_QUARTZ: /* Hidden treasure */ case FEAT_MAGMA_H: case FEAT_QUARTZ_H: /* Special passable terrain. */ case FEAT_LAVA: case FEAT_WATER: case FEAT_TREE: case FEAT_TREE2: case FEAT_GRASS: { /* Ignore */ notice = FALSE; /* Done */ break; } /* Walls */ case FEAT_WALL_EXTRA: case FEAT_WALL_INNER: case FEAT_WALL_OUTER: case FEAT_WALL_SOLID: case FEAT_PERM_EXTRA: case FEAT_PERM_INNER: case FEAT_PERM_OUTER: case FEAT_PERM_SOLID: { /* Ignore */ notice = FALSE; /* Done */ break; } /* Open doors */ case FEAT_OPEN: case FEAT_BROKEN: { /* Option -- ignore */ if (OPT(run_ignore_doors)) notice = FALSE; /* Done */ break; } /* Stairs */ case FEAT_LESS: case FEAT_MORE: { /* Option -- ignore */ if (OPT(run_ignore_stairs)) notice = FALSE; /* Done */ break; } } /* Interesting feature */ if (notice) return (TRUE); /* The grid is "visible" */ inv = FALSE; } /* Analyze unknown grids and floors */ if (inv || cave_floor_bold(row, col)) { /* Looking for open area */ if (p_ptr->run_open_area) { /* Nothing */ } /* The first new direction. */ else if (!option) { option = new_dir; } /* Three new directions. Stop running. */ else if (option2) { return (TRUE); } /* Two non-adjacent new directions. Stop running. */ else if (option != cycle[chome[prev_dir] + i - 1]) { return (TRUE); } /* Two new (adjacent) directions (case 1) */ else if (new_dir & 0x01) { check_dir = cycle[chome[prev_dir] + i - 2]; option2 = new_dir; } /* Two new (adjacent) directions (case 2) */ else { check_dir = cycle[chome[prev_dir] + i + 1]; option2 = option; option = new_dir; } } /* Obstacle, while looking for open area */ else { if (p_ptr->run_open_area) { if (i < 0) { /* Break to the right */ p_ptr->run_break_right = TRUE; } else if (i > 0) { /* Break to the left */ p_ptr->run_break_left = TRUE; } } } } /* Looking for open area */ if (p_ptr->run_open_area) { /* Hack -- look again */ for (i = -max; i < 0; i++) { new_dir = cycle[chome[prev_dir] + i]; row = py + ddy[new_dir]; col = px + ddx[new_dir]; /* Unknown grid or non-wall */ /* Was: cave_floor_bold(row, col) */ if (!(cave_info[row][col] & (CAVE_MARK)) || (cave_feat[row][col] < FEAT_SECRET) || (cave_feat[row][col] > FEAT_SHOP_HEAD)) { /* Looking to break right */ if (p_ptr->run_break_right) { return (TRUE); } } /* Obstacle */ else { /* Looking to break left */ if (p_ptr->run_break_left) { return (TRUE); } } } /* Hack -- look again */ for (i = max; i > 0; i--) { new_dir = cycle[chome[prev_dir] + i]; row = py + ddy[new_dir]; col = px + ddx[new_dir]; /* Unknown grid or non-wall */ /* Was: cave_floor_bold(row, col) */ if (!(cave_info[row][col] & (CAVE_MARK)) || (cave_feat[row][col] < FEAT_SECRET) || (cave_feat[row][col] > FEAT_SHOP_HEAD)) { /* Looking to break left */ if (p_ptr->run_break_left) { return (TRUE); } } /* Obstacle */ else { /* Looking to break right */ if (p_ptr->run_break_right) { return (TRUE); } } } } /* Not looking for open area */ else { /* No options */ if (!option) { return (TRUE); } /* One option */ else if (!option2) { /* Primary option */ p_ptr->run_cur_dir = option; /* No other options */ p_ptr->run_old_dir = option; } /* Two options, examining corners */ else if (OPT(run_use_corners) && !OPT(run_cut_corners)) { /* Primary option */ p_ptr->run_cur_dir = option; /* Hack -- allow curving */ p_ptr->run_old_dir = option2; } /* Two options, pick one */ else { /* Get next location */ row = py + ddy[option]; col = px + ddx[option]; /* Don't see that it is closed off. */ /* This could be a potential corner or an intersection. */ if (!see_wall(option, row, col) || !see_wall(check_dir, row, col)) { /* Can not see anything ahead and in the direction we */ /* are turning, assume that it is a potential corner. */ if (OPT(run_use_corners) && see_nothing(option, row, col) && see_nothing(option2, row, col)) { p_ptr->run_cur_dir = option; p_ptr->run_old_dir = option2; } /* STOP: we are next to an intersection or a room */ else { return (TRUE); } } /* This corner is seen to be enclosed; we cut the corner. */ else if (OPT(run_cut_corners)) { p_ptr->run_cur_dir = option2; p_ptr->run_old_dir = option2; } /* This corner is seen to be enclosed, and we */ /* deliberately go the long way. */ else { p_ptr->run_cur_dir = option; p_ptr->run_old_dir = option2; } } } /* About to hit a known wall, stop */ if (see_wall(p_ptr->run_cur_dir, py, px)) { return (TRUE); } /* Failure */ return (FALSE); }
/* * Update the current "run" path * * Return TRUE if the running should be stopped */ static bool run_test(void) { int fy = m_ptr->fy; int fx = m_ptr->fx; int prev_dir; int new_dir; int check_dir = 0; int row, col; int i, max; int option, option2; int feat; bool notice; /* No options yet */ option = 0; option2 = 0; /* Where we came from */ prev_dir = m_ptr->run_old_dir; /* Range of newly adjacent grids */ max = (prev_dir & 0x01) + 1; /* Look at every newly adjacent square. */ for (i = -max; i <= max; i++) { s16b this_o_idx, next_o_idx = 0; /* New direction */ new_dir = cycle[chome[prev_dir] + i]; /* New location */ row = fy + ddy[new_dir]; col = fx + ddx[new_dir]; /* Visible monsters abort running */ if (cave_m_idx[row][col] > 0) { return (TRUE); } /* Analyze unknown grids and floors */ if (cave_floor_bold(row, col)) { /* Looking for open area */ if (m_ptr->mflag & (MFLAG_RUN_OPEN_AREA)) { /* Nothing */ } /* The first new direction. */ else if (!option) { option = new_dir; } /* Three new directions. Stop running. */ else if (option2) { return (TRUE); } /* Two non-adjacent new directions. Stop running. */ else if (option != cycle[chome[prev_dir] + i - 1]) { return (TRUE); } /* Two new (adjacent) directions (case 1) */ else if (new_dir & 0x01) { check_dir = cycle[chome[prev_dir] + i - 2]; option2 = new_dir; } /* Two new (adjacent) directions (case 2) */ else { check_dir = cycle[chome[prev_dir] + i + 1]; option2 = option; option = new_dir; } } /* Obstacle, while looking for open area */ else { if (m_ptr->mflag & (MFLAG_RUN_OPEN_AREA)) { if (i < 0) { /* Break to the right */ m_ptr->mflag |= MFLAG_RUN_BREAK_RIGHT; } else if (i > 0) { /* Break to the left */ m_ptr->mflag |= MFLAG_RUN_BREAK_LEFT; } } } } /* Looking for open area */ if (m_ptr->mflag & (MFLAG_RUN_OPEN_AREA)run_open_area) { /* Hack -- look again */ for (i = -max; i < 0; i++) { new_dir = cycle[chome[prev_dir] + i]; row = fy + ddy[new_dir]; col = fx + ddx[new_dir]; /* Get feature */ feat = cave_feat[row][col]; /* Get mimiced feature */ feat = f_info[feat].mimic; /* Unknown grid or non-wall */ /* Was: cave_floor_bold(row, col) */ if (!(cave_info[row][col] & (CAVE_MARK)) || (!(f_info[feat].flags1 & (FF1_WALL))) ) { /* Looking to break right */ if ((m_ptr->mflag & (MFLAG_RUN_BREAK_RIGHT))) { return (TRUE); } } /* Obstacle */ else { /* Looking to break left */ if ((m_ptr->mflag & (MFLAG_RUN_BREAK_LEFT))) { return (TRUE); } } } /* Hack -- look again */ for (i = max; i > 0; i--) { new_dir = cycle[chome[prev_dir] + i]; row = fy + ddy[new_dir]; col = fx + ddx[new_dir]; /* Get feature */ feat = cave_feat[row][col]; /* Get mimiced feature */ feat = f_info[feat].mimic; /* Unknown grid or non-wall */ /* Was: cave_floor_bold(row, col) */ if (!(cave_info[row][col] & (CAVE_MARK)) || (!(f_info[feat].flags1 & (FF1_WALL)))) { /* Looking to break left */ if ((m_ptr->mflag & (MFLAG_RUN_BREAK_LEFT))) { return (TRUE); } } /* Obstacle */ else { /* Looking to break right */ if ((m_ptr->mflag & (MFLAG_RUN_BREAK_RIGHT))) { return (TRUE); } } } } /* Not looking for open area */ else { /* No options */ if (!option) { return (TRUE); } /* One option */ else if (!option2) { /* Primary option */ m_ptr->run_cur_dir = option; /* No other options */ m_ptr->run_old_dir = option; } /* Two options, examining corners */ else if (run_use_corners && !run_cut_corners) { /* Primary option */ m_ptr->run_cur_dir = option; /* Hack -- allow curving */ m_ptr->run_old_dir = option2; } /* Two options, pick one */ else { /* Get next location */ row = fy + ddy[option]; col = fx + ddx[option]; /* Don't see that it is closed off. */ /* This could be a potential corner or an intersection. */ if (!see_wall(option, row, col) || !see_wall(check_dir, row, col)) { /* Can not see anything ahead and in the direction we */ /* are turning, assume that it is a potential corner. */ if (run_use_corners && see_nothing(option, row, col) && see_nothing(option2, row, col)) { m_ptr->run_cur_dir = option; m_ptr->run_old_dir = option2; } /* STOP: we are next to an intersection or a room */ else { return (TRUE); } } /* This corner is seen to be enclosed; we cut the corner. */ else if (run_cut_corners) { m_ptr->run_cur_dir = option2; m_ptr->run_old_dir = option2; } /* This corner is seen to be enclosed, and we */ /* deliberately go the long way. */ else { m_ptr->run_cur_dir = option; m_ptr->run_old_dir = option2; } } } /* About to hit a known wall, stop */ if (see_wall(m_ptr->run_cur_dir, fy, fx)) { return (TRUE); } /* Failure */ return (FALSE); }