OSDN Git Service

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