OSDN Git Service

[Refactor] #40514 immune_cold は has_immune_cold() を直接参照. / For immune_cold, directly...
[hengband/hengband.git] / src / monster / monster-update.c
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/special-defense-types.h"
32 #include "player/player-status-flags.h"
33 #include "status/element-resistance.h"
34 #include "system/floor-type-definition.h"
35 #include "target/projection-path-calculator.h"
36
37 /*!
38  * @brief 騎乗中のモンスター情報を更新する
39  * @param target_ptr プレーヤーへの参照ポインタ
40  * @param turn_flags_ptr ターン経過処理フラグへの参照ポインタ
41  * @param m_idx モンスターID
42  * @param oy 移動前の、モンスターのY座標
43  * @param ox 移動前の、モンスターのX座標
44  * @param ny 移動後の、モンスターのY座標
45  * @param ox 移動後の、モンスターのX座標
46  * @return アイテム等に影響を及ぼしたらTRUE
47  */
48 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)
49 {
50         monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
51         grid_type *g_ptr;
52         g_ptr = &target_ptr->current_floor_ptr->grid_array[ny][nx];
53         monster_type *y_ptr;
54         y_ptr = &target_ptr->current_floor_ptr->m_list[g_ptr->m_idx];
55         if (turn_flags_ptr->is_riding_mon)
56                 return move_player_effect(target_ptr, ny, nx, MPE_DONT_PICKUP);
57
58         target_ptr->current_floor_ptr->grid_array[oy][ox].m_idx = g_ptr->m_idx;
59         if (g_ptr->m_idx)
60         {
61                 y_ptr->fy = oy;
62                 y_ptr->fx = ox;
63                 update_monster(target_ptr, g_ptr->m_idx, TRUE);
64         }
65
66         g_ptr->m_idx = m_idx;
67         m_ptr->fy = ny;
68         m_ptr->fx = nx;
69         update_monster(target_ptr, m_idx, TRUE);
70
71         lite_spot(target_ptr, oy, ox);
72         lite_spot(target_ptr, ny, nx);
73         return TRUE;
74 }
75
76
77 /*!
78  * @brief updateフィールドを更新する
79  * @param target_ptr プレーヤーへの参照ポインタ
80  * @param turn_flags_ptr ターン経過処理フラグへの参照ポインタ
81  * @return なし
82  */
83 void update_player_type(player_type *target_ptr, turn_flags *turn_flags_ptr, monster_race *r_ptr)
84 {
85         if (turn_flags_ptr->do_view)
86         {
87                 target_ptr->update |= (PU_FLOW);
88                 target_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
89         }
90
91         if (turn_flags_ptr->do_move && ((r_ptr->flags7 & (RF7_SELF_LD_MASK | RF7_HAS_DARK_1 | RF7_HAS_DARK_2))
92                 || ((r_ptr->flags7 & (RF7_HAS_LITE_1 | RF7_HAS_LITE_2)) && !target_ptr->phase_out)))
93         {
94                 target_ptr->update |= (PU_MON_LITE);
95         }
96 }
97
98
99 /*!
100  * @brief モンスターのフラグを更新する
101  * @param target_ptr プレーヤーへの参照ポインタ
102  * @param turn_flags_ptr ターン経過処理フラグへの参照ポインタ
103  * @param m_ptr モンスターへの参照ポインタ
104  * @return なし
105  */
106 void update_monster_race_flags(player_type *target_ptr, turn_flags *turn_flags_ptr, monster_type *m_ptr)
107 {
108         monster_race *r_ptr = &r_info[m_ptr->r_idx];
109         if (!is_original_ap_and_seen(target_ptr, m_ptr)) return;
110
111         if (turn_flags_ptr->did_open_door) r_ptr->r_flags2 |= (RF2_OPEN_DOOR);
112         if (turn_flags_ptr->did_bash_door) r_ptr->r_flags2 |= (RF2_BASH_DOOR);
113         if (turn_flags_ptr->did_take_item) r_ptr->r_flags2 |= (RF2_TAKE_ITEM);
114         if (turn_flags_ptr->did_kill_item) r_ptr->r_flags2 |= (RF2_KILL_ITEM);
115         if (turn_flags_ptr->did_move_body) r_ptr->r_flags2 |= (RF2_MOVE_BODY);
116         if (turn_flags_ptr->did_pass_wall) r_ptr->r_flags2 |= (RF2_PASS_WALL);
117         if (turn_flags_ptr->did_kill_wall) r_ptr->r_flags2 |= (RF2_KILL_WALL);
118 }
119
120
121 /*!
122  * @brief モンスターフラグの更新に基づき、モンスター表示を更新する
123  * @param monster_race_idx モンスターID
124  * @param window ウィンドウフラグ
125  * @param old_race_flags_ptr モンスターフラグへの参照ポインタ
126  * @return なし
127  */
128 void update_player_window(player_type *target_ptr, old_race_flags *old_race_flags_ptr)
129 {
130         monster_race *r_ptr;
131         r_ptr = &r_info[target_ptr->monster_race_idx];
132         if ((old_race_flags_ptr->old_r_flags1 != r_ptr->r_flags1) ||
133                 (old_race_flags_ptr->old_r_flags2 != r_ptr->r_flags2) ||
134                 (old_race_flags_ptr->old_r_flags3 != r_ptr->r_flags3) ||
135                 (old_race_flags_ptr->old_r_flags4 != r_ptr->r_flags4) ||
136                 (old_race_flags_ptr->old_r_flags5 != r_ptr->r_flags5) ||
137                 (old_race_flags_ptr->old_r_flags6 != r_ptr->r_flags6) ||
138                 (old_race_flags_ptr->old_r_flagsr != r_ptr->r_flagsr) ||
139                 (old_race_flags_ptr->old_r_blows0 != r_ptr->r_blows[0]) ||
140                 (old_race_flags_ptr->old_r_blows1 != r_ptr->r_blows[1]) ||
141                 (old_race_flags_ptr->old_r_blows2 != r_ptr->r_blows[2]) ||
142                 (old_race_flags_ptr->old_r_blows3 != r_ptr->r_blows[3]) ||
143                 (old_race_flags_ptr->old_r_cast_spell != r_ptr->r_cast_spell))
144         {
145                 target_ptr->window |= (PW_MONSTER);
146         }
147 }
148
149 /*!
150  * @brief モンスターの各情報を更新する / This function updates the monster record of the given monster
151  * @param m_idx 更新するモンスター情報のID
152  * @param full プレイヤーとの距離更新を行うならばtrue
153  * @return なし
154  */
155 void update_monster(player_type *subject_ptr, MONSTER_IDX m_idx, bool full)
156 {
157     monster_type *m_ptr = &subject_ptr->current_floor_ptr->m_list[m_idx];
158     monster_race *r_ptr = &r_info[m_ptr->r_idx];
159
160     bool do_disturb = disturb_move;
161
162     POSITION fy = m_ptr->fy;
163     POSITION fx = m_ptr->fx;
164
165     bool flag = FALSE;
166     bool easy = FALSE;
167     bool in_darkness = (d_info[subject_ptr->dungeon_idx].flags1 & DF1_DARKNESS) && !subject_ptr->see_nocto;
168     if (disturb_high) {
169         monster_race *ap_r_ptr = &r_info[m_ptr->ap_r_idx];
170         if (ap_r_ptr->r_tkills && ap_r_ptr->level >= subject_ptr->lev)
171             do_disturb = TRUE;
172     }
173
174     POSITION distance;
175     if (full) {
176         int dy = (subject_ptr->y > fy) ? (subject_ptr->y - fy) : (fy - subject_ptr->y);
177         int dx = (subject_ptr->x > fx) ? (subject_ptr->x - fx) : (fx - subject_ptr->x);
178
179         distance = (dy > dx) ? (dy + (dx >> 1)) : (dx + (dy >> 1));
180         if (distance > 255)
181             distance = 255;
182         if (!distance)
183             distance = 1;
184
185         m_ptr->cdis = distance;
186     } else {
187         distance = m_ptr->cdis;
188     }
189
190     if (m_ptr->mflag2 & (MFLAG2_MARK))
191         flag = TRUE;
192
193     if (distance <= (in_darkness ? MAX_SIGHT / 2 : MAX_SIGHT)) {
194         if (!in_darkness || (distance <= MAX_SIGHT / 4)) {
195             if (subject_ptr->special_defense & KATA_MUSOU) {
196                 flag = TRUE;
197                 if (is_original_ap(m_ptr) && !subject_ptr->image) {
198                     if (r_ptr->flags2 & (RF2_SMART))
199                         r_ptr->r_flags2 |= (RF2_SMART);
200                     if (r_ptr->flags2 & (RF2_STUPID))
201                         r_ptr->r_flags2 |= (RF2_STUPID);
202                 }
203             } else if (subject_ptr->telepathy) {
204                 if (r_ptr->flags2 & (RF2_EMPTY_MIND)) {
205                     if (is_original_ap(m_ptr) && !subject_ptr->image)
206                         r_ptr->r_flags2 |= (RF2_EMPTY_MIND);
207                 } else if (r_ptr->flags2 & (RF2_WEIRD_MIND)) {
208                     if ((m_idx % 10) == 5) {
209                         flag = TRUE;
210                         if (is_original_ap(m_ptr) && !subject_ptr->image) {
211                             r_ptr->r_flags2 |= (RF2_WEIRD_MIND);
212                             if (r_ptr->flags2 & (RF2_SMART))
213                                 r_ptr->r_flags2 |= (RF2_SMART);
214                             if (r_ptr->flags2 & (RF2_STUPID))
215                                 r_ptr->r_flags2 |= (RF2_STUPID);
216                         }
217                     }
218                 } else {
219                     flag = TRUE;
220                     if (is_original_ap(m_ptr) && !subject_ptr->image) {
221                         if (r_ptr->flags2 & (RF2_SMART))
222                             r_ptr->r_flags2 |= (RF2_SMART);
223                         if (r_ptr->flags2 & (RF2_STUPID))
224                             r_ptr->r_flags2 |= (RF2_STUPID);
225                     }
226                 }
227             }
228
229             if ((subject_ptr->esp_animal) && (r_ptr->flags3 & (RF3_ANIMAL))) {
230                 flag = TRUE;
231                 if (is_original_ap(m_ptr) && !subject_ptr->image)
232                     r_ptr->r_flags3 |= (RF3_ANIMAL);
233             }
234
235             if ((subject_ptr->esp_undead) && (r_ptr->flags3 & (RF3_UNDEAD))) {
236                 flag = TRUE;
237                 if (is_original_ap(m_ptr) && !subject_ptr->image)
238                     r_ptr->r_flags3 |= (RF3_UNDEAD);
239             }
240
241             if ((subject_ptr->esp_demon) && (r_ptr->flags3 & (RF3_DEMON))) {
242                 flag = TRUE;
243                 if (is_original_ap(m_ptr) && !subject_ptr->image)
244                     r_ptr->r_flags3 |= (RF3_DEMON);
245             }
246
247             if ((subject_ptr->esp_orc) && (r_ptr->flags3 & (RF3_ORC))) {
248                 flag = TRUE;
249                 if (is_original_ap(m_ptr) && !subject_ptr->image)
250                     r_ptr->r_flags3 |= (RF3_ORC);
251             }
252
253             if ((subject_ptr->esp_troll) && (r_ptr->flags3 & (RF3_TROLL))) {
254                 flag = TRUE;
255                 if (is_original_ap(m_ptr) && !subject_ptr->image)
256                     r_ptr->r_flags3 |= (RF3_TROLL);
257             }
258
259             if ((subject_ptr->esp_giant) && (r_ptr->flags3 & (RF3_GIANT))) {
260                 flag = TRUE;
261                 if (is_original_ap(m_ptr) && !subject_ptr->image)
262                     r_ptr->r_flags3 |= (RF3_GIANT);
263             }
264
265             if ((subject_ptr->esp_dragon) && (r_ptr->flags3 & (RF3_DRAGON))) {
266                 flag = TRUE;
267                 if (is_original_ap(m_ptr) && !subject_ptr->image)
268                     r_ptr->r_flags3 |= (RF3_DRAGON);
269             }
270
271             if ((subject_ptr->esp_human) && (r_ptr->flags2 & (RF2_HUMAN))) {
272                 flag = TRUE;
273                 if (is_original_ap(m_ptr) && !subject_ptr->image)
274                     r_ptr->r_flags2 |= (RF2_HUMAN);
275             }
276
277             if ((subject_ptr->esp_evil) && (r_ptr->flags3 & (RF3_EVIL))) {
278                 flag = TRUE;
279                 if (is_original_ap(m_ptr) && !subject_ptr->image)
280                     r_ptr->r_flags3 |= (RF3_EVIL);
281             }
282
283             if ((subject_ptr->esp_good) && (r_ptr->flags3 & (RF3_GOOD))) {
284                 flag = TRUE;
285                 if (is_original_ap(m_ptr) && !subject_ptr->image)
286                     r_ptr->r_flags3 |= (RF3_GOOD);
287             }
288
289             if ((subject_ptr->esp_nonliving) && ((r_ptr->flags3 & (RF3_DEMON | RF3_UNDEAD | RF3_NONLIVING)) == RF3_NONLIVING)) {
290                 flag = TRUE;
291                 if (is_original_ap(m_ptr) && !subject_ptr->image)
292                     r_ptr->r_flags3 |= (RF3_NONLIVING);
293             }
294
295             if ((subject_ptr->esp_unique) && (r_ptr->flags1 & (RF1_UNIQUE))) {
296                 flag = TRUE;
297                 if (is_original_ap(m_ptr) && !subject_ptr->image)
298                     r_ptr->r_flags1 |= (RF1_UNIQUE);
299             }
300         }
301
302         if (player_has_los_bold(subject_ptr, fy, fx) && !subject_ptr->blind) {
303             bool do_invisible = FALSE;
304             bool do_cold_blood = FALSE;
305
306             if (subject_ptr->concent >= CONCENT_RADAR_THRESHOLD) {
307                 easy = flag = TRUE;
308             }
309
310             if (distance <= subject_ptr->see_infra) {
311                 if ((r_ptr->flags2 & (RF2_COLD_BLOOD | RF2_AURA_FIRE)) == RF2_COLD_BLOOD) {
312                     do_cold_blood = TRUE;
313                 } else {
314                     easy = flag = TRUE;
315                 }
316             }
317
318             if (player_can_see_bold(subject_ptr, fy, fx)) {
319                 if (r_ptr->flags2 & (RF2_INVISIBLE)) {
320                     do_invisible = TRUE;
321                     if (subject_ptr->see_inv) {
322                         easy = flag = TRUE;
323                     }
324                 } else {
325                     easy = flag = TRUE;
326                 }
327             }
328
329             if (flag) {
330                 if (is_original_ap(m_ptr) && !subject_ptr->image) {
331                     if (do_invisible)
332                         r_ptr->r_flags2 |= (RF2_INVISIBLE);
333                     if (do_cold_blood)
334                         r_ptr->r_flags2 |= (RF2_COLD_BLOOD);
335                 }
336             }
337         }
338     }
339
340     /* The monster is now visible */
341     if (flag) {
342         if (!m_ptr->ml) {
343             m_ptr->ml = TRUE;
344             lite_spot(subject_ptr, fy, fx);
345
346             if (subject_ptr->health_who == m_idx)
347                 subject_ptr->redraw |= (PR_HEALTH);
348             if (subject_ptr->riding == m_idx)
349                 subject_ptr->redraw |= (PR_UHEALTH);
350
351             if (!subject_ptr->image) {
352                 if ((m_ptr->ap_r_idx == MON_KAGE) && (r_info[MON_KAGE].r_sights < MAX_SHORT))
353                     r_info[MON_KAGE].r_sights++;
354                 else if (is_original_ap(m_ptr) && (r_ptr->r_sights < MAX_SHORT))
355                     r_ptr->r_sights++;
356             }
357
358             if (r_info[m_ptr->ap_r_idx].flags2 & RF2_ELDRITCH_HORROR) {
359                 sanity_blast(subject_ptr, m_ptr, FALSE);
360             }
361
362             if (disturb_near
363                 && (projectable(subject_ptr, m_ptr->fy, m_ptr->fx, subject_ptr->y, subject_ptr->x)
364                     && projectable(subject_ptr, subject_ptr->y, subject_ptr->x, m_ptr->fy, m_ptr->fx))) {
365                 if (disturb_pets || is_hostile(m_ptr))
366                     disturb(subject_ptr, TRUE, TRUE);
367             }
368         }
369     }
370
371     /* The monster is not visible */
372     else {
373         if (m_ptr->ml) {
374             m_ptr->ml = FALSE;
375             lite_spot(subject_ptr, fy, fx);
376
377             if (subject_ptr->health_who == m_idx)
378                 subject_ptr->redraw |= (PR_HEALTH);
379             if (subject_ptr->riding == m_idx)
380                 subject_ptr->redraw |= (PR_UHEALTH);
381             if (do_disturb) {
382                 if (disturb_pets || is_hostile(m_ptr))
383                     disturb(subject_ptr, TRUE, TRUE);
384             }
385         }
386     }
387
388     /* The monster is now easily visible */
389     if (easy) {
390         if (!(m_ptr->mflag & (MFLAG_VIEW))) {
391             m_ptr->mflag |= (MFLAG_VIEW);
392             if (do_disturb) {
393                 if (disturb_pets || is_hostile(m_ptr))
394                     disturb(subject_ptr, TRUE, TRUE);
395             }
396         }
397
398         return;
399     }
400
401     /* The monster is not easily visible */
402     /* Change */
403     if (!(m_ptr->mflag & (MFLAG_VIEW)))
404         return;
405
406     /* Mark as not easily visible */
407     m_ptr->mflag &= ~(MFLAG_VIEW);
408
409     if (do_disturb) {
410         if (disturb_pets || is_hostile(m_ptr))
411             disturb(subject_ptr, TRUE, TRUE);
412     }
413 }
414
415 /*!
416  * @param player_ptr プレーヤーへの参照ポインタ
417  * @brief 単純に生存している全モンスターの更新処理を行う / This function simply updates all the (non-dead) monsters (see above).
418  * @param full 距離更新を行うならtrue
419  * @return なし
420  */
421 void update_monsters(player_type *player_ptr, bool full)
422 {
423     floor_type *floor_ptr = player_ptr->current_floor_ptr;
424     for (MONSTER_IDX i = 1; i < floor_ptr->m_max; i++) {
425         monster_type *m_ptr = &floor_ptr->m_list[i];
426         if (!monster_is_valid(m_ptr))
427             continue;
428         update_monster(player_ptr, i, full);
429     }
430 }
431
432 /*!
433  * @brief SMART(適格に攻撃を行う)モンスターの学習状況を更新する / Learn about an "observed" resistance.
434  * @param m_idx 更新を行う「モンスター情報ID
435  * @param what 学習対象ID
436  * @return なし
437  */
438 void update_smart_learn(player_type *player_ptr, MONSTER_IDX m_idx, int what)
439 {
440     monster_type *m_ptr = &player_ptr->current_floor_ptr->m_list[m_idx];
441     monster_race *r_ptr = &r_info[m_ptr->r_idx];
442
443     if (!smart_learn)
444         return;
445     if (r_ptr->flags2 & (RF2_STUPID))
446         return;
447     if (!(r_ptr->flags2 & (RF2_SMART)) && (randint0(100) < 50))
448         return;
449
450     switch (what) {
451     case DRS_ACID:
452         if (player_ptr->resist_acid)
453             m_ptr->smart |= (SM_RES_ACID);
454         if (is_oppose_acid(player_ptr))
455             m_ptr->smart |= (SM_OPP_ACID);
456         if (has_immune_acid(player_ptr))
457             m_ptr->smart |= (SM_IMM_ACID);
458         break;
459
460     case DRS_ELEC:
461         if (player_ptr->resist_elec)
462             m_ptr->smart |= (SM_RES_ELEC);
463         if (is_oppose_elec(player_ptr))
464             m_ptr->smart |= (SM_OPP_ELEC);
465         if (has_immune_elec(player_ptr))
466             m_ptr->smart |= (SM_IMM_ELEC);
467         break;
468
469     case DRS_FIRE:
470         if (player_ptr->resist_fire)
471             m_ptr->smart |= (SM_RES_FIRE);
472         if (is_oppose_fire(player_ptr))
473             m_ptr->smart |= (SM_OPP_FIRE);
474         if (has_immune_fire(player_ptr))
475             m_ptr->smart |= (SM_IMM_FIRE);
476         break;
477
478     case DRS_COLD:
479         if (player_ptr->resist_cold)
480             m_ptr->smart |= (SM_RES_COLD);
481         if (is_oppose_cold(player_ptr))
482             m_ptr->smart |= (SM_OPP_COLD);
483         if (has_immune_cold(player_ptr))
484             m_ptr->smart |= (SM_IMM_COLD);
485         break;
486
487     case DRS_POIS:
488         if (player_ptr->resist_pois)
489             m_ptr->smart |= (SM_RES_POIS);
490         if (is_oppose_pois(player_ptr))
491             m_ptr->smart |= (SM_OPP_POIS);
492         break;
493
494     case DRS_NETH:
495         if (player_ptr->resist_neth)
496             m_ptr->smart |= (SM_RES_NETH);
497         break;
498
499     case DRS_LITE:
500         if (player_ptr->resist_lite)
501             m_ptr->smart |= (SM_RES_LITE);
502         break;
503
504     case DRS_DARK:
505         if (player_ptr->resist_dark)
506             m_ptr->smart |= (SM_RES_DARK);
507         break;
508
509     case DRS_FEAR:
510         if (player_ptr->resist_fear)
511             m_ptr->smart |= (SM_RES_FEAR);
512         break;
513
514     case DRS_CONF:
515         if (player_ptr->resist_conf)
516             m_ptr->smart |= (SM_RES_CONF);
517         break;
518
519     case DRS_CHAOS:
520         if (player_ptr->resist_chaos)
521             m_ptr->smart |= (SM_RES_CHAOS);
522         break;
523
524     case DRS_DISEN:
525         if (player_ptr->resist_disen)
526             m_ptr->smart |= (SM_RES_DISEN);
527         break;
528
529     case DRS_BLIND:
530         if (player_ptr->resist_blind)
531             m_ptr->smart |= (SM_RES_BLIND);
532         break;
533
534     case DRS_NEXUS:
535         if (player_ptr->resist_nexus)
536             m_ptr->smart |= (SM_RES_NEXUS);
537         break;
538
539     case DRS_SOUND:
540         if (player_ptr->resist_sound)
541             m_ptr->smart |= (SM_RES_SOUND);
542         break;
543
544     case DRS_SHARD:
545         if (player_ptr->resist_shard)
546             m_ptr->smart |= (SM_RES_SHARD);
547         break;
548
549     case DRS_FREE:
550         if (player_ptr->free_act)
551             m_ptr->smart |= (SM_IMM_FREE);
552         break;
553
554     case DRS_MANA:
555         if (!player_ptr->msp)
556             m_ptr->smart |= (SM_IMM_MANA);
557         break;
558
559     case DRS_REFLECT:
560         if (player_ptr->reflect)
561             m_ptr->smart |= (SM_IMM_REFLECT);
562         break;
563     }
564 }