OSDN Git Service

[Refactor] #40030 process_door() からbash_normal_door() とbash_glass_door() を分離 / Separa...
[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
19 #include "cmd-dump.h"
20 #include "cmd-pet.h"
21 #include "creature.h"
22 #include "melee.h"
23 #include "spells.h"
24 #include "spells-floor.h"
25 #include "spells-summon.h"
26 #include "quest.h"
27 #include "avatar.h"
28 #include "realm-hex.h"
29 #include "object-flavor.h"
30 #include "object-hook.h"
31 #include "feature.h"
32 #include "grid.h"
33 #include "player-move.h"
34 #include "monster-status.h"
35 #include "monster-spell.h"
36 #include "monster-process.h"
37 #include "monsterrace-hook.h"
38 #include "dungeon.h"
39 #include "floor.h"
40 #include "files.h"
41 #include "view-mainwindow.h"
42
43 typedef struct {
44         bool is_riding_mon;
45         bool do_turn;
46         bool do_move;
47         bool do_view;
48         bool do_take;
49         bool must_alter_to_move;
50
51         bool did_open_door;
52         bool did_bash_door;
53         bool did_take_item;
54         bool did_kill_item;
55         bool did_move_body;
56         bool did_pass_wall;
57         bool did_kill_wall;
58 } turn_flags;
59
60 void decide_drop_from_monster(player_type *target_ptr, MONSTER_IDX m_idx, bool is_riding_mon);
61 bool vanish_summoned_children(player_type *target_ptr, MONSTER_IDX m_idx, bool see_m);
62 void awake_monster(player_type *target_ptr, MONSTER_IDX m_idx);
63 void process_angar(player_type *target_ptr, MONSTER_IDX m_idx, bool see_m);
64 bool process_quantum_effect(player_type *target_ptr, MONSTER_IDX m_idx, bool see_m);
65 void vanish_nonunique(player_type *target_ptr, MONSTER_IDX m_idx, bool see_m);
66 void produce_quantum_effect(player_type *target_ptr, MONSTER_IDX m_idx, bool see_m);
67 bool decide_monster_multiplication(player_type *target_ptr, MONSTER_IDX m_idx, POSITION oy, POSITION ox);
68 bool decide_monster_movement_direction(player_type *target_ptr, DIRECTION *mm, MONSTER_IDX m_idx, bool aware);
69 bool runaway_monster(player_type *target_ptr, MONSTER_IDX m_idx, bool is_riding_mon, bool see_m);
70 void process_special(player_type *target_ptr, MONSTER_IDX m_idx);
71 void process_speak_sound(player_type *target_ptr, MONSTER_IDX m_idx, POSITION oy, POSITION ox, bool aware);
72 bool cast_spell(player_type *target_ptr, MONSTER_IDX m_idx, bool aware);
73
74 bool process_wall(player_type *target_ptr, turn_flags *turn_flags_ptr, monster_type *m_ptr, POSITION ny, POSITION nx, bool can_cross);
75 bool process_door(player_type *target_ptr, turn_flags *turn_flags_ptr, monster_type *m_ptr, POSITION ny, POSITION nx);
76 bool bash_normal_door(player_type *target_ptr, turn_flags *turn_flags_ptr, monster_type *m_ptr, POSITION ny, POSITION nx);
77 void bash_glass_door(player_type *target_ptr, turn_flags *turn_flags_ptr, monster_type *m_ptr, grid_type *g_ptr, feature_type *f_ptr, bool may_bash);
78 bool process_protection_rune(player_type *target_ptr, turn_flags *turn_flags_ptr, monster_type *m_ptr, POSITION ny, POSITION nx);
79 bool process_explosive_rune(player_type *target_ptr, turn_flags *turn_flags_ptr, monster_type *m_ptr, POSITION ny, POSITION nx);
80
81  /*!
82   * @brief モンスターが敵に接近するための方向を決める /
83   * Calculate the direction to the next enemy
84   * @param target_ptr プレーヤーへの参照ポインタ
85   * @param m_idx モンスターの参照ID
86   * @param mm 移動するべき方角IDを返す参照ポインタ
87   * @return 方向が確定した場合TRUE、接近する敵がそもそもいない場合FALSEを返す
88   */
89 static bool get_enemy_dir(player_type *target_ptr, MONSTER_IDX m_idx, int *mm)
90 {
91         floor_type *floor_ptr = target_ptr->current_floor_ptr;
92         monster_type *m_ptr = &floor_ptr->m_list[m_idx];
93         monster_race *r_ptr = &r_info[m_ptr->r_idx];
94
95         POSITION x = 0, y = 0;
96         if (target_ptr->riding_t_m_idx && player_bold(target_ptr, m_ptr->fy, m_ptr->fx))
97         {
98                 y = floor_ptr->m_list[target_ptr->riding_t_m_idx].fy;
99                 x = floor_ptr->m_list[target_ptr->riding_t_m_idx].fx;
100         }
101         else if (is_pet(m_ptr) && target_ptr->pet_t_m_idx)
102         {
103                 y = floor_ptr->m_list[target_ptr->pet_t_m_idx].fy;
104                 x = floor_ptr->m_list[target_ptr->pet_t_m_idx].fx;
105         }
106         else
107         {
108                 int start;
109                 int plus = 1;
110                 if (target_ptr->phase_out)
111                 {
112                         start = randint1(floor_ptr->m_max - 1) + floor_ptr->m_max;
113                         if (randint0(2)) plus = -1;
114                 }
115                 else
116                 {
117                         start = floor_ptr->m_max + 1;
118                 }
119
120                 for (int i = start; ((i < start + floor_ptr->m_max) && (i > start - floor_ptr->m_max)); i += plus)
121                 {
122                         MONSTER_IDX dummy = (i % floor_ptr->m_max);
123                         if (!dummy) continue;
124
125                         MONSTER_IDX t_idx = dummy;
126                         monster_type *t_ptr;
127                         t_ptr = &floor_ptr->m_list[t_idx];
128
129                         if (t_ptr == m_ptr) continue;
130                         if (!monster_is_valid(t_ptr)) continue;
131
132                         if (is_pet(m_ptr))
133                         {
134                                 if (target_ptr->pet_follow_distance < 0)
135                                 {
136                                         if (t_ptr->cdis <= (0 - target_ptr->pet_follow_distance))
137                                         {
138                                                 continue;
139                                         }
140                                 }
141                                 else if ((m_ptr->cdis < t_ptr->cdis) && (t_ptr->cdis > target_ptr->pet_follow_distance))
142                                 {
143                                         continue;
144                                 }
145
146                                 if (r_ptr->aaf < t_ptr->cdis) continue;
147                         }
148
149                         if (!are_enemies(target_ptr, m_ptr, t_ptr)) continue;
150
151                         if (((r_ptr->flags2 & RF2_PASS_WALL) && ((m_idx != target_ptr->riding) || target_ptr->pass_wall)) ||
152                                 ((r_ptr->flags2 & RF2_KILL_WALL) && (m_idx != target_ptr->riding)))
153                         {
154                                 if (!in_disintegration_range(floor_ptr, m_ptr->fy, m_ptr->fx, t_ptr->fy, t_ptr->fx)) continue;
155                         }
156                         else
157                         {
158                                 if (!projectable(target_ptr, m_ptr->fy, m_ptr->fx, t_ptr->fy, t_ptr->fx)) continue;
159                         }
160
161                         y = t_ptr->fy;
162                         x = t_ptr->fx;
163
164                         break;
165                 }
166
167                 if (!x && !y) return FALSE;
168         }
169
170         x -= m_ptr->fx;
171         y -= m_ptr->fy;
172
173         /* North, South, East, West, North-West, North-East, South-West, South-East */
174         if ((y < 0) && (x == 0))
175         {
176                 mm[0] = 8;
177                 mm[1] = 7;
178                 mm[2] = 9;
179         }
180         else if ((y > 0) && (x == 0))
181         {
182                 mm[0] = 2;
183                 mm[1] = 1;
184                 mm[2] = 3;
185         }
186         else if ((x > 0) && (y == 0))
187         {
188                 mm[0] = 6;
189                 mm[1] = 9;
190                 mm[2] = 3;
191         }
192         else if ((x < 0) && (y == 0))
193         {
194                 mm[0] = 4;
195                 mm[1] = 7;
196                 mm[2] = 1;
197         }
198         else if ((y < 0) && (x < 0))
199         {
200                 mm[0] = 7;
201                 mm[1] = 4;
202                 mm[2] = 8;
203         }
204         else if ((y < 0) && (x > 0))
205         {
206                 mm[0] = 9;
207                 mm[1] = 6;
208                 mm[2] = 8;
209         }
210         else if ((y > 0) && (x < 0))
211         {
212                 mm[0] = 1;
213                 mm[1] = 4;
214                 mm[2] = 2;
215         }
216         else if ((y > 0) && (x > 0))
217         {
218                 mm[0] = 3;
219                 mm[1] = 6;
220                 mm[2] = 2;
221         }
222
223         return TRUE;
224 }
225
226
227 /*!
228  * @brief モンスターがプレイヤーから逃走するかどうかを返す /
229  * Returns whether a given monster will try to run from the player.
230  * @param m_idx 逃走するモンスターの参照ID
231  * @return モンスターがプレイヤーから逃走するならばTRUEを返す。
232  * @details
233  * Monsters will attempt to avoid very powerful players.  See below.\n
234  *\n
235  * Because this function is called so often, little details are important\n
236  * for efficiency.  Like not using "mod" or "div" when possible.  And\n
237  * attempting to check the conditions in an optimal order.  Note that\n
238  * "(x << 2) == (x * 4)" if "x" has enough bits to hold the result.\n
239  *\n
240  * Note that this function is responsible for about one to five percent\n
241  * of the processor use in normal conditions...\n
242  */
243 static bool mon_will_run(player_type *target_ptr, MONSTER_IDX m_idx)
244 {
245         monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
246         monster_race *r_ptr = &r_info[m_ptr->r_idx];
247
248         if (is_pet(m_ptr))
249         {
250                 return ((target_ptr->pet_follow_distance < 0) &&
251                         (m_ptr->cdis <= (0 - target_ptr->pet_follow_distance)));
252         }
253
254         if (m_ptr->cdis > MAX_SIGHT + 5) return FALSE;
255         if (MON_MONFEAR(m_ptr)) return TRUE;
256         if (m_ptr->cdis <= 5) return FALSE;
257
258         PLAYER_LEVEL p_lev = target_ptr->lev;
259         DEPTH m_lev = r_ptr->level + (m_idx & 0x08) + 25;
260         if (m_lev > p_lev + 4) return FALSE;
261         if (m_lev + 4 <= p_lev) return TRUE;
262
263         HIT_POINT p_chp = target_ptr->chp;
264         HIT_POINT p_mhp = target_ptr->mhp;
265         HIT_POINT m_chp = m_ptr->hp;
266         HIT_POINT m_mhp = m_ptr->maxhp;
267         u32b p_val = (p_lev * p_mhp) + (p_chp << 2);
268         u32b m_val = (m_lev * m_mhp) + (m_chp << 2);
269         if (p_val * m_mhp > m_val * p_mhp) return TRUE;
270
271         return FALSE;
272 }
273
274
275 /*!
276  * @brief モンスターがプレイヤーに向けて遠距離攻撃を行うことが可能なマスを走査する /
277  * Search spell castable grid
278  * @param target_ptr プレーヤーへの参照ポインタ
279  * @param m_idx モンスターの参照ID
280  * @param yp 適したマスのY座標を返す参照ポインタ
281  * @param xp 適したマスのX座標を返す参照ポインタ
282  * @return 有効なマスがあった場合TRUEを返す
283  */
284 static bool get_moves_aux2(player_type *target_ptr, MONSTER_IDX m_idx, POSITION *yp, POSITION *xp)
285 {
286         floor_type *floor_ptr = target_ptr->current_floor_ptr;
287         monster_type *m_ptr = &floor_ptr->m_list[m_idx];
288         monster_race *r_ptr = &r_info[m_ptr->r_idx];
289
290         POSITION y1 = m_ptr->fy;
291         POSITION x1 = m_ptr->fx;
292
293         if (projectable(target_ptr, y1, x1, target_ptr->y, target_ptr->x)) return FALSE;
294
295         int now_cost = floor_ptr->grid_array[y1][x1].cost;
296         if (now_cost == 0) now_cost = 999;
297
298         bool can_open_door = FALSE;
299         if (r_ptr->flags2 & (RF2_BASH_DOOR | RF2_OPEN_DOOR))
300         {
301                 can_open_door = TRUE;
302         }
303
304         int best = 999;
305         for (int i = 7; i >= 0; i--)
306         {
307                 POSITION y = y1 + ddy_ddd[i];
308                 POSITION x = x1 + ddx_ddd[i];
309                 if (!in_bounds2(floor_ptr, y, x)) continue;
310                 if (player_bold(target_ptr, y, x)) return FALSE;
311
312                 grid_type *g_ptr;
313                 g_ptr = &floor_ptr->grid_array[y][x];
314                 int cost = g_ptr->cost;
315                 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))))
316                 {
317                         if (cost == 0) continue;
318                         if (!can_open_door && is_closed_door(target_ptr, g_ptr->feat)) continue;
319                 }
320
321                 if (cost == 0) cost = 998;
322
323                 if (now_cost < cost) continue;
324                 if (!projectable(target_ptr, y, x, target_ptr->y, target_ptr->x)) continue;
325                 if (best < cost) continue;
326
327                 best = cost;
328                 *yp = y1 + ddy_ddd[i];
329                 *xp = x1 + ddx_ddd[i];
330         }
331
332         if (best == 999) return FALSE;
333
334         return TRUE;
335 }
336
337
338 /*!
339  * @brief モンスターがプレイヤーに向けて接近することが可能なマスを走査する /
340  * Choose the "best" direction for "flowing"
341  * @param m_idx モンスターの参照ID
342  * @param yp 移動先のマスのY座標を返す参照ポインタ
343  * @param xp 移動先のマスのX座標を返す参照ポインタ
344  * @param no_flow モンスターにFLOWフラグが経っていない状態でTRUE
345  * @return 有効なマスがあった場合TRUEを返す
346  * @details
347  * Note that ghosts and rock-eaters are never allowed to "flow",\n
348  * since they should move directly towards the player.\n
349  *\n
350  * Prefer "non-diagonal" directions, but twiddle them a little\n
351  * to angle slightly towards the player's actual location.\n
352  *\n
353  * Allow very perceptive monsters to track old "spoor" left by\n
354  * previous locations occupied by the player.  This will tend\n
355  * to have monsters end up either near the player or on a grid\n
356  * recently occupied by the player (and left via "teleport").\n
357  *\n
358  * Note that if "smell" is turned on, all monsters get vicious.\n
359  *\n
360  * Also note that teleporting away from a location will cause\n
361  * the monsters who were chasing you to converge on that location\n
362  * as long as you are still near enough to "annoy" them without\n
363  * being close enough to chase directly.  I have no idea what will\n
364  * happen if you combine "smell" with low "aaf" values.\n
365  */
366 static bool get_moves_aux(player_type *target_ptr, MONSTER_IDX m_idx, POSITION *yp, POSITION *xp, bool no_flow)
367 {
368         grid_type *g_ptr;
369         floor_type *floor_ptr = target_ptr->current_floor_ptr;
370         monster_type *m_ptr = &floor_ptr->m_list[m_idx];
371         monster_race *r_ptr = &r_info[m_ptr->r_idx];
372
373         if (r_ptr->flags4 & (RF4_ATTACK_MASK) ||
374                 r_ptr->a_ability_flags1 & (RF5_ATTACK_MASK) ||
375                 r_ptr->a_ability_flags2 & (RF6_ATTACK_MASK))
376         {
377                 if (get_moves_aux2(target_ptr, m_idx, yp, xp)) return TRUE;
378         }
379
380         if (no_flow) return FALSE;
381         if ((r_ptr->flags2 & RF2_PASS_WALL) && ((m_idx != target_ptr->riding) || target_ptr->pass_wall)) return FALSE;
382         if ((r_ptr->flags2 & RF2_KILL_WALL) && (m_idx != target_ptr->riding)) return FALSE;
383
384         POSITION y1 = m_ptr->fy;
385         POSITION x1 = m_ptr->fx;
386         if (player_has_los_bold(target_ptr, y1, x1) && projectable(target_ptr, target_ptr->y, target_ptr->x, y1, x1)) return FALSE;
387
388         g_ptr = &floor_ptr->grid_array[y1][x1];
389
390         int best;
391         bool use_scent = FALSE;
392         if (g_ptr->cost)
393         {
394                 best = 999;
395         }
396         else if (g_ptr->when)
397         {
398                 if (floor_ptr->grid_array[target_ptr->y][target_ptr->x].when - g_ptr->when > 127) return FALSE;
399
400                 use_scent = TRUE;
401                 best = 0;
402         }
403         else
404         {
405                 return FALSE;
406         }
407
408         for (int i = 7; i >= 0; i--)
409         {
410                 POSITION y = y1 + ddy_ddd[i];
411                 POSITION x = x1 + ddx_ddd[i];
412
413                 if (!in_bounds2(floor_ptr, y, x)) continue;
414
415                 g_ptr = &floor_ptr->grid_array[y][x];
416                 if (use_scent)
417                 {
418                         int when = g_ptr->when;
419                         if (best > when) continue;
420
421                         best = when;
422                 }
423                 else
424                 {
425                         int cost;
426                         if (r_ptr->flags2 & (RF2_BASH_DOOR | RF2_OPEN_DOOR))
427                         {
428                                 cost = g_ptr->dist;
429                         }
430                         else
431                         {
432                                 cost = g_ptr->cost;
433                         }
434
435                         if ((cost == 0) || (best < cost)) continue;
436
437                         best = cost;
438                 }
439
440                 *yp = target_ptr->y + 16 * ddy_ddd[i];
441                 *xp = target_ptr->x + 16 * ddx_ddd[i];
442         }
443
444         if (best == 999 || best == 0) return FALSE;
445
446         return TRUE;
447 }
448
449
450 /*!
451  * @brief モンスターがプレイヤーから逃走することが可能なマスを走査する /
452  * Provide a location to flee to, but give the player a wide berth.
453  * @param m_idx モンスターの参照ID
454  * @param yp 移動先のマスのY座標を返す参照ポインタ
455  * @param xp 移動先のマスのX座標を返す参照ポインタ
456  * @return 有効なマスがあった場合TRUEを返す
457  * @details
458  * A monster may wish to flee to a location that is behind the player,\n
459  * but instead of heading directly for it, the monster should "swerve"\n
460  * around the player so that he has a smaller chance of getting hit.\n
461  */
462 static bool get_fear_moves_aux(floor_type *floor_ptr, MONSTER_IDX m_idx, POSITION *yp, POSITION *xp)
463 {
464         POSITION gy = 0, gx = 0;
465
466         monster_type *m_ptr = &floor_ptr->m_list[m_idx];
467         POSITION fy = m_ptr->fy;
468         POSITION fx = m_ptr->fx;
469
470         POSITION y1 = fy - (*yp);
471         POSITION x1 = fx - (*xp);
472
473         int score = -1;
474         for (int i = 7; i >= 0; i--)
475         {
476                 POSITION y = fy + ddy_ddd[i];
477                 POSITION x = fx + ddx_ddd[i];
478                 if (!in_bounds2(floor_ptr, y, x)) continue;
479
480                 POSITION dis = distance(y, x, y1, x1);
481                 POSITION s = 5000 / (dis + 3) - 500 / (floor_ptr->grid_array[y][x].dist + 1);
482                 if (s < 0) s = 0;
483
484                 if (s < score) continue;
485
486                 score = s;
487                 gy = y;
488                 gx = x;
489         }
490
491         if (score == -1) return FALSE;
492
493         (*yp) = fy - gy;
494         (*xp) = fx - gx;
495
496         return TRUE;
497 }
498
499
500 /*
501  * Hack -- Precompute a bunch of calls to distance() in find_safety() and
502  * find_hiding().
503  *
504  * The pair of arrays dist_offsets_y[n] and dist_offsets_x[n] contain the
505  * offsets of all the locations with a distance of n from a central point,
506  * with an offset of (0,0) indicating no more offsets at this distance.
507  *
508  * This is, of course, fairly unreadable, but it eliminates multiple loops
509  * from the previous version.
510  *
511  * It is probably better to replace these arrays with code to compute
512  * the relevant arrays, even if the storage is pre-allocated in hard
513  * coded sizes.  At the very least, code should be included which is
514  * able to generate and dump these arrays (ala "los()").
515  *
516  * Also, the storage needs could be halved by using bytes.
517  *
518  * These arrays could be combined into two big arrays, using sub-arrays
519  * to hold the offsets and lengths of each portion of the sub-arrays, and
520  * this could perhaps also be used somehow in the "look" code.
521  */
522
523
524 static POSITION d_off_y_0[] = { 0 };
525 static POSITION d_off_x_0[] = { 0 };
526
527 static POSITION d_off_y_1[] = { -1, -1, -1, 0, 0, 1, 1, 1, 0 };
528 static POSITION d_off_x_1[] = { -1, 0, 1, -1, 1, -1, 0, 1, 0 };
529
530 static POSITION d_off_y_2[] = { -1, -1, -2, -2, -2, 0, 0, 1, 1, 2, 2, 2, 0 };
531 static POSITION d_off_x_2[] = { -2, 2, -1, 0, 1, -2, 2, -2, 2, -1, 0, 1, 0 };
532
533 static POSITION d_off_y_3[] = { -1, -1, -2, -2, -3, -3, -3, 0, 0, 1, 1, 2, 2, 3, 3, 3, 0 };
534 static POSITION d_off_x_3[] = { -3, 3, -2, 2, -1, 0, 1, -3, 3, -3, 3, -2, 2, -1, 0, 1, 0 };
535
536 static POSITION d_off_y_4[] = { -1, -1, -2, -2, -3, -3, -3, -3, -4, -4, -4, 0, 0, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 0 };
537 static POSITION d_off_x_4[] = { -4, 4, -3, 3, -2, -3, 2, 3, -1, 0, 1, -4, 4, -4, 4, -3, 3, -2, -3, 2, 3, -1, 0, 1, 0 };
538
539
540 static POSITION d_off_y_5[] =
541 { -1, -1, -2, -2, -3, -3, -4, -4, -4, -4, -5, -5,
542   -5, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5,
543   5, 0 };
544
545 static POSITION d_off_x_5[] =
546 { -5, 5, -4, 4, -4, 4, -2, -3, 2, 3, -1, 0, 1,
547   -5, 5, -5, 5, -4, 4, -4, 4, -2, -3, 2, 3, -1,
548   0, 1, 0 };
549
550
551 static POSITION d_off_y_6[] =
552 { -1, -1, -2, -2, -3, -3, -4, -4, -5, -5, -5, -5,
553   -6, -6, -6, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5,
554   5, 5, 6, 6, 6, 0 };
555
556 static POSITION d_off_x_6[] =
557 { -6, 6, -5, 5, -5, 5, -4, 4, -2, -3, 2, 3, -1,
558   0, 1, -6, 6, -6, 6, -5, 5, -5, 5, -4, 4, -2,
559   -3, 2, 3, -1, 0, 1, 0 };
560
561
562 static POSITION d_off_y_7[] =
563 { -1, -1, -2, -2, -3, -3, -4, -4, -5, -5, -5, -5,
564   -6, -6, -6, -6, -7, -7, -7, 0, 0, 1, 1, 2, 2, 3,
565   3, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 0 };
566
567 static POSITION d_off_x_7[] =
568 { -7, 7, -6, 6, -6, 6, -5, 5, -4, -5, 4, 5, -2,
569   -3, 2, 3, -1, 0, 1, -7, 7, -7, 7, -6, 6, -6,
570   6, -5, 5, -4, -5, 4, 5, -2, -3, 2, 3, -1, 0,
571   1, 0 };
572
573
574 static POSITION d_off_y_8[] =
575 { -1, -1, -2, -2, -3, -3, -4, -4, -5, -5, -6, -6,
576   -6, -6, -7, -7, -7, -7, -8, -8, -8, 0, 0, 1, 1,
577   2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7,
578   8, 8, 8, 0 };
579
580 static POSITION d_off_x_8[] =
581 { -8, 8, -7, 7, -7, 7, -6, 6, -6, 6, -4, -5, 4,
582   5, -2, -3, 2, 3, -1, 0, 1, -8, 8, -8, 8, -7,
583   7, -7, 7, -6, 6, -6, 6, -4, -5, 4, 5, -2, -3,
584   2, 3, -1, 0, 1, 0 };
585
586
587 static POSITION d_off_y_9[] =
588 { -1, -1, -2, -2, -3, -3, -4, -4, -5, -5, -6, -6,
589   -7, -7, -7, -7, -8, -8, -8, -8, -9, -9, -9, 0,
590   0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 7,
591   7, 8, 8, 8, 8, 9, 9, 9, 0 };
592
593 static POSITION d_off_x_9[] =
594 { -9, 9, -8, 8, -8, 8, -7, 7, -7, 7, -6, 6, -4,
595   -5, 4, 5, -2, -3, 2, 3, -1, 0, 1, -9, 9, -9,
596   9, -8, 8, -8, 8, -7, 7, -7, 7, -6, 6, -4, -5,
597   4, 5, -2, -3, 2, 3, -1, 0, 1, 0 };
598
599
600 static POSITION *dist_offsets_y[10] =
601 {
602         d_off_y_0, d_off_y_1, d_off_y_2, d_off_y_3, d_off_y_4,
603         d_off_y_5, d_off_y_6, d_off_y_7, d_off_y_8, d_off_y_9
604 };
605
606 static POSITION *dist_offsets_x[10] =
607 {
608         d_off_x_0, d_off_x_1, d_off_x_2, d_off_x_3, d_off_x_4,
609         d_off_x_5, d_off_x_6, d_off_x_7, d_off_x_8, d_off_x_9
610 };
611
612 /*!
613  * @brief モンスターが逃げ込める安全な地点を返す /
614  * Choose a "safe" location near a monster for it to run toward.
615  * @param target_ptr プレーヤーへの参照ポインタ
616  * @param m_idx モンスターの参照ID
617  * @param yp 移動先のマスのY座標を返す参照ポインタ
618  * @param xp 移動先のマスのX座標を返す参照ポインタ
619  * @return 有効なマスがあった場合TRUEを返す
620  * @details
621  * A location is "safe" if it can be reached quickly and the player\n
622  * is not able to fire into it (it isn't a "clean shot").  So, this will\n
623  * cause monsters to "duck" behind walls.  Hopefully, monsters will also\n
624  * try to run towards corridor openings if they are in a room.\n
625  *\n
626  * This function may take lots of CPU time if lots of monsters are\n
627  * fleeing.\n
628  *\n
629  * Return TRUE if a safe location is available.\n
630  */
631 static bool find_safety(player_type *target_ptr, MONSTER_IDX m_idx, POSITION *yp, POSITION *xp)
632 {
633         floor_type *floor_ptr = target_ptr->current_floor_ptr;
634         monster_type *m_ptr = &floor_ptr->m_list[m_idx];
635
636         POSITION fy = m_ptr->fy;
637         POSITION fx = m_ptr->fx;
638
639         POSITION gy = 0, gx = 0, gdis = 0;
640
641         for (POSITION d = 1; d < 10; d++)
642         {
643                 POSITION *y_offsets;
644                 y_offsets = dist_offsets_y[d];
645
646                 POSITION *x_offsets;
647                 x_offsets = dist_offsets_x[d];
648
649                 for (POSITION i = 0, dx = x_offsets[0], dy = y_offsets[0];
650                         dx != 0 || dy != 0;
651                         i++, dx = x_offsets[i], dy = y_offsets[i])
652                 {
653                         POSITION y = fy + dy;
654                         POSITION x = fx + dx;
655                         if (!in_bounds(floor_ptr, y, x)) continue;
656
657                         grid_type *g_ptr;
658                         g_ptr = &floor_ptr->grid_array[y][x];
659
660                         BIT_FLAGS16 riding_mode = (m_idx == target_ptr->riding) ? CEM_RIDING : 0;
661                         if (!monster_can_cross_terrain(target_ptr, g_ptr->feat, &r_info[m_ptr->r_idx], riding_mode))
662                                 continue;
663
664                         if (!(m_ptr->mflag2 & MFLAG2_NOFLOW))
665                         {
666                                 if (g_ptr->dist == 0) continue;
667                                 if (g_ptr->dist > floor_ptr->grid_array[fy][fx].dist + 2 * d) continue;
668                         }
669
670                         if (projectable(target_ptr, target_ptr->y, target_ptr->x, y, x)) continue;
671
672                         POSITION dis = distance(y, x, target_ptr->y, target_ptr->x);
673                         if (dis <= gdis) continue;
674
675                         gy = y;
676                         gx = x;
677                         gdis = dis;
678                 }
679
680                 if (gdis <= 0) continue;
681
682                 *yp = fy - gy;
683                 *xp = fx - gx;
684
685                 return TRUE;
686         }
687
688         return FALSE;
689 }
690
691
692 /*!
693  * @brief モンスターが隠れ潜める地点を返す /
694  * Choose a good hiding place near a monster for it to run toward.
695  * @param target_ptr プレーヤーへの参照ポインタ
696  * @param m_idx モンスターの参照ID
697  * @param yp 移動先のマスのY座標を返す参照ポインタ
698  * @param xp 移動先のマスのX座標を返す参照ポインタ
699  * @return 有効なマスがあった場合TRUEを返す
700  * @details
701  * Pack monsters will use this to "ambush" the player and lure him out\n
702  * of corridors into open space so they can swarm him.\n
703  *\n
704  * Return TRUE if a good location is available.\n
705  */
706 static bool find_hiding(player_type *target_ptr, MONSTER_IDX m_idx, POSITION *yp, POSITION *xp)
707 {
708         floor_type *floor_ptr = target_ptr->current_floor_ptr;
709         monster_type *m_ptr = &floor_ptr->m_list[m_idx];
710         monster_race *r_ptr = &r_info[m_ptr->r_idx];
711
712         POSITION fy = m_ptr->fy;
713         POSITION fx = m_ptr->fx;
714
715         POSITION gy = 0, gx = 0, gdis = 999;
716
717         for (POSITION d = 1; d < 10; d++)
718         {
719                 POSITION *y_offsets;
720                 y_offsets = dist_offsets_y[d];
721
722                 POSITION *x_offsets;
723                 x_offsets = dist_offsets_x[d];
724
725                 for (POSITION i = 0, dx = x_offsets[0], dy = y_offsets[0];
726                         dx != 0 || dy != 0;
727                         i++, dx = x_offsets[i], dy = y_offsets[i])
728                 {
729                         POSITION y = fy + dy;
730                         POSITION x = fx + dx;
731
732                         if (!in_bounds(floor_ptr, y, x)) continue;
733                         if (!monster_can_enter(target_ptr, y, x, r_ptr, 0)) continue;
734                         if (projectable(target_ptr, target_ptr->y, target_ptr->x, y, x) && clean_shot(target_ptr, fy, fx, y, x, FALSE))
735                                 continue;
736
737                         POSITION dis = distance(y, x, target_ptr->y, target_ptr->x);
738                         if (dis < gdis && dis >= 2)
739                         {
740                                 gy = y;
741                                 gx = x;
742                                 gdis = dis;
743                         }
744                 }
745
746                 if (gdis >= 999) continue;
747
748                 *yp = fy - gy;
749                 *xp = fx - gx;
750
751                 return TRUE;
752         }
753
754         return FALSE;
755 }
756
757
758 /*!
759  * @brief モンスターの移動方向を返す /
760  * Choose "logical" directions for monster movement
761  * @param target_ptr プレーヤーへの参照ポインタ
762  * @param m_idx モンスターの参照ID
763  * @param mm 移動方向を返す方向IDの参照ポインタ
764  * @return 有効方向があった場合TRUEを返す
765  */
766 static bool get_moves(player_type *target_ptr, MONSTER_IDX m_idx, DIRECTION *mm)
767 {
768         floor_type *floor_ptr = target_ptr->current_floor_ptr;
769         monster_type *m_ptr = &floor_ptr->m_list[m_idx];
770         monster_race *r_ptr = &r_info[m_ptr->r_idx];
771         POSITION y = 0, ay, x = 0, ax;
772         POSITION y2 = target_ptr->y;
773         POSITION x2 = target_ptr->x;
774         bool done = FALSE;
775         bool will_run = mon_will_run(target_ptr, m_idx);
776         grid_type *g_ptr;
777         bool no_flow = ((m_ptr->mflag2 & MFLAG2_NOFLOW) != 0) && (floor_ptr->grid_array[m_ptr->fy][m_ptr->fx].cost > 2);
778         bool can_pass_wall = ((r_ptr->flags2 & RF2_PASS_WALL) != 0) && ((m_idx != target_ptr->riding) || target_ptr->pass_wall);
779
780         if (!will_run && m_ptr->target_y)
781         {
782                 int t_m_idx = floor_ptr->grid_array[m_ptr->target_y][m_ptr->target_x].m_idx;
783                 if ((t_m_idx > 0) &&
784                         are_enemies(target_ptr, m_ptr, &floor_ptr->m_list[t_m_idx]) &&
785                         los(target_ptr, m_ptr->fy, m_ptr->fx, m_ptr->target_y, m_ptr->target_x) &&
786                         projectable(target_ptr, m_ptr->fy, m_ptr->fx, m_ptr->target_y, m_ptr->target_x))
787                 {
788                         y = m_ptr->fy - m_ptr->target_y;
789                         x = m_ptr->fx - m_ptr->target_x;
790                         done = TRUE;
791                 }
792         }
793
794         if (!done && !will_run && is_hostile(m_ptr) &&
795                 (r_ptr->flags1 & RF1_FRIENDS) &&
796                 ((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)) ||
797                 (floor_ptr->grid_array[m_ptr->fy][m_ptr->fx].dist < MAX_SIGHT / 2)))
798         {
799                 if ((r_ptr->flags3 & RF3_ANIMAL) && !can_pass_wall &&
800                         !(r_ptr->flags2 & RF2_KILL_WALL))
801                 {
802                         int room = 0;
803                         for (int i = 0; i < 8; i++)
804                         {
805                                 int xx = target_ptr->x + ddx_ddd[i];
806                                 int yy = target_ptr->y + ddy_ddd[i];
807
808                                 if (!in_bounds2(floor_ptr, yy, xx)) continue;
809
810                                 g_ptr = &floor_ptr->grid_array[yy][xx];
811                                 if (monster_can_cross_terrain(target_ptr, g_ptr->feat, r_ptr, 0))
812                                 {
813                                         room++;
814                                 }
815                         }
816
817                         if (floor_ptr->grid_array[target_ptr->y][target_ptr->x].info & CAVE_ROOM) room -= 2;
818                         if (!r_ptr->flags4 && !r_ptr->a_ability_flags1 && !r_ptr->a_ability_flags2) room -= 2;
819
820                         if (room < (8 * (target_ptr->chp + target_ptr->csp)) /
821                                 (target_ptr->mhp + target_ptr->msp))
822                         {
823                                 if (find_hiding(target_ptr, m_idx, &y, &x)) done = TRUE;
824                         }
825                 }
826
827                 if (!done && (floor_ptr->grid_array[m_ptr->fy][m_ptr->fx].dist < 3))
828                 {
829                         for (int i = 0; i < 8; i++)
830                         {
831                                 y2 = target_ptr->y + ddy_ddd[(m_idx + i) & 7];
832                                 x2 = target_ptr->x + ddx_ddd[(m_idx + i) & 7];
833                                 if ((m_ptr->fy == y2) && (m_ptr->fx == x2))
834                                 {
835                                         y2 = target_ptr->y;
836                                         x2 = target_ptr->x;
837                                         break;
838                                 }
839
840                                 if (!in_bounds2(floor_ptr, y2, x2)) continue;
841                                 if (!monster_can_enter(target_ptr, y2, x2, r_ptr, 0)) continue;
842
843                                 break;
844                         }
845
846                         y = m_ptr->fy - y2;
847                         x = m_ptr->fx - x2;
848                         done = TRUE;
849                 }
850         }
851
852         if (!done)
853         {
854                 (void)get_moves_aux(target_ptr, m_idx, &y2, &x2, no_flow);
855                 y = m_ptr->fy - y2;
856                 x = m_ptr->fx - x2;
857         }
858
859         if (is_pet(m_ptr) && will_run)
860         {
861                 y = (-y), x = (-x);
862         }
863         else
864         {
865                 if (!done && will_run)
866                 {
867                         int tmp_x = (-x);
868                         int tmp_y = (-y);
869                         if (find_safety(target_ptr, m_idx, &y, &x) && !no_flow)
870                         {
871                                 if (get_fear_moves_aux(target_ptr->current_floor_ptr, m_idx, &y, &x))
872                                         done = TRUE;
873                         }
874
875                         if (!done)
876                         {
877                                 y = tmp_y;
878                                 x = tmp_x;
879                         }
880                 }
881         }
882
883         if (!x && !y) return FALSE;
884
885         ax = ABS(x);
886         ay = ABS(y);
887
888         int move_val = 0;
889         if (y < 0) move_val += 8;
890         if (x > 0) move_val += 4;
891
892         if (ay > (ax << 1)) move_val += 2;
893         else if (ax > (ay << 1)) move_val++;
894
895         switch (move_val)
896         {
897         case 0:
898                 mm[0] = 9;
899                 if (ay > ax)
900                 {
901                         mm[1] = 8;
902                         mm[2] = 6;
903                         mm[3] = 7;
904                         mm[4] = 3;
905                 }
906                 else
907                 {
908                         mm[1] = 6;
909                         mm[2] = 8;
910                         mm[3] = 3;
911                         mm[4] = 7;
912                 }
913                 break;
914         case 1:
915         case 9:
916                 mm[0] = 6;
917                 if (y < 0)
918                 {
919                         mm[1] = 3;
920                         mm[2] = 9;
921                         mm[3] = 2;
922                         mm[4] = 8;
923                 }
924                 else
925                 {
926                         mm[1] = 9;
927                         mm[2] = 3;
928                         mm[3] = 8;
929                         mm[4] = 2;
930                 }
931                 break;
932         case 2:
933         case 6:
934                 mm[0] = 8;
935                 if (x < 0)
936                 {
937                         mm[1] = 9;
938                         mm[2] = 7;
939                         mm[3] = 6;
940                         mm[4] = 4;
941                 }
942                 else
943                 {
944                         mm[1] = 7;
945                         mm[2] = 9;
946                         mm[3] = 4;
947                         mm[4] = 6;
948                 }
949                 break;
950         case 4:
951                 mm[0] = 7;
952                 if (ay > ax)
953                 {
954                         mm[1] = 8;
955                         mm[2] = 4;
956                         mm[3] = 9;
957                         mm[4] = 1;
958                 }
959                 else
960                 {
961                         mm[1] = 4;
962                         mm[2] = 8;
963                         mm[3] = 1;
964                         mm[4] = 9;
965                 }
966                 break;
967         case 5:
968         case 13:
969                 mm[0] = 4;
970                 if (y < 0)
971                 {
972                         mm[1] = 1;
973                         mm[2] = 7;
974                         mm[3] = 2;
975                         mm[4] = 8;
976                 }
977                 else
978                 {
979                         mm[1] = 7;
980                         mm[2] = 1;
981                         mm[3] = 8;
982                         mm[4] = 2;
983                 }
984                 break;
985         case 8:
986                 mm[0] = 3;
987                 if (ay > ax)
988                 {
989                         mm[1] = 2;
990                         mm[2] = 6;
991                         mm[3] = 1;
992                         mm[4] = 9;
993                 }
994                 else
995                 {
996                         mm[1] = 6;
997                         mm[2] = 2;
998                         mm[3] = 9;
999                         mm[4] = 1;
1000                 }
1001                 break;
1002         case 10:
1003         case 14:
1004                 mm[0] = 2;
1005                 if (x < 0)
1006                 {
1007                         mm[1] = 3;
1008                         mm[2] = 1;
1009                         mm[3] = 6;
1010                         mm[4] = 4;
1011                 }
1012                 else
1013                 {
1014                         mm[1] = 1;
1015                         mm[2] = 3;
1016                         mm[3] = 4;
1017                         mm[4] = 6;
1018                 }
1019                 break;
1020         case 12:
1021                 mm[0] = 1;
1022                 if (ay > ax)
1023                 {
1024                         mm[1] = 2;
1025                         mm[2] = 4;
1026                         mm[3] = 3;
1027                         mm[4] = 7;
1028                 }
1029                 else
1030                 {
1031                         mm[1] = 4;
1032                         mm[2] = 2;
1033                         mm[3] = 7;
1034                         mm[4] = 3;
1035                 }
1036                 break;
1037         }
1038
1039         return TRUE;
1040 }
1041
1042
1043 static bool check_hp_for_feat_destruction(feature_type *f_ptr, monster_type *m_ptr)
1044 {
1045         return !have_flag(f_ptr->flags, FF_GLASS) ||
1046                 (r_info[m_ptr->r_idx].flags2 & RF2_STUPID) ||
1047                 (m_ptr->hp >= MAX(m_ptr->maxhp / 3, 200));
1048 }
1049
1050
1051 /*!
1052  * @brief モンスター単体の1ターン行動処理メインルーチン /
1053  * Process a monster
1054  * @param target_ptr プレーヤーへの参照ポインタ
1055  * @param m_idx 行動モンスターの参照ID
1056  * @return なし
1057  * @details
1058  * The monster is known to be within 100 grids of the player\n
1059  *\n
1060  * In several cases, we directly update the monster lore\n
1061  *\n
1062  * Note that a monster is only allowed to "reproduce" if there\n
1063  * are a limited number of "reproducing" monsters on the current\n
1064  * level.  This should prevent the level from being "swamped" by\n
1065  * reproducing monsters.  It also allows a large mass of mice to\n
1066  * prevent a louse from multiplying, but this is a small price to\n
1067  * pay for a simple multiplication method.\n
1068  *\n
1069  * XXX Monster fear is slightly odd, in particular, monsters will\n
1070  * fixate on opening a door even if they cannot open it.  Actually,\n
1071  * the same thing happens to normal monsters when they hit a door\n
1072  *\n
1073  * In addition, monsters which *cannot* open or bash\n
1074  * down a door will still stand there trying to open it...\n
1075  *\n
1076  * XXX Technically, need to check for monster in the way\n
1077  * combined with that monster being in a wall (or door?)\n
1078  *\n
1079  * A "direction" of "5" means "pick a random direction".\n
1080  */
1081 void process_monster(player_type *target_ptr, MONSTER_IDX m_idx)
1082 {
1083         monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
1084         monster_race *r_ptr = &r_info[m_ptr->r_idx];
1085         monster_race *ap_r_ptr = &r_info[m_ptr->ap_r_idx];
1086         DIRECTION mm[8];
1087
1088         turn_flags tmp_flags;
1089         turn_flags *turn_flags_ptr = &tmp_flags;
1090         turn_flags_ptr->is_riding_mon = (m_idx == target_ptr->riding);
1091         turn_flags_ptr->do_turn = FALSE;
1092         turn_flags_ptr->do_move = FALSE;
1093         turn_flags_ptr->do_view = FALSE;
1094         turn_flags_ptr->must_alter_to_move = FALSE;
1095         turn_flags_ptr->did_open_door = FALSE;
1096         turn_flags_ptr->did_bash_door = FALSE;
1097         turn_flags_ptr->did_take_item = FALSE;
1098         turn_flags_ptr->did_kill_item = FALSE;
1099         turn_flags_ptr->did_move_body = FALSE;
1100         turn_flags_ptr->did_pass_wall = FALSE;
1101         turn_flags_ptr->did_kill_wall = FALSE;
1102
1103         bool see_m = is_seen(m_ptr);
1104
1105         decide_drop_from_monster(target_ptr, m_idx, turn_flags_ptr->is_riding_mon);
1106         if ((m_ptr->mflag2 & MFLAG2_CHAMELEON) && one_in_(13) && !MON_CSLEEP(m_ptr))
1107         {
1108                 choose_new_monster(target_ptr, m_idx, FALSE, 0);
1109                 r_ptr = &r_info[m_ptr->r_idx];
1110         }
1111
1112         bool aware = TRUE;
1113         if (target_ptr->special_defense & NINJA_S_STEALTH)
1114         {
1115                 int tmp = target_ptr->lev * 6 + (target_ptr->skill_stl + 10) * 4;
1116                 if (target_ptr->monlite) tmp /= 3;
1117                 if (target_ptr->cursed & TRC_AGGRAVATE) tmp /= 2;
1118                 if (r_ptr->level > (target_ptr->lev * target_ptr->lev / 20 + 10)) tmp /= 3;
1119                 if (randint0(tmp) > (r_ptr->level + 20)) aware = FALSE;
1120         }
1121
1122         if (vanish_summoned_children(target_ptr, m_idx, see_m)) return;
1123         if (process_quantum_effect(target_ptr,m_idx, see_m)) return;
1124
1125         if (m_ptr->r_idx == MON_SHURYUUDAN)
1126         {
1127                 bool fear, dead;
1128                 mon_take_hit_mon(target_ptr, m_idx, 1, &dead, &fear, _("は爆発して粉々になった。", " explodes into tiny shreds."), m_idx);
1129                 if (dead) return;
1130         }
1131
1132         if (runaway_monster(target_ptr, m_idx, turn_flags_ptr->is_riding_mon, see_m)) return;
1133
1134         awake_monster(target_ptr, m_idx);
1135
1136         if (MON_STUNNED(m_ptr))
1137         {
1138                 if (one_in_(2)) return;
1139         }
1140
1141         if (turn_flags_ptr->is_riding_mon)
1142         {
1143                 target_ptr->update |= (PU_BONUS);
1144         }
1145
1146         process_angar(target_ptr, m_idx, see_m);
1147
1148         POSITION oy = m_ptr->fy;
1149         POSITION ox = m_ptr->fx;
1150         if (decide_monster_multiplication(target_ptr, m_idx, oy, ox)) return;
1151
1152         process_special(target_ptr, m_idx);
1153         process_speak_sound(target_ptr, m_idx, oy, ox, aware);
1154         if (cast_spell(target_ptr, m_idx, aware)) return;
1155
1156         mm[0] = mm[1] = mm[2] = mm[3] = 0;
1157         mm[4] = mm[5] = mm[6] = mm[7] = 0;
1158
1159         if (!decide_monster_movement_direction(target_ptr, mm, m_idx, aware)) return;
1160
1161         int i;
1162         for (i = 0; mm[i]; i++)
1163         {
1164                 int d = mm[i];
1165                 if (d == 5) d = ddd[randint0(8)];
1166
1167                 POSITION ny = oy + ddy[d];
1168                 POSITION nx = ox + ddx[d];
1169                 if (!in_bounds2(target_ptr->current_floor_ptr, ny, nx)) continue;
1170
1171                 grid_type *g_ptr;
1172                 g_ptr = &target_ptr->current_floor_ptr->grid_array[ny][nx];
1173                 feature_type *f_ptr;
1174                 f_ptr = &f_info[g_ptr->feat];
1175                 bool can_cross = monster_can_cross_terrain(target_ptr, g_ptr->feat, r_ptr, turn_flags_ptr->is_riding_mon ? CEM_RIDING : 0);
1176                 monster_type *y_ptr;
1177                 y_ptr = &target_ptr->current_floor_ptr->m_list[g_ptr->m_idx];
1178
1179                 if (!process_wall(target_ptr, turn_flags_ptr, m_ptr, ny, nx, can_cross))
1180                 {
1181                         if (!process_door(target_ptr, turn_flags_ptr, m_ptr, ny, nx))
1182                                 return;
1183                 }
1184
1185                 if (!process_protection_rune(target_ptr, turn_flags_ptr, m_ptr, ny, nx))
1186                 {
1187                         if (!process_explosive_rune(target_ptr, turn_flags_ptr, m_ptr, ny, nx))
1188                                 return;
1189                 }
1190
1191                 if (turn_flags_ptr->do_move && player_bold(target_ptr, ny, nx))
1192                 {
1193                         if (r_ptr->flags1 & RF1_NEVER_BLOW)
1194                         {
1195                                 if (is_original_ap_and_seen(target_ptr, m_ptr)) r_ptr->r_flags1 |= (RF1_NEVER_BLOW);
1196
1197                                 turn_flags_ptr->do_move = FALSE;
1198                         }
1199
1200                         if (turn_flags_ptr->do_move && (d_info[target_ptr->dungeon_idx].flags1 & DF1_NO_MELEE))
1201                         {
1202                                 if (!MON_CONFUSED(m_ptr))
1203                                 {
1204                                         if (!(r_ptr->flags2 & RF2_STUPID)) turn_flags_ptr->do_move = FALSE;
1205                                         else
1206                                         {
1207                                                 if (is_original_ap_and_seen(target_ptr, m_ptr)) r_ptr->r_flags2 |= (RF2_STUPID);
1208                                         }
1209                                 }
1210                         }
1211
1212                         if (turn_flags_ptr->do_move)
1213                         {
1214                                 if (!target_ptr->riding || one_in_(2))
1215                                 {
1216                                         (void)make_attack_normal(target_ptr, m_idx);
1217                                         turn_flags_ptr->do_move = FALSE;
1218                                         turn_flags_ptr->do_turn = TRUE;
1219                                 }
1220                         }
1221                 }
1222
1223                 if (turn_flags_ptr->do_move && g_ptr->m_idx)
1224                 {
1225                         monster_race *z_ptr = &r_info[y_ptr->r_idx];
1226                         turn_flags_ptr->do_move = FALSE;
1227                         if (((r_ptr->flags2 & RF2_KILL_BODY) && !(r_ptr->flags1 & RF1_NEVER_BLOW) &&
1228                                 (r_ptr->mexp * r_ptr->level > z_ptr->mexp * z_ptr->level) &&
1229                                 can_cross && (g_ptr->m_idx != target_ptr->riding)) ||
1230                                 are_enemies(target_ptr, m_ptr, y_ptr) || MON_CONFUSED(m_ptr))
1231                         {
1232                                 if (!(r_ptr->flags1 & RF1_NEVER_BLOW))
1233                                 {
1234                                         if (r_ptr->flags2 & RF2_KILL_BODY)
1235                                         {
1236                                                 if (is_original_ap_and_seen(target_ptr, m_ptr)) r_ptr->r_flags2 |= (RF2_KILL_BODY);
1237                                         }
1238
1239                                         if (y_ptr->r_idx && (y_ptr->hp >= 0))
1240                                         {
1241                                                 if (monst_attack_monst(target_ptr, m_idx, g_ptr->m_idx)) return;
1242
1243                                                 if (d_info[target_ptr->dungeon_idx].flags1 & DF1_NO_MELEE)
1244                                                 {
1245                                                         if (MON_CONFUSED(m_ptr)) return;
1246                                                         if (r_ptr->flags2 & RF2_STUPID)
1247                                                         {
1248                                                                 if (is_original_ap_and_seen(target_ptr, m_ptr)) r_ptr->r_flags2 |= (RF2_STUPID);
1249                                                                 return;
1250                                                         }
1251                                                 }
1252                                         }
1253                                 }
1254                         }
1255                         else if ((r_ptr->flags2 & RF2_MOVE_BODY) && !(r_ptr->flags1 & RF1_NEVER_MOVE) &&
1256                                 (r_ptr->mexp > z_ptr->mexp) &&
1257                                 can_cross && (g_ptr->m_idx != target_ptr->riding) &&
1258                                 monster_can_cross_terrain(target_ptr, target_ptr->current_floor_ptr->grid_array[m_ptr->fy][m_ptr->fx].feat, z_ptr, 0))
1259                         {
1260                                 turn_flags_ptr->do_move = TRUE;
1261                                 turn_flags_ptr->did_move_body = TRUE;
1262                                 (void)set_monster_csleep(target_ptr, g_ptr->m_idx, 0);
1263                         }
1264                 }
1265
1266                 if (turn_flags_ptr->is_riding_mon)
1267                 {
1268                         if (!target_ptr->riding_ryoute && !MON_MONFEAR(&target_ptr->current_floor_ptr->m_list[target_ptr->riding])) turn_flags_ptr->do_move = FALSE;
1269                 }
1270
1271                 if (turn_flags_ptr->did_kill_wall && turn_flags_ptr->do_move)
1272                 {
1273                         if (one_in_(GRINDNOISE))
1274                         {
1275                                 if (have_flag(f_ptr->flags, FF_GLASS))
1276                                         msg_print(_("何かの砕ける音が聞こえる。", "There is a crashing sound."));
1277                                 else
1278                                         msg_print(_("ギシギシいう音が聞こえる。", "There is a grinding sound."));
1279                         }
1280
1281                         cave_alter_feat(target_ptr, ny, nx, FF_HURT_DISI);
1282
1283                         if (!monster_is_valid(m_ptr))
1284                         {
1285                                 target_ptr->update |= (PU_FLOW);
1286                                 target_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
1287                                 if (is_original_ap_and_seen(target_ptr, m_ptr)) r_ptr->r_flags2 |= (RF2_KILL_WALL);
1288
1289                                 return;
1290                         }
1291
1292                         f_ptr = &f_info[g_ptr->feat];
1293                         turn_flags_ptr->do_view = TRUE;
1294                         turn_flags_ptr->do_turn = TRUE;
1295                 }
1296
1297                 if (turn_flags_ptr->must_alter_to_move && (r_ptr->flags7 & RF7_AQUATIC))
1298                 {
1299                         if (!monster_can_cross_terrain(target_ptr, g_ptr->feat, r_ptr, turn_flags_ptr->is_riding_mon ? CEM_RIDING : 0))
1300                         {
1301                                 turn_flags_ptr->do_move = FALSE;
1302                         }
1303                 }
1304
1305                 if (turn_flags_ptr->do_move && !can_cross && !turn_flags_ptr->did_kill_wall && !turn_flags_ptr->did_bash_door)
1306                 {
1307                         turn_flags_ptr->do_move = FALSE;
1308                 }
1309
1310                 if (turn_flags_ptr->do_move && (r_ptr->flags1 & RF1_NEVER_MOVE))
1311                 {
1312                         if (is_original_ap_and_seen(target_ptr, m_ptr)) r_ptr->r_flags1 |= (RF1_NEVER_MOVE);
1313
1314                         turn_flags_ptr->do_move = FALSE;
1315                 }
1316
1317                 if (!turn_flags_ptr->do_move)
1318                 {
1319                         if (turn_flags_ptr->do_turn) break;
1320
1321                         continue;
1322                 }
1323
1324                 turn_flags_ptr->do_turn = TRUE;
1325                 if (have_flag(f_ptr->flags, FF_TREE))
1326                 {
1327                         if (!(r_ptr->flags7 & RF7_CAN_FLY) && !(r_ptr->flags8 & RF8_WILD_WOOD))
1328                         {
1329                                 m_ptr->energy_need += ENERGY_NEED();
1330                         }
1331                 }
1332
1333                 if (!turn_flags_ptr->is_riding_mon)
1334                 {
1335                         target_ptr->current_floor_ptr->grid_array[oy][ox].m_idx = g_ptr->m_idx;
1336                         if (g_ptr->m_idx)
1337                         {
1338                                 y_ptr->fy = oy;
1339                                 y_ptr->fx = ox;
1340                                 update_monster(target_ptr, g_ptr->m_idx, TRUE);
1341                         }
1342
1343                         g_ptr->m_idx = m_idx;
1344                         m_ptr->fy = ny;
1345                         m_ptr->fx = nx;
1346                         update_monster(target_ptr, m_idx, TRUE);
1347
1348                         lite_spot(target_ptr, oy, ox);
1349                         lite_spot(target_ptr, ny, nx);
1350                 }
1351                 else
1352                 {
1353                         if (!move_player_effect(target_ptr, ny, nx, MPE_DONT_PICKUP)) break;
1354                 }
1355
1356                 if (m_ptr->ml &&
1357                         (disturb_move ||
1358                         (disturb_near && (m_ptr->mflag & MFLAG_VIEW) && projectable(target_ptr, target_ptr->y, target_ptr->x, m_ptr->fy, m_ptr->fx)) ||
1359                                 (disturb_high && ap_r_ptr->r_tkills && ap_r_ptr->level >= target_ptr->lev)))
1360                 {
1361                         if (is_hostile(m_ptr))
1362                                 disturb(target_ptr, FALSE, TRUE);
1363                 }
1364
1365                 bool is_takable_or_killable = g_ptr->o_idx > 0;
1366                 is_takable_or_killable &= (r_ptr->flags2 & (RF2_TAKE_ITEM | RF2_KILL_ITEM)) != 0;
1367
1368                 bool is_pickup_items = (target_ptr->pet_extra_flags & PF_PICKUP_ITEMS) != 0;
1369                 is_pickup_items &= (r_ptr->flags2 & RF2_TAKE_ITEM) != 0;
1370
1371                 is_takable_or_killable &= !is_pet(m_ptr) || is_pickup_items;
1372                 if (!is_takable_or_killable)
1373                 {
1374                         if (turn_flags_ptr->do_turn) break;
1375
1376                         continue;
1377                 }
1378
1379                 OBJECT_IDX this_o_idx, next_o_idx;
1380                 turn_flags_ptr->do_take = (r_ptr->flags2 & RF2_TAKE_ITEM) != 0;
1381                 for (this_o_idx = g_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
1382                 {
1383                         BIT_FLAGS flgs[TR_FLAG_SIZE], flg2 = 0L, flg3 = 0L, flgr = 0L;
1384                         GAME_TEXT m_name[MAX_NLEN], o_name[MAX_NLEN];
1385                         object_type *o_ptr = &target_ptr->current_floor_ptr->o_list[this_o_idx];
1386                         next_o_idx = o_ptr->next_o_idx;
1387
1388                         if (turn_flags_ptr->do_take)
1389                         {
1390                                 /* Skip gold, corpse and statue */
1391                                 if (o_ptr->tval == TV_GOLD || (o_ptr->tval == TV_CORPSE) || (o_ptr->tval == TV_STATUE))
1392                                         continue;
1393                         }
1394
1395                         object_flags(o_ptr, flgs);
1396                         object_desc(target_ptr, o_name, o_ptr, 0);
1397                         monster_desc(target_ptr, m_name, m_ptr, MD_INDEF_HIDDEN);
1398
1399                         if (have_flag(flgs, TR_SLAY_DRAGON)) flg3 |= (RF3_DRAGON);
1400                         if (have_flag(flgs, TR_KILL_DRAGON)) flg3 |= (RF3_DRAGON);
1401                         if (have_flag(flgs, TR_SLAY_TROLL))  flg3 |= (RF3_TROLL);
1402                         if (have_flag(flgs, TR_KILL_TROLL))  flg3 |= (RF3_TROLL);
1403                         if (have_flag(flgs, TR_SLAY_GIANT))  flg3 |= (RF3_GIANT);
1404                         if (have_flag(flgs, TR_KILL_GIANT))  flg3 |= (RF3_GIANT);
1405                         if (have_flag(flgs, TR_SLAY_ORC))    flg3 |= (RF3_ORC);
1406                         if (have_flag(flgs, TR_KILL_ORC))    flg3 |= (RF3_ORC);
1407                         if (have_flag(flgs, TR_SLAY_DEMON))  flg3 |= (RF3_DEMON);
1408                         if (have_flag(flgs, TR_KILL_DEMON))  flg3 |= (RF3_DEMON);
1409                         if (have_flag(flgs, TR_SLAY_UNDEAD)) flg3 |= (RF3_UNDEAD);
1410                         if (have_flag(flgs, TR_KILL_UNDEAD)) flg3 |= (RF3_UNDEAD);
1411                         if (have_flag(flgs, TR_SLAY_ANIMAL)) flg3 |= (RF3_ANIMAL);
1412                         if (have_flag(flgs, TR_KILL_ANIMAL)) flg3 |= (RF3_ANIMAL);
1413                         if (have_flag(flgs, TR_SLAY_EVIL))   flg3 |= (RF3_EVIL);
1414                         if (have_flag(flgs, TR_KILL_EVIL))   flg3 |= (RF3_EVIL);
1415                         if (have_flag(flgs, TR_SLAY_HUMAN))  flg2 |= (RF2_HUMAN);
1416                         if (have_flag(flgs, TR_KILL_HUMAN))  flg2 |= (RF2_HUMAN);
1417                         if (have_flag(flgs, TR_BRAND_ACID))  flgr |= (RFR_IM_ACID);
1418                         if (have_flag(flgs, TR_BRAND_ELEC))  flgr |= (RFR_IM_ELEC);
1419                         if (have_flag(flgs, TR_BRAND_FIRE))  flgr |= (RFR_IM_FIRE);
1420                         if (have_flag(flgs, TR_BRAND_COLD))  flgr |= (RFR_IM_COLD);
1421                         if (have_flag(flgs, TR_BRAND_POIS))  flgr |= (RFR_IM_POIS);
1422
1423                         if (object_is_artifact(o_ptr) || (r_ptr->flags3 & flg3) || (r_ptr->flags2 & flg2) ||
1424                                 ((~(r_ptr->flagsr) & flgr) && !(r_ptr->flagsr & RFR_RES_ALL)))
1425                         {
1426                                 if (turn_flags_ptr->do_take && (r_ptr->flags2 & RF2_STUPID))
1427                                 {
1428                                         turn_flags_ptr->did_take_item = TRUE;
1429                                         if (m_ptr->ml && player_can_see_bold(target_ptr, ny, nx))
1430                                         {
1431                                                 msg_format(_("%^sは%sを拾おうとしたが、だめだった。", "%^s tries to pick up %s, but fails."), m_name, o_name);
1432                                         }
1433                                 }
1434                         }
1435                         else if (turn_flags_ptr->do_take)
1436                         {
1437                                 turn_flags_ptr->did_take_item = TRUE;
1438                                 if (player_can_see_bold(target_ptr, ny, nx))
1439                                 {
1440                                         msg_format(_("%^sが%sを拾った。", "%^s picks up %s."), m_name, o_name);
1441                                 }
1442
1443                                 excise_object_idx(target_ptr->current_floor_ptr, this_o_idx);
1444                                 o_ptr->marked &= OM_TOUCHED;
1445                                 o_ptr->iy = o_ptr->ix = 0;
1446                                 o_ptr->held_m_idx = m_idx;
1447                                 o_ptr->next_o_idx = m_ptr->hold_o_idx;
1448                                 m_ptr->hold_o_idx = this_o_idx;
1449                         }
1450                         else if (!is_pet(m_ptr))
1451                         {
1452                                 turn_flags_ptr->did_kill_item = TRUE;
1453                                 if (player_has_los_bold(target_ptr, ny, nx))
1454                                 {
1455                                         msg_format(_("%^sが%sを破壊した。", "%^s destroys %s."), m_name, o_name);
1456                                 }
1457
1458                                 delete_object_idx(target_ptr, this_o_idx);
1459                         }
1460                 }
1461
1462                 if (turn_flags_ptr->do_turn) break;
1463         }
1464
1465         /*
1466          *  Forward movements failed, but now received LOS attack!
1467          *  Try to flow by smell.
1468          */
1469         if (target_ptr->no_flowed && i > 2 && m_ptr->target_y)
1470                 m_ptr->mflag2 &= ~MFLAG2_NOFLOW;
1471
1472         if (!turn_flags_ptr->do_turn && !turn_flags_ptr->do_move && !MON_MONFEAR(m_ptr) && !turn_flags_ptr->is_riding_mon && aware)
1473         {
1474                 if (r_ptr->freq_spell && randint1(100) <= r_ptr->freq_spell)
1475                 {
1476                         if (make_attack_spell(m_idx, target_ptr)) return;
1477                 }
1478         }
1479
1480         if (turn_flags_ptr->do_view)
1481         {
1482                 target_ptr->update |= (PU_FLOW);
1483                 target_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
1484         }
1485
1486         if (turn_flags_ptr->do_move && ((r_ptr->flags7 & (RF7_SELF_LD_MASK | RF7_HAS_DARK_1 | RF7_HAS_DARK_2))
1487                 || ((r_ptr->flags7 & (RF7_HAS_LITE_1 | RF7_HAS_LITE_2)) && !target_ptr->phase_out)))
1488         {
1489                 target_ptr->update |= (PU_MON_LITE);
1490         }
1491
1492         if (is_original_ap_and_seen(target_ptr, m_ptr))
1493         {
1494                 if (turn_flags_ptr->did_open_door) r_ptr->r_flags2 |= (RF2_OPEN_DOOR);
1495                 if (turn_flags_ptr->did_bash_door) r_ptr->r_flags2 |= (RF2_BASH_DOOR);
1496                 if (turn_flags_ptr->did_take_item) r_ptr->r_flags2 |= (RF2_TAKE_ITEM);
1497                 if (turn_flags_ptr->did_kill_item) r_ptr->r_flags2 |= (RF2_KILL_ITEM);
1498                 if (turn_flags_ptr->did_move_body) r_ptr->r_flags2 |= (RF2_MOVE_BODY);
1499                 if (turn_flags_ptr->did_pass_wall) r_ptr->r_flags2 |= (RF2_PASS_WALL);
1500                 if (turn_flags_ptr->did_kill_wall) r_ptr->r_flags2 |= (RF2_KILL_WALL);
1501         }
1502
1503         bool is_battle_determined = !turn_flags_ptr->do_turn && !turn_flags_ptr->do_move && MON_MONFEAR(m_ptr) && aware;
1504         if (!is_battle_determined) return;
1505
1506         (void)set_monster_monfear(target_ptr, m_idx, 0);
1507         if (see_m)
1508         {
1509                 GAME_TEXT m_name[MAX_NLEN];
1510                 monster_desc(target_ptr, m_name, m_ptr, 0);
1511                 msg_format(_("%^sは戦いを決意した!", "%^s turns to fight!"), m_name);
1512         }
1513
1514         if (m_ptr->ml) chg_virtue(target_ptr, V_COMPASSION, -1);
1515 }
1516
1517
1518 /*!
1519  * @brief 死亡したモンスターが乗馬中のモンスターだった場合に落馬処理を行う
1520  * @param target_ptr プレーヤーへの参照ポインタ
1521  * @param m_idx モンスターID
1522  * @param is_riding_mon 騎乗中であればTRUE
1523  * @return なし
1524  */
1525 void decide_drop_from_monster(player_type *target_ptr, MONSTER_IDX m_idx, bool is_riding_mon)
1526 {
1527         monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
1528         monster_race *r_ptr = &r_info[m_ptr->r_idx];
1529         if (!is_riding_mon || ((r_ptr->flags7 & RF7_RIDING) != 0)) return;
1530
1531         if (rakuba(target_ptr, 0, TRUE))
1532         {
1533 #ifdef JP
1534                 msg_print("地面に落とされた。");
1535 #else
1536                 GAME_TEXT m_name[MAX_NLEN];
1537                 monster_desc(target_ptr, m_name, &target_ptr->current_floor_ptr->m_list[target_ptr->riding], 0);
1538                 msg_format("You have fallen from %s.", m_name);
1539 #endif
1540         }
1541 }
1542
1543
1544 /*!
1545  * @brief 召喚の親元が消滅した時、子供も消滅させる
1546  * @param target_ptr プレーヤーへの参照ポインタ
1547  * @param m_idx モンスターID
1548  * @param see_m モンスターが視界内にいたらTRUE
1549  * @return 召喚モンスターが消滅したらTRUE
1550  */
1551 bool vanish_summoned_children(player_type *target_ptr, MONSTER_IDX m_idx, bool see_m)
1552 {
1553         monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
1554         if ((m_ptr->parent_m_idx == 0) || (target_ptr->current_floor_ptr->m_list[m_ptr->parent_m_idx].r_idx > 0))
1555                 return FALSE;
1556
1557         if (see_m)
1558         {
1559                 GAME_TEXT m_name[MAX_NLEN];
1560                 monster_desc(target_ptr, m_name, m_ptr, 0);
1561                 msg_format(_("%sは消え去った!", "%^s disappears!"), m_name);
1562         }
1563
1564         if (record_named_pet && is_pet(m_ptr) && m_ptr->nickname)
1565         {
1566                 GAME_TEXT m_name[MAX_NLEN];
1567                 monster_desc(target_ptr, m_name, m_ptr, MD_INDEF_VISIBLE);
1568                 exe_write_diary(target_ptr, DIARY_NAMED_PET, RECORD_NAMED_PET_LOSE_PARENT, m_name);
1569         }
1570
1571         delete_monster_idx(target_ptr, m_idx);
1572         return TRUE;
1573 }
1574
1575
1576 /*!
1577  * @brief 寝ているモンスターの起床を判定する
1578  * @param target_ptr プレーヤーへの参照ポインタ
1579  * @param m_idx モンスターID
1580  * @return なし
1581  */
1582 void awake_monster(player_type *target_ptr, MONSTER_IDX m_idx)
1583 {
1584         monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
1585         monster_race *r_ptr = &r_info[m_ptr->r_idx];
1586         if (!MON_CSLEEP(m_ptr)) return;
1587         if (!(target_ptr->cursed & TRC_AGGRAVATE)) return;
1588
1589         (void)set_monster_csleep(target_ptr, m_idx, 0);
1590         if (m_ptr->ml)
1591         {
1592                 GAME_TEXT m_name[MAX_NLEN];
1593                 monster_desc(target_ptr, m_name, m_ptr, 0);
1594                 msg_format(_("%^sが目を覚ました。", "%^s wakes up."), m_name);
1595         }
1596
1597         if (is_original_ap_and_seen(target_ptr, m_ptr) && (r_ptr->r_wake < MAX_UCHAR))
1598         {
1599                 r_ptr->r_wake++;
1600         }
1601 }
1602
1603
1604 /*!
1605  * @brief モンスターの怒り状態を判定する (起こっていたら敵に回す)
1606  * @param target_ptr プレーヤーへの参照ポインタ
1607  * @param m_idx モンスターID
1608  * @param see_m モンスターが視界内にいたらTRUE
1609  * @return なし
1610  */
1611 void process_angar(player_type *target_ptr, MONSTER_IDX m_idx, bool see_m)
1612 {
1613         monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
1614         monster_race *r_ptr = &r_info[m_ptr->r_idx];
1615         bool gets_angry = FALSE;
1616         if (is_friendly(m_ptr) && (target_ptr->cursed & TRC_AGGRAVATE))
1617                 gets_angry = TRUE;
1618
1619         if (is_pet(m_ptr) && ((((r_ptr->flags1 & RF1_UNIQUE) || (r_ptr->flags7 & RF7_NAZGUL)) &&
1620                 monster_has_hostile_align(target_ptr, NULL, 10, -10, r_ptr)) || (r_ptr->flagsr & RFR_RES_ALL)))
1621         {
1622                 gets_angry = TRUE;
1623         }
1624
1625         if (target_ptr->phase_out || !gets_angry) return;
1626
1627         if (is_pet(m_ptr) || see_m)
1628         {
1629                 GAME_TEXT m_name[MAX_NLEN];
1630                 monster_desc(target_ptr, m_name, m_ptr, is_pet(m_ptr) ? MD_ASSUME_VISIBLE : 0);
1631                 msg_format(_("%^sは突然敵にまわった!", "%^s suddenly becomes hostile!"), m_name);
1632         }
1633
1634         set_hostile(target_ptr, m_ptr);
1635 }
1636
1637
1638 /*!
1639  * @brief 量子生物の量子的効果を実行する
1640  * @param target_ptr プレーヤーへの参照ポインタ
1641  * @param m_idx モンスターID
1642  * @param see_m モンスターが視界内にいたらTRUE
1643  * @return モンスターが量子的効果により消滅したらTRUE
1644  */
1645 bool process_quantum_effect(player_type *target_ptr, MONSTER_IDX m_idx, bool see_m)
1646 {
1647         monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
1648         monster_race *r_ptr = &r_info[m_ptr->r_idx];
1649         if ((r_ptr->flags2 & RF2_QUANTUM) == 0) return FALSE;
1650         if (!randint0(2)) return FALSE;
1651         if (randint0((m_idx % 100) + 10)) return FALSE;
1652
1653         bool can_disappear = (r_ptr->flags1 & RF1_UNIQUE) == 0;
1654         can_disappear &= (r_ptr->flags1 & RF1_QUESTOR) == 0;
1655         if (can_disappear)
1656         {
1657                 vanish_nonunique(target_ptr, m_idx, see_m);
1658                 return TRUE;
1659         }
1660         
1661         produce_quantum_effect(target_ptr, m_idx, see_m);
1662         return FALSE;
1663 }
1664
1665
1666 /*!
1667  * @brief ユニークでない量子生物を消滅させる
1668  * @param target_ptr プレーヤーへの参照ポインタ
1669  * @param m_idx モンスターID
1670  * @param see_m モンスターが視界内にいたらTRUE
1671  * @return なし
1672  */
1673 void vanish_nonunique(player_type *target_ptr, MONSTER_IDX m_idx, bool see_m)
1674 {
1675         monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
1676         if (see_m)
1677         {
1678                 GAME_TEXT m_name[MAX_NLEN];
1679                 monster_desc(target_ptr, m_name, m_ptr, 0);
1680                 msg_format(_("%sは消え去った!", "%^s disappears!"), m_name);
1681         }
1682
1683         monster_death(target_ptr, m_idx, FALSE);
1684         delete_monster_idx(target_ptr, m_idx);
1685         if (is_pet(m_ptr) && !(m_ptr->ml))
1686         {
1687                 msg_print(_("少しの間悲しい気分になった。", "You feel sad for a moment."));
1688         }
1689 }
1690
1691
1692 /*!
1693  * @brief 量子生物ユニークの量子的効果 (ショート・テレポートまたは距離10のテレポート・アウェイ)を実行する
1694  * @param target_ptr プレーヤーへの参照ポインタ
1695  * @param m_idx モンスターID
1696  * @param see_m モンスターが視界内にいたらTRUE
1697  * @return なし
1698  * @details
1699  * プレーヤーが量子生物を観測しているか、量子生物がプレーヤーを観測している場合、互いの相対的な位置を確定させる
1700  * 波動関数の収縮はテレポートではないので反テレポート無効
1701  * todo パターンは収縮どころか拡散しているが、この際気にしてはいけない
1702  */
1703 void produce_quantum_effect(player_type *target_ptr, MONSTER_IDX m_idx, bool see_m)
1704 {
1705         monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
1706         bool coherent = los(target_ptr, m_ptr->fy, m_ptr->fx, target_ptr->y, target_ptr->x);
1707         if (!see_m && !coherent) return;
1708
1709         if (see_m)
1710         {
1711                 GAME_TEXT m_name[MAX_NLEN];
1712                 monster_desc(target_ptr, m_name, m_ptr, 0);
1713                 msg_format(_("%sは量子的効果を起こした!", "%^s produced a decoherence!"), m_name);
1714         }
1715         else
1716         {
1717                 msg_print(_("量子的効果が起こった!", "A decoherence was produced!"));
1718         }
1719
1720         bool target = one_in_(2);
1721         const int blink = 32 * 5 + 4;
1722         if (target)
1723         {
1724                 (void)monspell_to_monster(target_ptr, blink, m_ptr->fy, m_ptr->fx, m_idx, m_idx);
1725
1726         }
1727         else
1728         {
1729                 teleport_player_away(m_idx, target_ptr, 10, TRUE);
1730         }
1731 }
1732
1733
1734 /*!
1735  * @brief モンスター依存の特別な行動を取らせる
1736  * @param target_ptr プレーヤーへの参照ポインタ
1737  * @param m_idx モンスターID
1738  */
1739 void process_special(player_type *target_ptr, MONSTER_IDX m_idx)
1740 {
1741         monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
1742         monster_race *r_ptr = &r_info[m_ptr->r_idx];
1743         if ((r_ptr->a_ability_flags2 & RF6_SPECIAL) == 0) return;
1744         if (m_ptr->r_idx != MON_OHMU) return;
1745         if (target_ptr->current_floor_ptr->inside_arena || target_ptr->phase_out) return;
1746         if ((r_ptr->freq_spell == 0) || !(randint1(100) <= r_ptr->freq_spell)) return;
1747
1748         int count = 0;
1749         DEPTH rlev = ((r_ptr->level >= 1) ? r_ptr->level : 1);
1750         BIT_FLAGS p_mode = is_pet(m_ptr) ? PM_FORCE_PET : 0L;
1751
1752         for (int k = 0; k < A_MAX; k++)
1753         {
1754                 if (summon_specific(target_ptr, m_idx, m_ptr->fy, m_ptr->fx, rlev, SUMMON_MOLD, (PM_ALLOW_GROUP | p_mode)))
1755                 {
1756                         if (target_ptr->current_floor_ptr->m_list[hack_m_idx_ii].ml) count++;
1757                 }
1758         }
1759
1760         if (count && is_original_ap_and_seen(target_ptr, m_ptr)) r_ptr->r_flags6 |= (RF6_SPECIAL);
1761 }
1762
1763
1764 /*!
1765  * @brief モンスターを喋らせたり足音を立てたりする
1766  * @param target_ptr プレーヤーへの参照ポインタ
1767  * @param m_idx モンスターID
1768  * @param oy モンスターが元々いたY座標
1769  * @param ox モンスターが元々いたX座標
1770  * @param aware 起きていればTRUE
1771  * @return なし
1772  */
1773 void process_speak_sound(player_type *target_ptr, MONSTER_IDX m_idx, POSITION oy, POSITION ox, bool aware)
1774 {
1775         if (target_ptr->phase_out) return;
1776
1777         monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
1778         monster_race *ap_r_ptr = &r_info[m_ptr->ap_r_idx];
1779         if (m_ptr->ap_r_idx == MON_CYBER &&
1780                 one_in_(CYBERNOISE) &&
1781                 !m_ptr->ml && (m_ptr->cdis <= MAX_SIGHT))
1782         {
1783                 if (disturb_minor) disturb(target_ptr, FALSE, FALSE);
1784                 msg_print(_("重厚な足音が聞こえた。", "You hear heavy steps."));
1785         }
1786
1787         if (((ap_r_ptr->flags2 & RF2_CAN_SPEAK) == 0) || !aware ||
1788                 !one_in_(SPEAK_CHANCE) ||
1789                 !player_has_los_bold(target_ptr, oy, ox) ||
1790                 !projectable(target_ptr, oy, ox, target_ptr->y, target_ptr->x))
1791                 return;
1792
1793         GAME_TEXT m_name[MAX_NLEN];
1794         char monmessage[1024];
1795         concptr filename;
1796
1797         if (m_ptr->ml)
1798                 monster_desc(target_ptr, m_name, m_ptr, 0);
1799         else
1800                 strcpy(m_name, _("それ", "It"));
1801
1802         if (MON_MONFEAR(m_ptr))
1803                 filename = _("monfear_j.txt", "monfear.txt");
1804         else if (is_pet(m_ptr))
1805                 filename = _("monpet_j.txt", "monpet.txt");
1806         else if (is_friendly(m_ptr))
1807                 filename = _("monfrien_j.txt", "monfrien.txt");
1808         else
1809                 filename = _("monspeak_j.txt", "monspeak.txt");
1810
1811         if (get_rnd_line(filename, m_ptr->ap_r_idx, monmessage) == 0)
1812         {
1813                 msg_format(_("%^s%s", "%^s %s"), m_name, monmessage);
1814         }
1815 }
1816
1817
1818 /*!
1819  * @brief モンスターを分裂させるかどうかを決定する (分裂もさせる)
1820  * @param target_ptr プレーヤーへの参照ポインタ
1821  * @param m_idx モンスターID
1822  * @param oy 分裂元モンスターのY座標
1823  * @param ox 分裂元モンスターのX座標
1824  * @return 実際に分裂したらTRUEを返す
1825  */
1826 bool decide_monster_multiplication(player_type *target_ptr, MONSTER_IDX m_idx, POSITION oy, POSITION ox)
1827 {
1828         monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
1829         monster_race *r_ptr = &r_info[m_ptr->r_idx];
1830         if (((r_ptr->flags2 & RF2_MULTIPLY) == 0) || (target_ptr->current_floor_ptr->num_repro >= MAX_REPRO))
1831                 return FALSE;
1832
1833         int k = 0;
1834         for (POSITION y = oy - 1; y <= oy + 1; y++)
1835         {
1836                 for (POSITION x = ox - 1; x <= ox + 1; x++)
1837                 {
1838                         if (!in_bounds2(target_ptr->current_floor_ptr, y, x)) continue;
1839                         if (target_ptr->current_floor_ptr->grid_array[y][x].m_idx) k++;
1840                 }
1841         }
1842
1843         if (multiply_barrier(target_ptr, m_idx)) k = 8;
1844
1845         if ((k < 4) && (!k || !randint0(k * MON_MULT_ADJ)))
1846         {
1847                 if (multiply_monster(target_ptr, m_idx, FALSE, (is_pet(m_ptr) ? PM_FORCE_PET : 0)))
1848                 {
1849                         if (target_ptr->current_floor_ptr->m_list[hack_m_idx_ii].ml && is_original_ap_and_seen(target_ptr, m_ptr))
1850                         {
1851                                 r_ptr->r_flags2 |= (RF2_MULTIPLY);
1852                         }
1853
1854                         return TRUE;
1855                 }
1856         }
1857
1858         return FALSE;
1859 }
1860
1861
1862 /*!
1863  * @brief モンスターの移動パターンを決定する
1864  * @param target_ptr プレーヤーへの参照ポインタ
1865  * @param mm 移動方向
1866  * @param m_idx モンスターID
1867  * @param aware 起きていればTRUE
1868  * @return 移動先が存在すればTRUE
1869  */
1870 bool decide_monster_movement_direction(player_type *target_ptr, DIRECTION *mm, MONSTER_IDX m_idx, bool aware)
1871 {
1872         monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
1873         monster_race *r_ptr = &r_info[m_ptr->r_idx];
1874
1875         if (MON_CONFUSED(m_ptr) || !aware)
1876         {
1877                 mm[0] = mm[1] = mm[2] = mm[3] = 5;
1878                 return TRUE;
1879         }
1880
1881         if (((r_ptr->flags1 & (RF1_RAND_50 | RF1_RAND_25)) == (RF1_RAND_50 | RF1_RAND_25)) && (randint0(100) < 75))
1882         {
1883                 if (is_original_ap_and_seen(target_ptr, m_ptr)) r_ptr->r_flags1 |= (RF1_RAND_50 | RF1_RAND_25);
1884
1885                 mm[0] = mm[1] = mm[2] = mm[3] = 5;
1886                 return TRUE;
1887         }
1888
1889         if ((r_ptr->flags1 & RF1_RAND_50) && (randint0(100) < 50))
1890         {
1891                 if (is_original_ap_and_seen(target_ptr, m_ptr)) r_ptr->r_flags1 |= (RF1_RAND_50);
1892
1893                 mm[0] = mm[1] = mm[2] = mm[3] = 5;
1894                 return TRUE;
1895         }
1896
1897          if ((r_ptr->flags1 & RF1_RAND_25) && (randint0(100) < 25))
1898          {
1899                 if (is_original_ap_and_seen(target_ptr, m_ptr)) r_ptr->r_flags1 |= RF1_RAND_25;
1900
1901                 mm[0] = mm[1] = mm[2] = mm[3] = 5;
1902                 return TRUE;
1903          }
1904
1905         if ((r_ptr->flags1 & RF1_NEVER_MOVE) && (m_ptr->cdis > 1))
1906         {
1907                 mm[0] = mm[1] = mm[2] = mm[3] = 5;
1908                 return TRUE;
1909         }
1910
1911         if (is_pet(m_ptr))
1912         {
1913                 bool avoid = ((target_ptr->pet_follow_distance < 0) && (m_ptr->cdis <= (0 - target_ptr->pet_follow_distance)));
1914                 bool lonely = (!avoid && (m_ptr->cdis > target_ptr->pet_follow_distance));
1915                 bool distant = (m_ptr->cdis > PET_SEEK_DIST);
1916                 mm[0] = mm[1] = mm[2] = mm[3] = 5;
1917                 if (!get_enemy_dir(target_ptr, m_idx, mm))
1918                 {
1919                         if (avoid || lonely || distant)
1920                         {
1921                                 POSITION dis = target_ptr->pet_follow_distance;
1922                                 if (target_ptr->pet_follow_distance > PET_SEEK_DIST)
1923                                 {
1924                                         target_ptr->pet_follow_distance = PET_SEEK_DIST;
1925                                 }
1926
1927                                 (void)get_moves(target_ptr, m_idx, mm);
1928                                 target_ptr->pet_follow_distance = (s16b)dis;
1929                         }
1930                 }
1931
1932                 return TRUE;
1933         }
1934
1935         if (!is_hostile(m_ptr))
1936         {
1937                 mm[0] = mm[1] = mm[2] = mm[3] = 5;
1938                 get_enemy_dir(target_ptr, m_idx, mm);
1939                 return TRUE;
1940         }
1941
1942         if (!get_moves(target_ptr, m_idx, mm)) return FALSE;
1943
1944         return TRUE;
1945 }
1946
1947
1948 /*!
1949  * @brief ペットや友好的なモンスターがフロアから逃げる処理を行う
1950  * @param target_ptr プレーヤーへの参照ポインタ
1951  * @param m_idx モンスターID
1952  * @param is_riding_mon 騎乗状態ならばTRUE
1953  * @param see_m モンスターが視界内にいたらTRUE
1954  * @return モンスターがフロアから消えたらTRUE
1955  */
1956 bool runaway_monster(player_type *target_ptr, MONSTER_IDX m_idx, bool is_riding_mon, bool see_m)
1957 {
1958         monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
1959         monster_race *r_ptr = &r_info[m_ptr->r_idx];
1960         bool can_runaway = is_pet(m_ptr) || is_friendly(m_ptr);
1961         can_runaway &= ((r_ptr->flags1 & RF1_UNIQUE) != 0) || ((r_ptr->flags7 & RF7_NAZGUL) != 0);
1962         can_runaway &= !target_ptr->phase_out;
1963         if (!can_runaway) return FALSE;
1964
1965         static int riding_pinch = 0;
1966
1967         if (m_ptr->hp >= m_ptr->maxhp / 3)
1968         {
1969                 /* Reset the counter */
1970                 if (is_riding_mon) riding_pinch = 0;
1971                 
1972                 return FALSE;
1973         }
1974
1975         GAME_TEXT m_name[MAX_NLEN];
1976         monster_desc(target_ptr, m_name, m_ptr, 0);
1977         if (is_riding_mon && riding_pinch < 2)
1978         {
1979                 msg_format(_("%sは傷の痛さの余りあなたの束縛から逃れようとしている。",
1980                         "%^s seems to be in so much pain and tries to escape from your restriction."), m_name);
1981                 riding_pinch++;
1982                 disturb(target_ptr, TRUE, TRUE);
1983                 return FALSE;
1984         }
1985
1986         if (is_riding_mon)
1987         {
1988                 msg_format(_("%sはあなたの束縛から脱出した。", "%^s succeeded to escape from your restriction!"), m_name);
1989                 if (rakuba(target_ptr, -1, FALSE))
1990                 {
1991                         msg_print(_("地面に落とされた。", "You have fallen from the pet you were riding."));
1992                 }
1993         }
1994
1995         if (see_m)
1996         {
1997                 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) &&
1998                         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))
1999                 {
2000                         msg_format(_("%^s「ピンチだ!退却させてもらう!」", "%^s says 'It is the pinch! I will retreat'."), m_name);
2001                 }
2002
2003                 msg_format(_("%^sがテレポート・レベルの巻物を読んだ。", "%^s reads a scroll of teleport level."), m_name);
2004                 msg_format(_("%^sが消え去った。", "%^s disappears."), m_name);
2005         }
2006
2007         if (is_riding_mon && rakuba(target_ptr, -1, FALSE))
2008         {
2009                 msg_print(_("地面に落とされた。", "You have fallen from the pet you were riding."));
2010         }
2011
2012         check_quest_completion(target_ptr, m_ptr);
2013         delete_monster_idx(target_ptr, m_idx);
2014         return TRUE;
2015 }
2016
2017
2018 /*!
2019  * @brief モンスターに魔法を試行させる
2020  * @param target_ptr プレーヤーへの参照ポインタ
2021  * @param m_idx モンスターID
2022  * @param aware 起きていればTRUE
2023  * @return 魔法を唱えられなければ強制的にFALSE、その後モンスターが実際に魔法を唱えればTRUE
2024  */
2025 bool cast_spell(player_type *target_ptr, MONSTER_IDX m_idx, bool aware)
2026 {
2027         monster_type *m_ptr = &target_ptr->current_floor_ptr->m_list[m_idx];
2028         monster_race *r_ptr = &r_info[m_ptr->r_idx];
2029         if ((r_ptr->freq_spell == 0) || (randint1(100) > r_ptr->freq_spell))
2030                 return FALSE;
2031
2032         bool counterattack = FALSE;
2033         if (m_ptr->target_y)
2034         {
2035                 MONSTER_IDX t_m_idx = target_ptr->current_floor_ptr->grid_array[m_ptr->target_y][m_ptr->target_x].m_idx;
2036                 if (t_m_idx && are_enemies(target_ptr, m_ptr, &target_ptr->current_floor_ptr->m_list[t_m_idx]) &&
2037                         projectable(target_ptr, m_ptr->fy, m_ptr->fx, m_ptr->target_y, m_ptr->target_x))
2038                 {
2039                         counterattack = TRUE;
2040                 }
2041         }
2042
2043         if (counterattack)
2044         {
2045                 if (monst_spell_monst(target_ptr, m_idx)) return TRUE;
2046                 if (aware && make_attack_spell(m_idx, target_ptr)) return TRUE;
2047         }
2048         else
2049         {
2050                 if (aware && make_attack_spell(m_idx, target_ptr)) return TRUE;
2051                 if (monst_spell_monst(target_ptr, m_idx)) return TRUE;
2052         }
2053
2054         return FALSE;
2055 }
2056
2057
2058 /*!
2059  * @brief モンスターによる壁の透過・破壊を行う
2060  * @param target_ptr プレーヤーへの参照ポインタ
2061  * @param m_ptr モンスターへの参照ポインタ
2062  * @param ny モンスターのY座標
2063  * @param nx モンスターのX座標
2064  * @return 透過も破壊もしなかった場合はFALSE、それ以外はTRUE
2065  */
2066 bool process_wall(player_type *target_ptr, turn_flags *turn_flags_ptr, monster_type *m_ptr, POSITION ny, POSITION nx, bool can_cross)
2067 {
2068         monster_race *r_ptr = &r_info[m_ptr->r_idx];
2069         grid_type *g_ptr;
2070         g_ptr = &target_ptr->current_floor_ptr->grid_array[ny][nx];
2071         feature_type *f_ptr;
2072         f_ptr = &f_info[g_ptr->feat];
2073         if (player_bold(target_ptr, ny, nx))
2074         {
2075                 turn_flags_ptr->do_move = TRUE;
2076                 return TRUE;
2077         }
2078
2079         if (g_ptr->m_idx > 0)
2080         {
2081                 turn_flags_ptr->do_move = TRUE;
2082                 return TRUE;
2083         }
2084         
2085         if (((r_ptr->flags2 & RF2_KILL_WALL) != 0) &&
2086                 (can_cross ? !have_flag(f_ptr->flags, FF_LOS) : !turn_flags_ptr->is_riding_mon) &&
2087                 have_flag(f_ptr->flags, FF_HURT_DISI) && !have_flag(f_ptr->flags, FF_PERMANENT) &&
2088                 check_hp_for_feat_destruction(f_ptr, m_ptr))
2089         {
2090                 turn_flags_ptr->do_move = TRUE;
2091                 if (!can_cross) turn_flags_ptr->must_alter_to_move = TRUE;
2092
2093                 turn_flags_ptr->did_kill_wall = TRUE;
2094                 return TRUE;
2095         }
2096         
2097         if (!can_cross) return FALSE;
2098
2099         turn_flags_ptr->do_move = TRUE;
2100         if (((r_ptr->flags2 & RF2_PASS_WALL) != 0) && (!turn_flags_ptr->is_riding_mon || target_ptr->pass_wall) &&
2101                 have_flag(f_ptr->flags, FF_CAN_PASS))
2102         {
2103                 turn_flags_ptr->did_pass_wall = TRUE;
2104         }
2105
2106         return TRUE;
2107 }
2108
2109
2110 /*!
2111  * @brief モンスターによるドアの開放・破壊を行う
2112  * @param target_ptr プレーヤーへの参照ポインタ
2113  * @param m_ptr モンスターへの参照ポインタ
2114  * @param ny モンスターのY座標
2115  * @param nx モンスターのX座標
2116  * @return モンスターIDが異常でない限りTRUE
2117  */
2118 bool process_door(player_type *target_ptr, turn_flags *turn_flags_ptr, monster_type *m_ptr, POSITION ny, POSITION nx)
2119 {
2120         monster_race *r_ptr = &r_info[m_ptr->r_idx];
2121         grid_type *g_ptr;
2122         g_ptr = &target_ptr->current_floor_ptr->grid_array[ny][nx];
2123         if (!is_closed_door(target_ptr, g_ptr->feat)) return TRUE;
2124
2125         feature_type *f_ptr;
2126         f_ptr = &f_info[g_ptr->feat];
2127         bool may_bash = bash_normal_door(target_ptr, turn_flags_ptr, m_ptr, ny, nx);
2128         bash_glass_door(target_ptr, turn_flags_ptr, m_ptr, g_ptr, f_ptr, may_bash);
2129
2130         if (!turn_flags_ptr->did_open_door && !turn_flags_ptr->did_bash_door) return TRUE;
2131
2132         if (turn_flags_ptr->did_bash_door && 
2133                 ((randint0(100) < 50) || (feat_state(target_ptr, g_ptr->feat, FF_OPEN) == g_ptr->feat) || have_flag(f_ptr->flags, FF_GLASS)))
2134         {
2135                 cave_alter_feat(target_ptr, ny, nx, FF_BASH);
2136                 if (!monster_is_valid(m_ptr))
2137                 {
2138                         target_ptr->update |= (PU_FLOW);
2139                         target_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
2140                         if (is_original_ap_and_seen(target_ptr, m_ptr)) r_ptr->r_flags2 |= (RF2_BASH_DOOR);
2141
2142                         return FALSE;
2143                 }
2144         }
2145         else
2146         {
2147                 cave_alter_feat(target_ptr, ny, nx, FF_OPEN);
2148         }
2149
2150         f_ptr = &f_info[g_ptr->feat];
2151         turn_flags_ptr->do_view = TRUE;
2152         return TRUE;
2153 }
2154
2155
2156 /*!
2157  * @brief モンスターが普通のドアを開ける処理
2158  * @param target_ptr プレーヤーへの参照ポインタ
2159  * @param m_ptr モンスターへの参照ポインタ
2160  * @param ny モンスターのY座標
2161  * @param nx モンスターのX座標
2162  * @return ここではドアを開けず、ガラスのドアを開ける可能性があるならTRUE
2163  */
2164 bool bash_normal_door(player_type *target_ptr, turn_flags *turn_flags_ptr, monster_type *m_ptr, POSITION ny, POSITION nx)
2165 {
2166         monster_race *r_ptr = &r_info[m_ptr->r_idx];
2167         grid_type *g_ptr;
2168         g_ptr = &target_ptr->current_floor_ptr->grid_array[ny][nx];
2169         feature_type *f_ptr;
2170         f_ptr = &f_info[g_ptr->feat];
2171         turn_flags_ptr->do_move = FALSE;
2172         if (((r_ptr->flags2 & RF2_OPEN_DOOR) == 0) || !have_flag(f_ptr->flags, FF_OPEN) ||
2173                 (is_pet(m_ptr) && ((target_ptr->pet_extra_flags & PF_OPEN_DOORS) == 0)))
2174                 return TRUE;
2175
2176         if (f_ptr->power == 0)
2177         {
2178                 turn_flags_ptr->did_open_door = TRUE;
2179                 turn_flags_ptr->do_turn = TRUE;
2180                 return FALSE;
2181         }
2182
2183         if (randint0(m_ptr->hp / 10) > f_ptr->power)
2184         {
2185                 cave_alter_feat(target_ptr, ny, nx, FF_DISARM);
2186                 turn_flags_ptr->do_turn = TRUE;
2187                 return FALSE;
2188         }
2189
2190         return TRUE;
2191 }
2192
2193
2194 /*!
2195  * @brief モンスターがガラスのドアを開ける処理
2196  * @param target_ptr プレーヤーへの参照ポインタ
2197  * @param m_ptr モンスターへの参照ポインタ
2198  * @param ny モンスターのY座標
2199  * @param nx モンスターのX座標
2200  * @return なし
2201  */
2202 void bash_glass_door(player_type *target_ptr, turn_flags *turn_flags_ptr, monster_type *m_ptr, grid_type *g_ptr, feature_type *f_ptr, bool may_bash)
2203 {
2204         monster_race *r_ptr = &r_info[m_ptr->r_idx];
2205         if (!may_bash || ((r_ptr->flags2 & RF2_BASH_DOOR) == 0) || !have_flag(f_ptr->flags, FF_BASH) ||
2206                 (is_pet(m_ptr) && ((target_ptr->pet_extra_flags & PF_OPEN_DOORS) == 0)))
2207                 return;
2208
2209         if (!check_hp_for_feat_destruction(f_ptr, m_ptr) || (randint0(m_ptr->hp / 10) <= f_ptr->power))
2210                 return;
2211
2212         if (have_flag(f_ptr->flags, FF_GLASS))
2213                 msg_print(_("ガラスが砕ける音がした!", "You hear glass breaking!"));
2214         else
2215                 msg_print(_("ドアを叩き開ける音がした!", "You hear a door burst open!"));
2216
2217         if (disturb_minor) disturb(target_ptr, FALSE, FALSE);
2218
2219         turn_flags_ptr->did_bash_door = TRUE;
2220         turn_flags_ptr->do_move = TRUE;
2221         turn_flags_ptr->must_alter_to_move = TRUE;
2222 }
2223
2224
2225 /*!
2226  * @brief 守りのルーンによるモンスターの移動制限を処理する
2227  * @param target_ptr プレーヤーへの参照ポインタ
2228  * @param m_ptr モンスターへの参照ポインタ
2229  * @param ny モンスターのY座標
2230  * @param nx モンスターのX座標
2231  * @return ルーンのある/なし
2232  */
2233 bool process_protection_rune(player_type *target_ptr, turn_flags *turn_flags_ptr, monster_type *m_ptr, POSITION ny, POSITION nx)
2234 {
2235         grid_type *g_ptr;
2236         g_ptr = &target_ptr->current_floor_ptr->grid_array[ny][nx];
2237         monster_race *r_ptr = &r_info[m_ptr->r_idx];
2238         if (!turn_flags_ptr->do_move || !is_glyph_grid(g_ptr) ||
2239                 (((r_ptr->flags1 & RF1_NEVER_BLOW) != 0) && player_bold(target_ptr, ny, nx)))
2240                 return FALSE;
2241
2242         turn_flags_ptr->do_move = FALSE;
2243         if (is_pet(m_ptr) || (randint1(BREAK_GLYPH) >= r_ptr->level))
2244                 return TRUE;
2245
2246         if (g_ptr->info & CAVE_MARK)
2247         {
2248                 msg_print(_("守りのルーンが壊れた!", "The rune of protection is broken!"));
2249         }
2250
2251         g_ptr->info &= ~(CAVE_MARK);
2252         g_ptr->info &= ~(CAVE_OBJECT);
2253         g_ptr->mimic = 0;
2254         turn_flags_ptr->do_move = TRUE;
2255         note_spot(target_ptr, ny, nx);
2256         return TRUE;
2257 }
2258
2259
2260 /*!
2261  * @brief 爆発のルーンにを処理する
2262  * @param target_ptr プレーヤーへの参照ポインタ
2263  * @param m_ptr モンスターへの参照ポインタ
2264  * @param ny モンスターのY座標
2265  * @param nx モンスターのX座標
2266  * @return モンスター情報が異常でない限りTRUE
2267  */
2268 bool process_explosive_rune(player_type *target_ptr, turn_flags *turn_flags_ptr, monster_type *m_ptr, POSITION ny, POSITION nx)
2269 {
2270         grid_type *g_ptr;
2271         g_ptr = &target_ptr->current_floor_ptr->grid_array[ny][nx];
2272         monster_race *r_ptr = &r_info[m_ptr->r_idx];
2273         if (!turn_flags_ptr->do_move || !is_explosive_rune_grid(g_ptr) ||
2274                 (((r_ptr->flags1 & RF1_NEVER_BLOW) != 0) && player_bold(target_ptr, ny, nx)))
2275                 return TRUE;
2276
2277         turn_flags_ptr->do_move = FALSE;
2278         if (is_pet(m_ptr)) return TRUE;
2279
2280         if (randint1(BREAK_MINOR_GLYPH) > r_ptr->level)
2281         {
2282                 if (g_ptr->info & CAVE_MARK)
2283                 {
2284                         msg_print(_("ルーンが爆発した!", "The rune explodes!"));
2285                         BIT_FLAGS project_flags = PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL | PROJECT_JUMP | PROJECT_NO_HANGEKI;
2286                         project(target_ptr, 0, 2, ny, nx, 2 * (target_ptr->lev + damroll(7, 7)), GF_MANA, project_flags, -1);
2287                 }
2288         }
2289         else
2290         {
2291                 msg_print(_("爆発のルーンは解除された。", "An explosive rune was disarmed."));
2292         }
2293
2294         g_ptr->info &= ~(CAVE_MARK);
2295         g_ptr->info &= ~(CAVE_OBJECT);
2296         g_ptr->mimic = 0;
2297
2298         note_spot(target_ptr, ny, nx);
2299         lite_spot(target_ptr, ny, nx);
2300
2301         if (!monster_is_valid(m_ptr)) return FALSE;
2302
2303         turn_flags_ptr->do_move = TRUE;
2304         return TRUE;
2305 }
2306
2307
2308 /*!
2309  * @brief 全モンスターのターン管理メインルーチン /
2310  * Process all the "live" monsters, once per game turn.
2311  * @return なし
2312  * @details
2313  * During each game current game turn, we scan through the list of all the "live" monsters,\n
2314  * (backwards, so we can excise any "freshly dead" monsters), energizing each\n
2315  * monster, and allowing fully energized monsters to move, attack, pass, etc.\n
2316  *\n
2317  * Note that monsters can never move in the monster array (except when the\n
2318  * "compact_monsters()" function is called by "dungeon()" or "save_player()").\n
2319  *\n
2320  * This function is responsible for at least half of the processor time\n
2321  * on a normal system with a "normal" amount of monsters and a player doing\n
2322  * normal things.\n
2323  *\n
2324  * When the player is resting, virtually 90% of the processor time is spent\n
2325  * in this function, and its children, "process_monster()" and "make_move()".\n
2326  *\n
2327  * Most of the rest of the time is spent in "update_view()" and "lite_spot()",\n
2328  * especially when the player is running.\n
2329  *\n
2330  * Note the special "MFLAG_BORN" flag, which allows us to ignore "fresh"\n
2331  * monsters while they are still being "born".  A monster is "fresh" only\n
2332  * during the game turn in which it is created, and we use the "hack_m_idx" to\n
2333  * determine if the monster is yet to be processed during the game turn.\n
2334  *\n
2335  * Note the special "MFLAG_NICE" flag, which allows the player to get one\n
2336  * move before any "nasty" monsters get to use their spell attacks.\n
2337  *\n
2338  * Note that when the "knowledge" about the currently tracked monster\n
2339  * changes (flags, attacks, spells), we induce a redraw of the monster\n
2340  * recall window.\n
2341  */
2342 void process_monsters(player_type *target_ptr)
2343 {
2344         BIT_FLAGS old_r_flags1 = 0L;
2345         BIT_FLAGS old_r_flags2 = 0L;
2346         BIT_FLAGS old_r_flags3 = 0L;
2347         BIT_FLAGS old_r_flags4 = 0L;
2348         BIT_FLAGS old_r_flags5 = 0L;
2349         BIT_FLAGS old_r_flags6 = 0L;
2350         BIT_FLAGS old_r_flagsr = 0L;
2351
2352         byte old_r_blows0 = 0;
2353         byte old_r_blows1 = 0;
2354         byte old_r_blows2 = 0;
2355         byte old_r_blows3 = 0;
2356
2357         floor_type *floor_ptr = target_ptr->current_floor_ptr;
2358         floor_ptr->monster_noise = FALSE;
2359
2360         MONRACE_IDX old_monster_race_idx = target_ptr->monster_race_idx;
2361         byte old_r_cast_spell = 0;
2362         if (target_ptr->monster_race_idx)
2363         {
2364                 monster_race *r_ptr;
2365                 r_ptr = &r_info[target_ptr->monster_race_idx];
2366
2367                 old_r_flags1 = r_ptr->r_flags1;
2368                 old_r_flags2 = r_ptr->r_flags2;
2369                 old_r_flags3 = r_ptr->r_flags3;
2370                 old_r_flags4 = r_ptr->r_flags4;
2371                 old_r_flags5 = r_ptr->r_flags5;
2372                 old_r_flags6 = r_ptr->r_flags6;
2373                 old_r_flagsr = r_ptr->r_flagsr;
2374
2375                 old_r_blows0 = r_ptr->r_blows[0];
2376                 old_r_blows1 = r_ptr->r_blows[1];
2377                 old_r_blows2 = r_ptr->r_blows[2];
2378                 old_r_blows3 = r_ptr->r_blows[3];
2379
2380                 old_r_cast_spell = r_ptr->r_cast_spell;
2381         }
2382
2383         for (MONSTER_IDX i = floor_ptr->m_max - 1; i >= 1; i--)
2384         {
2385                 monster_type *m_ptr;
2386                 monster_race *r_ptr;
2387                 m_ptr = &floor_ptr->m_list[i];
2388                 r_ptr = &r_info[m_ptr->r_idx];
2389
2390                 if (target_ptr->leaving) break;
2391                 if (!monster_is_valid(m_ptr)) continue;
2392                 if (target_ptr->wild_mode) continue;
2393
2394                 if (m_ptr->mflag & MFLAG_BORN)
2395                 {
2396                         m_ptr->mflag &= ~(MFLAG_BORN);
2397                         continue;
2398                 }
2399
2400                 if (m_ptr->cdis >= AAF_LIMIT) continue;
2401
2402                 POSITION fx = m_ptr->fx;
2403                 POSITION fy = m_ptr->fy;
2404                 if (!target_ptr->no_flowed)
2405                 {
2406                         m_ptr->mflag2 &= ~MFLAG2_NOFLOW;
2407                 }
2408
2409                 bool test = FALSE;
2410                 if (m_ptr->cdis <= (is_pet(m_ptr) ? (r_ptr->aaf > MAX_SIGHT ? MAX_SIGHT : r_ptr->aaf) : r_ptr->aaf))
2411                 {
2412                         test = TRUE;
2413                 }
2414                 else if ((m_ptr->cdis <= MAX_SIGHT || target_ptr->phase_out) &&
2415                         (player_has_los_bold(target_ptr, fy, fx) || (target_ptr->cursed & TRC_AGGRAVATE)))
2416                 {
2417                         test = TRUE;
2418                 }
2419                 else if (m_ptr->target_y)
2420                 {
2421                         test = TRUE;
2422                 }
2423
2424                 if (!test) continue;
2425
2426                 SPEED speed;
2427                 if (target_ptr->riding == i)
2428                 {
2429                         speed = target_ptr->pspeed;
2430                 }
2431                 else
2432                 {
2433                         speed = m_ptr->mspeed;
2434                         if (ironman_nightmare) speed += 5;
2435
2436                         if (MON_FAST(m_ptr)) speed += 10;
2437                         if (MON_SLOW(m_ptr)) speed -= 10;
2438                 }
2439
2440                 m_ptr->energy_need -= SPEED_TO_ENERGY(speed);
2441                 if (m_ptr->energy_need > 0) continue;
2442
2443                 m_ptr->energy_need += ENERGY_NEED();
2444                 hack_m_idx = i;
2445                 process_monster(target_ptr, i);
2446                 reset_target(m_ptr);
2447
2448                 if (target_ptr->no_flowed && one_in_(3))
2449                         m_ptr->mflag2 |= MFLAG2_NOFLOW;
2450
2451                 if (!target_ptr->playing || target_ptr->is_dead) break;
2452                 if (target_ptr->leaving) break;
2453         }
2454
2455         hack_m_idx = 0;
2456         if (!target_ptr->monster_race_idx || (target_ptr->monster_race_idx != old_monster_race_idx))
2457                 return;
2458
2459         monster_race *r_ptr;
2460         r_ptr = &r_info[target_ptr->monster_race_idx];
2461
2462         if ((old_r_flags1 != r_ptr->r_flags1) ||
2463                 (old_r_flags2 != r_ptr->r_flags2) ||
2464                 (old_r_flags3 != r_ptr->r_flags3) ||
2465                 (old_r_flags4 != r_ptr->r_flags4) ||
2466                 (old_r_flags5 != r_ptr->r_flags5) ||
2467                 (old_r_flags6 != r_ptr->r_flags6) ||
2468                 (old_r_flagsr != r_ptr->r_flagsr) ||
2469                 (old_r_blows0 != r_ptr->r_blows[0]) ||
2470                 (old_r_blows1 != r_ptr->r_blows[1]) ||
2471                 (old_r_blows2 != r_ptr->r_blows[2]) ||
2472                 (old_r_blows3 != r_ptr->r_blows[3]) ||
2473                 (old_r_cast_spell != r_ptr->r_cast_spell))
2474         {
2475                 target_ptr->window |= (PW_MONSTER);
2476         }
2477 }