OSDN Git Service

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