/* * Mark the nearby area with CAVE_TEMP flags. Allow limited range. */ void spread_project_grid_mark(int y1, int x1, int range, bool room, bool pass_walls) { int i, y, x; /* Add the initial grid */ project_grid_mark(y1, x1, room); /* While grids are in the queue, add their neighbors */ for (i = 0; i < project_grids.size(); i++) { x = project_grids[i].x, y = project_grids[i].y; /* Walls get marked, but stop further spread, unless pass_walls is TRUE */ if (!pass_walls && !cave_project_bold(y, x)) continue; /* Note limited range (note: we spread out one grid further) */ if ((range) && (distance(y1, x1, y, x) >= range)) continue; /* Spread adjacent */ project_grid_mark(y + 1, x, room); project_grid_mark(y - 1, x, room); project_grid_mark(y, x + 1, room); project_grid_mark(y, x - 1, room); /* Spread diagonal */ project_grid_mark(y + 1, x + 1, room); project_grid_mark(y - 1, x - 1, room); project_grid_mark(y - 1, x + 1, room); project_grid_mark(y + 1, x - 1, room); } }
/* * Determine is a monster makes a reasonable target * * The concept of "targetting" was stolen from "Morgul" (?) * * The player can target any location, or any "target-able" monster. * * Currently, a monster is "target_able" if it is visible, and if * the player can hit it with a projection, and the player is not * hallucinating. This allows use of "use closest target" macros. * * Future versions may restrict the ability to target "trappers" * and "mimics", but the semantics is a little bit weird. */ bool target_able(int m_idx) { monster_type *m_ptr; /* No monster */ if (m_idx <= 0) return (FALSE); /* Get monster */ m_ptr = &mon_list[m_idx]; /* Monster must be alive */ if (!m_ptr->r_idx) return (FALSE); /* Monster must be visible */ if (!m_ptr->ml) return (FALSE); /*monster is an undiscovered mimic*/ if (m_ptr->mimic_k_idx) return (FALSE); /* Monster must be projectable */ if (!m_ptr->project) return (FALSE); /* Walls protect monsters */ if (!cave_project_bold(m_ptr->fy, m_ptr->fx) && !cave_passable_bold(m_ptr->fy, m_ptr->fx)) return (FALSE); /* Hack -- no targeting hallucinations */ if (p_ptr->timed[TMD_IMAGE]) return (FALSE); /* Hack -- Never target trappers XXX XXX XXX */ /* if (CLEAR_ATTR && (CLEAR_CHAR)) return (FALSE); */ /* Hidden monsters cannot be targets */ if (m_ptr->mflag & (MFLAG_HIDE)) return (FALSE); /* Assume okay */ return (TRUE); }
/* * Draw a visible path over the squares between (x1,y1) and (x2,y2). * The path consists of "*", which are white except where there is a * monster, object or feature in the grid. * * This routine has (at least) three weaknesses: * - remembered objects/walls which are no longer present are not shown, * - squares which (e.g.) the player has walked through in the dark are * treated as unknown space. * - walls which appear strange due to hallucination aren't treated correctly. * * The first two result from information being lost from the dungeon arrays, * which requires changes elsewhere */ static int draw_path(u16b path_n, u16b *path_g, char *c, byte *a, int y1, int x1, int cur_tar_y, int cur_tar_x) { int i; bool on_screen; byte color_type; /* No path, so do nothing. */ if (path_n < 1) return (FALSE); /* The starting square is never drawn, but notice if it is being * displayed. In theory, it could be the last such square. */ on_screen = panel_contains(y1, x1); /* Draw the path. */ for (i = 0; i < path_n; i++) { /* Find the co-ordinates on the level. */ int y = GRID_Y(path_g[i]); int x = GRID_X(path_g[i]); byte this_a; char this_c; /* * As path[] is a straight line and the screen is oblong, * there is only section of path[] on-screen. * If the square being drawn is visible, this is part of it. * If none of it has been drawn, continue until some of it * is found or the last square is reached. * If some of it has been drawn, finish now as there are no * more visible squares to draw. * */ if (panel_contains(y,x)) on_screen = TRUE; else if (on_screen) break; else continue; /* Find the position on-screen */ move_cursor_relative(y,x); /* This square is being overwritten, so save the original. */ Term_what(Term->scr->cx, Term->scr->cy, a+i, c+i); /* Choose a colour. */ /* Visible monsters are orange. */ if (cave_m_idx[y][x] && mon_list[cave_m_idx[y][x]].ml) { monster_type *m_ptr = &mon_list[cave_m_idx[y][x]]; /*mimics act as objects*/ if (m_ptr->mimic_k_idx) color_type = TERM_YELLOW; else color_type = TERM_ORANGE; } /* Known objects are yellow. */ else if (cave_o_idx[y][x] && o_list[cave_o_idx[y][x]].marked) { color_type = TERM_YELLOW; } /* Effects are green */ else if ((cave_x_idx[y][x] > 0) && (cave_info[y][x] & (CAVE_SEEN | CAVE_MARK))) { color_type = TERM_GREEN; } /* Known walls are blue. */ else if (!cave_project_bold(y,x) && ((cave_info[y][x] & (CAVE_MARK)) || player_can_see_bold(y,x))) { color_type = TERM_BLUE; } /* Unknown squares are grey. */ else if (!(cave_info[y][x] & (CAVE_MARK)) && !player_can_see_bold(y,x)) { color_type = TERM_L_DARK; } /* Unoccupied squares are white. */ else { color_type = TERM_WHITE; } /* ALways use red for the current target square */ if ((cur_tar_y == y) && (cur_tar_x == x)) color_type = TERM_RED; /* Get the character */ if (!use_graphics) { this_a = color_type; this_c = '*'; } /* Graphics are being used */ else { this_a = color_to_attr[TILE_BALL_INFO][color_type]; this_c = color_to_char[TILE_BALL_INFO][color_type]; } /* Visual effects -- Display */ print_rel(this_c, this_a, y, x); } return i; }