OSDN Git Service

[Refactor] #38997 death_ray()、wall_to_mud()、destroy_door()、disarm_trap()、wizard_lock...
[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 floor_ptr 配置するフロアの参照ポインタ
1654  * @param cy Y座標
1655  * @param cx X座標
1656  * @param pass_bold 地形条件を返す関数ポインタ
1657  * @return 該当地形の数
1658  */
1659 static int next_to_open(floor_type *floor_ptr, POSITION cy, POSITION cx, bool (*pass_bold)(floor_type*, POSITION, POSITION))
1660 {
1661         int i;
1662         POSITION y, x;
1663         int len = 0;
1664         int blen = 0;
1665
1666         for (i = 0; i < 16; i++)
1667         {
1668                 y = cy + ddy_cdd[i % 8];
1669                 x = cx + ddx_cdd[i % 8];
1670
1671                 /* Found a wall, break the length */
1672                 if (!pass_bold(floor_ptr, y, x))
1673                 {
1674                         /* Track best length */
1675                         if (len > blen)
1676                         {
1677                                 blen = len;
1678                         }
1679
1680                         len = 0;
1681                 }
1682                 else
1683                 {
1684                         len++;
1685                 }
1686         }
1687
1688         return (MAX(len, blen));
1689 }
1690
1691
1692 /*!
1693  * @brief 周辺に関数ポインタの条件に該当する地形がいくつあるかを計算する / Determine how much contiguous open space this grid is next to
1694  * @param floor_ptr 配置するフロアの参照ポインタ
1695  * @param cy Y座標
1696  * @param cx X座標
1697  * @param pass_bold 地形条件を返す関数ポインタ
1698  * @return 該当地形の数
1699  */
1700 static int next_to_walls_adj(floor_type *floor_ptr, POSITION cy, POSITION cx, bool (*pass_bold)(floor_type*, POSITION, POSITION))
1701 {
1702         DIRECTION i;
1703         POSITION y, x;
1704         int c = 0;
1705
1706         for (i = 0; i < 8; i++)
1707         {
1708                 y = cy + ddy_ddd[i];
1709                 x = cx + ddx_ddd[i];
1710
1711                 if (!pass_bold(floor_ptr, y, x)) c++;
1712         }
1713
1714         return c;
1715 }
1716
1717
1718 /*!
1719  * @brief 部屋内にある一点の周囲に該当する地形数かいくつあるかをグローバル変数tmp_pos.nに返す / Aux function -- see below
1720  * @param caster_ptr プレーヤーへの参照ポインタ
1721  * @param y 部屋内のy座標1点
1722  * @param x 部屋内のx座標1点
1723  * @param only_room 部屋内地形のみをチェック対象にするならば TRUE
1724  * @param pass_bold 地形条件を返す関数ポインタ
1725  * @return 該当地形の数
1726  */
1727 static void cave_temp_room_aux(player_type *caster_ptr, POSITION y, POSITION x, bool only_room, bool (*pass_bold)(floor_type*, POSITION, POSITION))
1728 {
1729         grid_type *g_ptr;
1730         floor_type *floor_ptr = caster_ptr->current_floor_ptr;
1731         g_ptr = &floor_ptr->grid_array[y][x];
1732
1733         /* Avoid infinite recursion */
1734         if (g_ptr->info & (CAVE_TEMP)) return;
1735
1736         /* Do not "leave" the current room */
1737         if (!(g_ptr->info & (CAVE_ROOM)))
1738         {
1739                 if (only_room) return;
1740
1741                 /* Verify */
1742                 if (!in_bounds2(floor_ptr, y, x)) return;
1743
1744                 /* Do not exceed the maximum spell range */
1745                 if (distance(caster_ptr->y, caster_ptr->x, y, x) > MAX_RANGE) return;
1746
1747                 /* Verify this grid */
1748                 /*
1749                  * The reason why it is ==6 instead of >5 is that 8 is impossible
1750                  * due to the check for cave_bold above.
1751                  * 7 lights dead-end corridors (you need to do this for the
1752                  * checkboard interesting rooms, so that the boundary is lit
1753                  * properly.
1754                  * This leaves only a check for 6 bounding walls!
1755                  */
1756                 if (in_bounds(floor_ptr, y, x) && pass_bold(floor_ptr, y, x) &&
1757                     (next_to_walls_adj(floor_ptr, y, x, pass_bold) == 6) && (next_to_open(floor_ptr, y, x, pass_bold) <= 1)) return;
1758         }
1759
1760         /* Paranoia -- verify space */
1761         if (tmp_pos.n == TEMP_MAX) return;
1762
1763         /* Mark the grid as "seen" */
1764         g_ptr->info |= (CAVE_TEMP);
1765
1766         /* Add it to the "seen" set */
1767         tmp_pos.y[tmp_pos.n] = y;
1768         tmp_pos.x[tmp_pos.n] = x;
1769         tmp_pos.n++;
1770 }
1771
1772
1773 /*!
1774  * todo このシンタックスシュガーは不要だが、関数ポインタなので安易には消せず……
1775  * @brief 指定のマスが光を通すか(LOSフラグを持つか)を返す。 / Aux function -- see below
1776  * @param floor_ptr 配置するフロアの参照ポインタ
1777  * @param y 指定Y座標
1778  * @param x 指定X座標
1779  * @return 光を通すならばtrueを返す。
1780  */
1781 static bool cave_pass_lite_bold(floor_type *floor_ptr, POSITION y, POSITION x)
1782 {
1783         return cave_los_bold(floor_ptr, y, x);
1784 }
1785
1786
1787 /*!
1788  * @brief 部屋内にある一点の周囲がいくつ光を通すかをグローバル変数tmp_pos.nに返す / Aux function -- see below
1789 * @param caster_ptr プレーヤーへの参照ポインタ
1790   * @param y 指定Y座標
1791  * @param x 指定X座標
1792  * @return なし
1793  */
1794 static void cave_temp_lite_room_aux(player_type *caster_ptr, POSITION y, POSITION x)
1795 {
1796         cave_temp_room_aux(caster_ptr, y, x, FALSE, cave_pass_lite_bold);
1797 }
1798
1799
1800 /*!
1801  * @brief 指定のマスが光を通さず射線のみを通すかを返す。 / Aux function -- see below
1802  * @param floor_ptr 配置するフロアの参照ポインタ
1803  * @param y 指定Y座標
1804  * @param x 指定X座標
1805  * @return 射線を通すならばtrueを返す。
1806  */
1807 static bool cave_pass_dark_bold(floor_type *floor_ptr, POSITION y, POSITION x)
1808 {
1809         return cave_have_flag_bold(floor_ptr, y, x, FF_PROJECT);
1810 }
1811
1812
1813 /*!
1814  * @brief 部屋内にある一点の周囲がいくつ射線を通すかをグローバル変数tmp_pos.nに返す / Aux function -- see below
1815  * @param caster_ptr プレーヤーへの参照ポインタ
1816  * @param y 指定Y座標
1817  * @param x 指定X座標
1818  * @return なし
1819  */
1820 static void cave_temp_unlite_room_aux(player_type *caster_ptr, POSITION y, POSITION x)
1821 {
1822         cave_temp_room_aux(caster_ptr, y, x, TRUE, cave_pass_dark_bold);
1823 }
1824
1825
1826 /*!
1827  * @brief 指定された部屋内を照らす / Illuminate any room containing the given location.
1828  * @param caster_ptr プレーヤーへの参照ポインタ
1829  * @param y1 指定Y座標
1830  * @param x1 指定X座標
1831  * @return なし
1832  */
1833 void lite_room(player_type *caster_ptr, POSITION y1, POSITION x1)
1834 {
1835         int i;
1836         POSITION x, y;
1837
1838         /* Add the initial grid */
1839         cave_temp_lite_room_aux(caster_ptr, y1, x1);
1840
1841         /* While grids are in the queue, add their neighbors */
1842         floor_type *floor_ptr = caster_ptr->current_floor_ptr;
1843         for (i = 0; i < tmp_pos.n; i++)
1844         {
1845                 x = tmp_pos.x[i], y = tmp_pos.y[i];
1846
1847                 /* Walls get lit, but stop light */
1848                 if (!cave_pass_lite_bold(floor_ptr, y, x)) continue;
1849
1850                 /* Spread adjacent */
1851                 cave_temp_lite_room_aux(caster_ptr, y + 1, x);
1852                 cave_temp_lite_room_aux(caster_ptr, y - 1, x);
1853                 cave_temp_lite_room_aux(caster_ptr, y, x + 1);
1854                 cave_temp_lite_room_aux(caster_ptr, y, x - 1);
1855
1856                 /* Spread diagonal */
1857                 cave_temp_lite_room_aux(caster_ptr, y + 1, x + 1);
1858                 cave_temp_lite_room_aux(caster_ptr, y - 1, x - 1);
1859                 cave_temp_lite_room_aux(caster_ptr, y - 1, x + 1);
1860                 cave_temp_lite_room_aux(caster_ptr, y + 1, x - 1);
1861         }
1862
1863         /* Now, lite them all up at once */
1864         cave_temp_room_lite(caster_ptr);
1865
1866         if (caster_ptr->special_defense & NINJA_S_STEALTH)
1867         {
1868                 if (floor_ptr->grid_array[caster_ptr->y][caster_ptr->x].info & CAVE_GLOW) set_superstealth(caster_ptr, FALSE);
1869         }
1870 }
1871
1872
1873 /*!
1874  * @brief 指定された部屋内を暗くする / Darken all rooms containing the given location
1875  * @param caster_ptr プレーヤーへの参照ポインタ
1876  * @param y1 指定Y座標
1877  * @param x1 指定X座標
1878  * @return なし
1879  */
1880 void unlite_room(player_type *caster_ptr, POSITION y1, POSITION x1)
1881 {
1882         int i;
1883         POSITION x, y;
1884
1885         /* Add the initial grid */
1886         cave_temp_unlite_room_aux(caster_ptr, y1, x1);
1887
1888         /* Spread, breadth first */
1889         for (i = 0; i < tmp_pos.n; i++)
1890         {
1891                 x = tmp_pos.x[i], y = tmp_pos.y[i];
1892
1893                 /* Walls get dark, but stop darkness */
1894                 if (!cave_pass_dark_bold(caster_ptr->current_floor_ptr, y, x)) continue;
1895
1896                 /* Spread adjacent */
1897                 cave_temp_unlite_room_aux(caster_ptr, y + 1, x);
1898                 cave_temp_unlite_room_aux(caster_ptr, y - 1, x);
1899                 cave_temp_unlite_room_aux(caster_ptr, y, x + 1);
1900                 cave_temp_unlite_room_aux(caster_ptr, y, x - 1);
1901
1902                 /* Spread diagonal */
1903                 cave_temp_unlite_room_aux(caster_ptr, y + 1, x + 1);
1904                 cave_temp_unlite_room_aux(caster_ptr, y - 1, x - 1);
1905                 cave_temp_unlite_room_aux(caster_ptr, y - 1, x + 1);
1906                 cave_temp_unlite_room_aux(caster_ptr, y + 1, x - 1);
1907         }
1908
1909         /* Now, darken them all at once */
1910         cave_temp_room_unlite(caster_ptr);
1911 }
1912
1913
1914 /*!
1915  * @brief スターライトの効果を発生させる
1916  * @param caster_ptr プレーヤーへの参照ポインタ
1917  * @param magic 魔法による効果であればTRUE、スターライトの杖による効果であればFALSE
1918  * @return 常にTRUE
1919  */
1920 bool starlight(player_type *caster_ptr, bool magic)
1921 {
1922         HIT_POINT num = damroll(5, 3);
1923         POSITION y = 0, x = 0;
1924         int k;
1925         int attempts;
1926
1927         if (!caster_ptr->blind && !magic)
1928         {
1929                 msg_print(_("杖の先が明るく輝いた...", "The end of the staff glows brightly..."));
1930         }
1931
1932         for (k = 0; k < num; k++)
1933         {
1934                 attempts = 1000;
1935
1936                 while (attempts--)
1937                 {
1938                         scatter(&y, &x, caster_ptr->y, caster_ptr->x, 4, PROJECT_LOS);
1939                         if (!cave_have_flag_bold(caster_ptr->current_floor_ptr, y, x, FF_PROJECT)) continue;
1940                         if (!player_bold(caster_ptr, y, x)) break;
1941                 }
1942
1943                 project(caster_ptr, 0, 0, y, x, damroll(6 + caster_ptr->lev / 8, 10), GF_LITE_WEAK,
1944                         (PROJECT_BEAM | PROJECT_THRU | PROJECT_GRID | PROJECT_KILL | PROJECT_LOS), -1);
1945         }
1946
1947         return TRUE;
1948 }
1949
1950
1951 /*!
1952  * @brief プレイヤー位置を中心にLITE_WEAK属性を通じた照明処理を行う / Hack -- call light around the player Affect all monsters in the projection radius
1953  * @param caster_ptr プレーヤーへの参照ポインタ
1954  * @param dam 威力
1955  * @param rad 効果半径
1956  * @return 作用が実際にあった場合TRUEを返す
1957  */
1958 bool lite_area(player_type *caster_ptr, HIT_POINT dam, POSITION rad)
1959 {
1960         BIT_FLAGS flg = PROJECT_GRID | PROJECT_KILL;
1961
1962         if (d_info[caster_ptr->dungeon_idx].flags1 & DF1_DARKNESS)
1963         {
1964                 msg_print(_("ダンジョンが光を吸収した。", "The darkness of this dungeon absorb your light."));
1965                 return FALSE;
1966         }
1967
1968         if (!caster_ptr->blind)
1969         {
1970                 msg_print(_("白い光が辺りを覆った。", "You are surrounded by a white light."));
1971         }
1972
1973         /* Hook into the "project()" function */
1974         (void)project(caster_ptr, 0, rad, caster_ptr->y, caster_ptr->x, dam, GF_LITE_WEAK, flg, -1);
1975
1976         lite_room(caster_ptr, caster_ptr->y, caster_ptr->x);
1977
1978         /* Assume seen */
1979         return (TRUE);
1980 }
1981
1982
1983 /*!
1984  * @brief プレイヤー位置を中心にLITE_DARK属性を通じた消灯処理を行う / Hack -- call light around the player Affect all monsters in the projection radius
1985  * @param caster_ptr プレーヤーへの参照ポインタ
1986  * @param dam 威力
1987  * @param rad 効果半径
1988  * @return 作用が実際にあった場合TRUEを返す
1989  */
1990 bool unlite_area(player_type *caster_ptr, HIT_POINT dam, POSITION rad)
1991 {
1992         BIT_FLAGS flg = PROJECT_GRID | PROJECT_KILL;
1993
1994         if (!caster_ptr->blind)
1995         {
1996                 msg_print(_("暗闇が辺りを覆った。", "Darkness surrounds you."));
1997         }
1998
1999         /* Hook into the "project()" function */
2000         (void)project(caster_ptr, 0, rad, caster_ptr->y, caster_ptr->x, dam, GF_DARK_WEAK, flg, -1);
2001
2002         unlite_room(caster_ptr, caster_ptr->y, caster_ptr->x);
2003
2004         /* Assume seen */
2005         return (TRUE);
2006 }
2007
2008
2009 /*!
2010  * @brief ボール系スペルの発動 / Cast a ball spell
2011  * @param caster_ptr プレーヤーへの参照ポインタ
2012  * @param typ 効果属性
2013  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
2014  * @param dam 威力
2015  * @param rad 半径
2016  * @return 作用が実際にあった場合TRUEを返す
2017  * @details
2018  * <pre>
2019  * Stop if we hit a monster, act as a "ball"
2020  * Allow "target" mode to pass over monsters
2021  * Affect grids, objects, and monsters
2022  * </pre>
2023  */
2024 bool fire_ball(player_type *caster_ptr, EFFECT_ID typ, DIRECTION dir, HIT_POINT dam, POSITION rad)
2025 {
2026         POSITION tx, ty;
2027
2028         BIT_FLAGS flg = PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL;
2029
2030         if (typ == GF_CHARM_LIVING) flg|= PROJECT_HIDE;
2031         /* Use the given direction */
2032         tx = caster_ptr->x + 99 * ddx[dir];
2033         ty = caster_ptr->y + 99 * ddy[dir];
2034
2035         /* Hack -- Use an actual "target" */
2036         if ((dir == 5) && target_okay())
2037         {
2038                 flg &= ~(PROJECT_STOP);
2039                 tx = target_col;
2040                 ty = target_row;
2041         }
2042
2043         /* Analyze the "dir" and the "target".  Hurt items on floor. */
2044         return (project(caster_ptr, 0, rad, ty, tx, dam, typ, flg, -1));
2045 }
2046
2047
2048 /*!
2049 * @brief ブレス系スペルの発動 / Cast a breath spell
2050 * @param caster_ptr プレーヤーへの参照ポインタ
2051 * @param typ 効果属性
2052 * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
2053 * @param dam 威力
2054 * @param rad 半径
2055 * @return 作用が実際にあった場合TRUEを返す
2056 * @details
2057 * <pre>
2058 * Stop if we hit a monster, act as a "ball"
2059 * Allow "target" mode to pass over monsters
2060 * Affect grids, objects, and monsters
2061 * </pre>
2062 */
2063 bool fire_breath(player_type *caster_ptr, EFFECT_ID typ, DIRECTION dir, HIT_POINT dam, POSITION rad)
2064 {
2065         return fire_ball(caster_ptr, typ, dir, dam, -rad);
2066 }
2067
2068
2069 /*!
2070  * @brief ロケット系スペルの発動(詳細な差は確認中) / Cast a ball spell
2071  * @param caster_ptr プレーヤーへの参照ポインタ
2072  * @param typ 効果属性
2073  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
2074  * @param dam 威力
2075  * @param rad 半径
2076  * @return 作用が実際にあった場合TRUEを返す
2077  * @details
2078  * <pre>
2079  * Stop if we hit a monster, act as a "ball"
2080  * Allow "target" mode to pass over monsters
2081  * Affect grids, objects, and monsters
2082  * </pre>
2083  */
2084 bool fire_rocket(player_type *caster_ptr, EFFECT_ID typ, DIRECTION dir, HIT_POINT dam, POSITION rad)
2085 {
2086         POSITION tx, ty;
2087         BIT_FLAGS flg = PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL;
2088
2089         /* Use the given direction */
2090         tx = caster_ptr->x + 99 * ddx[dir];
2091         ty = caster_ptr->y + 99 * ddy[dir];
2092
2093         /* Hack -- Use an actual "target" */
2094         if ((dir == 5) && target_okay())
2095         {
2096                 tx = target_col;
2097                 ty = target_row;
2098         }
2099
2100         /* Analyze the "dir" and the "target".  Hurt items on floor. */
2101         return (project(caster_ptr, 0, rad, ty, tx, dam, typ, flg, -1));
2102 }
2103
2104
2105 /*!
2106  * @brief ボール(ハイド)系スペルの発動 / Cast a ball spell
2107  * @param caster_ptr プレーヤーへの参照ポインタ
2108  * @param typ 効果属性
2109  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
2110  * @param dam 威力
2111  * @param rad 半径
2112  * @return 作用が実際にあった場合TRUEを返す
2113  * @details
2114  * <pre>
2115  * Stop if we hit a monster, act as a "ball"
2116  * Allow "target" mode to pass over monsters
2117  * Affect grids, objects, and monsters
2118  * </pre>
2119  */
2120 bool fire_ball_hide(player_type *caster_ptr, EFFECT_ID typ, DIRECTION dir, HIT_POINT dam, POSITION rad)
2121 {
2122         POSITION tx, ty;
2123         BIT_FLAGS flg = PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL | PROJECT_HIDE;
2124
2125         /* Use the given direction */
2126         tx = caster_ptr->x + 99 * ddx[dir];
2127         ty = caster_ptr->y + 99 * ddy[dir];
2128
2129         /* Hack -- Use an actual "target" */
2130         if ((dir == 5) && target_okay())
2131         {
2132                 flg &= ~(PROJECT_STOP);
2133                 tx = target_col;
2134                 ty = target_row;
2135         }
2136
2137         /* Analyze the "dir" and the "target".  Hurt items on floor. */
2138         return (project(caster_ptr, 0, rad, ty, tx, dam, typ, flg, -1));
2139 }
2140
2141
2142 /*!
2143  * @brief メテオ系スペルの発動 / Cast a meteor spell
2144  * @param caster_ptr プレーヤーへの参照ポインタ
2145  * @param who スぺル詠唱者のモンスターID(0=プレイヤー)
2146  * @param typ 効果属性
2147  * @param dam 威力
2148  * @param rad 半径
2149  * @param y 中心点Y座標
2150  * @param x 中心点X座標
2151  * @return 作用が実際にあった場合TRUEを返す
2152  * @details
2153  * <pre>
2154  * Cast a meteor spell, defined as a ball spell cast by an arbitary monster, 
2155  * player, or outside source, that starts out at an arbitrary location, and 
2156  * leaving no trail from the "caster" to the target.  This function is 
2157  * especially useful for bombardments and similar. -LM-
2158  * Option to hurt the player.
2159  * </pre>
2160  */
2161 bool fire_meteor(player_type *caster_ptr, MONSTER_IDX who, EFFECT_ID typ, POSITION y, POSITION x, HIT_POINT dam, POSITION rad)
2162 {
2163         BIT_FLAGS flg = PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL;
2164
2165         /* Analyze the "target" and the caster. */
2166         return (project(caster_ptr, who, rad, y, x, dam, typ, flg, -1));
2167 }
2168
2169
2170 /*!
2171  * @brief ブラスト系スペルの発動 / Cast a blast spell
2172  * @param caster_ptr プレーヤーへの参照ポインタ
2173  * @param typ 効果属性
2174  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
2175  * @param dd 威力ダイス数
2176  * @param ds 威力ダイス目
2177  * @param num 基本回数
2178  * @param dev 回数分散
2179  * @return 作用が実際にあった場合TRUEを返す
2180  */
2181 bool fire_blast(player_type *caster_ptr, EFFECT_ID typ, DIRECTION dir, DICE_NUMBER dd, DICE_SID ds, int num, int dev)
2182 {
2183         POSITION ly, lx;
2184         int ld;
2185         POSITION ty, tx, y, x;
2186         int i;
2187
2188         BIT_FLAGS flg = PROJECT_FAST | PROJECT_THRU | PROJECT_STOP | PROJECT_KILL | PROJECT_REFLECTABLE | PROJECT_GRID;
2189
2190         /* Assume okay */
2191         bool result = TRUE;
2192
2193         /* Use the given direction */
2194         if (dir != 5)
2195         {
2196                 ly = ty = caster_ptr->y + 20 * ddy[dir];
2197                 lx = tx = caster_ptr->x + 20 * ddx[dir];
2198         }
2199
2200         /* Use an actual "target" */
2201         else /* if (dir == 5) */
2202         {
2203                 tx = target_col;
2204                 ty = target_row;
2205
2206                 lx = 20 * (tx - caster_ptr->x) + caster_ptr->x;
2207                 ly = 20 * (ty - caster_ptr->y) + caster_ptr->y;
2208         }
2209
2210         ld = distance(caster_ptr->y, caster_ptr->x, ly, lx);
2211
2212         /* Blast */
2213         for (i = 0; i < num; i++)
2214         {
2215                 while (1)
2216                 {
2217                         /* Get targets for some bolts */
2218                         y = rand_spread(ly, ld * dev / 20);
2219                         x = rand_spread(lx, ld * dev / 20);
2220
2221                         if (distance(ly, lx, y, x) <= ld * dev / 20) break;
2222                 }
2223
2224                 /* Analyze the "dir" and the "target". */
2225                 if (!project(caster_ptr, 0, 0, y, x, damroll(dd, ds), typ, flg, -1))
2226                 {
2227                         result = FALSE;
2228                 }
2229         }
2230
2231         return (result);
2232 }
2233
2234
2235 /*!
2236  * @brief モンスターとの位置交換処理 / Switch position with a monster.
2237  * @param caster_ptr プレーヤーへの参照ポインタ
2238  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
2239  * @return 作用が実際にあった場合TRUEを返す
2240  */
2241 bool teleport_swap(player_type *caster_ptr, DIRECTION dir)
2242 {
2243         POSITION tx, ty;
2244         grid_type* g_ptr;
2245         monster_type* m_ptr;
2246         monster_race* r_ptr;
2247
2248         if ((dir == 5) && target_okay())
2249         {
2250                 tx = target_col;
2251                 ty = target_row;
2252         }
2253         else
2254         {
2255                 tx = caster_ptr->x + ddx[dir];
2256                 ty = caster_ptr->y + ddy[dir];
2257         }
2258         g_ptr = &caster_ptr->current_floor_ptr->grid_array[ty][tx];
2259
2260         if (caster_ptr->anti_tele)
2261         {
2262                 msg_print(_("不思議な力がテレポートを防いだ!", "A mysterious force prevents you from teleporting!"));
2263                 return FALSE;
2264         }
2265
2266         if (!g_ptr->m_idx || (g_ptr->m_idx == caster_ptr->riding))
2267         {
2268                 msg_print(_("それとは場所を交換できません。", "You can't trade places with that!"));
2269                 return FALSE;
2270         }
2271
2272         if ((g_ptr->info & CAVE_ICKY) || (distance(ty, tx, caster_ptr->y, caster_ptr->x) > caster_ptr->lev * 3 / 2 + 10))
2273         {
2274                 msg_print(_("失敗した。", "Failed to swap."));
2275                 return FALSE;
2276         }
2277
2278         m_ptr = &caster_ptr->current_floor_ptr->m_list[g_ptr->m_idx];
2279         r_ptr = &r_info[m_ptr->r_idx];
2280
2281         (void)set_monster_csleep(g_ptr->m_idx, 0);
2282
2283         if (r_ptr->flagsr & RFR_RES_TELE)
2284         {
2285                 msg_print(_("テレポートを邪魔された!", "Your teleportation is blocked!"));
2286                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= RFR_RES_TELE;
2287                 return FALSE;
2288         }
2289
2290         sound(SOUND_TELEPORT);
2291
2292         /* Swap the player and monster */
2293         (void)move_player_effect(caster_ptr, ty, tx, MPE_FORGET_FLOW | MPE_HANDLE_STUFF | MPE_DONT_PICKUP);
2294
2295         /* Success */
2296         return TRUE;
2297 }
2298
2299
2300 /*!
2301  * @brief 指定方向に飛び道具を飛ばす(フラグ任意指定) / Hack -- apply a "project()" in a direction (or at the target)
2302  * @param caster_ptr プレーヤーへの参照ポインタ
2303  * @param typ 効果属性
2304  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
2305  * @param dam 威力
2306  * @param flg フラグ
2307  * @return 作用が実際にあった場合TRUEを返す
2308  */
2309 bool project_hook(player_type *caster_ptr, EFFECT_ID typ, DIRECTION dir, HIT_POINT dam, BIT_FLAGS flg)
2310 {
2311         POSITION tx, ty;
2312
2313         /* Pass through the target if needed */
2314         flg |= (PROJECT_THRU);
2315
2316         /* Use the given direction */
2317         tx = caster_ptr->x + ddx[dir];
2318         ty = caster_ptr->y + ddy[dir];
2319
2320         /* Hack -- Use an actual "target" */
2321         if ((dir == 5) && target_okay())
2322         {
2323                 tx = target_col;
2324                 ty = target_row;
2325         }
2326
2327         /* Analyze the "dir" and the "target", do NOT explode */
2328         return (project(caster_ptr, 0, 0, ty, tx, dam, typ, flg, -1));
2329 }
2330
2331
2332 /*!
2333  * @brief ボルト系スペルの発動 / Cast a bolt spell.
2334  * @param caster_ptr プレーヤーへの参照ポインタ
2335  * @param typ 効果属性
2336  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
2337  * @param dam 威力
2338  * @return 作用が実際にあった場合TRUEを返す
2339  * @details
2340  * <pre>
2341  * Stop if we hit a monster, as a "bolt".
2342  * Affect monsters and grids (not objects).
2343  * </pre>
2344  */
2345 bool fire_bolt(player_type *caster_ptr, EFFECT_ID typ, DIRECTION dir, HIT_POINT dam)
2346 {
2347         BIT_FLAGS flg = PROJECT_STOP | PROJECT_KILL | PROJECT_GRID;
2348         if (typ != GF_ARROW) flg |= PROJECT_REFLECTABLE;
2349         return (project_hook(caster_ptr, typ, dir, dam, flg));
2350 }
2351
2352
2353 /*!
2354  * @brief ビーム系スペルの発動 / Cast a beam spell.
2355  * @param caster_ptr プレーヤーへの参照ポインタ
2356  * @param typ 効果属性
2357  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
2358  * @param dam 威力
2359  * @return 作用が実際にあった場合TRUEを返す
2360  * @details
2361  * <pre>
2362  * Pass through monsters, as a "beam".
2363  * Affect monsters, grids and objects.
2364  * </pre>
2365  */
2366 bool fire_beam(player_type *caster_ptr, EFFECT_ID typ, DIRECTION dir, HIT_POINT dam)
2367 {
2368         BIT_FLAGS flg = PROJECT_BEAM | PROJECT_KILL | PROJECT_GRID | PROJECT_ITEM;
2369         return (project_hook(caster_ptr, typ, dir, dam, flg));
2370 }
2371
2372
2373 /*!
2374  * @brief 確率に応じたボルト系/ビーム系スペルの発動 / Cast a bolt spell, or rarely, a beam spell.
2375  * @param caster_ptr プレーヤーへの参照ポインタ
2376  * @param prob ビーム化する確率(%)
2377  * @param typ 効果属性
2378  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
2379  * @param dam 威力
2380  * @return 作用が実際にあった場合TRUEを返す
2381  * @details
2382  * <pre>
2383  * Pass through monsters, as a "beam".
2384  * Affect monsters, grids and objects.
2385  * </pre>
2386  */
2387 bool fire_bolt_or_beam(player_type *caster_ptr, PERCENTAGE prob, EFFECT_ID typ, DIRECTION dir, HIT_POINT dam)
2388 {
2389         if (randint0(100) < prob)
2390         {
2391                 return (fire_beam(caster_ptr, typ, dir, dam));
2392         }
2393         else
2394         {
2395                 return (fire_bolt(caster_ptr, typ, dir, dam));
2396         }
2397 }
2398
2399
2400 /*!
2401  * @brief LITE_WEAK属性による光源ビーム処理
2402  * @param caster_ptr プレーヤーへの参照ポインタ
2403  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
2404  * @param dam 威力
2405  * @return 作用が実際にあった場合TRUEを返す
2406  */
2407 bool lite_line(player_type *caster_ptr, DIRECTION dir, HIT_POINT dam)
2408 {
2409         BIT_FLAGS flg = PROJECT_BEAM | PROJECT_GRID | PROJECT_KILL;
2410         return (project_hook(caster_ptr, GF_LITE_WEAK, dir, dam, flg));
2411 }
2412
2413
2414 /*!
2415  * @brief 衰弱ボルト処理
2416  * @param caster_ptr プレーヤーへの参照ポインタ
2417  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
2418  * @param dam 威力
2419  * @return 作用が実際にあった場合TRUEを返す
2420  */
2421 bool hypodynamic_bolt(player_type *caster_ptr, DIRECTION dir, HIT_POINT dam)
2422 {
2423         BIT_FLAGS flg = PROJECT_STOP | PROJECT_KILL | PROJECT_REFLECTABLE;
2424         return (project_hook(caster_ptr, GF_HYPODYNAMIA, dir, dam, flg));
2425 }
2426
2427
2428 /*!
2429  * @brief 岩石溶解処理
2430  * @param caster_ptr プレーヤーへの参照ポインタ
2431  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
2432  * @param dam 威力
2433  * @return 作用が実際にあった場合TRUEを返す
2434  */
2435 bool wall_to_mud(player_type *caster_ptr, DIRECTION dir, HIT_POINT dam)
2436 {
2437         BIT_FLAGS flg = PROJECT_BEAM | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL;
2438         return (project_hook(caster_ptr, GF_KILL_WALL, dir, dam, flg));
2439 }
2440
2441
2442 /*!
2443  * @brief 魔法の施錠処理
2444  * @param caster_ptr プレーヤーへの参照ポインタ
2445  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
2446  * @return 作用が実際にあった場合TRUEを返す
2447  */
2448 bool wizard_lock(player_type *caster_ptr, DIRECTION dir)
2449 {
2450         BIT_FLAGS flg = PROJECT_BEAM | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL;
2451         return (project_hook(caster_ptr, GF_JAM_DOOR, dir, 20 + randint1(30), flg));
2452 }
2453
2454
2455 /*!
2456  * @brief ドア破壊処理
2457  * @param caster_ptr プレーヤーへの参照ポインタ
2458  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
2459  * @return 作用が実際にあった場合TRUEを返す
2460  */
2461 bool destroy_door(player_type *caster_ptr, DIRECTION dir)
2462 {
2463         BIT_FLAGS flg = PROJECT_BEAM | PROJECT_GRID | PROJECT_ITEM;
2464         return (project_hook(caster_ptr, GF_KILL_DOOR, dir, 0, flg));
2465 }
2466
2467
2468 /*!
2469  * @brief トラップ解除処理
2470  * @param caster_ptr プレーヤーへの参照ポインタ
2471  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
2472  * @return 作用が実際にあった場合TRUEを返す
2473  */
2474 bool disarm_trap(player_type *caster_ptr, DIRECTION dir)
2475 {
2476         BIT_FLAGS flg = PROJECT_BEAM | PROJECT_GRID | PROJECT_ITEM;
2477         return (project_hook(caster_ptr, GF_KILL_TRAP, dir, 0, flg));
2478 }
2479
2480
2481 /*!
2482  * @brief 死の光線処理
2483  * @param caster_ptr プレーヤーへの参照ポインタ
2484  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
2485  * @param plev プレイヤーレベル(効力はplev*200)
2486  * @return 作用が実際にあった場合TRUEを返す
2487  */
2488 bool death_ray(player_type *caster_ptr, DIRECTION dir, PLAYER_LEVEL plev)
2489 {
2490         BIT_FLAGS flg = PROJECT_STOP | PROJECT_KILL | PROJECT_REFLECTABLE;
2491         return (project_hook(caster_ptr, GF_DEATH_RAY, dir, plev * 200, flg));
2492 }
2493
2494
2495 /*!
2496  * @brief モンスター用テレポート処理
2497  * @param caster_ptr プレーヤーへの参照ポインタ
2498  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
2499  * @param distance 移動距離
2500  * @return 作用が実際にあった場合TRUEを返す
2501  */
2502 bool teleport_monster(player_type *caster_ptr, DIRECTION dir, int distance)
2503 {
2504         BIT_FLAGS flg = PROJECT_BEAM | PROJECT_KILL;
2505         return (project_hook(caster_ptr, GF_AWAY_ALL, dir, distance, flg));
2506 }
2507
2508
2509 /*!
2510  * @brief ドア生成処理(プレイヤー中心に周囲1マス) / Hooks -- affect adjacent grids (radius 1 ball attack)
2511  * @param caster_ptr プレーヤーへの参照ポインタ
2512  * @return 作用が実際にあった場合TRUEを返す
2513  */
2514 bool door_creation(player_type *caster_ptr, POSITION y, POSITION x)
2515 {
2516         BIT_FLAGS flg = PROJECT_GRID | PROJECT_ITEM | PROJECT_HIDE;
2517         return (project(caster_ptr, 0, 1, y, x, 0, GF_MAKE_DOOR, flg, -1));
2518 }
2519
2520
2521 /*!
2522  * @brief トラップ生成処理(起点から周囲1マス)
2523  * @param caster_ptr プレーヤーへの参照ポインタ
2524  * @param y 起点Y座標
2525  * @param x 起点X座標
2526  * @return 作用が実際にあった場合TRUEを返す
2527  */
2528 bool trap_creation(player_type *caster_ptr, POSITION y, POSITION x)
2529 {
2530         BIT_FLAGS flg = PROJECT_GRID | PROJECT_ITEM | PROJECT_HIDE;
2531         return (project(caster_ptr, 0, 1, y, x, 0, GF_MAKE_TRAP, flg, -1));
2532 }
2533
2534
2535 /*!
2536  * @brief 森林生成処理(プレイヤー中心に周囲1マス)
2537  * @param caster_ptr プレーヤーへの参照ポインタ
2538  * @return 作用が実際にあった場合TRUEを返す
2539  */
2540 bool tree_creation(player_type *caster_ptr, POSITION y, POSITION x)
2541 {
2542         BIT_FLAGS flg = PROJECT_GRID | PROJECT_ITEM | PROJECT_HIDE;
2543         return (project(caster_ptr, 0, 1, y, x, 0, GF_MAKE_TREE, flg, -1));
2544 }
2545
2546
2547 /*!
2548  * @brief 魔法のルーン生成処理(プレイヤー中心に周囲1マス)
2549  * @param caster_ptr プレーヤーへの参照ポインタ
2550  * @return 作用が実際にあった場合TRUEを返す
2551  */
2552 bool glyph_creation(player_type *caster_ptr, POSITION y, POSITION x)
2553 {
2554         BIT_FLAGS flg = PROJECT_GRID | PROJECT_ITEM;
2555         return (project(caster_ptr, 0, 1, y, x, 0, GF_MAKE_GLYPH, flg, -1));
2556 }
2557
2558
2559 /*!
2560  * @brief 壁生成処理(プレイヤー中心に周囲1マス)
2561  * @param caster_ptr プレーヤーへの参照ポインタ
2562  * @return 作用が実際にあった場合TRUEを返す
2563  */
2564 bool wall_stone(void)
2565 {
2566         BIT_FLAGS flg = PROJECT_GRID | PROJECT_ITEM | PROJECT_HIDE;
2567         bool dummy = (project(p_ptr, 0, 1, p_ptr->y, p_ptr->x, 0, GF_STONE_WALL, flg, -1));
2568         p_ptr->update |= (PU_FLOW);
2569         p_ptr->redraw |= (PR_MAP);
2570         return dummy;
2571 }
2572
2573
2574 /*!
2575  * @brief ドア破壊処理(プレイヤー中心に周囲1マス)
2576  * @param caster_ptr プレーヤーへの参照ポインタ
2577  * @return 作用が実際にあった場合TRUEを返す
2578  */
2579 bool destroy_doors_touch(void)
2580 {
2581         BIT_FLAGS flg = PROJECT_GRID | PROJECT_ITEM | PROJECT_HIDE;
2582         return (project(p_ptr, 0, 1, p_ptr->y, p_ptr->x, 0, GF_KILL_DOOR, flg, -1));
2583 }
2584
2585
2586 /*!
2587  * @brief トラップ解除処理(プレイヤー中心に周囲1マス)
2588  * @param caster_ptr プレーヤーへの参照ポインタ
2589  * @return 作用が実際にあった場合TRUEを返す
2590  */
2591 bool disarm_traps_touch(void)
2592 {
2593         BIT_FLAGS flg = PROJECT_GRID | PROJECT_ITEM | PROJECT_HIDE;
2594         return (project(p_ptr, 0, 1, p_ptr->y, p_ptr->x, 0, GF_KILL_TRAP, flg, -1));
2595 }
2596
2597
2598 /*!
2599  * @brief スリープモンスター処理(プレイヤー中心に周囲1マス)
2600  * @param caster_ptr プレーヤーへの参照ポインタ
2601  * @return 作用が実際にあった場合TRUEを返す
2602  */
2603 bool sleep_monsters_touch(void)
2604 {
2605         BIT_FLAGS flg = PROJECT_KILL | PROJECT_HIDE;
2606         return (project(p_ptr, 0, 1, p_ptr->y, p_ptr->x, p_ptr->lev, GF_OLD_SLEEP, flg, -1));
2607 }
2608
2609
2610 /*!
2611  * @brief 死者復活処理(起点より周囲5マス)
2612  * @param caster_ptr プレーヤーへの参照ポインタ
2613  * @param who 術者モンスターID(0ならばプレイヤー)
2614  * @param y 起点Y座標
2615  * @param x 起点X座標
2616  * @return 作用が実際にあった場合TRUEを返す
2617  */
2618 bool animate_dead(MONSTER_IDX who, POSITION y, POSITION x)
2619 {
2620         BIT_FLAGS flg = PROJECT_ITEM | PROJECT_HIDE;
2621         return (project(p_ptr, who, 5, y, x, 0, GF_ANIM_DEAD, flg, -1));
2622 }
2623
2624
2625 /*!
2626  * @brief 混沌招来処理
2627  * @return 作用が実際にあった場合TRUEを返す
2628  */
2629 void call_chaos(player_type *caster_ptr)
2630 {
2631         int Chaos_type, dummy, dir;
2632         PLAYER_LEVEL plev = caster_ptr->lev;
2633         bool line_chaos = FALSE;
2634
2635         int hurt_types[31] =
2636         {
2637                 GF_ELEC,      GF_POIS,    GF_ACID,    GF_COLD,
2638                 GF_FIRE,      GF_MISSILE, GF_ARROW,   GF_PLASMA,
2639                 GF_HOLY_FIRE, GF_WATER,   GF_LITE,    GF_DARK,
2640                 GF_FORCE,     GF_INERTIAL, GF_MANA,    GF_METEOR,
2641                 GF_ICE,       GF_CHAOS,   GF_NETHER,  GF_DISENCHANT,
2642                 GF_SHARDS,    GF_SOUND,   GF_NEXUS,   GF_CONFUSION,
2643                 GF_TIME,      GF_GRAVITY, GF_ROCKET,  GF_NUKE,
2644                 GF_HELL_FIRE, GF_DISINTEGRATE, GF_PSY_SPEAR
2645         };
2646
2647         Chaos_type = hurt_types[randint0(31)];
2648         if (one_in_(4)) line_chaos = TRUE;
2649
2650         if (one_in_(6))
2651         {
2652                 for (dummy = 1; dummy < 10; dummy++)
2653                 {
2654                         if (dummy - 5)
2655                         {
2656                                 if (line_chaos)
2657                                         fire_beam(caster_ptr, Chaos_type, dummy, 150);
2658                                 else
2659                                         fire_ball(caster_ptr, Chaos_type, dummy, 150, 2);
2660                         }
2661                 }
2662         }
2663         else if (one_in_(3))
2664         {
2665                 fire_ball(caster_ptr, Chaos_type, 0, 500, 8);
2666         }
2667         else
2668         {
2669                 if (!get_aim_dir(&dir)) return;
2670                 if (line_chaos)
2671                         fire_beam(caster_ptr, Chaos_type, dir, 250);
2672                 else
2673                         fire_ball(caster_ptr, Chaos_type, dir, 250, 3 + (plev / 35));
2674         }
2675 }
2676
2677
2678 /*!
2679  * @brief TY_CURSE処理発動 / Activate the evil Topi Ylinen curse
2680  * @param target_ptr プレーヤーへの参照ポインタ
2681  * @param stop_ty 再帰処理停止フラグ
2682  * @param count 発動回数
2683  * @return 作用が実際にあった場合TRUEを返す
2684  * @details
2685  * <pre>
2686  * rr9: Stop the nasty things when a Cyberdemon is summoned
2687  * or the player gets paralyzed.
2688  * </pre>
2689  */
2690 bool activate_ty_curse(player_type *target_ptr, bool stop_ty, int *count)
2691 {
2692         BIT_FLAGS flg = (PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL | PROJECT_JUMP);
2693
2694         bool is_first_curse = TRUE;
2695         while (is_first_curse || one_in_(3) && !stop_ty)
2696         {
2697                 is_first_curse = FALSE;
2698                 switch (randint1(34))
2699                 {
2700                 case 28: case 29:
2701                         if (!(*count))
2702                         {
2703                                 msg_print(_("地面が揺れた...", "The ground trembles..."));
2704                                 earthquake(target_ptr, target_ptr->y, target_ptr->x, 5 + randint0(10), 0);
2705                                 if (!one_in_(6)) break;
2706                         }
2707                 case 30: case 31:
2708                         if (!(*count))
2709                         {
2710                                 HIT_POINT dam = damroll(10, 10);
2711                                 msg_print(_("純粋な魔力の次元への扉が開いた!", "A portal opens to a plane of raw mana!"));
2712                                 project(target_ptr, 0, 8, target_ptr->y, target_ptr->x, dam, GF_MANA, flg, -1);
2713                                 take_hit(target_ptr, DAMAGE_NOESCAPE, dam, _("純粋な魔力の解放", "released pure mana"), -1);
2714                                 if (!one_in_(6)) break;
2715                         }
2716                 case 32: case 33:
2717                         if (!(*count))
2718                         {
2719                                 msg_print(_("周囲の空間が歪んだ!", "Space warps about you!"));
2720                                 teleport_player(target_ptr, damroll(10, 10), TELEPORT_PASSIVE);
2721                                 if (randint0(13)) (*count) += activate_hi_summon(target_ptr->y, target_ptr->x, FALSE);
2722                                 if (!one_in_(6)) break;
2723                         }
2724                 case 34:
2725                         msg_print(_("エネルギーのうねりを感じた!", "You feel a surge of energy!"));
2726                         wall_breaker(target_ptr);
2727                         if (!randint0(7))
2728                         {
2729                                 project(target_ptr, 0, 7, target_ptr->y, target_ptr->x, 50, GF_KILL_WALL, flg, -1);
2730                                 take_hit(target_ptr, DAMAGE_NOESCAPE, 50, _("エネルギーのうねり", "surge of energy"), -1);
2731                         }
2732
2733                         if (!one_in_(6)) break;
2734                 case 1: case 2: case 3: case 16: case 17:
2735                         aggravate_monsters(target_ptr, 0);
2736                         if (!one_in_(6)) break;
2737                 case 4: case 5: case 6:
2738                         (*count) += activate_hi_summon(target_ptr->y, target_ptr->x, FALSE);
2739                         if (!one_in_(6)) break;
2740                 case 7: case 8: case 9: case 18:
2741                         (*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));
2742                         if (!one_in_(6)) break;
2743                 case 10: case 11: case 12:
2744                         msg_print(_("経験値が体から吸い取られた気がする!", "You feel your experience draining away..."));
2745                         lose_exp(target_ptr, target_ptr->exp / 16);
2746                         if (!one_in_(6)) break;
2747                 case 13: case 14: case 15: case 19: case 20:
2748                         if (stop_ty || (target_ptr->free_act && (randint1(125) < target_ptr->skill_sav)) || (target_ptr->pclass == CLASS_BERSERKER))
2749                         {
2750                                 /* Do nothing */ ;
2751                         }
2752                         else
2753                         {
2754                                 msg_print(_("彫像になった気分だ!", "You feel like a statue!"));
2755                                 if (target_ptr->free_act)
2756                                         set_paralyzed(target_ptr, target_ptr->paralyzed + randint1(3));
2757                                 else
2758                                         set_paralyzed(target_ptr, target_ptr->paralyzed + randint1(13));
2759                                 stop_ty = TRUE;
2760                         }
2761
2762                         if (!one_in_(6)) break;
2763                 case 21: case 22: case 23:
2764                         (void)do_dec_stat(target_ptr, randint0(6));
2765                         if (!one_in_(6)) break;
2766                 case 24:
2767                         msg_print(_("ほえ?私は誰?ここで何してる?", "Huh? Who am I? What am I doing here?"));
2768                         lose_all_info(target_ptr);
2769                         if (!one_in_(6)) break;
2770                 case 25:
2771                         /*
2772                          * Only summon Cyberdemons deep in the dungeon.
2773                          */
2774                         if ((target_ptr->current_floor_ptr->dun_level > 65) && !stop_ty)
2775                         {
2776                                 (*count) += summon_cyber(-1, target_ptr->y, target_ptr->x);
2777                                 stop_ty = TRUE;
2778                                 break;
2779                         }
2780
2781                         if (!one_in_(6)) break;
2782                 default:
2783                         for (int i = 0; i < A_MAX; i++)
2784                         {
2785                                 bool is_first_dec_stat = TRUE;
2786                                 while (is_first_dec_stat || one_in_(2))
2787                                 {
2788                                         is_first_dec_stat = FALSE;
2789                                         (void)do_dec_stat(target_ptr, i);
2790                                 }
2791                         }
2792                 }
2793         }
2794
2795         return stop_ty;
2796 }
2797
2798
2799 /*!
2800  * @brief HI_SUMMON(上級召喚)処理発動
2801  * @param caster_ptr プレーヤーへの参照ポインタ
2802  * @param y 召喚位置Y座標
2803  * @param x 召喚位置X座標
2804  * @param can_pet プレイヤーのペットとなる可能性があるならばTRUEにする
2805  * @return 作用が実際にあった場合TRUEを返す
2806  */
2807 int activate_hi_summon(POSITION y, POSITION x, bool can_pet)
2808 {
2809         int i;
2810         int count = 0;
2811         DEPTH summon_lev;
2812         BIT_FLAGS mode = PM_ALLOW_GROUP;
2813         bool pet = FALSE;
2814
2815         if (can_pet)
2816         {
2817                 if (one_in_(4))
2818                 {
2819                         mode |= PM_FORCE_FRIENDLY;
2820                 }
2821                 else
2822                 {
2823                         mode |= PM_FORCE_PET;
2824                         pet = TRUE;
2825                 }
2826         }
2827
2828         if (!pet) mode |= PM_NO_PET;
2829
2830         summon_lev = (pet ? p_ptr->lev * 2 / 3 + randint1(p_ptr->lev / 2) : p_ptr->current_floor_ptr->dun_level);
2831
2832         for (i = 0; i < (randint1(7) + (p_ptr->current_floor_ptr->dun_level / 40)); i++)
2833         {
2834                 switch (randint1(25) + (p_ptr->current_floor_ptr->dun_level / 20))
2835                 {
2836                         case 1: case 2:
2837                                 count += summon_specific((pet ? -1 : 0), y, x, summon_lev, SUMMON_ANT, mode);
2838                                 break;
2839                         case 3: case 4:
2840                                 count += summon_specific((pet ? -1 : 0), y, x, summon_lev, SUMMON_SPIDER, mode);
2841                                 break;
2842                         case 5: case 6:
2843                                 count += summon_specific((pet ? -1 : 0), y, x, summon_lev, SUMMON_HOUND, mode);
2844                                 break;
2845                         case 7: case 8:
2846                                 count += summon_specific((pet ? -1 : 0), y, x, summon_lev, SUMMON_HYDRA, mode);
2847                                 break;
2848                         case 9: case 10:
2849                                 count += summon_specific((pet ? -1 : 0), y, x, summon_lev, SUMMON_ANGEL, mode);
2850                                 break;
2851                         case 11: case 12:
2852                                 count += summon_specific((pet ? -1 : 0), y, x, summon_lev, SUMMON_UNDEAD, mode);
2853                                 break;
2854                         case 13: case 14:
2855                                 count += summon_specific((pet ? -1 : 0), y, x, summon_lev, SUMMON_DRAGON, mode);
2856                                 break;
2857                         case 15: case 16:
2858                                 count += summon_specific((pet ? -1 : 0), y, x, summon_lev, SUMMON_DEMON, mode);
2859                                 break;
2860                         case 17:
2861                                 if (can_pet) break;
2862                                 count += summon_specific((pet ? -1 : 0), y, x, summon_lev, SUMMON_AMBERITES, (mode | PM_ALLOW_UNIQUE));
2863                                 break;
2864                         case 18: case 19:
2865                                 if (can_pet) break;
2866                                 count += summon_specific((pet ? -1 : 0), y, x, summon_lev, SUMMON_UNIQUE, (mode | PM_ALLOW_UNIQUE));
2867                                 break;
2868                         case 20: case 21:
2869                                 if (!can_pet) mode |= PM_ALLOW_UNIQUE;
2870                                 count += summon_specific((pet ? -1 : 0), y, x, summon_lev, SUMMON_HI_UNDEAD, mode);
2871                                 break;
2872                         case 22: case 23:
2873                                 if (!can_pet) mode |= PM_ALLOW_UNIQUE;
2874                                 count += summon_specific((pet ? -1 : 0), y, x, summon_lev, SUMMON_HI_DRAGON, mode);
2875                                 break;
2876                         case 24:
2877                                 count += summon_specific((pet ? -1 : 0), y, x, 100, SUMMON_CYBER, mode);
2878                                 break;
2879                         default:
2880                                 if (!can_pet) mode |= PM_ALLOW_UNIQUE;
2881                                 count += summon_specific((pet ? -1 : 0), y, x,pet ? summon_lev : (((summon_lev * 3) / 2) + 5), 0, mode);
2882                 }
2883         }
2884
2885         return count;
2886 }
2887
2888
2889 /*!
2890  * @brief 周辺破壊効果(プレイヤー中心)
2891  * @param caster_ptr プレーヤーへの参照ポインタ
2892  * @return 作用が実際にあった場合TRUEを返す
2893  */
2894 void wall_breaker(player_type *caster_ptr)
2895 {
2896         int i;
2897         POSITION y = 0, x = 0;
2898         int attempts = 1000;
2899
2900         if (randint1(80 + caster_ptr->lev) < 70)
2901         {
2902                 while (attempts--)
2903                 {
2904                         scatter(&y, &x, caster_ptr->y, caster_ptr->x, 4, 0);
2905
2906                         if (!cave_have_flag_bold(caster_ptr->current_floor_ptr, y, x, FF_PROJECT)) continue;
2907
2908                         if (!player_bold(caster_ptr, y, x)) break;
2909                 }
2910
2911                 project(caster_ptr, 0, 0, y, x, 20 + randint1(30), GF_KILL_WALL,
2912                                   (PROJECT_BEAM | PROJECT_THRU | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL), -1);
2913         }
2914         else if (randint1(100) > 30)
2915         {
2916                 earthquake(caster_ptr, caster_ptr->y, caster_ptr->x, 1, 0);
2917         }
2918         else
2919         {
2920                 int num = damroll(5, 3);
2921
2922                 for (i = 0; i < num; i++)
2923                 {
2924                         while (1)
2925                         {
2926                                 scatter(&y, &x, caster_ptr->y, caster_ptr->x, 10, 0);
2927
2928                                 if (!player_bold(caster_ptr, y, x)) break;
2929                         }
2930
2931                         project(caster_ptr, 0, 0, y, x, 20 + randint1(30), GF_KILL_WALL,
2932                                           (PROJECT_BEAM | PROJECT_THRU | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL), -1);
2933                 }
2934         }
2935 }
2936
2937
2938 /*!
2939  * @brief パニック・モンスター効果(プレイヤー視界範囲内) / Confuse monsters
2940  * @param caster_ptr プレーヤーへの参照ポインタ
2941  * @param dam 効力
2942  * @return 作用が実際にあった場合TRUEを返す
2943  */
2944 bool confuse_monsters(HIT_POINT dam)
2945 {
2946         return (project_all_los(p_ptr, GF_OLD_CONF, dam));
2947 }
2948
2949
2950 /*!
2951  * @brief チャーム・モンスター効果(プレイヤー視界範囲内) / Charm monsters
2952  * @param caster_ptr プレーヤーへの参照ポインタ
2953  * @param dam 効力
2954  * @return 作用が実際にあった場合TRUEを返す
2955  */
2956 bool charm_monsters(HIT_POINT dam)
2957 {
2958         return (project_all_los(p_ptr, GF_CHARM, dam));
2959 }
2960
2961
2962 /*!
2963  * @brief 動物魅了効果(プレイヤー視界範囲内) / Charm Animals
2964  * @param caster_ptr プレーヤーへの参照ポインタ
2965  * @param dam 効力
2966  * @return 作用が実際にあった場合TRUEを返す
2967  */
2968 bool charm_animals(HIT_POINT dam)
2969 {
2970         return (project_all_los(p_ptr, GF_CONTROL_ANIMAL, dam));
2971 }
2972
2973
2974 /*!
2975  * @brief モンスター朦朧効果(プレイヤー視界範囲内) / Stun monsters
2976  * @param caster_ptr プレーヤーへの参照ポインタ
2977  * @param dam 効力
2978  * @return 作用が実際にあった場合TRUEを返す
2979  */
2980 bool stun_monsters(HIT_POINT dam)
2981 {
2982         return (project_all_los(p_ptr, GF_STUN, dam));
2983 }
2984
2985
2986 /*!
2987  * @brief モンスター停止効果(プレイヤー視界範囲内) / Stasis monsters
2988  * @param caster_ptr プレーヤーへの参照ポインタ
2989  * @param dam 効力
2990  * @return 作用が実際にあった場合TRUEを返す
2991  */
2992 bool stasis_monsters(HIT_POINT dam)
2993 {
2994         return (project_all_los(p_ptr, GF_STASIS, dam));
2995 }
2996
2997
2998 /*!
2999  * @brief モンスター精神攻撃効果(プレイヤー視界範囲内) / Mindblast monsters
3000  * @param caster_ptr プレーヤーへの参照ポインタ
3001  * @param dam 効力
3002  * @return 作用が実際にあった場合TRUEを返す
3003  */
3004 bool mindblast_monsters(HIT_POINT dam)
3005 {
3006         return (project_all_los(p_ptr, GF_PSI, dam));
3007 }
3008
3009
3010 /*!
3011  * @brief モンスター追放効果(プレイヤー視界範囲内) / Banish all monsters
3012  * @param caster_ptr プレーヤーへの参照ポインタ
3013  * @param dist 効力(距離)
3014  * @return 作用が実際にあった場合TRUEを返す
3015  */
3016 bool banish_monsters(int dist)
3017 {
3018         return (project_all_los(p_ptr, GF_AWAY_ALL, dist));
3019 }
3020
3021
3022 /*!
3023  * @brief 邪悪退散効果(プレイヤー視界範囲内) / Turn evil
3024  * @param caster_ptr プレーヤーへの参照ポインタ
3025  * @param dam 効力
3026  * @return 作用が実際にあった場合TRUEを返す
3027  */
3028 bool turn_evil(HIT_POINT dam)
3029 {
3030         return (project_all_los(p_ptr, GF_TURN_EVIL, dam));
3031 }
3032
3033
3034 /*!
3035  * @brief 全モンスター退散効果(プレイヤー視界範囲内) / Turn everyone
3036  * @param caster_ptr プレーヤーへの参照ポインタ
3037  * @param dam 効力
3038  * @return 作用が実際にあった場合TRUEを返す
3039  */
3040 bool turn_monsters(HIT_POINT dam)
3041 {
3042         return (project_all_los(p_ptr, GF_TURN_ALL, dam));
3043 }
3044
3045
3046 /*!
3047  * @brief 死の光線(プレイヤー視界範囲内) / Death-ray all monsters (note: OBSCENELY powerful)
3048  * @param caster_ptr プレーヤーへの参照ポインタ
3049  * @return 作用が実際にあった場合TRUEを返す
3050  */
3051 bool deathray_monsters(void)
3052 {
3053         return (project_all_los(p_ptr, GF_DEATH_RAY, p_ptr->lev * 200));
3054 }
3055
3056
3057 /*!
3058  * @brief チャーム・モンスター(1体)
3059  * @param caster_ptr プレーヤーへの参照ポインタ
3060  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
3061  * @param plev パワー
3062  * @return 作用が実際にあった場合TRUEを返す
3063  */
3064 bool charm_monster(DIRECTION dir, PLAYER_LEVEL plev)
3065 {
3066         BIT_FLAGS flg = PROJECT_STOP | PROJECT_KILL;
3067         return (project_hook(p_ptr, GF_CHARM, dir, plev, flg));
3068 }
3069
3070
3071 /*!
3072  * @brief アンデッド支配(1体)
3073  * @param caster_ptr プレーヤーへの参照ポインタ
3074  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
3075  * @param plev パワー
3076  * @return 作用が実際にあった場合TRUEを返す
3077  */
3078 bool control_one_undead(DIRECTION dir, PLAYER_LEVEL plev)
3079 {
3080         BIT_FLAGS flg = PROJECT_STOP | PROJECT_KILL;
3081         return (project_hook(p_ptr, GF_CONTROL_UNDEAD, dir, plev, flg));
3082 }
3083
3084
3085 /*!
3086  * @brief 悪魔支配(1体)
3087  * @param caster_ptr プレーヤーへの参照ポインタ
3088  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
3089  * @param plev パワー
3090  * @return 作用が実際にあった場合TRUEを返す
3091  */
3092 bool control_one_demon(DIRECTION dir, PLAYER_LEVEL plev)
3093 {
3094         BIT_FLAGS flg = PROJECT_STOP | PROJECT_KILL;
3095         return (project_hook(p_ptr, GF_CONTROL_DEMON, dir, plev, flg));
3096 }
3097
3098
3099 /*!
3100  * @brief 動物支配(1体)
3101  * @param caster_ptr プレーヤーへの参照ポインタ
3102  * @param dir 方向(5ならばグローバル変数 target_col/target_row の座標を目標にする)
3103  * @param plev パワー
3104  * @return 作用が実際にあった場合TRUEを返す
3105  */
3106 bool charm_animal(DIRECTION dir, PLAYER_LEVEL plev)
3107 {
3108         BIT_FLAGS flg = PROJECT_STOP | PROJECT_KILL;
3109         return (project_hook(p_ptr, GF_CONTROL_ANIMAL, dir, plev, flg));
3110 }
3111
3112
3113 /*!
3114  * @brief 変わり身処理
3115  * @param caster_ptr プレーヤーへの参照ポインタ
3116  * @param success 判定成功上の処理ならばTRUE
3117  * @return 作用が実際にあった場合TRUEを返す
3118  */
3119 bool kawarimi(player_type *caster_ptr, bool success)
3120 {
3121         object_type forge;
3122         object_type *q_ptr = &forge;
3123         POSITION y, x;
3124
3125         if (caster_ptr->is_dead) return FALSE;
3126         if (caster_ptr->confused || caster_ptr->blind || caster_ptr->paralyzed || caster_ptr->image) return FALSE;
3127         if (randint0(200) < caster_ptr->stun) return FALSE;
3128
3129         if (!success && one_in_(3))
3130         {
3131                 msg_print(_("失敗!逃げられなかった。", "Failed! You couldn't run away."));
3132                 caster_ptr->special_defense &= ~(NINJA_KAWARIMI);
3133                 caster_ptr->redraw |= (PR_STATUS);
3134                 return FALSE;
3135         }
3136
3137         y = caster_ptr->y;
3138         x = caster_ptr->x;
3139
3140         teleport_player(caster_ptr, 10 + randint1(90), 0L);
3141         object_wipe(q_ptr);
3142         object_prep(q_ptr, lookup_kind(TV_STATUE, SV_WOODEN_STATUE));
3143
3144         q_ptr->pval = MON_NINJA;
3145         (void)drop_near(q_ptr, -1, y, x);
3146
3147         if (success) msg_print(_("攻撃を受ける前に素早く身をひるがえした。", "You have turned around just before the attack hit you."));
3148         else msg_print(_("失敗!攻撃を受けてしまった。", "Failed! You are hit by the attack."));
3149
3150         caster_ptr->special_defense &= ~(NINJA_KAWARIMI);
3151         caster_ptr->redraw |= (PR_STATUS);
3152
3153         /* Teleported */
3154         return TRUE;
3155 }
3156
3157
3158 /*!
3159  * @brief 入身処理 / "Rush Attack" routine for Samurai or Ninja
3160  * @param caster_ptr プレーヤーへの参照ポインタ
3161  * @param mdeath 目標モンスターが死亡したかを返す
3162  * @return 作用が実際にあった場合TRUEを返す /  Return value is for checking "done"
3163  */
3164 bool rush_attack(player_type *attacker_ptr, bool *mdeath)
3165 {
3166         DIRECTION dir;
3167         int tx, ty;
3168         int tm_idx = 0;
3169         u16b path_g[32];
3170         int path_n, i;
3171         bool tmp_mdeath = FALSE;
3172         bool moved = FALSE;
3173
3174         if (mdeath) *mdeath = FALSE;
3175
3176         project_length = 5;
3177         if (!get_aim_dir(&dir)) return FALSE;
3178
3179         /* Use the given direction */
3180         tx = attacker_ptr->x + project_length * ddx[dir];
3181         ty = attacker_ptr->y + project_length * ddy[dir];
3182
3183         /* Hack -- Use an actual "target" */
3184         if ((dir == 5) && target_okay())
3185         {
3186                 tx = target_col;
3187                 ty = target_row;
3188         }
3189
3190         if (in_bounds(attacker_ptr->current_floor_ptr, ty, tx)) tm_idx = attacker_ptr->current_floor_ptr->grid_array[ty][tx].m_idx;
3191
3192         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);
3193         project_length = 0;
3194
3195         /* No need to move */
3196         if (!path_n) return TRUE;
3197
3198         /* Use ty and tx as to-move point */
3199         ty = attacker_ptr->y;
3200         tx = attacker_ptr->x;
3201
3202         /* Project along the path */
3203         for (i = 0; i < path_n; i++)
3204         {
3205                 monster_type *m_ptr;
3206
3207                 int ny = GRID_Y(path_g[i]);
3208                 int nx = GRID_X(path_g[i]);
3209
3210                 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))
3211                 {
3212                         ty = ny;
3213                         tx = nx;
3214
3215                         /* Go to next grid */
3216                         continue;
3217                 }
3218
3219                 if (!attacker_ptr->current_floor_ptr->grid_array[ny][nx].m_idx)
3220                 {
3221                         if (tm_idx)
3222                         {
3223                                 msg_print(_("失敗!", "Failed!"));
3224                         }
3225                         else
3226                         {
3227                                 msg_print(_("ここには入身では入れない。", "You can't move to that place."));
3228                         }
3229
3230                         /* Exit loop */
3231                         break;
3232                 }
3233
3234                 /* Move player before updating the monster */
3235                 if (!player_bold(attacker_ptr, ty, tx)) teleport_player_to(attacker_ptr, ty, tx, TELEPORT_NONMAGICAL);
3236                 update_monster(attacker_ptr, attacker_ptr->current_floor_ptr->grid_array[ny][nx].m_idx, TRUE);
3237
3238                 /* Found a monster */
3239                 m_ptr = &attacker_ptr->current_floor_ptr->m_list[attacker_ptr->current_floor_ptr->grid_array[ny][nx].m_idx];
3240
3241                 if (tm_idx != attacker_ptr->current_floor_ptr->grid_array[ny][nx].m_idx)
3242                 {
3243 #ifdef JP
3244                         msg_format("%s%sが立ちふさがっている!", tm_idx ? "別の" : "", m_ptr->ml ? "モンスター" : "何か");
3245 #else
3246                         msg_format("There is %s in the way!", m_ptr->ml ? (tm_idx ? "another monster" : "a monster") : "someone");
3247 #endif
3248                 }
3249                 else if (!player_bold(attacker_ptr, ty, tx))
3250                 {
3251                         /* Hold the monster name */
3252                         GAME_TEXT m_name[MAX_NLEN];
3253
3254                         /* Get the monster name (BEFORE polymorphing) */
3255                         monster_desc(m_name, m_ptr, 0);
3256                         msg_format(_("素早く%sの懐に入り込んだ!", "You quickly jump in and attack %s!"), m_name);
3257                 }
3258
3259                 if (!player_bold(attacker_ptr, ty, tx)) teleport_player_to(attacker_ptr, ty, tx, TELEPORT_NONMAGICAL);
3260                 moved = TRUE;
3261                 tmp_mdeath = py_attack(attacker_ptr, ny, nx, HISSATSU_NYUSIN);
3262
3263                 break;
3264         }
3265
3266         if (!moved && !player_bold(attacker_ptr, ty, tx)) teleport_player_to(attacker_ptr, ty, tx, TELEPORT_NONMAGICAL);
3267
3268         if (mdeath) *mdeath = tmp_mdeath;
3269         return TRUE;
3270 }
3271
3272
3273 /*!
3274  * @brief 全鏡の消去 / Remove all mirrors in this floor
3275  * @param caster_ptr プレーヤーへの参照ポインタ
3276  * @param explode 爆発処理を伴うならばTRUE
3277  * @return なし
3278  */
3279 void remove_all_mirrors(player_type *caster_ptr, bool explode)
3280 {
3281         POSITION x, y;
3282
3283         for (x = 0; x < caster_ptr->current_floor_ptr->width; x++)
3284         {
3285                 for (y = 0; y < caster_ptr->current_floor_ptr->height; y++)
3286                 {
3287                         if (is_mirror_grid(&caster_ptr->current_floor_ptr->grid_array[y][x]))
3288                         {
3289                                 remove_mirror(caster_ptr, y, x);
3290                                 if (explode)
3291                                         project(caster_ptr, 0, 2, y, x, caster_ptr->lev / 2 + 5, GF_SHARDS,
3292                                                 (PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL | PROJECT_JUMP | PROJECT_NO_HANGEKI), -1);
3293                         }
3294                 }
3295         }
3296 }
3297
3298
3299 /*!
3300  * @brief 『一つの指輪』の効果処理 /
3301  * Hack -- activate the ring of power
3302  * @param caster_ptr プレーヤーへの参照ポインタ
3303  * @param dir 発動の方向ID
3304  * @return なし
3305  */
3306 void ring_of_power(player_type *caster_ptr, DIRECTION dir)
3307 {
3308         /* Pick a random effect */
3309         switch (randint1(10))
3310         {
3311         case 1:
3312         case 2:
3313         {
3314                 msg_print(_("あなたは悪性のオーラに包み込まれた。", "You are surrounded by a malignant aura."));
3315                 sound(SOUND_EVIL);
3316
3317                 /* Decrease all stats (permanently) */
3318                 (void)dec_stat(caster_ptr, A_STR, 50, TRUE);
3319                 (void)dec_stat(caster_ptr, A_INT, 50, TRUE);
3320                 (void)dec_stat(caster_ptr, A_WIS, 50, TRUE);
3321                 (void)dec_stat(caster_ptr, A_DEX, 50, TRUE);
3322                 (void)dec_stat(caster_ptr, A_CON, 50, TRUE);
3323                 (void)dec_stat(caster_ptr, A_CHR, 50, TRUE);
3324
3325                 /* Lose some experience (permanently) */
3326                 caster_ptr->exp -= (caster_ptr->exp / 4);
3327                 caster_ptr->max_exp -= (caster_ptr->exp / 4);
3328                 check_experience(caster_ptr);
3329
3330                 break;
3331         }
3332
3333         case 3:
3334         {
3335                 msg_print(_("あなたは強力なオーラに包み込まれた。", "You are surrounded by a powerful aura."));
3336                 dispel_monsters(caster_ptr, 1000);
3337                 break;
3338         }
3339
3340         case 4:
3341         case 5:
3342         case 6:
3343         {
3344                 fire_ball(caster_ptr, GF_MANA, dir, 600, 3);
3345                 break;
3346         }
3347
3348         case 7:
3349         case 8:
3350         case 9:
3351         case 10:
3352         {
3353                 fire_bolt(caster_ptr, GF_MANA, dir, 500);
3354                 break;
3355         }
3356         }
3357 }
3358
3359
3360 /*!
3361 * @brief 運命の輪、並びにカオス的な効果の発動
3362 * @param caster_ptr プレーヤーへの参照ポインタ
3363 * @param spell ランダムな効果を選択するための基準ID
3364 * @return なし
3365 */
3366 void wild_magic(player_type *caster_ptr, int spell)
3367 {
3368         int counter = 0;
3369         int type = SUMMON_MOLD + randint0(6);
3370
3371         if (type < SUMMON_MOLD) type = SUMMON_MOLD;
3372         else if (type > SUMMON_MIMIC) type = SUMMON_MIMIC;
3373
3374         switch (randint1(spell) + randint1(8) + 1)
3375         {
3376         case 1:
3377         case 2:
3378         case 3:
3379                 teleport_player(caster_ptr, 10, TELEPORT_PASSIVE);
3380                 break;
3381         case 4:
3382         case 5:
3383         case 6:
3384                 teleport_player(caster_ptr, 100, TELEPORT_PASSIVE);
3385                 break;
3386         case 7:
3387         case 8:
3388                 teleport_player(caster_ptr, 200, TELEPORT_PASSIVE);
3389                 break;
3390         case 9:
3391         case 10:
3392         case 11:
3393                 unlite_area(caster_ptr, 10, 3);
3394                 break;
3395         case 12:
3396         case 13:
3397         case 14:
3398                 lite_area(caster_ptr, damroll(2, 3), 2);
3399                 break;
3400         case 15:
3401                 destroy_doors_touch();
3402                 break;
3403         case 16: case 17:
3404                 wall_breaker(caster_ptr);
3405         case 18:
3406                 sleep_monsters_touch();
3407                 break;
3408         case 19:
3409         case 20:
3410                 trap_creation(caster_ptr, caster_ptr->y, caster_ptr->x);
3411                 break;
3412         case 21:
3413         case 22:
3414                 door_creation(caster_ptr, caster_ptr->y, caster_ptr->x);
3415                 break;
3416         case 23:
3417         case 24:
3418         case 25:
3419                 aggravate_monsters(caster_ptr, 0);
3420                 break;
3421         case 26:
3422                 earthquake(caster_ptr, caster_ptr->y, caster_ptr->x, 5, 0);
3423                 break;
3424         case 27:
3425         case 28:
3426                 (void)gain_mutation(caster_ptr, 0);
3427                 break;
3428         case 29:
3429         case 30:
3430                 apply_disenchant(caster_ptr, 1);
3431                 break;
3432         case 31:
3433                 lose_all_info(caster_ptr);
3434                 break;
3435         case 32:
3436                 fire_ball(caster_ptr, GF_CHAOS, 0, spell + 5, 1 + (spell / 10));
3437                 break;
3438         case 33:
3439                 wall_stone();
3440                 break;
3441         case 34:
3442         case 35:
3443                 while (counter++ < 8)
3444                 {
3445                         (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));
3446                 }
3447                 break;
3448         case 36:
3449         case 37:
3450                 activate_hi_summon(caster_ptr->y, caster_ptr->x, FALSE);
3451                 break;
3452         case 38:
3453                 (void)summon_cyber(-1, caster_ptr->y, caster_ptr->x);
3454                 break;
3455         default:
3456         {
3457                 int count = 0;
3458                 (void)activate_ty_curse(caster_ptr, FALSE, &count);
3459                 break;
3460         }
3461         }
3462 }
3463
3464
3465 /*!
3466 * @brief カオス魔法「流星群」の処理としてプレイヤーを中心に隕石落下処理を10+1d10回繰り返す。
3467 * / Drop 10+1d10 meteor ball at random places near the player
3468 * @param caster_ptr プレーヤーへの参照ポインタ
3469 * @param dam ダメージ
3470 * @param rad 効力の半径
3471 * @return なし
3472 */
3473 void cast_meteor(player_type *caster_ptr, HIT_POINT dam, POSITION rad)
3474 {
3475         int i;
3476         int b = 10 + randint1(10);
3477
3478         for (i = 0; i < b; i++)
3479         {
3480                 POSITION y = 0, x = 0;
3481                 int count;
3482
3483                 for (count = 0; count <= 20; count++)
3484                 {
3485                         int dy, dx, d;
3486
3487                         x = caster_ptr->x - 8 + randint0(17);
3488                         y = caster_ptr->y - 8 + randint0(17);
3489
3490                         dx = (caster_ptr->x > x) ? (caster_ptr->x - x) : (x - caster_ptr->x);
3491                         dy = (caster_ptr->y > y) ? (caster_ptr->y - y) : (y - caster_ptr->y);
3492
3493                         /* Approximate distance */
3494                         d = (dy > dx) ? (dy + (dx >> 1)) : (dx + (dy >> 1));
3495
3496                         if (d >= 9) continue;
3497
3498                         if (!in_bounds(caster_ptr->current_floor_ptr, y, x) || !projectable(caster_ptr->current_floor_ptr, caster_ptr->y, caster_ptr->x, y, x)
3499                                 || !cave_have_flag_bold(caster_ptr->current_floor_ptr, y, x, FF_PROJECT)) continue;
3500
3501                         /* Valid position */
3502                         break;
3503                 }
3504
3505                 if (count > 20) continue;
3506
3507                 project(caster_ptr, 0, rad, y, x, dam, GF_METEOR, PROJECT_KILL | PROJECT_JUMP | PROJECT_ITEM, -1);
3508         }
3509 }
3510
3511
3512 /*!
3513 * @brief 破邪魔法「神の怒り」の処理としてターゲットを指定した後分解のボールを最大20回発生させる。
3514 * @param caster_ptr プレーヤーへの参照ポインタ
3515 * @param dam ダメージ
3516 * @param rad 効力の半径
3517 * @return ターゲットを指定し、実行したならばTRUEを返す。
3518 */
3519 bool cast_wrath_of_the_god(player_type *caster_ptr, HIT_POINT dam, POSITION rad)
3520 {
3521         POSITION x, y, tx, ty;
3522         POSITION nx, ny;
3523         DIRECTION dir;
3524         int i;
3525         int b = 10 + randint1(10);
3526
3527         if (!get_aim_dir(&dir)) return FALSE;
3528
3529         /* Use the given direction */
3530         tx = caster_ptr->x + 99 * ddx[dir];
3531         ty = caster_ptr->y + 99 * ddy[dir];
3532
3533         /* Hack -- Use an actual "target" */
3534         if ((dir == 5) && target_okay())
3535         {
3536                 tx = target_col;
3537                 ty = target_row;
3538         }
3539
3540         x = caster_ptr->x;
3541         y = caster_ptr->y;
3542
3543         while (1)
3544         {
3545                 /* Hack -- Stop at the target */
3546                 if ((y == ty) && (x == tx)) break;
3547
3548                 ny = y;
3549                 nx = x;
3550                 mmove2(&ny, &nx, caster_ptr->y, caster_ptr->x, ty, tx);
3551
3552                 /* Stop at maximum range */
3553                 if (MAX_RANGE <= distance(caster_ptr->y, caster_ptr->x, ny, nx)) break;
3554
3555                 /* Stopped by walls/doors */
3556                 if (!cave_have_flag_bold(caster_ptr->current_floor_ptr, ny, nx, FF_PROJECT)) break;
3557
3558                 /* Stopped by monsters */
3559                 if ((dir != 5) && caster_ptr->current_floor_ptr->grid_array[ny][nx].m_idx != 0) break;
3560
3561                 /* Save the new location */
3562                 x = nx;
3563                 y = ny;
3564         }
3565
3566         tx = x;
3567         ty = y;
3568
3569         for (i = 0; i < b; i++)
3570         {
3571                 int count = 20, d = 0;
3572
3573                 while (count--)
3574                 {
3575                         int dx, dy;
3576
3577                         x = tx - 5 + randint0(11);
3578                         y = ty - 5 + randint0(11);
3579
3580                         dx = (tx > x) ? (tx - x) : (x - tx);
3581                         dy = (ty > y) ? (ty - y) : (y - ty);
3582
3583                         /* Approximate distance */
3584                         d = (dy > dx) ? (dy + (dx >> 1)) : (dx + (dy >> 1));
3585                         /* Within the radius */
3586                         if (d < 5) break;
3587                 }
3588
3589                 if (count < 0) continue;
3590
3591                 /* Cannot penetrate perm walls */
3592                 if (!in_bounds(caster_ptr->current_floor_ptr, y, x) ||
3593                         cave_stop_disintegration(caster_ptr->current_floor_ptr, y, x) ||
3594                         !in_disintegration_range(caster_ptr->current_floor_ptr, ty, tx, y, x))
3595                         continue;
3596
3597                 project(caster_ptr, 0, rad, y, x, dam, GF_DISINTEGRATE, PROJECT_JUMP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL, -1);
3598         }
3599
3600         return TRUE;
3601 }
3602
3603 /*!
3604 * @brief 「ワンダー」のランダムな効果を決定して処理する。
3605 * @param caster_ptr プレーヤーへの参照ポインタ
3606 * @param dir 方向ID
3607 * @return なし
3608 * @details
3609 * This spell should become more useful (more controlled) as the\n
3610 * player gains experience levels.  Thus, add 1/5 of the player's\n
3611 * level to the die roll.  This eliminates the worst effects later on,\n
3612 * while keeping the results quite random.  It also allows some potent\n
3613 * effects only at high level.
3614 */
3615 void cast_wonder(player_type *caster_ptr, DIRECTION dir)
3616 {
3617         PLAYER_LEVEL plev = caster_ptr->lev;
3618         int die = randint1(100) + plev / 5;
3619         int vir = virtue_number(caster_ptr, V_CHANCE);
3620
3621         if (vir)
3622         {
3623                 if (caster_ptr->virtues[vir - 1] > 0)
3624                 {
3625                         while (randint1(400) < caster_ptr->virtues[vir - 1]) die++;
3626                 }
3627                 else
3628                 {
3629                         while (randint1(400) < (0 - caster_ptr->virtues[vir - 1])) die--;
3630                 }
3631         }
3632
3633         if (die < 26)
3634                 chg_virtue(caster_ptr, V_CHANCE, 1);
3635
3636         if (die > 100)
3637         {
3638                 msg_print(_("あなたは力がみなぎるのを感じた!", "You feel a surge of power!"));
3639         }
3640
3641         if (die < 8) clone_monster(dir);
3642         else if (die < 14) speed_monster(dir, plev);
3643         else if (die < 26) heal_monster(dir, damroll(4, 6));
3644         else if (die < 31) poly_monster(dir, plev);
3645         else if (die < 36)
3646                 fire_bolt_or_beam(caster_ptr, beam_chance(caster_ptr) - 10, GF_MISSILE, dir,
3647                         damroll(3 + ((plev - 1) / 5), 4));
3648         else if (die < 41) confuse_monster(dir, plev);
3649         else if (die < 46) fire_ball(caster_ptr, GF_POIS, dir, 20 + (plev / 2), 3);
3650         else if (die < 51) (void)lite_line(caster_ptr, dir, damroll(6, 8));
3651         else if (die < 56)
3652                 fire_bolt_or_beam(caster_ptr, beam_chance(caster_ptr) - 10, GF_ELEC, dir,
3653                         damroll(3 + ((plev - 5) / 4), 8));
3654         else if (die < 61)
3655                 fire_bolt_or_beam(caster_ptr, beam_chance(caster_ptr) - 10, GF_COLD, dir,
3656                         damroll(5 + ((plev - 5) / 4), 8));
3657         else if (die < 66)
3658                 fire_bolt_or_beam(caster_ptr, beam_chance(caster_ptr), GF_ACID, dir,
3659                         damroll(6 + ((plev - 5) / 4), 8));
3660         else if (die < 71)
3661                 fire_bolt_or_beam(caster_ptr, beam_chance(caster_ptr), GF_FIRE, dir,
3662                         damroll(8 + ((plev - 5) / 4), 8));
3663         else if (die < 76) hypodynamic_bolt(caster_ptr, dir, 75);
3664         else if (die < 81) fire_ball(caster_ptr, GF_ELEC, dir, 30 + plev / 2, 2);
3665         else if (die < 86) fire_ball(caster_ptr, GF_ACID, dir, 40 + plev, 2);
3666         else if (die < 91) fire_ball(caster_ptr, GF_ICE, dir, 70 + plev, 3);
3667         else if (die < 96) fire_ball(caster_ptr, GF_FIRE, dir, 80 + plev, 3);
3668         else if (die < 101) hypodynamic_bolt(caster_ptr, dir, 100 + plev);
3669         else if (die < 104)
3670         {
3671                 earthquake(caster_ptr, caster_ptr->y, caster_ptr->x, 12, 0);
3672         }
3673         else if (die < 106)
3674         {
3675                 (void)destroy_area(caster_ptr->current_floor_ptr, caster_ptr->y, caster_ptr->x, 13 + randint0(5), FALSE);
3676         }
3677         else if (die < 108)
3678         {
3679                 symbol_genocide(caster_ptr, plev + 50, TRUE);
3680         }
3681         else if (die < 110)
3682         {
3683                 dispel_monsters(caster_ptr, 120);
3684         }
3685         else /* RARE */
3686         {
3687                 dispel_monsters(caster_ptr, 150);
3688                 slow_monsters(caster_ptr, plev);
3689                 sleep_monsters(caster_ptr, plev);
3690                 hp_player(caster_ptr, 300);
3691         }
3692 }
3693
3694
3695 /*!
3696 * @brief 「悪霊召喚」のランダムな効果を決定して処理する。
3697 * @param caster_ptr プレーヤーへの参照ポインタ
3698 * @param dir 方向ID
3699 * @return なし
3700 */
3701 void cast_invoke_spirits(player_type *caster_ptr, DIRECTION dir)
3702 {
3703         PLAYER_LEVEL plev = caster_ptr->lev;
3704         int die = randint1(100) + plev / 5;
3705         int vir = virtue_number(caster_ptr, V_CHANCE);
3706
3707         if (vir)
3708         {
3709                 if (caster_ptr->virtues[vir - 1] > 0)
3710                 {
3711                         while (randint1(400) < caster_ptr->virtues[vir - 1]) die++;
3712                 }
3713                 else
3714                 {
3715                         while (randint1(400) < (0 - caster_ptr->virtues[vir - 1])) die--;
3716                 }
3717         }
3718
3719         msg_print(_("あなたは死者たちの力を招集した...", "You call on the power of the dead..."));
3720         if (die < 26)
3721                 chg_virtue(caster_ptr, V_CHANCE, 1);
3722
3723         if (die > 100)
3724         {
3725                 msg_print(_("あなたはおどろおどろしい力のうねりを感じた!", "You feel a surge of eldritch force!"));
3726         }
3727
3728         if (die < 8)
3729         {
3730                 msg_print(_("なんてこった!あなたの周りの地面から朽ちた人影が立ち上がってきた!",
3731                         "Oh no! Mouldering forms rise from the earth around you!"));
3732
3733                 (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));
3734                 chg_virtue(caster_ptr, V_UNLIFE, 1);
3735         }
3736         else if (die < 14)
3737         {
3738                 msg_print(_("名状し難い邪悪な存在があなたの心を通り過ぎて行った...", "An unnamable evil brushes against your mind..."));
3739
3740                 set_afraid(caster_ptr, caster_ptr->afraid + randint1(4) + 4);
3741         }
3742         else if (die < 26)
3743         {
3744                 msg_print(_("あなたの頭に大量の幽霊たちの騒々しい声が押し寄せてきた...",
3745                         "Your head is invaded by a horde of gibbering spectral voices..."));
3746
3747                 set_confused(caster_ptr, caster_ptr->confused + randint1(4) + 4);
3748         }
3749         else if (die < 31)
3750         {
3751                 poly_monster(dir, plev);
3752         }
3753         else if (die < 36)
3754         {
3755                 fire_bolt_or_beam(caster_ptr, beam_chance(caster_ptr) - 10, GF_MISSILE, dir,
3756                         damroll(3 + ((plev - 1) / 5), 4));
3757         }
3758         else if (die < 41)
3759         {
3760                 confuse_monster(dir, plev);
3761         }
3762         else if (die < 46)
3763         {
3764                 fire_ball(caster_ptr, GF_POIS, dir, 20 + (plev / 2), 3);
3765         }
3766         else if (die < 51)
3767         {
3768                 (void)lite_line(caster_ptr, dir, damroll(6, 8));
3769         }
3770         else if (die < 56)
3771         {
3772                 fire_bolt_or_beam(caster_ptr, beam_chance(caster_ptr) - 10, GF_ELEC, dir,
3773                         damroll(3 + ((plev - 5) / 4), 8));
3774         }
3775         else if (die < 61)
3776         {
3777                 fire_bolt_or_beam(caster_ptr, beam_chance(caster_ptr) - 10, GF_COLD, dir,
3778                         damroll(5 + ((plev - 5) / 4), 8));
3779         }
3780         else if (die < 66)
3781         {
3782                 fire_bolt_or_beam(caster_ptr, beam_chance(caster_ptr), GF_ACID, dir,
3783                         damroll(6 + ((plev - 5) / 4), 8));
3784         }
3785         else if (die < 71)
3786         {
3787                 fire_bolt_or_beam(caster_ptr, beam_chance(caster_ptr), GF_FIRE, dir,
3788                         damroll(8 + ((plev - 5) / 4), 8));
3789         }
3790         else if (die < 76)
3791         {
3792                 hypodynamic_bolt(caster_ptr, dir, 75);
3793         }
3794         else if (die < 81)
3795         {
3796                 fire_ball(caster_ptr, GF_ELEC, dir, 30 + plev / 2, 2);
3797         }
3798         else if (die < 86)
3799         {
3800                 fire_ball(caster_ptr, GF_ACID, dir, 40 + plev, 2);
3801         }
3802         else if (die < 91)
3803         {
3804                 fire_ball(caster_ptr, GF_ICE, dir, 70 + plev, 3);
3805         }
3806         else if (die < 96)
3807         {
3808                 fire_ball(caster_ptr, GF_FIRE, dir, 80 + plev, 3);
3809         }
3810         else if (die < 101)
3811         {
3812                 hypodynamic_bolt(caster_ptr, dir, 100 + plev);
3813         }
3814         else if (die < 104)
3815         {
3816                 earthquake(caster_ptr, caster_ptr->y, caster_ptr->x, 12, 0);
3817         }
3818         else if (die < 106)
3819         {
3820                 (void)destroy_area(caster_ptr->current_floor_ptr, caster_ptr->y, caster_ptr->x, 13 + randint0(5), FALSE);
3821         }
3822         else if (die < 108)
3823         {
3824                 symbol_genocide(caster_ptr, plev + 50, TRUE);
3825         }
3826         else if (die < 110)
3827         {
3828                 dispel_monsters(caster_ptr, 120);
3829         }
3830         else
3831         { /* RARE */
3832                 dispel_monsters(caster_ptr, 150);
3833                 slow_monsters(caster_ptr, plev);
3834                 sleep_monsters(caster_ptr, plev);
3835                 hp_player(caster_ptr, 300);
3836         }
3837
3838         if (die < 31)
3839         {
3840                 msg_print(_("陰欝な声がクスクス笑う。「もうすぐおまえは我々の仲間になるだろう。弱き者よ。」",
3841                         "Sepulchral voices chuckle. 'Soon you will join us, mortal.'"));
3842         }
3843 }
3844
3845 /*!
3846 * @brief トランプ領域の「シャッフル」の効果をランダムに決めて処理する。
3847 * @param caster_ptr プレーヤーへの参照ポインタ
3848 * @return なし
3849 */
3850 void cast_shuffle(player_type *caster_ptr)
3851 {
3852         PLAYER_LEVEL plev = caster_ptr->lev;
3853         DIRECTION dir;
3854         int die;
3855         int vir = virtue_number(caster_ptr, V_CHANCE);
3856         int i;
3857
3858         /* Card sharks and high mages get a level bonus */
3859         if ((caster_ptr->pclass == CLASS_ROGUE) ||
3860                 (caster_ptr->pclass == CLASS_HIGH_MAGE) ||
3861                 (caster_ptr->pclass == CLASS_SORCERER))
3862                 die = (randint1(110)) + plev / 5;
3863         else
3864                 die = randint1(120);
3865         
3866         if (vir)
3867         {
3868                 if (caster_ptr->virtues[vir - 1] > 0)
3869                 {
3870                         while (randint1(400) < caster_ptr->virtues[vir - 1]) die++;
3871                 }
3872                 else
3873                 {
3874                         while (randint1(400) < (0 - caster_ptr->virtues[vir - 1])) die--;
3875                 }
3876         }
3877
3878         msg_print(_("あなたはカードを切って一枚引いた...", "You shuffle the deck and draw a card..."));
3879
3880         if (die < 30)
3881                 chg_virtue(caster_ptr, V_CHANCE, 1);
3882
3883         if (die < 7)
3884         {
3885                 msg_print(_("なんてこった!《死》だ!", "Oh no! It's Death!"));
3886
3887                 for (i = 0; i < randint1(3); i++)
3888                         activate_hi_summon(caster_ptr->y, caster_ptr->x, FALSE);
3889         }
3890         else if (die < 14)
3891         {
3892                 msg_print(_("なんてこった!《悪魔》だ!", "Oh no! It's the Devil!"));
3893                 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));
3894         }
3895         else if (die < 18)
3896         {
3897                 int count = 0;
3898                 msg_print(_("なんてこった!《吊られた男》だ!", "Oh no! It's the Hanged Man."));
3899                 activate_ty_curse(caster_ptr, FALSE, &count);
3900         }
3901         else if (die < 22)
3902         {
3903                 msg_print(_("《不調和の剣》だ。", "It's the swords of discord."));
3904                 aggravate_monsters(caster_ptr, 0);
3905         }
3906         else if (die < 26)
3907         {
3908                 msg_print(_("《愚者》だ。", "It's the Fool."));
3909                 do_dec_stat(caster_ptr, A_INT);
3910                 do_dec_stat(caster_ptr, A_WIS);
3911         }
3912         else if (die < 30)
3913         {
3914                 msg_print(_("奇妙なモンスターの絵だ。", "It's the picture of a strange monster."));
3915                 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);
3916         }
3917         else if (die < 33)
3918         {
3919                 msg_print(_("《月》だ。", "It's the Moon."));
3920                 unlite_area(caster_ptr, 10, 3);
3921         }
3922         else if (die < 38)
3923         {
3924                 msg_print(_("《運命の輪》だ。", "It's the Wheel of Fortune."));
3925                 wild_magic(caster_ptr, randint0(32));
3926         }
3927         else if (die < 40)
3928         {
3929                 msg_print(_("テレポート・カードだ。", "It's a teleport trump card."));
3930                 teleport_player(caster_ptr, 10, TELEPORT_PASSIVE);
3931         }
3932         else if (die < 42)
3933         {
3934                 msg_print(_("《正義》だ。", "It's Justice."));
3935                 set_blessed(caster_ptr, caster_ptr->lev, FALSE);
3936         }
3937         else if (die < 47)
3938         {
3939                 msg_print(_("テレポート・カードだ。", "It's a teleport trump card."));
3940                 teleport_player(caster_ptr, 100, TELEPORT_PASSIVE);
3941         }
3942         else if (die < 52)
3943         {
3944                 msg_print(_("テレポート・カードだ。", "It's a teleport trump card."));
3945                 teleport_player(caster_ptr, 200, TELEPORT_PASSIVE);
3946         }
3947         else if (die < 60)
3948         {
3949                 msg_print(_("《塔》だ。", "It's the Tower."));
3950                 wall_breaker(caster_ptr);
3951         }
3952         else if (die < 72)
3953         {
3954                 msg_print(_("《節制》だ。", "It's Temperance."));
3955                 sleep_monsters_touch();
3956         }
3957         else if (die < 80)
3958         {
3959                 msg_print(_("《塔》だ。", "It's the Tower."));
3960
3961                 earthquake(caster_ptr, caster_ptr->y, caster_ptr->x, 5, 0);
3962         }
3963         else if (die < 82)
3964         {
3965                 msg_print(_("友好的なモンスターの絵だ。", "It's the picture of a friendly monster."));
3966                 trump_summoning(caster_ptr, 1, TRUE, caster_ptr->y, caster_ptr->x, (caster_ptr->current_floor_ptr->dun_level * 3 / 2), SUMMON_MOLD, 0L);
3967         }
3968         else if (die < 84)
3969         {
3970                 msg_print(_("友好的なモンスターの絵だ。", "It's the picture of a friendly monster."));
3971                 trump_summoning(caster_ptr, 1, TRUE, caster_ptr->y, caster_ptr->x, (caster_ptr->current_floor_ptr->dun_level * 3 / 2), SUMMON_BAT, 0L);
3972         }
3973         else if (die < 86)
3974         {
3975                 msg_print(_("友好的なモンスターの絵だ。", "It's the picture of a friendly monster."));
3976                 trump_summoning(caster_ptr, 1, TRUE, caster_ptr->y, caster_ptr->x, (caster_ptr->current_floor_ptr->dun_level * 3 / 2), SUMMON_VORTEX, 0L);
3977         }
3978         else if (die < 88)
3979         {
3980                 msg_print(_("友好的なモンスターの絵だ。", "It's the picture of a friendly monster."));
3981                 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);
3982         }
3983         else if (die < 96)
3984         {
3985                 msg_print(_("《恋人》だ。", "It's the Lovers."));
3986
3987                 if (get_aim_dir(&dir))
3988                         charm_monster(dir, MIN(caster_ptr->lev, 20));
3989         }
3990         else if (die < 101)
3991         {
3992                 msg_print(_("《隠者》だ。", "It's the Hermit."));
3993                 wall_stone();
3994         }
3995         else if (die < 111)
3996         {
3997                 msg_print(_("《審判》だ。", "It's the Judgement."));
3998                 roll_hitdice(caster_ptr, 0L);
3999                 lose_all_mutations(caster_ptr);
4000         }
4001         else if (die < 120)
4002         {
4003                 msg_print(_("《太陽》だ。", "It's the Sun."));
4004                 chg_virtue(caster_ptr, V_KNOWLEDGE, 1);
4005                 chg_virtue(caster_ptr, V_ENLIGHTEN, 1);
4006                 wiz_lite(caster_ptr, FALSE);
4007         }
4008         else
4009         {
4010                 msg_print(_("《世界》だ。", "It's the World."));
4011                 if (caster_ptr->exp < PY_MAX_EXP)
4012                 {
4013                         s32b ee = (caster_ptr->exp / 25) + 1;
4014                         if (ee > 5000) ee = 5000;
4015                         msg_print(_("更に経験を積んだような気がする。", "You feel more experienced."));
4016                         gain_exp(caster_ptr, ee);
4017                 }
4018         }
4019 }
4020
4021 /*!
4022  * @brief 口を使う継続的な処理を中断する
4023  * @param caster_ptr プレーヤーへの参照ポインタ
4024  * @return なし
4025  */
4026 void stop_mouth(player_type *caster_ptr)
4027 {
4028         if (music_singing_any(caster_ptr)) stop_singing(caster_ptr);
4029         if (hex_spelling_any(caster_ptr)) stop_hex_spell_all(caster_ptr);
4030 }
4031
4032
4033 bool_hack vampirism(player_type *caster_ptr)
4034 {
4035         DIRECTION dir;
4036         POSITION x, y;
4037         int dummy;
4038         grid_type *g_ptr;
4039
4040         if (d_info[caster_ptr->dungeon_idx].flags1 & DF1_NO_MELEE)
4041         {
4042                 msg_print(_("なぜか攻撃することができない。", "Something prevent you from attacking."));
4043                 return FALSE;
4044         }
4045
4046         /* Only works on adjacent monsters */
4047         if (!get_direction(caster_ptr, &dir, FALSE, FALSE)) return FALSE;
4048         y = caster_ptr->y + ddy[dir];
4049         x = caster_ptr->x + ddx[dir];
4050         g_ptr = &caster_ptr->current_floor_ptr->grid_array[y][x];
4051
4052         stop_mouth(caster_ptr);
4053
4054         if (!(g_ptr->m_idx))
4055         {
4056                 msg_print(_("何もない場所に噛みついた!", "You bite into thin air!"));
4057                 return FALSE;
4058         }
4059
4060         msg_print(_("あなたはニヤリとして牙をむいた...", "You grin and bare your fangs..."));
4061
4062         dummy = caster_ptr->lev * 2;
4063
4064         if (hypodynamic_bolt(caster_ptr, dir, dummy))
4065         {
4066                 if (caster_ptr->food < PY_FOOD_FULL)
4067                         /* No heal if we are "full" */
4068                         (void)hp_player(caster_ptr, dummy);
4069                 else
4070                         msg_print(_("あなたは空腹ではありません。", "You were not hungry."));
4071
4072                 /* Gain nutritional sustenance: 150/hp drained */
4073                 /* A Food ration gives 5000 food points (by contrast) */
4074                 /* Don't ever get more than "Full" this way */
4075                 /* But if we ARE Gorged,  it won't cure us */
4076                 dummy = caster_ptr->food + MIN(5000, 100 * dummy);
4077                 if (caster_ptr->food < PY_FOOD_MAX)   /* Not gorged already */
4078                         (void)set_food(caster_ptr, dummy >= PY_FOOD_MAX ? PY_FOOD_MAX - 1 : dummy);
4079         }
4080         else
4081                 msg_print(_("げぇ!ひどい味だ。", "Yechh. That tastes foul."));
4082         return TRUE;
4083 }
4084
4085
4086 bool panic_hit(void)
4087 {
4088         DIRECTION dir;
4089         POSITION x, y;
4090
4091         if (!get_direction(p_ptr, &dir, FALSE, FALSE)) return FALSE;
4092         y = p_ptr->y + ddy[dir];
4093         x = p_ptr->x + ddx[dir];
4094         if (p_ptr->current_floor_ptr->grid_array[y][x].m_idx)
4095         {
4096                 py_attack(p_ptr, y, x, 0);
4097                 if (randint0(p_ptr->skill_dis) < 7)
4098                         msg_print(_("うまく逃げられなかった。", "You failed to run away."));
4099                 else
4100                         teleport_player(p_ptr, 30, 0L);
4101                 return TRUE;
4102         }
4103         else
4104         {
4105                 msg_print(_("その方向にはモンスターはいません。", "You don't see any monster in this direction"));
4106                 msg_print(NULL);
4107                 return FALSE;
4108         }
4109 }
4110
4111
4112 /*!
4113 * @brief 超能力者のサイコメトリー処理/ Forcibly pseudo-identify an object in the inventory (or on the floor)
4114 * @param caster_ptr プレーヤーへの参照ポインタ
4115 * @return なし
4116 * @note
4117 * currently this function allows pseudo-id of any object,
4118 * including silly ones like potions & scrolls, which always
4119 * get '{average}'. This should be changed, either to stop such
4120 * items from being pseudo-id'd, or to allow psychometry to
4121 * detect whether the unidentified potion/scroll/etc is
4122 * good (Cure Light Wounds, Restore Strength, etc) or
4123 * bad (Poison, Weakness etc) or 'useless' (Slime Mold Juice, etc).
4124 */
4125 bool psychometry(player_type *caster_ptr)
4126 {
4127         OBJECT_IDX      item;
4128         object_type *o_ptr;
4129         GAME_TEXT o_name[MAX_NLEN];
4130         byte            feel;
4131         concptr            q, s;
4132         bool okay = FALSE;
4133
4134         q = _("どのアイテムを調べますか?", "Meditate on which item? ");
4135         s = _("調べるアイテムがありません。", "You have nothing appropriate.");
4136
4137         o_ptr = choose_object(caster_ptr, &item, q, s, (USE_EQUIP | USE_INVEN | USE_FLOOR | IGNORE_BOTHHAND_SLOT), 0);
4138         if (!o_ptr) return (FALSE);
4139
4140         /* It is fully known, no information needed */
4141         if (object_is_known(o_ptr))
4142         {
4143                 msg_print(_("何も新しいことは判らなかった。", "You cannot find out anything more about that."));
4144                 return TRUE;
4145         }
4146
4147         /* Check for a feeling */
4148         feel = value_check_aux1(o_ptr);
4149
4150         /* Get an object description */
4151         object_desc(o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
4152
4153         /* Skip non-feelings */
4154         if (!feel)
4155         {
4156                 msg_format(_("%sからは特に変わった事は感じとれなかった。", "You do not perceive anything unusual about the %s."), o_name);
4157                 return TRUE;
4158         }
4159
4160 #ifdef JP
4161         msg_format("%sは%sという感じがする...", o_name, game_inscriptions[feel]);
4162 #else
4163         msg_format("You feel that the %s %s %s...",
4164                 o_name, ((o_ptr->number == 1) ? "is" : "are"), game_inscriptions[feel]);
4165 #endif
4166
4167
4168         o_ptr->ident |= (IDENT_SENSE);
4169         o_ptr->feeling = feel;
4170         o_ptr->marked |= OM_TOUCHED;
4171
4172         caster_ptr->update |= (PU_COMBINE | PU_REORDER);
4173         caster_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
4174
4175         /* Valid "tval" codes */
4176         switch (o_ptr->tval)
4177         {
4178         case TV_SHOT:
4179         case TV_ARROW:
4180         case TV_BOLT:
4181         case TV_BOW:
4182         case TV_DIGGING:
4183         case TV_HAFTED:
4184         case TV_POLEARM:
4185         case TV_SWORD:
4186         case TV_BOOTS:
4187         case TV_GLOVES:
4188         case TV_HELM:
4189         case TV_CROWN:
4190         case TV_SHIELD:
4191         case TV_CLOAK:
4192         case TV_SOFT_ARMOR:
4193         case TV_HARD_ARMOR:
4194         case TV_DRAG_ARMOR:
4195         case TV_CARD:
4196         case TV_RING:
4197         case TV_AMULET:
4198         case TV_LITE:
4199         case TV_FIGURINE:
4200                 okay = TRUE;
4201                 break;
4202         }
4203
4204         /* Auto-inscription/destroy */
4205         autopick_alter_item(item, (bool)(okay && destroy_feeling));
4206
4207         /* Something happened */
4208         return (TRUE);
4209 }
4210
4211
4212 bool draconian_breath(player_type *creature_ptr)
4213 {
4214         DIRECTION dir;
4215         int Type = (one_in_(3) ? GF_COLD : GF_FIRE);
4216         concptr Type_desc = ((Type == GF_COLD) ? _("冷気", "cold") : _("炎", "fire"));
4217
4218         if (!get_aim_dir(&dir)) return FALSE;
4219
4220         if (randint1(100) < creature_ptr->lev)
4221         {
4222                 switch (creature_ptr->pclass)
4223                 {
4224                 case CLASS_WARRIOR:
4225                 case CLASS_BERSERKER:
4226                 case CLASS_RANGER:
4227                 case CLASS_TOURIST:
4228                 case CLASS_IMITATOR:
4229                 case CLASS_ARCHER:
4230                 case CLASS_SMITH:
4231                         if (one_in_(3))
4232                         {
4233                                 Type = GF_MISSILE;
4234                                 Type_desc = _("エレメント", "the elements");
4235                         }
4236                         else
4237                         {
4238                                 Type = GF_SHARDS;
4239                                 Type_desc = _("破片", "shards");
4240                         }
4241
4242                         break;
4243                 case CLASS_MAGE:
4244                 case CLASS_WARRIOR_MAGE:
4245                 case CLASS_HIGH_MAGE:
4246                 case CLASS_SORCERER:
4247                 case CLASS_MAGIC_EATER:
4248                 case CLASS_RED_MAGE:
4249                 case CLASS_BLUE_MAGE:
4250                 case CLASS_MIRROR_MASTER:
4251                         if (one_in_(3))
4252                         {
4253                                 Type = GF_MANA;
4254                                 Type_desc = _("魔力", "mana");
4255                         }
4256                         else
4257                         {
4258                                 Type = GF_DISENCHANT;
4259                                 Type_desc = _("劣化", "disenchantment");
4260                         }
4261
4262                         break;
4263                 case CLASS_CHAOS_WARRIOR:
4264                         if (!one_in_(3))
4265                         {
4266                                 Type = GF_CONFUSION;
4267                                 Type_desc = _("混乱", "confusion");
4268                         }
4269                         else
4270                         {
4271                                 Type = GF_CHAOS;
4272                                 Type_desc = _("カオス", "chaos");
4273                         }
4274
4275                         break;
4276                 case CLASS_MONK:
4277                 case CLASS_SAMURAI:
4278                 case CLASS_FORCETRAINER:
4279                         if (!one_in_(3))
4280                         {
4281                                 Type = GF_CONFUSION;
4282                                 Type_desc = _("混乱", "confusion");
4283                         }
4284                         else
4285                         {
4286                                 Type = GF_SOUND;
4287                                 Type_desc = _("轟音", "sound");
4288                         }
4289
4290                         break;
4291                 case CLASS_MINDCRAFTER:
4292                         if (!one_in_(3))
4293                         {
4294                                 Type = GF_CONFUSION;
4295                                 Type_desc = _("混乱", "confusion");
4296                         }
4297                         else
4298                         {
4299                                 Type = GF_PSI;
4300                                 Type_desc = _("精神エネルギー", "mental energy");
4301                         }
4302
4303                         break;
4304                 case CLASS_PRIEST:
4305                 case CLASS_PALADIN:
4306                         if (one_in_(3))
4307                         {
4308                                 Type = GF_HELL_FIRE;
4309                                 Type_desc = _("地獄の劫火", "hellfire");
4310                         }
4311                         else
4312                         {
4313                                 Type = GF_HOLY_FIRE;
4314                                 Type_desc = _("聖なる炎", "holy fire");
4315                         }
4316
4317                         break;
4318                 case CLASS_ROGUE:
4319                 case CLASS_NINJA:
4320                         if (one_in_(3))
4321                         {
4322                                 Type = GF_DARK;
4323                                 Type_desc = _("暗黒", "darkness");
4324                         }
4325                         else
4326                         {
4327                                 Type = GF_POIS;
4328                                 Type_desc = _("毒", "poison");
4329                         }
4330
4331                         break;
4332                 case CLASS_BARD:
4333                         if (!one_in_(3))
4334                         {
4335                                 Type = GF_SOUND;
4336                                 Type_desc = _("轟音", "sound");
4337                         }
4338                         else
4339                         {
4340                                 Type = GF_CONFUSION;
4341                                 Type_desc = _("混乱", "confusion");
4342                         }
4343
4344                         break;
4345                 }
4346         }
4347
4348         stop_mouth(creature_ptr);
4349         msg_format(_("あなたは%sのブレスを吐いた。", "You breathe %s."), Type_desc);
4350
4351         fire_breath(creature_ptr, Type, dir, creature_ptr->lev * 2, (creature_ptr->lev / 15) + 1);
4352         return TRUE;
4353 }
4354
4355
4356 bool android_inside_weapon(player_type *creature_ptr)
4357 {
4358         DIRECTION dir;
4359         if (!get_aim_dir(&dir)) return FALSE;
4360         if (creature_ptr->lev < 10)
4361         {
4362                 msg_print(_("レイガンを発射した。", "You fire your ray gun."));
4363                 fire_bolt(creature_ptr, GF_MISSILE, dir, (creature_ptr->lev + 1) / 2);
4364         }
4365         else if (creature_ptr->lev < 25)
4366         {
4367                 msg_print(_("ブラスターを発射した。", "You fire your blaster."));
4368                 fire_bolt(creature_ptr, GF_MISSILE, dir, creature_ptr->lev);
4369         }
4370         else if (creature_ptr->lev < 35)
4371         {
4372                 msg_print(_("バズーカを発射した。", "You fire your bazooka."));
4373                 fire_ball(creature_ptr, GF_MISSILE, dir, creature_ptr->lev * 2, 2);
4374         }
4375         else if (creature_ptr->lev < 45)
4376         {
4377                 msg_print(_("ビームキャノンを発射した。", "You fire a beam cannon."));
4378                 fire_beam(creature_ptr, GF_MISSILE, dir, creature_ptr->lev * 2);
4379         }
4380         else
4381         {
4382                 msg_print(_("ロケットを発射した。", "You fire a rocket."));
4383                 fire_rocket(creature_ptr, GF_ROCKET, dir, creature_ptr->lev * 5, 2);
4384         }
4385
4386         return TRUE;
4387 }
4388
4389
4390 bool create_ration(player_type *crature_ptr)
4391 {
4392         object_type *q_ptr;
4393         object_type forge;
4394         q_ptr = &forge;
4395
4396         /* Create the food ration */
4397         object_prep(q_ptr, lookup_kind(TV_FOOD, SV_FOOD_RATION));
4398
4399         /* Drop the object from heaven */
4400         (void)drop_near(q_ptr, -1, crature_ptr->y, crature_ptr->x);
4401         msg_print(_("食事を料理して作った。", "You cook some food."));
4402         return TRUE;
4403 }
4404
4405
4406 void hayagake(player_type *creature_ptr)
4407 {
4408         if (creature_ptr->action == ACTION_HAYAGAKE)
4409         {
4410                 set_action(creature_ptr, ACTION_NONE);
4411         }
4412         else
4413         {
4414                 grid_type *g_ptr = &creature_ptr->current_floor_ptr->grid_array[creature_ptr->y][creature_ptr->x];
4415                 feature_type *f_ptr = &f_info[g_ptr->feat];
4416
4417                 if (!have_flag(f_ptr->flags, FF_PROJECT) ||
4418                         (!creature_ptr->levitation && have_flag(f_ptr->flags, FF_DEEP)))
4419                 {
4420                         msg_print(_("ここでは素早く動けない。", "You cannot run in here."));
4421                 }
4422                 else
4423                 {
4424                         set_action(creature_ptr, ACTION_HAYAGAKE);
4425                 }
4426         }
4427
4428         creature_ptr->energy_use = 0;
4429 }
4430
4431
4432 bool double_attack(player_type *creature_ptr)
4433 {
4434         DIRECTION dir;
4435         POSITION x, y;
4436
4437         if (!get_rep_dir(&dir, FALSE)) return FALSE;
4438         y = creature_ptr->y + ddy[dir];
4439         x = creature_ptr->x + ddx[dir];
4440         if (creature_ptr->current_floor_ptr->grid_array[y][x].m_idx)
4441         {
4442                 if (one_in_(3))
4443                         msg_print(_("あーたたたたたたたたたたたたたたたたたたたたたた!!!",
4444                                 "Ahhhtatatatatatatatatatatatatatataatatatatattaaaaa!!!!"));
4445                 else if(one_in_(2))
4446                         msg_print(_("無駄無駄無駄無駄無駄無駄無駄無駄無駄無駄無駄無駄!!!",
4447                                 "Mudamudamudamudamudamudamudamudamudamudamudamudamuda!!!!"));
4448                 else
4449                         msg_print(_("オラオラオラオラオラオラオラオラオラオラオラオラ!!!",
4450                                 "Oraoraoraoraoraoraoraoraoraoraoraoraoraoraoraoraora!!!!"));
4451
4452                 py_attack(creature_ptr, y, x, 0);
4453                 if (creature_ptr->current_floor_ptr->grid_array[y][x].m_idx)
4454                 {
4455                         handle_stuff();
4456                         py_attack(creature_ptr, y, x, 0);
4457                 }
4458                 creature_ptr->energy_need += ENERGY_NEED();
4459         }
4460         else
4461         {
4462                 msg_print(_("その方向にはモンスターはいません。", "You don't see any monster in this direction"));
4463                 msg_print(NULL);
4464         }
4465
4466         return TRUE;
4467 }
4468
4469
4470 bool comvert_hp_to_mp(player_type *creature_ptr)
4471 {
4472         int gain_sp = take_hit(p_ptr, DAMAGE_USELIFE, creature_ptr->lev, _("HPからMPへの無謀な変換", "thoughtless convertion from HP to SP"), -1) / 5;
4473         if (gain_sp)
4474         {
4475                 creature_ptr->csp += gain_sp;
4476                 if (creature_ptr->csp > creature_ptr->msp)
4477                 {
4478                         creature_ptr->csp = creature_ptr->msp;
4479                         creature_ptr->csp_frac = 0;
4480                 }
4481         }
4482         else
4483         {
4484                 msg_print(_("変換に失敗した。", "You failed to convert."));
4485         }
4486
4487         creature_ptr->redraw |= (PR_HP | PR_MANA);
4488         return TRUE;
4489 }
4490
4491
4492 bool comvert_mp_to_hp(player_type *creature_ptr)
4493 {
4494         if (creature_ptr->csp >= creature_ptr->lev / 5)
4495         {
4496                 creature_ptr->csp -= creature_ptr->lev / 5;
4497                 hp_player(p_ptr, creature_ptr->lev);
4498         }
4499         else
4500         {
4501                 msg_print(_("変換に失敗した。", "You failed to convert."));
4502         }
4503
4504         creature_ptr->redraw |= (PR_HP | PR_MANA);
4505         return TRUE;
4506 }
4507
4508
4509 bool demonic_breath(player_type *creature_ptr)
4510 {
4511         DIRECTION dir;
4512         int type = (one_in_(2) ? GF_NETHER : GF_FIRE);
4513         if (!get_aim_dir(&dir)) return FALSE;
4514         stop_mouth(creature_ptr);
4515         msg_format(_("あなたは%sのブレスを吐いた。", "You breathe %s."), ((type == GF_NETHER) ? _("地獄", "nether") : _("火炎", "fire")));
4516         fire_breath(creature_ptr, type, dir, creature_ptr->lev * 3, (creature_ptr->lev / 15) + 1);
4517         return TRUE;
4518 }
4519
4520
4521 bool mirror_concentration(player_type *creature_ptr)
4522 {
4523         if (total_friends)
4524         {
4525                 msg_print(_("今はペットを操ることに集中していないと。", "You need concentration on the pets now."));
4526                 return FALSE;
4527         }
4528
4529         if (is_mirror_grid(&p_ptr->current_floor_ptr->grid_array[creature_ptr->y][creature_ptr->x]))
4530         {
4531                 msg_print(_("少し頭がハッキリした。", "You feel your head clear a little."));
4532
4533                 creature_ptr->csp += (5 + creature_ptr->lev * creature_ptr->lev / 100);
4534                 if (creature_ptr->csp >= creature_ptr->msp)
4535                 {
4536                         creature_ptr->csp = creature_ptr->msp;
4537                         creature_ptr->csp_frac = 0;
4538                 }
4539                 creature_ptr->redraw |= (PR_MANA);
4540         }
4541         else
4542         {
4543                 msg_print(_("鏡の上でないと集中できない!", "Here are not any mirrors!"));
4544         }
4545
4546         return TRUE;
4547 }
4548
4549
4550 bool sword_dancing(player_type *creature_ptr)
4551 {
4552         DIRECTION dir;
4553         POSITION y = 0, x = 0;
4554         int i;
4555         grid_type *g_ptr;
4556
4557         for (i = 0; i < 6; i++)
4558         {
4559                 dir = randint0(8);
4560                 y = creature_ptr->y + ddy_ddd[dir];
4561                 x = creature_ptr->x + ddx_ddd[dir];
4562                 g_ptr = &creature_ptr->current_floor_ptr->grid_array[y][x];
4563
4564                 /* Hack -- attack monsters */
4565                 if (g_ptr->m_idx)
4566                         py_attack(creature_ptr, y, x, 0);
4567                 else
4568                 {
4569                         msg_print(_("攻撃が空をきった。", "You attack the empty air."));
4570                 }
4571         }
4572
4573         return TRUE;
4574 }
4575
4576 /*!
4577  * 幻惑の光
4578  * @param creature_ptr プレーヤーへの参照ポインタ
4579  * @return 常にTRUE
4580 */
4581 bool confusing_light(player_type *creature_ptr)
4582 {
4583         msg_print(_("辺りを睨んだ...", "You glare nearby monsters..."));
4584         slow_monsters(creature_ptr, creature_ptr->lev);
4585         stun_monsters(creature_ptr->lev * 4);
4586         confuse_monsters(creature_ptr->lev * 4);
4587         turn_monsters(creature_ptr->lev * 4);
4588         stasis_monsters(creature_ptr->lev * 4);
4589         return TRUE;
4590 }
4591
4592
4593 /*!
4594  * 荒馬慣らし
4595  * @param creature_ptr プレーヤーへの参照ポインタ
4596  * @return 結果はどうあれ騎乗したらTRUE
4597 */
4598 bool rodeo(player_type *creature_ptr)
4599 {
4600         GAME_TEXT m_name[MAX_NLEN];
4601         monster_type *m_ptr;
4602         monster_race *r_ptr;
4603         int rlev;
4604
4605         if (creature_ptr->riding)
4606         {
4607                 msg_print(_("今は乗馬中だ。", "You ARE riding."));
4608                 return FALSE;
4609         }
4610
4611         if (!do_cmd_riding(creature_ptr, TRUE)) return TRUE;
4612
4613         m_ptr = &p_ptr->current_floor_ptr->m_list[creature_ptr->riding];
4614         r_ptr = &r_info[m_ptr->r_idx];
4615         monster_desc(m_name, m_ptr, 0);
4616         msg_format(_("%sに乗った。", "You ride on %s."), m_name);
4617
4618         if (is_pet(m_ptr)) return TRUE;
4619
4620         rlev = r_ptr->level;
4621
4622         if (r_ptr->flags1 & RF1_UNIQUE) rlev = rlev * 3 / 2;
4623         if (rlev > 60) rlev = 60 + (rlev - 60) / 2;
4624         if ((randint1(creature_ptr->skill_exp[GINOU_RIDING] / 120 + creature_ptr->lev * 2 / 3) > rlev)
4625                 && one_in_(2) && !creature_ptr->current_floor_ptr->inside_arena && !creature_ptr->phase_out
4626                 && !(r_ptr->flags7 & (RF7_GUARDIAN)) && !(r_ptr->flags1 & (RF1_QUESTOR))
4627                 && (rlev < creature_ptr->lev * 3 / 2 + randint0(creature_ptr->lev / 5)))
4628         {
4629                 msg_format(_("%sを手なずけた。", "You tame %s."), m_name);
4630                 set_pet(m_ptr);
4631         }
4632         else
4633         {
4634                 msg_format(_("%sに振り落とされた!", "You have thrown off by %s."), m_name);
4635                 rakuba(p_ptr, 1, TRUE);
4636                 /* 落馬処理に失敗してもとにかく乗馬解除 */
4637                 creature_ptr->riding = 0;
4638         }
4639
4640         return TRUE;
4641 }
4642
4643
4644 bool clear_mind(player_type *creature_ptr)
4645 {
4646         if (total_friends)
4647         {
4648                 msg_print(_("今はペットを操ることに集中していないと。", "You need concentration on the pets now."));
4649                 return FALSE;
4650         }
4651         msg_print(_("少し頭がハッキリした。", "You feel your head clear a little."));
4652
4653         creature_ptr->csp += (3 + creature_ptr->lev / 20);
4654         if (creature_ptr->csp >= creature_ptr->msp)
4655         {
4656                 creature_ptr->csp = creature_ptr->msp;
4657                 creature_ptr->csp_frac = 0;
4658         }
4659
4660         creature_ptr->redraw |= (PR_MANA);
4661         return TRUE;
4662 }
4663
4664
4665 bool concentration(player_type *creature_ptr)
4666 {
4667         int max_csp = MAX(creature_ptr->msp * 4, creature_ptr->lev * 5 + 5);
4668
4669         if (total_friends)
4670         {
4671                 msg_print(_("今はペットを操ることに集中していないと。", "You need concentration on the pets now."));
4672                 return FALSE;
4673         }
4674
4675         if (creature_ptr->special_defense & KATA_MASK)
4676         {
4677                 msg_print(_("今は構えに集中している。", "You need concentration on your form."));
4678                 return FALSE;
4679         }
4680
4681         msg_print(_("精神を集中して気合いを溜めた。", "You concentrate to charge your power."));
4682
4683         creature_ptr->csp += creature_ptr->msp / 2;
4684         if (creature_ptr->csp >= max_csp)
4685         {
4686                 creature_ptr->csp = max_csp;
4687                 creature_ptr->csp_frac = 0;
4688         }
4689
4690         creature_ptr->redraw |= (PR_MANA);
4691         return TRUE;
4692 }