OSDN Git Service

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