OSDN Git Service

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