OSDN Git Service

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