OSDN Git Service

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