OSDN Git Service

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