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/grid-type-definition.h"
15 #include "system/monster-race-definition.h"
16 #include "system/monster-type-definition.h"
17 #include "system/player-type-definition.h"
18 #include "util/point-2d.h"
19 #include "view/display-messages.h"
20 #include "world/world.h"
24 * @brief モンスターによる光量状態更新 / Add a square to the changes array
25 * @param subject_ptr 主観となるクリーチャーの参照ポインタ
26 * @param points 座標たちを記録する配列
30 static void update_monster_lite(
31 player_type *const subject_ptr, std::vector<Pos2D> &points, const POSITION y, const POSITION x, const monster_lite_type *const ml_ptr)
36 g_ptr = &subject_ptr->current_floor_ptr->grid_array[y][x];
37 if ((g_ptr->info & (CAVE_MNLT | CAVE_VIEW)) != CAVE_VIEW)
40 if (!feat_supports_los(g_ptr->feat)) {
41 if (((y < subject_ptr->y) && (y > ml_ptr->mon_fy)) || ((y > subject_ptr->y) && (y < ml_ptr->mon_fy))) {
42 dpf = subject_ptr->y - ml_ptr->mon_fy;
43 d = y - ml_ptr->mon_fy;
44 midpoint = ml_ptr->mon_fx + ((subject_ptr->x - ml_ptr->mon_fx) * ABS(d)) / ABS(dpf);
46 if (!cave_los_bold(subject_ptr->current_floor_ptr, y, x + 1))
48 } else if (x > midpoint) {
49 if (!cave_los_bold(subject_ptr->current_floor_ptr, y, x - 1))
51 } else if (ml_ptr->mon_invis)
55 if (((x < subject_ptr->x) && (x > ml_ptr->mon_fx)) || ((x > subject_ptr->x) && (x < ml_ptr->mon_fx))) {
56 dpf = subject_ptr->x - ml_ptr->mon_fx;
57 d = x - ml_ptr->mon_fx;
58 midpoint = ml_ptr->mon_fy + ((subject_ptr->y - ml_ptr->mon_fy) * ABS(d)) / ABS(dpf);
60 if (!cave_los_bold(subject_ptr->current_floor_ptr, y + 1, x))
62 } else if (y > midpoint) {
63 if (!cave_los_bold(subject_ptr->current_floor_ptr, y - 1, x))
65 } else if (ml_ptr->mon_invis)
70 if (!(g_ptr->info & CAVE_MNDK)) {
71 points.emplace_back(y, x);
73 g_ptr->info &= ~(CAVE_MNDK);
76 g_ptr->info |= CAVE_MNLT;
80 * Add a square to the changes array
82 static void update_monster_dark(
83 player_type *const subject_ptr, std::vector<Pos2D> &points, const POSITION y, const POSITION x, const monster_lite_type *const ml_ptr)
87 g_ptr = &subject_ptr->current_floor_ptr->grid_array[y][x];
88 if ((g_ptr->info & (CAVE_LITE | CAVE_MNLT | CAVE_MNDK | CAVE_VIEW)) != CAVE_VIEW)
91 if (!feat_supports_los(g_ptr->feat) && !g_ptr->cave_has_flag(FF_PROJECT)) {
92 if (((y < subject_ptr->y) && (y > ml_ptr->mon_fy)) || ((y > subject_ptr->y) && (y < ml_ptr->mon_fy))) {
93 dpf = subject_ptr->y - ml_ptr->mon_fy;
94 d = y - ml_ptr->mon_fy;
95 midpoint = ml_ptr->mon_fx + ((subject_ptr->x - ml_ptr->mon_fx) * ABS(d)) / ABS(dpf);
97 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))
99 } else if (x > midpoint) {
100 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))
102 } else if (ml_ptr->mon_invis)
106 if (((x < subject_ptr->x) && (x > ml_ptr->mon_fx)) || ((x > subject_ptr->x) && (x < ml_ptr->mon_fx))) {
107 dpf = subject_ptr->x - ml_ptr->mon_fx;
108 d = x - ml_ptr->mon_fx;
109 midpoint = ml_ptr->mon_fy + ((subject_ptr->y - ml_ptr->mon_fy) * ABS(d)) / ABS(dpf);
111 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))
113 } else if (y > midpoint) {
114 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))
116 } else if (ml_ptr->mon_invis)
121 points.emplace_back(y, x);
122 g_ptr->info |= CAVE_MNDK;
126 * @brief Update squares illuminated or darkened by monsters.
127 * The CAVE_TEMP and CAVE_XTRA flag are used to store the state during the
128 * updating. Only squares in view of the player, whos state
129 * changes are drawn via lite_spot().
130 * @todo player-status からのみ呼ばれている。しかしあちらは行数が酷いので要調整
132 void update_mon_lite(player_type *subject_ptr)
135 std::vector<Pos2D> points;
137 void (*add_mon_lite)(player_type *, std::vector<Pos2D> &, const POSITION, const POSITION, const monster_lite_type *);
138 int dis_lim = (d_info[subject_ptr->dungeon_idx].flags.has(DF::DARKNESS) && !subject_ptr->see_nocto) ? (MAX_SIGHT / 2 + 1) : (MAX_SIGHT + 3);
139 floor_type *floor_ptr = subject_ptr->current_floor_ptr;
140 for (int i = 0; i < floor_ptr->mon_lite_n; i++) {
142 g_ptr = &floor_ptr->grid_array[floor_ptr->mon_lite_y[i]][floor_ptr->mon_lite_x[i]];
143 g_ptr->info |= (g_ptr->info & CAVE_MNLT) ? CAVE_TEMP : CAVE_XTRA;
144 g_ptr->info &= ~(CAVE_MNLT | CAVE_MNDK);
147 if (!current_world_ptr->timewalk_m_idx) {
150 for (int i = 1; i < floor_ptr->m_max; i++) {
151 m_ptr = &floor_ptr->m_list[i];
152 r_ptr = &r_info[m_ptr->r_idx];
153 if (!monster_is_valid(m_ptr) || (m_ptr->cdis > dis_lim))
157 if (r_ptr->flags7 & (RF7_HAS_LITE_1 | RF7_SELF_LITE_1))
160 if (r_ptr->flags7 & (RF7_HAS_LITE_2 | RF7_SELF_LITE_2))
163 if (r_ptr->flags7 & (RF7_HAS_DARK_1 | RF7_SELF_DARK_1))
166 if (r_ptr->flags7 & (RF7_HAS_DARK_2 | RF7_SELF_DARK_2))
172 feature_flag_type f_flag;
174 if (!(r_ptr->flags7 & (RF7_SELF_LITE_1 | RF7_SELF_LITE_2))
175 && (monster_csleep_remaining(m_ptr) || (!floor_ptr->dun_level && is_daytime()) || subject_ptr->phase_out))
178 if (d_info[subject_ptr->dungeon_idx].flags.has(DF::DARKNESS))
181 add_mon_lite = update_monster_lite;
184 if (!(r_ptr->flags7 & (RF7_SELF_DARK_1 | RF7_SELF_DARK_2)) && (monster_csleep_remaining(m_ptr) || (!floor_ptr->dun_level && !is_daytime())))
187 add_mon_lite = update_monster_dark;
192 monster_lite_type tmp_ml;
193 monster_lite_type *ml_ptr = initialize_monster_lite_type(floor_ptr->grid_array[m_ptr->fy][m_ptr->fx].info, &tmp_ml, m_ptr);
194 add_mon_lite(subject_ptr, points, ml_ptr->mon_fy, ml_ptr->mon_fx, ml_ptr);
195 add_mon_lite(subject_ptr, points, ml_ptr->mon_fy + 1, ml_ptr->mon_fx, ml_ptr);
196 add_mon_lite(subject_ptr, points, ml_ptr->mon_fy - 1, ml_ptr->mon_fx, ml_ptr);
197 add_mon_lite(subject_ptr, points, ml_ptr->mon_fy, ml_ptr->mon_fx + 1, ml_ptr);
198 add_mon_lite(subject_ptr, points, ml_ptr->mon_fy, ml_ptr->mon_fx - 1, ml_ptr);
199 add_mon_lite(subject_ptr, points, ml_ptr->mon_fy + 1, ml_ptr->mon_fx + 1, ml_ptr);
200 add_mon_lite(subject_ptr, points, ml_ptr->mon_fy + 1, ml_ptr->mon_fx - 1, ml_ptr);
201 add_mon_lite(subject_ptr, points, ml_ptr->mon_fy - 1, ml_ptr->mon_fx + 1, ml_ptr);
202 add_mon_lite(subject_ptr, points, ml_ptr->mon_fy - 1, ml_ptr->mon_fx - 1, ml_ptr);
207 if (cave_has_flag_bold(subject_ptr->current_floor_ptr, ml_ptr->mon_fy + 1, ml_ptr->mon_fx, f_flag)) {
208 add_mon_lite(subject_ptr, points, ml_ptr->mon_fy + 2, ml_ptr->mon_fx + 1, ml_ptr);
209 add_mon_lite(subject_ptr, points, ml_ptr->mon_fy + 2, ml_ptr->mon_fx, ml_ptr);
210 add_mon_lite(subject_ptr, points, ml_ptr->mon_fy + 2, ml_ptr->mon_fx - 1, ml_ptr);
211 g_ptr = &floor_ptr->grid_array[ml_ptr->mon_fy + 2][ml_ptr->mon_fx];
212 if ((rad == 3) && g_ptr->cave_has_flag(f_flag)) {
213 add_mon_lite(subject_ptr, points, ml_ptr->mon_fy + 3, ml_ptr->mon_fx + 1, ml_ptr);
214 add_mon_lite(subject_ptr, points, ml_ptr->mon_fy + 3, ml_ptr->mon_fx, ml_ptr);
215 add_mon_lite(subject_ptr, points, ml_ptr->mon_fy + 3, ml_ptr->mon_fx - 1, ml_ptr);
219 if (cave_has_flag_bold(subject_ptr->current_floor_ptr, ml_ptr->mon_fy - 1, ml_ptr->mon_fx, f_flag)) {
220 add_mon_lite(subject_ptr, points, ml_ptr->mon_fy - 2, ml_ptr->mon_fx + 1, ml_ptr);
221 add_mon_lite(subject_ptr, points, ml_ptr->mon_fy - 2, ml_ptr->mon_fx, ml_ptr);
222 add_mon_lite(subject_ptr, points, ml_ptr->mon_fy - 2, ml_ptr->mon_fx - 1, ml_ptr);
223 g_ptr = &floor_ptr->grid_array[ml_ptr->mon_fy - 2][ml_ptr->mon_fx];
224 if ((rad == 3) && g_ptr->cave_has_flag(f_flag)) {
225 add_mon_lite(subject_ptr, points, ml_ptr->mon_fy - 3, ml_ptr->mon_fx + 1, ml_ptr);
226 add_mon_lite(subject_ptr, points, ml_ptr->mon_fy - 3, ml_ptr->mon_fx, ml_ptr);
227 add_mon_lite(subject_ptr, points, ml_ptr->mon_fy - 3, ml_ptr->mon_fx - 1, ml_ptr);
231 if (cave_has_flag_bold(subject_ptr->current_floor_ptr, ml_ptr->mon_fy, ml_ptr->mon_fx + 1, f_flag)) {
232 add_mon_lite(subject_ptr, points, ml_ptr->mon_fy + 1, ml_ptr->mon_fx + 2, ml_ptr);
233 add_mon_lite(subject_ptr, points, ml_ptr->mon_fy, ml_ptr->mon_fx + 2, ml_ptr);
234 add_mon_lite(subject_ptr, points, ml_ptr->mon_fy - 1, ml_ptr->mon_fx + 2, ml_ptr);
235 g_ptr = &floor_ptr->grid_array[ml_ptr->mon_fy][ml_ptr->mon_fx + 2];
236 if ((rad == 3) && g_ptr->cave_has_flag(f_flag)) {
237 add_mon_lite(subject_ptr, points, ml_ptr->mon_fy + 1, ml_ptr->mon_fx + 3, ml_ptr);
238 add_mon_lite(subject_ptr, points, ml_ptr->mon_fy, ml_ptr->mon_fx + 3, ml_ptr);
239 add_mon_lite(subject_ptr, points, ml_ptr->mon_fy - 1, ml_ptr->mon_fx + 3, ml_ptr);
243 if (cave_has_flag_bold(subject_ptr->current_floor_ptr, ml_ptr->mon_fy, ml_ptr->mon_fx - 1, f_flag)) {
244 add_mon_lite(subject_ptr, points, ml_ptr->mon_fy + 1, ml_ptr->mon_fx - 2, ml_ptr);
245 add_mon_lite(subject_ptr, points, ml_ptr->mon_fy, ml_ptr->mon_fx - 2, ml_ptr);
246 add_mon_lite(subject_ptr, points, ml_ptr->mon_fy - 1, ml_ptr->mon_fx - 2, ml_ptr);
247 g_ptr = &floor_ptr->grid_array[ml_ptr->mon_fy][ml_ptr->mon_fx - 2];
248 if ((rad == 3) && g_ptr->cave_has_flag(f_flag)) {
249 add_mon_lite(subject_ptr, points, ml_ptr->mon_fy + 1, ml_ptr->mon_fx - 3, ml_ptr);
250 add_mon_lite(subject_ptr, points, ml_ptr->mon_fy, ml_ptr->mon_fx - 3, ml_ptr);
251 add_mon_lite(subject_ptr, points, ml_ptr->mon_fy - 1, ml_ptr->mon_fx - 3, 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, points, 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, points, ml_ptr->mon_fy + 2, ml_ptr->mon_fx - 2, ml_ptr);
264 if (cave_has_flag_bold(subject_ptr->current_floor_ptr, ml_ptr->mon_fy - 1, ml_ptr->mon_fx + 1, f_flag))
265 add_mon_lite(subject_ptr, points, ml_ptr->mon_fy - 2, ml_ptr->mon_fx + 2, ml_ptr);
267 if (cave_has_flag_bold(subject_ptr->current_floor_ptr, ml_ptr->mon_fy - 1, ml_ptr->mon_fx - 1, f_flag))
268 add_mon_lite(subject_ptr, points, ml_ptr->mon_fy - 2, ml_ptr->mon_fx - 2, ml_ptr);
272 const auto end_temp = size(points);
273 for (int i = 0; i < floor_ptr->mon_lite_n; i++) {
274 POSITION fx = floor_ptr->mon_lite_x[i];
275 POSITION fy = floor_ptr->mon_lite_y[i];
277 g_ptr = &floor_ptr->grid_array[fy][fx];
278 if (g_ptr->info & CAVE_TEMP) {
279 if ((g_ptr->info & (CAVE_VIEW | CAVE_MNLT)) == CAVE_VIEW)
280 cave_note_and_redraw_later(floor_ptr, fy, fx);
281 } else if ((g_ptr->info & (CAVE_VIEW | CAVE_MNDK)) == CAVE_VIEW)
282 cave_note_and_redraw_later(floor_ptr, fy, fx);
284 points.emplace_back(fy, fx);
287 floor_ptr->mon_lite_n = 0;
288 for (size_t i = 0; i < end_temp; i++) {
289 const auto [fy, fx] = points[i];
291 grid_type *const g_ptr = &floor_ptr->grid_array[fy][fx];
292 if (g_ptr->info & CAVE_MNLT) {
293 if ((g_ptr->info & (CAVE_VIEW | CAVE_TEMP)) == CAVE_VIEW)
294 cave_note_and_redraw_later(floor_ptr, fy, fx);
295 } else if ((g_ptr->info & (CAVE_VIEW | CAVE_XTRA)) == CAVE_VIEW)
296 cave_note_and_redraw_later(floor_ptr, fy, fx);
298 floor_ptr->mon_lite_x[floor_ptr->mon_lite_n] = fx;
299 floor_ptr->mon_lite_y[floor_ptr->mon_lite_n] = fy;
300 floor_ptr->mon_lite_n++;
303 for (size_t i = end_temp; i < size(points); i++) {
304 const auto [y, x] = points[i];
305 floor_ptr->grid_array[y][x].info &= ~(CAVE_TEMP | CAVE_XTRA);
308 subject_ptr->update |= PU_DELAY_VIS;
309 subject_ptr->monlite = (floor_ptr->grid_array[subject_ptr->y][subject_ptr->x].info & CAVE_MNLT) != 0;
310 if (!(subject_ptr->special_defense & NINJA_S_STEALTH)) {
311 subject_ptr->old_monlite = subject_ptr->monlite;
315 if (subject_ptr->old_monlite == subject_ptr->monlite) {
316 subject_ptr->old_monlite = subject_ptr->monlite;
320 if (subject_ptr->monlite)
321 msg_print(_("影の覆いが薄れた気がする。", "Your mantle of shadow becomes thin."));
323 msg_print(_("影の覆いが濃くなった!", "Your mantle of shadow is restored to its original darkness."));
325 subject_ptr->old_monlite = subject_ptr->monlite;
329 * @brief 画面切り替え等でモンスターの灯りを消去する
330 * @param floor_ptr 現在フロアへの参照ポインタ
332 void clear_mon_lite(floor_type *floor_ptr)
334 for (int i = 0; i < floor_ptr->mon_lite_n; i++) {
336 g_ptr = &floor_ptr->grid_array[floor_ptr->mon_lite_y[i]][floor_ptr->mon_lite_x[i]];
337 g_ptr->info &= ~(CAVE_MNLT | CAVE_MNDK);
340 floor_ptr->mon_lite_n = 0;