1 #include "target/projection-path-calculator.h"
2 #include "effect/effect-characteristics.h"
3 #include "floor/cave.h"
4 #include "grid/feature-flag-types.h"
6 #include "system/floor-type-definition.h"
8 typedef struct projection_path_type {
25 } projection_path_type;
28 * @brief Convert a "location" (Y, X) into a "grid" (G)
31 * return
\8co
\98H
\8dÀ
\95W
33 static u16b location_to_grid(POSITION y, POSITION x) { return 256 * y + x; }
35 static projection_path_type *initialize_projection_path_type(projection_path_type *pp_ptr, POSITION y1, POSITION x1, POSITION y2, POSITION x2)
44 static void set_asxy(projection_path_type *pp_ptr)
46 if (pp_ptr->y2 < pp_ptr->y1) {
47 pp_ptr->ay = pp_ptr->y1 - pp_ptr->y2;
50 pp_ptr->ay = pp_ptr->y2 - pp_ptr->y1;
54 if (pp_ptr->x2 < pp_ptr->x1) {
55 pp_ptr->ax = pp_ptr->x1 - pp_ptr->x2;
58 pp_ptr->ax = pp_ptr->x2 - pp_ptr->x1;
64 * @brief
\8en
\93_
\82©
\82ç
\8fI
\93_
\82Ö
\82Ì
\92¼
\90ü
\8co
\98H
\82ð
\95Ô
\82· /
65 * Determine the path taken by a projection.
66 * @param player_ptr
\83v
\83\8c\81[
\83\84\81[
\82Ö
\82Ì
\8eQ
\8fÆ
\83|
\83C
\83\93\83^
67 * @param gp
\8co
\98H
\8dÀ
\95W
\83\8a\83X
\83g
\82ð
\95Ô
\82·
\8eQ
\8fÆ
\83|
\83C
\83\93\83^
68 * @param range
\8b\97\97£
69 * @param y1
\8en
\93_Y
\8dÀ
\95W
70 * @param x1
\8en
\93_X
\8dÀ
\95W
71 * @param y2
\8fI
\93_Y
\8dÀ
\95W
72 * @param x2
\8fI
\93_X
\8dÀ
\95W
73 * @param flg
\83t
\83\89\83OID
74 * @return
\83\8a\83X
\83g
\82Ì
\92·
\82³
76 int projection_path(player_type *player_ptr, u16b *gp, POSITION range, POSITION y1, POSITION x1, POSITION y2, POSITION x2, BIT_FLAGS flg)
78 if ((x1 == x2) && (y1 == y2))
81 projection_path_type tmp_projection_path;
82 projection_path_type *pp_ptr = initialize_projection_path_type(&tmp_projection_path, y1, x1, y2, x2);
84 pp_ptr->half = pp_ptr->ay * pp_ptr->ax;
85 pp_ptr->full = pp_ptr->half << 1;
90 if (pp_ptr->ay > pp_ptr->ax) {
91 pp_ptr->m = pp_ptr->ax * pp_ptr->ax * 2;
92 pp_ptr->y = y1 + pp_ptr->sy;
94 pp_ptr->frac = pp_ptr->m;
95 if (pp_ptr->frac > pp_ptr->half) {
96 pp_ptr->x += pp_ptr->sx;
97 pp_ptr->frac -= pp_ptr->full;
101 floor_type *floor_ptr = player_ptr->current_floor_ptr;
103 gp[pp_ptr->n++] = location_to_grid(pp_ptr->y, pp_ptr->x);
104 if ((pp_ptr->n + (pp_ptr->k >> 1)) >= range)
107 if (!(flg & PROJECT_THRU)) {
108 if ((pp_ptr->x == x2) && (pp_ptr->y == y2))
112 if (flg & PROJECT_DISI) {
113 if ((pp_ptr->n > 0) && cave_stop_disintegration(floor_ptr, pp_ptr->y, pp_ptr->x))
115 } else if (flg & PROJECT_LOS) {
116 if ((pp_ptr->n > 0) && !cave_los_bold(floor_ptr, pp_ptr->y, pp_ptr->x))
118 } else if (!(flg & PROJECT_PATH)) {
119 if ((pp_ptr->n > 0) && !cave_have_flag_bold(floor_ptr, pp_ptr->y, pp_ptr->x, FF_PROJECT))
123 if (flg & PROJECT_STOP) {
124 if ((pp_ptr->n > 0) && (player_bold(player_ptr, pp_ptr->y, pp_ptr->x) || floor_ptr->grid_array[pp_ptr->y][pp_ptr->x].m_idx != 0))
128 if (!in_bounds(floor_ptr, pp_ptr->y, pp_ptr->x))
132 pp_ptr->frac += pp_ptr->m;
133 if (pp_ptr->frac > pp_ptr->half) {
134 pp_ptr->x += pp_ptr->sx;
135 pp_ptr->frac -= pp_ptr->full;
140 pp_ptr->y += pp_ptr->sy;
147 if (pp_ptr->ax > pp_ptr->ay) {
148 pp_ptr->m = pp_ptr->ay * pp_ptr->ay * 2;
150 pp_ptr->x = x1 + pp_ptr->sx;
151 pp_ptr->frac = pp_ptr->m;
152 if (pp_ptr->frac > pp_ptr->half) {
153 pp_ptr->y += pp_ptr->sy;
154 pp_ptr->frac -= pp_ptr->full;
158 floor_type *floor_ptr = player_ptr->current_floor_ptr;
160 gp[pp_ptr->n++] = location_to_grid(pp_ptr->y, pp_ptr->x);
161 if ((pp_ptr->n + (pp_ptr->k >> 1)) >= range)
164 if (!(flg & (PROJECT_THRU))) {
165 if ((pp_ptr->x == x2) && (pp_ptr->y == y2))
169 if (flg & (PROJECT_DISI)) {
170 if ((pp_ptr->n > 0) && cave_stop_disintegration(floor_ptr, pp_ptr->y, pp_ptr->x))
172 } else if (flg & (PROJECT_LOS)) {
173 if ((pp_ptr->n > 0) && !cave_los_bold(floor_ptr, pp_ptr->y, pp_ptr->x))
175 } else if (!(flg & (PROJECT_PATH))) {
176 if ((pp_ptr->n > 0) && !cave_have_flag_bold(floor_ptr, pp_ptr->y, pp_ptr->x, FF_PROJECT))
180 if (flg & (PROJECT_STOP)) {
181 if ((pp_ptr->n > 0) && (player_bold(player_ptr, pp_ptr->y, pp_ptr->x) || floor_ptr->grid_array[pp_ptr->y][pp_ptr->x].m_idx != 0))
185 if (!in_bounds(floor_ptr, pp_ptr->y, pp_ptr->x))
189 pp_ptr->frac += pp_ptr->m;
190 if (pp_ptr->frac > pp_ptr->half) {
191 pp_ptr->y += pp_ptr->sy;
192 pp_ptr->frac -= pp_ptr->full;
197 pp_ptr->x += pp_ptr->sx;
203 pp_ptr->y = y1 + pp_ptr->sy;
204 pp_ptr->x = x1 + pp_ptr->sx;
206 floor_type *floor_ptr = player_ptr->current_floor_ptr;
208 gp[pp_ptr->n++] = location_to_grid(pp_ptr->y, pp_ptr->x);
209 if ((pp_ptr->n + (pp_ptr->n >> 1)) >= range)
212 if (!(flg & PROJECT_THRU)) {
213 if ((pp_ptr->x == x2) && (pp_ptr->y == y2))
217 if (flg & PROJECT_DISI) {
218 if ((pp_ptr->n > 0) && cave_stop_disintegration(floor_ptr, pp_ptr->y, pp_ptr->x))
220 } else if (flg & PROJECT_LOS) {
221 if ((pp_ptr->n > 0) && !cave_los_bold(floor_ptr, pp_ptr->y, pp_ptr->x))
223 } else if (!(flg & PROJECT_PATH)) {
224 if ((pp_ptr->n > 0) && !cave_have_flag_bold(floor_ptr, pp_ptr->y, pp_ptr->x, FF_PROJECT))
228 if (flg & PROJECT_STOP) {
229 if ((pp_ptr->n > 0) && (player_bold(player_ptr, pp_ptr->y, pp_ptr->x) || floor_ptr->grid_array[pp_ptr->y][pp_ptr->x].m_idx != 0))
233 if (!in_bounds(floor_ptr, pp_ptr->y, pp_ptr->x))
236 pp_ptr->y += pp_ptr->sy;
237 pp_ptr->x += pp_ptr->sx;