/** * Initialize the running algorithm for a new direction. * * Diagonal Corridor -- allow diaginal entry into corridors. * * Blunt Corridor -- If there is a wall two spaces ahead and * we seem to be in a corridor, then force a turn into the side * corridor, must be moving straight into a corridor here. ??? * * Diagonal Corridor Blunt Corridor (?) * # # # * #x# @x# * @p. p */ static void run_init(int dir) { int py = p_ptr->py; int px = p_ptr->px; int i, row, col; bool deepleft, deepright; bool shortleft, shortright; /* Save the direction */ p_ptr->run_cur_dir = dir; /* Assume running straight */ p_ptr->run_old_dir = dir; /* If it's wilderness, done -NRM- */ if ((stage_map[p_ptr->stage][STAGE_TYPE] != CAVE) && (stage_map[p_ptr->stage][STAGE_TYPE] != TOWN)) return; /* Assume looking for open area */ p_ptr->run_open_area = TRUE; /* Assume not looking for breaks */ p_ptr->run_break_right = FALSE; p_ptr->run_break_left = FALSE; /* Assume no nearby walls */ deepleft = deepright = FALSE; shortright = shortleft = FALSE; /* Find the destination grid */ row = py + ddy[dir]; col = px + ddx[dir]; /* Extract cycle index */ i = chome[dir]; /* Check for nearby wall */ if (see_wall(cycle[i + 1], py, px)) { p_ptr->run_break_left = TRUE; shortleft = TRUE; } /* Check for distant wall */ else if (see_wall(cycle[i + 1], row, col)) { p_ptr->run_break_left = TRUE; deepleft = TRUE; } /* Check for nearby wall */ if (see_wall(cycle[i - 1], py, px)) { p_ptr->run_break_right = TRUE; shortright = TRUE; } /* Check for distant wall */ else if (see_wall(cycle[i - 1], row, col)) { p_ptr->run_break_right = TRUE; deepright = TRUE; } /* Looking for a break */ if (p_ptr->run_break_left && p_ptr->run_break_right) { /* Not looking for open area */ p_ptr->run_open_area = FALSE; /* Hack -- allow angled corridor entry */ if (dir & 0x01) { if (deepleft && !deepright) { p_ptr->run_old_dir = cycle[i - 1]; } else if (deepright && !deepleft) { p_ptr->run_old_dir = cycle[i + 1]; } } /* Hack -- allow blunt corridor entry */ else if (see_wall(cycle[i], row, col)) { if (shortleft && !shortright) { p_ptr->run_old_dir = cycle[i - 2]; } else if (shortright && !shortleft) { p_ptr->run_old_dir = cycle[i + 2]; } } } }
/** * 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 py = player->py; int px = player->px; int prev_dir; int new_dir; int row, col; int i, max, inv; int option, option2; /* No options yet */ option = 0; option2 = 0; /* Where we came from */ prev_dir = 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++) { struct object *obj; /* 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->squares[row][col].mon > 0) { monster_type *m_ptr = square_monster(cave, row, col); /* Visible monster */ if (mflag_has(m_ptr->mflag, MFLAG_VISIBLE)) return (TRUE); } /* Visible objects abort running */ for (obj = square_object(cave, row, col); obj; obj = obj->next) /* Visible object */ if (obj->marked && !ignore_item_ok(obj)) return (TRUE); /* Assume unknown */ inv = TRUE; /* Check memorized grids */ if (square_ismark(cave, row, col)) { bool notice = square_noticeable(cave, row, col); /* Interesting feature */ if (notice) return (TRUE); /* The grid is "visible" */ inv = FALSE; } /* Analyze unknown grids and floors */ if (inv || square_ispassable(cave, row, col)) { /* Looking for open area */ if (run_open_area) { /* Nothing */ } else if (!option) { /* The first new direction. */ option = new_dir; } else if (option2) { /* Three new directions. Stop running. */ return (TRUE); } else if (option != cycle[chome[prev_dir] + i - 1]) { /* Two non-adjacent new directions. Stop running. */ return (TRUE); } else if (new_dir & 0x01) { /* Two new (adjacent) directions (case 1) */ option2 = new_dir; } else { /* Two new (adjacent) directions (case 2) */ option2 = option; option = new_dir; } } else { /* Obstacle, while looking for open area */ if (run_open_area) { if (i < 0) { /* Break to the right */ run_break_right = TRUE; } else if (i > 0) { /* Break to the left */ run_break_left = TRUE; } } } } /* Look at every soon to be newly adjacent square. */ for (i = -max; i <= max; i++) { /* New direction */ new_dir = cycle[chome[prev_dir] + i]; /* New location */ row = py + ddy[prev_dir] + ddy[new_dir]; col = px + ddx[prev_dir] + ddx[new_dir]; /* HACK: Ugh. Sometimes we come up with illegal bounds. This will * treat the symptom but not the disease. */ if (row >= cave->height || col >= cave->width) continue; if (row < 0 || col < 0) continue; /* Visible monsters abort running */ if (cave->squares[row][col].mon > 0) { monster_type *m_ptr = square_monster(cave, row, col); /* Visible monster */ if (mflag_has(m_ptr->mflag, MFLAG_VISIBLE) && !is_mimicking(m_ptr)) return (TRUE); } } /* Looking for open area */ if (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: square_ispassable(cave, row, col) */ if (!square_ismark(cave, row, col) || (square_ispassable(cave, row, col))) { /* Looking to break right */ if (run_break_right) { return (TRUE); } } else { /* Obstacle */ /* Looking to break left */ if (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: square_ispassable(cave, row, col) */ if (!square_ismark(cave, row, col) || (square_ispassable(cave, row, col))) { /* Looking to break left */ if (run_break_left) { return (TRUE); } } else { /* Obstacle */ /* Looking to break right */ if (run_break_right) { return (TRUE); } } } } else { /* Not looking for open area */ /* No options */ if (!option) { return (TRUE); } else if (!option2) { /* One option */ /* Primary option */ run_cur_dir = option; /* No other options */ run_old_dir = option; } else { /* Two options, examining corners */ /* Primary option */ run_cur_dir = option; /* Hack -- allow curving */ run_old_dir = option2; } } /* About to hit a known wall, stop */ if (see_wall(run_cur_dir, py, px)) return (TRUE); /* Failure */ return (FALSE); }
/** * Initialize the running algorithm for a new direction. * * Diagonal Corridor -- allow diaginal entry into corridors. * * Blunt Corridor -- If there is a wall two spaces ahead and * we seem to be in a corridor, then force a turn into the side * corridor, must be moving straight into a corridor here. (?) * * Diagonal Corridor Blunt Corridor (?) * # # # * #x# @x# * @p. p */ static void run_init(int dir) { int py = player->py; int px = player->px; int i, row, col; bool deepleft, deepright; bool shortleft, shortright; /* Mark that we're starting a run */ player->upkeep->running_firststep = TRUE; /* Save the direction */ run_cur_dir = dir; /* Assume running straight */ run_old_dir = dir; /* Assume looking for open area */ run_open_area = TRUE; /* Assume not looking for breaks */ run_break_right = FALSE; run_break_left = FALSE; /* Assume no nearby walls */ deepleft = deepright = FALSE; shortright = shortleft = FALSE; /* Find the destination grid */ row = py + ddy[dir]; col = px + ddx[dir]; /* Extract cycle index */ i = chome[dir]; /* Check for nearby or distant wall */ if (see_wall(cycle[i+1], py, px)) { run_break_left = TRUE; shortleft = TRUE; } else if (see_wall(cycle[i+1], row, col)) { run_break_left = TRUE; deepleft = TRUE; } /* Check for nearby or distant wall */ if (see_wall(cycle[i-1], py, px)) { run_break_right = TRUE; shortright = TRUE; } else if (see_wall(cycle[i-1], row, col)) { run_break_right = TRUE; deepright = TRUE; } /* Looking for a break */ if (run_break_left && run_break_right) { /* Not looking for open area */ run_open_area = FALSE; /* Angled or blunt corridor entry */ if (dir & 0x01) { if (deepleft && !deepright) run_old_dir = cycle[i - 1]; else if (deepright && !deepleft) run_old_dir = cycle[i + 1]; } else if (see_wall(cycle[i], row, col)) { if (shortleft && !shortright) run_old_dir = cycle[i - 2]; else if (shortright && !shortleft) run_old_dir = cycle[i + 2]; } } }
/* * 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 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; /* Look at every newly adjacent square. */ for (i = -max; i <= max; i++) { object_type *o_ptr; /* 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 = &mon_list[cave_m_idx[row][col]]; /* Visible monster */ if (m_ptr->ml) return (TRUE); } /* Visible objects abort running */ for (o_ptr = get_first_object(row, col); o_ptr; o_ptr = get_next_object(o_ptr)) { /* Visible object */ if (o_ptr->marked && !squelch_hide_item(o_ptr)) 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: /* Secret doors */ case FEAT_SECRET: /* Normal veins */ case FEAT_MAGMA: case FEAT_QUARTZ: /* Hidden treasure */ case FEAT_MAGMA_H: case FEAT_QUARTZ_H: /* 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; } } /* 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; } } } } /* Look at every soon to be newly adjacent square. */ for (i = -max; i <= max; i++) { /* New direction */ new_dir = cycle[chome[prev_dir] + i]; /* New location */ row = py + ddy[prev_dir] + ddy[new_dir]; col = px + ddx[prev_dir] + ddx[new_dir]; /* HACK: Ugh. Sometimes we come up with illegal bounds. This will * treat the symptom but not the disease. */ if (row >= DUNGEON_HGT || col >= DUNGEON_WID) continue; if (row < 0 || col < 0) continue; /* Visible monsters abort running */ if (cave_m_idx[row][col] > 0) { monster_type *m_ptr = &mon_list[cave_m_idx[row][col]]; /* Visible monster */ if (m_ptr->ml) return (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)) { /* 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)) { /* 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 { /* Primary option */ p_ptr->run_cur_dir = option; /* Hack -- allow curving */ 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); }
/* * Initialize the running algorithm for a new direction. * * Diagonal Corridor -- allow diaginal entry into corridors. * * Blunt Corridor -- If there is a wall two spaces ahead and * we seem to be in a corridor, then force a turn into the side * corridor, must be moving straight into a corridor here. ??? * * Diagonal Corridor Blunt Corridor (?) * # # # * #x# @x# * @p. p */ static void mon_run_init(int dir) { int fy = m_ptr->fy; int fx = m_ptr->fx; int i, row, col; bool deepleft, deepright; bool shortleft, shortright; /* Save the direction */ m_ptr->run_cur_dir = dir; /* Assume running straight */ m_ptr->run_old_dir = dir; /* Assume looking for open area */ m_ptr->mflag |= MFLAG_RUN_OPEN_AREA; /* Assume not looking for breaks */ m_ptr->mflag &= ~(MFLAG_RUN_BREAK_RIGHT); m_ptr->mflag &= ~(MFLAG_RUN_BREAK_LEFT); /* Assume no nearby walls */ deepleft = deepright = FALSE; shortright = shortleft = FALSE; /* Find the destination grid */ row = fy + ddy[dir]; col = fx + ddx[dir]; /* Extract cycle index */ i = chome[dir]; /* Check for nearby wall */ if (see_wall(cycle[i+1], fy, fx)) { m_ptr->mflag |= MFLAG_RUN_BREAK_LEFT; shortleft = TRUE; } /* Check for distant wall */ else if (see_wall(cycle[i+1], row, col)) { m_ptr->mflag |= MFLAG_RUN_BREAK_LEFT; deepleft = TRUE; } /* Check for nearby wall */ if (see_wall(cycle[i-1], fy, fx)) { m_ptr->mflag |= MFLAG_RUN_BREAK_RIGHT; shortright = TRUE; } /* Check for distant wall */ else if (see_wall(cycle[i-1], row, col)) { m_ptr->mflag |= MFLAG_RUN_BREAK_RIGHT; deepright = TRUE; } /* Looking for a break */ if ((m_ptr->mflag & (MFLAG_RUN_BREAK_LEFT)) && (m_ptr->mflag & (MFLAG_RUN_BREAK_RIGHT))) { /* Not looking for open area */ m_ptr->mflag &= ~(MFLAG_RUN_OPEN_AREA); /* Hack -- allow angled corridor entry */ if (dir & 0x01) { if (deepleft && !deepright) { m_ptr->run_old_dir = cycle[i - 1]; } else if (deepright && !deepleft) { m_ptr->run_old_dir = cycle[i + 1]; } } /* Hack -- allow blunt corridor entry */ else if (see_wall(cycle[i], row, col)) { if (shortleft && !shortright) { m_ptr->run_old_dir = cycle[i - 2]; } else if (shortright && !shortleft) { m_ptr->run_old_dir = cycle[i + 2]; } } } }