OSDN Git Service

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