OSDN Git Service

[Refactor] #40030 Moved *_door() from monster-process.c to monster-move.c/h
[hengband/hengband.git] / src / monster-process.c
1 /*!
2  * @file monster-process.c
3  * @brief モンスターの特殊技能とターン経過処理 (移動等)/ Monster spells and movement for passaging a turn
4  * @date 2014/01/17
5  * @author
6  * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke\n
7  * This software may be copied and distributed for educational, research,\n
8  * and not for profit purposes provided that this copyright and statement\n
9  * are included in all such copies.  Other copyrights may also apply.\n
10  * 2014 Deskull rearranged comment for Doxygen.\n
11  * @details
12  * This file has several additions to it by Keldon Jones (keldon@umr.edu)
13  * to improve the general quality of the AI (version 0.1.1).
14  */
15
16 #include "angband.h"
17 #include "util.h"
18 #include "monster/monster-attack.h"
19 #include "monster/monster-object.h"
20 #include "monster/monster-move.h"
21 #include "monster/monster-util.h"
22 #include "monster/quantum-effect.h"
23
24 #include "cmd-dump.h"
25 #include "cmd-pet.h"
26 #include "creature.h"
27 #include "melee.h"
28 #include "spells.h"
29 #include "spells-floor.h"
30 #include "spells-summon.h"
31 #include "quest.h"
32 #include "avatar.h"
33 #include "realm-hex.h"
34 #include "feature.h"
35 #include "grid.h"
36 #include "player-move.h"
37 #include "monster-status.h"
38 #include "monster-spell.h"
39 #include "monster-process.h"
40 #include "monster-dist-offsets.h"
41 #include "monsterrace-hook.h"
42 #include "floor.h"
43 #include "files.h"
44 #include "view-mainwindow.h"
45
46 bool get_enemy_dir(player_type *target_ptr, MONSTER_IDX m_idx, int *mm);
47 void decide_enemy_approch_direction(player_type *target_ptr, MONSTER_IDX m_idx, int start, int plus, POSITION *y, POSITION *x);
48 bool decide_pet_approch_direction(player_type *target_ptr, monster_type *m_ptr, monster_type *t_ptr);
49
50 bool find_safety(player_type *target_ptr, MONSTER_IDX m_idx, POSITION *yp, POSITION *xp);
51 coordinate_candidate sweep_safe_coordinate(player_type *target_ptr, MONSTER_IDX m_idx, const POSITION *y_offsets, const POSITION *x_offsets, int d);
52
53 bool find_hiding(player_type *target_ptr, MONSTER_IDX m_idx, POSITION *yp, POSITION *xp);
54 void sweep_hiding_candidate(player_type *target_ptr, monster_type *m_ptr, const POSITION *y_offsets, const POSITION *x_offsets, coordinate_candidate *candidate);
55
56 void decide_drop_from_monster(player_type *target_ptr, MONSTER_IDX m_idx, bool is_riding_mon);
57 bool process_stealth(player_type *target_ptr, MONSTER_IDX m_idx);
58 bool vanish_summoned_children(player_type *target_ptr, MONSTER_IDX m_idx, bool see_m);
59 void awake_monster(player_type *target_ptr, MONSTER_IDX m_idx);
60 void process_angar(player_type *target_ptr, MONSTER_IDX m_idx, bool see_m);
61 bool explode_grenade(player_type *target_ptr, MONSTER_IDX m_idx);
62 bool decide_monster_multiplication(player_type *target_ptr, MONSTER_IDX m_idx, POSITION oy, POSITION ox);
63 bool decide_monster_movement_direction(player_type *target_ptr, DIRECTION *mm, MONSTER_IDX m_idx, bool aware);
64 bool random_walk(player_type *target_ptr, DIRECTION *mm, monster_type *m_ptr);
65 bool decide_pet_movement_direction(player_type *target_ptr, DIRECTION *mm, MONSTER_IDX m_idx);
66 bool runaway_monster(player_type *target_ptr, turn_flags *turn_flags_ptr, MONSTER_IDX m_idx);
67 void escape_monster(player_type *target_ptr, turn_flags *turn_flags_ptr, monster_type *m_ptr, GAME_TEXT *m_name);
68 void process_special(player_type *target_ptr, MONSTER_IDX m_idx);
69 void process_speak_sound(player_type *target_ptr, MONSTER_IDX m_idx, POSITION oy, POSITION ox, bool aware);
70 bool cast_spell(player_type *target_ptr, MONSTER_IDX m_idx, bool aware);
71
72 bool process_monster_movement(player_type *target_ptr, turn_flags *turn_flags_ptr, MONSTER_IDX m_idx, DIRECTION *mm, POSITION oy, POSITION ox, int *count);
73 bool process_post_dig_wall(player_type *target_ptr, turn_flags *turn_flags_ptr, monster_type *m_ptr, POSITION ny, POSITION nx);
74 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);
75
76 void update_player_type(player_type *target_ptr, turn_flags *turn_flags_ptr, monster_race *r_ptr);
77 void update_monster_race_flags(player_type *target_ptr, turn_flags *turn_flags_ptr, monster_type *m_ptr);
78 bool process_monster_fear(player_type *target_ptr, turn_flags *turn_flags_ptr, MONSTER_IDX m_idx);
79
80 void sweep_monster_process(player_type *target_ptr);
81 bool decide_process_continue(player_type *target_ptr, monster_type *m_ptr);
82
83 /*!
84  * @brief モンスターが敵に接近するための方向を計算するメインルーチン
85  * Calculate the direction to the next enemy
86  * @param target_ptr プレーヤーへの参照ポインタ
87  * @param m_idx モンスターの参照ID
88  * @param mm 移動するべき方角IDを返す参照ポインタ
89  * @return 方向が確定した場合TRUE、接近する敵がそもそもいない場合FALSEを返す
90  */
91 bool get_enemy_dir(player_type *target_ptr, MONSTER_IDX m_idx, int *mm)
92 {
93         floor_type *floor_ptr = target_ptr->current_floor_ptr;
94         monster_type *m_ptr = &floor_ptr->m_list[m_idx];
95
96         POSITION x = 0, y = 0;
97         if (target_ptr->riding_t_m_idx && player_bold(target_ptr, m_ptr->fy, m_ptr->fx))
98         {
99                 y = floor_ptr->m_list[target_ptr->riding_t_m_idx].fy;
100                 x = floor_ptr->m_list[target_ptr->riding_t_m_idx].fx;
101         }
102         else if (is_pet(m_ptr) && target_ptr->pet_t_m_idx)
103         {
104                 y = floor_ptr->m_list[target_ptr->pet_t_m_idx].fy;
105                 x = floor_ptr->m_list[target_ptr->pet_t_m_idx].fx;
106         }
107         else
108         {
109                 int start;
110                 int plus = 1;
111                 if (target_ptr->phase_out)
112                 {
113                         start = randint1(floor_ptr->m_max - 1) + floor_ptr->m_max;
114                         if (randint0(2)) plus = -1;
115                 }
116                 else
117                 {
118                         start = floor_ptr->m_max + 1;
119                 }
120
121                 decide_enemy_approch_direction(target_ptr, m_idx, start, plus, &y, &x);
122
123                 if ((x == 0) && (y == 0)) return FALSE;
124         }
125
126         x -= m_ptr->fx;
127         y -= m_ptr->fy;
128
129         store_enemy_approch_direction(mm, y, x);
130         return TRUE;
131 }
132
133
134 /*!
135  * @brief モンスターが敵に接近するための方向を決定する
136  * @param target_ptr プレーヤーへの参照ポインタ
137  * @param m_idx モンスターID
138  * @param start モンスターIDの開始
139  * @param plus モンスターIDの増減 (1/2 の確率で+1、1/2の確率で-1)
140  * @param y モンスターの移動方向Y
141  * @param x モンスターの移動方向X
142  * @return なし
143  */
144 void decide_enemy_approch_direction(player_type *target_ptr, MONSTER_IDX m_idx, int start, int plus, POSITION *y, POSITION *x)
145 {
146         floor_type *floor_ptr = target_ptr->current_floor_ptr;
147         monster_type *m_ptr = &floor_ptr->m_list[m_idx];
148         monster_race *r_ptr = &r_info[m_ptr->r_idx];
149         for (int i = start; ((i < start + floor_ptr->m_max) && (i > start - floor_ptr->m_max)); i += plus)
150         {
151                 MONSTER_IDX dummy = (i % floor_ptr->m_max);
152                 if (dummy == 0) continue;
153
154                 MONSTER_IDX t_idx = dummy;
155                 monster_type *t_ptr;
156                 t_ptr = &floor_ptr->m_list[t_idx];
157                 if (t_ptr == m_ptr) continue;
158                 if (!monster_is_valid(t_ptr)) continue;
159                 if (decide_pet_approch_direction(target_ptr, m_ptr, t_ptr)) continue;
160                 if (!are_enemies(target_ptr, m_ptr, t_ptr)) continue;
161
162                 if (((r_ptr->flags2 & RF2_PASS_WALL) && ((m_idx != target_ptr->riding) || target_ptr->pass_wall)) ||
163                         ((r_ptr->flags2 & RF2_KILL_WALL) && (m_idx != target_ptr->riding)))
164                 {
165                         if (!in_disintegration_range(floor_ptr, m_ptr->fy, m_ptr->fx, t_ptr->fy, t_ptr->fx)) continue;
166                 }
167                 else
168                 {
169                         if (!projectable(target_ptr, m_ptr->fy, m_ptr->fx, t_ptr->fy, t_ptr->fx)) continue;
170                 }
171
172                 *y = t_ptr->fy;
173                 *x = t_ptr->fx;
174                 return;
175         }
176 }
177
178
179 /*!
180  * @brief ペットが敵に接近するための方向を決定する
181  * @param target_ptr プレーヤーへの参照ポインタ
182  * @param m_ptr 移動を試みているモンスターへの参照ポインタ
183  * @param t_ptr 移動先モンスターへの参照ポインタ
184  * @param plus モンスターIDの増減 (1/2 の確率で+1、1/2の確率で-1)
185  * @return ペットがモンスターに近づくならばTRUE
186  */
187 bool decide_pet_approch_direction(player_type *target_ptr, monster_type *m_ptr, monster_type *t_ptr)
188 {
189         monster_race *r_ptr = &r_info[m_ptr->r_idx];
190         if (!is_pet(m_ptr)) return FALSE;
191
192         if (target_ptr->pet_follow_distance < 0)
193         {
194                 if (t_ptr->cdis <= (0 - target_ptr->pet_follow_distance))
195                 {
196                         return TRUE;
197                 }
198         }
199         else if ((m_ptr->cdis < t_ptr->cdis) && (t_ptr->cdis > target_ptr->pet_follow_distance))
200         {
201                 return TRUE;
202         }
203
204         return (r_ptr->aaf < t_ptr->cdis);
205 }
206
207
208 /*!
209  * @brief モンスターがプレイヤーから逃走するかどうかを返す /
210  * Returns whether a given monster will try to run from the player.
211  * @param m_idx 逃走するモンスターの参照ID
212  * @return モンスターがプレイヤーから逃走するならばTRUEを返す。
213  * @details
214  * Monsters will attempt to avoid very powerful players.  See below.\n
215  *\n
216  * Because this function is called so often, little details are important\n
217  * for efficiency.  Like not using "mod" or "div" when possible.  And\n
218  * attempting to check the conditions in an optimal order.  Note that\n
219  * "(x << 2) == (x * 4)" if "x" has enough bits to hold the result.\n
220  *\n
221  * Note that this function is responsible for about one to five percent\n
222  * of the processor use in normal conditions...\n
223  */
224 static bool mon_will_run(player_type *target_ptr, MONSTER_IDX m_idx)
225 {
226         monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
227         monster_race *r_ptr = &r_info[m_ptr->r_idx];
228
229         if (is_pet(m_ptr))
230         {
231                 return ((target_ptr->pet_follow_distance < 0) &&
232                         (m_ptr->cdis <= (0 - target_ptr->pet_follow_distance)));
233         }
234
235         if (m_ptr->cdis > MAX_SIGHT + 5) return FALSE;
236         if (MON_MONFEAR(m_ptr)) return TRUE;
237         if (m_ptr->cdis <= 5) return FALSE;
238
239         PLAYER_LEVEL p_lev = target_ptr->lev;
240         DEPTH m_lev = r_ptr->level + (m_idx & 0x08) + 25;
241         if (m_lev > p_lev + 4) return FALSE;
242         if (m_lev + 4 <= p_lev) return TRUE;
243
244         HIT_POINT p_chp = target_ptr->chp;
245         HIT_POINT p_mhp = target_ptr->mhp;
246         HIT_POINT m_chp = m_ptr->hp;
247         HIT_POINT m_mhp = m_ptr->maxhp;
248         u32b p_val = (p_lev * p_mhp) + (p_chp << 2);
249         u32b m_val = (m_lev * m_mhp) + (m_chp << 2);
250         if (p_val * m_mhp > m_val * p_mhp) return TRUE;
251
252         return FALSE;
253 }
254
255
256 /*!
257  * @brief モンスターがプレイヤーに向けて遠距離攻撃を行うことが可能なマスを走査する /
258  * Search spell castable grid
259  * @param target_ptr プレーヤーへの参照ポインタ
260  * @param m_idx モンスターの参照ID
261  * @param yp 適したマスのY座標を返す参照ポインタ
262  * @param xp 適したマスのX座標を返す参照ポインタ
263  * @return 有効なマスがあった場合TRUEを返す
264  */
265 static bool get_moves_aux2(player_type *target_ptr, MONSTER_IDX m_idx, POSITION *yp, POSITION *xp)
266 {
267         floor_type *floor_ptr = target_ptr->current_floor_ptr;
268         monster_type *m_ptr = &floor_ptr->m_list[m_idx];
269         monster_race *r_ptr = &r_info[m_ptr->r_idx];
270
271         POSITION y1 = m_ptr->fy;
272         POSITION x1 = m_ptr->fx;
273
274         if (projectable(target_ptr, y1, x1, target_ptr->y, target_ptr->x)) return FALSE;
275
276         int now_cost = floor_ptr->grid_array[y1][x1].cost;
277         if (now_cost == 0) now_cost = 999;
278
279         bool can_open_door = FALSE;
280         if (r_ptr->flags2 & (RF2_BASH_DOOR | RF2_OPEN_DOOR))
281         {
282                 can_open_door = TRUE;
283         }
284
285         int best = 999;
286         for (int i = 7; i >= 0; i--)
287         {
288                 POSITION y = y1 + ddy_ddd[i];
289                 POSITION x = x1 + ddx_ddd[i];
290                 if (!in_bounds2(floor_ptr, y, x)) continue;
291                 if (player_bold(target_ptr, y, x)) return FALSE;
292
293                 grid_type *g_ptr;
294                 g_ptr = &floor_ptr->grid_array[y][x];
295                 int cost = g_ptr->cost;
296                 if (!(((r_ptr->flags2 & RF2_PASS_WALL) && ((m_idx != target_ptr->riding) || target_ptr->pass_wall)) || ((r_ptr->flags2 & RF2_KILL_WALL) && (m_idx != target_ptr->riding))))
297                 {
298                         if (cost == 0) continue;
299                         if (!can_open_door && is_closed_door(target_ptr, g_ptr->feat)) continue;
300                 }
301
302                 if (cost == 0) cost = 998;
303
304                 if (now_cost < cost) continue;
305                 if (!projectable(target_ptr, y, x, target_ptr->y, target_ptr->x)) continue;
306                 if (best < cost) continue;
307
308                 best = cost;
309                 *yp = y1 + ddy_ddd[i];
310                 *xp = x1 + ddx_ddd[i];
311         }
312
313         if (best == 999) return FALSE;
314
315         return TRUE;
316 }
317
318
319 /*!
320  * @brief モンスターがプレイヤーに向けて接近することが可能なマスを走査する /
321  * Choose the "best" direction for "flowing"
322  * @param m_idx モンスターの参照ID
323  * @param yp 移動先のマスのY座標を返す参照ポインタ
324  * @param xp 移動先のマスのX座標を返す参照ポインタ
325  * @param no_flow モンスターにFLOWフラグが経っていない状態でTRUE
326  * @return 有効なマスがあった場合TRUEを返す
327  * @details
328  * Note that ghosts and rock-eaters are never allowed to "flow",\n
329  * since they should move directly towards the player.\n
330  *\n
331  * Prefer "non-diagonal" directions, but twiddle them a little\n
332  * to angle slightly towards the player's actual location.\n
333  *\n
334  * Allow very perceptive monsters to track old "spoor" left by\n
335  * previous locations occupied by the player.  This will tend\n
336  * to have monsters end up either near the player or on a grid\n
337  * recently occupied by the player (and left via "teleport").\n
338  *\n
339  * Note that if "smell" is turned on, all monsters get vicious.\n
340  *\n
341  * Also note that teleporting away from a location will cause\n
342  * the monsters who were chasing you to converge on that location\n
343  * as long as you are still near enough to "annoy" them without\n
344  * being close enough to chase directly.  I have no idea what will\n
345  * happen if you combine "smell" with low "aaf" values.\n
346  */
347 static bool get_moves_aux(player_type *target_ptr, MONSTER_IDX m_idx, POSITION *yp, POSITION *xp, bool no_flow)
348 {
349         grid_type *g_ptr;
350         floor_type *floor_ptr = target_ptr->current_floor_ptr;
351         monster_type *m_ptr = &floor_ptr->m_list[m_idx];
352         monster_race *r_ptr = &r_info[m_ptr->r_idx];
353
354         if (r_ptr->flags4 & (RF4_ATTACK_MASK) ||
355                 r_ptr->a_ability_flags1 & (RF5_ATTACK_MASK) ||
356                 r_ptr->a_ability_flags2 & (RF6_ATTACK_MASK))
357         {
358                 if (get_moves_aux2(target_ptr, m_idx, yp, xp)) return TRUE;
359         }
360
361         if (no_flow) return FALSE;
362         if ((r_ptr->flags2 & RF2_PASS_WALL) && ((m_idx != target_ptr->riding) || target_ptr->pass_wall)) return FALSE;
363         if ((r_ptr->flags2 & RF2_KILL_WALL) && (m_idx != target_ptr->riding)) return FALSE;
364
365         POSITION y1 = m_ptr->fy;
366         POSITION x1 = m_ptr->fx;
367         if (player_has_los_bold(target_ptr, y1, x1) && projectable(target_ptr, target_ptr->y, target_ptr->x, y1, x1)) return FALSE;
368
369         g_ptr = &floor_ptr->grid_array[y1][x1];
370
371         int best;
372         bool use_scent = FALSE;
373         if (g_ptr->cost)
374         {
375                 best = 999;
376         }
377         else if (g_ptr->when)
378         {
379                 if (floor_ptr->grid_array[target_ptr->y][target_ptr->x].when - g_ptr->when > 127) return FALSE;
380
381                 use_scent = TRUE;
382                 best = 0;
383         }
384         else
385         {
386                 return FALSE;
387         }
388
389         for (int i = 7; i >= 0; i--)
390         {
391                 POSITION y = y1 + ddy_ddd[i];
392                 POSITION x = x1 + ddx_ddd[i];
393
394                 if (!in_bounds2(floor_ptr, y, x)) continue;
395
396                 g_ptr = &floor_ptr->grid_array[y][x];
397                 if (use_scent)
398                 {
399                         int when = g_ptr->when;
400                         if (best > when) continue;
401
402                         best = when;
403                 }
404                 else
405                 {
406                         int cost;
407                         if (r_ptr->flags2 & (RF2_BASH_DOOR | RF2_OPEN_DOOR))
408                         {
409                                 cost = g_ptr->dist;
410                         }
411                         else
412                         {
413                                 cost = g_ptr->cost;
414                         }
415
416                         if ((cost == 0) || (best < cost)) continue;
417
418                         best = cost;
419                 }
420
421                 *yp = target_ptr->y + 16 * ddy_ddd[i];
422                 *xp = target_ptr->x + 16 * ddx_ddd[i];
423         }
424
425         if (best == 999 || best == 0) return FALSE;
426
427         return TRUE;
428 }
429
430
431 /*!
432  * @brief モンスターがプレイヤーから逃走することが可能なマスを走査する /
433  * Provide a location to flee to, but give the player a wide berth.
434  * @param m_idx モンスターの参照ID
435  * @param yp 移動先のマスのY座標を返す参照ポインタ
436  * @param xp 移動先のマスのX座標を返す参照ポインタ
437  * @return 有効なマスがあった場合TRUEを返す
438  * @details
439  * A monster may wish to flee to a location that is behind the player,\n
440  * but instead of heading directly for it, the monster should "swerve"\n
441  * around the player so that he has a smaller chance of getting hit.\n
442  */
443 static bool get_fear_moves_aux(floor_type *floor_ptr, MONSTER_IDX m_idx, POSITION *yp, POSITION *xp)
444 {
445         POSITION gy = 0, gx = 0;
446
447         monster_type *m_ptr = &floor_ptr->m_list[m_idx];
448         POSITION fy = m_ptr->fy;
449         POSITION fx = m_ptr->fx;
450
451         POSITION y1 = fy - (*yp);
452         POSITION x1 = fx - (*xp);
453
454         int score = -1;
455         for (int i = 7; i >= 0; i--)
456         {
457                 POSITION y = fy + ddy_ddd[i];
458                 POSITION x = fx + ddx_ddd[i];
459                 if (!in_bounds2(floor_ptr, y, x)) continue;
460
461                 POSITION dis = distance(y, x, y1, x1);
462                 POSITION s = 5000 / (dis + 3) - 500 / (floor_ptr->grid_array[y][x].dist + 1);
463                 if (s < 0) s = 0;
464
465                 if (s < score) continue;
466
467                 score = s;
468                 gy = y;
469                 gx = x;
470         }
471
472         if (score == -1) return FALSE;
473
474         (*yp) = fy - gy;
475         (*xp) = fx - gx;
476
477         return TRUE;
478 }
479
480
481 /*!
482  * @brief モンスターが逃げ込める安全な地点を返す /
483  * Choose a "safe" location near a monster for it to run toward.
484  * @param target_ptr プレーヤーへの参照ポインタ
485  * @param m_idx モンスターの参照ID
486  * @param yp 移動先のマスのY座標を返す参照ポインタ
487  * @param xp 移動先のマスのX座標を返す参照ポインタ
488  * @return 有効なマスがあった場合TRUEを返す
489  * @details
490  * A location is "safe" if it can be reached quickly and the player\n
491  * is not able to fire into it (it isn't a "clean shot").  So, this will\n
492  * cause monsters to "duck" behind walls.  Hopefully, monsters will also\n
493  * try to run towards corridor openings if they are in a room.\n
494  *\n
495  * This function may take lots of CPU time if lots of monsters are\n
496  * fleeing.\n
497  *\n
498  * Return TRUE if a safe location is available.\n
499  */
500 bool find_safety(player_type *target_ptr, MONSTER_IDX m_idx, POSITION *yp, POSITION *xp)
501 {
502         monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
503         for (POSITION d = 1; d < 10; d++)
504         {
505                 const POSITION *y_offsets;
506                 y_offsets = dist_offsets_y[d];
507
508                 const POSITION *x_offsets;
509                 x_offsets = dist_offsets_x[d];
510
511                 coordinate_candidate candidate = sweep_safe_coordinate(target_ptr, m_idx, y_offsets, x_offsets, d);
512
513                 if (candidate.gdis <= 0) continue;
514
515                 *yp = m_ptr->fy - candidate.gy;
516                 *xp = m_ptr->fx - candidate.gx;
517
518                 return TRUE;
519         }
520
521         return FALSE;
522 }
523
524
525 /*!
526  * @brief モンスターが逃げ込める地点を走査する
527  * @param target_ptr プレーヤーへの参照ポインタ
528  * @param m_idx モンスターID
529  * @param y_offsets
530  * @param x_offsets
531  * @param d モンスターがいる地点からの距離
532  * @return 逃げ込める地点の候補地
533  */
534 coordinate_candidate sweep_safe_coordinate(player_type *target_ptr, MONSTER_IDX m_idx, const POSITION *y_offsets, const POSITION *x_offsets, int d)
535 {
536         coordinate_candidate candidate = init_coordinate_candidate();
537         floor_type *floor_ptr = target_ptr->current_floor_ptr;
538         monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
539         for (POSITION i = 0, dx = x_offsets[0], dy = y_offsets[0];
540                 dx != 0 || dy != 0;
541                 i++, dx = x_offsets[i], dy = y_offsets[i])
542         {
543                 POSITION y = m_ptr->fy + dy;
544                 POSITION x = m_ptr->fx + dx;
545                 if (!in_bounds(floor_ptr, y, x)) continue;
546
547                 grid_type *g_ptr;
548                 g_ptr = &floor_ptr->grid_array[y][x];
549
550                 BIT_FLAGS16 riding_mode = (m_idx == target_ptr->riding) ? CEM_RIDING : 0;
551                 if (!monster_can_cross_terrain(target_ptr, g_ptr->feat, &r_info[m_ptr->r_idx], riding_mode))
552                         continue;
553
554                 if (!(m_ptr->mflag2 & MFLAG2_NOFLOW))
555                 {
556                         if (g_ptr->dist == 0) continue;
557                         if (g_ptr->dist > floor_ptr->grid_array[m_ptr->fy][m_ptr->fx].dist + 2 * d) continue;
558                 }
559
560                 if (projectable(target_ptr, target_ptr->y, target_ptr->x, y, x)) continue;
561
562                 POSITION dis = distance(y, x, target_ptr->y, target_ptr->x);
563                 if (dis <= candidate.gdis) continue;
564
565                 candidate.gy = y;
566                 candidate.gx = x;
567                 candidate.gdis = dis;
568         }
569
570         return candidate;
571 }
572
573
574 /*!
575  * @brief モンスターが隠れ潜める地点を返す /
576  * Choose a good hiding place near a monster for it to run toward.
577  * @param target_ptr プレーヤーへの参照ポインタ
578  * @param m_idx モンスターの参照ID
579  * @param yp 移動先のマスのY座標を返す参照ポインタ
580  * @param xp 移動先のマスのX座標を返す参照ポインタ
581  * @return 有効なマスがあった場合TRUEを返す
582  * @details
583  * Pack monsters will use this to "ambush" the player and lure him out\n
584  * of corridors into open space so they can swarm him.\n
585  *\n
586  * Return TRUE if a good location is available.\n
587  */
588 bool find_hiding(player_type *target_ptr, MONSTER_IDX m_idx, POSITION *yp, POSITION *xp)
589 {
590         monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
591         coordinate_candidate candidate = init_coordinate_candidate();
592         candidate.gdis = 999;
593
594         for (POSITION d = 1; d < 10; d++)
595         {
596                 const POSITION *y_offsets;
597                 y_offsets = dist_offsets_y[d];
598
599                 const POSITION *x_offsets;
600                 x_offsets = dist_offsets_x[d];
601
602                 sweep_hiding_candidate(target_ptr, m_ptr, y_offsets, x_offsets, &candidate);
603                 if (candidate.gdis >= 999) continue;
604
605                 *yp = m_ptr->fy - candidate.gy;
606                 *xp = m_ptr->fx - candidate.gx;
607                 return TRUE;
608         }
609
610         return FALSE;
611 }
612
613
614 /*!
615  * @brief モンスターが隠れられる地点を走査する
616  * @param target_ptr プレーヤーへの参照ポインタ
617  * @param m_idx モンスターID
618  * @param y_offsets
619  * @param x_offsets
620  * @param candidate 隠れられる地点の候補地
621  * @return なし
622  */
623 void sweep_hiding_candidate(player_type *target_ptr, monster_type *m_ptr, const POSITION *y_offsets, const POSITION *x_offsets, coordinate_candidate *candidate)
624 {
625         monster_race *r_ptr = &r_info[m_ptr->r_idx];
626         for (POSITION i = 0, dx = x_offsets[0], dy = y_offsets[0];
627                 dx != 0 || dy != 0;
628                 i++, dx = x_offsets[i], dy = y_offsets[i])
629         {
630                 POSITION y = m_ptr->fy + dy;
631                 POSITION x = m_ptr->fx + dx;
632                 if (!in_bounds(target_ptr->current_floor_ptr, y, x)) continue;
633                 if (!monster_can_enter(target_ptr, y, x, r_ptr, 0)) continue;
634                 if (projectable(target_ptr, target_ptr->y, target_ptr->x, y, x) && clean_shot(target_ptr, m_ptr->fy, m_ptr->fx, y, x, FALSE))
635                         continue;
636
637                 POSITION dis = distance(y, x, target_ptr->y, target_ptr->x);
638                 if (dis < candidate->gdis && dis >= 2)
639                 {
640                         candidate->gy = y;
641                         candidate->gx = x;
642                         candidate->gdis = dis;
643                 }
644         }
645 }
646
647
648 /*!
649  * todo 分割したいが条件が多すぎて適切な関数名と詳細処理を追いきれない……
650  * @brief モンスターの移動方向を返す /
651  * Choose "logical" directions for monster movement
652  * @param target_ptr プレーヤーへの参照ポインタ
653  * @param m_idx モンスターの参照ID
654  * @param mm 移動方向を返す方向IDの参照ポインタ
655  * @return 有効方向があった場合TRUEを返す
656  */
657 static bool get_moves(player_type *target_ptr, MONSTER_IDX m_idx, DIRECTION *mm)
658 {
659         floor_type *floor_ptr = target_ptr->current_floor_ptr;
660         monster_type *m_ptr = &floor_ptr->m_list[m_idx];
661         monster_race *r_ptr = &r_info[m_ptr->r_idx];
662         POSITION y = 0, ay, x = 0, ax;
663         POSITION y2 = target_ptr->y;
664         POSITION x2 = target_ptr->x;
665         bool done = FALSE;
666         bool will_run = mon_will_run(target_ptr, m_idx);
667         grid_type *g_ptr;
668         bool no_flow = ((m_ptr->mflag2 & MFLAG2_NOFLOW) != 0) && (floor_ptr->grid_array[m_ptr->fy][m_ptr->fx].cost > 2);
669         bool can_pass_wall = ((r_ptr->flags2 & RF2_PASS_WALL) != 0) && ((m_idx != target_ptr->riding) || target_ptr->pass_wall);
670
671         if (!will_run && m_ptr->target_y)
672         {
673                 int t_m_idx = floor_ptr->grid_array[m_ptr->target_y][m_ptr->target_x].m_idx;
674                 if ((t_m_idx > 0) &&
675                         are_enemies(target_ptr, m_ptr, &floor_ptr->m_list[t_m_idx]) &&
676                         los(target_ptr, m_ptr->fy, m_ptr->fx, m_ptr->target_y, m_ptr->target_x) &&
677                         projectable(target_ptr, m_ptr->fy, m_ptr->fx, m_ptr->target_y, m_ptr->target_x))
678                 {
679                         y = m_ptr->fy - m_ptr->target_y;
680                         x = m_ptr->fx - m_ptr->target_x;
681                         done = TRUE;
682                 }
683         }
684
685         if (!done && !will_run && is_hostile(m_ptr) &&
686                 (r_ptr->flags1 & RF1_FRIENDS) &&
687                 ((los(target_ptr, m_ptr->fy, m_ptr->fx, target_ptr->y, target_ptr->x) && projectable(target_ptr, m_ptr->fy, m_ptr->fx, target_ptr->y, target_ptr->x)) ||
688                 (floor_ptr->grid_array[m_ptr->fy][m_ptr->fx].dist < MAX_SIGHT / 2)))
689         {
690                 if ((r_ptr->flags3 & RF3_ANIMAL) && !can_pass_wall &&
691                         !(r_ptr->flags2 & RF2_KILL_WALL))
692                 {
693                         int room = 0;
694                         for (int i = 0; i < 8; i++)
695                         {
696                                 int xx = target_ptr->x + ddx_ddd[i];
697                                 int yy = target_ptr->y + ddy_ddd[i];
698
699                                 if (!in_bounds2(floor_ptr, yy, xx)) continue;
700
701                                 g_ptr = &floor_ptr->grid_array[yy][xx];
702                                 if (monster_can_cross_terrain(target_ptr, g_ptr->feat, r_ptr, 0))
703                                 {
704                                         room++;
705                                 }
706                         }
707
708                         if (floor_ptr->grid_array[target_ptr->y][target_ptr->x].info & CAVE_ROOM) room -= 2;
709                         if (!r_ptr->flags4 && !r_ptr->a_ability_flags1 && !r_ptr->a_ability_flags2) room -= 2;
710
711                         if (room < (8 * (target_ptr->chp + target_ptr->csp)) /
712                                 (target_ptr->mhp + target_ptr->msp))
713                         {
714                                 if (find_hiding(target_ptr, m_idx, &y, &x)) done = TRUE;
715                         }
716                 }
717
718                 if (!done && (floor_ptr->grid_array[m_ptr->fy][m_ptr->fx].dist < 3))
719                 {
720                         for (int i = 0; i < 8; i++)
721                         {
722                                 y2 = target_ptr->y + ddy_ddd[(m_idx + i) & 7];
723                                 x2 = target_ptr->x + ddx_ddd[(m_idx + i) & 7];
724                                 if ((m_ptr->fy == y2) && (m_ptr->fx == x2))
725                                 {
726                                         y2 = target_ptr->y;
727                                         x2 = target_ptr->x;
728                                         break;
729                                 }
730
731                                 if (!in_bounds2(floor_ptr, y2, x2)) continue;
732                                 if (!monster_can_enter(target_ptr, y2, x2, r_ptr, 0)) continue;
733
734                                 break;
735                         }
736
737                         y = m_ptr->fy - y2;
738                         x = m_ptr->fx - x2;
739                         done = TRUE;
740                 }
741         }
742
743         if (!done)
744         {
745                 (void)get_moves_aux(target_ptr, m_idx, &y2, &x2, no_flow);
746                 y = m_ptr->fy - y2;
747                 x = m_ptr->fx - x2;
748         }
749
750         if (is_pet(m_ptr) && will_run)
751         {
752                 y = (-y), x = (-x);
753         }
754         else
755         {
756                 if (!done && will_run)
757                 {
758                         int tmp_x = (-x);
759                         int tmp_y = (-y);
760                         if (find_safety(target_ptr, m_idx, &y, &x) && !no_flow)
761                         {
762                                 if (get_fear_moves_aux(target_ptr->current_floor_ptr, m_idx, &y, &x))
763                                         done = TRUE;
764                         }
765
766                         if (!done)
767                         {
768                                 y = tmp_y;
769                                 x = tmp_x;
770                         }
771                 }
772         }
773
774         if (!x && !y) return FALSE;
775
776         ax = ABS(x);
777         ay = ABS(y);
778
779         int move_val = 0;
780         if (y < 0) move_val += 8;
781         if (x > 0) move_val += 4;
782
783         if (ay > (ax << 1)) move_val += 2;
784         else if (ax > (ay << 1)) move_val++;
785
786         switch (move_val)
787         {
788         case 0:
789                 mm[0] = 9;
790                 if (ay > ax)
791                 {
792                         mm[1] = 8;
793                         mm[2] = 6;
794                         mm[3] = 7;
795                         mm[4] = 3;
796                 }
797                 else
798                 {
799                         mm[1] = 6;
800                         mm[2] = 8;
801                         mm[3] = 3;
802                         mm[4] = 7;
803                 }
804                 break;
805         case 1:
806         case 9:
807                 mm[0] = 6;
808                 if (y < 0)
809                 {
810                         mm[1] = 3;
811                         mm[2] = 9;
812                         mm[3] = 2;
813                         mm[4] = 8;
814                 }
815                 else
816                 {
817                         mm[1] = 9;
818                         mm[2] = 3;
819                         mm[3] = 8;
820                         mm[4] = 2;
821                 }
822                 break;
823         case 2:
824         case 6:
825                 mm[0] = 8;
826                 if (x < 0)
827                 {
828                         mm[1] = 9;
829                         mm[2] = 7;
830                         mm[3] = 6;
831                         mm[4] = 4;
832                 }
833                 else
834                 {
835                         mm[1] = 7;
836                         mm[2] = 9;
837                         mm[3] = 4;
838                         mm[4] = 6;
839                 }
840                 break;
841         case 4:
842                 mm[0] = 7;
843                 if (ay > ax)
844                 {
845                         mm[1] = 8;
846                         mm[2] = 4;
847                         mm[3] = 9;
848                         mm[4] = 1;
849                 }
850                 else
851                 {
852                         mm[1] = 4;
853                         mm[2] = 8;
854                         mm[3] = 1;
855                         mm[4] = 9;
856                 }
857                 break;
858         case 5:
859         case 13:
860                 mm[0] = 4;
861                 if (y < 0)
862                 {
863                         mm[1] = 1;
864                         mm[2] = 7;
865                         mm[3] = 2;
866                         mm[4] = 8;
867                 }
868                 else
869                 {
870                         mm[1] = 7;
871                         mm[2] = 1;
872                         mm[3] = 8;
873                         mm[4] = 2;
874                 }
875                 break;
876         case 8:
877                 mm[0] = 3;
878                 if (ay > ax)
879                 {
880                         mm[1] = 2;
881                         mm[2] = 6;
882                         mm[3] = 1;
883                         mm[4] = 9;
884                 }
885                 else
886                 {
887                         mm[1] = 6;
888                         mm[2] = 2;
889                         mm[3] = 9;
890                         mm[4] = 1;
891                 }
892                 break;
893         case 10:
894         case 14:
895                 mm[0] = 2;
896                 if (x < 0)
897                 {
898                         mm[1] = 3;
899                         mm[2] = 1;
900                         mm[3] = 6;
901                         mm[4] = 4;
902                 }
903                 else
904                 {
905                         mm[1] = 1;
906                         mm[2] = 3;
907                         mm[3] = 4;
908                         mm[4] = 6;
909                 }
910                 break;
911         case 12:
912                 mm[0] = 1;
913                 if (ay > ax)
914                 {
915                         mm[1] = 2;
916                         mm[2] = 4;
917                         mm[3] = 3;
918                         mm[4] = 7;
919                 }
920                 else
921                 {
922                         mm[1] = 4;
923                         mm[2] = 2;
924                         mm[3] = 7;
925                         mm[4] = 3;
926                 }
927                 break;
928         }
929
930         return TRUE;
931 }
932
933
934 /*!
935  * @brief モンスター単体の1ターン行動処理メインルーチン /
936  * Process a monster
937  * @param target_ptr プレーヤーへの参照ポインタ
938  * @param m_idx 行動モンスターの参照ID
939  * @return なし
940  * @details
941  * The monster is known to be within 100 grids of the player\n
942  *\n
943  * In several cases, we directly update the monster lore\n
944  *\n
945  * Note that a monster is only allowed to "reproduce" if there\n
946  * are a limited number of "reproducing" monsters on the current\n
947  * level.  This should prevent the level from being "swamped" by\n
948  * reproducing monsters.  It also allows a large mass of mice to\n
949  * prevent a louse from multiplying, but this is a small price to\n
950  * pay for a simple multiplication method.\n
951  *\n
952  * XXX Monster fear is slightly odd, in particular, monsters will\n
953  * fixate on opening a door even if they cannot open it.  Actually,\n
954  * the same thing happens to normal monsters when they hit a door\n
955  *\n
956  * In addition, monsters which *cannot* open or bash\n
957  * down a door will still stand there trying to open it...\n
958  *\n
959  * XXX Technically, need to check for monster in the way\n
960  * combined with that monster being in a wall (or door?)\n
961  *\n
962  * A "direction" of "5" means "pick a random direction".\n
963  */
964 void process_monster(player_type *target_ptr, MONSTER_IDX m_idx)
965 {
966         monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
967         monster_race *r_ptr = &r_info[m_ptr->r_idx];
968         turn_flags tmp_flags;
969         turn_flags *turn_flags_ptr = init_turn_flags(target_ptr->riding, m_idx, &tmp_flags);
970         turn_flags_ptr->see_m = is_seen(m_ptr);
971
972         decide_drop_from_monster(target_ptr, m_idx, turn_flags_ptr->is_riding_mon);
973         if ((m_ptr->mflag2 & MFLAG2_CHAMELEON) && one_in_(13) && !MON_CSLEEP(m_ptr))
974         {
975                 choose_new_monster(target_ptr, m_idx, FALSE, 0);
976                 r_ptr = &r_info[m_ptr->r_idx];
977         }
978
979         turn_flags_ptr->aware = process_stealth(target_ptr, m_idx);
980         if (vanish_summoned_children(target_ptr, m_idx, turn_flags_ptr->see_m)) return;
981         if (process_quantum_effect(target_ptr, m_idx, turn_flags_ptr->see_m)) return;
982         if (explode_grenade(target_ptr, m_idx)) return;
983         if (runaway_monster(target_ptr, turn_flags_ptr, m_idx)) return;
984
985         awake_monster(target_ptr, m_idx);
986         if (MON_STUNNED(m_ptr))
987         {
988                 if (one_in_(2)) return;
989         }
990
991         if (turn_flags_ptr->is_riding_mon)
992         {
993                 target_ptr->update |= (PU_BONUS);
994         }
995
996         process_angar(target_ptr, m_idx, turn_flags_ptr->see_m);
997
998         POSITION oy = m_ptr->fy;
999         POSITION ox = m_ptr->fx;
1000         if (decide_monster_multiplication(target_ptr, m_idx, oy, ox)) return;
1001
1002         process_special(target_ptr, m_idx);
1003         process_speak_sound(target_ptr, m_idx, oy, ox, turn_flags_ptr->aware);
1004         if (cast_spell(target_ptr, m_idx, turn_flags_ptr->aware)) return;
1005
1006         DIRECTION mm[8];
1007         mm[0] = mm[1] = mm[2] = mm[3] = 0;
1008         mm[4] = mm[5] = mm[6] = mm[7] = 0;
1009
1010         if (!decide_monster_movement_direction(target_ptr, mm, m_idx, turn_flags_ptr->aware)) return;
1011
1012         int count = 0;
1013         if (!process_monster_movement(target_ptr, turn_flags_ptr, m_idx, mm, oy, ox, &count)) return;
1014
1015         /*
1016          *  Forward movements failed, but now received LOS attack!
1017          *  Try to flow by smell.
1018          */
1019         if (target_ptr->no_flowed && count > 2 && m_ptr->target_y)
1020                 m_ptr->mflag2 &= ~MFLAG2_NOFLOW;
1021
1022         if (!turn_flags_ptr->do_turn && !turn_flags_ptr->do_move && !MON_MONFEAR(m_ptr) && !turn_flags_ptr->is_riding_mon && turn_flags_ptr->aware)
1023         {
1024                 if (r_ptr->freq_spell && randint1(100) <= r_ptr->freq_spell)
1025                 {
1026                         if (make_attack_spell(m_idx, target_ptr)) return;
1027                 }
1028         }
1029
1030         update_player_type(target_ptr, turn_flags_ptr, r_ptr);
1031         update_monster_race_flags(target_ptr, turn_flags_ptr, m_ptr);
1032
1033         if (!process_monster_fear(target_ptr, turn_flags_ptr, m_idx)) return;
1034
1035         if (m_ptr->ml) chg_virtue(target_ptr, V_COMPASSION, -1);
1036 }
1037
1038
1039 /*!
1040  * @brief 超隠密処理
1041  * @param target_ptr プレーヤーへの参照ポインタ
1042  * @param m_idx モンスターID
1043  * @return モンスターがプレーヤーに気付いているならばTRUE、超隠密状態ならばFALSE
1044  */
1045 bool process_stealth(player_type *target_ptr, MONSTER_IDX m_idx)
1046 {
1047         if ((target_ptr->special_defense & NINJA_S_STEALTH) == 0) return TRUE;
1048
1049         monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
1050         monster_race *r_ptr = &r_info[m_ptr->r_idx];
1051         int tmp = target_ptr->lev * 6 + (target_ptr->skill_stl + 10) * 4;
1052         if (target_ptr->monlite) tmp /= 3;
1053         if (target_ptr->cursed & TRC_AGGRAVATE) tmp /= 2;
1054         if (r_ptr->level > (target_ptr->lev * target_ptr->lev / 20 + 10)) tmp /= 3;
1055         return (randint0(tmp) <= (r_ptr->level + 20));
1056 }
1057
1058
1059 /*!
1060  * @brief 死亡したモンスターが乗馬中のモンスターだった場合に落馬処理を行う
1061  * @param target_ptr プレーヤーへの参照ポインタ
1062  * @param m_idx モンスターID
1063  * @param is_riding_mon 騎乗中であればTRUE
1064  * @return なし
1065  */
1066 void decide_drop_from_monster(player_type *target_ptr, MONSTER_IDX m_idx, bool is_riding_mon)
1067 {
1068         monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
1069         monster_race *r_ptr = &r_info[m_ptr->r_idx];
1070         if (!is_riding_mon || ((r_ptr->flags7 & RF7_RIDING) != 0)) return;
1071
1072         if (rakuba(target_ptr, 0, TRUE))
1073         {
1074 #ifdef JP
1075                 msg_print("地面に落とされた。");
1076 #else
1077                 GAME_TEXT m_name[MAX_NLEN];
1078                 monster_desc(target_ptr, m_name, &target_ptr->current_floor_ptr->m_list[target_ptr->riding], 0);
1079                 msg_format("You have fallen from %s.", m_name);
1080 #endif
1081         }
1082 }
1083
1084
1085 /*!
1086  * @brief 召喚の親元が消滅した時、子供も消滅させる
1087  * @param target_ptr プレーヤーへの参照ポインタ
1088  * @param m_idx モンスターID
1089  * @param see_m モンスターが視界内にいたらTRUE
1090  * @return 召喚モンスターが消滅したらTRUE
1091  */
1092 bool vanish_summoned_children(player_type *target_ptr, MONSTER_IDX m_idx, bool see_m)
1093 {
1094         monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
1095         if ((m_ptr->parent_m_idx == 0) || (target_ptr->current_floor_ptr->m_list[m_ptr->parent_m_idx].r_idx > 0))
1096                 return FALSE;
1097
1098         if (see_m)
1099         {
1100                 GAME_TEXT m_name[MAX_NLEN];
1101                 monster_desc(target_ptr, m_name, m_ptr, 0);
1102                 msg_format(_("%sは消え去った!", "%^s disappears!"), m_name);
1103         }
1104
1105         if (record_named_pet && is_pet(m_ptr) && m_ptr->nickname)
1106         {
1107                 GAME_TEXT m_name[MAX_NLEN];
1108                 monster_desc(target_ptr, m_name, m_ptr, MD_INDEF_VISIBLE);
1109                 exe_write_diary(target_ptr, DIARY_NAMED_PET, RECORD_NAMED_PET_LOSE_PARENT, m_name);
1110         }
1111
1112         delete_monster_idx(target_ptr, m_idx);
1113         return TRUE;
1114 }
1115
1116
1117 /*!
1118  * @brief 寝ているモンスターの起床を判定する
1119  * @param target_ptr プレーヤーへの参照ポインタ
1120  * @param m_idx モンスターID
1121  * @return なし
1122  */
1123 void awake_monster(player_type *target_ptr, MONSTER_IDX m_idx)
1124 {
1125         monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
1126         monster_race *r_ptr = &r_info[m_ptr->r_idx];
1127         if (!MON_CSLEEP(m_ptr)) return;
1128         if (!(target_ptr->cursed & TRC_AGGRAVATE)) return;
1129
1130         (void)set_monster_csleep(target_ptr, m_idx, 0);
1131         if (m_ptr->ml)
1132         {
1133                 GAME_TEXT m_name[MAX_NLEN];
1134                 monster_desc(target_ptr, m_name, m_ptr, 0);
1135                 msg_format(_("%^sが目を覚ました。", "%^s wakes up."), m_name);
1136         }
1137
1138         if (is_original_ap_and_seen(target_ptr, m_ptr) && (r_ptr->r_wake < MAX_UCHAR))
1139         {
1140                 r_ptr->r_wake++;
1141         }
1142 }
1143
1144
1145 /*!
1146  * @brief モンスターの怒り状態を判定する (起こっていたら敵に回す)
1147  * @param target_ptr プレーヤーへの参照ポインタ
1148  * @param m_idx モンスターID
1149  * @param see_m モンスターが視界内にいたらTRUE
1150  * @return なし
1151  */
1152 void process_angar(player_type *target_ptr, MONSTER_IDX m_idx, bool see_m)
1153 {
1154         monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
1155         monster_race *r_ptr = &r_info[m_ptr->r_idx];
1156         bool gets_angry = FALSE;
1157         if (is_friendly(m_ptr) && (target_ptr->cursed & TRC_AGGRAVATE))
1158                 gets_angry = TRUE;
1159
1160         if (is_pet(m_ptr) && ((((r_ptr->flags1 & RF1_UNIQUE) || (r_ptr->flags7 & RF7_NAZGUL)) &&
1161                 monster_has_hostile_align(target_ptr, NULL, 10, -10, r_ptr)) || (r_ptr->flagsr & RFR_RES_ALL)))
1162         {
1163                 gets_angry = TRUE;
1164         }
1165
1166         if (target_ptr->phase_out || !gets_angry) return;
1167
1168         if (is_pet(m_ptr) || see_m)
1169         {
1170                 GAME_TEXT m_name[MAX_NLEN];
1171                 monster_desc(target_ptr, m_name, m_ptr, is_pet(m_ptr) ? MD_ASSUME_VISIBLE : 0);
1172                 msg_format(_("%^sは突然敵にまわった!", "%^s suddenly becomes hostile!"), m_name);
1173         }
1174
1175         set_hostile(target_ptr, m_ptr);
1176 }
1177
1178
1179 /*!
1180  * @brief 手榴弾の爆発処理
1181  * @param target_ptr プレーヤーへの参照ポインタ
1182  * @param m_idx モンスターID
1183  * @return 爆死したらTRUE
1184  */
1185 bool explode_grenade(player_type *target_ptr, MONSTER_IDX m_idx)
1186 {
1187         monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
1188         if (m_ptr->r_idx != MON_GRENADE) return FALSE;
1189
1190         bool fear, dead;
1191         mon_take_hit_mon(target_ptr, m_idx, 1, &dead, &fear, _("は爆発して粉々になった。", " explodes into tiny shreds."), m_idx);
1192         return dead;
1193 }
1194
1195
1196 /*!
1197  * @brief モンスター依存の特別な行動を取らせる
1198  * @param target_ptr プレーヤーへの参照ポインタ
1199  * @param m_idx モンスターID
1200  * @return なし
1201  */
1202 void process_special(player_type *target_ptr, MONSTER_IDX m_idx)
1203 {
1204         monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
1205         monster_race *r_ptr = &r_info[m_ptr->r_idx];
1206         if ((r_ptr->a_ability_flags2 & RF6_SPECIAL) == 0) return;
1207         if (m_ptr->r_idx != MON_OHMU) return;
1208         if (target_ptr->current_floor_ptr->inside_arena || target_ptr->phase_out) return;
1209         if ((r_ptr->freq_spell == 0) || !(randint1(100) <= r_ptr->freq_spell)) return;
1210
1211         int count = 0;
1212         DEPTH rlev = ((r_ptr->level >= 1) ? r_ptr->level : 1);
1213         BIT_FLAGS p_mode = is_pet(m_ptr) ? PM_FORCE_PET : 0L;
1214
1215         for (int k = 0; k < A_MAX; k++)
1216         {
1217                 if (summon_specific(target_ptr, m_idx, m_ptr->fy, m_ptr->fx, rlev, SUMMON_MOLD, (PM_ALLOW_GROUP | p_mode)))
1218                 {
1219                         if (target_ptr->current_floor_ptr->m_list[hack_m_idx_ii].ml) count++;
1220                 }
1221         }
1222
1223         if (count && is_original_ap_and_seen(target_ptr, m_ptr)) r_ptr->r_flags6 |= (RF6_SPECIAL);
1224 }
1225
1226
1227 /*!
1228  * @brief モンスターを喋らせたり足音を立てたりする
1229  * @param target_ptr プレーヤーへの参照ポインタ
1230  * @param m_idx モンスターID
1231  * @param oy モンスターが元々いたY座標
1232  * @param ox モンスターが元々いたX座標
1233  * @param aware モンスターがプレーヤーに気付いているならばTRUE、超隠密状態ならばFALSE
1234  * @return なし
1235  */
1236 void process_speak_sound(player_type *target_ptr, MONSTER_IDX m_idx, POSITION oy, POSITION ox, bool aware)
1237 {
1238         if (target_ptr->phase_out) return;
1239
1240         monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
1241         monster_race *ap_r_ptr = &r_info[m_ptr->ap_r_idx];
1242         if (m_ptr->ap_r_idx == MON_CYBER &&
1243                 one_in_(CYBERNOISE) &&
1244                 !m_ptr->ml && (m_ptr->cdis <= MAX_SIGHT))
1245         {
1246                 if (disturb_minor) disturb(target_ptr, FALSE, FALSE);
1247                 msg_print(_("重厚な足音が聞こえた。", "You hear heavy steps."));
1248         }
1249
1250         if (((ap_r_ptr->flags2 & RF2_CAN_SPEAK) == 0) || !aware ||
1251                 !one_in_(SPEAK_CHANCE) ||
1252                 !player_has_los_bold(target_ptr, oy, ox) ||
1253                 !projectable(target_ptr, oy, ox, target_ptr->y, target_ptr->x))
1254                 return;
1255
1256         GAME_TEXT m_name[MAX_NLEN];
1257         char monmessage[1024];
1258         concptr filename;
1259
1260         if (m_ptr->ml)
1261                 monster_desc(target_ptr, m_name, m_ptr, 0);
1262         else
1263                 strcpy(m_name, _("それ", "It"));
1264
1265         if (MON_MONFEAR(m_ptr))
1266                 filename = _("monfear_j.txt", "monfear.txt");
1267         else if (is_pet(m_ptr))
1268                 filename = _("monpet_j.txt", "monpet.txt");
1269         else if (is_friendly(m_ptr))
1270                 filename = _("monfrien_j.txt", "monfrien.txt");
1271         else
1272                 filename = _("monspeak_j.txt", "monspeak.txt");
1273
1274         if (get_rnd_line(filename, m_ptr->ap_r_idx, monmessage) == 0)
1275         {
1276                 msg_format(_("%^s%s", "%^s %s"), m_name, monmessage);
1277         }
1278 }
1279
1280
1281 /*!
1282  * @brief モンスターを分裂させるかどうかを決定する (分裂もさせる)
1283  * @param target_ptr プレーヤーへの参照ポインタ
1284  * @param m_idx モンスターID
1285  * @param oy 分裂元モンスターのY座標
1286  * @param ox 分裂元モンスターのX座標
1287  * @return 実際に分裂したらTRUEを返す
1288  */
1289 bool decide_monster_multiplication(player_type *target_ptr, MONSTER_IDX m_idx, POSITION oy, POSITION ox)
1290 {
1291         monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
1292         monster_race *r_ptr = &r_info[m_ptr->r_idx];
1293         if (((r_ptr->flags2 & RF2_MULTIPLY) == 0) || (target_ptr->current_floor_ptr->num_repro >= MAX_REPRO))
1294                 return FALSE;
1295
1296         int k = 0;
1297         for (POSITION y = oy - 1; y <= oy + 1; y++)
1298         {
1299                 for (POSITION x = ox - 1; x <= ox + 1; x++)
1300                 {
1301                         if (!in_bounds2(target_ptr->current_floor_ptr, y, x)) continue;
1302                         if (target_ptr->current_floor_ptr->grid_array[y][x].m_idx) k++;
1303                 }
1304         }
1305
1306         if (multiply_barrier(target_ptr, m_idx)) k = 8;
1307
1308         if ((k < 4) && (!k || !randint0(k * MON_MULT_ADJ)))
1309         {
1310                 if (multiply_monster(target_ptr, m_idx, FALSE, (is_pet(m_ptr) ? PM_FORCE_PET : 0)))
1311                 {
1312                         if (target_ptr->current_floor_ptr->m_list[hack_m_idx_ii].ml && is_original_ap_and_seen(target_ptr, m_ptr))
1313                         {
1314                                 r_ptr->r_flags2 |= (RF2_MULTIPLY);
1315                         }
1316
1317                         return TRUE;
1318                 }
1319         }
1320
1321         return FALSE;
1322 }
1323
1324
1325 /*!
1326  * @brief モンスターの移動パターンを決定する
1327  * @param target_ptr プレーヤーへの参照ポインタ
1328  * @param mm 移動方向
1329  * @param m_idx モンスターID
1330  * @param aware モンスターがプレーヤーに気付いているならばTRUE、超隠密状態ならばFALSE
1331  * @return 移動先が存在すればTRUE
1332  */
1333 bool decide_monster_movement_direction(player_type *target_ptr, DIRECTION *mm, MONSTER_IDX m_idx, bool aware)
1334 {
1335         monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
1336         monster_race *r_ptr = &r_info[m_ptr->r_idx];
1337
1338         if (MON_CONFUSED(m_ptr) || !aware)
1339         {
1340                 mm[0] = mm[1] = mm[2] = mm[3] = 5;
1341                 return TRUE;
1342         }
1343
1344         if (random_walk(target_ptr, mm, m_ptr)) return TRUE;
1345
1346         if ((r_ptr->flags1 & RF1_NEVER_MOVE) && (m_ptr->cdis > 1))
1347         {
1348                 mm[0] = mm[1] = mm[2] = mm[3] = 5;
1349                 return TRUE;
1350         }
1351
1352         if (decide_pet_movement_direction(target_ptr, mm, m_idx)) return TRUE;
1353
1354         if (!is_hostile(m_ptr))
1355         {
1356                 mm[0] = mm[1] = mm[2] = mm[3] = 5;
1357                 get_enemy_dir(target_ptr, m_idx, mm);
1358                 return TRUE;
1359         }
1360
1361         if (!get_moves(target_ptr, m_idx, mm)) return FALSE;
1362
1363         return TRUE;
1364 }
1365
1366
1367 /*!
1368  * todo ↓のように書いたが、"5"とはもしかして「その場に留まる」という意味か?
1369  * @brief 不規則歩行フラグを持つモンスターの移動方向をその確率に基づいて決定する
1370  * @param target_ptr プレーヤーへの参照ポインタ
1371  * @param mm 移動方向
1372  * @param m_ptr モンスターへの参照ポインタ
1373  * @return 不規則な方向へ歩くことになったらTRUE
1374  */
1375 bool random_walk(player_type *target_ptr, DIRECTION *mm, monster_type *m_ptr)
1376 {
1377         monster_race *r_ptr = &r_info[m_ptr->r_idx];
1378         if (((r_ptr->flags1 & (RF1_RAND_50 | RF1_RAND_25)) == (RF1_RAND_50 | RF1_RAND_25)) && (randint0(100) < 75))
1379         {
1380                 if (is_original_ap_and_seen(target_ptr, m_ptr)) r_ptr->r_flags1 |= (RF1_RAND_50 | RF1_RAND_25);
1381
1382                 mm[0] = mm[1] = mm[2] = mm[3] = 5;
1383                 return TRUE;
1384         }
1385
1386         if ((r_ptr->flags1 & RF1_RAND_50) && (randint0(100) < 50))
1387         {
1388                 if (is_original_ap_and_seen(target_ptr, m_ptr)) r_ptr->r_flags1 |= RF1_RAND_50;
1389
1390                 mm[0] = mm[1] = mm[2] = mm[3] = 5;
1391                 return TRUE;
1392         }
1393
1394         if ((r_ptr->flags1 & RF1_RAND_25) && (randint0(100) < 25))
1395         {
1396                 if (is_original_ap_and_seen(target_ptr, m_ptr)) r_ptr->r_flags1 |= RF1_RAND_25;
1397
1398                 mm[0] = mm[1] = mm[2] = mm[3] = 5;
1399                 return TRUE;
1400         }
1401
1402         return FALSE;
1403 }
1404
1405
1406 /*!
1407  * @brief ペットや友好的なモンスターがフロアから逃げる処理を行う
1408  * @param target_ptr プレーヤーへの参照ポインタ
1409  * @param mm 移動方向
1410  * @param m_idx モンスターID
1411  * @return モンスターがペットであればTRUE
1412  */
1413 bool decide_pet_movement_direction(player_type *target_ptr, DIRECTION *mm, MONSTER_IDX m_idx)
1414 {
1415         monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
1416         if (!is_pet(m_ptr)) return FALSE;
1417
1418         bool avoid = ((target_ptr->pet_follow_distance < 0) && (m_ptr->cdis <= (0 - target_ptr->pet_follow_distance)));
1419         bool lonely = (!avoid && (m_ptr->cdis > target_ptr->pet_follow_distance));
1420         bool distant = (m_ptr->cdis > PET_SEEK_DIST);
1421         mm[0] = mm[1] = mm[2] = mm[3] = 5;
1422         if (get_enemy_dir(target_ptr, m_idx, mm)) return TRUE;
1423         if (!avoid && !lonely && !distant) return TRUE;
1424
1425         POSITION dis = target_ptr->pet_follow_distance;
1426         if (target_ptr->pet_follow_distance > PET_SEEK_DIST)
1427         {
1428                 target_ptr->pet_follow_distance = PET_SEEK_DIST;
1429         }
1430
1431         (void)get_moves(target_ptr, m_idx, mm);
1432         target_ptr->pet_follow_distance = (s16b)dis;
1433         return TRUE;
1434 }
1435
1436
1437 /*!
1438  * @brief ペットや友好的なモンスターがフロアから逃げる処理を行う
1439  * @param target_ptr プレーヤーへの参照ポインタ
1440  * @param m_idx モンスターID
1441  * @param is_riding_mon 騎乗状態ならばTRUE
1442  * @param see_m モンスターが視界内にいたらTRUE
1443  * @return モンスターがフロアから消えたらTRUE
1444  */
1445 bool runaway_monster(player_type *target_ptr, turn_flags *turn_flags_ptr, MONSTER_IDX m_idx)
1446 {
1447         monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
1448         monster_race *r_ptr = &r_info[m_ptr->r_idx];
1449         bool can_runaway = is_pet(m_ptr) || is_friendly(m_ptr);
1450         can_runaway &= ((r_ptr->flags1 & RF1_UNIQUE) != 0) || ((r_ptr->flags7 & RF7_NAZGUL) != 0);
1451         can_runaway &= !target_ptr->phase_out;
1452         if (!can_runaway) return FALSE;
1453
1454         static int riding_pinch = 0;
1455
1456         if (m_ptr->hp >= m_ptr->maxhp / 3)
1457         {
1458                 /* Reset the counter */
1459                 if (turn_flags_ptr->is_riding_mon) riding_pinch = 0;
1460
1461                 return FALSE;
1462         }
1463
1464         GAME_TEXT m_name[MAX_NLEN];
1465         monster_desc(target_ptr, m_name, m_ptr, 0);
1466         if (turn_flags_ptr->is_riding_mon && riding_pinch < 2)
1467         {
1468                 msg_format(_("%sは傷の痛さの余りあなたの束縛から逃れようとしている。",
1469                         "%^s seems to be in so much pain and tries to escape from your restriction."), m_name);
1470                 riding_pinch++;
1471                 disturb(target_ptr, TRUE, TRUE);
1472                 return FALSE;
1473         }
1474
1475         escape_monster(target_ptr, turn_flags_ptr, m_ptr, m_name);
1476         check_quest_completion(target_ptr, m_ptr);
1477         delete_monster_idx(target_ptr, m_idx);
1478         return TRUE;
1479 }
1480
1481
1482 /*!
1483  * @brief HPが1/3未満になった有効的なユニークモンスターの逃走処理を行う
1484  * @param target_ptr プレーヤーへの参照ポインタ
1485  * @param is_riding_mon 騎乗状態ならばTRUE
1486  * @param m_ptr モンスターへの参照ポインタ
1487  * @param m_name モンスター名称
1488  * @param see_m モンスターが視界内にいたらTRUE
1489  * @return なし
1490  */
1491 void escape_monster(player_type *target_ptr, turn_flags *turn_flags_ptr, monster_type *m_ptr, GAME_TEXT *m_name)
1492 {
1493         monster_race *r_ptr = &r_info[m_ptr->r_idx];
1494         if (turn_flags_ptr->is_riding_mon)
1495         {
1496                 msg_format(_("%sはあなたの束縛から脱出した。", "%^s succeeded to escape from your restriction!"), m_name);
1497                 if (rakuba(target_ptr, -1, FALSE))
1498                 {
1499                         msg_print(_("地面に落とされた。", "You have fallen from the pet you were riding."));
1500                 }
1501         }
1502
1503         if (turn_flags_ptr->see_m)
1504         {
1505                 if ((r_ptr->flags2 & RF2_CAN_SPEAK) && (m_ptr->r_idx != MON_GRIP) && (m_ptr->r_idx != MON_WOLF) && (m_ptr->r_idx != MON_FANG) &&
1506                         player_has_los_bold(target_ptr, m_ptr->fy, m_ptr->fx) && projectable(target_ptr, m_ptr->fy, m_ptr->fx, target_ptr->y, target_ptr->x))
1507                 {
1508                         msg_format(_("%^s「ピンチだ!退却させてもらう!」", "%^s says 'It is the pinch! I will retreat'."), m_name);
1509                 }
1510
1511                 msg_format(_("%^sがテレポート・レベルの巻物を読んだ。", "%^s reads a scroll of teleport level."), m_name);
1512                 msg_format(_("%^sが消え去った。", "%^s disappears."), m_name);
1513         }
1514
1515         if (turn_flags_ptr->is_riding_mon && rakuba(target_ptr, -1, FALSE))
1516         {
1517                 msg_print(_("地面に落とされた。", "You have fallen from the pet you were riding."));
1518         }
1519 }
1520
1521
1522 /*!
1523  * @brief モンスターに魔法を試行させる
1524  * @param target_ptr プレーヤーへの参照ポインタ
1525  * @param m_idx モンスターID
1526  * @param aware モンスターがプレーヤーに気付いているならばTRUE、超隠密状態ならばFALSE
1527  * @return 魔法を唱えられなければ強制的にFALSE、その後モンスターが実際に魔法を唱えればTRUE
1528  */
1529 bool cast_spell(player_type *target_ptr, MONSTER_IDX m_idx, bool aware)
1530 {
1531         monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
1532         monster_race *r_ptr = &r_info[m_ptr->r_idx];
1533         if ((r_ptr->freq_spell == 0) || (randint1(100) > r_ptr->freq_spell))
1534                 return FALSE;
1535
1536         bool counterattack = FALSE;
1537         if (m_ptr->target_y)
1538         {
1539                 MONSTER_IDX t_m_idx = target_ptr->current_floor_ptr->grid_array[m_ptr->target_y][m_ptr->target_x].m_idx;
1540                 if (t_m_idx && are_enemies(target_ptr, m_ptr, &target_ptr->current_floor_ptr->m_list[t_m_idx]) &&
1541                         projectable(target_ptr, m_ptr->fy, m_ptr->fx, m_ptr->target_y, m_ptr->target_x))
1542                 {
1543                         counterattack = TRUE;
1544                 }
1545         }
1546
1547         if (counterattack)
1548         {
1549                 if (monst_spell_monst(target_ptr, m_idx)) return TRUE;
1550                 if (aware && make_attack_spell(m_idx, target_ptr)) return TRUE;
1551         }
1552         else
1553         {
1554                 if (aware && make_attack_spell(m_idx, target_ptr)) return TRUE;
1555                 if (monst_spell_monst(target_ptr, m_idx)) return TRUE;
1556         }
1557
1558         return FALSE;
1559 }
1560
1561
1562 /*!
1563  * todo 少し長いが、これといってブロックとしてまとまった部分もないので暫定でこのままとする
1564  * @brief モンスターの移動に関するメインルーチン
1565  * @param target_ptr プレーヤーへの参照ポインタ
1566  * @param turn_flags_ptr ターン経過処理フラグへの参照ポインタ
1567  * @param m_idx モンスターID
1568  * @param mm モンスターの移動方向
1569  * @param oy 移動前の、モンスターのY座標
1570  * @param ox 移動前の、モンスターのX座標
1571  * @param count 移動回数 (のはず todo)
1572  * @return 移動が阻害される何か (ドア等)があったらFALSE
1573  */
1574 bool process_monster_movement(player_type *target_ptr, turn_flags *turn_flags_ptr, MONSTER_IDX m_idx, DIRECTION *mm, POSITION oy, POSITION ox, int *count)
1575 {
1576         for (int i = 0; mm[i]; i++)
1577         {
1578                 int d = mm[i];
1579                 if (d == 5) d = ddd[randint0(8)];
1580
1581                 POSITION ny = oy + ddy[d];
1582                 POSITION nx = ox + ddx[d];
1583                 if (!in_bounds2(target_ptr->current_floor_ptr, ny, nx)) continue;
1584
1585                 grid_type *g_ptr;
1586                 g_ptr = &target_ptr->current_floor_ptr->grid_array[ny][nx];
1587                 monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
1588                 monster_race *r_ptr = &r_info[m_ptr->r_idx];
1589                 bool can_cross = monster_can_cross_terrain(target_ptr, g_ptr->feat, r_ptr, turn_flags_ptr->is_riding_mon ? CEM_RIDING : 0);
1590
1591                 if (!process_wall(target_ptr, turn_flags_ptr, m_ptr, ny, nx, can_cross))
1592                 {
1593                         if (!process_door(target_ptr, turn_flags_ptr, m_ptr, ny, nx))
1594                                 return FALSE;
1595                 }
1596
1597                 if (!process_protection_rune(target_ptr, turn_flags_ptr, m_ptr, ny, nx))
1598                 {
1599                         if (!process_explosive_rune(target_ptr, turn_flags_ptr, m_ptr, ny, nx))
1600                                 return FALSE;
1601                 }
1602
1603                 exe_monster_attack_to_player(target_ptr, turn_flags_ptr, m_idx, ny, nx);
1604                 if (process_monster_attack_to_monster(target_ptr, turn_flags_ptr, m_idx, g_ptr, can_cross)) return FALSE;
1605
1606                 if (turn_flags_ptr->is_riding_mon)
1607                 {
1608                         if (!target_ptr->riding_ryoute && !MON_MONFEAR(&target_ptr->current_floor_ptr->m_list[target_ptr->riding])) turn_flags_ptr->do_move = FALSE;
1609                 }
1610
1611                 if (!process_post_dig_wall(target_ptr, turn_flags_ptr, m_ptr, ny, nx)) return FALSE;
1612
1613                 if (turn_flags_ptr->must_alter_to_move && (r_ptr->flags7 & RF7_AQUATIC))
1614                 {
1615                         if (!monster_can_cross_terrain(target_ptr, g_ptr->feat, r_ptr, turn_flags_ptr->is_riding_mon ? CEM_RIDING : 0))
1616                                 turn_flags_ptr->do_move = FALSE;
1617                 }
1618
1619                 if (turn_flags_ptr->do_move && !can_cross && !turn_flags_ptr->did_kill_wall && !turn_flags_ptr->did_bash_door)
1620                         turn_flags_ptr->do_move = FALSE;
1621
1622                 if (turn_flags_ptr->do_move && (r_ptr->flags1 & RF1_NEVER_MOVE))
1623                 {
1624                         if (is_original_ap_and_seen(target_ptr, m_ptr))
1625                                 r_ptr->r_flags1 |= (RF1_NEVER_MOVE);
1626
1627                         turn_flags_ptr->do_move = FALSE;
1628                 }
1629
1630                 if (!turn_flags_ptr->do_move)
1631                 {
1632                         if (turn_flags_ptr->do_turn) break;
1633
1634                         continue;
1635                 }
1636
1637                 turn_flags_ptr->do_turn = TRUE;
1638                 feature_type *f_ptr;
1639                 f_ptr = &f_info[g_ptr->feat];
1640                 if (have_flag(f_ptr->flags, FF_TREE))
1641                 {
1642                         if (!(r_ptr->flags7 & RF7_CAN_FLY) && !(r_ptr->flags8 & RF8_WILD_WOOD))
1643                         {
1644                                 m_ptr->energy_need += ENERGY_NEED();
1645                         }
1646                 }
1647
1648                 if (!update_riding_monster(target_ptr, turn_flags_ptr, m_idx, oy, ox, ny, nx)) break;
1649
1650                 monster_race *ap_r_ptr = &r_info[m_ptr->ap_r_idx];
1651                 if (m_ptr->ml &&
1652                         (disturb_move ||
1653                         (disturb_near && (m_ptr->mflag & MFLAG_VIEW) && projectable(target_ptr, target_ptr->y, target_ptr->x, m_ptr->fy, m_ptr->fx)) ||
1654                                 (disturb_high && ap_r_ptr->r_tkills && ap_r_ptr->level >= target_ptr->lev)))
1655                 {
1656                         if (is_hostile(m_ptr))
1657                                 disturb(target_ptr, FALSE, TRUE);
1658                 }
1659
1660                 bool is_takable_or_killable = g_ptr->o_idx > 0;
1661                 is_takable_or_killable &= (r_ptr->flags2 & (RF2_TAKE_ITEM | RF2_KILL_ITEM)) != 0;
1662
1663                 bool is_pickup_items = (target_ptr->pet_extra_flags & PF_PICKUP_ITEMS) != 0;
1664                 is_pickup_items &= (r_ptr->flags2 & RF2_TAKE_ITEM) != 0;
1665
1666                 is_takable_or_killable &= !is_pet(m_ptr) || is_pickup_items;
1667                 if (!is_takable_or_killable)
1668                 {
1669                         if (turn_flags_ptr->do_turn) break;
1670
1671                         continue;
1672                 }
1673
1674                 update_object_by_monster_movement(target_ptr, turn_flags_ptr, m_idx, ny, nx);
1675                 if (turn_flags_ptr->do_turn) break;
1676
1677                 (*count)++;
1678         }
1679
1680         return TRUE;
1681 }
1682
1683
1684 /*!
1685  * @brief 騎乗中のモンスター情報を更新する
1686  * @param target_ptr プレーヤーへの参照ポインタ
1687  * @param turn_flags_ptr ターン経過処理フラグへの参照ポインタ
1688  * @param m_idx モンスターID
1689  * @param oy 移動前の、モンスターのY座標
1690  * @param ox 移動前の、モンスターのX座標
1691  * @param ny 移動後の、モンスターのY座標
1692  * @param ox 移動後の、モンスターのX座標
1693  * @return アイテム等に影響を及ぼしたらTRUE
1694  */
1695 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)
1696 {
1697         monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
1698         grid_type *g_ptr;
1699         g_ptr = &target_ptr->current_floor_ptr->grid_array[ny][nx];
1700         monster_type *y_ptr;
1701         y_ptr = &target_ptr->current_floor_ptr->m_list[g_ptr->m_idx];
1702         if (turn_flags_ptr->is_riding_mon)
1703                 return move_player_effect(target_ptr, ny, nx, MPE_DONT_PICKUP);
1704
1705         target_ptr->current_floor_ptr->grid_array[oy][ox].m_idx = g_ptr->m_idx;
1706         if (g_ptr->m_idx)
1707         {
1708                 y_ptr->fy = oy;
1709                 y_ptr->fx = ox;
1710                 update_monster(target_ptr, g_ptr->m_idx, TRUE);
1711         }
1712
1713         g_ptr->m_idx = m_idx;
1714         m_ptr->fy = ny;
1715         m_ptr->fx = nx;
1716         update_monster(target_ptr, m_idx, TRUE);
1717
1718         lite_spot(target_ptr, oy, ox);
1719         lite_spot(target_ptr, ny, nx);
1720         return TRUE;
1721 }
1722
1723
1724 /*!
1725  * @brief updateフィールドを更新する
1726  * @param target_ptr プレーヤーへの参照ポインタ
1727  * @param turn_flags_ptr ターン経過処理フラグへの参照ポインタ
1728  * @return なし
1729  */
1730 void update_player_type(player_type *target_ptr, turn_flags *turn_flags_ptr, monster_race *r_ptr)
1731 {
1732         if (turn_flags_ptr->do_view)
1733         {
1734                 target_ptr->update |= (PU_FLOW);
1735                 target_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
1736         }
1737
1738         if (turn_flags_ptr->do_move && ((r_ptr->flags7 & (RF7_SELF_LD_MASK | RF7_HAS_DARK_1 | RF7_HAS_DARK_2))
1739                 || ((r_ptr->flags7 & (RF7_HAS_LITE_1 | RF7_HAS_LITE_2)) && !target_ptr->phase_out)))
1740         {
1741                 target_ptr->update |= (PU_MON_LITE);
1742         }
1743 }
1744
1745
1746 /*!
1747  * @brief モンスターのフラグを更新する
1748  * @param target_ptr プレーヤーへの参照ポインタ
1749  * @param turn_flags_ptr ターン経過処理フラグへの参照ポインタ
1750  * @param m_ptr モンスターへの参照ポインタ
1751  * @return なし
1752  */
1753 void update_monster_race_flags(player_type *target_ptr, turn_flags *turn_flags_ptr, monster_type *m_ptr)
1754 {
1755         monster_race *r_ptr = &r_info[m_ptr->r_idx];
1756         if (!is_original_ap_and_seen(target_ptr, m_ptr)) return;
1757
1758         if (turn_flags_ptr->did_open_door) r_ptr->r_flags2 |= (RF2_OPEN_DOOR);
1759         if (turn_flags_ptr->did_bash_door) r_ptr->r_flags2 |= (RF2_BASH_DOOR);
1760         if (turn_flags_ptr->did_take_item) r_ptr->r_flags2 |= (RF2_TAKE_ITEM);
1761         if (turn_flags_ptr->did_kill_item) r_ptr->r_flags2 |= (RF2_KILL_ITEM);
1762         if (turn_flags_ptr->did_move_body) r_ptr->r_flags2 |= (RF2_MOVE_BODY);
1763         if (turn_flags_ptr->did_pass_wall) r_ptr->r_flags2 |= (RF2_PASS_WALL);
1764         if (turn_flags_ptr->did_kill_wall) r_ptr->r_flags2 |= (RF2_KILL_WALL);
1765 }
1766
1767
1768 /*!
1769  * @brief モンスターの恐怖状態を処理する
1770  * @param target_ptr プレーヤーへの参照ポインタ
1771  * @param turn_flags_ptr ターン経過処理フラグへの参照ポインタ
1772  * @param m_idx モンスターID
1773  * @param aware モンスターがプレーヤーに気付いているならばTRUE、超隠密状態ならばFALSE
1774  * @return モンスターが戦いを決意したらTRUE
1775  */
1776 bool process_monster_fear(player_type *target_ptr, turn_flags *turn_flags_ptr, MONSTER_IDX m_idx)
1777 {
1778         monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
1779         bool is_battle_determined = !turn_flags_ptr->do_turn && !turn_flags_ptr->do_move && MON_MONFEAR(m_ptr) && turn_flags_ptr->aware;
1780         if (!is_battle_determined) return FALSE;
1781
1782         (void)set_monster_monfear(target_ptr, m_idx, 0);
1783         if (!turn_flags_ptr->see_m) return TRUE;
1784
1785         GAME_TEXT m_name[MAX_NLEN];
1786         monster_desc(target_ptr, m_name, m_ptr, 0);
1787         msg_format(_("%^sは戦いを決意した!", "%^s turns to fight!"), m_name);
1788         return TRUE;
1789 }
1790
1791
1792 /*!
1793  * @brief 全モンスターのターン管理メインルーチン /
1794  * Process all the "live" monsters, once per game turn.
1795  * @return なし
1796  * @details
1797  * During each game current game turn, we scan through the list of all the "live" monsters,\n
1798  * (backwards, so we can excise any "freshly dead" monsters), energizing each\n
1799  * monster, and allowing fully energized monsters to move, attack, pass, etc.\n
1800  *\n
1801  * Note that monsters can never move in the monster array (except when the\n
1802  * "compact_monsters()" function is called by "dungeon()" or "save_player()").\n
1803  *\n
1804  * This function is responsible for at least half of the processor time\n
1805  * on a normal system with a "normal" amount of monsters and a player doing\n
1806  * normal things.\n
1807  *\n
1808  * When the player is resting, virtually 90% of the processor time is spent\n
1809  * in this function, and its children, "process_monster()" and "make_move()".\n
1810  *\n
1811  * Most of the rest of the time is spent in "update_view()" and "lite_spot()",\n
1812  * especially when the player is running.\n
1813  *\n
1814  * Note the special "MFLAG_BORN" flag, which allows us to ignore "fresh"\n
1815  * monsters while they are still being "born".  A monster is "fresh" only\n
1816  * during the game turn in which it is created, and we use the "hack_m_idx" to\n
1817  * determine if the monster is yet to be processed during the game turn.\n
1818  *\n
1819  * Note the special "MFLAG_NICE" flag, which allows the player to get one\n
1820  * move before any "nasty" monsters get to use their spell attacks.\n
1821  *\n
1822  * Note that when the "knowledge" about the currently tracked monster\n
1823  * changes (flags, attacks, spells), we induce a redraw of the monster\n
1824  * recall window.\n
1825  */
1826 void process_monsters(player_type *target_ptr)
1827 {
1828         old_race_flags tmp_flags;
1829         old_race_flags *old_race_flags_ptr = init_old_race_flags(&tmp_flags);
1830
1831         floor_type *floor_ptr = target_ptr->current_floor_ptr;
1832         floor_ptr->monster_noise = FALSE;
1833
1834         MONRACE_IDX old_monster_race_idx = target_ptr->monster_race_idx;
1835         save_old_race_flags(target_ptr->monster_race_idx, old_race_flags_ptr);
1836         sweep_monster_process(target_ptr);
1837
1838         hack_m_idx = 0;
1839         if (!target_ptr->monster_race_idx || (target_ptr->monster_race_idx != old_monster_race_idx))
1840                 return;
1841
1842         update_player_window(target_ptr->monster_race_idx, &target_ptr->window, old_race_flags_ptr);
1843 }
1844
1845
1846 /*!
1847  * @brief フロア内のモンスターについてターン終了時の処理を繰り返す
1848  * @param target_ptr プレーヤーへの参照ポインタ
1849  */
1850 void sweep_monster_process(player_type *target_ptr)
1851 {
1852         floor_type *floor_ptr = target_ptr->current_floor_ptr;
1853         for (MONSTER_IDX i = floor_ptr->m_max - 1; i >= 1; i--)
1854         {
1855                 monster_type *m_ptr;
1856                 m_ptr = &floor_ptr->m_list[i];
1857
1858                 if (target_ptr->leaving) return;
1859                 if (!monster_is_valid(m_ptr)) continue;
1860                 if (target_ptr->wild_mode) continue;
1861
1862                 if (m_ptr->mflag & MFLAG_BORN)
1863                 {
1864                         m_ptr->mflag &= ~(MFLAG_BORN);
1865                         continue;
1866                 }
1867
1868                 if (m_ptr->cdis >= AAF_LIMIT) continue;
1869                 if (!decide_process_continue(target_ptr, m_ptr)) continue;
1870
1871                 SPEED speed = (target_ptr->riding == i) ? target_ptr->pspeed : decide_monster_speed(m_ptr);
1872                 m_ptr->energy_need -= SPEED_TO_ENERGY(speed);
1873                 if (m_ptr->energy_need > 0) continue;
1874
1875                 m_ptr->energy_need += ENERGY_NEED();
1876                 hack_m_idx = i;
1877                 process_monster(target_ptr, i);
1878                 reset_target(m_ptr);
1879
1880                 if (target_ptr->no_flowed && one_in_(3))
1881                         m_ptr->mflag2 |= MFLAG2_NOFLOW;
1882
1883                 if (!target_ptr->playing || target_ptr->is_dead) return;
1884                 if (target_ptr->leaving) return;
1885         }
1886 }
1887
1888
1889 /*!
1890  * @brief 後続のモンスター処理が必要かどうか判定する (要調査)
1891  * @param target_ptr プレーヤーへの参照ポインタ
1892  * @param m_ptr モンスターへの参照ポインタ
1893  * @return 後続処理が必要ならTRUE
1894  */
1895 bool decide_process_continue(player_type *target_ptr, monster_type *m_ptr)
1896 {
1897         monster_race *r_ptr;
1898         r_ptr = &r_info[m_ptr->r_idx];
1899         if (!target_ptr->no_flowed)
1900         {
1901                 m_ptr->mflag2 &= ~MFLAG2_NOFLOW;
1902         }
1903
1904         if (m_ptr->cdis <= (is_pet(m_ptr) ? (r_ptr->aaf > MAX_SIGHT ? MAX_SIGHT : r_ptr->aaf) : r_ptr->aaf))
1905                 return TRUE;
1906
1907         if ((m_ptr->cdis <= MAX_SIGHT || target_ptr->phase_out) &&
1908                 (player_has_los_bold(target_ptr, m_ptr->fy, m_ptr->fx) || (target_ptr->cursed & TRC_AGGRAVATE)))
1909                 return TRUE;
1910
1911         if (m_ptr->target_y)
1912                 return TRUE;
1913
1914         return FALSE;
1915 }