1 #include "monster-floor/monster-lite.h"
2 #include "core/player-update-types.h"
3 #include "dungeon/dungeon-flag-types.h"
4 #include "dungeon/dungeon.h"
5 #include "floor/cave.h"
6 #include "grid/feature-flag-types.h"
8 #include "monster-floor/monster-lite-util.h"
9 #include "monster-race/monster-race.h"
10 #include "monster-race/race-flags7.h"
11 #include "monster/monster-status.h"
12 #include "player/special-defense-types.h"
13 #include "system/floor-type-definition.h"
14 #include "system/monster-type-definition.h"
15 #include "view/display-messages.h"
16 #include "world/world.h"
19 * @brief モンスターによる光量状態更新 / Add a square to the changes array
20 * @param subject_ptr 主観となるクリーチャーの参照ポインタ
24 static void update_monster_lite(player_type *subject_ptr, const POSITION y, const POSITION x, monster_lite_type *ml_ptr)
29 g_ptr = &subject_ptr->current_floor_ptr->grid_array[y][x];
30 if ((g_ptr->info & (CAVE_MNLT | CAVE_VIEW)) != CAVE_VIEW)
33 if (!cave_los_grid(g_ptr)) {
34 if (((y < subject_ptr->y) && (y > ml_ptr->mon_fy)) || ((y > subject_ptr->y) && (y < ml_ptr->mon_fy))) {
35 dpf = subject_ptr->y - ml_ptr->mon_fy;
36 d = y - ml_ptr->mon_fy;
37 midpoint = ml_ptr->mon_fx + ((subject_ptr->x - ml_ptr->mon_fx) * ABS(d)) / ABS(dpf);
39 if (!cave_los_bold(subject_ptr->current_floor_ptr, y, x + 1))
41 } else if (x > midpoint) {
42 if (!cave_los_bold(subject_ptr->current_floor_ptr, y, x - 1))
44 } else if (ml_ptr->mon_invis)
48 if (((x < subject_ptr->x) && (x > ml_ptr->mon_fx)) || ((x > subject_ptr->x) && (x < ml_ptr->mon_fx))) {
49 dpf = subject_ptr->x - ml_ptr->mon_fx;
50 d = x - ml_ptr->mon_fx;
51 midpoint = ml_ptr->mon_fy + ((subject_ptr->y - ml_ptr->mon_fy) * ABS(d)) / ABS(dpf);
53 if (!cave_los_bold(subject_ptr->current_floor_ptr, y + 1, x))
55 } else if (y > midpoint) {
56 if (!cave_los_bold(subject_ptr->current_floor_ptr, y - 1, x))
58 } else if (ml_ptr->mon_invis)
63 if (!(g_ptr->info & CAVE_MNDK)) {
64 tmp_pos.x[tmp_pos.n] = x;
65 tmp_pos.y[tmp_pos.n] = y;
68 g_ptr->info &= ~(CAVE_MNDK);
71 g_ptr->info |= CAVE_MNLT;
75 * Add a square to the changes array
77 static void update_monster_dark(player_type *subject_ptr, const POSITION y, const POSITION x, monster_lite_type *ml_ptr)
81 g_ptr = &subject_ptr->current_floor_ptr->grid_array[y][x];
82 if ((g_ptr->info & (CAVE_LITE | CAVE_MNLT | CAVE_MNDK | CAVE_VIEW)) != CAVE_VIEW)
85 if (!cave_los_grid(g_ptr) && !cave_has_flag_grid(g_ptr, FF_PROJECT)) {
86 if (((y < subject_ptr->y) && (y > ml_ptr->mon_fy)) || ((y > subject_ptr->y) && (y < ml_ptr->mon_fy))) {
87 dpf = subject_ptr->y - ml_ptr->mon_fy;
88 d = y - ml_ptr->mon_fy;
89 midpoint = ml_ptr->mon_fx + ((subject_ptr->x - ml_ptr->mon_fx) * ABS(d)) / ABS(dpf);
91 if (!cave_los_bold(subject_ptr->current_floor_ptr, y, x + 1) && !cave_has_flag_bold(subject_ptr->current_floor_ptr, y, x + 1, FF_PROJECT))
93 } else if (x > midpoint) {
94 if (!cave_los_bold(subject_ptr->current_floor_ptr, y, x - 1) && !cave_has_flag_bold(subject_ptr->current_floor_ptr, y, x - 1, FF_PROJECT))
96 } else if (ml_ptr->mon_invis)
100 if (((x < subject_ptr->x) && (x > ml_ptr->mon_fx)) || ((x > subject_ptr->x) && (x < ml_ptr->mon_fx))) {
101 dpf = subject_ptr->x - ml_ptr->mon_fx;
102 d = x - ml_ptr->mon_fx;
103 midpoint = ml_ptr->mon_fy + ((subject_ptr->y - ml_ptr->mon_fy) * ABS(d)) / ABS(dpf);
105 if (!cave_los_bold(subject_ptr->current_floor_ptr, y + 1, x) && !cave_has_flag_bold(subject_ptr->current_floor_ptr, y + 1, x, FF_PROJECT))
107 } else if (y > midpoint) {
108 if (!cave_los_bold(subject_ptr->current_floor_ptr, y - 1, x) && !cave_has_flag_bold(subject_ptr->current_floor_ptr, y - 1, x, FF_PROJECT))
110 } else if (ml_ptr->mon_invis)
115 tmp_pos.x[tmp_pos.n] = x;
116 tmp_pos.y[tmp_pos.n] = y;
118 g_ptr->info |= CAVE_MNDK;
122 * todo player-status からのみ呼ばれている。しかしあちらは行数が酷いので要調整
123 * Update squares illuminated or darkened by monsters.
124 * The CAVE_TEMP and CAVE_XTRA flag are used to store the state during the
125 * updating. Only squares in view of the player, whos state
126 * changes are drawn via lite_spot().
128 void update_mon_lite(player_type *subject_ptr)
130 void (*add_mon_lite)(player_type *, const POSITION, const POSITION, monster_lite_type *);
131 int dis_lim = ((d_info[subject_ptr->dungeon_idx].flags1 & DF1_DARKNESS) && !subject_ptr->see_nocto) ? (MAX_SIGHT / 2 + 1) : (MAX_SIGHT + 3);
132 floor_type *floor_ptr = subject_ptr->current_floor_ptr;
133 for (int i = 0; i < floor_ptr->mon_lite_n; i++) {
135 g_ptr = &floor_ptr->grid_array[floor_ptr->mon_lite_y[i]][floor_ptr->mon_lite_x[i]];
136 g_ptr->info |= (g_ptr->info & CAVE_MNLT) ? CAVE_TEMP : CAVE_XTRA;
137 g_ptr->info &= ~(CAVE_MNLT | CAVE_MNDK);
141 if (!current_world_ptr->timewalk_m_idx) {
144 for (int i = 1; i < floor_ptr->m_max; i++) {
145 m_ptr = &floor_ptr->m_list[i];
146 r_ptr = &r_info[m_ptr->r_idx];
147 if (!monster_is_valid(m_ptr) || (m_ptr->cdis > dis_lim))
151 if (r_ptr->flags7 & (RF7_HAS_LITE_1 | RF7_SELF_LITE_1))
154 if (r_ptr->flags7 & (RF7_HAS_LITE_2 | RF7_SELF_LITE_2))
157 if (r_ptr->flags7 & (RF7_HAS_DARK_1 | RF7_SELF_DARK_1))
160 if (r_ptr->flags7 & (RF7_HAS_DARK_2 | RF7_SELF_DARK_2))
168 if (!(r_ptr->flags7 & (RF7_SELF_LITE_1 | RF7_SELF_LITE_2))
169 && (monster_csleep_remaining(m_ptr) || (!floor_ptr->dun_level && is_daytime()) || subject_ptr->phase_out))
172 if (d_info[subject_ptr->dungeon_idx].flags1 & DF1_DARKNESS)
175 add_mon_lite = update_monster_lite;
178 if (!(r_ptr->flags7 & (RF7_SELF_DARK_1 | RF7_SELF_DARK_2)) && (monster_csleep_remaining(m_ptr) || (!floor_ptr->dun_level && !is_daytime())))
181 add_mon_lite = update_monster_dark;
186 monster_lite_type tmp_ml;
187 monster_lite_type *ml_ptr = initialize_monster_lite_type(floor_ptr, &tmp_ml, m_ptr);
188 add_mon_lite(subject_ptr, ml_ptr->mon_fy, ml_ptr->mon_fx, ml_ptr);
189 add_mon_lite(subject_ptr, ml_ptr->mon_fy + 1, ml_ptr->mon_fx, ml_ptr);
190 add_mon_lite(subject_ptr, ml_ptr->mon_fy - 1, ml_ptr->mon_fx, ml_ptr);
191 add_mon_lite(subject_ptr, ml_ptr->mon_fy, ml_ptr->mon_fx + 1, ml_ptr);
192 add_mon_lite(subject_ptr, ml_ptr->mon_fy, ml_ptr->mon_fx - 1, ml_ptr);
193 add_mon_lite(subject_ptr, ml_ptr->mon_fy + 1, ml_ptr->mon_fx + 1, ml_ptr);
194 add_mon_lite(subject_ptr, ml_ptr->mon_fy + 1, ml_ptr->mon_fx - 1, ml_ptr);
195 add_mon_lite(subject_ptr, ml_ptr->mon_fy - 1, ml_ptr->mon_fx + 1, ml_ptr);
196 add_mon_lite(subject_ptr, ml_ptr->mon_fy - 1, ml_ptr->mon_fx - 1, ml_ptr);
201 if (cave_has_flag_bold(subject_ptr->current_floor_ptr, ml_ptr->mon_fy + 1, ml_ptr->mon_fx, f_flag)) {
202 add_mon_lite(subject_ptr, ml_ptr->mon_fy + 2, ml_ptr->mon_fx + 1, ml_ptr);
203 add_mon_lite(subject_ptr, ml_ptr->mon_fy + 2, ml_ptr->mon_fx, ml_ptr);
204 add_mon_lite(subject_ptr, ml_ptr->mon_fy + 2, ml_ptr->mon_fx - 1, ml_ptr);
205 g_ptr = &floor_ptr->grid_array[ml_ptr->mon_fy + 2][ml_ptr->mon_fx];
206 if ((rad == 3) && cave_has_flag_grid(g_ptr, f_flag)) {
207 add_mon_lite(subject_ptr, ml_ptr->mon_fy + 3, ml_ptr->mon_fx + 1, ml_ptr);
208 add_mon_lite(subject_ptr, ml_ptr->mon_fy + 3, ml_ptr->mon_fx, ml_ptr);
209 add_mon_lite(subject_ptr, ml_ptr->mon_fy + 3, ml_ptr->mon_fx - 1, ml_ptr);
213 if (cave_has_flag_bold(subject_ptr->current_floor_ptr, ml_ptr->mon_fy - 1, ml_ptr->mon_fx, f_flag)) {
214 add_mon_lite(subject_ptr, ml_ptr->mon_fy - 2, ml_ptr->mon_fx + 1, ml_ptr);
215 add_mon_lite(subject_ptr, ml_ptr->mon_fy - 2, ml_ptr->mon_fx, ml_ptr);
216 add_mon_lite(subject_ptr, ml_ptr->mon_fy - 2, ml_ptr->mon_fx - 1, ml_ptr);
217 g_ptr = &floor_ptr->grid_array[ml_ptr->mon_fy - 2][ml_ptr->mon_fx];
218 if ((rad == 3) && cave_has_flag_grid(g_ptr, f_flag)) {
219 add_mon_lite(subject_ptr, ml_ptr->mon_fy - 3, ml_ptr->mon_fx + 1, ml_ptr);
220 add_mon_lite(subject_ptr, ml_ptr->mon_fy - 3, ml_ptr->mon_fx, ml_ptr);
221 add_mon_lite(subject_ptr, ml_ptr->mon_fy - 3, ml_ptr->mon_fx - 1, ml_ptr);
225 if (cave_has_flag_bold(subject_ptr->current_floor_ptr, ml_ptr->mon_fy, ml_ptr->mon_fx + 1, f_flag)) {
226 add_mon_lite(subject_ptr, ml_ptr->mon_fy + 1, ml_ptr->mon_fx + 2, ml_ptr);
227 add_mon_lite(subject_ptr, ml_ptr->mon_fy, ml_ptr->mon_fx + 2, ml_ptr);
228 add_mon_lite(subject_ptr, ml_ptr->mon_fy - 1, ml_ptr->mon_fx + 2, ml_ptr);
229 g_ptr = &floor_ptr->grid_array[ml_ptr->mon_fy][ml_ptr->mon_fx + 2];
230 if ((rad == 3) && cave_has_flag_grid(g_ptr, f_flag)) {
231 add_mon_lite(subject_ptr, ml_ptr->mon_fy + 1, ml_ptr->mon_fx + 3, ml_ptr);
232 add_mon_lite(subject_ptr, ml_ptr->mon_fy, ml_ptr->mon_fx + 3, ml_ptr);
233 add_mon_lite(subject_ptr, ml_ptr->mon_fy - 1, ml_ptr->mon_fx + 3, ml_ptr);
237 if (cave_has_flag_bold(subject_ptr->current_floor_ptr, ml_ptr->mon_fy, ml_ptr->mon_fx - 1, f_flag)) {
238 add_mon_lite(subject_ptr, ml_ptr->mon_fy + 1, ml_ptr->mon_fx - 2, ml_ptr);
239 add_mon_lite(subject_ptr, ml_ptr->mon_fy, ml_ptr->mon_fx - 2, ml_ptr);
240 add_mon_lite(subject_ptr, ml_ptr->mon_fy - 1, ml_ptr->mon_fx - 2, ml_ptr);
241 g_ptr = &floor_ptr->grid_array[ml_ptr->mon_fy][ml_ptr->mon_fx - 2];
242 if ((rad == 3) && cave_has_flag_grid(g_ptr, f_flag)) {
243 add_mon_lite(subject_ptr, ml_ptr->mon_fy + 1, ml_ptr->mon_fx - 3, ml_ptr);
244 add_mon_lite(subject_ptr, ml_ptr->mon_fy, ml_ptr->mon_fx - 3, ml_ptr);
245 add_mon_lite(subject_ptr, ml_ptr->mon_fy - 1, ml_ptr->mon_fx - 3, ml_ptr);
252 if (cave_has_flag_bold(subject_ptr->current_floor_ptr, ml_ptr->mon_fy + 1, ml_ptr->mon_fx + 1, f_flag))
253 add_mon_lite(subject_ptr, ml_ptr->mon_fy + 2, ml_ptr->mon_fx + 2, ml_ptr);
255 if (cave_has_flag_bold(subject_ptr->current_floor_ptr, ml_ptr->mon_fy + 1, ml_ptr->mon_fx - 1, f_flag))
256 add_mon_lite(subject_ptr, ml_ptr->mon_fy + 2, ml_ptr->mon_fx - 2, ml_ptr);
258 if (cave_has_flag_bold(subject_ptr->current_floor_ptr, ml_ptr->mon_fy - 1, ml_ptr->mon_fx + 1, f_flag))
259 add_mon_lite(subject_ptr, ml_ptr->mon_fy - 2, ml_ptr->mon_fx + 2, ml_ptr);
261 if (cave_has_flag_bold(subject_ptr->current_floor_ptr, ml_ptr->mon_fy - 1, ml_ptr->mon_fx - 1, f_flag))
262 add_mon_lite(subject_ptr, ml_ptr->mon_fy - 2, ml_ptr->mon_fx - 2, ml_ptr);
266 s16b end_temp = tmp_pos.n;
267 for (int i = 0; i < floor_ptr->mon_lite_n; i++) {
268 POSITION fx = floor_ptr->mon_lite_x[i];
269 POSITION fy = floor_ptr->mon_lite_y[i];
271 g_ptr = &floor_ptr->grid_array[fy][fx];
272 if (g_ptr->info & CAVE_TEMP) {
273 if ((g_ptr->info & (CAVE_VIEW | CAVE_MNLT)) == CAVE_VIEW)
274 cave_note_and_redraw_later(floor_ptr, g_ptr, fy, fx);
275 } else if ((g_ptr->info & (CAVE_VIEW | CAVE_MNDK)) == CAVE_VIEW)
276 cave_note_and_redraw_later(floor_ptr, g_ptr, fy, fx);
278 tmp_pos.x[tmp_pos.n] = fx;
279 tmp_pos.y[tmp_pos.n] = fy;
283 floor_ptr->mon_lite_n = 0;
284 for (int i = 0; i < end_temp; i++) {
285 POSITION fx = tmp_pos.x[i];
286 POSITION fy = tmp_pos.y[i];
288 g_ptr = &floor_ptr->grid_array[fy][fx];
289 if (g_ptr->info & CAVE_MNLT) {
290 if ((g_ptr->info & (CAVE_VIEW | CAVE_TEMP)) == CAVE_VIEW)
291 cave_note_and_redraw_later(floor_ptr, g_ptr, fy, fx);
292 } else if ((g_ptr->info & (CAVE_VIEW | CAVE_XTRA)) == CAVE_VIEW)
293 cave_note_and_redraw_later(floor_ptr, g_ptr, fy, fx);
295 floor_ptr->mon_lite_x[floor_ptr->mon_lite_n] = fx;
296 floor_ptr->mon_lite_y[floor_ptr->mon_lite_n] = fy;
297 floor_ptr->mon_lite_n++;
300 for (int i = end_temp; i < tmp_pos.n; i++)
301 floor_ptr->grid_array[tmp_pos.y[i]][tmp_pos.x[i]].info &= ~(CAVE_TEMP | CAVE_XTRA);
304 subject_ptr->update |= PU_DELAY_VIS;
305 subject_ptr->monlite = (floor_ptr->grid_array[subject_ptr->y][subject_ptr->x].info & CAVE_MNLT) != 0;
306 if (!(subject_ptr->special_defense & NINJA_S_STEALTH)) {
307 subject_ptr->old_monlite = subject_ptr->monlite;
311 if (subject_ptr->old_monlite == subject_ptr->monlite) {
312 subject_ptr->old_monlite = subject_ptr->monlite;
316 if (subject_ptr->monlite)
317 msg_print(_("影の覆いが薄れた気がする。", "Your mantle of shadow becomes thin."));
319 msg_print(_("影の覆いが濃くなった!", "Your mantle of shadow is restored to its original darkness."));
321 subject_ptr->old_monlite = subject_ptr->monlite;
325 * @brief 画面切り替え等でモンスターの灯りを消去する
326 * @param floor_ptr 現在フロアへの参照ポインタ
329 void clear_mon_lite(floor_type *floor_ptr)
331 for (int i = 0; i < floor_ptr->mon_lite_n; i++) {
333 g_ptr = &floor_ptr->grid_array[floor_ptr->mon_lite_y[i]][floor_ptr->mon_lite_x[i]];
334 g_ptr->info &= ~(CAVE_MNLT | CAVE_MNDK);
337 floor_ptr->mon_lite_n = 0;