OSDN Git Service

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