OSDN Git Service

[Refactor] enum classの型名変更 MFLAG -> MonsterTemporaryFlagType
[hengbandforosx/hengbandosx.git] / src / monster / monster-update.cpp
1 /*!
2  * @brief モンスター情報のアップデート処理
3  * @date 2020/03/08
4  * @author Hourier
5  */
6
7 #include "monster/monster-update.h"
8 #include "core/disturbance.h"
9 #include "core/player-redraw-types.h"
10 #include "core/player-update-types.h"
11 #include "core/window-redrawer.h"
12 #include "dungeon/dungeon-flag-types.h"
13 #include "dungeon/dungeon.h"
14 #include "floor/cave.h"
15 #include "floor/geometry.h"
16 #include "game-option/birth-options.h"
17 #include "game-option/disturbance-options.h"
18 #include "grid/grid.h"
19 #include "mind/drs-types.h"
20 #include "monster-race/monster-race.h"
21 #include "monster-race/race-flags1.h"
22 #include "monster-race/race-flags2.h"
23 #include "monster-race/race-flags3.h"
24 #include "monster-race/race-flags7.h"
25 #include "monster-race/race-indice-types.h"
26 #include "monster/monster-flag-types.h"
27 #include "monster/monster-info.h"
28 #include "monster/monster-processor-util.h"
29 #include "monster/monster-status.h"
30 #include "monster/smart-learn-types.h"
31 #include "player-base/player-class.h"
32 #include "player-info/samurai-data-type.h"
33 #include "player-info/sniper-data-type.h"
34 #include "player/player-move.h"
35 #include "player/player-status-flags.h"
36 #include "player/special-defense-types.h"
37 #include "status/element-resistance.h"
38 #include "system/floor-type-definition.h"
39 #include "system/grid-type-definition.h"
40 #include "system/monster-race-definition.h"
41 #include "system/monster-type-definition.h"
42 #include "system/player-type-definition.h"
43 #include "target/projection-path-calculator.h"
44 #include "util/bit-flags-calculator.h"
45 #include "world/world.h"
46
47 // Update Monster.
48 typedef struct um_type {
49     monster_type *m_ptr;
50     bool do_disturb;
51     POSITION fy;
52     POSITION fx;
53     bool flag;
54     bool easy;
55     bool in_darkness;
56     bool full;
57 } um_type;
58
59 /*!
60  * @brief 騎乗中のモンスター情報を更新する
61  * @param player_ptr プレイヤーへの参照ポインタ
62  * @param turn_flags_ptr ターン経過処理フラグへの参照ポインタ
63  * @param m_idx モンスターID
64  * @param oy 移動前の、モンスターのY座標
65  * @param ox 移動前の、モンスターのX座標
66  * @param ny 移動後の、モンスターのY座標
67  * @param ox 移動後の、モンスターのX座標
68  * @return アイテム等に影響を及ぼしたらTRUE
69  */
70 bool update_riding_monster(player_type *player_ptr, turn_flags *turn_flags_ptr, MONSTER_IDX m_idx, POSITION oy, POSITION ox, POSITION ny, POSITION nx)
71 {
72     monster_type *m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
73     grid_type *g_ptr = &player_ptr->current_floor_ptr->grid_array[ny][nx];
74     monster_type *y_ptr = &player_ptr->current_floor_ptr->m_list[g_ptr->m_idx];
75     if (turn_flags_ptr->is_riding_mon)
76         return move_player_effect(player_ptr, ny, nx, MPE_DONT_PICKUP);
77
78     player_ptr->current_floor_ptr->grid_array[oy][ox].m_idx = g_ptr->m_idx;
79     if (g_ptr->m_idx) {
80         y_ptr->fy = oy;
81         y_ptr->fx = ox;
82         update_monster(player_ptr, g_ptr->m_idx, true);
83     }
84
85     g_ptr->m_idx = m_idx;
86     m_ptr->fy = ny;
87     m_ptr->fx = nx;
88     update_monster(player_ptr, m_idx, true);
89
90     lite_spot(player_ptr, oy, ox);
91     lite_spot(player_ptr, ny, nx);
92     return true;
93 }
94
95 /*!
96  * @brief updateフィールドを更新する
97  * @param player_ptr プレイヤーへの参照ポインタ
98  * @param turn_flags_ptr ターン経過処理フラグへの参照ポインタ
99  */
100 void update_player_type(player_type *player_ptr, turn_flags *turn_flags_ptr, monster_race *r_ptr)
101 {
102     if (turn_flags_ptr->do_view) {
103         player_ptr->update |= PU_FLOW;
104         player_ptr->window_flags |= PW_OVERHEAD | PW_DUNGEON;
105     }
106
107     if (turn_flags_ptr->do_move
108         && ((r_ptr->flags7 & (RF7_SELF_LD_MASK | RF7_HAS_DARK_1 | RF7_HAS_DARK_2))
109             || ((r_ptr->flags7 & (RF7_HAS_LITE_1 | RF7_HAS_LITE_2)) && !player_ptr->phase_out))) {
110         player_ptr->update |= PU_MON_LITE;
111     }
112 }
113
114 /*!
115  * @brief モンスターのフラグを更新する
116  * @param player_ptr プレイヤーへの参照ポインタ
117  * @param turn_flags_ptr ターン経過処理フラグへの参照ポインタ
118  * @param m_ptr モンスターへの参照ポインタ
119  */
120 void update_monster_race_flags(player_type *player_ptr, turn_flags *turn_flags_ptr, monster_type *m_ptr)
121 {
122     monster_race *r_ptr = &r_info[m_ptr->r_idx];
123     if (!is_original_ap_and_seen(player_ptr, m_ptr))
124         return;
125
126     if (turn_flags_ptr->did_open_door)
127         r_ptr->r_flags2 |= RF2_OPEN_DOOR;
128
129     if (turn_flags_ptr->did_bash_door)
130         r_ptr->r_flags2 |= RF2_BASH_DOOR;
131
132     if (turn_flags_ptr->did_take_item)
133         r_ptr->r_flags2 |= RF2_TAKE_ITEM;
134
135     if (turn_flags_ptr->did_kill_item)
136         r_ptr->r_flags2 |= RF2_KILL_ITEM;
137
138     if (turn_flags_ptr->did_move_body)
139         r_ptr->r_flags2 |= RF2_MOVE_BODY;
140
141     if (turn_flags_ptr->did_pass_wall)
142         r_ptr->r_flags2 |= RF2_PASS_WALL;
143
144     if (turn_flags_ptr->did_kill_wall)
145         r_ptr->r_flags2 |= RF2_KILL_WALL;
146 }
147
148 /*!
149  * @brief モンスターフラグの更新に基づき、モンスター表示を更新する
150  * @param monster_race_idx モンスターID
151  * @param window ウィンドウフラグ
152  * @param old_race_flags_ptr モンスターフラグへの参照ポインタ
153  */
154 void update_player_window(player_type *player_ptr, old_race_flags *old_race_flags_ptr)
155 {
156     monster_race *r_ptr;
157     r_ptr = &r_info[player_ptr->monster_race_idx];
158     if ((old_race_flags_ptr->old_r_flags1 != r_ptr->r_flags1) || (old_race_flags_ptr->old_r_flags2 != r_ptr->r_flags2)
159         || (old_race_flags_ptr->old_r_flags3 != r_ptr->r_flags3) || (old_race_flags_ptr->old_r_ability_flags != r_ptr->r_ability_flags)
160         || (old_race_flags_ptr->old_r_flagsr != r_ptr->r_flagsr) || (old_race_flags_ptr->old_r_blows0 != r_ptr->r_blows[0])
161         || (old_race_flags_ptr->old_r_blows1 != r_ptr->r_blows[1]) || (old_race_flags_ptr->old_r_blows2 != r_ptr->r_blows[2])
162         || (old_race_flags_ptr->old_r_blows3 != r_ptr->r_blows[3]) || (old_race_flags_ptr->old_r_cast_spell != r_ptr->r_cast_spell)) {
163         player_ptr->window_flags |= PW_MONSTER;
164     }
165 }
166
167 static um_type *initialize_um_type(player_type *player_ptr, um_type *um_ptr, MONSTER_IDX m_idx, bool full)
168 {
169     um_ptr->m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
170     um_ptr->do_disturb = disturb_move;
171     um_ptr->fy = um_ptr->m_ptr->fy;
172     um_ptr->fx = um_ptr->m_ptr->fx;
173     um_ptr->flag = false;
174     um_ptr->easy = false;
175     um_ptr->in_darkness = d_info[player_ptr->dungeon_idx].flags.has(DungeonFeatureType::DARKNESS) && !player_ptr->see_nocto;
176     um_ptr->full = full;
177     return um_ptr;
178 }
179
180 static POSITION decide_updated_distance(player_type *player_ptr, um_type *um_ptr)
181 {
182     if (!um_ptr->full)
183         return um_ptr->m_ptr->cdis;
184
185     int dy = (player_ptr->y > um_ptr->fy) ? (player_ptr->y - um_ptr->fy) : (um_ptr->fy - player_ptr->y);
186     int dx = (player_ptr->x > um_ptr->fx) ? (player_ptr->x - um_ptr->fx) : (um_ptr->fx - player_ptr->x);
187     POSITION distance = (dy > dx) ? (dy + (dx >> 1)) : (dx + (dy >> 1));
188     if (distance > 255)
189         distance = 255;
190
191     if (!distance)
192         distance = 1;
193
194     um_ptr->m_ptr->cdis = distance;
195     return distance;
196 }
197
198 static void update_smart_stupid_flags(monster_race *r_ptr)
199 {
200     if (r_ptr->flags2 & RF2_SMART)
201         r_ptr->r_flags2 |= RF2_SMART;
202
203     if (r_ptr->flags2 & RF2_STUPID)
204         r_ptr->r_flags2 |= RF2_STUPID;
205 }
206
207 /*!
208  * @brief WEIRD_MINDフラグ持ちのモンスターを1/10の確率でテレパシーに引っかける
209  * @param player_ptr プレイヤーへの参照ポインタ
210  * @param um_ptr モンスター情報アップデート構造体への参照ポインタ
211  * @param m_idx モンスターID
212  * @return WEIRD_MINDフラグがあるならTRUE
213  */
214 static bool update_weird_telepathy(player_type *player_ptr, um_type *um_ptr, MONSTER_IDX m_idx)
215 {
216     monster_race *r_ptr = &r_info[um_ptr->m_ptr->r_idx];
217     if ((r_ptr->flags2 & RF2_WEIRD_MIND) == 0)
218         return false;
219
220     if ((m_idx % 10) != (w_ptr->game_turn % 10))
221         return true;
222
223     um_ptr->flag = true;
224     um_ptr->m_ptr->mflag.set(MonsterTemporaryFlagType::ESP);
225     if (is_original_ap(um_ptr->m_ptr) && !player_ptr->hallucinated) {
226         r_ptr->r_flags2 |= RF2_WEIRD_MIND;
227         update_smart_stupid_flags(r_ptr);
228     }
229
230     return true;
231 }
232
233 static void update_telepathy_sight(player_type *player_ptr, um_type *um_ptr, MONSTER_IDX m_idx)
234 {
235     monster_race *r_ptr = &r_info[um_ptr->m_ptr->r_idx];
236     if (PlayerClass(player_ptr).samurai_stance_is(SamuraiStance::MUSOU)) {
237         um_ptr->flag = true;
238         um_ptr->m_ptr->mflag.set(MonsterTemporaryFlagType::ESP);
239         if (is_original_ap(um_ptr->m_ptr) && !player_ptr->hallucinated)
240             update_smart_stupid_flags(r_ptr);
241
242         return;
243     }
244
245     if (!player_ptr->telepathy)
246         return;
247
248     if (r_ptr->flags2 & RF2_EMPTY_MIND) {
249         if (is_original_ap(um_ptr->m_ptr) && !player_ptr->hallucinated)
250             r_ptr->r_flags2 |= RF2_EMPTY_MIND;
251
252         return;
253     }
254
255     if (update_weird_telepathy(player_ptr, um_ptr, m_idx))
256         return;
257
258     um_ptr->flag = true;
259     um_ptr->m_ptr->mflag.set(MonsterTemporaryFlagType::ESP);
260     if (is_original_ap(um_ptr->m_ptr) && !player_ptr->hallucinated)
261         update_smart_stupid_flags(r_ptr);
262 }
263
264 static void update_specific_race_telepathy(player_type *player_ptr, um_type *um_ptr)
265 {
266     monster_race *r_ptr = &r_info[um_ptr->m_ptr->r_idx];
267     if ((player_ptr->esp_animal) && (r_ptr->flags3 & RF3_ANIMAL)) {
268         um_ptr->flag = true;
269         um_ptr->m_ptr->mflag.set(MonsterTemporaryFlagType::ESP);
270         if (is_original_ap(um_ptr->m_ptr) && !player_ptr->hallucinated)
271             r_ptr->r_flags3 |= RF3_ANIMAL;
272     }
273
274     if ((player_ptr->esp_undead) && (r_ptr->flags3 & RF3_UNDEAD)) {
275         um_ptr->flag = true;
276         um_ptr->m_ptr->mflag.set(MonsterTemporaryFlagType::ESP);
277         if (is_original_ap(um_ptr->m_ptr) && !player_ptr->hallucinated)
278             r_ptr->r_flags3 |= RF3_UNDEAD;
279     }
280
281     if ((player_ptr->esp_demon) && (r_ptr->flags3 & RF3_DEMON)) {
282         um_ptr->flag = true;
283         um_ptr->m_ptr->mflag.set(MonsterTemporaryFlagType::ESP);
284         if (is_original_ap(um_ptr->m_ptr) && !player_ptr->hallucinated)
285             r_ptr->r_flags3 |= RF3_DEMON;
286     }
287
288     if ((player_ptr->esp_orc) && (r_ptr->flags3 & RF3_ORC)) {
289         um_ptr->flag = true;
290         um_ptr->m_ptr->mflag.set(MonsterTemporaryFlagType::ESP);
291         if (is_original_ap(um_ptr->m_ptr) && !player_ptr->hallucinated)
292             r_ptr->r_flags3 |= RF3_ORC;
293     }
294
295     if ((player_ptr->esp_troll) && (r_ptr->flags3 & RF3_TROLL)) {
296         um_ptr->flag = true;
297         um_ptr->m_ptr->mflag.set(MonsterTemporaryFlagType::ESP);
298         if (is_original_ap(um_ptr->m_ptr) && !player_ptr->hallucinated)
299             r_ptr->r_flags3 |= RF3_TROLL;
300     }
301
302     if ((player_ptr->esp_giant) && (r_ptr->flags3 & RF3_GIANT)) {
303         um_ptr->flag = true;
304         um_ptr->m_ptr->mflag.set(MonsterTemporaryFlagType::ESP);
305         if (is_original_ap(um_ptr->m_ptr) && !player_ptr->hallucinated)
306             r_ptr->r_flags3 |= RF3_GIANT;
307     }
308
309     if ((player_ptr->esp_dragon) && (r_ptr->flags3 & RF3_DRAGON)) {
310         um_ptr->flag = true;
311         um_ptr->m_ptr->mflag.set(MonsterTemporaryFlagType::ESP);
312         if (is_original_ap(um_ptr->m_ptr) && !player_ptr->hallucinated)
313             r_ptr->r_flags3 |= RF3_DRAGON;
314     }
315
316     if ((player_ptr->esp_human) && (r_ptr->flags2 & RF2_HUMAN)) {
317         um_ptr->flag = true;
318         um_ptr->m_ptr->mflag.set(MonsterTemporaryFlagType::ESP);
319         if (is_original_ap(um_ptr->m_ptr) && !player_ptr->hallucinated)
320             r_ptr->r_flags2 |= RF2_HUMAN;
321     }
322
323     if ((player_ptr->esp_evil) && (r_ptr->flags3 & RF3_EVIL)) {
324         um_ptr->flag = true;
325         um_ptr->m_ptr->mflag.set(MonsterTemporaryFlagType::ESP);
326         if (is_original_ap(um_ptr->m_ptr) && !player_ptr->hallucinated)
327             r_ptr->r_flags3 |= RF3_EVIL;
328     }
329
330     if ((player_ptr->esp_good) && (r_ptr->flags3 & RF3_GOOD)) {
331         um_ptr->flag = true;
332         um_ptr->m_ptr->mflag.set(MonsterTemporaryFlagType::ESP);
333         if (is_original_ap(um_ptr->m_ptr) && !player_ptr->hallucinated)
334             r_ptr->r_flags3 |= RF3_GOOD;
335     }
336
337     if ((player_ptr->esp_nonliving) && ((r_ptr->flags3 & (RF3_DEMON | RF3_UNDEAD | RF3_NONLIVING)) == RF3_NONLIVING)) {
338         um_ptr->flag = true;
339         um_ptr->m_ptr->mflag.set(MonsterTemporaryFlagType::ESP);
340         if (is_original_ap(um_ptr->m_ptr) && !player_ptr->hallucinated)
341             r_ptr->r_flags3 |= RF3_NONLIVING;
342     }
343
344     if ((player_ptr->esp_unique) && (r_ptr->flags1 & RF1_UNIQUE)) {
345         um_ptr->flag = true;
346         um_ptr->m_ptr->mflag.set(MonsterTemporaryFlagType::ESP);
347         if (is_original_ap(um_ptr->m_ptr) && !player_ptr->hallucinated)
348             r_ptr->r_flags1 |= RF1_UNIQUE;
349     }
350 }
351
352 static bool check_cold_blood(player_type *player_ptr, um_type *um_ptr, const POSITION distance)
353 {
354     if (distance > player_ptr->see_infra)
355         return false;
356
357     monster_race *r_ptr = &r_info[um_ptr->m_ptr->r_idx];
358     if (any_bits(r_ptr->flags2, RF2_COLD_BLOOD) && r_ptr->aura_flags.has_not(MonsterAuraType::FIRE))
359         return false;
360
361     um_ptr->easy = true;
362     um_ptr->flag = true;
363     return true;
364 }
365
366 static bool check_invisible(player_type *player_ptr, um_type *um_ptr)
367 {
368     if (!player_can_see_bold(player_ptr, um_ptr->fy, um_ptr->fx))
369         return false;
370
371     monster_race *r_ptr = &r_info[um_ptr->m_ptr->r_idx];
372     if (r_ptr->flags2 & RF2_INVISIBLE) {
373         if (player_ptr->see_inv) {
374             um_ptr->easy = true;
375             um_ptr->flag = true;
376         }
377     } else {
378         um_ptr->easy = true;
379         um_ptr->flag = true;
380     }
381
382     return true;
383 }
384
385 /*!
386  * @brief テレパシー・赤外線視力・可視透明によってモンスターを感知できるかどうかの判定
387  * @param player_ptr プレイヤーへの参照ポインタ
388  * @param um_ptr モンスター情報アップデート構造体への参照ポインタ
389  */
390 static void decide_sight_invisible_monster(player_type *player_ptr, um_type *um_ptr, MONSTER_IDX m_idx)
391 {
392     POSITION distance = decide_updated_distance(player_ptr, um_ptr);
393     monster_race *r_ptr = &r_info[um_ptr->m_ptr->r_idx];
394
395     um_ptr->m_ptr->mflag.reset(MonsterTemporaryFlagType::ESP);
396
397     if (distance > (um_ptr->in_darkness ? MAX_SIGHT / 2 : MAX_SIGHT))
398         return;
399
400     if (!um_ptr->in_darkness || (distance <= MAX_SIGHT / 4)) {
401         update_telepathy_sight(player_ptr, um_ptr, m_idx);
402         update_specific_race_telepathy(player_ptr, um_ptr);
403     }
404
405     if (!player_has_los_bold(player_ptr, um_ptr->fy, um_ptr->fx) || player_ptr->blind)
406         return;
407
408     auto sniper_data = PlayerClass(player_ptr).get_specific_data<sniper_data_type>();
409     if (sniper_data && (sniper_data->concent >= CONCENT_RADAR_THRESHOLD)) {
410         um_ptr->easy = true;
411         um_ptr->flag = true;
412     }
413
414     bool do_cold_blood = check_cold_blood(player_ptr, um_ptr, distance);
415     bool do_invisible = check_invisible(player_ptr, um_ptr);
416     if (!um_ptr->flag || !is_original_ap(um_ptr->m_ptr) || player_ptr->hallucinated)
417         return;
418
419     if (do_invisible)
420         r_ptr->r_flags2 |= RF2_INVISIBLE;
421
422     if (do_cold_blood)
423         r_ptr->r_flags2 |= RF2_COLD_BLOOD;
424 }
425
426 /*!
427  * @brief 壁の向こうにいるモンスターへのテレパシー・赤外線視力による冷血動物以外の透明モンスター・可視透明能力による透明モンスター
428  * 以上を感知する
429  * @param player_ptr プレイヤーへの参照ポインタ
430  * @param um_ptr モンスター情報アップデート構造体への参照ポインタ
431  * @param m_idx フロアのモンスター番号
432  * @details 感知した結果、エルドリッチホラー持ちがいたら精神を破壊する
433  */
434 static void update_invisible_monster(player_type *player_ptr, um_type *um_ptr, MONSTER_IDX m_idx)
435 {
436     if (um_ptr->m_ptr->ml)
437         return;
438
439     um_ptr->m_ptr->ml = true;
440     lite_spot(player_ptr, um_ptr->fy, um_ptr->fx);
441
442     if (player_ptr->health_who == m_idx)
443         player_ptr->redraw |= PR_HEALTH;
444
445     if (player_ptr->riding == m_idx)
446         player_ptr->redraw |= PR_UHEALTH;
447
448     if (!player_ptr->hallucinated) {
449         monster_race *r_ptr = &r_info[um_ptr->m_ptr->r_idx];
450         if ((um_ptr->m_ptr->ap_r_idx == MON_KAGE) && (r_info[MON_KAGE].r_sights < MAX_SHORT))
451             r_info[MON_KAGE].r_sights++;
452         else if (is_original_ap(um_ptr->m_ptr) && (r_ptr->r_sights < MAX_SHORT))
453             r_ptr->r_sights++;
454     }
455
456     if (w_ptr->is_loading_now && w_ptr->character_dungeon && !player_ptr->phase_out
457         && r_info[um_ptr->m_ptr->ap_r_idx].flags2 & RF2_ELDRITCH_HORROR)
458         um_ptr->m_ptr->mflag.set(MonsterTemporaryFlagType::SANITY_BLAST);
459
460     if (disturb_near
461         && (projectable(player_ptr, um_ptr->m_ptr->fy, um_ptr->m_ptr->fx, player_ptr->y, player_ptr->x)
462             && projectable(player_ptr, player_ptr->y, player_ptr->x, um_ptr->m_ptr->fy, um_ptr->m_ptr->fx))) {
463         if (disturb_pets || is_hostile(um_ptr->m_ptr))
464             disturb(player_ptr, true, true);
465     }
466 }
467
468 static void update_visible_monster(player_type *player_ptr, um_type *um_ptr, MONSTER_IDX m_idx)
469 {
470     if (!um_ptr->m_ptr->ml)
471         return;
472
473     um_ptr->m_ptr->ml = false;
474     lite_spot(player_ptr, um_ptr->fy, um_ptr->fx);
475
476     if (player_ptr->health_who == m_idx)
477         player_ptr->redraw |= PR_HEALTH;
478
479     if (player_ptr->riding == m_idx)
480         player_ptr->redraw |= PR_UHEALTH;
481
482     if (um_ptr->do_disturb && (disturb_pets || is_hostile(um_ptr->m_ptr)))
483         disturb(player_ptr, true, true);
484 }
485
486 static bool update_clear_monster(player_type *player_ptr, um_type *um_ptr)
487 {
488     if (!um_ptr->easy)
489         return false;
490
491     if (um_ptr->m_ptr->mflag.has_not(MonsterTemporaryFlagType::VIEW)) {
492         um_ptr->m_ptr->mflag.set(MonsterTemporaryFlagType::VIEW);
493         if (um_ptr->do_disturb && (disturb_pets || is_hostile(um_ptr->m_ptr)))
494             disturb(player_ptr, true, true);
495     }
496
497     return true;
498 }
499
500 /*!
501  * @brief モンスターの各情報を更新する / This function updates the monster record of the given monster
502  * @param m_idx 更新するモンスター情報のID
503  * @param full プレイヤーとの距離更新を行うならばtrue
504  */
505 void update_monster(player_type *player_ptr, MONSTER_IDX m_idx, bool full)
506 {
507     um_type tmp_um;
508     um_type *um_ptr = initialize_um_type(player_ptr, &tmp_um, m_idx, full);
509     if (disturb_high) {
510         monster_race *ap_r_ptr = &r_info[um_ptr->m_ptr->ap_r_idx];
511         if (ap_r_ptr->r_tkills && ap_r_ptr->level >= player_ptr->lev)
512             um_ptr->do_disturb = true;
513     }
514
515     if (um_ptr->m_ptr->mflag2.has(MFLAG2::MARK))
516         um_ptr->flag = true;
517
518     decide_sight_invisible_monster(player_ptr, um_ptr, m_idx);
519     if (um_ptr->flag)
520         update_invisible_monster(player_ptr, um_ptr, m_idx);
521     else
522         update_visible_monster(player_ptr, um_ptr, m_idx);
523
524     if (update_clear_monster(player_ptr, um_ptr) || um_ptr->m_ptr->mflag.has_not(MonsterTemporaryFlagType::VIEW))
525         return;
526
527     um_ptr->m_ptr->mflag.reset(MonsterTemporaryFlagType::VIEW);
528     if (um_ptr->do_disturb && (disturb_pets || is_hostile(um_ptr->m_ptr)))
529         disturb(player_ptr, true, true);
530 }
531
532 /*!
533  * @param player_ptr プレイヤーへの参照ポインタ
534  * @brief 単純に生存している全モンスターの更新処理を行う / This function simply updates all the (non-dead) monsters (see above).
535  * @param full 距離更新を行うならtrue
536  * @todo モンスターの感知状況しか更新していないように見える。関数名変更を検討する
537  */
538 void update_monsters(player_type *player_ptr, bool full)
539 {
540     floor_type *floor_ptr = player_ptr->current_floor_ptr;
541     for (MONSTER_IDX i = 1; i < floor_ptr->m_max; i++) {
542         monster_type *m_ptr = &floor_ptr->m_list[i];
543         if (!monster_is_valid(m_ptr))
544             continue;
545
546         update_monster(player_ptr, i, full);
547     }
548 }
549
550 /*!
551  * @brief SMART(適格に攻撃を行う)モンスターの学習状況を更新する / Learn about an "observed" resistance.
552  * @param m_idx 更新を行う「モンスター情報ID
553  * @param what 学習対象ID
554  */
555 void update_smart_learn(player_type *player_ptr, MONSTER_IDX m_idx, int what)
556 {
557     monster_type *m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
558     monster_race *r_ptr = &r_info[m_ptr->r_idx];
559     if (!smart_learn || ((r_ptr->flags2 & RF2_STUPID) != 0) || (((r_ptr->flags2 & RF2_SMART) == 0) && (randint0(100) < 50)))
560         return;
561
562     switch (what) {
563     case DRS_ACID:
564         if (has_resist_acid(player_ptr))
565             m_ptr->smart.set(SM::RES_ACID);
566
567         if (is_oppose_acid(player_ptr))
568             m_ptr->smart.set(SM::OPP_ACID);
569
570         if (has_immune_acid(player_ptr))
571             m_ptr->smart.set(SM::IMM_ACID);
572
573         break;
574     case DRS_ELEC:
575         if (has_resist_elec(player_ptr))
576             m_ptr->smart.set(SM::RES_ELEC);
577
578         if (is_oppose_elec(player_ptr))
579             m_ptr->smart.set(SM::OPP_ELEC);
580
581         if (has_immune_elec(player_ptr))
582             m_ptr->smart.set(SM::IMM_ELEC);
583
584         break;
585     case DRS_FIRE:
586         if (has_resist_fire(player_ptr))
587             m_ptr->smart.set(SM::RES_FIRE);
588
589         if (is_oppose_fire(player_ptr))
590             m_ptr->smart.set(SM::OPP_FIRE);
591
592         if (has_immune_fire(player_ptr))
593             m_ptr->smart.set(SM::IMM_FIRE);
594
595         break;
596     case DRS_COLD:
597         if (has_resist_cold(player_ptr))
598             m_ptr->smart.set(SM::RES_COLD);
599
600         if (is_oppose_cold(player_ptr))
601             m_ptr->smart.set(SM::OPP_COLD);
602
603         if (has_immune_cold(player_ptr))
604             m_ptr->smart.set(SM::IMM_COLD);
605
606         break;
607     case DRS_POIS:
608         if (has_resist_pois(player_ptr))
609             m_ptr->smart.set(SM::RES_POIS);
610
611         if (is_oppose_pois(player_ptr))
612             m_ptr->smart.set(SM::OPP_POIS);
613
614         break;
615     case DRS_NETH:
616         if (has_resist_neth(player_ptr))
617             m_ptr->smart.set(SM::RES_NETH);
618
619         break;
620     case DRS_LITE:
621         if (has_resist_lite(player_ptr))
622             m_ptr->smart.set(SM::RES_LITE);
623
624         break;
625     case DRS_DARK:
626         if (has_resist_dark(player_ptr))
627             m_ptr->smart.set(SM::RES_DARK);
628
629         break;
630     case DRS_FEAR:
631         if (has_resist_fear(player_ptr))
632             m_ptr->smart.set(SM::RES_FEAR);
633
634         break;
635     case DRS_CONF:
636         if (has_resist_conf(player_ptr))
637             m_ptr->smart.set(SM::RES_CONF);
638
639         break;
640     case DRS_CHAOS:
641         if (has_resist_chaos(player_ptr))
642             m_ptr->smart.set(SM::RES_CHAOS);
643
644         break;
645     case DRS_DISEN:
646         if (has_resist_disen(player_ptr))
647             m_ptr->smart.set(SM::RES_DISEN);
648
649         break;
650     case DRS_BLIND:
651         if (has_resist_blind(player_ptr))
652             m_ptr->smart.set(SM::RES_BLIND);
653
654         break;
655     case DRS_NEXUS:
656         if (has_resist_nexus(player_ptr))
657             m_ptr->smart.set(SM::RES_NEXUS);
658
659         break;
660     case DRS_SOUND:
661         if (has_resist_sound(player_ptr))
662             m_ptr->smart.set(SM::RES_SOUND);
663
664         break;
665     case DRS_SHARD:
666         if (has_resist_shard(player_ptr))
667             m_ptr->smart.set(SM::RES_SHARD);
668
669         break;
670     case DRS_FREE:
671         if (player_ptr->free_act)
672             m_ptr->smart.set(SM::IMM_FREE);
673
674         break;
675     case DRS_MANA:
676         if (!player_ptr->msp)
677             m_ptr->smart.set(SM::IMM_MANA);
678
679         break;
680     case DRS_REFLECT:
681         if (has_reflect(player_ptr))
682             m_ptr->smart.set(SM::IMM_REFLECT);
683
684         break;
685     default:
686         break;
687     }
688 }