static void ottolook(int rel_dir, struct item *itemp) { int r, c; char ch; r = 0; itemp->what = 0; itemp->distance = -1; itemp->flags = DEADEND|BEEN; /* true until proven false */ switch (direction(facing, rel_dir)) { case NORTH: if (been_there[row - 1][col] & NORTH) itemp->flags |= BEEN_SAME; for (r = row - 1; r >= 0; r--) for (c = col - 1; c < col + 2; c++) { ch = SCREEN(r, c); if (stop_look(itemp, ch, row - r, c - col)) goto cont_north; if (c == col && !been_there[r][c]) itemp->flags &= ~BEEN; } cont_north: if (itemp->flags & DEADEND) { itemp->flags |= BEEN; if (r >= 0) been_there[r][col] |= NORTH; for (r = row - 1; r > row - itemp->distance; r--) been_there[r][col] = ALLDIRS; } break; case SOUTH: if (been_there[row + 1][col] & SOUTH) itemp->flags |= BEEN_SAME; for (r = row + 1; r < HEIGHT; r++) for (c = col - 1; c < col + 2; c++) { ch = SCREEN(r, c); if (stop_look(itemp, ch, r - row, col - c)) goto cont_south; if (c == col && !been_there[r][c]) itemp->flags &= ~BEEN; } cont_south: if (itemp->flags & DEADEND) { itemp->flags |= BEEN; if (r < HEIGHT) been_there[r][col] |= SOUTH; for (r = row + 1; r < row + itemp->distance; r++) been_there[r][col] = ALLDIRS; } break; case WEST: if (been_there[row][col - 1] & WEST) itemp->flags |= BEEN_SAME; for (c = col - 1; c >= 0; c--) for (r = row - 1; r < row + 2; r++) { ch = SCREEN(r, c); if (stop_look(itemp, ch, col - c, row - r)) goto cont_west; if (r == row && !been_there[r][c]) itemp->flags &= ~BEEN; } cont_west: if (itemp->flags & DEADEND) { itemp->flags |= BEEN; been_there[r][col] |= WEST; for (c = col - 1; c > col - itemp->distance; c--) been_there[row][c] = ALLDIRS; } break; case EAST: if (been_there[row][col + 1] & EAST) itemp->flags |= BEEN_SAME; for (c = col + 1; c < WIDTH; c++) for (r = row - 1; r < row + 2; r++) { ch = SCREEN(r, c); if (stop_look(itemp, ch, c - col, r - row)) goto cont_east; if (r == row && !been_there[r][c]) itemp->flags &= ~BEEN; } cont_east: if (itemp->flags & DEADEND) { itemp->flags |= BEEN; been_there[r][col] |= EAST; for (c = col + 1; c < col + itemp->distance; c++) been_there[row][c] = ALLDIRS; } break; default: panic("unknown look"); } }
/** * Looks for an object in a given direction. * @param[in] rel_dir A direction. * @param[in,out] itemp An object. * [PSR] */ STATIC void ottolook(int rel_dir,struct item *itemp) { int r, c; char ch; bool exit; r = 0; itemp->what = 0; itemp->distance = -1; itemp->flags = DEADEND|BEEN; /* true until proven false */ switch (direction(facing, rel_dir)) { case NORTH: if (been_there[row - 1][col] & NORTH) { itemp->flags |= BEEN_SAME; } exit = false; for (r = row - 1; r >= 0 && !exit; r--) { for (c = col - 1; (c < col + 2) && !exit; c++) { ch = SCREEN(r, c); if (stop_look(itemp, ch, row - r, c - col)) { exit = true; } else { if (c == col && !been_there[r][c]) { itemp->flags &= ~BEEN; } } } } if (itemp->flags & DEADEND) { itemp->flags |= BEEN; been_there[r][col] |= NORTH; for (r = row - 1; r > row - itemp->distance; r--) { been_there[r][col] = ALLDIRS; } } break; case SOUTH: if (been_there[row + 1][col] & SOUTH) { itemp->flags |= BEEN_SAME; } exit=false; for (r = row + 1; r < HEIGHT && !exit; r++) { for (c = col - 1; (c < col + 2) && !exit; c++) { ch = SCREEN(r, c); if (stop_look(itemp, ch, r - row, col - c)) { exit=true; } else { if (c == col && !been_there[r][c]) { itemp->flags &= ~BEEN; } } } } if (itemp->flags & DEADEND) { itemp->flags |= BEEN; been_there[r][col] |= SOUTH; for (r = row + 1; r < row + itemp->distance; r++) { been_there[r][col] = ALLDIRS; } } break; case WEST: if (been_there[row][col - 1] & WEST) { itemp->flags |= BEEN_SAME; } exit=false; for (c = col - 1; c >= 0 && !exit; c--) { for (r = row - 1; r < (row + 2)&&!exit; r++) { ch = SCREEN(r, c); if (stop_look(itemp, ch, col - c, row - r)) { exit=true; } else { if (r == row && !been_there[r][c]) { itemp->flags &= ~BEEN; } } } } if (itemp->flags & DEADEND) { itemp->flags |= BEEN; been_there[r][col] |= WEST; for (c = col - 1; c > col - itemp->distance; c--) { been_there[row][c] = ALLDIRS; } } break; case EAST: if (been_there[row][col + 1] & EAST) { itemp->flags |= BEEN_SAME; } exit=false; for (c = col + 1; c < WIDTH && !exit; c++) { for (r = row - 1; r < (row + 2) && !exit; r++) { ch = SCREEN(r, c); if (stop_look(itemp, ch, c - col, r - row)) { exit=true; } else { if (r == row && !been_there[r][c]) { itemp->flags &= ~BEEN; } } } } if (itemp->flags & DEADEND) { itemp->flags |= BEEN; been_there[r][col] |= EAST; for (c = col + 1; c < col + itemp->distance; c++) { been_there[row][c] = ALLDIRS; } } break; default: abort(); } }