7 * キーパッドの方向を南から反時計回り順に列挙 / Global array for looping through the "keypad directions"
9 const POSITION ddd[9] =
10 { 2, 8, 6, 4, 3, 1, 9, 7, 5 };
13 * dddで定義した順にベクトルのX軸成分を定義 / Global arrays for converting "keypad direction" into offsets
15 const POSITION ddx[10] =
16 { 0, -1, 0, 1, -1, 0, 1, -1, 0, 1 };
19 * dddで定義した順にベクトルのY軸成分を定義 / Global arrays for converting "keypad direction" into offsets
21 const POSITION ddy[10] =
22 { 0, 1, 1, 1, 0, 0, 0, -1, -1, -1 };
25 * ddd越しにベクトルのX軸成分を定義 / Global arrays for optimizing "ddx[ddd[i]]" and "ddy[ddd[i]]"
27 const POSITION ddx_ddd[9] =
28 { 0, 0, 1, -1, 1, -1, 1, -1, 0 };
31 * ddd越しにベクトルのY軸成分を定義 / Global arrays for optimizing "ddx[ddd[i]]" and "ddy[ddd[i]]"
33 const POSITION ddy_ddd[9] =
34 { 1, -1, 0, 0, 1, 1, -1, -1, 0 };
38 * キーパッドの円環状方向配列 / Circular keypad direction array
40 const POSITION cdd[8] =
41 { 2, 3, 6, 9, 8, 7, 4, 1 };
44 * cdd越しにベクトルのX軸成分を定義 / Global arrays for optimizing "ddx[cdd[i]]" and "ddy[cdd[i]]"
46 const POSITION ddx_cdd[8] =
47 { 0, 1, 1, 1, 0, -1, -1, -1 };
50 * cdd越しにベクトルのY軸成分を定義 / Global arrays for optimizing "ddx[cdd[i]]" and "ddy[cdd[i]]"
52 const POSITION ddy_cdd[8] =
53 { 1, 1, 0, -1, -1, -1, 0, 1 };
57 * @brief 2点間の距離をニュートン・ラプソン法で算出する / Distance between two points via Newton-Raphson technique
64 POSITION distance(POSITION y1, POSITION x1, POSITION y2, POSITION x2)
66 POSITION dy = (y1 > y2) ? (y1 - y2) : (y2 - y1);
67 POSITION dx = (x1 > x2) ? (x1 - x2) : (x2 - x1);
69 /* Squared distance */
70 POSITION target = (dy * dy) + (dx * dx);
72 /* Approximate distance: hypot(dy,dx) = max(dy,dx) + min(dy,dx) / 2 */
73 POSITION d = (dy > dx) ? (dy + (dx >> 1)) : (dx + (dy >> 1));
78 if (!dy || !dx) return d;
82 /* Approximate error */
83 err = (target - d * d) / (2 * d);
85 /* No error - we are done */
96 * @brief プレイヤーから指定の座標がどの方角にあるかを返す /
97 * Convert an adjacent location to a direction.
102 DIRECTION coords_to_dir(player_type *creature_ptr, POSITION y, POSITION x)
104 DIRECTION d[3][3] = { {7, 4, 1}, {8, 5, 2}, {9, 6, 3} };
107 dy = y - creature_ptr->y;
108 dx = x - creature_ptr->x;
109 if (ABS(dx) > 1 || ABS(dy) > 1) return 0;
111 return d[dx + 1][dy + 1];
117 * @brief 指定された座標をプレイヤーが視覚に収められるかを返す。 / Can the player "see" the given grid in detail?
120 * @return 視覚に収められる状態ならTRUEを返す
122 * He must have vision, illumination, and line of sight.\n
124 * Note -- "CAVE_LITE" is only set if the "torch" has "los()".\n
125 * So, given "CAVE_LITE", we know that the grid is "fully visible".\n
127 * Note that "CAVE_GLOW" makes little sense for a wall, since it would mean\n
128 * that a wall is visible from any direction. That would be odd. Except\n
129 * under wizard light, which might make sense. Thus, for walls, we require\n
130 * not only that they be "CAVE_GLOW", but also, that they be adjacent to a\n
131 * grid which is not only "CAVE_GLOW", but which is a non-wall, and which is\n
132 * in line of sight of the player.\n
134 * This extra check is expensive, but it provides a more "correct" semantics.\n
136 * Note that we should not run this check on walls which are "outer walls" of\n
137 * the dungeon, or we will induce a memory fault, but actually verifying all\n
138 * of the locations would be extremely expensive.\n
140 * Thus, to speed up the function, we assume that all "perma-walls" which are\n
141 * "CAVE_GLOW" are "illuminated" from all sides. This is correct for all cases\n
142 * except "vaults" and the "buildings" in town. But the town is a hack anyway,\n
143 * and the player has more important things on his mind when he is attacking a\n
144 * monster vault. It is annoying, but an extremely important optimization.\n
146 * Note that "glowing walls" are only considered to be "illuminated" if the\n
147 * grid which is next to the wall in the direction of the player is also a\n
148 * "glowing" grid. This prevents the player from being able to "see" the\n
149 * walls of illuminated rooms from a corridor outside the room.\n
151 bool player_can_see_bold(player_type *creature_ptr, POSITION y, POSITION x)
155 /* Blind players see nothing */
156 if (creature_ptr->blind) return FALSE;
158 g_ptr = &creature_ptr->current_floor_ptr->grid_array[y][x];
160 /* Note that "torch-lite" yields "illumination" */
161 if (g_ptr->info & (CAVE_LITE | CAVE_MNLT)) return TRUE;
163 /* Require line of sight to the grid */
164 if (!player_has_los_bold(creature_ptr, y, x)) return FALSE;
166 /* Noctovision of Ninja */
167 if (creature_ptr->see_nocto) return TRUE;
169 /* Require "perma-lite" of the grid */
170 if ((g_ptr->info & (CAVE_GLOW | CAVE_MNDK)) != CAVE_GLOW) return FALSE;
172 /* Feature code (applying "mimic" field) */
173 /* Floors are simple */
174 if (feat_supports_los(get_feat_mimic(g_ptr))) return TRUE;
176 /* Check for "local" illumination */
177 return check_local_illumination(creature_ptr, y, x);
181 * Calculate "incremental motion". Used by project() and shoot().
182 * Assumes that (*y,*x) lies on the path from (y1,x1) to (y2,x2).
184 void mmove2(POSITION *y, POSITION *x, POSITION y1, POSITION x1, POSITION y2, POSITION x2)
186 POSITION dy, dx, dist, shift;
188 /* Extract the distance travelled */
189 dy = (*y < y1) ? y1 - *y : *y - y1;
190 dx = (*x < x1) ? x1 - *x : *x - x1;
192 /* Number of steps */
193 dist = (dy > dx) ? dy : dx;
195 /* We are calculating the next location */
199 /* Calculate the total distance along each axis */
200 dy = (y2 < y1) ? (y1 - y2) : (y2 - y1);
201 dx = (x2 < x1) ? (x1 - x2) : (x2 - x1);
203 /* Paranoia -- Hack -- no motion */
204 if (!dy && !dx) return;
207 /* Move mostly vertically */
210 /* Extract a shift factor */
211 shift = (dist * dx + (dy - 1) / 2) / dy;
213 /* Sometimes move along the minor axis */
214 (*x) = (x2 < x1) ? (x1 - shift) : (x1 + shift);
216 /* Always move along major axis */
217 (*y) = (y2 < y1) ? (y1 - dist) : (y1 + dist);
220 /* Move mostly horizontally */
223 /* Extract a shift factor */
224 shift = (dist * dy + (dx - 1) / 2) / dx;
226 /* Sometimes move along the minor axis */
227 (*y) = (y2 < y1) ? (y1 - shift) : (y1 + shift);
229 /* Always move along major axis */
230 (*x) = (x2 < x1) ? (x1 - dist) : (x1 + dist);