OSDN Git Service

[Fix] #37285 ティボルトのUNIQUE属性付加忘れを修正。
[hengband/hengband.git] / src / spells2.c
1 /*!
2  * @file spells2.c
3  * @brief 魔法効果の実装/ Spell code (part 2)
4  * @date 2014/07/15
5  * @author
6  * <pre>
7  * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke
8  * This software may be copied and distributed for educational, research,
9  * and not for profit purposes provided that this copyright and statement
10  * are included in all such copies.  Other copyrights may also apply.
11  * </pre>
12  */
13
14 #include "angband.h"
15 #include "cmd-pet.h"
16 #include "grid.h"
17 #include "trap.h"
18 #include "monsterrace-hook.h"
19 #include "melee.h"
20 #include "world.h"
21 #include "projection.h"
22 #include "spells-summon.h"
23 #include "mutation.h"
24 #include "quest.h"
25 #include "avatar.h"
26
27 #include "spells-status.h"
28 #include "spells-floor.h"
29 #include "realm-hex.h"
30 #include "object-hook.h"
31 #include "monster-status.h"
32 #include "player-status.h"
33
34 /*!
35  * @brief プレイヤー周辺の地形を感知する
36  * @param range 効果範囲
37  * @param flag 特定地形ID
38  * @param known 地形から危険フラグを外すならTRUE
39  * @return 効力があった場合TRUEを返す
40  */
41 static bool detect_feat_flag(POSITION range, int flag, bool known)
42 {
43         POSITION x, y;
44         bool detect = FALSE;
45         grid_type *g_ptr;
46
47         if (d_info[p_ptr->dungeon_idx].flags1 & DF1_DARKNESS) range /= 3;
48
49         /* Scan the current panel */
50         for (y = 1; y < current_floor_ptr->height - 1; y++)
51         {
52                 for (x = 1; x <= current_floor_ptr->width - 1; x++)
53                 {
54                         int dist = distance(p_ptr->y, p_ptr->x, y, x);
55                         if (dist > range) continue;
56                         g_ptr = &current_floor_ptr->grid_array[y][x];
57
58                         /* Hack -- Safe */
59                         if (flag == FF_TRAP)
60                         {
61                                 /* Mark as detected */
62                                 if (dist <= range && known)
63                                 {
64                                         if (dist <= range - 1) g_ptr->info |= (CAVE_IN_DETECT);
65
66                                         g_ptr->info &= ~(CAVE_UNSAFE);
67
68                                         lite_spot(y, x);
69                                 }
70                         }
71
72                         /* Detect flags */
73                         if (cave_have_flag_grid(g_ptr, flag))
74                         {
75                                 /* Detect secrets */
76                                 disclose_grid(y, x);
77
78                                 /* Hack -- Memorize */
79                                 g_ptr->info |= (CAVE_MARK);
80
81                                 lite_spot(y, x);
82
83                                 detect = TRUE;
84                         }
85                 }
86         }
87         return detect;
88 }
89
90
91 /*!
92  * @brief プレイヤー周辺のトラップを感知する / Detect all traps on current panel
93  * @param range 効果範囲
94  * @param known 感知外範囲を超える警告フラグを立てる場合TRUEを返す
95  * @return 効力があった場合TRUEを返す
96  */
97 bool detect_traps(POSITION range, bool known)
98 {
99         bool detect = detect_feat_flag(range, FF_TRAP, known);
100
101         if (known) p_ptr->dtrap = TRUE;
102
103         if (music_singing(MUSIC_DETECT) && SINGING_COUNT(p_ptr) > 0) detect = FALSE;
104         if (detect)
105         {
106                 msg_print(_("トラップの存在を感じとった!", "You sense the presence of traps!"));
107         }
108         return detect;
109 }
110
111
112 /*!
113  * @brief プレイヤー周辺のドアを感知する / Detect all doors on current panel
114  * @param range 効果範囲
115  * @return 効力があった場合TRUEを返す
116  */
117 bool detect_doors(POSITION range)
118 {
119         bool detect = detect_feat_flag(range, FF_DOOR, TRUE);
120
121         if (music_singing(MUSIC_DETECT) && SINGING_COUNT(p_ptr) > 0) detect = FALSE;
122         if (detect)
123         {
124                 msg_print(_("ドアの存在を感じとった!", "You sense the presence of doors!"));
125         }
126         return detect;
127 }
128
129
130 /*!
131  * @brief プレイヤー周辺の階段を感知する / Detect all stairs on current panel
132  * @param range 効果範囲
133  * @return 効力があった場合TRUEを返す
134  */
135 bool detect_stairs(POSITION range)
136 {
137         bool detect = detect_feat_flag(range, FF_STAIRS, TRUE);
138
139         if (music_singing(MUSIC_DETECT) && SINGING_COUNT(p_ptr) > 0) detect = FALSE;
140         if (detect)
141         {
142                 msg_print(_("階段の存在を感じとった!", "You sense the presence of stairs!"));
143         }
144         return detect;
145 }
146
147
148 /*!
149  * @brief プレイヤー周辺の地形財宝を感知する / Detect any treasure on the current panel
150  * @param range 効果範囲
151  * @return 効力があった場合TRUEを返す
152  */
153 bool detect_treasure(POSITION range)
154 {
155         bool detect = detect_feat_flag(range, FF_HAS_GOLD, TRUE);
156
157         if (music_singing(MUSIC_DETECT) && SINGING_COUNT(p_ptr) > 6) detect = FALSE;
158         if (detect)
159         {
160                 msg_print(_("埋蔵された財宝の存在を感じとった!", "You sense the presence of buried treasure!"));
161         }
162         return detect;
163 }
164
165
166 /*!
167  * @brief プレイヤー周辺のアイテム財宝を感知する / Detect all "gold" objects on the current panel
168  * @param range 効果範囲
169  * @return 効力があった場合TRUEを返す
170  */
171 bool detect_objects_gold(POSITION range)
172 {
173         OBJECT_IDX i;
174         POSITION y, x;
175         POSITION range2 = range;
176
177         bool detect = FALSE;
178
179         if (d_info[p_ptr->dungeon_idx].flags1 & DF1_DARKNESS) range2 /= 3;
180
181         /* Scan objects */
182         for (i = 1; i < o_max; i++)
183         {
184                 object_type *o_ptr = &current_floor_ptr->o_list[i];
185
186                 /* Skip dead objects */
187                 if (!o_ptr->k_idx) continue;
188
189                 /* Skip held objects */
190                 if (o_ptr->held_m_idx) continue;
191
192                 y = o_ptr->iy;
193                 x = o_ptr->ix;
194
195                 /* Only detect nearby objects */
196                 if (distance(p_ptr->y, p_ptr->x, y, x) > range2) continue;
197
198                 /* Detect "gold" objects */
199                 if (o_ptr->tval == TV_GOLD)
200                 {
201                         o_ptr->marked |= OM_FOUND;
202                         lite_spot(y, x);
203                         detect = TRUE;
204                 }
205         }
206
207         if (music_singing(MUSIC_DETECT) && SINGING_COUNT(p_ptr) > 6) detect = FALSE;
208         if (detect)
209         {
210                 msg_print(_("財宝の存在を感じとった!", "You sense the presence of treasure!"));
211         }
212
213         if (detect_monsters_string(range, "$"))
214         {
215                 detect = TRUE;
216         }
217         return (detect);
218 }
219
220
221 /*!
222  * @brief 通常のアイテムオブジェクトを感知する / Detect all "normal" objects on the current panel
223  * @param range 効果範囲
224  * @return 効力があった場合TRUEを返す
225  */
226 bool detect_objects_normal(POSITION range)
227 {
228         OBJECT_IDX i;
229         POSITION y, x;
230         POSITION range2 = range;
231
232         bool detect = FALSE;
233
234         if (d_info[p_ptr->dungeon_idx].flags1 & DF1_DARKNESS) range2 /= 3;
235
236         /* Scan objects */
237         for (i = 1; i < o_max; i++)
238         {
239                 object_type *o_ptr = &current_floor_ptr->o_list[i];
240
241                 /* Skip dead objects */
242                 if (!o_ptr->k_idx) continue;
243
244                 /* Skip held objects */
245                 if (o_ptr->held_m_idx) continue;
246
247                 y = o_ptr->iy;
248                 x = o_ptr->ix;
249
250                 /* Only detect nearby objects */
251                 if (distance(p_ptr->y, p_ptr->x, y, x) > range2) continue;
252
253                 /* Detect "real" objects */
254                 if (o_ptr->tval != TV_GOLD)
255                 {
256                         o_ptr->marked |= OM_FOUND;
257                         lite_spot(y, x);
258                         detect = TRUE;
259                 }
260         }
261
262         if (music_singing(MUSIC_DETECT) && SINGING_COUNT(p_ptr) > 6) detect = FALSE;
263         if (detect)
264         {
265                 msg_print(_("アイテムの存在を感じとった!", "You sense the presence of objects!"));
266         }
267
268         if (detect_monsters_string(range, "!=?|/`"))
269         {
270                 detect = TRUE;
271         }
272         return (detect);
273 }
274
275
276 /*!
277  * @brief 魔法効果のあるのアイテムオブジェクトを感知する / Detect all "magic" objects on the current panel.
278  * @param range 効果範囲
279  * @return 効力があった場合TRUEを返す
280  * @details
281  * <pre>
282  * This will light up all spaces with "magic" items, including artifacts,
283  * ego-items, potions, scrolls, books, rods, wands, staves, amulets, rings,
284  * and "enchanted" items of the "good" variety.
285  *
286  * It can probably be argued that this function is now too powerful.
287  * </pre>
288  */
289 bool detect_objects_magic(POSITION range)
290 {
291         OBJECT_TYPE_VALUE tv;
292         OBJECT_IDX i;
293         POSITION y, x;
294
295         bool detect = FALSE;
296
297         if (d_info[p_ptr->dungeon_idx].flags1 & DF1_DARKNESS) range /= 3;
298
299         /* Scan all objects */
300         for (i = 1; i < o_max; i++)
301         {
302                 object_type *o_ptr = &current_floor_ptr->o_list[i];
303
304                 /* Skip dead objects */
305                 if (!o_ptr->k_idx) continue;
306
307                 /* Skip held objects */
308                 if (o_ptr->held_m_idx) continue;
309
310                 y = o_ptr->iy;
311                 x = o_ptr->ix;
312
313                 /* Only detect nearby objects */
314                 if (distance(p_ptr->y, p_ptr->x, y, x) > range) continue;
315
316                 /* Examine the tval */
317                 tv = o_ptr->tval;
318
319                 /* Artifacts, misc magic items, or enchanted wearables */
320                 if (object_is_artifact(o_ptr) ||
321                         object_is_ego(o_ptr) ||
322                     (tv == TV_WHISTLE) ||
323                     (tv == TV_AMULET) ||
324                         (tv == TV_RING) ||
325                     (tv == TV_STAFF) ||
326                         (tv == TV_WAND) ||
327                         (tv == TV_ROD) ||
328                     (tv == TV_SCROLL) ||
329                         (tv == TV_POTION) ||
330                     (tv == TV_LIFE_BOOK) ||
331                         (tv == TV_SORCERY_BOOK) ||
332                     (tv == TV_NATURE_BOOK) ||
333                         (tv == TV_CHAOS_BOOK) ||
334                     (tv == TV_DEATH_BOOK) ||
335                     (tv == TV_TRUMP_BOOK) ||
336                         (tv == TV_ARCANE_BOOK) ||
337                         (tv == TV_CRAFT_BOOK) ||
338                         (tv == TV_DAEMON_BOOK) ||
339                         (tv == TV_CRUSADE_BOOK) ||
340                         (tv == TV_MUSIC_BOOK) ||
341                         (tv == TV_HISSATSU_BOOK) ||
342                         (tv == TV_HEX_BOOK) ||
343                     ((o_ptr->to_a > 0) || (o_ptr->to_h + o_ptr->to_d > 0)))
344                 {
345                         /* Memorize the item */
346                         o_ptr->marked |= OM_FOUND;
347                         lite_spot(y, x);
348                         detect = TRUE;
349                 }
350         }
351         if (detect)
352         {
353                 msg_print(_("魔法のアイテムの存在を感じとった!", "You sense the presence of magic objects!"));
354         }
355
356         /* Return result */
357         return (detect);
358 }
359
360
361 /*!
362  * @brief 一般のモンスターを感知する / Detect all "normal" monsters on the current panel
363  * @param range 効果範囲
364  * @return 効力があった場合TRUEを返す
365  */
366 bool detect_monsters_normal(POSITION range)
367 {
368         MONSTER_IDX i;
369         POSITION y, x;
370         bool flag = FALSE;
371
372         if (d_info[p_ptr->dungeon_idx].flags1 & DF1_DARKNESS) range /= 3;
373
374         for (i = 1; i < m_max; i++)
375         {
376                 monster_type *m_ptr = &current_floor_ptr->m_list[i];
377                 monster_race *r_ptr = &r_info[m_ptr->r_idx];
378                 if (!monster_is_valid(m_ptr)) continue;
379
380                 y = m_ptr->fy;
381                 x = m_ptr->fx;
382
383                 /* Only detect nearby monsters */
384                 if (distance(p_ptr->y, p_ptr->x, y, x) > range) continue;
385
386                 /* Detect all non-invisible monsters */
387                 if (!(r_ptr->flags2 & RF2_INVISIBLE) || p_ptr->see_inv)
388                 {
389                         /* Repair visibility later */
390                         repair_monsters = TRUE;
391
392                         m_ptr->mflag2 |= (MFLAG2_MARK | MFLAG2_SHOW);
393                         update_monster(i, FALSE);
394                         flag = TRUE;
395                 }
396         }
397
398         if (music_singing(MUSIC_DETECT) && SINGING_COUNT(p_ptr) > 3) flag = FALSE;
399         if (flag)
400         {
401                 msg_print(_("モンスターの存在を感じとった!", "You sense the presence of monsters!"));
402         }
403         return (flag);
404 }
405
406
407 /*!
408  * @brief 不可視のモンスターを感知する / Detect all "invisible" monsters around the player
409  * @param range 効果範囲
410  * @return 効力があった場合TRUEを返す
411  */
412 bool detect_monsters_invis(POSITION range)
413 {
414         MONSTER_IDX i;
415         POSITION y, x;
416         bool flag = FALSE;
417
418         if (d_info[p_ptr->dungeon_idx].flags1 & DF1_DARKNESS) range /= 3;
419
420         for (i = 1; i < m_max; i++)
421         {
422                 monster_type *m_ptr = &current_floor_ptr->m_list[i];
423                 monster_race *r_ptr = &r_info[m_ptr->r_idx];
424
425                 if (!monster_is_valid(m_ptr)) continue;
426
427                 y = m_ptr->fy;
428                 x = m_ptr->fx;
429
430                 /* Only detect nearby monsters */
431                 if (distance(p_ptr->y, p_ptr->x, y, x) > range) continue;
432
433                 /* Detect invisible monsters */
434                 if (r_ptr->flags2 & RF2_INVISIBLE)
435                 {
436                         /* Update monster recall window */
437                         if (p_ptr->monster_race_idx == m_ptr->r_idx)
438                         {
439                                 p_ptr->window |= (PW_MONSTER);
440                         }
441
442                         /* Repair visibility later */
443                         repair_monsters = TRUE;
444
445                         m_ptr->mflag2 |= (MFLAG2_MARK | MFLAG2_SHOW);
446                         update_monster(i, FALSE);
447                         flag = TRUE;
448                 }
449         }
450
451         if (music_singing(MUSIC_DETECT) && SINGING_COUNT(p_ptr) > 3) flag = FALSE;
452         if (flag)
453         {
454                 msg_print(_("透明な生物の存在を感じとった!", "You sense the presence of invisible creatures!"));
455         }
456         return (flag);
457 }
458
459 /*!
460  * @brief 邪悪なモンスターを感知する / Detect all "evil" monsters on current panel
461  * @param range 効果範囲
462  * @return 効力があった場合TRUEを返す
463  */
464 bool detect_monsters_evil(POSITION range)
465 {
466         MONSTER_IDX i;
467         POSITION y, x;
468         bool flag = FALSE;
469
470         if (d_info[p_ptr->dungeon_idx].flags1 & DF1_DARKNESS) range /= 3;
471
472         for (i = 1; i < m_max; i++)
473         {
474                 monster_type *m_ptr = &current_floor_ptr->m_list[i];
475                 monster_race *r_ptr = &r_info[m_ptr->r_idx];
476                 if (!monster_is_valid(m_ptr)) continue;
477
478                 y = m_ptr->fy;
479                 x = m_ptr->fx;
480
481                 /* Only detect nearby monsters */
482                 if (distance(p_ptr->y, p_ptr->x, y, x) > range) continue;
483
484                 /* Detect evil monsters */
485                 if (r_ptr->flags3 & RF3_EVIL)
486                 {
487                         if (is_original_ap(m_ptr))
488                         {
489                                 /* Take note that they are evil */
490                                 r_ptr->r_flags3 |= (RF3_EVIL);
491
492                                 /* Update monster recall window */
493                                 if (p_ptr->monster_race_idx == m_ptr->r_idx)
494                                 {
495                                         p_ptr->window |= (PW_MONSTER);
496                                 }
497                         }
498
499                         /* Repair visibility later */
500                         repair_monsters = TRUE;
501
502                         m_ptr->mflag2 |= (MFLAG2_MARK | MFLAG2_SHOW);
503                         update_monster(i, FALSE);
504                         flag = TRUE;
505                 }
506         }
507         if (flag)
508         {
509                 msg_print(_("邪悪なる生物の存在を感じとった!", "You sense the presence of evil creatures!"));
510         }
511         return (flag);
512 }
513
514 /*!
515  * @brief 無生命のモンスターを感知する(アンデッド、悪魔系を含む) / Detect all "nonliving", "undead" or "demonic" monsters on current panel
516  * @param range 効果範囲
517  * @return 効力があった場合TRUEを返す
518  */
519 bool detect_monsters_nonliving(POSITION range)
520 {
521         MONSTER_IDX i;
522         POSITION y, x;
523         bool flag = FALSE;
524
525         if (d_info[p_ptr->dungeon_idx].flags1 & DF1_DARKNESS) range /= 3;
526
527         for (i = 1; i < m_max; i++)
528         {
529                 monster_type *m_ptr = &current_floor_ptr->m_list[i];
530                 if (!monster_is_valid(m_ptr)) continue;
531
532                 y = m_ptr->fy;
533                 x = m_ptr->fx;
534
535                 /* Only detect nearby monsters */
536                 if (distance(p_ptr->y, p_ptr->x, y, x) > range) continue;
537
538                 /* Detect non-living monsters */
539                 if (!monster_living(m_ptr->r_idx))
540                 {
541                         /* Update monster recall window */
542                         if (p_ptr->monster_race_idx == m_ptr->r_idx)
543                         {
544                                 p_ptr->window |= (PW_MONSTER);
545                         }
546
547                         /* Repair visibility later */
548                         repair_monsters = TRUE;
549
550                         m_ptr->mflag2 |= (MFLAG2_MARK | MFLAG2_SHOW);
551                         update_monster(i, FALSE);
552                         flag = TRUE;
553                 }
554         }
555         if (flag)
556         {
557                 msg_print(_("自然でないモンスターの存在を感じた!", "You sense the presence of unnatural beings!"));
558         }
559         return (flag);
560 }
561
562 /*!
563  * @brief 精神のあるモンスターを感知する / Detect all monsters it has mind on current panel
564  * @param range 効果範囲
565  * @return 効力があった場合TRUEを返す
566  */
567 bool detect_monsters_mind(POSITION range)
568 {
569         MONSTER_IDX i;
570         POSITION y, x;
571         bool flag = FALSE;
572
573         if (d_info[p_ptr->dungeon_idx].flags1 & DF1_DARKNESS) range /= 3;
574
575         for (i = 1; i < m_max; i++)
576         {
577                 monster_type *m_ptr = &current_floor_ptr->m_list[i];
578                 monster_race *r_ptr = &r_info[m_ptr->r_idx];
579                 if (!monster_is_valid(m_ptr)) continue;
580
581                 y = m_ptr->fy;
582                 x = m_ptr->fx;
583
584                 /* Only detect nearby monsters */
585                 if (distance(p_ptr->y, p_ptr->x, y, x) > range) continue;
586
587                 /* Detect non-living monsters */
588                 if (!(r_ptr->flags2 & RF2_EMPTY_MIND))
589                 {
590                         /* Update monster recall window */
591                         if (p_ptr->monster_race_idx == m_ptr->r_idx)
592                         {
593                                 p_ptr->window |= (PW_MONSTER);
594                         }
595
596                         /* Repair visibility later */
597                         repair_monsters = TRUE;
598
599                         m_ptr->mflag2 |= (MFLAG2_MARK | MFLAG2_SHOW);
600                         update_monster(i, FALSE);
601                         flag = TRUE;
602                 }
603         }
604         if (flag)
605         {
606                 msg_print(_("殺気を感じとった!", "You sense the presence of someone's mind!"));
607         }
608         return (flag);
609 }
610
611
612 /*!
613  * @brief 該当シンボルのモンスターを感知する / Detect all (string) monsters on current panel
614  * @param range 効果範囲
615  * @param Match 対応シンボルの混じったモンスター文字列(複数指定化)
616  * @return 効力があった場合TRUEを返す
617  */
618 bool detect_monsters_string(POSITION range, concptr Match)
619 {
620         MONSTER_IDX i;
621         POSITION y, x;
622         bool flag = FALSE;
623
624         if (d_info[p_ptr->dungeon_idx].flags1 & DF1_DARKNESS) range /= 3;
625
626         for (i = 1; i < m_max; i++)
627         {
628                 monster_type *m_ptr = &current_floor_ptr->m_list[i];
629                 monster_race *r_ptr = &r_info[m_ptr->r_idx];
630                 if (!monster_is_valid(m_ptr)) continue;
631
632                 y = m_ptr->fy;
633                 x = m_ptr->fx;
634
635                 /* Only detect nearby monsters */
636                 if (distance(p_ptr->y, p_ptr->x, y, x) > range) continue;
637
638                 /* Detect monsters with the same symbol */
639                 if (my_strchr(Match, r_ptr->d_char))
640                 {
641                         /* Update monster recall window */
642                         if (p_ptr->monster_race_idx == m_ptr->r_idx)
643                         {
644                                 p_ptr->window |= (PW_MONSTER);
645                         }
646
647                         /* Repair visibility later */
648                         repair_monsters = TRUE;
649
650                         m_ptr->mflag2 |= (MFLAG2_MARK | MFLAG2_SHOW);
651                         update_monster(i, FALSE);
652                         flag = TRUE;
653                 }
654         }
655
656         if (music_singing(MUSIC_DETECT) && SINGING_COUNT(p_ptr) > 3) flag = FALSE;
657         if (flag)
658         {
659                 msg_print(_("モンスターの存在を感じとった!", "You sense the presence of monsters!"));
660         }
661         return (flag);
662 }
663
664 /*!
665  * @brief flags3に対応するモンスターを感知する / A "generic" detect monsters routine, tagged to flags3
666  * @param range 効果範囲
667  * @param match_flag 感知フラグ
668  * @return 効力があった場合TRUEを返す
669  */
670 bool detect_monsters_xxx(POSITION range, u32b match_flag)
671 {
672         MONSTER_IDX i;
673         POSITION y, x;
674         bool flag = FALSE;
675         concptr desc_monsters = _("変なモンスター", "weird monsters");
676
677         if (d_info[p_ptr->dungeon_idx].flags1 & DF1_DARKNESS) range /= 3;
678
679         for (i = 1; i < m_max; i++)
680         {
681                 monster_type *m_ptr = &current_floor_ptr->m_list[i];
682                 monster_race *r_ptr = &r_info[m_ptr->r_idx];
683                 if (!monster_is_valid(m_ptr)) continue;
684
685                 y = m_ptr->fy;
686                 x = m_ptr->fx;
687
688                 /* Only detect nearby monsters */
689                 if (distance(p_ptr->y, p_ptr->x, y, x) > range) continue;
690
691                 /* Detect evil monsters */
692                 if (r_ptr->flags3 & (match_flag))
693                 {
694                         if (is_original_ap(m_ptr))
695                         {
696                                 /* Take note that they are something */
697                                 r_ptr->r_flags3 |= (match_flag);
698
699                                 /* Update monster recall window */
700                                 if (p_ptr->monster_race_idx == m_ptr->r_idx)
701                                 {
702                                         p_ptr->window |= (PW_MONSTER);
703                                 }
704                         }
705
706                         /* Repair visibility later */
707                         repair_monsters = TRUE;
708
709                         m_ptr->mflag2 |= (MFLAG2_MARK | MFLAG2_SHOW);
710                         update_monster(i, FALSE);
711                         flag = TRUE;
712                 }
713         }
714         if (flag)
715         {
716                 switch (match_flag)
717                 {
718                         case RF3_DEMON:
719                         desc_monsters = _("デーモン", "demons");
720                                 break;
721                         case RF3_UNDEAD:
722                         desc_monsters = _("アンデッド", "the undead");
723                                 break;
724                 }
725
726                 msg_format(_("%sの存在を感じとった!", "You sense the presence of %s!"), desc_monsters);
727                 msg_print(NULL);
728         }
729         return (flag);
730 }
731
732
733 /*!
734  * @brief 全感知処理 / Detect everything
735  * @param range 効果範囲
736  * @return 効力があった場合TRUEを返す
737  */
738 bool detect_all(POSITION range)
739 {
740         bool detect = FALSE;
741
742         /* Detect everything */
743         if (detect_traps(range, TRUE)) detect = TRUE;
744         if (detect_doors(range)) detect = TRUE;
745         if (detect_stairs(range)) detect = TRUE;
746
747         /* There are too many hidden treasure.  So... */
748         /* if (detect_treasure(range)) detect = TRUE; */
749
750         if (detect_objects_gold(range)) detect = TRUE;
751         if (detect_objects_normal(range)) detect = TRUE;
752         if (detect_monsters_invis(range)) detect = TRUE;
753         if (detect_monsters_normal(range)) detect = TRUE;
754         return (detect);
755 }
756
757
758 /*!
759  * @brief 視界内モンスターに魔法効果を与える / Apply a "project()" directly to all viewable monsters
760  * @param typ 属性効果
761  * @param dam 効果量
762  * @return 効力があった場合TRUEを返す
763  * @details
764  * <pre>
765  * Note that affected monsters are NOT auto-tracked by this usage.
766  *
767  * To avoid misbehavior when monster deaths have side-effects,
768  * this is done in two passes. -- JDL
769  * </pre>
770  */
771 bool project_all_los(EFFECT_ID typ, HIT_POINT dam)
772 {
773         MONSTER_IDX i;
774         POSITION x, y;
775         BIT_FLAGS flg = PROJECT_JUMP | PROJECT_KILL | PROJECT_HIDE;
776         bool obvious = FALSE;
777
778         /* Mark all (nearby) monsters */
779         for (i = 1; i < m_max; i++)
780         {
781                 monster_type *m_ptr = &current_floor_ptr->m_list[i];
782                 if (!monster_is_valid(m_ptr)) continue;
783
784                 y = m_ptr->fy;
785                 x = m_ptr->fx;
786
787                 /* Require line of sight */
788                 if (!player_has_los_bold(y, x) || !projectable(p_ptr->y, p_ptr->x, y, x)) continue;
789
790                 /* Mark the monster */
791                 m_ptr->mflag |= (MFLAG_LOS);
792         }
793
794         /* Affect all marked monsters */
795         for (i = 1; i < m_max; i++)
796         {
797                 monster_type *m_ptr = &current_floor_ptr->m_list[i];
798
799                 /* Skip unmarked monsters */
800                 if (!(m_ptr->mflag & (MFLAG_LOS))) continue;
801
802                 /* Remove mark */
803                 m_ptr->mflag &= ~(MFLAG_LOS);
804
805                 y = m_ptr->fy;
806                 x = m_ptr->fx;
807
808                 /* Jump directly to the target monster */
809                 if (project(0, 0, y, x, dam, typ, flg, -1)) obvious = TRUE;
810         }
811         return (obvious);
812 }
813
814
815 /*!
816  * @brief 視界内モンスターを加速する処理 / Speed monsters
817  * @return 効力があった場合TRUEを返す
818  */
819 bool speed_monsters(void)
820 {
821         return (project_all_los(GF_OLD_SPEED, p_ptr->lev));
822 }
823
824 /*!
825  * @brief 視界内モンスターを加速する処理 / Slow monsters
826  * @return 効力があった場合TRUEを返す
827  */
828 bool slow_monsters(int power)
829 {
830         return (project_all_los(GF_OLD_SLOW, power));
831 }
832
833 /*!
834  * @brief 視界内モンスターを眠らせる処理 / Sleep monsters
835  * @return 効力があった場合TRUEを返す
836  */
837 bool sleep_monsters(int power)
838 {
839         return (project_all_los(GF_OLD_SLEEP, power));
840 }
841
842 /*!
843  * @brief 視界内の邪悪なモンスターをテレポート・アウェイさせる処理 / Banish evil monsters
844  * @return 効力があった場合TRUEを返す
845  */
846 bool banish_evil(int dist)
847 {
848         return (project_all_los(GF_AWAY_EVIL, dist));
849 }
850
851 /*!
852  * @brief 視界内のアンデッド・モンスターを恐怖させる処理 / Turn undead
853  * @return 効力があった場合TRUEを返す
854  */
855 bool turn_undead(void)
856 {
857         bool tester = (project_all_los(GF_TURN_UNDEAD, p_ptr->lev));
858         if (tester)
859                 chg_virtue(V_UNLIFE, -1);
860         return tester;
861 }
862
863 /*!
864  * @brief 視界内のアンデッド・モンスターにダメージを与える処理 / Dispel undead monsters
865  * @return 効力があった場合TRUEを返す
866  */
867 bool dispel_undead(HIT_POINT dam)
868 {
869         bool tester = (project_all_los(GF_DISP_UNDEAD, dam));
870         if (tester)
871                 chg_virtue(V_UNLIFE, -2);
872         return tester;
873 }
874
875 /*!
876  * @brief 視界内の邪悪なモンスターにダメージを与える処理 / Dispel evil monsters
877  * @return 効力があった場合TRUEを返す
878  */
879 bool dispel_evil(HIT_POINT dam)
880 {
881         return (project_all_los(GF_DISP_EVIL, dam));
882 }
883
884 /*!
885  * @brief 視界内の善良なモンスターにダメージを与える処理 / Dispel good monsters
886  * @return 効力があった場合TRUEを返す
887  */
888 bool dispel_good(HIT_POINT dam)
889 {
890         return (project_all_los(GF_DISP_GOOD, dam));
891 }
892
893 /*!
894  * @brief 視界内のあらゆるモンスターにダメージを与える処理 / Dispel all monsters
895  * @return 効力があった場合TRUEを返す
896  */
897 bool dispel_monsters(HIT_POINT dam)
898 {
899         return (project_all_los(GF_DISP_ALL, dam));
900 }
901
902 bool cleansing_nova(player_type *creature_ptr, bool magic, bool powerful)
903 {
904         bool ident = FALSE;
905         if (dispel_evil(powerful ? 225 : 150)) ident = TRUE;
906         int k = 3 * creature_ptr->lev;
907         if (set_protevil((magic ? 0 : creature_ptr->protevil) + randint1(25) + k, FALSE)) ident = TRUE;
908         if (set_poisoned(0)) ident = TRUE;
909         if (set_afraid(0)) ident = TRUE;
910         if (hp_player(50)) ident = TRUE;
911         if (set_stun(0)) ident = TRUE;
912         if (set_cut(0)) ident = TRUE;
913         return ident;
914 }
915
916 bool unleash_mana_storm(player_type *creature_ptr, bool powerful)
917 {
918         msg_print(_("強力な魔力が敵を引き裂いた!", "Mighty magics rend your enemies!"));
919         project(0, (powerful ? 7 : 5), creature_ptr->y, creature_ptr->x,
920         (randint1(200) + (powerful ? 500 : 300)) * 2, GF_MANA, PROJECT_KILL | PROJECT_ITEM | PROJECT_GRID, -1);
921         if ((creature_ptr->pclass != CLASS_MAGE) && (creature_ptr->pclass != CLASS_HIGH_MAGE) && (creature_ptr->pclass != CLASS_SORCERER) && (creature_ptr->pclass != CLASS_MAGIC_EATER) && (creature_ptr->pclass != CLASS_BLUE_MAGE))
922         {
923                 (void)take_hit(DAMAGE_NOESCAPE, 50, _("コントロールし難い強力な魔力の解放", "unleashing magics too mighty to control"), -1);
924         }
925         return TRUE;
926 }
927
928 /*!
929  * @brief 視界内の生命のあるモンスターにダメージを与える処理 / Dispel 'living' monsters
930  * @return 効力があった場合TRUEを返す
931  */
932 bool dispel_living(HIT_POINT dam)
933 {
934         return (project_all_los(GF_DISP_LIVING, dam));
935 }
936
937 /*!
938  * @brief 視界内の悪魔系モンスターにダメージを与える処理 / Dispel 'living' monsters
939  * @return 効力があった場合TRUEを返す
940  */
941 bool dispel_demons(HIT_POINT dam)
942 {
943         return (project_all_los(GF_DISP_DEMON, dam));
944 }
945
946 /*!
947  * @brief 視界内のモンスターに「聖戦」効果を与える処理
948  * @return 効力があった場合TRUEを返す
949  */
950 bool crusade(void)
951 {
952         return (project_all_los(GF_CRUSADE, p_ptr->lev*4));
953 }
954
955 /*!
956  * @brief 視界内モンスターを怒らせる処理 / Wake up all monsters, and speed up "los" monsters.
957  * @param who 怒らせる原因を起こしたモンスター(0ならばプレイヤー)
958  * @return なし
959  */
960 void aggravate_monsters(MONSTER_IDX who)
961 {
962         MONSTER_IDX i;
963         bool sleep = FALSE;
964         bool speed = FALSE;
965
966         /* Aggravate everyone nearby */
967         for (i = 1; i < m_max; i++)
968         {
969                 monster_type *m_ptr = &current_floor_ptr->m_list[i];
970                 if (!monster_is_valid(m_ptr)) continue;
971
972                 /* Skip aggravating monster (or player) */
973                 if (i == who) continue;
974
975                 /* Wake up nearby sleeping monsters */
976                 if (m_ptr->cdis < MAX_SIGHT * 2)
977                 {
978                         /* Wake up */
979                         if (MON_CSLEEP(m_ptr))
980                         {
981                                 (void)set_monster_csleep(i, 0);
982                                 sleep = TRUE;
983                         }
984                         if (!is_pet(m_ptr)) m_ptr->mflag2 |= MFLAG2_NOPET;
985                 }
986
987                 /* Speed up monsters in line of sight */
988                 if (player_has_los_bold(m_ptr->fy, m_ptr->fx))
989                 {
990                         if (!is_pet(m_ptr))
991                         {
992                                 (void)set_monster_fast(i, MON_FAST(m_ptr) + 100);
993                                 speed = TRUE;
994                         }
995                 }
996         }
997
998         if (speed) msg_print(_("付近で何かが突如興奮したような感じを受けた!", "You feel a sudden stirring nearby!"));
999         else if (sleep) msg_print(_("何かが突如興奮したような騒々しい音が遠くに聞こえた!", "You hear a sudden stirring in the distance!"));
1000         if (p_ptr->riding) p_ptr->update |= PU_BONUS;
1001 }
1002
1003
1004 /*!
1005  * @brief モンスターへの単体抹殺処理サブルーチン / Delete a non-unique/non-quest monster
1006  * @param m_idx 抹殺するモンスターID
1007  * @param power 抹殺の威力
1008  * @param player_cast プレイヤーの魔法によるものならば TRUE
1009  * @param dam_side プレイヤーへの負担ダメージ量(1d(dam_side))
1010  * @param spell_name 抹殺効果を起こした魔法の名前
1011  * @return 効力があった場合TRUEを返す
1012  */
1013 bool genocide_aux(MONSTER_IDX m_idx, int power, bool player_cast, int dam_side, concptr spell_name)
1014 {
1015         int          msec = delay_factor * delay_factor * delay_factor;
1016         monster_type *m_ptr = &current_floor_ptr->m_list[m_idx];
1017         monster_race *r_ptr = &r_info[m_ptr->r_idx];
1018         bool         resist = FALSE;
1019
1020         if (is_pet(m_ptr) && !player_cast) return FALSE;
1021
1022         /* Hack -- Skip Unique Monsters or Quest Monsters */
1023         if (r_ptr->flags1 & (RF1_UNIQUE | RF1_QUESTOR)) resist = TRUE;
1024         else if (r_ptr->flags7 & RF7_UNIQUE2) resist = TRUE;
1025         else if (m_idx == p_ptr->riding) resist = TRUE;
1026         else if ((p_ptr->inside_quest && !random_quest_number(current_floor_ptr->dun_level)) || p_ptr->inside_arena || p_ptr->inside_battle) resist = TRUE;
1027         else if (player_cast && (r_ptr->level > randint0(power))) resist = TRUE;
1028         else if (player_cast && (m_ptr->mflag2 & MFLAG2_NOGENO)) resist = TRUE;
1029
1030         else
1031         {
1032                 if (record_named_pet && is_pet(m_ptr) && m_ptr->nickname)
1033                 {
1034                         GAME_TEXT m_name[MAX_NLEN];
1035
1036                         monster_desc(m_name, m_ptr, MD_INDEF_VISIBLE);
1037                         do_cmd_write_nikki(NIKKI_NAMED_PET, RECORD_NAMED_PET_GENOCIDE, m_name);
1038                 }
1039
1040                 delete_monster_idx(m_idx);
1041         }
1042
1043         if (resist && player_cast)
1044         {
1045                 bool see_m = is_seen(m_ptr);
1046                 GAME_TEXT m_name[MAX_NLEN];
1047
1048                 monster_desc(m_name, m_ptr, 0);
1049                 if (see_m)
1050                 {
1051                         msg_format(_("%^sには効果がなかった。", "%^s is unaffected."), m_name);
1052                 }
1053                 if (MON_CSLEEP(m_ptr))
1054                 {
1055                         (void)set_monster_csleep(m_idx, 0);
1056                         if (m_ptr->ml)
1057                         {
1058                                 msg_format(_("%^sが目を覚ました。", "%^s wakes up."), m_name);
1059                         }
1060                 }
1061                 if (is_friendly(m_ptr) && !is_pet(m_ptr))
1062                 {
1063                         if (see_m)
1064                         {
1065                                 msg_format(_("%sは怒った!", "%^s gets angry!"), m_name);
1066                         }
1067                         set_hostile(m_ptr);
1068                 }
1069                 if (one_in_(13)) m_ptr->mflag2 |= MFLAG2_NOGENO;
1070         }
1071
1072         if (player_cast)
1073         {
1074                 take_hit(DAMAGE_GENO, randint1(dam_side), format(_("%^sの呪文を唱えた疲労", "the strain of casting %^s"), spell_name), -1);
1075         }
1076
1077         /* Visual feedback */
1078         move_cursor_relative(p_ptr->y, p_ptr->x);
1079
1080         p_ptr->redraw |= (PR_HP);
1081         p_ptr->window |= (PW_PLAYER);
1082
1083         handle_stuff();
1084         Term_fresh();
1085
1086         Term_xtra(TERM_XTRA_DELAY, msec);
1087
1088         return !resist;
1089 }
1090
1091
1092 /*!
1093  * @brief モンスターへのシンボル抹殺処理ルーチン / Delete all non-unique/non-quest monsters of a given "type" from the level
1094  * @param power 抹殺の威力
1095  * @param player_cast プレイヤーの魔法によるものならば TRUE
1096  * @return 効力があった場合TRUEを返す
1097  */
1098 bool symbol_genocide(int power, bool player_cast)
1099 {
1100         MONSTER_IDX i;
1101         char typ;
1102         bool result = FALSE;
1103
1104         /* Prevent genocide in quest levels */
1105         if ((p_ptr->inside_quest && !random_quest_number(current_floor_ptr->dun_level)) || p_ptr->inside_arena || p_ptr->inside_battle)
1106         {
1107                 msg_print(_("何も起きないようだ……", "It seems nothing happen here..."));
1108                 return (FALSE);
1109         }
1110
1111         /* Mega-Hack -- Get a monster symbol */
1112         while (!get_com(_("どの種類(文字)のモンスターを抹殺しますか: ", "Choose a monster race (by symbol) to genocide: "), &typ, FALSE)) ;
1113
1114         /* Delete the monsters of that "type" */
1115         for (i = 1; i < m_max; i++)
1116         {
1117                 monster_type *m_ptr = &current_floor_ptr->m_list[i];
1118                 monster_race *r_ptr = &r_info[m_ptr->r_idx];
1119                 if (!monster_is_valid(m_ptr)) continue;
1120
1121                 /* Skip "wrong" monsters */
1122                 if (r_ptr->d_char != typ) continue;
1123
1124                 result |= genocide_aux(i, power, player_cast, 4, _("抹殺", "Genocide"));
1125         }
1126
1127         if (result)
1128         {
1129                 chg_virtue(V_VITALITY, -2);
1130                 chg_virtue(V_CHANCE, -1);
1131         }
1132
1133         return result;
1134 }
1135
1136
1137 /*!
1138  * @brief モンスターへの周辺抹殺処理ルーチン / Delete all nearby (non-unique) monsters
1139  * @param power 抹殺の威力
1140  * @param player_cast プレイヤーの魔法によるものならば TRUE
1141  * @return 効力があった場合TRUEを返す
1142  */
1143 bool mass_genocide(int power, bool player_cast)
1144 {
1145         MONSTER_IDX i;
1146         bool result = FALSE;
1147
1148         /* Prevent mass genocide in quest levels */
1149         if ((p_ptr->inside_quest && !random_quest_number(current_floor_ptr->dun_level)) || p_ptr->inside_arena || p_ptr->inside_battle)
1150         {
1151                 return (FALSE);
1152         }
1153
1154         /* Delete the (nearby) monsters */
1155         for (i = 1; i < m_max; i++)
1156         {
1157                 monster_type *m_ptr = &current_floor_ptr->m_list[i];
1158                 if (!monster_is_valid(m_ptr)) continue;
1159
1160                 /* Skip distant monsters */
1161                 if (m_ptr->cdis > MAX_SIGHT) continue;
1162
1163                 /* Note effect */
1164                 result |= genocide_aux(i, power, player_cast, 3, _("周辺抹殺", "Mass Genocide"));
1165         }
1166
1167         if (result)
1168         {
1169                 chg_virtue(V_VITALITY, -2);
1170                 chg_virtue(V_CHANCE, -1);
1171         }
1172
1173         return result;
1174 }
1175
1176
1177 /*!
1178  * @brief アンデッド・モンスターへの周辺抹殺処理ルーチン / Delete all nearby (non-unique) undead
1179  * @param power 抹殺の威力
1180  * @param player_cast プレイヤーの魔法によるものならば TRUE
1181  * @return 効力があった場合TRUEを返す
1182  */
1183 bool mass_genocide_undead(int power, bool player_cast)
1184 {
1185         MONSTER_IDX i;
1186         bool result = FALSE;
1187
1188         /* Prevent mass genocide in quest levels */
1189         if ((p_ptr->inside_quest && !random_quest_number(current_floor_ptr->dun_level)) || p_ptr->inside_arena || p_ptr->inside_battle)
1190         {
1191                 return (FALSE);
1192         }
1193
1194         /* Delete the (nearby) monsters */
1195         for (i = 1; i < m_max; i++)
1196         {
1197                 monster_type *m_ptr = &current_floor_ptr->m_list[i];
1198                 monster_race *r_ptr = &r_info[m_ptr->r_idx];
1199                 if (!monster_is_valid(m_ptr)) continue;
1200
1201                 if (!(r_ptr->flags3 & RF3_UNDEAD)) continue;
1202
1203                 /* Skip distant monsters */
1204                 if (m_ptr->cdis > MAX_SIGHT) continue;
1205
1206                 /* Note effect */
1207                 result |= genocide_aux(i, power, player_cast, 3, _("アンデッド消滅", "Annihilate Undead"));
1208         }
1209
1210         if (result)
1211         {
1212                 chg_virtue(V_UNLIFE, -2);
1213                 chg_virtue(V_CHANCE, -1);
1214         }
1215
1216         return result;
1217 }
1218
1219
1220 /*!
1221  * @brief 周辺モンスターを調査する / Probe nearby monsters
1222  * @return 効力があった場合TRUEを返す
1223  */
1224 bool probing(void)
1225 {
1226         int i;
1227         int speed; /* TODO */
1228         bool_hack cu, cv;
1229         bool probe = FALSE;
1230         char buf[256];
1231         concptr align;
1232
1233         cu = Term->scr->cu;
1234         cv = Term->scr->cv;
1235         Term->scr->cu = 0;
1236         Term->scr->cv = 1;
1237
1238         /* Probe all (nearby) monsters */
1239         for (i = 1; i < m_max; i++)
1240         {
1241                 monster_type *m_ptr = &current_floor_ptr->m_list[i];
1242                 monster_race *r_ptr = &r_info[m_ptr->r_idx];
1243                 if (!monster_is_valid(m_ptr)) continue;
1244
1245                 /* Require line of sight */
1246                 if (!player_has_los_bold(m_ptr->fy, m_ptr->fx)) continue;
1247
1248                 /* Probe visible monsters */
1249                 if (m_ptr->ml)
1250                 {
1251                         GAME_TEXT m_name[MAX_NLEN];
1252
1253                         /* Start the message */
1254                         if (!probe)
1255                         {
1256                                 msg_print(_("調査中...", "Probing..."));
1257                         }
1258
1259                         msg_print(NULL);
1260
1261                         if (!is_original_ap(m_ptr))
1262                         {
1263                                 if (m_ptr->mflag2 & MFLAG2_KAGE)
1264                                         m_ptr->mflag2 &= ~(MFLAG2_KAGE);
1265
1266                                 m_ptr->ap_r_idx = m_ptr->r_idx;
1267                                 lite_spot(m_ptr->fy, m_ptr->fx);
1268                         }
1269                         /* Get "the monster" or "something" */
1270                         monster_desc(m_name, m_ptr, MD_IGNORE_HALLU | MD_INDEF_HIDDEN);
1271
1272                         speed = m_ptr->mspeed - 110;
1273                         if (MON_FAST(m_ptr)) speed += 10;
1274                         if (MON_SLOW(m_ptr)) speed -= 10;
1275                         if (ironman_nightmare) speed += 5;
1276
1277                         /* Get the monster's alignment */
1278                         if ((r_ptr->flags3 & (RF3_EVIL | RF3_GOOD)) == (RF3_EVIL | RF3_GOOD)) align = _("善悪", "good&evil");
1279                         else if (r_ptr->flags3 & RF3_EVIL) align = _("邪悪", "evil");
1280                         else if (r_ptr->flags3 & RF3_GOOD) align = _("善良", "good");
1281                         else if ((m_ptr->sub_align & (SUB_ALIGN_EVIL | SUB_ALIGN_GOOD)) == (SUB_ALIGN_EVIL | SUB_ALIGN_GOOD)) _(align = "中立(善悪)", "neutral(good&evil)");
1282                         else if (m_ptr->sub_align & SUB_ALIGN_EVIL) align = _("中立(邪悪)", "neutral(evil)");
1283                         else if (m_ptr->sub_align & SUB_ALIGN_GOOD) align = _("中立(善良)", "neutral(good)");
1284                         else align = _("中立", "neutral");
1285
1286                         sprintf(buf,_("%s ... 属性:%s HP:%d/%d AC:%d 速度:%s%d 経験:", "%s ... align:%s HP:%d/%d AC:%d speed:%s%d exp:"),
1287                                 m_name, align, (int)m_ptr->hp, (int)m_ptr->maxhp, r_ptr->ac, (speed > 0) ? "+" : "", speed);
1288
1289                         if (r_ptr->next_r_idx)
1290                         {
1291                                 strcat(buf, format("%d/%d ", m_ptr->exp, r_ptr->next_exp));
1292                         }
1293                         else
1294                         {
1295                                 strcat(buf, "xxx ");
1296                         }
1297
1298                         if (MON_CSLEEP(m_ptr)) strcat(buf,_("睡眠 ", "sleeping "));
1299                         if (MON_STUNNED(m_ptr)) strcat(buf, _("朦朧 ", "stunned "));
1300                         if (MON_MONFEAR(m_ptr)) strcat(buf, _("恐怖 ", "scared "));
1301                         if (MON_CONFUSED(m_ptr)) strcat(buf, _("混乱 ", "confused "));
1302                         if (MON_INVULNER(m_ptr)) strcat(buf, _("無敵 ", "invulnerable "));
1303                         buf[strlen(buf)-1] = '\0';
1304                         prt(buf, 0, 0);
1305
1306                         /* HACK : Add the line to message buffer */
1307                         message_add(buf);
1308
1309                         p_ptr->window |= (PW_MESSAGE);
1310                         handle_stuff();
1311
1312                         if (m_ptr->ml) move_cursor_relative(m_ptr->fy, m_ptr->fx);
1313                         inkey();
1314
1315                         Term_erase(0, 0, 255);
1316
1317                         /* Learn everything about this monster */
1318                         if (lore_do_probe(m_ptr->r_idx))
1319                         {
1320                                 /* Get base name of monster */
1321                                 strcpy(buf, (r_name + r_ptr->name));
1322
1323 #ifdef JP
1324                                 /* Note that we learnt some new flags  -Mogami- */
1325                                 msg_format("%sについてさらに詳しくなった気がする。", buf);
1326 #else
1327                                 /* Pluralize it */
1328                                 plural_aux(buf);
1329
1330                                 /* Note that we learnt some new flags  -Mogami- */
1331                                 msg_format("You now know more about %s.", buf);
1332 #endif
1333                                 /* Clear -more- prompt */
1334                                 msg_print(NULL);
1335                         }
1336
1337                         /* Probe worked */
1338                         probe = TRUE;
1339                 }
1340         }
1341
1342         Term->scr->cu = cu;
1343         Term->scr->cv = cv;
1344         Term_fresh();
1345
1346         if (probe)
1347         {
1348                 chg_virtue(V_KNOWLEDGE, 1);
1349                 msg_print(_("これで全部です。", "That's all."));
1350         }
1351         return (probe);
1352 }
1353
1354
1355
1356 /*!
1357  * @brief *破壊*処理を行う / The spell of destruction
1358  * @param y1 破壊の中心Y座標
1359  * @param x1 破壊の中心X座標 
1360  * @param r 破壊の半径
1361  * @param in_generate ダンジョンフロア生成中の処理ならばTRUE
1362  * @return 効力があった場合TRUEを返す
1363  * @details
1364  * <pre>
1365  * This spell "deletes" monsters (instead of "killing" them).
1366  *
1367  * Later we may use one function for both "destruction" and
1368  * "earthquake" by using the "full" to select "destruction".
1369  * </pre>
1370  */
1371 bool destroy_area(POSITION y1, POSITION x1, POSITION r, bool in_generate)
1372 {
1373         POSITION y, x;
1374         int k, t;
1375         grid_type *g_ptr;
1376         bool flag = FALSE;
1377
1378         /* Prevent destruction of quest levels and town */
1379         if ((p_ptr->inside_quest && is_fixed_quest_idx(p_ptr->inside_quest)) || !current_floor_ptr->dun_level)
1380         {
1381                 return (FALSE);
1382         }
1383
1384         /* Lose monster light */
1385         if (!in_generate) clear_mon_lite();
1386
1387         /* Big area of affect */
1388         for (y = (y1 - r); y <= (y1 + r); y++)
1389         {
1390                 for (x = (x1 - r); x <= (x1 + r); x++)
1391                 {
1392                         /* Skip illegal grids */
1393                         if (!in_bounds(y, x)) continue;
1394
1395                         /* Extract the distance */
1396                         k = distance(y1, x1, y, x);
1397
1398                         /* Stay in the circle of death */
1399                         if (k > r) continue;
1400                         g_ptr = &current_floor_ptr->grid_array[y][x];
1401
1402                         /* Lose room and vault */
1403                         g_ptr->info &= ~(CAVE_ROOM | CAVE_ICKY);
1404
1405                         /* Lose light and knowledge */
1406                         g_ptr->info &= ~(CAVE_MARK | CAVE_GLOW | CAVE_KNOWN);
1407
1408                         if (!in_generate) /* Normal */
1409                         {
1410                                 /* Lose unsafety */
1411                                 g_ptr->info &= ~(CAVE_UNSAFE);
1412
1413                                 /* Hack -- Notice player affect */
1414                                 if (player_bold(y, x))
1415                                 {
1416                                         /* Hurt the player later */
1417                                         flag = TRUE;
1418
1419                                         /* Do not hurt this grid */
1420                                         continue;
1421                                 }
1422                         }
1423
1424                         /* Hack -- Skip the epicenter */
1425                         if ((y == y1) && (x == x1)) continue;
1426
1427                         if (g_ptr->m_idx)
1428                         {
1429                                 monster_type *m_ptr = &current_floor_ptr->m_list[g_ptr->m_idx];
1430                                 monster_race *r_ptr = &r_info[m_ptr->r_idx];
1431
1432                                 if (in_generate) /* In generation */
1433                                 {
1434                                         /* Delete the monster (if any) */
1435                                         delete_monster(y, x);
1436                                 }
1437                                 else if (r_ptr->flags1 & RF1_QUESTOR)
1438                                 {
1439                                         /* Heal the monster */
1440                                         m_ptr->hp = m_ptr->maxhp;
1441
1442                                         /* Try to teleport away quest monsters */
1443                                         if (!teleport_away(g_ptr->m_idx, (r * 2) + 1, TELEPORT_DEC_VALOUR)) continue;
1444                                 }
1445                                 else
1446                                 {
1447                                         if (record_named_pet && is_pet(m_ptr) && m_ptr->nickname)
1448                                         {
1449                                                 GAME_TEXT m_name[MAX_NLEN];
1450
1451                                                 monster_desc(m_name, m_ptr, MD_INDEF_VISIBLE);
1452                                                 do_cmd_write_nikki(NIKKI_NAMED_PET, RECORD_NAMED_PET_DESTROY, m_name);
1453                                         }
1454
1455                                         /* Delete the monster (if any) */
1456                                         delete_monster(y, x);
1457                                 }
1458                         }
1459
1460                         /* During generation, destroyed artifacts are "preserved" */
1461                         if (preserve_mode || in_generate)
1462                         {
1463                                 OBJECT_IDX this_o_idx, next_o_idx = 0;
1464
1465                                 /* Scan all objects in the grid */
1466                                 for (this_o_idx = g_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
1467                                 {
1468                                         object_type *o_ptr;
1469                                         o_ptr = &current_floor_ptr->o_list[this_o_idx];
1470                                         next_o_idx = o_ptr->next_o_idx;
1471
1472                                         /* Hack -- Preserve unknown artifacts */
1473                                         if (object_is_fixed_artifact(o_ptr) && (!object_is_known(o_ptr) || in_generate))
1474                                         {
1475                                                 /* Mega-Hack -- Preserve the artifact */
1476                                                 a_info[o_ptr->name1].cur_num = 0;
1477
1478                                                 if (in_generate && cheat_peek)
1479                                                 {
1480                                                         GAME_TEXT o_name[MAX_NLEN];
1481                                                         object_desc(o_name, o_ptr, (OD_NAME_ONLY | OD_STORE));
1482                                                         msg_format(_("伝説のアイテム (%s) は生成中に*破壊*された。", "Artifact (%s) was *destroyed* during generation."), o_name);
1483                                                 }
1484                                         }
1485                                         else if (in_generate && cheat_peek && o_ptr->art_name)
1486                                         {
1487                                                 msg_print(_("ランダム・アーティファクトの1つは生成中に*破壊*された。", 
1488                                                                         "One of the random artifacts was *destroyed* during generation."));
1489                                         }
1490                                 }
1491                         }
1492
1493                         delete_object(y, x);
1494
1495                         /* Destroy "non-permanent" grids */
1496                         if (!cave_perma_grid(g_ptr))
1497                         {
1498                                 /* Wall (or floor) type */
1499                                 t = randint0(200);
1500
1501                                 if (!in_generate) /* Normal */
1502                                 {
1503                                         if (t < 20)
1504                                         {
1505                                                 /* Create granite wall */
1506                                                 cave_set_feat(y, x, feat_granite);
1507                                         }
1508                                         else if (t < 70)
1509                                         {
1510                                                 /* Create quartz vein */
1511                                                 cave_set_feat(y, x, feat_quartz_vein);
1512                                         }
1513                                         else if (t < 100)
1514                                         {
1515                                                 /* Create magma vein */
1516                                                 cave_set_feat(y, x, feat_magma_vein);
1517                                         }
1518                                         else
1519                                         {
1520                                                 /* Create floor */
1521                                                 cave_set_feat(y, x, feat_ground_type[randint0(100)]);
1522                                         }
1523                                 }
1524                                 else /* In generation */
1525                                 {
1526                                         if (t < 20)
1527                                         {
1528                                                 /* Create granite wall */
1529                                                 place_extra_grid(g_ptr);
1530                                         }
1531                                         else if (t < 70)
1532                                         {
1533                                                 /* Create quartz vein */
1534                                                 g_ptr->feat = feat_quartz_vein;
1535                                         }
1536                                         else if (t < 100)
1537                                         {
1538                                                 /* Create magma vein */
1539                                                 g_ptr->feat = feat_magma_vein;
1540                                         }
1541                                         else
1542                                         {
1543                                                 /* Create floor */
1544                                                 place_floor_grid(g_ptr);
1545                                         }
1546
1547                                         /* Clear garbage of hidden trap or door */
1548                                         g_ptr->mimic = 0;
1549                                 }
1550                         }
1551                 }
1552         }
1553
1554         if (!in_generate)
1555         {
1556                 /* Process "re-glowing" */
1557                 for (y = (y1 - r); y <= (y1 + r); y++)
1558                 {
1559                         for (x = (x1 - r); x <= (x1 + r); x++)
1560                         {
1561                                 /* Skip illegal grids */
1562                                 if (!in_bounds(y, x)) continue;
1563
1564                                 /* Extract the distance */
1565                                 k = distance(y1, x1, y, x);
1566
1567                                 /* Stay in the circle of death */
1568                                 if (k > r) continue;
1569                                 g_ptr = &current_floor_ptr->grid_array[y][x];
1570
1571                                 if (is_mirror_grid(g_ptr)) g_ptr->info |= CAVE_GLOW;
1572                                 else if (!(d_info[p_ptr->dungeon_idx].flags1 & DF1_DARKNESS))
1573                                 {
1574                                         DIRECTION i;
1575                                         POSITION yy, xx;
1576                                         grid_type *cc_ptr;
1577
1578                                         for (i = 0; i < 9; i++)
1579                                         {
1580                                                 yy = y + ddy_ddd[i];
1581                                                 xx = x + ddx_ddd[i];
1582                                                 if (!in_bounds2(yy, xx)) continue;
1583                                                 cc_ptr = &current_floor_ptr->grid_array[yy][xx];
1584                                                 if (have_flag(f_info[get_feat_mimic(cc_ptr)].flags, FF_GLOW))
1585                                                 {
1586                                                         g_ptr->info |= CAVE_GLOW;
1587                                                         break;
1588                                                 }
1589                                         }
1590                                 }
1591                         }
1592                 }
1593
1594                 /* Hack -- Affect player */
1595                 if (flag)
1596                 {
1597                         msg_print(_("燃えるような閃光が発生した!", "There is a searing blast of light!"));
1598
1599                         /* Blind the player */
1600                         if (!p_ptr->resist_blind && !p_ptr->resist_lite)
1601                         {
1602                                 /* Become blind */
1603                                 (void)set_blind(p_ptr->blind + 10 + randint1(10));
1604                         }
1605                 }
1606
1607                 forget_flow();
1608
1609                 /* Mega-Hack -- Forget the view and lite */
1610                 p_ptr->update |= (PU_UN_VIEW | PU_UN_LITE | PU_VIEW | PU_LITE | PU_FLOW | PU_MON_LITE | PU_MONSTERS);
1611                 p_ptr->redraw |= (PR_MAP);
1612                 p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
1613
1614                 if (p_ptr->special_defense & NINJA_S_STEALTH)
1615                 {
1616                         if (current_floor_ptr->grid_array[p_ptr->y][p_ptr->x].info & CAVE_GLOW) set_superstealth(FALSE);
1617                 }
1618         }
1619
1620         /* Success */
1621         return (TRUE);
1622 }
1623
1624
1625 /*!
1626  * @brief 地震処理(サブルーチン) /
1627  * Induce an "earthquake" of the given radius at the given location.
1628  * @return 効力があった場合TRUEを返す
1629  * @param cy 中心Y座標
1630  * @param cx 中心X座標
1631  * @param r 効果半径
1632  * @param m_idx 地震を起こしたモンスターID(0ならばプレイヤー)
1633  * @details
1634  * <pre>
1635  *
1636  * This will current_world_ptr->game_turn some walls into floors and some floors into walls.
1637  *
1638  * The player will take damage and "jump" into a safe grid if possible,
1639  * otherwise, he will "tunnel" through the rubble instantaneously.
1640  *
1641  * Monsters will take damage, and "jump" into a safe grid if possible,
1642  * otherwise they will be "buried" in the rubble, disappearing from
1643  * the level in the same way that they do when genocided.
1644  *
1645  * Note that thus the player and monsters (except eaters of walls and
1646  * passers through walls) will never occupy the same grid as a wall.
1647  * Note that as of now (2.7.8) no monster may occupy a "wall" grid, even
1648  * for a single current_world_ptr->game_turn, unless that monster can pass_walls or kill_walls.
1649  * This has allowed massive simplification of the "monster" code.
1650  * </pre>
1651  */
1652 bool earthquake_aux(POSITION cy, POSITION cx, POSITION r, MONSTER_IDX m_idx)
1653 {
1654         DIRECTION i;
1655         int t;
1656         POSITION y, x, yy, xx, dy, dx;
1657         int damage = 0;
1658         int sn = 0;
1659         POSITION sy = 0, sx = 0;
1660         bool hurt = FALSE;
1661         grid_type *g_ptr;
1662         bool map[32][32];
1663
1664         /* Prevent destruction of quest levels and town */
1665         if ((p_ptr->inside_quest && is_fixed_quest_idx(p_ptr->inside_quest)) || !current_floor_ptr->dun_level)
1666         {
1667                 return (FALSE);
1668         }
1669
1670         /* Paranoia -- Enforce maximum range */
1671         if (r > 12) r = 12;
1672
1673         /* Clear the "maximal blast" area */
1674         for (y = 0; y < 32; y++)
1675         {
1676                 for (x = 0; x < 32; x++)
1677                 {
1678                         map[y][x] = FALSE;
1679                 }
1680         }
1681
1682         /* Check around the epicenter */
1683         for (dy = -r; dy <= r; dy++)
1684         {
1685                 for (dx = -r; dx <= r; dx++)
1686                 {
1687                         /* Extract the location */
1688                         yy = cy + dy;
1689                         xx = cx + dx;
1690
1691                         /* Skip illegal grids */
1692                         if (!in_bounds(yy, xx)) continue;
1693
1694                         /* Skip distant grids */
1695                         if (distance(cy, cx, yy, xx) > r) continue;
1696                         g_ptr = &current_floor_ptr->grid_array[yy][xx];
1697
1698                         /* Lose room and vault / Lose light and knowledge */
1699                         g_ptr->info &= ~(CAVE_ROOM | CAVE_ICKY | CAVE_UNSAFE);
1700                         g_ptr->info &= ~(CAVE_GLOW | CAVE_MARK | CAVE_KNOWN);
1701
1702                         /* Skip the epicenter */
1703                         if (!dx && !dy) continue;
1704
1705                         /* Skip most grids */
1706                         if (randint0(100) < 85) continue;
1707
1708                         /* Damage this grid */
1709                         map[16+yy-cy][16+xx-cx] = TRUE;
1710
1711                         /* Hack -- Take note of player damage */
1712                         if (player_bold(yy, xx)) hurt = TRUE;
1713                 }
1714         }
1715
1716         /* First, affect the player (if necessary) */
1717         if (hurt && !p_ptr->pass_wall && !p_ptr->kill_wall)
1718         {
1719                 /* Check around the player */
1720                 for (i = 0; i < 8; i++)
1721                 {
1722                         y = p_ptr->y + ddy_ddd[i];
1723                         x = p_ptr->x + ddx_ddd[i];
1724
1725                         /* Skip non-empty grids */
1726                         if (!cave_empty_bold(y, x)) continue;
1727
1728                         /* Important -- Skip "quake" grids */
1729                         if (map[16+y-cy][16+x-cx]) continue;
1730
1731                         if (current_floor_ptr->grid_array[y][x].m_idx) continue;
1732
1733                         /* Count "safe" grids */
1734                         sn++;
1735
1736                         /* Randomize choice */
1737                         if (randint0(sn) > 0) continue;
1738
1739                         /* Save the safe location */
1740                         sy = y; sx = x;
1741                 }
1742
1743                 /* Random message */
1744                 switch (randint1(3))
1745                 {
1746                         case 1:
1747                         {
1748                                 msg_print(_("ダンジョンの壁が崩れた!", "The current_floor_ptr->grid_array ceiling collapses!"));
1749                                 break;
1750                         }
1751                         case 2:
1752                         {
1753                                 msg_print(_("ダンジョンの床が不自然にねじ曲がった!", "The current_floor_ptr->grid_array floor twists in an unnatural way!"));
1754                                 break;
1755                         }
1756                         default:
1757                         {
1758                                 msg_print(_("ダンジョンが揺れた!崩れた岩が頭に降ってきた!", "The current_floor_ptr->grid_array quakes!  You are pummeled with debris!"));
1759                                 break;
1760                         }
1761                 }
1762
1763                 /* Hurt the player a lot */
1764                 if (!sn)
1765                 {
1766                         /* Message and damage */
1767                         msg_print(_("あなたはひどい怪我を負った!", "You are severely crushed!"));
1768                         damage = 200;
1769                 }
1770
1771                 /* Destroy the grid, and push the player to safety */
1772                 else
1773                 {
1774                         /* Calculate results */
1775                         switch (randint1(3))
1776                         {
1777                                 case 1:
1778                                 {
1779                                         msg_print(_("降り注ぐ岩をうまく避けた!", "You nimbly dodge the blast!"));
1780                                         damage = 0;
1781                                         break;
1782                                 }
1783                                 case 2:
1784                                 {
1785                                         msg_print(_("岩石があなたに直撃した!", "You are bashed by rubble!"));
1786                                         damage = damroll(10, 4);
1787                                         (void)set_stun(p_ptr->stun + randint1(50));
1788                                         break;
1789                                 }
1790                                 case 3:
1791                                 {
1792                                         msg_print(_("あなたは床と壁との間に挟まれてしまった!", "You are crushed between the floor and ceiling!"));
1793                                         damage = damroll(10, 4);
1794                                         (void)set_stun(p_ptr->stun + randint1(50));
1795                                         break;
1796                                 }
1797                         }
1798
1799                         /* Move the player to the safe location */
1800                         (void)move_player_effect(sy, sx, MPE_DONT_PICKUP);
1801                 }
1802
1803                 /* Important -- no wall on player */
1804                 map[16+p_ptr->y-cy][16+p_ptr->x-cx] = FALSE;
1805
1806                 if (damage)
1807                 {
1808                         concptr killer;
1809
1810                         if (m_idx)
1811                         {
1812                                 GAME_TEXT m_name[MAX_NLEN];
1813                                 monster_type *m_ptr = &current_floor_ptr->m_list[m_idx];
1814                                 monster_desc(m_name, m_ptr, MD_WRONGDOER_NAME);
1815                                 killer = format(_("%sの起こした地震", "an earthquake caused by %s"), m_name);
1816                         }
1817                         else
1818                         {
1819                                 killer = _("地震", "an earthquake");
1820                         }
1821
1822                         take_hit(DAMAGE_ATTACK, damage, killer, -1);
1823                 }
1824         }
1825
1826         /* Examine the quaked region */
1827         for (dy = -r; dy <= r; dy++)
1828         {
1829                 for (dx = -r; dx <= r; dx++)
1830                 {
1831                         /* Extract the location */
1832                         yy = cy + dy;
1833                         xx = cx + dx;
1834
1835                         /* Skip unaffected grids */
1836                         if (!map[16+yy-cy][16+xx-cx]) continue;
1837                         g_ptr = &current_floor_ptr->grid_array[yy][xx];
1838
1839                         if (g_ptr->m_idx == p_ptr->riding) continue;
1840
1841                         /* Process monsters */
1842                         if (g_ptr->m_idx)
1843                         {
1844                                 monster_type *m_ptr = &current_floor_ptr->m_list[g_ptr->m_idx];
1845                                 monster_race *r_ptr = &r_info[m_ptr->r_idx];
1846
1847                                 /* Quest monsters */
1848                                 if (r_ptr->flags1 & RF1_QUESTOR)
1849                                 {
1850                                         /* No wall on quest monsters */
1851                                         map[16+yy-cy][16+xx-cx] = FALSE;
1852
1853                                         continue;
1854                                 }
1855
1856                                 /* Most monsters cannot co-exist with rock */
1857                                 if (!(r_ptr->flags2 & (RF2_KILL_WALL)) &&
1858                                     !(r_ptr->flags2 & (RF2_PASS_WALL)))
1859                                 {
1860                                         GAME_TEXT m_name[MAX_NLEN];
1861
1862                                         /* Assume not safe */
1863                                         sn = 0;
1864
1865                                         /* Monster can move to escape the wall */
1866                                         if (!(r_ptr->flags1 & (RF1_NEVER_MOVE)))
1867                                         {
1868                                                 /* Look for safety */
1869                                                 for (i = 0; i < 8; i++)
1870                                                 {
1871                                                         y = yy + ddy_ddd[i];
1872                                                         x = xx + ddx_ddd[i];
1873
1874                                                         /* Skip non-empty grids */
1875                                                         if (!cave_empty_bold(y, x)) continue;
1876
1877                                                         /* Hack -- no safety on glyph of warding */
1878                                                         if (is_glyph_grid(&current_floor_ptr->grid_array[y][x])) continue;
1879                                                         if (is_explosive_rune_grid(&current_floor_ptr->grid_array[y][x])) continue;
1880
1881                                                         /* ... nor on the Pattern */
1882                                                         if (pattern_tile(y, x)) continue;
1883
1884                                                         /* Important -- Skip "quake" grids */
1885                                                         if (map[16+y-cy][16+x-cx]) continue;
1886
1887                                                         if (current_floor_ptr->grid_array[y][x].m_idx) continue;
1888                                                         if (player_bold(y, x)) continue;
1889
1890                                                         /* Count "safe" grids */
1891                                                         sn++;
1892
1893                                                         /* Randomize choice */
1894                                                         if (randint0(sn) > 0) continue;
1895
1896                                                         /* Save the safe grid */
1897                                                         sy = y; sx = x;
1898                                                 }
1899                                         }
1900
1901                                         monster_desc(m_name, m_ptr, 0);
1902
1903                                         /* Scream in pain */
1904                                         if (!ignore_unview || is_seen(m_ptr)) msg_format(_("%^sは苦痛で泣きわめいた!", "%^s wails out in pain!"), m_name);
1905
1906                                         /* Take damage from the quake */
1907                                         damage = (sn ? damroll(4, 8) : (m_ptr->hp + 1));
1908
1909                                         /* Monster is certainly awake */
1910                                         (void)set_monster_csleep(g_ptr->m_idx, 0);
1911
1912                                         /* Apply damage directly */
1913                                         m_ptr->hp -= damage;
1914
1915                                         /* Delete (not kill) "dead" monsters */
1916                                         if (m_ptr->hp < 0)
1917                                         {
1918                                                 if (!ignore_unview || is_seen(m_ptr)) 
1919                                                         msg_format(_("%^sは岩石に埋もれてしまった!", "%^s is embedded in the rock!"), m_name);
1920
1921                                                 if (g_ptr->m_idx)
1922                                                 {
1923                                                         if (record_named_pet && is_pet(&current_floor_ptr->m_list[g_ptr->m_idx]) && current_floor_ptr->m_list[g_ptr->m_idx].nickname)
1924                                                         {
1925                                                                 char m2_name[MAX_NLEN];
1926
1927                                                                 monster_desc(m2_name, m_ptr, MD_INDEF_VISIBLE);
1928                                                                 do_cmd_write_nikki(NIKKI_NAMED_PET, RECORD_NAMED_PET_EARTHQUAKE, m2_name);
1929                                                         }
1930                                                 }
1931
1932                                                 delete_monster(yy, xx);
1933
1934                                                 /* No longer safe */
1935                                                 sn = 0;
1936                                         }
1937
1938                                         /* Hack -- Escape from the rock */
1939                                         if (sn)
1940                                         {
1941                                                 IDX m_idx_aux = current_floor_ptr->grid_array[yy][xx].m_idx;
1942
1943                                                 /* Update the old location */
1944                                                 current_floor_ptr->grid_array[yy][xx].m_idx = 0;
1945
1946                                                 /* Update the new location */
1947                                                 current_floor_ptr->grid_array[sy][sx].m_idx = m_idx_aux;
1948
1949                                                 /* Move the monster */
1950                                                 m_ptr->fy = sy;
1951                                                 m_ptr->fx = sx;
1952
1953                                                 update_monster(m_idx, TRUE);
1954                                                 lite_spot(yy, xx);
1955                                                 lite_spot(sy, sx);
1956                                         }
1957                                 }
1958                         }
1959                 }
1960         }
1961
1962         /* Lose monster light */
1963         clear_mon_lite();
1964
1965         /* Examine the quaked region */
1966         for (dy = -r; dy <= r; dy++)
1967         {
1968                 for (dx = -r; dx <= r; dx++)
1969                 {
1970                         /* Extract the location */
1971                         yy = cy + dy;
1972                         xx = cx + dx;
1973
1974                         /* Skip unaffected grids */
1975                         if (!map[16+yy-cy][16+xx-cx]) continue;
1976
1977                         g_ptr = &current_floor_ptr->grid_array[yy][xx];
1978
1979                         /* Paranoia -- never affect player */
1980 /*                      if (player_bold(yy, xx)) continue; */
1981
1982                         /* Destroy location (if valid) */
1983                         if (cave_valid_bold(yy, xx))
1984                         {
1985                                 delete_object(yy, xx);
1986
1987                                 /* Wall (or floor) type */
1988                                 t = cave_have_flag_bold(yy, xx, FF_PROJECT) ? randint0(100) : 200;
1989
1990                                 /* Granite */
1991                                 if (t < 20)
1992                                 {
1993                                         /* Create granite wall */
1994                                         cave_set_feat(yy, xx, feat_granite);
1995                                 }
1996
1997                                 /* Quartz */
1998                                 else if (t < 70)
1999                                 {
2000                                         /* Create quartz vein */
2001                                         cave_set_feat(yy, xx, feat_quartz_vein);
2002                                 }
2003
2004                                 /* Magma */
2005                                 else if (t < 100)
2006                                 {
2007                                         /* Create magma vein */
2008                                         cave_set_feat(yy, xx, feat_magma_vein);
2009                                 }
2010
2011                                 /* Floor */
2012                                 else
2013                                 {
2014                                         /* Create floor */
2015                                         cave_set_feat(yy, xx, feat_ground_type[randint0(100)]);
2016                                 }
2017                         }
2018                 }
2019         }
2020
2021         /* Process "re-glowing" */
2022         for (dy = -r; dy <= r; dy++)
2023         {
2024                 for (dx = -r; dx <= r; dx++)
2025                 {
2026                         /* Extract the location */
2027                         yy = cy + dy;
2028                         xx = cx + dx;
2029
2030                         /* Skip illegal grids */
2031                         if (!in_bounds(yy, xx)) continue;
2032
2033                         /* Skip distant grids */
2034                         if (distance(cy, cx, yy, xx) > r) continue;
2035                         g_ptr = &current_floor_ptr->grid_array[yy][xx];
2036
2037                         if (is_mirror_grid(g_ptr)) g_ptr->info |= CAVE_GLOW;
2038                         else if (!(d_info[p_ptr->dungeon_idx].flags1 & DF1_DARKNESS))
2039                         {
2040                                 DIRECTION ii;
2041                                 POSITION yyy, xxx;
2042                                 grid_type *cc_ptr;
2043
2044                                 for (ii = 0; ii < 9; ii++)
2045                                 {
2046                                         yyy = yy + ddy_ddd[ii];
2047                                         xxx = xx + ddx_ddd[ii];
2048                                         if (!in_bounds2(yyy, xxx)) continue;
2049                                         cc_ptr = &current_floor_ptr->grid_array[yyy][xxx];
2050                                         if (have_flag(f_info[get_feat_mimic(cc_ptr)].flags, FF_GLOW))
2051                                         {
2052                                                 g_ptr->info |= CAVE_GLOW;
2053                                                 break;
2054                                         }
2055                                 }
2056                         }
2057                 }
2058         }
2059
2060         /* Mega-Hack -- Forget the view and lite */
2061         p_ptr->update |= (PU_UN_VIEW | PU_UN_LITE | PU_VIEW | PU_LITE | PU_FLOW | PU_MON_LITE | PU_MONSTERS);
2062         p_ptr->redraw |= (PR_HEALTH | PR_UHEALTH | PR_MAP);
2063         p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
2064
2065         if (p_ptr->special_defense & NINJA_S_STEALTH)
2066         {
2067                 if (current_floor_ptr->grid_array[p_ptr->y][p_ptr->x].info & CAVE_GLOW) set_superstealth(FALSE);
2068         }
2069
2070         /* Success */
2071         return (TRUE);
2072 }
2073
2074 /*!
2075  * @brief 地震処理(プレイヤーの中心発動) /
2076  * Induce an "earthquake" of the given radius at the given location.
2077  * @return 効力があった場合TRUEを返す
2078  * @param cy 中心Y座標
2079  * @param cx 中心X座標
2080  * @param r 効果半径
2081  */
2082 bool earthquake(POSITION cy, POSITION cx, POSITION r)
2083 {
2084         return earthquake_aux(cy, cx, r, 0);
2085 }
2086
2087 /*!
2088  * @brief ペット爆破処理 /
2089  * @return なし
2090  */
2091 void discharge_minion(void)
2092 {
2093         MONSTER_IDX i;
2094         bool okay = TRUE;
2095
2096         for (i = 1; i < m_max; i++)
2097         {
2098                 monster_type *m_ptr = &current_floor_ptr->m_list[i];
2099                 if (!m_ptr->r_idx || !is_pet(m_ptr)) continue;
2100                 if (m_ptr->nickname) okay = FALSE;
2101         }
2102         if (!okay || p_ptr->riding)
2103         {
2104                 if (!get_check(_("本当に全ペットを爆破しますか?", "You will blast all pets. Are you sure? ")))
2105                         return;
2106         }
2107         for (i = 1; i < m_max; i++)
2108         {
2109                 HIT_POINT dam;
2110                 monster_type *m_ptr = &current_floor_ptr->m_list[i];
2111                 monster_race *r_ptr;
2112
2113                 if (!m_ptr->r_idx || !is_pet(m_ptr)) continue;
2114                 r_ptr = &r_info[m_ptr->r_idx];
2115
2116                 /* Uniques resist discharging */
2117                 if (r_ptr->flags1 & RF1_UNIQUE)
2118                 {
2119                         GAME_TEXT m_name[MAX_NLEN];
2120                         monster_desc(m_name, m_ptr, 0x00);
2121                         msg_format(_("%sは爆破されるのを嫌がり、勝手に自分の世界へと帰った。", "%^s resists to be blasted, and run away."), m_name);
2122                         delete_monster_idx(i);
2123                         continue;
2124                 }
2125                 dam = m_ptr->maxhp / 2;
2126                 if (dam > 100) dam = (dam - 100) / 2 + 100;
2127                 if (dam > 400) dam = (dam - 400) / 2 + 400;
2128                 if (dam > 800) dam = 800;
2129                 project(i, 2 + (r_ptr->level / 20), m_ptr->fy, m_ptr->fx, dam, GF_PLASMA, 
2130                         PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL, -1);
2131
2132                 if (record_named_pet && m_ptr->nickname)
2133                 {
2134                         GAME_TEXT m_name[MAX_NLEN];
2135
2136                         monster_desc(m_name, m_ptr, MD_INDEF_VISIBLE);
2137                         do_cmd_write_nikki(NIKKI_NAMED_PET, RECORD_NAMED_PET_BLAST, m_name);
2138                 }
2139
2140                 delete_monster_idx(i);
2141         }
2142 }
2143
2144
2145 /*!
2146  * @brief 部屋全体を照らすサブルーチン
2147  * @return なし
2148  * @details
2149  * <pre>
2150  * This routine clears the entire "temp" set.
2151  * This routine will Perma-Lite all "temp" grids.
2152  * This routine is used (only) by "lite_room()"
2153  * Dark grids are illuminated.
2154  * Also, process all affected monsters.
2155  *
2156  * SMART monsters always wake up when illuminated
2157  * NORMAL monsters wake up 1/4 the time when illuminated
2158  * STUPID monsters wake up 1/10 the time when illuminated
2159  * </pre>
2160  */
2161 static void cave_temp_room_lite(void)
2162 {
2163         int i;
2164
2165         /* Clear them all */
2166         for (i = 0; i < tmp_pos.n; i++)
2167         {
2168                 POSITION y = tmp_pos.y[i];
2169                 POSITION x = tmp_pos.x[i];
2170
2171                 grid_type *g_ptr = &current_floor_ptr->grid_array[y][x];
2172
2173                 /* No longer in the array */
2174                 g_ptr->info &= ~(CAVE_TEMP);
2175
2176                 /* Update only non-CAVE_GLOW grids */
2177                 /* if (g_ptr->info & (CAVE_GLOW)) continue; */
2178
2179                 /* Perma-Lite */
2180                 g_ptr->info |= (CAVE_GLOW);
2181
2182                 /* Process affected monsters */
2183                 if (g_ptr->m_idx)
2184                 {
2185                         PERCENTAGE chance = 25;
2186                         monster_type    *m_ptr = &current_floor_ptr->m_list[g_ptr->m_idx];
2187                         monster_race    *r_ptr = &r_info[m_ptr->r_idx];
2188                         update_monster(g_ptr->m_idx, FALSE);
2189
2190                         /* Stupid monsters rarely wake up */
2191                         if (r_ptr->flags2 & (RF2_STUPID)) chance = 10;
2192
2193                         /* Smart monsters always wake up */
2194                         if (r_ptr->flags2 & (RF2_SMART)) chance = 100;
2195
2196                         /* Sometimes monsters wake up */
2197                         if (MON_CSLEEP(m_ptr) && (randint0(100) < chance))
2198                         {
2199                                 /* Wake up! */
2200                                 (void)set_monster_csleep(g_ptr->m_idx, 0);
2201
2202                                 /* Notice the "waking up" */
2203                                 if (m_ptr->ml)
2204                                 {
2205                                         GAME_TEXT m_name[MAX_NLEN];
2206                                         monster_desc(m_name, m_ptr, 0);
2207                                         msg_format(_("%^sが目を覚ました。", "%^s wakes up."), m_name);
2208                                 }
2209                         }
2210                 }
2211
2212                 note_spot(y, x);
2213                 lite_spot(y, x);
2214                 update_local_illumination(y, x);
2215         }
2216
2217         /* None left */
2218         tmp_pos.n = 0;
2219 }
2220
2221
2222
2223 /*!
2224  * @brief 部屋全体を暗くするサブルーチン
2225  * @return なし
2226  * @details
2227  * <pre>
2228  * This routine clears the entire "temp" set.
2229  * This routine will "darken" all "temp" grids.
2230  * In addition, some of these grids will be "unmarked".
2231  * This routine is used (only) by "unlite_room()"
2232  * Also, process all affected monsters
2233  * </pre>
2234  */
2235 static void cave_temp_room_unlite(void)
2236 {
2237         int i;
2238
2239         /* Clear them all */
2240         for (i = 0; i < tmp_pos.n; i++)
2241         {
2242                 POSITION y = tmp_pos.y[i];
2243                 POSITION x = tmp_pos.x[i];
2244                 int j;
2245
2246                 grid_type *g_ptr = &current_floor_ptr->grid_array[y][x];
2247                 bool do_dark = !is_mirror_grid(g_ptr);
2248
2249                 /* No longer in the array */
2250                 g_ptr->info &= ~(CAVE_TEMP);
2251
2252                 /* Darken the grid */
2253                 if (do_dark)
2254                 {
2255                         if (current_floor_ptr->dun_level || !is_daytime())
2256                         {
2257                                 for (j = 0; j < 9; j++)
2258                                 {
2259                                         POSITION by = y + ddy_ddd[j];
2260                                         POSITION bx = x + ddx_ddd[j];
2261
2262                                         if (in_bounds2(by, bx))
2263                                         {
2264                                                 grid_type *cc_ptr = &current_floor_ptr->grid_array[by][bx];
2265
2266                                                 if (have_flag(f_info[get_feat_mimic(cc_ptr)].flags, FF_GLOW))
2267                                                 {
2268                                                         do_dark = FALSE;
2269                                                         break;
2270                                                 }
2271                                         }
2272                                 }
2273
2274                                 if (!do_dark) continue;
2275                         }
2276
2277                         g_ptr->info &= ~(CAVE_GLOW);
2278
2279                         /* Hack -- Forget "boring" grids */
2280                         if (!have_flag(f_info[get_feat_mimic(g_ptr)].flags, FF_REMEMBER))
2281                         {
2282                                 /* Forget the grid */
2283                                 if (!view_torch_grids) g_ptr->info &= ~(CAVE_MARK);
2284                                 note_spot(y, x);
2285                         }
2286
2287                         /* Process affected monsters */
2288                         if (g_ptr->m_idx)
2289                         {
2290                                 update_monster(g_ptr->m_idx, FALSE);
2291                         }
2292
2293                         lite_spot(y, x);
2294                         update_local_illumination(y, x);
2295                 }
2296         }
2297
2298         /* None left */
2299         tmp_pos.n = 0;
2300 }
2301
2302
2303 /*!
2304  * @brief 周辺に関数ポインタの条件に該当する地形がいくつあるかを計算する / Determine how much contiguous open space this grid is next to
2305  * @param cy Y座標
2306  * @param cx X座標
2307  * @param pass_bold 地形条件を返す関数ポインタ
2308  * @return 該当地形の数
2309  */
2310 static int next_to_open(POSITION cy, POSITION cx, bool (*pass_bold)(POSITION, POSITION))
2311 {
2312         int i;
2313         POSITION y, x;
2314         int len = 0;
2315         int blen = 0;
2316
2317         for (i = 0; i < 16; i++)
2318         {
2319                 y = cy + ddy_cdd[i % 8];
2320                 x = cx + ddx_cdd[i % 8];
2321
2322                 /* Found a wall, break the length */
2323                 if (!pass_bold(y, x))
2324                 {
2325                         /* Track best length */
2326                         if (len > blen)
2327                         {
2328                                 blen = len;
2329                         }
2330
2331                         len = 0;
2332                 }
2333                 else
2334                 {
2335                         len++;
2336                 }
2337         }
2338
2339         return (MAX(len, blen));
2340 }
2341
2342 /*!
2343  * @brief 周辺に関数ポインタの条件に該当する地形がいくつあるかを計算する / Determine how much contiguous open space this grid is next to
2344  * @param cy Y座標
2345  * @param cx X座標
2346  * @param pass_bold 地形条件を返す関数ポインタ
2347  * @return 該当地形の数
2348  */
2349 static int next_to_walls_adj(POSITION cy, POSITION cx, bool (*pass_bold)(POSITION, POSITION))
2350 {
2351         DIRECTION i;
2352         POSITION y, x;
2353         int c = 0;
2354
2355         for (i = 0; i < 8; i++)
2356         {
2357                 y = cy + ddy_ddd[i];
2358                 x = cx + ddx_ddd[i];
2359
2360                 if (!pass_bold(y, x)) c++;
2361         }
2362
2363         return c;
2364 }
2365
2366
2367 /*!
2368  * @brief 部屋内にある一点の周囲に該当する地形数かいくつあるかをグローバル変数tmp_pos.nに返す / Aux function -- see below
2369  * @param y 部屋内のy座標1点
2370  * @param x 部屋内のx座標1点
2371  * @param only_room 部屋内地形のみをチェック対象にするならば TRUE
2372  * @param pass_bold 地形条件を返す関数ポインタ
2373  * @return 該当地形の数
2374  */
2375 static void cave_temp_room_aux(POSITION y, POSITION x, bool only_room, bool (*pass_bold)(POSITION, POSITION))
2376 {
2377         grid_type *g_ptr;
2378         g_ptr = &current_floor_ptr->grid_array[y][x];
2379
2380         /* Avoid infinite recursion */
2381         if (g_ptr->info & (CAVE_TEMP)) return;
2382
2383         /* Do not "leave" the current room */
2384         if (!(g_ptr->info & (CAVE_ROOM)))
2385         {
2386                 if (only_room) return;
2387
2388                 /* Verify */
2389                 if (!in_bounds2(y, x)) return;
2390
2391                 /* Do not exceed the maximum spell range */
2392                 if (distance(p_ptr->y, p_ptr->x, y, x) > MAX_RANGE) return;
2393
2394                 /* Verify this grid */
2395                 /*
2396                  * The reason why it is ==6 instead of >5 is that 8 is impossible
2397                  * due to the check for cave_bold above.
2398                  * 7 lights dead-end corridors (you need to do this for the
2399                  * checkboard interesting rooms, so that the boundary is lit
2400                  * properly.
2401                  * This leaves only a check for 6 bounding walls!
2402                  */
2403                 if (in_bounds(y, x) && pass_bold(y, x) &&
2404                     (next_to_walls_adj(y, x, pass_bold) == 6) && (next_to_open(y, x, pass_bold) <= 1)) return;
2405         }
2406
2407         /* Paranoia -- verify space */
2408         if (tmp_pos.n == TEMP_MAX) return;
2409
2410         /* Mark the grid as "seen" */
2411         g_ptr->info |= (CAVE_TEMP);
2412
2413         /* Add it to the "seen" set */
2414         tmp_pos.y[tmp_pos.n] = y;
2415         tmp_pos.x[tmp_pos.n] = x;
2416         tmp_pos.n++;
2417 }
2418
2419 /*!
2420  * @brief 指定のマスが光を通すか(LOSフラグを持つか)を返す。 / Aux function -- see below
2421  * @param y 指定Y座標
2422  * @param x 指定X座標
2423  * @return 光を通すならばtrueを返す。
2424  */
2425 static bool cave_pass_lite_bold(POSITION y, POSITION x)
2426 {
2427         return cave_los_bold(y, x);
2428 }
2429
2430 /*!
2431  * @brief 部屋内にある一点の周囲がいくつ光を通すかをグローバル変数tmp_pos.nに返す / Aux function -- see below
2432  * @param y 指定Y座標
2433  * @param x 指定X座標
2434  * @return なし
2435  */
2436 static void cave_temp_lite_room_aux(POSITION y, POSITION x)
2437 {
2438         cave_temp_room_aux(y, x, FALSE, cave_pass_lite_bold);
2439 }
2440
2441 /*!
2442  * @brief 指定のマスが光を通さず射線のみを通すかを返す。 / Aux function -- see below
2443  * @param y 指定Y座標
2444  * @param x 指定X座標
2445  * @return 射線を通すならばtrueを返す。
2446  */
2447 static bool cave_pass_dark_bold(POSITION y, POSITION x)
2448 {
2449         return cave_have_flag_bold(y, x, FF_PROJECT);
2450 }
2451
2452
2453 /*!
2454  * @brief 部屋内にある一点の周囲がいくつ射線を通すかをグローバル変数tmp_pos.nに返す / Aux function -- see below
2455  * @param y 指定Y座標
2456  * @param x 指定X座標
2457  * @return なし
2458  */
2459 static void cave_temp_unlite_room_aux(POSITION y, POSITION x)
2460 {
2461         cave_temp_room_aux(y, x, TRUE, cave_pass_dark_bold);
2462 }
2463
2464
2465 /*!
2466  * @brief 指定された部屋内を照らす / Illuminate any room containing the given location.
2467  * @param y1 指定Y座標
2468  * @param x1 指定X座標
2469  * @return なし
2470  */
2471 void lite_room(POSITION y1, POSITION x1)
2472 {
2473         int i;
2474         POSITION x, y;
2475
2476         /* Add the initial grid */
2477         cave_temp_lite_room_aux(y1, x1);
2478
2479         /* While grids are in the queue, add their neighbors */
2480         for (i = 0; i < tmp_pos.n; i++)
2481         {
2482                 x = tmp_pos.x[i], y = tmp_pos.y[i];
2483
2484                 /* Walls get lit, but stop light */
2485                 if (!cave_pass_lite_bold(y, x)) continue;
2486
2487                 /* Spread adjacent */
2488                 cave_temp_lite_room_aux(y + 1, x);
2489                 cave_temp_lite_room_aux(y - 1, x);
2490                 cave_temp_lite_room_aux(y, x + 1);
2491                 cave_temp_lite_room_aux(y, x - 1);
2492
2493                 /* Spread diagonal */
2494                 cave_temp_lite_room_aux(y + 1, x + 1);
2495                 cave_temp_lite_room_aux(y - 1, x - 1);
2496                 cave_temp_lite_room_aux(y - 1, x + 1);
2497                 cave_temp_lite_room_aux(y + 1, x - 1);
2498         }
2499
2500         /* Now, lite them all up at once */
2501         cave_temp_room_lite();
2502
2503         if (p_ptr->special_defense & NINJA_S_STEALTH)
2504         {
2505                 if (current_floor_ptr->grid_array[p_ptr->y][p_ptr->x].info & CAVE_GLOW) set_superstealth(FALSE);
2506         }
2507 }
2508
2509
2510 /*!
2511  * @brief 指定された部屋内を暗くする / Darken all rooms containing the given location
2512  * @param y1 指定Y座標
2513  * @param x1 指定X座標
2514  * @return なし
2515  */
2516 void unlite_room(POSITION y1, POSITION x1)
2517 {
2518         int i;
2519         POSITION x, y;
2520
2521         /* Add the initial grid */
2522         cave_temp_unlite_room_aux(y1, x1);
2523
2524         /* Spread, breadth first */
2525         for (i = 0; i < tmp_pos.n; i++)
2526         {
2527                 x = tmp_pos.x[i], y = tmp_pos.y[i];
2528
2529                 /* Walls get dark, but stop darkness */
2530                 if (!cave_pass_dark_bold(y, x)) continue;
2531
2532                 /* Spread adjacent */
2533                 cave_temp_unlite_room_aux(y + 1, x);
2534                 cave_temp_unlite_room_aux(y - 1, x);
2535                 cave_temp_unlite_room_aux(y, x + 1);
2536                 cave_temp_unlite_room_aux(y, x - 1);
2537
2538                 /* Spread diagonal */
2539                 cave_temp_unlite_room_aux(y + 1, x + 1);
2540                 cave_temp_unlite_room_aux(y - 1, x - 1);
2541                 cave_temp_unlite_room_aux(y - 1, x + 1);
2542                 cave_temp_unlite_room_aux(y + 1, x - 1);
2543         }
2544
2545         /* Now, darken them all at once */
2546         cave_temp_room_unlite();
2547 }
2548
2549 bool starlight(bool magic)
2550 {
2551         HIT_POINT num = damroll(5, 3);
2552         POSITION y = 0, x = 0;
2553         int k;
2554         int attempts;
2555
2556         if (!p_ptr->blind && !magic)
2557         {
2558                 msg_print(_("杖の先が明るく輝いた...", "The end of the staff glows brightly..."));
2559         }
2560         for (k = 0; k < num; k++)
2561         {
2562                 attempts = 1000;
2563
2564                 while (attempts--)
2565                 {
2566                         scatter(&y, &x, p_ptr->y, p_ptr->x, 4, PROJECT_LOS);
2567                         if (!cave_have_flag_bold(y, x, FF_PROJECT)) continue;
2568                         if (!player_bold(y, x)) break;
2569                 }
2570
2571                 project(0, 0, y, x, damroll(6 + p_ptr->lev / 8, 10), GF_LITE_WEAK,
2572                         (PROJECT_BEAM | PROJECT_THRU | PROJECT_GRID | PROJECT_KILL | PROJECT_LOS), -1);
2573         }
2574         return TRUE;
2575 }
2576
2577
2578
2579 /*!
2580  * @brief プレイヤー位置を中心にLITE_WEAK属性を通じた照明処理を行う / Hack -- call light around the player Affect all monsters in the projection radius
2581  * @param dam 威力
2582  * @param rad 効果半径
2583  * @return 作用が実際にあった場合TRUEを返す
2584  */
2585 bool lite_area(HIT_POINT dam, POSITION rad)
2586 {
2587         BIT_FLAGS flg = PROJECT_GRID | PROJECT_KILL;
2588
2589         if (d_info[p_ptr->dungeon_idx].flags1 & DF1_DARKNESS)
2590         {
2591                 msg_print(_("ダンジョンが光を吸収した。", "The darkness of this dungeon absorb your light."));
2592                 return FALSE;
2593         }
2594
2595         if (!p_ptr->blind)
2596         {
2597                 msg_print(_("白い光が辺りを覆った。", "You are surrounded by a white light."));
2598         }
2599
2600         /* Hook into the "project()" function */
2601         (void)project(0, rad, p_ptr->y, p_ptr->x, dam, GF_LITE_WEAK, flg, -1);
2602
2603         lite_room(p_ptr->y, p_ptr->x);
2604
2605         /* Assume seen */
2606         return (TRUE);
2607 }
2608
2609
2610 /*!
2611  * @brief プレイヤー位置を中心にLITE_DARK属性を通じた消灯処理を行う / Hack -- call light around the player Affect all monsters in the projection radius
2612  * @param dam 威力
2613  * @param rad 効果半径
2614  * @return 作用が実際にあった場合TRUEを返す
2615  */
2616 bool unlite_area(HIT_POINT dam, POSITION rad)
2617 {
2618         BIT_FLAGS flg = PROJECT_GRID | PROJECT_KILL;
2619
2620         if (!p_ptr->blind)
2621         {
2622                 msg_print(_("暗闇が辺りを覆った。", "Darkness surrounds you."));
2623         }
2624
2625         /* Hook into the "project()" function */
2626         (void)project(0, rad, p_ptr->y, p_ptr->x, dam, GF_DARK_WEAK, flg, -1);
2627
2628         unlite_room(p_ptr->y, p_ptr->x);
2629
2630         /* Assume seen */
2631         return (TRUE);
2632 }
2633
2634
2635
2636 /*!
2637  * @brief ボール系スペルの発動 / Cast a ball spell
2638  * @param typ 効果属性
2639  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
2640  * @param dam 威力
2641  * @param rad 半径
2642  * @return 作用が実際にあった場合TRUEを返す
2643  * @details
2644  * <pre>
2645  * Stop if we hit a monster, act as a "ball"
2646  * Allow "target" mode to pass over monsters
2647  * Affect grids, objects, and monsters
2648  * </pre>
2649  */
2650 bool fire_ball(EFFECT_ID typ, DIRECTION dir, HIT_POINT dam, POSITION rad)
2651 {
2652         POSITION tx, ty;
2653
2654         BIT_FLAGS flg = PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL;
2655
2656         if (typ == GF_CHARM_LIVING) flg|= PROJECT_HIDE;
2657         /* Use the given direction */
2658         tx = p_ptr->x + 99 * ddx[dir];
2659         ty = p_ptr->y + 99 * ddy[dir];
2660
2661         /* Hack -- Use an actual "target" */
2662         if ((dir == 5) && target_okay())
2663         {
2664                 flg &= ~(PROJECT_STOP);
2665                 tx = target_col;
2666                 ty = target_row;
2667         }
2668
2669         /* Analyze the "dir" and the "target".  Hurt items on floor. */
2670         return (project(0, rad, ty, tx, dam, typ, flg, -1));
2671 }
2672
2673 /*!
2674 * @brief ブレス系スペルの発動 / Cast a breath spell
2675 * @param typ 効果属性
2676 * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
2677 * @param dam 威力
2678 * @param rad 半径
2679 * @return 作用が実際にあった場合TRUEを返す
2680 * @details
2681 * <pre>
2682 * Stop if we hit a monster, act as a "ball"
2683 * Allow "target" mode to pass over monsters
2684 * Affect grids, objects, and monsters
2685 * </pre>
2686 */
2687 bool fire_breath(EFFECT_ID typ, DIRECTION dir, HIT_POINT dam, POSITION rad)
2688 {
2689         return fire_ball(typ, dir, dam, -rad);
2690 }
2691
2692
2693 /*!
2694  * @brief ロケット系スペルの発動(詳細な差は確認中) / Cast a ball spell
2695  * @param typ 効果属性
2696  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
2697  * @param dam 威力
2698  * @param rad 半径
2699  * @return 作用が実際にあった場合TRUEを返す
2700  * @details
2701  * <pre>
2702  * Stop if we hit a monster, act as a "ball"
2703  * Allow "target" mode to pass over monsters
2704  * Affect grids, objects, and monsters
2705  * </pre>
2706  */
2707 bool fire_rocket(EFFECT_ID typ, DIRECTION dir, HIT_POINT dam, POSITION rad)
2708 {
2709         POSITION tx, ty;
2710         BIT_FLAGS flg = PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL;
2711
2712         /* Use the given direction */
2713         tx = p_ptr->x + 99 * ddx[dir];
2714         ty = p_ptr->y + 99 * ddy[dir];
2715
2716         /* Hack -- Use an actual "target" */
2717         if ((dir == 5) && target_okay())
2718         {
2719                 tx = target_col;
2720                 ty = target_row;
2721         }
2722
2723         /* Analyze the "dir" and the "target".  Hurt items on floor. */
2724         return (project(0, rad, ty, tx, dam, typ, flg, -1));
2725 }
2726
2727
2728 /*!
2729  * @brief ボール(ハイド)系スペルの発動 / Cast a ball spell
2730  * @param typ 効果属性
2731  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
2732  * @param dam 威力
2733  * @param rad 半径
2734  * @return 作用が実際にあった場合TRUEを返す
2735  * @details
2736  * <pre>
2737  * Stop if we hit a monster, act as a "ball"
2738  * Allow "target" mode to pass over monsters
2739  * Affect grids, objects, and monsters
2740  * </pre>
2741  */
2742 bool fire_ball_hide(EFFECT_ID typ, DIRECTION dir, HIT_POINT dam, POSITION rad)
2743 {
2744         POSITION tx, ty;
2745         BIT_FLAGS flg = PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL | PROJECT_HIDE;
2746
2747         /* Use the given direction */
2748         tx = p_ptr->x + 99 * ddx[dir];
2749         ty = p_ptr->y + 99 * ddy[dir];
2750
2751         /* Hack -- Use an actual "target" */
2752         if ((dir == 5) && target_okay())
2753         {
2754                 flg &= ~(PROJECT_STOP);
2755                 tx = target_col;
2756                 ty = target_row;
2757         }
2758
2759         /* Analyze the "dir" and the "target".  Hurt items on floor. */
2760         return (project(0, rad, ty, tx, dam, typ, flg, -1));
2761 }
2762
2763
2764 /*!
2765  * @brief メテオ系スペルの発動 / Cast a meteor spell
2766  * @param who スぺル詠唱者のモンスターID(0=プレイヤー)
2767  * @param typ 効果属性
2768  * @param dam 威力
2769  * @param rad 半径
2770  * @param y 中心点Y座標
2771  * @param x 中心点X座標
2772  * @return 作用が実際にあった場合TRUEを返す
2773  * @details
2774  * <pre>
2775  * Cast a meteor spell, defined as a ball spell cast by an arbitary monster, 
2776  * player, or outside source, that starts out at an arbitrary location, and 
2777  * leaving no trail from the "caster" to the target.  This function is 
2778  * especially useful for bombardments and similar. -LM-
2779  * Option to hurt the player.
2780  * </pre>
2781  */
2782 bool fire_meteor(MONSTER_IDX who, EFFECT_ID typ, POSITION y, POSITION x, HIT_POINT dam, POSITION rad)
2783 {
2784         BIT_FLAGS flg = PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL;
2785
2786         /* Analyze the "target" and the caster. */
2787         return (project(who, rad, y, x, dam, typ, flg, -1));
2788 }
2789
2790
2791 /*!
2792  * @brief ブラスト系スペルの発動 / Cast a blast spell
2793  * @param typ 効果属性
2794  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
2795  * @param dd 威力ダイス数
2796  * @param ds 威力ダイス目
2797  * @param num 基本回数
2798  * @param dev 回数分散
2799  * @return 作用が実際にあった場合TRUEを返す
2800  */
2801 bool fire_blast(EFFECT_ID typ, DIRECTION dir, DICE_NUMBER dd, DICE_SID ds, int num, int dev)
2802 {
2803         POSITION ly, lx;
2804         int ld;
2805         POSITION ty, tx, y, x;
2806         int i;
2807
2808         BIT_FLAGS flg = PROJECT_FAST | PROJECT_THRU | PROJECT_STOP | PROJECT_KILL | PROJECT_REFLECTABLE | PROJECT_GRID;
2809
2810         /* Assume okay */
2811         bool result = TRUE;
2812
2813         /* Use the given direction */
2814         if (dir != 5)
2815         {
2816                 ly = ty = p_ptr->y + 20 * ddy[dir];
2817                 lx = tx = p_ptr->x + 20 * ddx[dir];
2818         }
2819
2820         /* Use an actual "target" */
2821         else /* if (dir == 5) */
2822         {
2823                 tx = target_col;
2824                 ty = target_row;
2825
2826                 lx = 20 * (tx - p_ptr->x) + p_ptr->x;
2827                 ly = 20 * (ty - p_ptr->y) + p_ptr->y;
2828         }
2829
2830         ld = distance(p_ptr->y, p_ptr->x, ly, lx);
2831
2832         /* Blast */
2833         for (i = 0; i < num; i++)
2834         {
2835                 while (1)
2836                 {
2837                         /* Get targets for some bolts */
2838                         y = rand_spread(ly, ld * dev / 20);
2839                         x = rand_spread(lx, ld * dev / 20);
2840
2841                         if (distance(ly, lx, y, x) <= ld * dev / 20) break;
2842                 }
2843
2844                 /* Analyze the "dir" and the "target". */
2845                 if (!project(0, 0, y, x, damroll(dd, ds), typ, flg, -1))
2846                 {
2847                         result = FALSE;
2848                 }
2849         }
2850
2851         return (result);
2852 }
2853
2854
2855 /*!
2856  * @brief モンスターとの位置交換処理 / Switch position with a monster.
2857  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
2858  * @return 作用が実際にあった場合TRUEを返す
2859  */
2860 bool teleport_swap(DIRECTION dir)
2861 {
2862         POSITION tx, ty;
2863         grid_type* g_ptr;
2864         monster_type* m_ptr;
2865         monster_race* r_ptr;
2866
2867         if ((dir == 5) && target_okay())
2868         {
2869                 tx = target_col;
2870                 ty = target_row;
2871         }
2872         else
2873         {
2874                 tx = p_ptr->x + ddx[dir];
2875                 ty = p_ptr->y + ddy[dir];
2876         }
2877         g_ptr = &current_floor_ptr->grid_array[ty][tx];
2878
2879         if (p_ptr->anti_tele)
2880         {
2881                 msg_print(_("不思議な力がテレポートを防いだ!", "A mysterious force prevents you from teleporting!"));
2882                 return FALSE;
2883         }
2884
2885         if (!g_ptr->m_idx || (g_ptr->m_idx == p_ptr->riding))
2886         {
2887                 msg_print(_("それとは場所を交換できません。", "You can't trade places with that!"));
2888                 return FALSE;
2889         }
2890
2891         if ((g_ptr->info & CAVE_ICKY) || (distance(ty, tx, p_ptr->y, p_ptr->x) > p_ptr->lev * 3 / 2 + 10))
2892         {
2893                 msg_print(_("失敗した。", "Failed to swap."));
2894                 return FALSE;
2895         }
2896
2897         m_ptr = &current_floor_ptr->m_list[g_ptr->m_idx];
2898         r_ptr = &r_info[m_ptr->r_idx];
2899
2900         (void)set_monster_csleep(g_ptr->m_idx, 0);
2901
2902         if (r_ptr->flagsr & RFR_RES_TELE)
2903         {
2904                 msg_print(_("テレポートを邪魔された!", "Your teleportation is blocked!"));
2905                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= RFR_RES_TELE;
2906                 return FALSE;
2907         }
2908
2909         sound(SOUND_TELEPORT);
2910
2911         /* Swap the player and monster */
2912         (void)move_player_effect(ty, tx, MPE_FORGET_FLOW | MPE_HANDLE_STUFF | MPE_DONT_PICKUP);
2913
2914         /* Success */
2915         return TRUE;
2916 }
2917
2918
2919 /*!
2920  * @brief 指定方向に飛び道具を飛ばす(フラグ任意指定) / Hack -- apply a "project()" in a direction (or at the target)
2921  * @param typ 効果属性
2922  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
2923  * @param dam 威力
2924  * @param flg フラグ
2925  * @return 作用が実際にあった場合TRUEを返す
2926  */
2927 bool project_hook(EFFECT_ID typ, DIRECTION dir, HIT_POINT dam, BIT_FLAGS flg)
2928 {
2929         POSITION tx, ty;
2930
2931         /* Pass through the target if needed */
2932         flg |= (PROJECT_THRU);
2933
2934         /* Use the given direction */
2935         tx = p_ptr->x + ddx[dir];
2936         ty = p_ptr->y + ddy[dir];
2937
2938         /* Hack -- Use an actual "target" */
2939         if ((dir == 5) && target_okay())
2940         {
2941                 tx = target_col;
2942                 ty = target_row;
2943         }
2944
2945         /* Analyze the "dir" and the "target", do NOT explode */
2946         return (project(0, 0, ty, tx, dam, typ, flg, -1));
2947 }
2948
2949
2950 /*!
2951  * @brief ボルト系スペルの発動 / Cast a bolt spell.
2952  * @param typ 効果属性
2953  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
2954  * @param dam 威力
2955  * @return 作用が実際にあった場合TRUEを返す
2956  * @details
2957  * <pre>
2958  * Stop if we hit a monster, as a "bolt".
2959  * Affect monsters and grids (not objects).
2960  * </pre>
2961  */
2962 bool fire_bolt(EFFECT_ID typ, DIRECTION dir, HIT_POINT dam)
2963 {
2964         BIT_FLAGS flg = PROJECT_STOP | PROJECT_KILL | PROJECT_GRID;
2965         if (typ != GF_ARROW) flg |= PROJECT_REFLECTABLE;
2966         return (project_hook(typ, dir, dam, flg));
2967 }
2968
2969
2970 /*!
2971  * @brief ビーム系スペルの発動 / Cast a beam spell.
2972  * @param typ 効果属性
2973  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
2974  * @param dam 威力
2975  * @return 作用が実際にあった場合TRUEを返す
2976  * @details
2977  * <pre>
2978  * Pass through monsters, as a "beam".
2979  * Affect monsters, grids and objects.
2980  * </pre>
2981  */
2982 bool fire_beam(EFFECT_ID typ, DIRECTION dir, HIT_POINT dam)
2983 {
2984         BIT_FLAGS flg = PROJECT_BEAM | PROJECT_KILL | PROJECT_GRID | PROJECT_ITEM;
2985         return (project_hook(typ, dir, dam, flg));
2986 }
2987
2988
2989 /*!
2990  * @brief 確率に応じたボルト系/ビーム系スペルの発動 / Cast a bolt spell, or rarely, a beam spell.
2991  * @param prob ビーム化する確率(%)
2992  * @param typ 効果属性
2993  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
2994  * @param dam 威力
2995  * @return 作用が実際にあった場合TRUEを返す
2996  * @details
2997  * <pre>
2998  * Pass through monsters, as a "beam".
2999  * Affect monsters, grids and objects.
3000  * </pre>
3001  */
3002 bool fire_bolt_or_beam(PERCENTAGE prob, EFFECT_ID typ, DIRECTION dir, HIT_POINT dam)
3003 {
3004         if (randint0(100) < prob)
3005         {
3006                 return (fire_beam(typ, dir, dam));
3007         }
3008         else
3009         {
3010                 return (fire_bolt(typ, dir, dam));
3011         }
3012 }
3013
3014 /*!
3015  * @brief LITE_WEAK属性による光源ビーム処理
3016  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
3017  * @param dam 威力
3018  * @return 作用が実際にあった場合TRUEを返す
3019  */
3020 bool lite_line(DIRECTION dir, HIT_POINT dam)
3021 {
3022         BIT_FLAGS flg = PROJECT_BEAM | PROJECT_GRID | PROJECT_KILL;
3023         return (project_hook(GF_LITE_WEAK, dir, dam, flg));
3024 }
3025
3026 /*!
3027  * @brief 衰弱ボルト処理
3028  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
3029  * @param dam 威力
3030  * @return 作用が実際にあった場合TRUEを返す
3031  */
3032 bool hypodynamic_bolt(DIRECTION dir, HIT_POINT dam)
3033 {
3034         BIT_FLAGS flg = PROJECT_STOP | PROJECT_KILL | PROJECT_REFLECTABLE;
3035         return (project_hook(GF_HYPODYNAMIA, dir, dam, flg));
3036 }
3037
3038 /*!
3039  * @brief 岩石溶解処理
3040  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
3041  * @param dam 威力
3042  * @return 作用が実際にあった場合TRUEを返す
3043  */
3044 bool wall_to_mud(DIRECTION dir, HIT_POINT dam)
3045 {
3046         BIT_FLAGS flg = PROJECT_BEAM | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL;
3047         return (project_hook(GF_KILL_WALL, dir, dam, flg));
3048 }
3049
3050 /*!
3051  * @brief 魔法の施錠処理
3052  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
3053  * @return 作用が実際にあった場合TRUEを返す
3054  */
3055 bool wizard_lock(DIRECTION dir)
3056 {
3057         BIT_FLAGS flg = PROJECT_BEAM | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL;
3058         return (project_hook(GF_JAM_DOOR, dir, 20 + randint1(30), flg));
3059 }
3060
3061 /*!
3062  * @brief ドア破壊処理
3063  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
3064  * @return 作用が実際にあった場合TRUEを返す
3065  */
3066 bool destroy_door(DIRECTION dir)
3067 {
3068         BIT_FLAGS flg = PROJECT_BEAM | PROJECT_GRID | PROJECT_ITEM;
3069         return (project_hook(GF_KILL_DOOR, dir, 0, flg));
3070 }
3071
3072 /*!
3073  * @brief トラップ解除処理
3074  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
3075  * @return 作用が実際にあった場合TRUEを返す
3076  */
3077 bool disarm_trap(DIRECTION dir)
3078 {
3079         BIT_FLAGS flg = PROJECT_BEAM | PROJECT_GRID | PROJECT_ITEM;
3080         return (project_hook(GF_KILL_TRAP, dir, 0, flg));
3081 }
3082
3083
3084 /*!
3085  * @brief 死の光線処理
3086  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
3087  * @param plev プレイヤーレベル(効力はplev*200)
3088  * @return 作用が実際にあった場合TRUEを返す
3089  */
3090 bool death_ray(DIRECTION dir, PLAYER_LEVEL plev)
3091 {
3092         BIT_FLAGS flg = PROJECT_STOP | PROJECT_KILL | PROJECT_REFLECTABLE;
3093         return (project_hook(GF_DEATH_RAY, dir, plev * 200, flg));
3094 }
3095
3096 /*!
3097  * @brief モンスター用テレポート処理
3098  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
3099  * @param distance 移動距離
3100  * @return 作用が実際にあった場合TRUEを返す
3101  */
3102 bool teleport_monster(DIRECTION dir, int distance)
3103 {
3104         BIT_FLAGS flg = PROJECT_BEAM | PROJECT_KILL;
3105         return (project_hook(GF_AWAY_ALL, dir, distance, flg));
3106 }
3107
3108 /*!
3109  * @brief ドア生成処理(プレイヤー中心に周囲1マス) / Hooks -- affect adjacent grids (radius 1 ball attack)
3110  * @return 作用が実際にあった場合TRUEを返す
3111  */
3112 bool door_creation(void)
3113 {
3114         BIT_FLAGS flg = PROJECT_GRID | PROJECT_ITEM | PROJECT_HIDE;
3115         return (project(0, 1, p_ptr->y, p_ptr->x, 0, GF_MAKE_DOOR, flg, -1));
3116 }
3117
3118 /*!
3119  * @brief トラップ生成処理(起点から周囲1マス)
3120  * @param y 起点Y座標
3121  * @param x 起点X座標
3122  * @return 作用が実際にあった場合TRUEを返す
3123  */
3124 bool trap_creation(POSITION y, POSITION x)
3125 {
3126         BIT_FLAGS flg = PROJECT_GRID | PROJECT_ITEM | PROJECT_HIDE;
3127         return (project(0, 1, y, x, 0, GF_MAKE_TRAP, flg, -1));
3128 }
3129
3130 /*!
3131  * @brief 森林生成処理(プレイヤー中心に周囲1マス)
3132  * @return 作用が実際にあった場合TRUEを返す
3133  */
3134 bool tree_creation(void)
3135 {
3136         BIT_FLAGS flg = PROJECT_GRID | PROJECT_ITEM | PROJECT_HIDE;
3137         return (project(0, 1, p_ptr->y, p_ptr->x, 0, GF_MAKE_TREE, flg, -1));
3138 }
3139
3140 /*!
3141  * @brief 魔法のルーン生成処理(プレイヤー中心に周囲1マス)
3142  * @return 作用が実際にあった場合TRUEを返す
3143  */
3144 bool glyph_creation(void)
3145 {
3146         BIT_FLAGS flg = PROJECT_GRID | PROJECT_ITEM;
3147         return (project(0, 1, p_ptr->y, p_ptr->x, 0, GF_MAKE_GLYPH, flg, -1));
3148 }
3149
3150 /*!
3151  * @brief 壁生成処理(プレイヤー中心に周囲1マス)
3152  * @return 作用が実際にあった場合TRUEを返す
3153  */
3154 bool wall_stone(void)
3155 {
3156         BIT_FLAGS flg = PROJECT_GRID | PROJECT_ITEM | PROJECT_HIDE;
3157         bool dummy = (project(0, 1, p_ptr->y, p_ptr->x, 0, GF_STONE_WALL, flg, -1));
3158         p_ptr->update |= (PU_FLOW);
3159         p_ptr->redraw |= (PR_MAP);
3160         return dummy;
3161 }
3162
3163 /*!
3164  * @brief ドア破壊処理(プレイヤー中心に周囲1マス)
3165  * @return 作用が実際にあった場合TRUEを返す
3166  */
3167 bool destroy_doors_touch(void)
3168 {
3169         BIT_FLAGS flg = PROJECT_GRID | PROJECT_ITEM | PROJECT_HIDE;
3170         return (project(0, 1, p_ptr->y, p_ptr->x, 0, GF_KILL_DOOR, flg, -1));
3171 }
3172
3173 /*!
3174  * @brief トラップ解除処理(プレイヤー中心に周囲1マス)
3175  * @return 作用が実際にあった場合TRUEを返す
3176  */
3177 bool disarm_traps_touch(void)
3178 {
3179         BIT_FLAGS flg = PROJECT_GRID | PROJECT_ITEM | PROJECT_HIDE;
3180         return (project(0, 1, p_ptr->y, p_ptr->x, 0, GF_KILL_TRAP, flg, -1));
3181 }
3182
3183 /*!
3184  * @brief スリープモンスター処理(プレイヤー中心に周囲1マス)
3185  * @return 作用が実際にあった場合TRUEを返す
3186  */
3187 bool sleep_monsters_touch(void)
3188 {
3189         BIT_FLAGS flg = PROJECT_KILL | PROJECT_HIDE;
3190         return (project(0, 1, p_ptr->y, p_ptr->x, p_ptr->lev, GF_OLD_SLEEP, flg, -1));
3191 }
3192
3193
3194 /*!
3195  * @brief 死者復活処理(起点より周囲5マス)
3196  * @param who 術者モンスターID(0ならばプレイヤー)
3197  * @param y 起点Y座標
3198  * @param x 起点X座標
3199  * @return 作用が実際にあった場合TRUEを返す
3200  */
3201 bool animate_dead(MONSTER_IDX who, POSITION y, POSITION x)
3202 {
3203         BIT_FLAGS flg = PROJECT_ITEM | PROJECT_HIDE;
3204         return (project(who, 5, y, x, 0, GF_ANIM_DEAD, flg, -1));
3205 }
3206
3207 /*!
3208  * @brief 混沌招来処理
3209  * @return 作用が実際にあった場合TRUEを返す
3210  */
3211 void call_chaos(void)
3212 {
3213         int Chaos_type, dummy, dir;
3214         PLAYER_LEVEL plev = p_ptr->lev;
3215         bool line_chaos = FALSE;
3216
3217         int hurt_types[31] =
3218         {
3219                 GF_ELEC,      GF_POIS,    GF_ACID,    GF_COLD,
3220                 GF_FIRE,      GF_MISSILE, GF_ARROW,   GF_PLASMA,
3221                 GF_HOLY_FIRE, GF_WATER,   GF_LITE,    GF_DARK,
3222                 GF_FORCE,     GF_INERTIAL, GF_MANA,    GF_METEOR,
3223                 GF_ICE,       GF_CHAOS,   GF_NETHER,  GF_DISENCHANT,
3224                 GF_SHARDS,    GF_SOUND,   GF_NEXUS,   GF_CONFUSION,
3225                 GF_TIME,      GF_GRAVITY, GF_ROCKET,  GF_NUKE,
3226                 GF_HELL_FIRE, GF_DISINTEGRATE, GF_PSY_SPEAR
3227         };
3228
3229         Chaos_type = hurt_types[randint0(31)];
3230         if (one_in_(4)) line_chaos = TRUE;
3231
3232         if (one_in_(6))
3233         {
3234                 for (dummy = 1; dummy < 10; dummy++)
3235                 {
3236                         if (dummy - 5)
3237                         {
3238                                 if (line_chaos)
3239                                         fire_beam(Chaos_type, dummy, 150);
3240                                 else
3241                                         fire_ball(Chaos_type, dummy, 150, 2);
3242                         }
3243                 }
3244         }
3245         else if (one_in_(3))
3246         {
3247                 fire_ball(Chaos_type, 0, 500, 8);
3248         }
3249         else
3250         {
3251                 if (!get_aim_dir(&dir)) return;
3252                 if (line_chaos)
3253                         fire_beam(Chaos_type, dir, 250);
3254                 else
3255                         fire_ball(Chaos_type, dir, 250, 3 + (plev / 35));
3256         }
3257 }
3258
3259 /*!
3260  * @brief TY_CURSE処理発動 / Activate the evil Topi Ylinen curse
3261  * @param stop_ty 再帰処理停止フラグ
3262  * @param count 発動回数
3263  * @return 作用が実際にあった場合TRUEを返す
3264  * @details
3265  * <pre>
3266  * rr9: Stop the nasty things when a Cyberdemon is summoned
3267  * or the player gets paralyzed.
3268  * </pre>
3269  */
3270 bool activate_ty_curse(bool stop_ty, int *count)
3271 {
3272         int i = 0;
3273         BIT_FLAGS flg = (PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL | PROJECT_JUMP);
3274
3275         do
3276         {
3277                 switch (randint1(34))
3278                 {
3279                 case 28: case 29:
3280                         if (!(*count))
3281                         {
3282                                 msg_print(_("地面が揺れた...", "The ground trembles..."));
3283                                 earthquake(p_ptr->y, p_ptr->x, 5 + randint0(10));
3284                                 if (!one_in_(6)) break;
3285                         }
3286                 case 30: case 31:
3287                         if (!(*count))
3288                         {
3289                                 HIT_POINT dam = damroll(10, 10);
3290                                 msg_print(_("純粋な魔力の次元への扉が開いた!", "A portal opens to a plane of raw mana!"));
3291                                 project(0, 8, p_ptr->y, p_ptr->x, dam, GF_MANA, flg, -1);
3292                                 take_hit(DAMAGE_NOESCAPE, dam, _("純粋な魔力の解放", "released pure mana"), -1);
3293                                 if (!one_in_(6)) break;
3294                         }
3295                 case 32: case 33:
3296                         if (!(*count))
3297                         {
3298                                 msg_print(_("周囲の空間が歪んだ!", "Space warps about you!"));
3299                                 teleport_player(damroll(10, 10), TELEPORT_PASSIVE);
3300                                 if (randint0(13)) (*count) += activate_hi_summon(p_ptr->y, p_ptr->x, FALSE);
3301                                 if (!one_in_(6)) break;
3302                         }
3303                 case 34:
3304                         msg_print(_("エネルギーのうねりを感じた!", "You feel a surge of energy!"));
3305                         wall_breaker();
3306                         if (!randint0(7))
3307                         {
3308                                 project(0, 7, p_ptr->y, p_ptr->x, 50, GF_KILL_WALL, flg, -1);
3309                                 take_hit(DAMAGE_NOESCAPE, 50, _("エネルギーのうねり", "surge of energy"), -1);
3310                         }
3311                         if (!one_in_(6)) break;
3312                 case 1: case 2: case 3: case 16: case 17:
3313                         aggravate_monsters(0);
3314                         if (!one_in_(6)) break;
3315                 case 4: case 5: case 6:
3316                         (*count) += activate_hi_summon(p_ptr->y, p_ptr->x, FALSE);
3317                         if (!one_in_(6)) break;
3318                 case 7: case 8: case 9: case 18:
3319                         (*count) += summon_specific(0, p_ptr->y, p_ptr->x, current_floor_ptr->dun_level, 0, (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE | PM_NO_PET), '\0');
3320                         if (!one_in_(6)) break;
3321                 case 10: case 11: case 12:
3322                         msg_print(_("経験値が体から吸い取られた気がする!", "You feel your experience draining away..."));
3323                         lose_exp(p_ptr->exp / 16);
3324                         if (!one_in_(6)) break;
3325                 case 13: case 14: case 15: case 19: case 20:
3326                         if (stop_ty || (p_ptr->free_act && (randint1(125) < p_ptr->skill_sav)) || (p_ptr->pclass == CLASS_BERSERKER))
3327                         {
3328                                 /* Do nothing */ ;
3329                         }
3330                         else
3331                         {
3332                                 msg_print(_("彫像になった気分だ!", "You feel like a statue!"));
3333                                 if (p_ptr->free_act)
3334                                         set_paralyzed(p_ptr->paralyzed + randint1(3));
3335                                 else
3336                                         set_paralyzed(p_ptr->paralyzed + randint1(13));
3337                                 stop_ty = TRUE;
3338                         }
3339                         if (!one_in_(6)) break;
3340                 case 21: case 22: case 23:
3341                         (void)do_dec_stat(randint0(6));
3342                         if (!one_in_(6)) break;
3343                 case 24:
3344                         msg_print(_("ほえ?私は誰?ここで何してる?", "Huh? Who am I? What am I doing here?"));
3345                         lose_all_info();
3346                         if (!one_in_(6)) break;
3347                 case 25:
3348                         /*
3349                          * Only summon Cyberdemons deep in the dungeon.
3350                          */
3351                         if ((current_floor_ptr->dun_level > 65) && !stop_ty)
3352                         {
3353                                 (*count) += summon_cyber(-1, p_ptr->y, p_ptr->x);
3354                                 stop_ty = TRUE;
3355                                 break;
3356                         }
3357                         if (!one_in_(6)) break;
3358                 default:
3359                         while (i < A_MAX)
3360                         {
3361                                 do
3362                                 {
3363                                         (void)do_dec_stat(i);
3364                                 }
3365                                 while (one_in_(2));
3366
3367                                 i++;
3368                         }
3369                 }
3370         }
3371         while (one_in_(3) && !stop_ty);
3372
3373         return stop_ty;
3374 }
3375
3376 /*!
3377  * @brief HI_SUMMON(上級召喚)処理発動
3378  * @param y 召喚位置Y座標
3379  * @param x 召喚位置X座標
3380  * @param can_pet プレイヤーのペットとなる可能性があるならばTRUEにする
3381  * @return 作用が実際にあった場合TRUEを返す
3382  */
3383 int activate_hi_summon(POSITION y, POSITION x, bool can_pet)
3384 {
3385         int i;
3386         int count = 0;
3387         DEPTH summon_lev;
3388         BIT_FLAGS mode = PM_ALLOW_GROUP;
3389         bool pet = FALSE;
3390
3391         if (can_pet)
3392         {
3393                 if (one_in_(4))
3394                 {
3395                         mode |= PM_FORCE_FRIENDLY;
3396                 }
3397                 else
3398                 {
3399                         mode |= PM_FORCE_PET;
3400                         pet = TRUE;
3401                 }
3402         }
3403
3404         if (!pet) mode |= PM_NO_PET;
3405
3406         summon_lev = (pet ? p_ptr->lev * 2 / 3 + randint1(p_ptr->lev / 2) : current_floor_ptr->dun_level);
3407
3408         for (i = 0; i < (randint1(7) + (current_floor_ptr->dun_level / 40)); i++)
3409         {
3410                 switch (randint1(25) + (current_floor_ptr->dun_level / 20))
3411                 {
3412                         case 1: case 2:
3413                                 count += summon_specific((pet ? -1 : 0), y, x, summon_lev, SUMMON_ANT, mode, '\0');
3414                                 break;
3415                         case 3: case 4:
3416                                 count += summon_specific((pet ? -1 : 0), y, x, summon_lev, SUMMON_SPIDER, mode, '\0');
3417                                 break;
3418                         case 5: case 6:
3419                                 count += summon_specific((pet ? -1 : 0), y, x, summon_lev, SUMMON_HOUND, mode, '\0');
3420                                 break;
3421                         case 7: case 8:
3422                                 count += summon_specific((pet ? -1 : 0), y, x, summon_lev, SUMMON_HYDRA, mode, '\0');
3423                                 break;
3424                         case 9: case 10:
3425                                 count += summon_specific((pet ? -1 : 0), y, x, summon_lev, SUMMON_ANGEL, mode, '\0');
3426                                 break;
3427                         case 11: case 12:
3428                                 count += summon_specific((pet ? -1 : 0), y, x, summon_lev, SUMMON_UNDEAD, mode, '\0');
3429                                 break;
3430                         case 13: case 14:
3431                                 count += summon_specific((pet ? -1 : 0), y, x, summon_lev, SUMMON_DRAGON, mode, '\0');
3432                                 break;
3433                         case 15: case 16:
3434                                 count += summon_specific((pet ? -1 : 0), y, x, summon_lev, SUMMON_DEMON, mode, '\0');
3435                                 break;
3436                         case 17:
3437                                 if (can_pet) break;
3438                                 count += summon_specific((pet ? -1 : 0), y, x, summon_lev, SUMMON_AMBERITES, (mode | PM_ALLOW_UNIQUE), '\0');
3439                                 break;
3440                         case 18: case 19:
3441                                 if (can_pet) break;
3442                                 count += summon_specific((pet ? -1 : 0), y, x, summon_lev, SUMMON_UNIQUE, (mode | PM_ALLOW_UNIQUE), '\0');
3443                                 break;
3444                         case 20: case 21:
3445                                 if (!can_pet) mode |= PM_ALLOW_UNIQUE;
3446                                 count += summon_specific((pet ? -1 : 0), y, x, summon_lev, SUMMON_HI_UNDEAD, mode, '\0');
3447                                 break;
3448                         case 22: case 23:
3449                                 if (!can_pet) mode |= PM_ALLOW_UNIQUE;
3450                                 count += summon_specific((pet ? -1 : 0), y, x, summon_lev, SUMMON_HI_DRAGON, mode, '\0');
3451                                 break;
3452                         case 24:
3453                                 count += summon_specific((pet ? -1 : 0), y, x, 100, SUMMON_CYBER, mode, '\0');
3454                                 break;
3455                         default:
3456                                 if (!can_pet) mode |= PM_ALLOW_UNIQUE;
3457                                 count += summon_specific((pet ? -1 : 0), y, x,pet ? summon_lev : (((summon_lev * 3) / 2) + 5), 0, mode, '\0');
3458                 }
3459         }
3460
3461         return count;
3462 }
3463
3464 /*!
3465  * @brief 周辺破壊効果(プレイヤー中心)
3466  * @return 作用が実際にあった場合TRUEを返す
3467  */
3468 void wall_breaker(void)
3469 {
3470         int i;
3471         POSITION y = 0, x = 0;
3472         int attempts = 1000;
3473
3474         if (randint1(80 + p_ptr->lev) < 70)
3475         {
3476                 while (attempts--)
3477                 {
3478                         scatter(&y, &x, p_ptr->y, p_ptr->x, 4, 0);
3479
3480                         if (!cave_have_flag_bold(y, x, FF_PROJECT)) continue;
3481
3482                         if (!player_bold(y, x)) break;
3483                 }
3484
3485                 project(0, 0, y, x, 20 + randint1(30), GF_KILL_WALL,
3486                                   (PROJECT_BEAM | PROJECT_THRU | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL), -1);
3487         }
3488         else if (randint1(100) > 30)
3489         {
3490                 earthquake(p_ptr->y, p_ptr->x, 1);
3491         }
3492         else
3493         {
3494                 int num = damroll(5, 3);
3495
3496                 for (i = 0; i < num; i++)
3497                 {
3498                         while (1)
3499                         {
3500                                 scatter(&y, &x, p_ptr->y, p_ptr->x, 10, 0);
3501
3502                                 if (!player_bold(y, x)) break;
3503                         }
3504
3505                         project(0, 0, y, x, 20 + randint1(30), GF_KILL_WALL,
3506                                           (PROJECT_BEAM | PROJECT_THRU | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL), -1);
3507                 }
3508         }
3509 }
3510
3511
3512 /*!
3513  * @brief パニック・モンスター効果(プレイヤー視界範囲内) / Confuse monsters
3514  * @param dam 効力
3515  * @return 作用が実際にあった場合TRUEを返す
3516  */
3517 bool confuse_monsters(HIT_POINT dam)
3518 {
3519         return (project_all_los(GF_OLD_CONF, dam));
3520 }
3521
3522
3523 /*!
3524  * @brief チャーム・モンスター効果(プレイヤー視界範囲内) / Charm monsters
3525  * @param dam 効力
3526  * @return 作用が実際にあった場合TRUEを返す
3527  */
3528 bool charm_monsters(HIT_POINT dam)
3529 {
3530         return (project_all_los(GF_CHARM, dam));
3531 }
3532
3533
3534 /*!
3535  * @brief 動物魅了効果(プレイヤー視界範囲内) / Charm Animals
3536  * @param dam 効力
3537  * @return 作用が実際にあった場合TRUEを返す
3538  */
3539 bool charm_animals(HIT_POINT dam)
3540 {
3541         return (project_all_los(GF_CONTROL_ANIMAL, dam));
3542 }
3543
3544
3545 /*!
3546  * @brief モンスター朦朧効果(プレイヤー視界範囲内) / Stun monsters
3547  * @param dam 効力
3548  * @return 作用が実際にあった場合TRUEを返す
3549  */
3550 bool stun_monsters(HIT_POINT dam)
3551 {
3552         return (project_all_los(GF_STUN, dam));
3553 }
3554
3555
3556 /*!
3557  * @brief モンスター停止効果(プレイヤー視界範囲内) / Stasis monsters
3558  * @param dam 効力
3559  * @return 作用が実際にあった場合TRUEを返す
3560  */
3561 bool stasis_monsters(HIT_POINT dam)
3562 {
3563         return (project_all_los(GF_STASIS, dam));
3564 }
3565
3566
3567 /*!
3568  * @brief モンスター精神攻撃効果(プレイヤー視界範囲内) / Mindblast monsters
3569  * @param dam 効力
3570  * @return 作用が実際にあった場合TRUEを返す
3571  */
3572 bool mindblast_monsters(HIT_POINT dam)
3573 {
3574         return (project_all_los(GF_PSI, dam));
3575 }
3576
3577
3578 /*!
3579  * @brief モンスター追放効果(プレイヤー視界範囲内) / Banish all monsters
3580  * @param dist 効力(距離)
3581  * @return 作用が実際にあった場合TRUEを返す
3582  */
3583 bool banish_monsters(int dist)
3584 {
3585         return (project_all_los(GF_AWAY_ALL, dist));
3586 }
3587
3588
3589 /*!
3590  * @brief 邪悪退散効果(プレイヤー視界範囲内) / Turn evil
3591  * @param dam 効力
3592  * @return 作用が実際にあった場合TRUEを返す
3593  */
3594 bool turn_evil(HIT_POINT dam)
3595 {
3596         return (project_all_los(GF_TURN_EVIL, dam));
3597 }
3598
3599
3600 /*!
3601  * @brief 全モンスター退散効果(プレイヤー視界範囲内) / Turn everyone
3602  * @param dam 効力
3603  * @return 作用が実際にあった場合TRUEを返す
3604  */
3605 bool turn_monsters(HIT_POINT dam)
3606 {
3607         return (project_all_los(GF_TURN_ALL, dam));
3608 }
3609
3610
3611 /*!
3612  * @brief 死の光線(プレイヤー視界範囲内) / Death-ray all monsters (note: OBSCENELY powerful)
3613  * @return 作用が実際にあった場合TRUEを返す
3614  */
3615 bool deathray_monsters(void)
3616 {
3617         return (project_all_los(GF_DEATH_RAY, p_ptr->lev * 200));
3618 }
3619
3620 /*!
3621  * @brief チャーム・モンスター(1体)
3622  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
3623  * @param plev パワー
3624  * @return 作用が実際にあった場合TRUEを返す
3625  */
3626 bool charm_monster(DIRECTION dir, PLAYER_LEVEL plev)
3627 {
3628         BIT_FLAGS flg = PROJECT_STOP | PROJECT_KILL;
3629         return (project_hook(GF_CHARM, dir, plev, flg));
3630 }
3631
3632 /*!
3633  * @brief アンデッド支配(1体)
3634  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
3635  * @param plev パワー
3636  * @return 作用が実際にあった場合TRUEを返す
3637  */
3638 bool control_one_undead(DIRECTION dir, PLAYER_LEVEL plev)
3639 {
3640         BIT_FLAGS flg = PROJECT_STOP | PROJECT_KILL;
3641         return (project_hook(GF_CONTROL_UNDEAD, dir, plev, flg));
3642 }
3643
3644 /*!
3645  * @brief 悪魔支配(1体)
3646  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
3647  * @param plev パワー
3648  * @return 作用が実際にあった場合TRUEを返す
3649  */
3650 bool control_one_demon(DIRECTION dir, PLAYER_LEVEL plev)
3651 {
3652         BIT_FLAGS flg = PROJECT_STOP | PROJECT_KILL;
3653         return (project_hook(GF_CONTROL_DEMON, dir, plev, flg));
3654 }
3655
3656 /*!
3657  * @brief 動物支配(1体)
3658  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
3659  * @param plev パワー
3660  * @return 作用が実際にあった場合TRUEを返す
3661  */
3662 bool charm_animal(DIRECTION dir, PLAYER_LEVEL plev)
3663 {
3664         BIT_FLAGS flg = PROJECT_STOP | PROJECT_KILL;
3665         return (project_hook(GF_CONTROL_ANIMAL, dir, plev, flg));
3666 }
3667
3668
3669 /*!
3670  * @brief 変わり身処理
3671  * @param success 判定成功上の処理ならばTRUE
3672  * @return 作用が実際にあった場合TRUEを返す
3673  */
3674 bool kawarimi(bool success)
3675 {
3676         object_type forge;
3677         object_type *q_ptr = &forge;
3678         POSITION y, x;
3679
3680         if (p_ptr->is_dead) return FALSE;
3681         if (p_ptr->confused || p_ptr->blind || p_ptr->paralyzed || p_ptr->image) return FALSE;
3682         if (randint0(200) < p_ptr->stun) return FALSE;
3683
3684         if (!success && one_in_(3))
3685         {
3686                 msg_print(_("失敗!逃げられなかった。", "Failed! You couldn't run away."));
3687                 p_ptr->special_defense &= ~(NINJA_KAWARIMI);
3688                 p_ptr->redraw |= (PR_STATUS);
3689                 return FALSE;
3690         }
3691
3692         y = p_ptr->y;
3693         x = p_ptr->x;
3694
3695         teleport_player(10 + randint1(90), 0L);
3696         object_wipe(q_ptr);
3697         object_prep(q_ptr, lookup_kind(TV_STATUE, SV_WOODEN_STATUE));
3698
3699         q_ptr->pval = MON_NINJA;
3700         (void)drop_near(q_ptr, -1, y, x);
3701
3702         if (success) msg_print(_("攻撃を受ける前に素早く身をひるがえした。", "You have turned around just before the attack hit you."));
3703         else msg_print(_("失敗!攻撃を受けてしまった。", "Failed! You are hit by the attack."));
3704
3705         p_ptr->special_defense &= ~(NINJA_KAWARIMI);
3706         p_ptr->redraw |= (PR_STATUS);
3707
3708         /* Teleported */
3709         return TRUE;
3710 }
3711
3712
3713 /*!
3714  * @brief 入身処理 / "Rush Attack" routine for Samurai or Ninja
3715  * @param mdeath 目標モンスターが死亡したかを返す
3716  * @return 作用が実際にあった場合TRUEを返す /  Return value is for checking "done"
3717  */
3718 bool rush_attack(bool *mdeath)
3719 {
3720         DIRECTION dir;
3721         int tx, ty;
3722         int tm_idx = 0;
3723         u16b path_g[32];
3724         int path_n, i;
3725         bool tmp_mdeath = FALSE;
3726         bool moved = FALSE;
3727
3728         if (mdeath) *mdeath = FALSE;
3729
3730         project_length = 5;
3731         if (!get_aim_dir(&dir)) return FALSE;
3732
3733         /* Use the given direction */
3734         tx = p_ptr->x + project_length * ddx[dir];
3735         ty = p_ptr->y + project_length * ddy[dir];
3736
3737         /* Hack -- Use an actual "target" */
3738         if ((dir == 5) && target_okay())
3739         {
3740                 tx = target_col;
3741                 ty = target_row;
3742         }
3743
3744         if (in_bounds(ty, tx)) tm_idx = current_floor_ptr->grid_array[ty][tx].m_idx;
3745
3746         path_n = project_path(path_g, project_length, p_ptr->y, p_ptr->x, ty, tx, PROJECT_STOP | PROJECT_KILL);
3747         project_length = 0;
3748
3749         /* No need to move */
3750         if (!path_n) return TRUE;
3751
3752         /* Use ty and tx as to-move point */
3753         ty = p_ptr->y;
3754         tx = p_ptr->x;
3755
3756         /* Project along the path */
3757         for (i = 0; i < path_n; i++)
3758         {
3759                 monster_type *m_ptr;
3760
3761                 int ny = GRID_Y(path_g[i]);
3762                 int nx = GRID_X(path_g[i]);
3763
3764                 if (cave_empty_bold(ny, nx) && player_can_enter(current_floor_ptr->grid_array[ny][nx].feat, 0))
3765                 {
3766                         ty = ny;
3767                         tx = nx;
3768
3769                         /* Go to next grid */
3770                         continue;
3771                 }
3772
3773                 if (!current_floor_ptr->grid_array[ny][nx].m_idx)
3774                 {
3775                         if (tm_idx)
3776                         {
3777                                 msg_print(_("失敗!", "Failed!"));
3778                         }
3779                         else
3780                         {
3781                                 msg_print(_("ここには入身では入れない。", "You can't move to that place."));
3782                         }
3783
3784                         /* Exit loop */
3785                         break;
3786                 }
3787
3788                 /* Move player before updating the monster */
3789                 if (!player_bold(ty, tx)) teleport_player_to(ty, tx, TELEPORT_NONMAGICAL);
3790                 update_monster(current_floor_ptr->grid_array[ny][nx].m_idx, TRUE);
3791
3792                 /* Found a monster */
3793                 m_ptr = &current_floor_ptr->m_list[current_floor_ptr->grid_array[ny][nx].m_idx];
3794
3795                 if (tm_idx != current_floor_ptr->grid_array[ny][nx].m_idx)
3796                 {
3797 #ifdef JP
3798                         msg_format("%s%sが立ちふさがっている!", tm_idx ? "別の" : "", m_ptr->ml ? "モンスター" : "何か");
3799 #else
3800                         msg_format("There is %s in the way!", m_ptr->ml ? (tm_idx ? "another monster" : "a monster") : "someone");
3801 #endif
3802                 }
3803                 else if (!player_bold(ty, tx))
3804                 {
3805                         /* Hold the monster name */
3806                         GAME_TEXT m_name[MAX_NLEN];
3807
3808                         /* Get the monster name (BEFORE polymorphing) */
3809                         monster_desc(m_name, m_ptr, 0);
3810                         msg_format(_("素早く%sの懐に入り込んだ!", "You quickly jump in and attack %s!"), m_name);
3811                 }
3812
3813                 if (!player_bold(ty, tx)) teleport_player_to(ty, tx, TELEPORT_NONMAGICAL);
3814                 moved = TRUE;
3815                 tmp_mdeath = py_attack(ny, nx, HISSATSU_NYUSIN);
3816
3817                 break;
3818         }
3819
3820         if (!moved && !player_bold(ty, tx)) teleport_player_to(ty, tx, TELEPORT_NONMAGICAL);
3821
3822         if (mdeath) *mdeath = tmp_mdeath;
3823         return TRUE;
3824 }
3825
3826
3827 /*!
3828  * @brief 全鏡の消去 / Remove all mirrors in this floor
3829  * @param explode 爆発処理を伴うならばTRUE
3830  * @return なし
3831  */
3832 void remove_all_mirrors(bool explode)
3833 {
3834         POSITION x, y;
3835
3836         for (x = 0; x < current_floor_ptr->width; x++)
3837         {
3838                 for (y = 0; y < current_floor_ptr->height; y++)
3839                 {
3840                         if (is_mirror_grid(&current_floor_ptr->grid_array[y][x]))
3841                         {
3842                                 remove_mirror(y, x);
3843                                 if (explode)
3844                                         project(0, 2, y, x, p_ptr->lev / 2 + 5, GF_SHARDS,
3845                                                 (PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL | PROJECT_JUMP | PROJECT_NO_HANGEKI), -1);
3846                         }
3847                 }
3848         }
3849 }
3850
3851 /*!
3852  * @brief 『一つの指輪』の効果処理 /
3853  * Hack -- activate the ring of power
3854  * @param dir 発動の方向ID
3855  * @return なし
3856  */
3857 void ring_of_power(DIRECTION dir)
3858 {
3859         /* Pick a random effect */
3860         switch (randint1(10))
3861         {
3862         case 1:
3863         case 2:
3864         {
3865                 msg_print(_("あなたは悪性のオーラに包み込まれた。", "You are surrounded by a malignant aura."));
3866                 sound(SOUND_EVIL);
3867
3868                 /* Decrease all stats (permanently) */
3869                 (void)dec_stat(A_STR, 50, TRUE);
3870                 (void)dec_stat(A_INT, 50, TRUE);
3871                 (void)dec_stat(A_WIS, 50, TRUE);
3872                 (void)dec_stat(A_DEX, 50, TRUE);
3873                 (void)dec_stat(A_CON, 50, TRUE);
3874                 (void)dec_stat(A_CHR, 50, TRUE);
3875
3876                 /* Lose some experience (permanently) */
3877                 p_ptr->exp -= (p_ptr->exp / 4);
3878                 p_ptr->max_exp -= (p_ptr->exp / 4);
3879                 check_experience();
3880
3881                 break;
3882         }
3883
3884         case 3:
3885         {
3886                 msg_print(_("あなたは強力なオーラに包み込まれた。", "You are surrounded by a powerful aura."));
3887                 dispel_monsters(1000);
3888                 break;
3889         }
3890
3891         case 4:
3892         case 5:
3893         case 6:
3894         {
3895                 fire_ball(GF_MANA, dir, 600, 3);
3896                 break;
3897         }
3898
3899         case 7:
3900         case 8:
3901         case 9:
3902         case 10:
3903         {
3904                 fire_bolt(GF_MANA, dir, 500);
3905                 break;
3906         }
3907         }
3908 }
3909
3910 /*!
3911 * @brief 運命の輪、並びにカオス的な効果の発動
3912 * @param spell ランダムな効果を選択するための基準ID
3913 * @return なし
3914 */
3915 void wild_magic(int spell)
3916 {
3917         int counter = 0;
3918         int type = SUMMON_MOLD + randint0(6);
3919
3920         if (type < SUMMON_MOLD) type = SUMMON_MOLD;
3921         else if (type > SUMMON_MIMIC) type = SUMMON_MIMIC;
3922
3923         switch (randint1(spell) + randint1(8) + 1)
3924         {
3925         case 1:
3926         case 2:
3927         case 3:
3928                 teleport_player(10, TELEPORT_PASSIVE);
3929                 break;
3930         case 4:
3931         case 5:
3932         case 6:
3933                 teleport_player(100, TELEPORT_PASSIVE);
3934                 break;
3935         case 7:
3936         case 8:
3937                 teleport_player(200, TELEPORT_PASSIVE);
3938                 break;
3939         case 9:
3940         case 10:
3941         case 11:
3942                 unlite_area(10, 3);
3943                 break;
3944         case 12:
3945         case 13:
3946         case 14:
3947                 lite_area(damroll(2, 3), 2);
3948                 break;
3949         case 15:
3950                 destroy_doors_touch();
3951                 break;
3952         case 16: case 17:
3953                 wall_breaker();
3954         case 18:
3955                 sleep_monsters_touch();
3956                 break;
3957         case 19:
3958         case 20:
3959                 trap_creation(p_ptr->y, p_ptr->x);
3960                 break;
3961         case 21:
3962         case 22:
3963                 door_creation();
3964                 break;
3965         case 23:
3966         case 24:
3967         case 25:
3968                 aggravate_monsters(0);
3969                 break;
3970         case 26:
3971                 earthquake(p_ptr->y, p_ptr->x, 5);
3972                 break;
3973         case 27:
3974         case 28:
3975                 (void)gain_mutation(p_ptr, 0);
3976                 break;
3977         case 29:
3978         case 30:
3979                 apply_disenchant(1);
3980                 break;
3981         case 31:
3982                 lose_all_info();
3983                 break;
3984         case 32:
3985                 fire_ball(GF_CHAOS, 0, spell + 5, 1 + (spell / 10));
3986                 break;
3987         case 33:
3988                 wall_stone();
3989                 break;
3990         case 34:
3991         case 35:
3992                 while (counter++ < 8)
3993                 {
3994                         (void)summon_specific(0, p_ptr->y, p_ptr->x, (current_floor_ptr->dun_level * 3) / 2, type, (PM_ALLOW_GROUP | PM_NO_PET), '\0');
3995                 }
3996                 break;
3997         case 36:
3998         case 37:
3999                 activate_hi_summon(p_ptr->y, p_ptr->x, FALSE);
4000                 break;
4001         case 38:
4002                 (void)summon_cyber(-1, p_ptr->y, p_ptr->x);
4003                 break;
4004         default:
4005         {
4006                 int count = 0;
4007                 (void)activate_ty_curse(FALSE, &count);
4008                 break;
4009         }
4010         }
4011
4012         return;
4013 }
4014
4015 /*!
4016 * @brief カオス魔法「流星群」の処理としてプレイヤーを中心に隕石落下処理を10+1d10回繰り返す。
4017 * / Drop 10+1d10 meteor ball at random places near the player
4018 * @param dam ダメージ
4019 * @param rad 効力の半径
4020 * @return なし
4021 */
4022 void cast_meteor(HIT_POINT dam, POSITION rad)
4023 {
4024         int i;
4025         int b = 10 + randint1(10);
4026
4027         for (i = 0; i < b; i++)
4028         {
4029                 POSITION y = 0, x = 0;
4030                 int count;
4031
4032                 for (count = 0; count <= 20; count++)
4033                 {
4034                         int dy, dx, d;
4035
4036                         x = p_ptr->x - 8 + randint0(17);
4037                         y = p_ptr->y - 8 + randint0(17);
4038
4039                         dx = (p_ptr->x > x) ? (p_ptr->x - x) : (x - p_ptr->x);
4040                         dy = (p_ptr->y > y) ? (p_ptr->y - y) : (y - p_ptr->y);
4041
4042                         /* Approximate distance */
4043                         d = (dy > dx) ? (dy + (dx >> 1)) : (dx + (dy >> 1));
4044
4045                         if (d >= 9) continue;
4046
4047                         if (!in_bounds(y, x) || !projectable(p_ptr->y, p_ptr->x, y, x)
4048                                 || !cave_have_flag_bold(y, x, FF_PROJECT)) continue;
4049
4050                         /* Valid position */
4051                         break;
4052                 }
4053
4054                 if (count > 20) continue;
4055
4056                 project(0, rad, y, x, dam, GF_METEOR, PROJECT_KILL | PROJECT_JUMP | PROJECT_ITEM, -1);
4057         }
4058 }
4059
4060
4061 /*!
4062 * @brief 破邪魔法「神の怒り」の処理としてターゲットを指定した後分解のボールを最大20回発生させる。
4063 * @param dam ダメージ
4064 * @param rad 効力の半径
4065 * @return ターゲットを指定し、実行したならばTRUEを返す。
4066 */
4067 bool cast_wrath_of_the_god(HIT_POINT dam, POSITION rad)
4068 {
4069         POSITION x, y, tx, ty;
4070         POSITION nx, ny;
4071         DIRECTION dir;
4072         int i;
4073         int b = 10 + randint1(10);
4074
4075         if (!get_aim_dir(&dir)) return FALSE;
4076
4077         /* Use the given direction */
4078         tx = p_ptr->x + 99 * ddx[dir];
4079         ty = p_ptr->y + 99 * ddy[dir];
4080
4081         /* Hack -- Use an actual "target" */
4082         if ((dir == 5) && target_okay())
4083         {
4084                 tx = target_col;
4085                 ty = target_row;
4086         }
4087
4088         x = p_ptr->x;
4089         y = p_ptr->y;
4090
4091         while (1)
4092         {
4093                 /* Hack -- Stop at the target */
4094                 if ((y == ty) && (x == tx)) break;
4095
4096                 ny = y;
4097                 nx = x;
4098                 mmove2(&ny, &nx, p_ptr->y, p_ptr->x, ty, tx);
4099
4100                 /* Stop at maximum range */
4101                 if (MAX_RANGE <= distance(p_ptr->y, p_ptr->x, ny, nx)) break;
4102
4103                 /* Stopped by walls/doors */
4104                 if (!cave_have_flag_bold(ny, nx, FF_PROJECT)) break;
4105
4106                 /* Stopped by monsters */
4107                 if ((dir != 5) && current_floor_ptr->grid_array[ny][nx].m_idx != 0) break;
4108
4109                 /* Save the new location */
4110                 x = nx;
4111                 y = ny;
4112         }
4113         tx = x;
4114         ty = y;
4115
4116         for (i = 0; i < b; i++)
4117         {
4118                 int count = 20, d = 0;
4119
4120                 while (count--)
4121                 {
4122                         int dx, dy;
4123
4124                         x = tx - 5 + randint0(11);
4125                         y = ty - 5 + randint0(11);
4126
4127                         dx = (tx > x) ? (tx - x) : (x - tx);
4128                         dy = (ty > y) ? (ty - y) : (y - ty);
4129
4130                         /* Approximate distance */
4131                         d = (dy > dx) ? (dy + (dx >> 1)) : (dx + (dy >> 1));
4132                         /* Within the radius */
4133                         if (d < 5) break;
4134                 }
4135
4136                 if (count < 0) continue;
4137
4138                 /* Cannot penetrate perm walls */
4139                 if (!in_bounds(y, x) ||
4140                         cave_stop_disintegration(y, x) ||
4141                         !in_disintegration_range(ty, tx, y, x))
4142                         continue;
4143
4144                 project(0, rad, y, x, dam, GF_DISINTEGRATE, PROJECT_JUMP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL, -1);
4145         }
4146
4147         return TRUE;
4148 }
4149
4150 /*!
4151 * @brief 「ワンダー」のランダムな効果を決定して処理する。
4152 * @param dir 方向ID
4153 * @return なし
4154 * @details
4155 * This spell should become more useful (more controlled) as the\n
4156 * player gains experience levels.  Thus, add 1/5 of the player's\n
4157 * level to the die roll.  This eliminates the worst effects later on,\n
4158 * while keeping the results quite random.  It also allows some potent\n
4159 * effects only at high level.
4160 */
4161 void cast_wonder(DIRECTION dir)
4162 {
4163         PLAYER_LEVEL plev = p_ptr->lev;
4164         int die = randint1(100) + plev / 5;
4165         int vir = virtue_number(V_CHANCE);
4166
4167         if (vir)
4168         {
4169                 if (p_ptr->virtues[vir - 1] > 0)
4170                 {
4171                         while (randint1(400) < p_ptr->virtues[vir - 1]) die++;
4172                 }
4173                 else
4174                 {
4175                         while (randint1(400) < (0 - p_ptr->virtues[vir - 1])) die--;
4176                 }
4177         }
4178
4179         if (die < 26)
4180                 chg_virtue(V_CHANCE, 1);
4181
4182         if (die > 100)
4183         {
4184                 msg_print(_("あなたは力がみなぎるのを感じた!", "You feel a surge of power!"));
4185         }
4186
4187         if (die < 8) clone_monster(dir);
4188         else if (die < 14) speed_monster(dir, plev);
4189         else if (die < 26) heal_monster(dir, damroll(4, 6));
4190         else if (die < 31) poly_monster(dir, plev);
4191         else if (die < 36)
4192                 fire_bolt_or_beam(beam_chance() - 10, GF_MISSILE, dir,
4193                         damroll(3 + ((plev - 1) / 5), 4));
4194         else if (die < 41) confuse_monster(dir, plev);
4195         else if (die < 46) fire_ball(GF_POIS, dir, 20 + (plev / 2), 3);
4196         else if (die < 51) (void)lite_line(dir, damroll(6, 8));
4197         else if (die < 56)
4198                 fire_bolt_or_beam(beam_chance() - 10, GF_ELEC, dir,
4199                         damroll(3 + ((plev - 5) / 4), 8));
4200         else if (die < 61)
4201                 fire_bolt_or_beam(beam_chance() - 10, GF_COLD, dir,
4202                         damroll(5 + ((plev - 5) / 4), 8));
4203         else if (die < 66)
4204                 fire_bolt_or_beam(beam_chance(), GF_ACID, dir,
4205                         damroll(6 + ((plev - 5) / 4), 8));
4206         else if (die < 71)
4207                 fire_bolt_or_beam(beam_chance(), GF_FIRE, dir,
4208                         damroll(8 + ((plev - 5) / 4), 8));
4209         else if (die < 76) hypodynamic_bolt(dir, 75);
4210         else if (die < 81) fire_ball(GF_ELEC, dir, 30 + plev / 2, 2);
4211         else if (die < 86) fire_ball(GF_ACID, dir, 40 + plev, 2);
4212         else if (die < 91) fire_ball(GF_ICE, dir, 70 + plev, 3);
4213         else if (die < 96) fire_ball(GF_FIRE, dir, 80 + plev, 3);
4214         else if (die < 101) hypodynamic_bolt(dir, 100 + plev);
4215         else if (die < 104)
4216         {
4217                 earthquake(p_ptr->y, p_ptr->x, 12);
4218         }
4219         else if (die < 106)
4220         {
4221                 (void)destroy_area(p_ptr->y, p_ptr->x, 13 + randint0(5), FALSE);
4222         }
4223         else if (die < 108)
4224         {
4225                 symbol_genocide(plev + 50, TRUE);
4226         }
4227         else if (die < 110) dispel_monsters(120);
4228         else /* RARE */
4229         {
4230                 dispel_monsters(150);
4231                 slow_monsters(plev);
4232                 sleep_monsters(plev);
4233                 hp_player(300);
4234         }
4235 }
4236
4237
4238 /*!
4239 * @brief 「悪霊召喚」のランダムな効果を決定して処理する。
4240 * @param dir 方向ID
4241 * @return なし
4242 */
4243 void cast_invoke_spirits(DIRECTION dir)
4244 {
4245         PLAYER_LEVEL plev = p_ptr->lev;
4246         int die = randint1(100) + plev / 5;
4247         int vir = virtue_number(V_CHANCE);
4248
4249         if (vir)
4250         {
4251                 if (p_ptr->virtues[vir - 1] > 0)
4252                 {
4253                         while (randint1(400) < p_ptr->virtues[vir - 1]) die++;
4254                 }
4255                 else
4256                 {
4257                         while (randint1(400) < (0 - p_ptr->virtues[vir - 1])) die--;
4258                 }
4259         }
4260
4261         msg_print(_("あなたは死者たちの力を招集した...", "You call on the power of the dead..."));
4262         if (die < 26)
4263                 chg_virtue(V_CHANCE, 1);
4264
4265         if (die > 100)
4266         {
4267                 msg_print(_("あなたはおどろおどろしい力のうねりを感じた!", "You feel a surge of eldritch force!"));
4268         }
4269
4270         if (die < 8)
4271         {
4272                 msg_print(_("なんてこった!あなたの周りの地面から朽ちた人影が立ち上がってきた!",
4273                         "Oh no! Mouldering forms rise from the earth around you!"));
4274
4275                 (void)summon_specific(0, p_ptr->y, p_ptr->x, current_floor_ptr->dun_level, SUMMON_UNDEAD, (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE | PM_NO_PET), '\0');
4276                 chg_virtue(V_UNLIFE, 1);
4277         }
4278         else if (die < 14)
4279         {
4280                 msg_print(_("名状し難い邪悪な存在があなたの心を通り過ぎて行った...", "An unnamable evil brushes against your mind..."));
4281
4282                 set_afraid(p_ptr->afraid + randint1(4) + 4);
4283         }
4284         else if (die < 26)
4285         {
4286                 msg_print(_("あなたの頭に大量の幽霊たちの騒々しい声が押し寄せてきた...",
4287                         "Your head is invaded by a horde of gibbering spectral voices..."));
4288
4289                 set_confused(p_ptr->confused + randint1(4) + 4);
4290         }
4291         else if (die < 31)
4292         {
4293                 poly_monster(dir, plev);
4294         }
4295         else if (die < 36)
4296         {
4297                 fire_bolt_or_beam(beam_chance() - 10, GF_MISSILE, dir,
4298                         damroll(3 + ((plev - 1) / 5), 4));
4299         }
4300         else if (die < 41)
4301         {
4302                 confuse_monster(dir, plev);
4303         }
4304         else if (die < 46)
4305         {
4306                 fire_ball(GF_POIS, dir, 20 + (plev / 2), 3);
4307         }
4308         else if (die < 51)
4309         {
4310                 (void)lite_line(dir, damroll(6, 8));
4311         }
4312         else if (die < 56)
4313         {
4314                 fire_bolt_or_beam(beam_chance() - 10, GF_ELEC, dir,
4315                         damroll(3 + ((plev - 5) / 4), 8));
4316         }
4317         else if (die < 61)
4318         {
4319                 fire_bolt_or_beam(beam_chance() - 10, GF_COLD, dir,
4320                         damroll(5 + ((plev - 5) / 4), 8));
4321         }
4322         else if (die < 66)
4323         {
4324                 fire_bolt_or_beam(beam_chance(), GF_ACID, dir,
4325                         damroll(6 + ((plev - 5) / 4), 8));
4326         }
4327         else if (die < 71)
4328         {
4329                 fire_bolt_or_beam(beam_chance(), GF_FIRE, dir,
4330                         damroll(8 + ((plev - 5) / 4), 8));
4331         }
4332         else if (die < 76)
4333         {
4334                 hypodynamic_bolt(dir, 75);
4335         }
4336         else if (die < 81)
4337         {
4338                 fire_ball(GF_ELEC, dir, 30 + plev / 2, 2);
4339         }
4340         else if (die < 86)
4341         {
4342                 fire_ball(GF_ACID, dir, 40 + plev, 2);
4343         }
4344         else if (die < 91)
4345         {
4346                 fire_ball(GF_ICE, dir, 70 + plev, 3);
4347         }
4348         else if (die < 96)
4349         {
4350                 fire_ball(GF_FIRE, dir, 80 + plev, 3);
4351         }
4352         else if (die < 101)
4353         {
4354                 hypodynamic_bolt(dir, 100 + plev);
4355         }
4356         else if (die < 104)
4357         {
4358                 earthquake(p_ptr->y, p_ptr->x, 12);
4359         }
4360         else if (die < 106)
4361         {
4362                 (void)destroy_area(p_ptr->y, p_ptr->x, 13 + randint0(5), FALSE);
4363         }
4364         else if (die < 108)
4365         {
4366                 symbol_genocide(plev + 50, TRUE);
4367         }
4368         else if (die < 110)
4369         {
4370                 dispel_monsters(120);
4371         }
4372         else
4373         { /* RARE */
4374                 dispel_monsters(150);
4375                 slow_monsters(plev);
4376                 sleep_monsters(plev);
4377                 hp_player(300);
4378         }
4379
4380         if (die < 31)
4381         {
4382                 msg_print(_("陰欝な声がクスクス笑う。「もうすぐおまえは我々の仲間になるだろう。弱き者よ。」",
4383                         "Sepulchral voices chuckle. 'Soon you will join us, mortal.'"));
4384         }
4385 }
4386
4387 /*!
4388 * @brief トランプ領域の「シャッフル」の効果をランダムに決めて処理する。
4389 * @return なし
4390 */
4391 void cast_shuffle(void)
4392 {
4393         PLAYER_LEVEL plev = p_ptr->lev;
4394         DIRECTION dir;
4395         int die;
4396         int vir = virtue_number(V_CHANCE);
4397         int i;
4398
4399         /* Card sharks and high mages get a level bonus */
4400         if ((p_ptr->pclass == CLASS_ROGUE) ||
4401                 (p_ptr->pclass == CLASS_HIGH_MAGE) ||
4402                 (p_ptr->pclass == CLASS_SORCERER))
4403                 die = (randint1(110)) + plev / 5;
4404         else
4405                 die = randint1(120);
4406
4407
4408         if (vir)
4409         {
4410                 if (p_ptr->virtues[vir - 1] > 0)
4411                 {
4412                         while (randint1(400) < p_ptr->virtues[vir - 1]) die++;
4413                 }
4414                 else
4415                 {
4416                         while (randint1(400) < (0 - p_ptr->virtues[vir - 1])) die--;
4417                 }
4418         }
4419
4420         msg_print(_("あなたはカードを切って一枚引いた...", "You shuffle the deck and draw a card..."));
4421
4422         if (die < 30)
4423                 chg_virtue(V_CHANCE, 1);
4424
4425         if (die < 7)
4426         {
4427                 msg_print(_("なんてこった!《死》だ!", "Oh no! It's Death!"));
4428
4429                 for (i = 0; i < randint1(3); i++)
4430                         activate_hi_summon(p_ptr->y, p_ptr->x, FALSE);
4431         }
4432         else if (die < 14)
4433         {
4434                 msg_print(_("なんてこった!《悪魔》だ!", "Oh no! It's the Devil!"));
4435                 summon_specific(0, p_ptr->y, p_ptr->x, current_floor_ptr->dun_level, SUMMON_DEMON, (PM_ALLOW_GROUP | PM_ALLOW_UNIQUE | PM_NO_PET), '\0');
4436         }
4437         else if (die < 18)
4438         {
4439                 int count = 0;
4440                 msg_print(_("なんてこった!《吊られた男》だ!", "Oh no! It's the Hanged Man."));
4441                 activate_ty_curse(FALSE, &count);
4442         }
4443         else if (die < 22)
4444         {
4445                 msg_print(_("《不調和の剣》だ。", "It's the swords of discord."));
4446                 aggravate_monsters(0);
4447         }
4448         else if (die < 26)
4449         {
4450                 msg_print(_("《愚者》だ。", "It's the Fool."));
4451                 do_dec_stat(A_INT);
4452                 do_dec_stat(A_WIS);
4453         }
4454         else if (die < 30)
4455         {
4456                 msg_print(_("奇妙なモンスターの絵だ。", "It's the picture of a strange monster."));
4457                 trump_summoning(1, FALSE, p_ptr->y, p_ptr->x, (current_floor_ptr->dun_level * 3 / 2), (32 + randint1(6)), PM_ALLOW_GROUP | PM_ALLOW_UNIQUE);
4458         }
4459         else if (die < 33)
4460         {
4461                 msg_print(_("《月》だ。", "It's the Moon."));
4462                 unlite_area(10, 3);
4463         }
4464         else if (die < 38)
4465         {
4466                 msg_print(_("《運命の輪》だ。", "It's the Wheel of Fortune."));
4467                 wild_magic(randint0(32));
4468         }
4469         else if (die < 40)
4470         {
4471                 msg_print(_("テレポート・カードだ。", "It's a teleport trump card."));
4472                 teleport_player(10, TELEPORT_PASSIVE);
4473         }
4474         else if (die < 42)
4475         {
4476                 msg_print(_("《正義》だ。", "It's Justice."));
4477                 set_blessed(p_ptr->lev, FALSE);
4478         }
4479         else if (die < 47)
4480         {
4481                 msg_print(_("テレポート・カードだ。", "It's a teleport trump card."));
4482                 teleport_player(100, TELEPORT_PASSIVE);
4483         }
4484         else if (die < 52)
4485         {
4486                 msg_print(_("テレポート・カードだ。", "It's a teleport trump card."));
4487                 teleport_player(200, TELEPORT_PASSIVE);
4488         }
4489         else if (die < 60)
4490         {
4491                 msg_print(_("《塔》だ。", "It's the Tower."));
4492                 wall_breaker();
4493         }
4494         else if (die < 72)
4495         {
4496                 msg_print(_("《節制》だ。", "It's Temperance."));
4497                 sleep_monsters_touch();
4498         }
4499         else if (die < 80)
4500         {
4501                 msg_print(_("《塔》だ。", "It's the Tower."));
4502
4503                 earthquake(p_ptr->y, p_ptr->x, 5);
4504         }
4505         else if (die < 82)
4506         {
4507                 msg_print(_("友好的なモンスターの絵だ。", "It's the picture of a friendly monster."));
4508                 trump_summoning(1, TRUE, p_ptr->y, p_ptr->x, (current_floor_ptr->dun_level * 3 / 2), SUMMON_MOLD, 0L);
4509         }
4510         else if (die < 84)
4511         {
4512                 msg_print(_("友好的なモンスターの絵だ。", "It's the picture of a friendly monster."));
4513                 trump_summoning(1, TRUE, p_ptr->y, p_ptr->x, (current_floor_ptr->dun_level * 3 / 2), SUMMON_BAT, 0L);
4514         }
4515         else if (die < 86)
4516         {
4517                 msg_print(_("友好的なモンスターの絵だ。", "It's the picture of a friendly monster."));
4518                 trump_summoning(1, TRUE, p_ptr->y, p_ptr->x, (current_floor_ptr->dun_level * 3 / 2), SUMMON_VORTEX, 0L);
4519         }
4520         else if (die < 88)
4521         {
4522                 msg_print(_("友好的なモンスターの絵だ。", "It's the picture of a friendly monster."));
4523                 trump_summoning(1, TRUE, p_ptr->y, p_ptr->x, (current_floor_ptr->dun_level * 3 / 2), SUMMON_COIN_MIMIC, 0L);
4524         }
4525         else if (die < 96)
4526         {
4527                 msg_print(_("《恋人》だ。", "It's the Lovers."));
4528
4529                 if (get_aim_dir(&dir))
4530                         charm_monster(dir, MIN(p_ptr->lev, 20));
4531         }
4532         else if (die < 101)
4533         {
4534                 msg_print(_("《隠者》だ。", "It's the Hermit."));
4535                 wall_stone();
4536         }
4537         else if (die < 111)
4538         {
4539                 msg_print(_("《審判》だ。", "It's the Judgement."));
4540                 roll_hitdice(p_ptr, 0L);
4541                 lose_all_mutations();
4542         }
4543         else if (die < 120)
4544         {
4545                 msg_print(_("《太陽》だ。", "It's the Sun."));
4546                 chg_virtue(V_KNOWLEDGE, 1);
4547                 chg_virtue(V_ENLIGHTEN, 1);
4548                 wiz_lite(FALSE);
4549         }
4550         else
4551         {
4552                 msg_print(_("《世界》だ。", "It's the World."));
4553                 if (p_ptr->exp < PY_MAX_EXP)
4554                 {
4555                         s32b ee = (p_ptr->exp / 25) + 1;
4556                         if (ee > 5000) ee = 5000;
4557                         msg_print(_("更に経験を積んだような気がする。", "You feel more experienced."));
4558                         gain_exp(ee);
4559                 }
4560         }
4561 }
4562
4563 /*!
4564  * @brief 口を使う継続的な処理を中断する
4565  * @return なし
4566  */
4567 void stop_mouth(void)
4568 {
4569         if (music_singing_any()) stop_singing(p_ptr);
4570         if (hex_spelling_any()) stop_hex_spell_all();
4571 }
4572
4573
4574 bool_hack vampirism(void)
4575 {
4576         DIRECTION dir;
4577         POSITION x, y;
4578         int dummy;
4579         grid_type *g_ptr;
4580
4581         if (d_info[p_ptr->dungeon_idx].flags1 & DF1_NO_MELEE)
4582         {
4583                 msg_print(_("なぜか攻撃することができない。", "Something prevent you from attacking."));
4584                 return FALSE;
4585         }
4586
4587         /* Only works on adjacent monsters */
4588         if (!get_direction(&dir, FALSE, FALSE)) return FALSE;
4589         y = p_ptr->y + ddy[dir];
4590         x = p_ptr->x + ddx[dir];
4591         g_ptr = &current_floor_ptr->grid_array[y][x];
4592
4593         stop_mouth();
4594
4595         if (!(g_ptr->m_idx))
4596         {
4597                 msg_print(_("何もない場所に噛みついた!", "You bite into thin air!"));
4598                 return FALSE;
4599         }
4600
4601         msg_print(_("あなたはニヤリとして牙をむいた...", "You grin and bare your fangs..."));
4602
4603         dummy = p_ptr->lev * 2;
4604
4605         if (hypodynamic_bolt(dir, dummy))
4606         {
4607                 if (p_ptr->food < PY_FOOD_FULL)
4608                         /* No heal if we are "full" */
4609                         (void)hp_player(dummy);
4610                 else
4611                         msg_print(_("あなたは空腹ではありません。", "You were not hungry."));
4612
4613                 /* Gain nutritional sustenance: 150/hp drained */
4614                 /* A Food ration gives 5000 food points (by contrast) */
4615                 /* Don't ever get more than "Full" this way */
4616                 /* But if we ARE Gorged,  it won't cure us */
4617                 dummy = p_ptr->food + MIN(5000, 100 * dummy);
4618                 if (p_ptr->food < PY_FOOD_MAX)   /* Not gorged already */
4619                         (void)set_food(dummy >= PY_FOOD_MAX ? PY_FOOD_MAX - 1 : dummy);
4620         }
4621         else
4622                 msg_print(_("げぇ!ひどい味だ。", "Yechh. That tastes foul."));
4623         return TRUE;
4624 }
4625
4626 bool panic_hit(void)
4627 {
4628         DIRECTION dir;
4629         POSITION x, y;
4630
4631         if (!get_direction(&dir, FALSE, FALSE)) return FALSE;
4632         y = p_ptr->y + ddy[dir];
4633         x = p_ptr->x + ddx[dir];
4634         if (current_floor_ptr->grid_array[y][x].m_idx)
4635         {
4636                 py_attack(y, x, 0);
4637                 if (randint0(p_ptr->skill_dis) < 7)
4638                         msg_print(_("うまく逃げられなかった。", "You failed to run away."));
4639                 else
4640                         teleport_player(30, 0L);
4641                 return TRUE;
4642         }
4643         else
4644         {
4645                 msg_print(_("その方向にはモンスターはいません。", "You don't see any monster in this direction"));
4646                 msg_print(NULL);
4647                 return FALSE;
4648         }
4649
4650 }
4651
4652 /*!
4653 * @brief 超能力者のサイコメトリー処理/ Forcibly pseudo-identify an object in the inventory (or on the floor)
4654 * @return なし
4655 * @note
4656 * currently this function allows pseudo-id of any object,
4657 * including silly ones like potions & scrolls, which always
4658 * get '{average}'. This should be changed, either to stop such
4659 * items from being pseudo-id'd, or to allow psychometry to
4660 * detect whether the unidentified potion/scroll/etc is
4661 * good (Cure Light Wounds, Restore Strength, etc) or
4662 * bad (Poison, Weakness etc) or 'useless' (Slime Mold Juice, etc).
4663 */
4664 bool psychometry(void)
4665 {
4666         OBJECT_IDX      item;
4667         object_type *o_ptr;
4668         GAME_TEXT o_name[MAX_NLEN];
4669         byte            feel;
4670         concptr            q, s;
4671         bool okay = FALSE;
4672
4673         q = _("どのアイテムを調べますか?", "Meditate on which item? ");
4674         s = _("調べるアイテムがありません。", "You have nothing appropriate.");
4675
4676         o_ptr = choose_object(&item, q, s, (USE_EQUIP | USE_INVEN | USE_FLOOR | IGNORE_BOTHHAND_SLOT));
4677         if (!o_ptr) return (FALSE);
4678
4679         /* It is fully known, no information needed */
4680         if (object_is_known(o_ptr))
4681         {
4682                 msg_print(_("何も新しいことは判らなかった。", "You cannot find out anything more about that."));
4683                 return TRUE;
4684         }
4685
4686         /* Check for a feeling */
4687         feel = value_check_aux1(o_ptr);
4688
4689         /* Get an object description */
4690         object_desc(o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
4691
4692         /* Skip non-feelings */
4693         if (!feel)
4694         {
4695                 msg_format(_("%sからは特に変わった事は感じとれなかった。", "You do not perceive anything unusual about the %s."), o_name);
4696                 return TRUE;
4697         }
4698
4699 #ifdef JP
4700         msg_format("%sは%sという感じがする...", o_name, game_inscriptions[feel]);
4701 #else
4702         msg_format("You feel that the %s %s %s...",
4703                 o_name, ((o_ptr->number == 1) ? "is" : "are"), game_inscriptions[feel]);
4704 #endif
4705
4706
4707         o_ptr->ident |= (IDENT_SENSE);
4708         o_ptr->feeling = feel;
4709         o_ptr->marked |= OM_TOUCHED;
4710
4711         p_ptr->update |= (PU_COMBINE | PU_REORDER);
4712         p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
4713
4714         /* Valid "tval" codes */
4715         switch (o_ptr->tval)
4716         {
4717         case TV_SHOT:
4718         case TV_ARROW:
4719         case TV_BOLT:
4720         case TV_BOW:
4721         case TV_DIGGING:
4722         case TV_HAFTED:
4723         case TV_POLEARM:
4724         case TV_SWORD:
4725         case TV_BOOTS:
4726         case TV_GLOVES:
4727         case TV_HELM:
4728         case TV_CROWN:
4729         case TV_SHIELD:
4730         case TV_CLOAK:
4731         case TV_SOFT_ARMOR:
4732         case TV_HARD_ARMOR:
4733         case TV_DRAG_ARMOR:
4734         case TV_CARD:
4735         case TV_RING:
4736         case TV_AMULET:
4737         case TV_LITE:
4738         case TV_FIGURINE:
4739                 okay = TRUE;
4740                 break;
4741         }
4742
4743         /* Auto-inscription/destroy */
4744         autopick_alter_item(item, (bool)(okay && destroy_feeling));
4745
4746         /* Something happened */
4747         return (TRUE);
4748 }
4749
4750
4751 bool draconian_breath(player_type *creature_ptr)
4752 {
4753         DIRECTION dir;
4754         int Type = (one_in_(3) ? GF_COLD : GF_FIRE);
4755         concptr Type_desc = ((Type == GF_COLD) ? _("冷気", "cold") : _("炎", "fire"));
4756
4757         if (!get_aim_dir(&dir)) return FALSE;
4758
4759         if (randint1(100) < creature_ptr->lev)
4760         {
4761                 switch (creature_ptr->pclass)
4762                 {
4763                 case CLASS_WARRIOR:
4764                 case CLASS_BERSERKER:
4765                 case CLASS_RANGER:
4766                 case CLASS_TOURIST:
4767                 case CLASS_IMITATOR:
4768                 case CLASS_ARCHER:
4769                 case CLASS_SMITH:
4770                         if (one_in_(3))
4771                         {
4772                                 Type = GF_MISSILE;
4773                                 Type_desc = _("エレメント", "the elements");
4774                         }
4775                         else
4776                         {
4777                                 Type = GF_SHARDS;
4778                                 Type_desc = _("破片", "shards");
4779                         }
4780                         break;
4781                 case CLASS_MAGE:
4782                 case CLASS_WARRIOR_MAGE:
4783                 case CLASS_HIGH_MAGE:
4784                 case CLASS_SORCERER:
4785                 case CLASS_MAGIC_EATER:
4786                 case CLASS_RED_MAGE:
4787                 case CLASS_BLUE_MAGE:
4788                 case CLASS_MIRROR_MASTER:
4789                         if (one_in_(3))
4790                         {
4791                                 Type = GF_MANA;
4792                                 Type_desc = _("魔力", "mana");
4793                         }
4794                         else
4795                         {
4796                                 Type = GF_DISENCHANT;
4797                                 Type_desc = _("劣化", "disenchantment");
4798                         }
4799                         break;
4800                 case CLASS_CHAOS_WARRIOR:
4801                         if (!one_in_(3))
4802                         {
4803                                 Type = GF_CONFUSION;
4804                                 Type_desc = _("混乱", "confusion");
4805                         }
4806                         else
4807                         {
4808                                 Type = GF_CHAOS;
4809                                 Type_desc = _("カオス", "chaos");
4810                         }
4811                         break;
4812                 case CLASS_MONK:
4813                 case CLASS_SAMURAI:
4814                 case CLASS_FORCETRAINER:
4815                         if (!one_in_(3))
4816                         {
4817                                 Type = GF_CONFUSION;
4818                                 Type_desc = _("混乱", "confusion");
4819                         }
4820                         else
4821                         {
4822                                 Type = GF_SOUND;
4823                                 Type_desc = _("轟音", "sound");
4824                         }
4825                         break;
4826                 case CLASS_MINDCRAFTER:
4827                         if (!one_in_(3))
4828                         {
4829                                 Type = GF_CONFUSION;
4830                                 Type_desc = _("混乱", "confusion");
4831                         }
4832                         else
4833                         {
4834                                 Type = GF_PSI;
4835                                 Type_desc = _("精神エネルギー", "mental energy");
4836                         }
4837                         break;
4838                 case CLASS_PRIEST:
4839                 case CLASS_PALADIN:
4840                         if (one_in_(3))
4841                         {
4842                                 Type = GF_HELL_FIRE;
4843                                 Type_desc = _("地獄の劫火", "hellfire");
4844                         }
4845                         else
4846                         {
4847                                 Type = GF_HOLY_FIRE;
4848                                 Type_desc = _("聖なる炎", "holy fire");
4849                         }
4850                         break;
4851                 case CLASS_ROGUE:
4852                 case CLASS_NINJA:
4853                         if (one_in_(3))
4854                         {
4855                                 Type = GF_DARK;
4856                                 Type_desc = _("暗黒", "darkness");
4857                         }
4858                         else
4859                         {
4860                                 Type = GF_POIS;
4861                                 Type_desc = _("毒", "poison");
4862                         }
4863                         break;
4864                 case CLASS_BARD:
4865                         if (!one_in_(3))
4866                         {
4867                                 Type = GF_SOUND;
4868                                 Type_desc = _("轟音", "sound");
4869                         }
4870                         else
4871                         {
4872                                 Type = GF_CONFUSION;
4873                                 Type_desc = _("混乱", "confusion");
4874                         }
4875                         break;
4876                 }
4877         }
4878
4879         stop_mouth();
4880         msg_format(_("あなたは%sのブレスを吐いた。", "You breathe %s."), Type_desc);
4881
4882         fire_breath(Type, dir, creature_ptr->lev * 2, (creature_ptr->lev / 15) + 1);
4883         return TRUE;
4884 }
4885
4886 bool android_inside_weapon(player_type *creature_ptr)
4887 {
4888         DIRECTION dir;
4889         if (!get_aim_dir(&dir)) return FALSE;
4890         if (creature_ptr->lev < 10)
4891         {
4892                 msg_print(_("レイガンを発射した。", "You fire your ray gun."));
4893                 fire_bolt(GF_MISSILE, dir, (creature_ptr->lev + 1) / 2);
4894         }
4895         else if (creature_ptr->lev < 25)
4896         {
4897                 msg_print(_("ブラスターを発射した。", "You fire your blaster."));
4898                 fire_bolt(GF_MISSILE, dir, creature_ptr->lev);
4899         }
4900         else if (creature_ptr->lev < 35)
4901         {
4902                 msg_print(_("バズーカを発射した。", "You fire your bazooka."));
4903                 fire_ball(GF_MISSILE, dir, creature_ptr->lev * 2, 2);
4904         }
4905         else if (creature_ptr->lev < 45)
4906         {
4907                 msg_print(_("ビームキャノンを発射した。", "You fire a beam cannon."));
4908                 fire_beam(GF_MISSILE, dir, creature_ptr->lev * 2);
4909         }
4910         else
4911         {
4912                 msg_print(_("ロケットを発射した。", "You fire a rocket."));
4913                 fire_rocket(GF_ROCKET, dir, creature_ptr->lev * 5, 2);
4914         }
4915         return TRUE;
4916 }
4917
4918 bool create_ration(player_type *crature_ptr)
4919 {
4920         object_type *q_ptr;
4921         object_type forge;
4922         q_ptr = &forge;
4923
4924         /* Create the food ration */
4925         object_prep(q_ptr, lookup_kind(TV_FOOD, SV_FOOD_RATION));
4926
4927         /* Drop the object from heaven */
4928         (void)drop_near(q_ptr, -1, crature_ptr->y, crature_ptr->x);
4929         msg_print(_("食事を料理して作った。", "You cook some food."));
4930         return TRUE;
4931 }
4932
4933 void hayagake(player_type *creature_ptr)
4934 {
4935         if (creature_ptr->action == ACTION_HAYAGAKE)
4936         {
4937                 set_action(ACTION_NONE);
4938         }
4939         else
4940         {
4941                 grid_type *g_ptr = &current_floor_ptr->grid_array[creature_ptr->y][creature_ptr->x];
4942                 feature_type *f_ptr = &f_info[g_ptr->feat];
4943
4944                 if (!have_flag(f_ptr->flags, FF_PROJECT) ||
4945                         (!creature_ptr->levitation && have_flag(f_ptr->flags, FF_DEEP)))
4946                 {
4947                         msg_print(_("ここでは素早く動けない。", "You cannot run in here."));
4948                 }
4949                 else
4950                 {
4951                         set_action(ACTION_HAYAGAKE);
4952                 }
4953         }
4954         creature_ptr->energy_use = 0;
4955 }
4956
4957 bool double_attack(player_type *creature_ptr)
4958 {
4959         DIRECTION dir;
4960         POSITION x, y;
4961
4962         if (!get_rep_dir(&dir, FALSE)) return FALSE;
4963         y = creature_ptr->y + ddy[dir];
4964         x = creature_ptr->x + ddx[dir];
4965         if (current_floor_ptr->grid_array[y][x].m_idx)
4966         {
4967                 if (one_in_(3))
4968                         msg_print(_("あーたたたたたたたたたたたたたたたたたたたたたた!!!",
4969                                 "Ahhhtatatatatatatatatatatatatatataatatatatattaaaaa!!!!"));
4970                 else if(one_in_(2))
4971                         msg_print(_("無駄無駄無駄無駄無駄無駄無駄無駄無駄無駄無駄無駄!!!",
4972                                 "Mudamudamudamudamudamudamudamudamudamudamudamudamuda!!!!"));
4973                 else
4974                         msg_print(_("オラオラオラオラオラオラオラオラオラオラオラオラ!!!",
4975                                 "Oraoraoraoraoraoraoraoraoraoraoraoraoraoraoraoraora!!!!"));
4976
4977                 py_attack(y, x, 0);
4978                 if (current_floor_ptr->grid_array[y][x].m_idx)
4979                 {
4980                         handle_stuff();
4981                         py_attack(y, x, 0);
4982                 }
4983                 creature_ptr->energy_need += ENERGY_NEED();
4984         }
4985         else
4986         {
4987                 msg_print(_("その方向にはモンスターはいません。", "You don't see any monster in this direction"));
4988                 msg_print(NULL);
4989         }
4990         return TRUE;
4991 }
4992
4993 bool comvert_hp_to_mp(player_type *creature_ptr)
4994 {
4995         int gain_sp = take_hit(DAMAGE_USELIFE, creature_ptr->lev, _("HPからMPへの無謀な変換", "thoughtless convertion from HP to SP"), -1) / 5;
4996         if (gain_sp)
4997         {
4998                 creature_ptr->csp += gain_sp;
4999                 if (creature_ptr->csp > creature_ptr->msp)
5000                 {
5001                         creature_ptr->csp = creature_ptr->msp;
5002                         creature_ptr->csp_frac = 0;
5003                 }
5004         }
5005         else
5006         {
5007                 msg_print(_("変換に失敗した。", "You failed to convert."));
5008         }
5009         creature_ptr->redraw |= (PR_HP | PR_MANA);
5010         return TRUE;
5011 }
5012
5013 bool comvert_mp_to_hp(player_type *creature_ptr)
5014 {
5015         if (creature_ptr->csp >= creature_ptr->lev / 5)
5016         {
5017                 creature_ptr->csp -= creature_ptr->lev / 5;
5018                 hp_player(creature_ptr->lev);
5019         }
5020         else
5021         {
5022                 msg_print(_("変換に失敗した。", "You failed to convert."));
5023         }
5024         creature_ptr->redraw |= (PR_HP | PR_MANA);
5025         return TRUE;
5026 }
5027
5028 bool demonic_breath(player_type *creature_ptr)
5029 {
5030         DIRECTION dir;
5031         int type = (one_in_(2) ? GF_NETHER : GF_FIRE);
5032         if (!get_aim_dir(&dir)) return FALSE;
5033         stop_mouth();
5034         msg_format(_("あなたは%sのブレスを吐いた。", "You breathe %s."), ((type == GF_NETHER) ? _("地獄", "nether") : _("火炎", "fire")));
5035         fire_breath(type, dir, creature_ptr->lev * 3, (creature_ptr->lev / 15) + 1);
5036         return TRUE;
5037 }
5038
5039 bool mirror_concentration(player_type *creature_ptr)
5040 {
5041         if (total_friends)
5042         {
5043                 msg_print(_("今はペットを操ることに集中していないと。", "You need concentration on the pets now."));
5044                 return FALSE;
5045         }
5046         if (is_mirror_grid(&current_floor_ptr->grid_array[creature_ptr->y][creature_ptr->x]))
5047         {
5048                 msg_print(_("少し頭がハッキリした。", "You feel your head clear a little."));
5049
5050                 creature_ptr->csp += (5 + creature_ptr->lev * creature_ptr->lev / 100);
5051                 if (creature_ptr->csp >= creature_ptr->msp)
5052                 {
5053                         creature_ptr->csp = creature_ptr->msp;
5054                         creature_ptr->csp_frac = 0;
5055                 }
5056                 creature_ptr->redraw |= (PR_MANA);
5057         }
5058         else
5059         {
5060                 msg_print(_("鏡の上でないと集中できない!", "Here are not any mirrors!"));
5061         }
5062         return TRUE;
5063 }
5064
5065 bool sword_dancing(player_type *creature_ptr)
5066 {
5067         DIRECTION dir;
5068         POSITION y = 0, x = 0;
5069         int i;
5070         grid_type *g_ptr;
5071
5072         for (i = 0; i < 6; i++)
5073         {
5074                 dir = randint0(8);
5075                 y = creature_ptr->y + ddy_ddd[dir];
5076                 x = creature_ptr->x + ddx_ddd[dir];
5077                 g_ptr = &current_floor_ptr->grid_array[y][x];
5078
5079                 /* Hack -- attack monsters */
5080                 if (g_ptr->m_idx)
5081                         py_attack(y, x, 0);
5082                 else
5083                 {
5084                         msg_print(_("攻撃が空をきった。", "You attack the empty air."));
5085                 }
5086         }
5087         return TRUE;
5088 }
5089
5090 bool confusing_light(player_type *creature_ptr)
5091 {
5092         msg_print(_("辺りを睨んだ...", "You glare nearby monsters..."));
5093         slow_monsters(creature_ptr->lev);
5094         stun_monsters(creature_ptr->lev * 4);
5095         confuse_monsters(creature_ptr->lev * 4);
5096         turn_monsters(creature_ptr->lev * 4);
5097         stasis_monsters(creature_ptr->lev * 4);
5098         return TRUE;
5099 }
5100
5101 bool rodeo(player_type *creature_ptr)
5102 {
5103         GAME_TEXT m_name[MAX_NLEN];
5104         monster_type *m_ptr;
5105         monster_race *r_ptr;
5106         int rlev;
5107
5108         if (creature_ptr->riding)
5109         {
5110                 msg_print(_("今は乗馬中だ。", "You ARE riding."));
5111                 return FALSE;
5112         }
5113         if (!do_riding(TRUE)) return TRUE;
5114
5115         m_ptr = &current_floor_ptr->m_list[creature_ptr->riding];
5116         r_ptr = &r_info[m_ptr->r_idx];
5117         monster_desc(m_name, m_ptr, 0);
5118         msg_format(_("%sに乗った。", "You ride on %s."), m_name);
5119
5120         if (is_pet(m_ptr)) return TRUE;
5121
5122         rlev = r_ptr->level;
5123
5124         if (r_ptr->flags1 & RF1_UNIQUE) rlev = rlev * 3 / 2;
5125         if (rlev > 60) rlev = 60 + (rlev - 60) / 2;
5126         if ((randint1(creature_ptr->skill_exp[GINOU_RIDING] / 120 + creature_ptr->lev * 2 / 3) > rlev)
5127                 && one_in_(2) && !creature_ptr->inside_arena && !creature_ptr->inside_battle
5128                 && !(r_ptr->flags7 & (RF7_GUARDIAN)) && !(r_ptr->flags1 & (RF1_QUESTOR))
5129                 && (rlev < creature_ptr->lev * 3 / 2 + randint0(creature_ptr->lev / 5)))
5130         {
5131                 msg_format(_("%sを手なずけた。", "You tame %s."), m_name);
5132                 set_pet(m_ptr);
5133         }
5134         else
5135         {
5136                 msg_format(_("%sに振り落とされた!", "You have thrown off by %s."), m_name);
5137                 rakuba(1, TRUE);
5138                 /* 落馬処理に失敗してもとにかく乗馬解除 */
5139                 creature_ptr->riding = 0;
5140         }
5141         return TRUE;
5142 }
5143
5144 bool clear_mind(player_type *creature_ptr)
5145 {
5146         if (total_friends)
5147         {
5148                 msg_print(_("今はペットを操ることに集中していないと。", "You need concentration on the pets now."));
5149                 return FALSE;
5150         }
5151         msg_print(_("少し頭がハッキリした。", "You feel your head clear a little."));
5152
5153         creature_ptr->csp += (3 + creature_ptr->lev / 20);
5154         if (creature_ptr->csp >= creature_ptr->msp)
5155         {
5156                 creature_ptr->csp = creature_ptr->msp;
5157                 creature_ptr->csp_frac = 0;
5158         }
5159         creature_ptr->redraw |= (PR_MANA);
5160         return TRUE;
5161 }
5162
5163 bool concentration(player_type *creature_ptr)
5164 {
5165         int max_csp = MAX(creature_ptr->msp * 4, creature_ptr->lev * 5 + 5);
5166
5167         if (total_friends)
5168         {
5169                 msg_print(_("今はペットを操ることに集中していないと。", "You need concentration on the pets now."));
5170                 return FALSE;
5171         }
5172         if (creature_ptr->special_defense & KATA_MASK)
5173         {
5174                 msg_print(_("今は構えに集中している。", "You need concentration on your form."));
5175                 return FALSE;
5176         }
5177         msg_print(_("精神を集中して気合いを溜めた。", "You concentrate to charge your power."));
5178
5179         creature_ptr->csp += creature_ptr->msp / 2;
5180         if (creature_ptr->csp >= max_csp)
5181         {
5182                 creature_ptr->csp = max_csp;
5183                 creature_ptr->csp_frac = 0;
5184         }
5185         creature_ptr->redraw |= (PR_MANA);
5186         return TRUE;
5187 }