OSDN Git Service

[Refactor] #37353 コメントとメッセージ整理 / Refactor comments and messages.
[hengband/hengband.git] / src / spells1.c
1 /*!
2  * @file spells1.c
3  * @brief 魔法による遠隔処理の実装 / Spell projection
4  * @date 2014/07/10
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 "cmd-pet.h"
16 #include "trap.h"
17 #include "object-curse.h"
18
19
20 static int rakubadam_m; /*!< 振り落とされた際のダメージ量 */
21 static int rakubadam_p; /*!< 落馬した際のダメージ量 */
22
23 int project_length = 0; /*!< 投射の射程距離 */
24
25
26 /*!
27  * @brief モンスター魅了用セービングスロー共通部(汎用系)
28  * @param pow 魅了パワー
29  * @param m_ptr 対象モンスター
30  * @return 魅了に抵抗したらTRUE
31  */
32 static bool_hack common_saving_throw_charm(player_type *player_ptr, HIT_POINT pow, monster_type *m_ptr)
33 {
34         monster_race *r_ptr = &r_info[m_ptr->r_idx];
35
36         if(p_ptr->inside_arena) return TRUE;
37
38         /* Memorize a flag */
39         if (r_ptr->flagsr & RFR_RES_ALL)
40         {
41                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
42                 return TRUE;
43         }
44
45         if (r_ptr->flags3 & RF3_NO_CONF)
46         {
47                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags3 |= (RF3_NO_CONF);
48                 return TRUE;
49         }
50
51         if (r_ptr->flags1 & RF1_QUESTOR || m_ptr->mflag2 & MFLAG2_NOPET) return TRUE;
52
53         pow += (adj_chr_chm[player_ptr->stat_ind[A_CHR]] - 1);
54         if((r_ptr->flags1 & RF1_UNIQUE) || (r_ptr->flags7 & RF7_NAZGUL)) pow = pow * 2 / 3;
55         return (r_ptr->level > randint1((pow - 10) < 1 ? 1 : (pow - 10)) + 5);
56 }
57
58 /*!
59  * @brief モンスター服従用セービングスロー共通部(部族依存系)
60  * @param pow 服従パワー
61  * @param m_ptr 対象モンスター
62  * @return 服従に抵抗したらTRUE
63  */
64 static bool_hack common_saving_throw_control(player_type *player_ptr, HIT_POINT pow, monster_type *m_ptr)
65 {
66         monster_race *r_ptr = &r_info[m_ptr->r_idx];
67
68         if (p_ptr->inside_arena) return TRUE;
69
70         /* Memorize a flag */
71         if (r_ptr->flagsr & RFR_RES_ALL)
72         {
73                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
74                 return TRUE;
75         }
76
77         if (r_ptr->flags1 & RF1_QUESTOR || m_ptr->mflag2 & MFLAG2_NOPET) return TRUE;
78
79         pow += adj_chr_chm[player_ptr->stat_ind[A_CHR]] - 1;
80         if ((r_ptr->flags1 & RF1_UNIQUE) || (r_ptr->flags7 & RF7_NAZGUL)) pow = pow * 2 / 3;
81         return (r_ptr->level > randint1((pow - 10) < 1 ? 1 : (pow - 10)) + 5);
82 }
83
84 /*!
85 * @brief 一部ボルト魔法のビーム化確率を算出する / Prepare standard probability to become beam for fire_bolt_or_beam()
86 * @return ビーム化確率(%)
87 * @details
88 * ハードコーティングによる実装が行われている。
89 * メイジは(レベル)%、ハイメイジ、スペルマスターは(レベル)%、それ以外の職業は(レベル/2)%
90 */
91 PERCENTAGE beam_chance(void)
92 {
93         if (p_ptr->pclass == CLASS_MAGE)
94                 return (PERCENTAGE)(p_ptr->lev);
95         if (p_ptr->pclass == CLASS_HIGH_MAGE || p_ptr->pclass == CLASS_SORCERER)
96                 return (PERCENTAGE)(p_ptr->lev + 10);
97
98         return (PERCENTAGE)(p_ptr->lev / 2);
99 }
100
101
102 /*!
103  * @brief 配置した鏡リストの次を取得する /
104  * Get another mirror. for SEEKER 
105  * @param next_y 次の鏡のy座標を返す参照ポインタ
106  * @param next_x 次の鏡のx座標を返す参照ポインタ
107  * @param cury 現在の鏡のy座標
108  * @param curx 現在の鏡のx座標
109  */
110 static void next_mirror(int* next_y, int* next_x, int cury, int curx)
111 {
112         int mirror_x[10], mirror_y[10]; /* 鏡はもっと少ない */
113         int mirror_num = 0;                       /* 鏡の数 */
114         POSITION x, y;
115         int num;
116
117         for (x = 0; x < cur_wid; x++)
118         {
119                 for (y = 0; y < cur_hgt; y++)
120                 {
121                         if (is_mirror_grid(&cave[y][x])) {
122                                 mirror_y[mirror_num] = y;
123                                 mirror_x[mirror_num] = x;
124                                 mirror_num++;
125                         }
126                 }
127         }
128         if (mirror_num)
129         {
130                 num = randint0(mirror_num);
131                 *next_y = mirror_y[num];
132                 *next_x = mirror_x[num];
133                 return;
134         }
135         *next_y = cury + randint0(5) - 2;
136         *next_x = curx + randint0(5) - 2;
137         return;
138 }
139                 
140 /*!
141  * @brief 万色表現用にランダムな色を選択する関数 /
142  * Get a legal "multi-hued" color for drawing "spells"
143  * @param max 色IDの最大値
144  * @return 選択した色ID
145  */
146 static byte mh_attr(int max)
147 {
148         switch (randint1(max))
149         {
150                 case  1: return (TERM_RED);
151                 case  2: return (TERM_GREEN);
152                 case  3: return (TERM_BLUE);
153                 case  4: return (TERM_YELLOW);
154                 case  5: return (TERM_ORANGE);
155                 case  6: return (TERM_VIOLET);
156                 case  7: return (TERM_L_RED);
157                 case  8: return (TERM_L_GREEN);
158                 case  9: return (TERM_L_BLUE);
159                 case 10: return (TERM_UMBER);
160                 case 11: return (TERM_L_UMBER);
161                 case 12: return (TERM_SLATE);
162                 case 13: return (TERM_WHITE);
163                 case 14: return (TERM_L_WHITE);
164                 case 15: return (TERM_L_DARK);
165         }
166
167         return (TERM_WHITE);
168 }
169
170
171 /*!
172  * @brief 魔法属性に応じたエフェクトの色を返す /
173  * Return a color to use for the bolt/ball spells
174  * @param type 魔法属性
175  * @return 対応する色ID
176  */
177 static byte spell_color(int type)
178 {
179         /* Check if A.B.'s new graphics should be used (rr9) */
180         if (streq(ANGBAND_GRAF, "new") || streq(ANGBAND_GRAF, "ne2"))
181         {
182                 /* Analyze */
183                 switch (type)
184                 {
185                         case GF_PSY_SPEAR:              return (0x06);
186                         case GF_MISSILE:                return (0x0F);
187                         case GF_ACID:                   return (0x04);
188                         case GF_ELEC:                   return (0x02);
189                         case GF_FIRE:                   return (0x00);
190                         case GF_COLD:                   return (0x01);
191                         case GF_POIS:                   return (0x03);
192                         case GF_HOLY_FIRE:              return (0x00);
193                         case GF_HELL_FIRE:              return (0x00);
194                         case GF_MANA:                   return (0x0E);
195                           /* by henkma */
196                         case GF_SEEKER:                 return (0x0E);
197                         case GF_SUPER_RAY:              return (0x0E);
198
199                         case GF_ARROW:                  return (0x0F);
200                         case GF_WATER:                  return (0x04);
201                         case GF_NETHER:                 return (0x07);
202                         case GF_CHAOS:                  return (mh_attr(15));
203                         case GF_DISENCHANT:             return (0x05);
204                         case GF_NEXUS:                  return (0x0C);
205                         case GF_CONFUSION:              return (mh_attr(4));
206                         case GF_SOUND:                  return (0x09);
207                         case GF_SHARDS:                 return (0x08);
208                         case GF_FORCE:                  return (0x09);
209                         case GF_INERTIAL:               return (0x09);
210                         case GF_GRAVITY:                return (0x09);
211                         case GF_TIME:                   return (0x09);
212                         case GF_LITE_WEAK:              return (0x06);
213                         case GF_LITE:                   return (0x06);
214                         case GF_DARK_WEAK:              return (0x07);
215                         case GF_DARK:                   return (0x07);
216                         case GF_PLASMA:                 return (0x0B);
217                         case GF_METEOR:                 return (0x00);
218                         case GF_ICE:                    return (0x01);
219                         case GF_ROCKET:                 return (0x0F);
220                         case GF_DEATH_RAY:              return (0x07);
221                         case GF_NUKE:                   return (mh_attr(2));
222                         case GF_DISINTEGRATE:   return (0x05);
223                         case GF_PSI:
224                         case GF_PSI_DRAIN:
225                         case GF_TELEKINESIS:
226                         case GF_DOMINATION:
227                         case GF_DRAIN_MANA:
228                         case GF_MIND_BLAST:
229                         case GF_BRAIN_SMASH:
230                                 return (0x09);
231                         case GF_CAUSE_1:
232                         case GF_CAUSE_2:
233                         case GF_CAUSE_3:
234                         case GF_CAUSE_4:                return (0x0E);
235                         case GF_HAND_DOOM:              return (0x07);
236                         case GF_CAPTURE  :              return (0x0E);
237                         case GF_IDENTIFY:               return (0x01);
238                         case GF_ATTACK:                 return (0x0F);
239                         case GF_PHOTO   :               return (0x06);
240                 }
241         }
242         /* Normal tiles or ASCII */
243         else
244         {
245                 byte a;
246                 char c;
247
248                 /* Lookup the default colors for this type */
249                 cptr s = quark_str(gf_color[type]);
250
251                 /* Oops */
252                 if (!s) return (TERM_WHITE);
253
254                 /* Pick a random color */
255                 c = s[randint0(strlen(s))];
256
257                 /* Lookup this color */
258                 a = my_strchr(color_char, c) - color_char;
259
260                 /* Invalid color (note check for < 0 removed, gave a silly
261                  * warning because bytes are always >= 0 -- RG) */
262                 if (a > 15) return (TERM_WHITE);
263
264                 /* Use this color */
265                 return (a);
266         }
267
268         /* Standard "color" */
269         return (TERM_WHITE);
270 }
271
272
273 /*!
274  * @brief 始点から終点にかけた方向毎にボルトのキャラクタを返す /
275  * Find the attr/char pair to use for a spell effect
276  * @param y 始点Y座標
277  * @param x 始点X座標
278  * @param ny 終点Y座標
279  * @param nx 終点X座標
280  * @param typ 魔法の効果属性
281  * @return 方向キャラID
282  * @details
283  * <pre>
284  * It is moving (or has moved) from (x,y) to (nx,ny).
285  * If the distance is not "one", we (may) return "*".
286  * </pre>
287  */
288 u16b bolt_pict(POSITION y, POSITION x, POSITION ny, POSITION nx, EFFECT_ID typ)
289 {
290         int base;
291
292         byte k;
293
294         TERM_COLOR a;
295         char c;
296
297         /* No motion (*) */
298         if ((ny == y) && (nx == x)) base = 0x30;
299
300         /* Vertical (|) */
301         else if (nx == x) base = 0x40;
302
303         /* Horizontal (-) */
304         else if (ny == y) base = 0x50;
305
306         /* Diagonal (/) */
307         else if ((ny - y) == (x - nx)) base = 0x60;
308
309         /* Diagonal (\) */
310         else if ((ny - y) == (nx - x)) base = 0x70;
311
312         /* Weird (*) */
313         else base = 0x30;
314
315         /* Basic spell color */
316         k = spell_color(typ);
317
318         /* Obtain attr/char */
319         a = misc_to_attr[base + k];
320         c = misc_to_char[base + k];
321
322         /* Create pict */
323         return (PICT(a, c));
324 }
325
326
327 /*!
328  * @brief 始点から終点への経路を返す /
329  * Determine the path taken by a projection.
330  * @param gp 経路座標リストを返す参照ポインタ
331  * @param range 距離
332  * @param y1 始点Y座標
333  * @param x1 始点X座標
334  * @param y2 終点Y座標
335  * @param x2 終点X座標
336  * @param flg フラグID
337  * @return リストの長さ
338  * @details
339  * <pre>
340  * The projection will always start from the grid (y1,x1), and will travel
341  * towards the grid (y2,x2), touching one grid per unit of distance along
342  * the major axis, and stopping when it enters the destination grid or a
343  * wall grid, or has travelled the maximum legal distance of "range".
344  *
345  * Note that "distance" in this function (as in the "update_view()" code)
346  * is defined as "MAX(dy,dx) + MIN(dy,dx)/2", which means that the player
347  * actually has an "octagon of projection" not a "circle of projection".
348  *
349  * The path grids are saved into the grid array pointed to by "gp", and
350  * there should be room for at least "range" grids in "gp".  Note that
351  * due to the way in which distance is calculated, this function normally
352  * uses fewer than "range" grids for the projection path, so the result
353  * of this function should never be compared directly to "range".  Note
354  * that the initial grid (y1,x1) is never saved into the grid array, not
355  * even if the initial grid is also the final grid.  XXX XXX XXX
356  *
357  * The "flg" flags can be used to modify the behavior of this function.
358  *
359  * In particular, the "PROJECT_STOP" and "PROJECT_THRU" flags have the same
360  * semantics as they do for the "project" function, namely, that the path
361  * will stop as soon as it hits a monster, or that the path will continue
362  * through the destination grid, respectively.
363  *
364  * The "PROJECT_JUMP" flag, which for the "project()" function means to
365  * start at a special grid (which makes no sense in this function), means
366  * that the path should be "angled" slightly if needed to avoid any wall
367  * grids, allowing the player to "target" any grid which is in "view".
368  * This flag is non-trivial and has not yet been implemented, but could
369  * perhaps make use of the "vinfo" array (above).  XXX XXX XXX
370  *
371  * This function returns the number of grids (if any) in the path.  This
372  * function will return zero if and only if (y1,x1) and (y2,x2) are equal.
373  *
374  * This algorithm is similar to, but slightly different from, the one used
375  * by "update_view_los()", and very different from the one used by "los()".
376  * </pre>
377  */
378 sint project_path(u16b *gp, POSITION range, POSITION y1, POSITION x1, POSITION y2, POSITION x2, BIT_FLAGS flg)
379 {
380         int y, x;
381
382         int n = 0;
383         int k = 0;
384
385         /* Absolute */
386         int ay, ax;
387
388         /* Offsets */
389         int sy, sx;
390
391         /* Fractions */
392         int frac;
393
394         /* Scale factors */
395         int full, half;
396
397         /* Slope */
398         int m;
399
400         /* No path necessary (or allowed) */
401         if ((x1 == x2) && (y1 == y2)) return (0);
402
403
404         /* Analyze "dy" */
405         if (y2 < y1)
406         {
407                 ay = (y1 - y2);
408                 sy = -1;
409         }
410         else
411         {
412                 ay = (y2 - y1);
413                 sy = 1;
414         }
415
416         /* Analyze "dx" */
417         if (x2 < x1)
418         {
419                 ax = (x1 - x2);
420                 sx = -1;
421         }
422         else
423         {
424                 ax = (x2 - x1);
425                 sx = 1;
426         }
427
428
429         /* Number of "units" in one "half" grid */
430         half = (ay * ax);
431
432         /* Number of "units" in one "full" grid */
433         full = half << 1;
434
435         /* Vertical */
436         if (ay > ax)
437         {
438                 /* Let m = ((dx/dy) * full) = (dx * dx * 2) */
439                 m = ax * ax * 2;
440
441                 /* Start */
442                 y = y1 + sy;
443                 x = x1;
444
445                 frac = m;
446
447                 if (frac > half)
448                 {
449                         /* Advance (X) part 2 */
450                         x += sx;
451
452                         /* Advance (X) part 3 */
453                         frac -= full;
454
455                         /* Track distance */
456                         k++;
457                 }
458
459                 /* Create the projection path */
460                 while (1)
461                 {
462                         /* Save grid */
463                         gp[n++] = GRID(y, x);
464
465                         /* Hack -- Check maximum range */
466                         if ((n + (k >> 1)) >= range) break;
467
468                         /* Sometimes stop at destination grid */
469                         if (!(flg & (PROJECT_THRU)))
470                         {
471                                 if ((x == x2) && (y == y2)) break;
472                         }
473
474                         if (flg & (PROJECT_DISI))
475                         {
476                                 if ((n > 0) && cave_stop_disintegration(y, x)) break;
477                         }
478                         else if (flg & (PROJECT_LOS))
479                         {
480                                 if ((n > 0) && !cave_los_bold(y, x)) break;
481                         }
482                         else if (!(flg & (PROJECT_PATH)))
483                         {
484                                 /* Always stop at non-initial wall grids */
485                                 if ((n > 0) && !cave_have_flag_bold(y, x, FF_PROJECT)) break;
486                         }
487
488                         /* Sometimes stop at non-initial monsters/players */
489                         if (flg & (PROJECT_STOP))
490                         {
491                                 if ((n > 0) &&
492                                         (player_bold(y, x) || cave[y][x].m_idx != 0))
493                                         break;
494                         }
495
496                         if (!in_bounds(y, x)) break;
497
498                         /* Slant */
499                         if (m)
500                         {
501                                 /* Advance (X) part 1 */
502                                 frac += m;
503
504                                 /* Horizontal change */
505                                 if (frac > half)
506                                 {
507                                         /* Advance (X) part 2 */
508                                         x += sx;
509
510                                         /* Advance (X) part 3 */
511                                         frac -= full;
512
513                                         /* Track distance */
514                                         k++;
515                                 }
516                         }
517
518                         /* Advance (Y) */
519                         y += sy;
520                 }
521         }
522
523         /* Horizontal */
524         else if (ax > ay)
525         {
526                 /* Let m = ((dy/dx) * full) = (dy * dy * 2) */
527                 m = ay * ay * 2;
528
529                 /* Start */
530                 y = y1;
531                 x = x1 + sx;
532
533                 frac = m;
534
535                 /* Vertical change */
536                 if (frac > half)
537                 {
538                         /* Advance (Y) part 2 */
539                         y += sy;
540
541                         /* Advance (Y) part 3 */
542                         frac -= full;
543
544                         /* Track distance */
545                         k++;
546                 }
547
548                 /* Create the projection path */
549                 while (1)
550                 {
551                         /* Save grid */
552                         gp[n++] = GRID(y, x);
553
554                         /* Hack -- Check maximum range */
555                         if ((n + (k >> 1)) >= range) break;
556
557                         /* Sometimes stop at destination grid */
558                         if (!(flg & (PROJECT_THRU)))
559                         {
560                                 if ((x == x2) && (y == y2)) break;
561                         }
562
563                         if (flg & (PROJECT_DISI))
564                         {
565                                 if ((n > 0) && cave_stop_disintegration(y, x)) break;
566                         }
567                         else if (flg & (PROJECT_LOS))
568                         {
569                                 if ((n > 0) && !cave_los_bold(y, x)) break;
570                         }
571                         else if (!(flg & (PROJECT_PATH)))
572                         {
573                                 /* Always stop at non-initial wall grids */
574                                 if ((n > 0) && !cave_have_flag_bold(y, x, FF_PROJECT)) break;
575                         }
576
577                         /* Sometimes stop at non-initial monsters/players */
578                         if (flg & (PROJECT_STOP))
579                         {
580                                 if ((n > 0) &&
581                                         (player_bold(y, x) || cave[y][x].m_idx != 0))
582                                         break;
583                         }
584
585                         if (!in_bounds(y, x)) break;
586
587                         /* Slant */
588                         if (m)
589                         {
590                                 /* Advance (Y) part 1 */
591                                 frac += m;
592
593                                 /* Vertical change */
594                                 if (frac > half)
595                                 {
596                                         /* Advance (Y) part 2 */
597                                         y += sy;
598
599                                         /* Advance (Y) part 3 */
600                                         frac -= full;
601
602                                         /* Track distance */
603                                         k++;
604                                 }
605                         }
606
607                         /* Advance (X) */
608                         x += sx;
609                 }
610         }
611
612         /* Diagonal */
613         else
614         {
615                 /* Start */
616                 y = y1 + sy;
617                 x = x1 + sx;
618
619                 /* Create the projection path */
620                 while (1)
621                 {
622                         /* Save grid */
623                         gp[n++] = GRID(y, x);
624
625                         /* Hack -- Check maximum range */
626                         if ((n + (n >> 1)) >= range) break;
627
628                         /* Sometimes stop at destination grid */
629                         if (!(flg & (PROJECT_THRU)))
630                         {
631                                 if ((x == x2) && (y == y2)) break;
632                         }
633
634                         if (flg & (PROJECT_DISI))
635                         {
636                                 if ((n > 0) && cave_stop_disintegration(y, x)) break;
637                         }
638                         else if (flg & (PROJECT_LOS))
639                         {
640                                 if ((n > 0) && !cave_los_bold(y, x)) break;
641                         }
642                         else if (!(flg & (PROJECT_PATH)))
643                         {
644                                 /* Always stop at non-initial wall grids */
645                                 if ((n > 0) && !cave_have_flag_bold(y, x, FF_PROJECT)) break;
646                         }
647
648                         /* Sometimes stop at non-initial monsters/players */
649                         if (flg & (PROJECT_STOP))
650                         {
651                                 if ((n > 0) &&
652                                         (player_bold(y, x) || cave[y][x].m_idx != 0))
653                                         break;
654                         }
655
656                         if (!in_bounds(y, x)) break;
657
658                         /* Advance (Y) */
659                         y += sy;
660
661                         /* Advance (X) */
662                         x += sx;
663                 }
664         }
665
666         /* Length */
667         return (n);
668 }
669
670
671
672 /*
673  * Mega-Hack -- track "affected" monsters (see "project()" comments)
674  */
675 static int project_m_n; /*!< 魔法効果範囲内にいるモンスターの数 */
676 static POSITION project_m_x; /*!< 処理中のモンスターX座標 */
677 static POSITION project_m_y; /*!< 処理中のモンスターY座標 */
678 /* Mega-Hack -- monsters target */
679 static POSITION monster_target_x; /*!< モンスターの攻撃目標X座標 */
680 static POSITION monster_target_y; /*!< モンスターの攻撃目標Y座標 */
681
682
683 /*!
684  * @brief 汎用的なビーム/ボルト/ボール系による地形効果処理 / We are called from "project()" to "damage" terrain features
685  * @param who 魔法を発動したモンスター(0ならばプレイヤー) / Index of "source" monster (zero for "player")
686  * @param r 効果半径(ビーム/ボルト = 0 / ボール = 1以上) / Radius of explosion (0 = beam/bolt, 1 to 9 = ball)
687  * @param y 目標Y座標 / Target y location (or location to travel "towards")
688  * @param x 目標X座標 / Target x location (or location to travel "towards")
689  * @param dam 基本威力 / Base damage roll to apply to affected monsters (or player)
690  * @param typ 効果属性 / Type of damage to apply to monsters (and objects)
691  * @return 何か一つでも効力があればTRUEを返す / TRUE if any "effects" of the projection were observed, else FALSE
692  * @details
693  * <pre>
694  * We are called both for "beam" effects and "ball" effects.
695  *
696  * The "r" parameter is the "distance from ground zero".
697  *
698  * Note that we determine if the player can "see" anything that happens
699  * by taking into account: blindness, line-of-sight, and illumination.
700  *
701  * We return "TRUE" if the effect of the projection is "obvious".
702  *
703  * XXX XXX XXX We also "see" grids which are "memorized", probably a hack
704  *
705  * XXX XXX XXX Perhaps we should affect doors?
706  * </pre>
707  */
708 static bool project_f(MONSTER_IDX who, POSITION r, POSITION y, POSITION x, HIT_POINT dam, EFFECT_ID typ)
709 {
710         cave_type *c_ptr = &cave[y][x];
711         feature_type *f_ptr = &f_info[c_ptr->feat];
712
713         bool obvious = FALSE;
714         bool known = player_has_los_bold(y, x);
715
716
717         /* XXX XXX XXX */
718         who = who ? who : 0;
719
720         /* Reduce damage by distance */
721         dam = (dam + r) / (r + 1);
722
723
724         if (have_flag(f_ptr->flags, FF_TREE))
725         {
726                 cptr message;
727                 switch (typ)
728                 {
729                 case GF_POIS:
730                 case GF_NUKE:
731                 case GF_DEATH_RAY:
732                         message = _("枯れた", "was blasted."); break;
733                 case GF_TIME:
734                         message = _("縮んだ", "shrank."); break;
735                 case GF_ACID:
736                         message = _("溶けた", "melted."); break;
737                 case GF_COLD:
738                 case GF_ICE:
739                         message = _("凍り、砕け散った", "was frozen and smashed."); break;
740                 case GF_FIRE:
741                 case GF_ELEC:
742                 case GF_PLASMA:
743                         message = _("燃えた", "burns up!"); break;
744                 case GF_METEOR:
745                 case GF_CHAOS:
746                 case GF_MANA:
747                 case GF_SEEKER:
748                 case GF_SUPER_RAY:
749                 case GF_SHARDS:
750                 case GF_ROCKET:
751                 case GF_SOUND:
752                 case GF_DISENCHANT:
753                 case GF_FORCE:
754                 case GF_GRAVITY:
755                         message = _("粉砕された", "was crushed."); break;
756                 default:
757                         message = NULL;break;
758                 }
759                 if (message)
760                 {
761                         msg_format(_("木は%s。", "A tree %s"), message);
762                         cave_set_feat(y, x, one_in_(3) ? feat_brake : feat_grass);
763
764                         /* Observe */
765                         if (c_ptr->info & (CAVE_MARK)) obvious = TRUE;
766                 }
767         }
768
769         /* Analyze the type */
770         switch (typ)
771         {
772                 /* Ignore most effects */
773                 case GF_CAPTURE:
774                 case GF_HAND_DOOM:
775                 case GF_CAUSE_1:
776                 case GF_CAUSE_2:
777                 case GF_CAUSE_3:
778                 case GF_CAUSE_4:
779                 case GF_MIND_BLAST:
780                 case GF_BRAIN_SMASH:
781                 case GF_DRAIN_MANA:
782                 case GF_PSY_SPEAR:
783                 case GF_FORCE:
784                 case GF_HOLY_FIRE:
785                 case GF_HELL_FIRE:
786                 case GF_PSI:
787                 case GF_PSI_DRAIN:
788                 case GF_TELEKINESIS:
789                 case GF_DOMINATION:
790                 case GF_IDENTIFY:
791                 case GF_ATTACK:
792                 case GF_ACID:
793                 case GF_ELEC:
794                 case GF_COLD:
795                 case GF_ICE:
796                 case GF_FIRE:
797                 case GF_PLASMA:
798                 case GF_METEOR:
799                 case GF_CHAOS:
800                 case GF_MANA:
801                 case GF_SEEKER:
802                 case GF_SUPER_RAY:
803                 {
804                         break;
805                 }
806
807                 /* Destroy Traps (and Locks) */
808                 case GF_KILL_TRAP:
809                 {
810                         /* Reveal secret doors */
811                         if (is_hidden_door(c_ptr))
812                         {
813                                 /* Pick a door */
814                                 disclose_grid(y, x);
815
816                                 /* Check line of sight */
817                                 if (known)
818                                 {
819                                         obvious = TRUE;
820                                 }
821                         }
822
823                         /* Destroy traps */
824                         if (is_trap(c_ptr->feat))
825                         {
826                                 /* Check line of sight */
827                                 if (known)
828                                 {
829                                         msg_print(_("まばゆい閃光が走った!", "There is a bright flash of light!"));
830                                         obvious = TRUE;
831                                 }
832
833                                 /* Destroy the trap */
834                                 cave_alter_feat(y, x, FF_DISARM);
835                         }
836
837                         /* Locked doors are unlocked */
838                         if (is_closed_door(c_ptr->feat) && f_ptr->power && have_flag(f_ptr->flags, FF_OPEN))
839                         {
840                                 s16b old_feat = c_ptr->feat;
841
842                                 /* Unlock the door */
843                                 cave_alter_feat(y, x, FF_DISARM);
844
845                                 /* Check line of sound */
846                                 if (known && (old_feat != c_ptr->feat))
847                                 {
848                                         msg_print(_("カチッと音がした!", "Click!"));
849                                         obvious = TRUE;
850                                 }
851                         }
852
853                         /* Remove "unsafe" flag if player is not blind */
854                         if (!p_ptr->blind && player_has_los_bold(y, x))
855                         {
856                                 c_ptr->info &= ~(CAVE_UNSAFE);
857
858                                 /* Redraw */
859                                 lite_spot(y, x);
860
861                                 obvious = TRUE;
862                         }
863
864                         break;
865                 }
866
867                 /* Destroy Doors (and traps) */
868                 case GF_KILL_DOOR:
869                 {
870                         /* Destroy all doors and traps */
871                         if (is_trap(c_ptr->feat) || have_flag(f_ptr->flags, FF_DOOR))
872                         {
873                                 /* Check line of sight */
874                                 if (known)
875                                 {
876                                         msg_print(_("まばゆい閃光が走った!", "There is a bright flash of light!"));
877                                         obvious = TRUE;
878                                 }
879
880                                 /* Destroy the feature */
881                                 cave_alter_feat(y, x, FF_TUNNEL);
882                         }
883
884                         /* Remove "unsafe" flag if player is not blind */
885                         if (!p_ptr->blind && player_has_los_bold(y, x))
886                         {
887                                 c_ptr->info &= ~(CAVE_UNSAFE);
888
889                                 /* Redraw */
890                                 lite_spot(y, x);
891
892                                 obvious = TRUE;
893                         }
894
895                         break;
896                 }
897
898                 case GF_JAM_DOOR: /* Jams a door (as if with a spike) */
899                 {
900                         if (have_flag(f_ptr->flags, FF_SPIKE))
901                         {
902                                 s16b old_mimic = c_ptr->mimic;
903                                 feature_type *mimic_f_ptr = &f_info[get_feat_mimic(c_ptr)];
904
905                                 cave_alter_feat(y, x, FF_SPIKE);
906
907                                 c_ptr->mimic = old_mimic;
908
909                                 /* Notice */
910                                 note_spot(y, x);
911
912                                 /* Redraw */
913                                 lite_spot(y, x);
914
915                                 /* Check line of sight */
916                                 if (known && have_flag(mimic_f_ptr->flags, FF_OPEN))
917                                 {
918                                         msg_format(_("%sに何かがつっかえて開かなくなった。", "The %s seems stuck."), f_name + mimic_f_ptr->name);
919                                         obvious = TRUE;
920                                 }
921                         }
922                         break;
923                 }
924
925                 /* Destroy walls (and doors) */
926                 case GF_KILL_WALL:
927                 {
928                         if (have_flag(f_ptr->flags, FF_HURT_ROCK))
929                         {
930                                 if (known && (c_ptr->info & (CAVE_MARK)))
931                                 {
932                                         msg_format(_("%sが溶けて泥になった!", "The %s turns into mud!"), f_name + f_info[get_feat_mimic(c_ptr)].name);
933                                         obvious = TRUE;
934                                 }
935
936                                 /* Destroy the wall */
937                                 cave_alter_feat(y, x, FF_HURT_ROCK);
938
939                                 /* Update some things */
940                                 p_ptr->update |= (PU_FLOW);
941                         }
942
943                         break;
944                 }
945
946                 /* Make doors */
947                 case GF_MAKE_DOOR:
948                 {
949                         /* Require a "naked" floor grid */
950                         if (!cave_naked_bold(y, x)) break;
951
952                         /* Not on the player */
953                         if (player_bold(y, x)) break;
954
955                         /* Create a closed door */
956                         cave_set_feat(y, x, feat_door[DOOR_DOOR].closed);
957
958                         /* Observe */
959                         if (c_ptr->info & (CAVE_MARK)) obvious = TRUE;
960
961                         break;
962                 }
963
964                 /* Make traps */
965                 case GF_MAKE_TRAP:
966                 {
967                         /* Place a trap */
968                         place_trap(y, x);
969
970                         break;
971                 }
972
973                 /* Make doors */
974                 case GF_MAKE_TREE:
975                 {
976                         /* Require a "naked" floor grid */
977                         if (!cave_naked_bold(y, x)) break;
978
979                         /* Not on the player */
980                         if (player_bold(y, x)) break;
981
982                         /* Create a closed door */
983                         cave_set_feat(y, x, feat_tree);
984
985                         /* Observe */
986                         if (c_ptr->info & (CAVE_MARK)) obvious = TRUE;
987
988
989                         break;
990                 }
991
992                 case GF_MAKE_GLYPH:
993                 {
994                         /* Require a "naked" floor grid */
995                         if (!cave_naked_bold(y, x)) break;
996
997                         /* Create a glyph */
998                         c_ptr->info |= CAVE_OBJECT;
999                         c_ptr->mimic = feat_glyph;
1000
1001                         /* Notice */
1002                         note_spot(y, x);
1003
1004                         /* Redraw */
1005                         lite_spot(y, x);
1006
1007                         break;
1008                 }
1009
1010                 case GF_STONE_WALL:
1011                 {
1012                         /* Require a "naked" floor grid */
1013                         if (!cave_naked_bold(y, x)) break;
1014
1015                         /* Not on the player */
1016                         if (player_bold(y, x)) break;
1017
1018                         /* Place a wall */
1019                         cave_set_feat(y, x, feat_granite);
1020
1021                         break;
1022                 }
1023
1024
1025                 case GF_LAVA_FLOW:
1026                 {
1027                         /* Ignore permanent grid */
1028                         if (have_flag(f_ptr->flags, FF_PERMANENT)) break;
1029
1030                         /* Shallow Lava */
1031                         if (dam == 1)
1032                         {
1033                                 /* Ignore grid without enough space */
1034                                 if (!have_flag(f_ptr->flags, FF_FLOOR)) break;
1035
1036                                 /* Place a shallow lava */
1037                                 cave_set_feat(y, x, feat_shallow_lava);
1038                         }
1039                         /* Deep Lava */
1040                         else if (dam)
1041                         {
1042                                 /* Place a deep lava */
1043                                 cave_set_feat(y, x, feat_deep_lava);
1044                         }
1045                         break;
1046                 }
1047
1048                 case GF_WATER_FLOW:
1049                 {
1050                         /* Ignore permanent grid */
1051                         if (have_flag(f_ptr->flags, FF_PERMANENT)) break;
1052
1053                         /* Shallow Water */
1054                         if (dam == 1)
1055                         {
1056                                 /* Ignore grid without enough space */
1057                                 if (!have_flag(f_ptr->flags, FF_FLOOR)) break;
1058
1059                                 /* Place a shallow water */
1060                                 cave_set_feat(y, x, feat_shallow_water);
1061                         }
1062                         /* Deep Water */
1063                         else if (dam)
1064                         {
1065                                 /* Place a deep water */
1066                                 cave_set_feat(y, x, feat_deep_water);
1067                         }
1068                         break;
1069                 }
1070
1071                 /* Lite up the grid */
1072                 case GF_LITE_WEAK:
1073                 case GF_LITE:
1074                 {
1075                         /* Turn on the light */
1076                         if (!(d_info[dungeon_type].flags1 & DF1_DARKNESS))
1077                         {
1078                                 c_ptr->info |= (CAVE_GLOW);
1079
1080                                 /* Notice */
1081                                 note_spot(y, x);
1082
1083                                 /* Redraw */
1084                                 lite_spot(y, x);
1085
1086                                 update_local_illumination(y, x);
1087
1088                                 /* Observe */
1089                                 if (player_can_see_bold(y, x)) obvious = TRUE;
1090
1091                                 /* Mega-Hack -- Update the monster in the affected grid */
1092                                 /* This allows "spear of light" (etc) to work "correctly" */
1093                                 if (c_ptr->m_idx) update_mon(c_ptr->m_idx, FALSE);
1094
1095                                 if (p_ptr->special_defense & NINJA_S_STEALTH)
1096                                 {
1097                                         if (player_bold(y, x)) set_superstealth(FALSE);
1098                                 }
1099                         }
1100
1101                         break;
1102                 }
1103
1104                 /* Darken the grid */
1105                 case GF_DARK_WEAK:
1106                 case GF_DARK:
1107                 {
1108                         bool do_dark = !p_ptr->inside_battle && !is_mirror_grid(c_ptr);
1109                         int j;
1110
1111                         /* Turn off the light. */
1112                         if (do_dark)
1113                         {
1114                                 if (dun_level || !is_daytime())
1115                                 {
1116                                         for (j = 0; j < 9; j++)
1117                                         {
1118                                                 int by = y + ddy_ddd[j];
1119                                                 int bx = x + ddx_ddd[j];
1120
1121                                                 if (in_bounds2(by, bx))
1122                                                 {
1123                                                         cave_type *cc_ptr = &cave[by][bx];
1124
1125                                                         if (have_flag(f_info[get_feat_mimic(cc_ptr)].flags, FF_GLOW))
1126                                                         {
1127                                                                 do_dark = FALSE;
1128                                                                 break;
1129                                                         }
1130                                                 }
1131                                         }
1132
1133                                         if (!do_dark) break;
1134                                 }
1135
1136                                 c_ptr->info &= ~(CAVE_GLOW);
1137
1138                                 /* Hack -- Forget "boring" grids */
1139                                 if (!have_flag(f_ptr->flags, FF_REMEMBER))
1140                                 {
1141                                         /* Forget */
1142                                         c_ptr->info &= ~(CAVE_MARK);
1143
1144                                         /* Notice */
1145                                         note_spot(y, x);
1146                                 }
1147
1148                                 /* Redraw */
1149                                 lite_spot(y, x);
1150
1151                                 update_local_illumination(y, x);
1152
1153                                 /* Notice */
1154                                 if (player_can_see_bold(y, x)) obvious = TRUE;
1155
1156                                 /* Mega-Hack -- Update the monster in the affected grid */
1157                                 /* This allows "spear of light" (etc) to work "correctly" */
1158                                 if (c_ptr->m_idx) update_mon(c_ptr->m_idx, FALSE);
1159                         }
1160
1161                         /* All done */
1162                         break;
1163                 }
1164
1165                 case GF_SHARDS:
1166                 case GF_ROCKET:
1167                 {
1168                         if (is_mirror_grid(c_ptr))
1169                         {
1170                                 msg_print(_("鏡が割れた!", "The mirror was crashed!"));
1171                                 sound(SOUND_GLASS);
1172                                 remove_mirror(y, x);
1173                                 project(0, 2, y, x, p_ptr->lev / 2 + 5, GF_SHARDS, (PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL | PROJECT_JUMP | PROJECT_NO_HANGEKI), -1);
1174                         }
1175
1176                         if (have_flag(f_ptr->flags, FF_GLASS) && !have_flag(f_ptr->flags, FF_PERMANENT) && (dam >= 50))
1177                         {
1178                                 if (known && (c_ptr->info & CAVE_MARK))
1179                                 {
1180                                         msg_format(_("%sが割れた!", "The %s was crashed!"), f_name + f_info[get_feat_mimic(c_ptr)].name);
1181                                         sound(SOUND_GLASS);
1182                                 }
1183
1184                                 /* Destroy the wall */
1185                                 cave_alter_feat(y, x, FF_HURT_ROCK);
1186
1187                                 /* Update some things */
1188                                 p_ptr->update |= (PU_FLOW);
1189                         }
1190                         break;
1191                 }
1192
1193                 case GF_SOUND:
1194                 {
1195                         if (is_mirror_grid(c_ptr) && p_ptr->lev < 40)
1196                         {
1197                                 msg_print(_("鏡が割れた!", "The mirror was crashed!"));
1198                                 sound(SOUND_GLASS);
1199                                 remove_mirror(y, x);
1200                                 project(0, 2, y, x, p_ptr->lev / 2 + 5, GF_SHARDS, (PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL | PROJECT_JUMP | PROJECT_NO_HANGEKI), -1);
1201                         }
1202
1203                         if (have_flag(f_ptr->flags, FF_GLASS) && !have_flag(f_ptr->flags, FF_PERMANENT) && (dam >= 200))
1204                         {
1205                                 if (known && (c_ptr->info & CAVE_MARK))
1206                                 {
1207                                         msg_format(_("%sが割れた!", "The %s was crashed!"), f_name + f_info[get_feat_mimic(c_ptr)].name);
1208                                         sound(SOUND_GLASS);
1209                                 }
1210
1211                                 /* Destroy the wall */
1212                                 cave_alter_feat(y, x, FF_HURT_ROCK);
1213
1214                                 /* Update some things */
1215                                 p_ptr->update |= (PU_FLOW);
1216                         }
1217                         break;
1218                 }
1219
1220                 case GF_DISINTEGRATE:
1221                 {
1222                         /* Destroy mirror/glyph */
1223                         if (is_mirror_grid(c_ptr) || is_glyph_grid(c_ptr) || is_explosive_rune_grid(c_ptr))
1224                                 remove_mirror(y, x);
1225
1226                         /* Permanent features don't get effect */
1227                         /* But not protect monsters and other objects */
1228                         if (have_flag(f_ptr->flags, FF_HURT_DISI) && !have_flag(f_ptr->flags, FF_PERMANENT))
1229                         {
1230                                 cave_alter_feat(y, x, FF_HURT_DISI);
1231
1232                                 /* Update some things -- similar to GF_KILL_WALL */
1233                                 p_ptr->update |= (PU_FLOW);
1234                         }
1235                         break;
1236                 }
1237         }
1238
1239         lite_spot(y, x);
1240         /* Return "Anything seen?" */
1241         return (obvious);
1242 }
1243
1244
1245
1246 /*!
1247  * @brief 汎用的なビーム/ボルト/ボール系によるアイテムオブジェクトへの効果処理 / Handle a beam/bolt/ball causing damage to a monster.
1248  * @param who 魔法を発動したモンスター(0ならばプレイヤー) / Index of "source" monster (zero for "player")
1249  * @param r 効果半径(ビーム/ボルト = 0 / ボール = 1以上) / Radius of explosion (0 = beam/bolt, 1 to 9 = ball)
1250  * @param y 目標Y座標 / Target y location (or location to travel "towards")
1251  * @param x 目標X座標 / Target x location (or location to travel "towards")
1252  * @param dam 基本威力 / Base damage roll to apply to affected monsters (or player)
1253  * @param typ 効果属性 / Type of damage to apply to monsters (and objects)
1254  * @return 何か一つでも効力があればTRUEを返す / TRUE if any "effects" of the projection were observed, else FALSE
1255  * @details
1256  * <pre>
1257  * We are called from "project()" to "damage" objects
1258  *
1259  * We are called both for "beam" effects and "ball" effects.
1260  *
1261  * Perhaps we should only SOMETIMES damage things on the ground.
1262  *
1263  * The "r" parameter is the "distance from ground zero".
1264  *
1265  * Note that we determine if the player can "see" anything that happens
1266  * by taking into account: blindness, line-of-sight, and illumination.
1267  *
1268  * XXX XXX XXX We also "see" grids which are "memorized", probably a hack
1269  *
1270  * We return "TRUE" if the effect of the projection is "obvious".
1271  * </pre>
1272  */
1273 static bool project_o(MONSTER_IDX who, POSITION r, POSITION y, POSITION x, HIT_POINT dam, EFFECT_ID typ)
1274 {
1275         cave_type *c_ptr = &cave[y][x];
1276
1277         OBJECT_IDX this_o_idx, next_o_idx = 0;
1278
1279         bool obvious = FALSE;
1280         bool known = player_has_los_bold(y, x);
1281
1282         BIT_FLAGS flgs[TR_FLAG_SIZE];
1283
1284         char o_name[MAX_NLEN];
1285
1286         KIND_OBJECT_IDX k_idx = 0;
1287         bool is_potion = FALSE;
1288
1289
1290         /* XXX XXX XXX */
1291         who = who ? who : 0;
1292
1293         /* Reduce damage by distance */
1294         dam = (dam + r) / (r + 1);
1295
1296
1297         /* Scan all objects in the grid */
1298         for (this_o_idx = c_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
1299         {
1300                 /* Acquire object */
1301                 object_type *o_ptr = &o_list[this_o_idx];
1302
1303                 bool is_art = FALSE;
1304                 bool ignore = FALSE;
1305                 bool do_kill = FALSE;
1306
1307                 cptr note_kill = NULL;
1308
1309 #ifndef JP
1310                 /* Get the "plural"-ness */
1311                 bool plural = (o_ptr->number > 1);
1312 #endif
1313
1314                 /* Acquire next object */
1315                 next_o_idx = o_ptr->next_o_idx;
1316
1317                 /* Extract the flags */
1318                 object_flags(o_ptr, flgs);
1319
1320                 /* Check for artifact */
1321                 if (object_is_artifact(o_ptr)) is_art = TRUE;
1322
1323                 /* Analyze the type */
1324                 switch (typ)
1325                 {
1326                         /* Acid -- Lots of things */
1327                         case GF_ACID:
1328                         {
1329                                 if (hates_acid(o_ptr))
1330                                 {
1331                                         do_kill = TRUE;
1332                                         note_kill = _("融けてしまった!", (plural ? " melt!" : " melts!"));
1333                                         if (have_flag(flgs, TR_IGNORE_ACID)) ignore = TRUE;
1334                                 }
1335                                 break;
1336                         }
1337
1338                         /* Elec -- Rings and Wands */
1339                         case GF_ELEC:
1340                         {
1341                                 if (hates_elec(o_ptr))
1342                                 {
1343                                         do_kill = TRUE;
1344                                         note_kill = _("壊れてしまった!", (plural ? " are destroyed!" : " is destroyed!"));
1345                                         if (have_flag(flgs, TR_IGNORE_ELEC)) ignore = TRUE;
1346                                 }
1347                                 break;
1348                         }
1349
1350                         /* Fire -- Flammable objects */
1351                         case GF_FIRE:
1352                         {
1353                                 if (hates_fire(o_ptr))
1354                                 {
1355                                         do_kill = TRUE;
1356                                         note_kill = _("燃えてしまった!", (plural ? " burn up!" : " burns up!"));
1357                                         if (have_flag(flgs, TR_IGNORE_FIRE)) ignore = TRUE;
1358                                 }
1359                                 break;
1360                         }
1361
1362                         /* Cold -- potions and flasks */
1363                         case GF_COLD:
1364                         {
1365                                 if (hates_cold(o_ptr))
1366                                 {
1367                                         note_kill = _("砕け散ってしまった!", (plural ? " shatter!" : " shatters!"));
1368                                         do_kill = TRUE;
1369                                         if (have_flag(flgs, TR_IGNORE_COLD)) ignore = TRUE;
1370                                 }
1371                                 break;
1372                         }
1373
1374                         /* Fire + Elec */
1375                         case GF_PLASMA:
1376                         {
1377                                 if (hates_fire(o_ptr))
1378                                 {
1379                                         do_kill = TRUE;
1380                                         note_kill = _("燃えてしまった!", (plural ? " burn up!" : " burns up!"));
1381                                         if (have_flag(flgs, TR_IGNORE_FIRE)) ignore = TRUE;
1382                                 }
1383                                 if (hates_elec(o_ptr))
1384                                 {
1385                                         ignore = FALSE;
1386                                         do_kill = TRUE;
1387                                         note_kill = _("壊れてしまった!", (plural ? " are destroyed!" : " is destroyed!"));
1388                                         if (have_flag(flgs, TR_IGNORE_ELEC)) ignore = TRUE;
1389                                 }
1390                                 break;
1391                         }
1392
1393                         /* Fire + Cold */
1394                         case GF_METEOR:
1395                         {
1396                                 if (hates_fire(o_ptr))
1397                                 {
1398                                         do_kill = TRUE;
1399                                         note_kill = _("燃えてしまった!", (plural ? " burn up!" : " burns up!"));
1400                                         if (have_flag(flgs, TR_IGNORE_FIRE)) ignore = TRUE;
1401                                 }
1402                                 if (hates_cold(o_ptr))
1403                                 {
1404                                         ignore = FALSE;
1405                                         do_kill = TRUE;
1406                                         note_kill = _("砕け散ってしまった!", (plural ? " shatter!" : " shatters!"));
1407                                         if (have_flag(flgs, TR_IGNORE_COLD)) ignore = TRUE;
1408                                 }
1409                                 break;
1410                         }
1411
1412                         /* Hack -- break potions and such */
1413                         case GF_ICE:
1414                         case GF_SHARDS:
1415                         case GF_FORCE:
1416                         case GF_SOUND:
1417                         {
1418                                 if (hates_cold(o_ptr))
1419                                 {
1420                                         note_kill = _("砕け散ってしまった!", (plural ? " shatter!" : " shatters!"));
1421                                         do_kill = TRUE;
1422                                 }
1423                                 break;
1424                         }
1425
1426                         /* Mana and Chaos -- destroy everything */
1427                         case GF_MANA:
1428                         case GF_SEEKER:
1429                         case GF_SUPER_RAY:
1430                         {
1431                                 do_kill = TRUE;
1432                                 note_kill = _("壊れてしまった!", (plural ? " are destroyed!" : " is destroyed!"));
1433                                 break;
1434                         }
1435
1436                         case GF_DISINTEGRATE:
1437                         {
1438                                 do_kill = TRUE;
1439                                 note_kill = _("蒸発してしまった!", (plural ? " evaporate!" : " evaporates!"));
1440                                 break;
1441                         }
1442
1443                         case GF_CHAOS:
1444                         {
1445                                 do_kill = TRUE;
1446                                 note_kill = _("壊れてしまった!", (plural ? " are destroyed!" : " is destroyed!"));
1447                                 if (have_flag(flgs, TR_RES_CHAOS)) ignore = TRUE;
1448                                 else if ((o_ptr->tval == TV_SCROLL) && (o_ptr->sval == SV_SCROLL_CHAOS)) ignore = TRUE;
1449                                 break;
1450                         }
1451
1452                         /* Holy Fire and Hell Fire -- destroys cursed non-artifacts */
1453                         case GF_HOLY_FIRE:
1454                         case GF_HELL_FIRE:
1455                         {
1456                                 if (object_is_cursed(o_ptr))
1457                                 {
1458                                         do_kill = TRUE;
1459                                         note_kill = _("壊れてしまった!", (plural ? " are destroyed!" : " is destroyed!"));
1460                                 }
1461                                 break;
1462                         }
1463
1464                         case GF_IDENTIFY:
1465                         {
1466                                 identify_item(o_ptr);
1467
1468                                 /* Auto-inscription */
1469                                 autopick_alter_item((-this_o_idx), FALSE);
1470                                 break;
1471                         }
1472
1473                         /* Unlock chests */
1474                         case GF_KILL_TRAP:
1475                         case GF_KILL_DOOR:
1476                         {
1477                                 /* Chests are noticed only if trapped or locked */
1478                                 if (o_ptr->tval == TV_CHEST)
1479                                 {
1480                                         /* Disarm/Unlock traps */
1481                                         if (o_ptr->pval > 0)
1482                                         {
1483                                                 /* Disarm or Unlock */
1484                                                 o_ptr->pval = (0 - o_ptr->pval);
1485
1486                                                 /* Identify */
1487                                                 object_known(o_ptr);
1488
1489                                                 /* Notice */
1490                                                 if (known && (o_ptr->marked & OM_FOUND))
1491                                                 {
1492                                                         msg_print(_("カチッと音がした!", "Click!"));
1493                                                         obvious = TRUE;
1494                                                 }
1495                                         }
1496                                 }
1497
1498                                 break;
1499                         }
1500                         case GF_ANIM_DEAD:
1501                         {
1502                                 if (o_ptr->tval == TV_CORPSE)
1503                                 {
1504                                         int i;
1505                                         BIT_FLAGS mode = 0L;
1506
1507                                         if (!who || is_pet(&m_list[who]))
1508                                                 mode |= PM_FORCE_PET;
1509
1510                                         for (i = 0; i < o_ptr->number ; i++)
1511                                         {
1512                                                 if (((o_ptr->sval == SV_CORPSE) && (randint1(100) > 80)) ||
1513                                                         ((o_ptr->sval == SV_SKELETON) && (randint1(100) > 60)))
1514                                                 {
1515                                                         if (!note_kill)
1516                                                         {
1517                                                                 note_kill = _("灰になった。", (plural ? " become dust." : " becomes dust."));
1518                                                         }
1519                                                         continue;
1520                                                 }
1521                                                 else if (summon_named_creature(who, y, x, o_ptr->pval, mode))
1522                                                 {
1523                                                         note_kill = _("生き返った。", " revived.");
1524                                                 }
1525                                                 else if (!note_kill)
1526                                                 {
1527                                                         note_kill = _("灰になった。", (plural ? " become dust." : " becomes dust."));
1528                                                 }
1529                                         }
1530                                         do_kill = TRUE;
1531                                         obvious = TRUE;
1532                                 }
1533                                 break;
1534                         }
1535                 }
1536
1537
1538                 /* Attempt to destroy the object */
1539                 if (do_kill)
1540                 {
1541                         /* Effect "observed" */
1542                         if (known && (o_ptr->marked & OM_FOUND))
1543                         {
1544                                 obvious = TRUE;
1545                                 object_desc(o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
1546                         }
1547
1548                         /* Artifacts, and other objects, get to resist */
1549                         if (is_art || ignore)
1550                         {
1551                                 /* Observe the resist */
1552                                 if (known && (o_ptr->marked & OM_FOUND))
1553                                 {
1554                                         msg_format(_("%sは影響を受けない!", 
1555                                            (plural ? "The %s are unaffected!" : "The %s is unaffected!")), o_name);
1556                                 }
1557                         }
1558
1559                         /* Kill it */
1560                         else
1561                         {
1562                                 /* Describe if needed */
1563                                 if (known && (o_ptr->marked & OM_FOUND) && note_kill)
1564                                 {
1565                                         msg_format(_("%sは%s", "The %s%s"), o_name, note_kill);
1566                                 }
1567
1568                                 k_idx = o_ptr->k_idx;
1569                                 is_potion = object_is_potion(o_ptr);
1570
1571
1572                                 /* Delete the object */
1573                                 delete_object_idx(this_o_idx);
1574
1575                                 /* Potions produce effects when 'shattered' */
1576                                 if (is_potion)
1577                                 {
1578                                         (void)potion_smash_effect(who, y, x, k_idx);
1579                                 }
1580
1581                                 /* Redraw */
1582                                 lite_spot(y, x);
1583                         }
1584                 }
1585         }
1586
1587         /* Return "Anything seen?" */
1588         return (obvious);
1589 }
1590
1591
1592 /*!
1593  * @brief 汎用的なビーム/ボルト/ボール系によるモンスターへの効果処理 / Handle a beam/bolt/ball causing damage to a monster.
1594  * @param who 魔法を発動したモンスター(0ならばプレイヤー) / Index of "source" monster (zero for "player")
1595  * @param r 効果半径(ビーム/ボルト = 0 / ボール = 1以上) / Radius of explosion (0 = beam/bolt, 1 to 9 = ball)
1596  * @param y 目標Y座標 / Target y location (or location to travel "towards")
1597  * @param x 目標X座標 / Target x location (or location to travel "towards")
1598  * @param dam 基本威力 / Base damage roll to apply to affected monsters (or player)
1599  * @param typ 効果属性 / Type of damage to apply to monsters (and objects)
1600  * @param flg 効果フラグ
1601  * @param see_s_msg TRUEならばメッセージを表示する
1602  * @return 何か一つでも効力があればTRUEを返す / TRUE if any "effects" of the projection were observed, else FALSE
1603  * @details
1604  * <pre>
1605  * This routine takes a "source monster" (by index) which is mostly used to
1606  * determine if the player is causing the damage, and a "radius" (see below),
1607  * which is used to decrease the power of explosions with distance, and a
1608  * location, via integers which are modified by certain types of attacks
1609  * (polymorph and teleport being the obvious ones), a default damage, which
1610  * is modified as needed based on various properties, and finally a "damage
1611  * type" (see below).
1612  * </pre>
1613  * <pre>
1614  * Note that this routine can handle "no damage" attacks (like teleport) by
1615  * taking a "zero" damage, and can even take "parameters" to attacks (like
1616  * confuse) by accepting a "damage", using it to calculate the effect, and
1617  * then setting the damage to zero.  Note that the "damage" parameter is
1618  * divided by the radius, so monsters not at the "epicenter" will not take
1619  * as much damage (or whatever)...
1620  * </pre>
1621  * <pre>
1622  * Note that "polymorph" is dangerous, since a failure in "place_monster()"'
1623  * may result in a dereference of an invalid pointer.  XXX XXX XXX
1624  * </pre>
1625  * <pre>
1626  * Various messages are produced, and damage is applied.
1627  * </pre>
1628  * <pre>
1629  * Just "casting" a substance (i.e. plasma) does not make you immune, you must
1630  * actually be "made" of that substance, or "breathe" big balls of it.
1631  * We assume that "Plasma" monsters, and "Plasma" breathers, are immune
1632  * to plasma.
1633  * We assume "Nether" is an evil, necromantic force, so it doesn't hurt undead,
1634  * and hurts evil less.  If can breath nether, then it resists it as well.
1635  * </pre>
1636  * <pre>
1637  * Damage reductions use the following formulas:
1638  *   Note that "dam = dam * 6 / (randint1(6) + 6);"
1639  *       gives avg damage of .655, ranging from .858 to .500
1640  *   Note that "dam = dam * 5 / (randint1(6) + 6);"
1641  *       gives avg damage of .544, ranging from .714 to .417
1642  *   Note that "dam = dam * 4 / (randint1(6) + 6);"
1643  *       gives avg damage of .444, ranging from .556 to .333
1644  *   Note that "dam = dam * 3 / (randint1(6) + 6);"
1645  *       gives avg damage of .327, ranging from .427 to .250
1646  *   Note that "dam = dam * 2 / (randint1(6) + 6);"
1647  *       gives something simple.
1648  * </pre>
1649  * <pre>
1650  * In this function, "result" messages are postponed until the end, where
1651  * the "note" string is appended to the monster name, if not NULL.  So,
1652  * to make a spell have "no effect" just set "note" to NULL.  You should
1653  * also set "notice" to FALSE, or the player will learn what the spell does.
1654  * </pre>
1655  * <pre>
1656  * We attempt to return "TRUE" if the player saw anything "useful" happen.
1657  * "flg" was added.
1658  * </pre>
1659  */
1660 static bool project_m(MONSTER_IDX who, POSITION r, POSITION y, POSITION x, HIT_POINT dam, EFFECT_ID typ, BIT_FLAGS flg, bool see_s_msg)
1661 {
1662         int tmp;
1663
1664         cave_type *c_ptr = &cave[y][x];
1665
1666         monster_type *m_ptr = &m_list[c_ptr->m_idx];
1667         monster_type *caster_ptr = (who > 0) ? &m_list[who] : NULL;
1668
1669         monster_race *r_ptr = &r_info[m_ptr->r_idx];
1670
1671         char killer[80];
1672
1673         /* Is the monster "seen"? */
1674         bool seen = m_ptr->ml;
1675         bool seen_msg = is_seen(m_ptr);
1676
1677         bool slept = (bool)MON_CSLEEP(m_ptr);
1678
1679         /* Were the effects "obvious" (if seen)? */
1680         bool obvious = FALSE;
1681
1682         /* Can the player know about this effect? */
1683         bool known = ((m_ptr->cdis <= MAX_SIGHT) || p_ptr->inside_battle);
1684
1685         /* Were the effects "irrelevant"? */
1686         bool skipped = FALSE;
1687
1688         /* Gets the monster angry at the source of the effect? */
1689         bool get_angry = FALSE;
1690
1691         /* Polymorph setting (true or false) */
1692         bool do_poly = FALSE;
1693
1694         /* Teleport setting (max distance) */
1695         int do_dist = 0;
1696
1697         /* Confusion setting (amount to confuse) */
1698         int do_conf = 0;
1699
1700         /* Stunning setting (amount to stun) */
1701         int do_stun = 0;
1702
1703         /* Sleep amount (amount to sleep) */
1704         int do_sleep = 0;
1705
1706         /* Fear amount (amount to fear) */
1707         int do_fear = 0;
1708
1709         /* Time amount (amount to time) */
1710         int do_time = 0;
1711
1712         bool heal_leper = FALSE;
1713
1714         /* Hold the monster name */
1715         char m_name[80];
1716         char m_poss[10];
1717
1718         PARAMETER_VALUE photo = 0;
1719
1720         /* Assume no note */
1721         cptr note = NULL;
1722
1723         /* Assume a default death */
1724         cptr note_dies = extract_note_dies(real_r_ptr(m_ptr));
1725
1726         int ty = m_ptr->fy;
1727         int tx = m_ptr->fx;
1728
1729         int caster_lev = (who > 0) ? r_info[caster_ptr->r_idx].level : (p_ptr->lev * 2);
1730
1731         /* Nobody here */
1732         if (!c_ptr->m_idx) return (FALSE);
1733
1734         /* Never affect projector */
1735         if (who && (c_ptr->m_idx == who)) return (FALSE);
1736         if ((c_ptr->m_idx == p_ptr->riding) && !who && !(typ == GF_OLD_HEAL) && !(typ == GF_OLD_SPEED) && !(typ == GF_STAR_HEAL)) return (FALSE);
1737         if (sukekaku && ((m_ptr->r_idx == MON_SUKE) || (m_ptr->r_idx == MON_KAKU))) return FALSE;
1738
1739         /* Don't affect already death monsters */
1740         /* Prevents problems with chain reactions of exploding monsters */
1741         if (m_ptr->hp < 0) return (FALSE);
1742
1743         /* Reduce damage by distance */
1744         dam = (dam + r) / (r + 1);
1745
1746
1747         /* Get the monster name (BEFORE polymorphing) */
1748         monster_desc(m_name, m_ptr, 0);
1749
1750         /* Get the monster possessive ("his"/"her"/"its") */
1751         monster_desc(m_poss, m_ptr, MD_PRON_VISIBLE | MD_POSSESSIVE);
1752
1753         if (p_ptr->riding && (c_ptr->m_idx == p_ptr->riding)) disturb(1, 1);
1754
1755         /* Analyze the damage type */
1756         switch (typ)
1757         {
1758                 /* Magic Missile -- pure damage */
1759                 case GF_MISSILE:
1760                 {
1761                         if (seen) obvious = TRUE;
1762
1763                         if (r_ptr->flagsr & RFR_RES_ALL)
1764                         {
1765                                 note = _("には完全な耐性がある!", " is immune.");
1766                                 dam = 0;
1767                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
1768                                 break;
1769                         }
1770                         break;
1771                 }
1772
1773                 /* Acid */
1774                 case GF_ACID:
1775                 {
1776                         if (seen) obvious = TRUE;
1777
1778                         if (r_ptr->flagsr & RFR_RES_ALL)
1779                         {
1780                                 note = _("には完全な耐性がある!", " is immune.");
1781                                 dam = 0;
1782                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
1783                                 break;
1784                         }
1785                         if (r_ptr->flagsr & RFR_IM_ACID)
1786                         {
1787                                 note = _("にはかなり耐性がある!", " resists a lot.");
1788                                 dam /= 9;
1789                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_IM_ACID);
1790                         }
1791                         break;
1792                 }
1793
1794                 /* Electricity */
1795                 case GF_ELEC:
1796                 {
1797                         if (seen) obvious = TRUE;
1798
1799                         if (r_ptr->flagsr & RFR_RES_ALL)
1800                         {
1801                                 note = _("には完全な耐性がある!", " is immune.");
1802                                 dam = 0;
1803                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
1804                                 break;
1805                         }
1806                         if (r_ptr->flagsr & RFR_IM_ELEC)
1807                         {
1808                                 note = _("にはかなり耐性がある!", " resists a lot.");
1809                                 dam /= 9;
1810                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_IM_ELEC);
1811                         }
1812                         break;
1813                 }
1814
1815                 /* Fire damage */
1816                 case GF_FIRE:
1817                 {
1818                         if (seen) obvious = TRUE;
1819
1820                         if (r_ptr->flagsr & RFR_RES_ALL)
1821                         {
1822                                 note = _("には完全な耐性がある!", " is immune.");
1823                                 dam = 0;
1824                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
1825                                 break;
1826                         }
1827                         if (r_ptr->flagsr & RFR_IM_FIRE)
1828                         {
1829                                 note = _("にはかなり耐性がある!", " resists a lot.");
1830                                 dam /= 9;
1831                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_IM_FIRE);
1832                         }
1833                         else if (r_ptr->flags3 & (RF3_HURT_FIRE))
1834                         {
1835                                 note = _("はひどい痛手をうけた。", " is hit hard.");
1836                                 dam *= 2;
1837                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags3 |= (RF3_HURT_FIRE);
1838                         }
1839                         break;
1840                 }
1841
1842                 /* Cold */
1843                 case GF_COLD:
1844                 {
1845                         if (seen) obvious = TRUE;
1846
1847                         if (r_ptr->flagsr & RFR_RES_ALL)
1848                         {
1849                                 note = _("には完全な耐性がある!", " is immune.");
1850                                 dam = 0;
1851                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
1852                                 break;
1853                         }
1854                         if (r_ptr->flagsr & RFR_IM_COLD)
1855                         {
1856                                 note = _("にはかなり耐性がある!", " resists a lot.");
1857                                 dam /= 9;
1858                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_IM_COLD);
1859                         }
1860                         else if (r_ptr->flags3 & (RF3_HURT_COLD))
1861                         {
1862                                 note = _("はひどい痛手をうけた。", " is hit hard.");
1863                                 dam *= 2;
1864                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags3 |= (RF3_HURT_COLD);
1865                         }
1866                         break;
1867                 }
1868
1869                 /* Poison */
1870                 case GF_POIS:
1871                 {
1872                         if (seen) obvious = TRUE;
1873
1874                         if (r_ptr->flagsr & RFR_RES_ALL)
1875                         {
1876                                 note = _("には完全な耐性がある!", " is immune.");
1877                                 dam = 0;
1878                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
1879                                 break;
1880                         }
1881                         if (r_ptr->flagsr & RFR_IM_POIS)
1882                         {
1883                                 note = _("にはかなり耐性がある!", " resists a lot.");
1884                                 dam /= 9;
1885                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_IM_POIS);
1886                         }
1887                         break;
1888                 }
1889
1890                 /* Nuclear waste */
1891                 case GF_NUKE:
1892                 {
1893                         if (seen) obvious = TRUE;
1894
1895                         if (r_ptr->flagsr & RFR_RES_ALL)
1896                         {
1897                                 note = _("には完全な耐性がある!", " is immune.");
1898                                 dam = 0;
1899                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
1900                                 break;
1901                         }
1902                         if (r_ptr->flagsr & RFR_IM_POIS)
1903                         {
1904                                 note = _("には耐性がある。", " resists.");
1905                                 dam *= 3; dam /= randint1(6) + 6;
1906                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_IM_POIS);
1907                         }
1908                         else if (one_in_(3)) do_poly = TRUE;
1909                         break;
1910                 }
1911
1912                 /* Hellfire -- hurts Evil */
1913                 case GF_HELL_FIRE:
1914                 {
1915                         if (seen) obvious = TRUE;
1916
1917                         if (r_ptr->flagsr & RFR_RES_ALL)
1918                         {
1919                                 note = _("には完全な耐性がある!", " is immune.");
1920                                 dam = 0;
1921                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
1922                                 break;
1923                         }
1924                         if (r_ptr->flags3 & RF3_GOOD)
1925                         {
1926                                 note = _("はひどい痛手をうけた。", " is hit hard.");
1927                                 dam *= 2;
1928                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags3 |= (RF3_GOOD);
1929                         }
1930                         break;
1931                 }
1932
1933                 /* Holy Fire -- hurts Evil, Good are immune, others _resist_ */
1934                 case GF_HOLY_FIRE:
1935                 {
1936                         if (seen) obvious = TRUE;
1937
1938                         if (r_ptr->flagsr & RFR_RES_ALL)
1939                         {
1940                                 note = _("には完全な耐性がある!", " is immune.");
1941                                 dam = 0;
1942                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
1943                                 break;
1944                         }
1945                         if (r_ptr->flags3 & RF3_GOOD)
1946                         {
1947                                 note = _("には完全な耐性がある!", " is immune.");
1948                                 dam = 0;
1949                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags3 |= RF3_GOOD;
1950                         }
1951                         else if (r_ptr->flags3 & RF3_EVIL)
1952                         {
1953                                 dam *= 2;
1954                                 note = _("はひどい痛手をうけた。", " is hit hard.");
1955                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags3 |= RF3_EVIL;
1956                         }
1957                         else
1958                         {
1959                                 note = _("には耐性がある。", " resists.");
1960                                 dam *= 3; dam /= randint1(6) + 6;
1961                         }
1962                         break;
1963                 }
1964
1965                 /* Arrow -- XXX no defense */
1966                 case GF_ARROW:
1967                 {
1968                         if (seen) obvious = TRUE;
1969
1970                         if (r_ptr->flagsr & RFR_RES_ALL)
1971                         {
1972                                 note = _("には完全な耐性がある!", " is immune.");
1973                                 dam = 0;
1974                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
1975                                 break;
1976                         }
1977                         break;
1978                 }
1979
1980                 /* Plasma -- XXX perhaps check ELEC or FIRE */
1981                 case GF_PLASMA:
1982                 {
1983                         if (seen) obvious = TRUE;
1984
1985                         if (r_ptr->flagsr & RFR_RES_ALL)
1986                         {
1987                                 note = _("には完全な耐性がある!", " is immune.");
1988                                 dam = 0;
1989                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
1990                                 break;
1991                         }
1992                         if (r_ptr->flagsr & RFR_RES_PLAS)
1993                         {
1994                                 note = _("には耐性がある。", " resists.");
1995                                 dam *= 3; dam /= randint1(6) + 6;
1996                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_PLAS);
1997                         }
1998                         break;
1999                 }
2000
2001                 /* Nether -- see above */
2002                 case GF_NETHER:
2003                 {
2004                         if (seen) obvious = TRUE;
2005
2006                         if (r_ptr->flagsr & RFR_RES_ALL)
2007                         {
2008                                 note = _("には完全な耐性がある!", " is immune.");
2009                                 dam = 0;
2010                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
2011                                 break;
2012                         }
2013                         if (r_ptr->flagsr & RFR_RES_NETH)
2014                         {
2015                                 if (r_ptr->flags3 & RF3_UNDEAD)
2016                                 {
2017                                         note = _("には完全な耐性がある!", " is immune.");
2018                                         dam = 0;
2019                                         if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags3 |= (RF3_UNDEAD);
2020                                 }
2021                                 else
2022                                 {
2023                                         note = _("には耐性がある。", " resists.");
2024                                         dam *= 3; dam /= randint1(6) + 6;
2025                                 }
2026                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_NETH);
2027                         }
2028                         else if (r_ptr->flags3 & RF3_EVIL)
2029                         {
2030                                 note = _("はいくらか耐性を示した。", " resists somewhat.");
2031                                 dam /= 2;
2032                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags3 |= (RF3_EVIL);
2033                         }
2034                         break;
2035                 }
2036
2037                 /* Water (acid) damage -- Water spirits/elementals are immune */
2038                 case GF_WATER:
2039                 {
2040                         if (seen) obvious = TRUE;
2041
2042                         if (r_ptr->flagsr & RFR_RES_ALL)
2043                         {
2044                                 note = _("には完全な耐性がある!", " is immune.");
2045                                 dam = 0;
2046                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
2047                                 break;
2048                         }
2049                         if (r_ptr->flagsr & RFR_RES_WATE)
2050                         {
2051                                 if ((m_ptr->r_idx == MON_WATER_ELEM) || (m_ptr->r_idx == MON_UNMAKER))
2052                                 {
2053                                         note = _("には完全な耐性がある!", " is immune.");
2054                                         dam = 0;
2055                                 }
2056                                 else
2057                                 {
2058                                         note = _("には耐性がある。", " resists.");
2059                                         dam *= 3; dam /= randint1(6) + 6;
2060                                 }
2061                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_WATE);
2062                         }
2063                         break;
2064                 }
2065
2066                 /* Chaos -- Chaos breathers resist */
2067                 case GF_CHAOS:
2068                 {
2069                         if (seen) obvious = TRUE;
2070
2071                         if (r_ptr->flagsr & RFR_RES_ALL)
2072                         {
2073                                 note = _("には完全な耐性がある!", " is immune.");
2074                                 dam = 0;
2075                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
2076                                 break;
2077                         }
2078                         if (r_ptr->flagsr & RFR_RES_CHAO)
2079                         {
2080                                 note = _("には耐性がある。", " resists.");
2081                                 dam *= 3; dam /= randint1(6) + 6;
2082                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_CHAO);
2083                         }
2084                         else if ((r_ptr->flags3 & RF3_DEMON) && one_in_(3))
2085                         {
2086                                 note = _("はいくらか耐性を示した。", " resists somewhat.");
2087                                 dam *= 3; dam /= randint1(6) + 6;
2088                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags3 |= (RF3_DEMON);
2089                         }
2090                         else
2091                         {
2092                                 do_poly = TRUE;
2093                                 do_conf = (5 + randint1(11) + r) / (r + 1);
2094                         }
2095                         break;
2096                 }
2097
2098                 /* Shards -- Shard breathers resist */
2099                 case GF_SHARDS:
2100                 {
2101                         if (seen) obvious = TRUE;
2102
2103                         if (r_ptr->flagsr & RFR_RES_ALL)
2104                         {
2105                                 note = _("には完全な耐性がある!", " is immune.");
2106                                 dam = 0;
2107                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
2108                                 break;
2109                         }
2110                         if (r_ptr->flagsr & RFR_RES_SHAR)
2111                         {
2112                                 note = _("には耐性がある。", " resists.");
2113                                 dam *= 3; dam /= randint1(6) + 6;
2114                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_SHAR);
2115                         }
2116                         break;
2117                 }
2118
2119                 /* Rocket: Shard resistance helps */
2120                 case GF_ROCKET:
2121                 {
2122                         if (seen) obvious = TRUE;
2123
2124                         if (r_ptr->flagsr & RFR_RES_ALL)
2125                         {
2126                                 note = _("には完全な耐性がある!", " is immune.");
2127                                 dam = 0;
2128                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
2129                                 break;
2130                         }
2131                         if (r_ptr->flagsr & RFR_RES_SHAR)
2132                         {
2133                                 note = _("はいくらか耐性を示した。", " resists somewhat.");
2134                                 dam /= 2;
2135                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_SHAR);
2136                         }
2137                         break;
2138                 }
2139
2140
2141                 /* Sound -- Sound breathers resist */
2142                 case GF_SOUND:
2143                 {
2144                         if (seen) obvious = TRUE;
2145
2146                         if (r_ptr->flagsr & RFR_RES_ALL)
2147                         {
2148                                 note = _("には完全な耐性がある!", " is immune.");
2149                                 dam = 0;
2150                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
2151                                 break;
2152                         }
2153                         if (r_ptr->flagsr & RFR_RES_SOUN)
2154                         {
2155                                 note = _("には耐性がある。", " resists.");
2156                                 dam *= 2; dam /= randint1(6) + 6;
2157                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_SOUN);
2158                         }
2159                         else do_stun = (10 + randint1(15) + r) / (r + 1);
2160                         break;
2161                 }
2162
2163                 /* Confusion */
2164                 case GF_CONFUSION:
2165                 {
2166                         if (seen) obvious = TRUE;
2167
2168                         if (r_ptr->flagsr & RFR_RES_ALL)
2169                         {
2170                                 note = _("には完全な耐性がある!", " is immune.");
2171                                 dam = 0;
2172                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
2173                                 break;
2174                         }
2175                         if (r_ptr->flags3 & RF3_NO_CONF)
2176                         {
2177                                 note = _("には耐性がある。", " resists.");
2178                                 dam *= 3; dam /= randint1(6) + 6;
2179                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags3 |= (RF3_NO_CONF);
2180                         }
2181                         else do_conf = (10 + randint1(15) + r) / (r + 1);
2182                         break;
2183                 }
2184
2185                 /* Disenchantment -- Breathers and Disenchanters resist */
2186                 case GF_DISENCHANT:
2187                 {
2188                         if (seen) obvious = TRUE;
2189
2190                         if (r_ptr->flagsr & RFR_RES_ALL)
2191                         {
2192                                 note = _("には完全な耐性がある!", " is immune.");
2193                                 dam = 0;
2194                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
2195                                 break;
2196                         }
2197                         if (r_ptr->flagsr & RFR_RES_DISE)
2198                         {
2199                                 note = _("には耐性がある。", " resists.");
2200                                 dam *= 3; dam /= randint1(6) + 6;
2201                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_DISE);
2202                         }
2203                         break;
2204                 }
2205
2206                 /* Nexus -- Breathers and Existers resist */
2207                 case GF_NEXUS:
2208                 {
2209                         if (seen) obvious = TRUE;
2210
2211                         if (r_ptr->flagsr & RFR_RES_ALL)
2212                         {
2213                                 note = _("には完全な耐性がある!", " is immune.");
2214                                 dam = 0;
2215                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
2216                                 break;
2217                         }
2218                         if (r_ptr->flagsr & RFR_RES_NEXU)
2219                         {
2220                                 note = _("には耐性がある。", " resists.");
2221                                 dam *= 3; dam /= randint1(6) + 6;
2222                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_NEXU);
2223                         }
2224                         break;
2225                 }
2226
2227                 /* Force */
2228                 case GF_FORCE:
2229                 {
2230                         if (seen) obvious = TRUE;
2231
2232                         if (r_ptr->flagsr & RFR_RES_ALL)
2233                         {
2234                                 note = _("には完全な耐性がある!", " is immune.");
2235                                 dam = 0;
2236                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
2237                                 break;
2238                         }
2239                         if (r_ptr->flagsr & RFR_RES_WALL)
2240                         {
2241                                 note = _("には耐性がある。", " resists.");
2242                                 dam *= 3; dam /= randint1(6) + 6;
2243                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_WALL);
2244                         }
2245                         else do_stun = (randint1(15) + r) / (r + 1);
2246                         break;
2247                 }
2248
2249                 /* Inertia -- breathers resist */
2250                 case GF_INERTIAL:
2251                 {
2252                         if (seen) obvious = TRUE;
2253
2254                         if (r_ptr->flagsr & RFR_RES_ALL)
2255                         {
2256                                 note = _("には完全な耐性がある!", " is immune.");
2257                                 dam = 0;
2258                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
2259                                 break;
2260                         }
2261                         if (r_ptr->flagsr & RFR_RES_INER)
2262                         {
2263                                 note = _("には耐性がある。", " resists.");
2264                                 dam *= 3; dam /= randint1(6) + 6;
2265                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_INER);
2266                         }
2267                         else
2268                         {
2269                                 /* Powerful monsters can resist */
2270                                 if ((r_ptr->flags1 & (RF1_UNIQUE)) ||
2271                                         (r_ptr->level > randint1((dam - 10) < 1 ? 1 : (dam - 10)) + 10))
2272                                 {
2273                                         obvious = FALSE;
2274                                 }
2275                                 /* Normal monsters slow down */
2276                                 else
2277                                 {
2278                                         if (set_monster_slow(c_ptr->m_idx, MON_SLOW(m_ptr) + 50))
2279                                         {
2280                                                 note = _("の動きが遅くなった。", " starts moving slower.");
2281                                         }
2282                                 }
2283                         }
2284                         break;
2285                 }
2286
2287                 /* Time -- breathers resist */
2288                 case GF_TIME:
2289                 {
2290                         if (seen) obvious = TRUE;
2291
2292                         if (r_ptr->flagsr & RFR_RES_ALL)
2293                         {
2294                                 note = _("には完全な耐性がある!", " is immune.");
2295                                 dam = 0;
2296                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
2297                                 break;
2298                         }
2299                         if (r_ptr->flagsr & RFR_RES_TIME)
2300                         {
2301                                 note = _("には耐性がある。", " resists.");
2302                                 dam *= 3; dam /= randint1(6) + 6;
2303                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_TIME);
2304                         }
2305                         else do_time = (dam + 1) / 2;
2306                         break;
2307                 }
2308
2309                 /* Gravity -- breathers resist */
2310                 case GF_GRAVITY:
2311                 {
2312                         bool resist_tele = FALSE;
2313
2314                         if (seen) obvious = TRUE;
2315
2316                         if (r_ptr->flagsr & RFR_RES_ALL)
2317                         {
2318                                 note = _("には完全な耐性がある!", " is immune.");
2319                                 dam = 0;
2320                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
2321                                 break;
2322                         }
2323                         if (r_ptr->flagsr & RFR_RES_TELE)
2324                         {
2325                                 if (r_ptr->flags1 & (RF1_UNIQUE))
2326                                 {
2327                                         if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= RFR_RES_TELE;
2328                                         note = _("には効果がなかった。", " is unaffected!");
2329                                         resist_tele = TRUE;
2330                                 }
2331                                 else if (r_ptr->level > randint1(100))
2332                                 {
2333                                         if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= RFR_RES_TELE;
2334                                         note = _("には耐性がある!", " resists!");
2335                                         resist_tele = TRUE;
2336                                 }
2337                         }
2338
2339                         if (!resist_tele) do_dist = 10;
2340                         else do_dist = 0;
2341                         if (p_ptr->riding && (c_ptr->m_idx == p_ptr->riding)) do_dist = 0;
2342
2343                         if (r_ptr->flagsr & RFR_RES_GRAV)
2344                         {
2345                                 note = _("には耐性がある!", " resists!");
2346                                 dam *= 3; dam /= randint1(6) + 6;
2347                                 do_dist = 0;
2348                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_GRAV);
2349                         }
2350                         else
2351                         {
2352                                 /* 1. slowness */
2353                                 /* Powerful monsters can resist */
2354                                 if ((r_ptr->flags1 & (RF1_UNIQUE)) ||
2355                                         (r_ptr->level > randint1((dam - 10) < 1 ? 1 : (dam - 10)) + 10))
2356                                 {
2357                                         obvious = FALSE;
2358                                 }
2359                                 /* Normal monsters slow down */
2360                                 else
2361                                 {
2362                                         if (set_monster_slow(c_ptr->m_idx, MON_SLOW(m_ptr) + 50))
2363                                         {
2364                                                 note = _("の動きが遅くなった。", " starts moving slower.");
2365                                         }
2366                                 }
2367
2368                                 /* 2. stun */
2369                                 do_stun = damroll((caster_lev / 20) + 3 , (dam)) + 1;
2370
2371                                 /* Attempt a saving throw */
2372                                 if ((r_ptr->flags1 & (RF1_UNIQUE)) ||
2373                                         (r_ptr->level > randint1((dam - 10) < 1 ? 1 : (dam - 10)) + 10))
2374                                 {
2375                                         /* Resist */
2376                                         do_stun = 0;
2377                                         /* No obvious effect */
2378                                         note = _("には効果がなかった。", " is unaffected!");
2379                                         obvious = FALSE;
2380                                 }
2381                         }
2382                         break;
2383                 }
2384
2385                 /* Pure damage */
2386                 case GF_MANA:
2387                 case GF_SEEKER:
2388                 case GF_SUPER_RAY:
2389                 {
2390                         if (seen) obvious = TRUE;
2391
2392                         if (r_ptr->flagsr & RFR_RES_ALL)
2393                         {
2394                                 note = _("には完全な耐性がある!", " is immune.");
2395                                 dam = 0;
2396                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
2397                                 break;
2398                         }
2399                         break;
2400                 }
2401
2402
2403                 /* Pure damage */
2404                 case GF_DISINTEGRATE:
2405                 {
2406                         if (seen) obvious = TRUE;
2407
2408                         if (r_ptr->flagsr & RFR_RES_ALL)
2409                         {
2410                                 note = _("には完全な耐性がある!", " is immune.");
2411                                 dam = 0;
2412                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
2413                                 break;
2414                         }
2415                         if (r_ptr->flags3 & RF3_HURT_ROCK)
2416                         {
2417                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags3 |= (RF3_HURT_ROCK);
2418                                 note = _("の皮膚がただれた!", " loses some skin!");
2419                                 note_dies = _("は蒸発した!", " evaporates!");
2420                                 dam *= 2;
2421                         }
2422                         break;
2423                 }
2424
2425                 case GF_PSI:
2426                 {
2427                         if (seen) obvious = TRUE;
2428
2429                         /* PSI only works if the monster can see you! -- RG */
2430                         if (!(los(m_ptr->fy, m_ptr->fx, p_ptr->y, p_ptr->x)))
2431                         {
2432                                 if (seen_msg) 
2433                                         msg_format(_("%sはあなたが見えないので影響されない!", "%^s can't see you, and isn't affected!"), m_name);
2434                                 skipped = TRUE;
2435                                 break;
2436                         }
2437
2438                         if (r_ptr->flagsr & RFR_RES_ALL)
2439                         {
2440                                 note = _("には完全な耐性がある!", " is immune.");
2441                                 dam = 0;
2442                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
2443                                 break;
2444                         }
2445                         if (r_ptr->flags2 & RF2_EMPTY_MIND)
2446                         {
2447                                 dam = 0;
2448                                 note = _("には完全な耐性がある!", " is immune.");
2449                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags2 |= (RF2_EMPTY_MIND);
2450
2451                         }
2452                         else if ((r_ptr->flags2 & (RF2_STUPID | RF2_WEIRD_MIND)) ||
2453                                          (r_ptr->flags3 & RF3_ANIMAL) ||
2454                                          (r_ptr->level > randint1(3 * dam)))
2455                         {
2456                                 note = _("には耐性がある!", " resists!");
2457                                 dam /= 3;
2458
2459                                 /*
2460                                  * Powerful demons & undead can turn a mindcrafter's
2461                                  * attacks back on them
2462                                  */
2463                                 if ((r_ptr->flags3 & (RF3_UNDEAD | RF3_DEMON)) &&
2464                                         (r_ptr->level > p_ptr->lev / 2) &&
2465                                         one_in_(2))
2466                                 {
2467                                         note = NULL;
2468                                         msg_format(_("%^sの堕落した精神は攻撃を跳ね返した!", 
2469                                                 (seen ? "%^s's corrupted mind backlashes your attack!" : 
2470                                                                 "%^ss corrupted mind backlashes your attack!")), m_name);
2471
2472                                         /* Saving throw */
2473                                         if ((randint0(100 + r_ptr->level / 2) < p_ptr->skill_sav) && !CHECK_MULTISHADOW())
2474                                         {
2475                                                 msg_print(_("しかし効力を跳ね返した!", "You resist the effects!"));
2476                                         }
2477                                         else
2478                                         {
2479                                                 /* Injure +/- confusion */
2480                                                 monster_desc(killer, m_ptr, MD_IGNORE_HALLU | MD_ASSUME_VISIBLE | MD_INDEF_VISIBLE);
2481                                                 take_hit(DAMAGE_ATTACK, dam, killer, -1);  /* has already been /3 */
2482                                                 if (one_in_(4) && !CHECK_MULTISHADOW())
2483                                                 {
2484                                                         switch (randint1(4))
2485                                                         {
2486                                                                 case 1:
2487                                                                         set_confused(p_ptr->confused + 3 + randint1(dam));
2488                                                                         break;
2489                                                                 case 2:
2490                                                                         set_stun(p_ptr->stun + randint1(dam));
2491                                                                         break;
2492                                                                 case 3:
2493                                                                 {
2494                                                                         if (r_ptr->flags3 & RF3_NO_FEAR)
2495                                                                                 note = _("には効果がなかった。", " is unaffected.");
2496                                                                         else
2497                                                                                 set_afraid(p_ptr->afraid + 3 + randint1(dam));
2498                                                                         break;
2499                                                                 }
2500                                                                 default:
2501                                                                         if (!p_ptr->free_act)
2502                                                                                 (void)set_paralyzed(p_ptr->paralyzed + randint1(dam));
2503                                                                         break;
2504                                                         }
2505                                                 }
2506                                         }
2507                                         dam = 0;
2508                                 }
2509                         }
2510
2511                         if ((dam > 0) && one_in_(4))
2512                         {
2513                                 switch (randint1(4))
2514                                 {
2515                                         case 1:
2516                                                 do_conf = 3 + randint1(dam);
2517                                                 break;
2518                                         case 2:
2519                                                 do_stun = 3 + randint1(dam);
2520                                                 break;
2521                                         case 3:
2522                                                 do_fear = 3 + randint1(dam);
2523                                                 break;
2524                                         default:
2525                                                 note = _("は眠り込んでしまった!", " falls asleep!");
2526                                                 do_sleep = 3 + randint1(dam);
2527                                                 break;
2528                                 }
2529                         }
2530
2531                         note_dies = _("の精神は崩壊し、肉体は抜け殻となった。", " collapses, a mindless husk.");
2532                         break;
2533                 }
2534
2535                 case GF_PSI_DRAIN:
2536                 {
2537                         if (seen) obvious = TRUE;
2538
2539                         if (r_ptr->flagsr & RFR_RES_ALL)
2540                         {
2541                                 note = _("には完全な耐性がある!", " is immune.");
2542                                 dam = 0;
2543                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
2544                                 break;
2545                         }
2546                         if (r_ptr->flags2 & RF2_EMPTY_MIND)
2547                         {
2548                                 dam = 0;
2549                                 note = _("には完全な耐性がある!", " is immune.");
2550                         }
2551                         else if ((r_ptr->flags2 & (RF2_STUPID | RF2_WEIRD_MIND)) ||
2552                                          (r_ptr->flags3 & RF3_ANIMAL) ||
2553                                          (r_ptr->level > randint1(3 * dam)))
2554                         {
2555                                 note = _("には耐性がある!", " resists!");
2556                                 dam /= 3;
2557
2558                                 /*
2559                                  * Powerful demons & undead can turn a mindcrafter's
2560                                  * attacks back on them
2561                                  */
2562                                 if ((r_ptr->flags3 & (RF3_UNDEAD | RF3_DEMON)) &&
2563                                          (r_ptr->level > p_ptr->lev / 2) &&
2564                                          (one_in_(2)))
2565                                 {
2566                                         note = NULL;
2567                                         msg_format(_("%^sの堕落した精神は攻撃を跳ね返した!", 
2568                                                 (seen ? "%^s's corrupted mind backlashes your attack!" : 
2569                                                                 "%^ss corrupted mind backlashes your attack!")), m_name);
2570                                         /* Saving throw */
2571                                         if ((randint0(100 + r_ptr->level / 2) < p_ptr->skill_sav) && !CHECK_MULTISHADOW())
2572                                         {
2573                                                 msg_print(_("あなたは効力を跳ね返した!", "You resist the effects!"));
2574                                         }
2575                                         else
2576                                         {
2577                                                 /* Injure + mana drain */
2578                                                 monster_desc(killer, m_ptr, MD_IGNORE_HALLU | MD_ASSUME_VISIBLE | MD_INDEF_VISIBLE);
2579                                                 if (!CHECK_MULTISHADOW())
2580                                                 {
2581                                                         msg_print(_("超能力パワーを吸いとられた!", "Your psychic energy is drained!"));
2582                                                         p_ptr->csp -= damroll(5, dam) / 2;
2583                                                         if (p_ptr->csp < 0) p_ptr->csp = 0;
2584                                                         p_ptr->redraw |= PR_MANA;
2585                                                         p_ptr->window |= (PW_SPELL);
2586                                                 }
2587                                                 take_hit(DAMAGE_ATTACK, dam, killer, -1);  /* has already been /3 */
2588                                         }
2589                                         dam = 0;
2590                                 }
2591                         }
2592                         else if (dam > 0)
2593                         {
2594                                 int b = damroll(5, dam) / 4;
2595                                 cptr str = (p_ptr->pclass == CLASS_MINDCRAFTER) ? _("超能力パワー", "psychic energy") : _("魔力", "mana");
2596                                 cptr msg = _("あなたは%sの苦痛を%sに変換した!", 
2597                                          (seen ? "You convert %s's pain into %s!" : 
2598                                                          "You convert %ss pain into %s!"));
2599                                 msg_format(msg, m_name, str);
2600
2601                                 b = MIN(p_ptr->msp, p_ptr->csp + b);
2602                                 p_ptr->csp = b;
2603                                 p_ptr->redraw |= PR_MANA;
2604                                 p_ptr->window |= (PW_SPELL);
2605                         }
2606                         note_dies = _("の精神は崩壊し、肉体は抜け殻となった。", " collapses, a mindless husk.");
2607                         break;
2608                 }
2609
2610                 case GF_TELEKINESIS:
2611                 {
2612                         if (seen) obvious = TRUE;
2613
2614                         if (r_ptr->flagsr & RFR_RES_ALL)
2615                         {
2616                                 note = _("には完全な耐性がある!", " is immune.");
2617                                 dam = 0;
2618                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
2619                                 break;
2620                         }
2621                         if (one_in_(4))
2622                         {
2623                                 if (p_ptr->riding && (c_ptr->m_idx == p_ptr->riding)) do_dist = 0;
2624                                 else do_dist = 7;
2625                         }
2626
2627                         /* 1. stun */
2628                         do_stun = damroll((caster_lev / 20) + 3 , dam) + 1;
2629
2630                         /* Attempt a saving throw */
2631                         if ((r_ptr->flags1 & RF1_UNIQUE) ||
2632                                 (r_ptr->level > 5 + randint1(dam)))
2633                         {
2634                                 /* Resist */
2635                                 do_stun = 0;
2636                                 /* No obvious effect */
2637                                 obvious = FALSE;
2638                         }
2639                         break;
2640                 }
2641
2642                 /* Psycho-spear -- powerful magic missile */
2643                 case GF_PSY_SPEAR:
2644                 {
2645                         if (seen) obvious = TRUE;
2646
2647                         if (r_ptr->flagsr & RFR_RES_ALL)
2648                         {
2649                                 note = _("には完全な耐性がある!", " is immune.");
2650                                 dam = 0;
2651                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
2652                                 break;
2653                         }
2654                         break;
2655                 }
2656
2657                 /* Meteor -- powerful magic missile */
2658                 case GF_METEOR:
2659                 {
2660                         if (seen) obvious = TRUE;
2661
2662                         if (r_ptr->flagsr & RFR_RES_ALL)
2663                         {
2664                                 note = _("には完全な耐性がある!", " is immune.");
2665                                 dam = 0;
2666                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
2667                                 break;
2668                         }
2669                         break;
2670                 }
2671
2672                 case GF_DOMINATION:
2673                 {
2674                         if (!is_hostile(m_ptr)) break;
2675
2676                         if (seen) obvious = TRUE;
2677
2678                         if (r_ptr->flagsr & RFR_RES_ALL)
2679                         {
2680                                 note = _("には効果がなかった!", " is immune.");
2681                                 dam = 0;
2682                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
2683                                 break;
2684                         }
2685                         /* Attempt a saving throw */
2686                         if ((r_ptr->flags1 & (RF1_UNIQUE | RF1_QUESTOR)) ||
2687                                 (r_ptr->flags3 & RF3_NO_CONF) ||
2688                                 (r_ptr->level > randint1((dam - 10) < 1 ? 1 : (dam - 10)) + 10))
2689                         {
2690                                 /* Memorize a flag */
2691                                 if (r_ptr->flags3 & RF3_NO_CONF)
2692                                 {
2693                                         if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags3 |= (RF3_NO_CONF);
2694                                 }
2695
2696                                 /* Resist */
2697                                 do_conf = 0;
2698
2699                                 /*
2700                                  * Powerful demons & undead can turn a mindcrafter's
2701                                  * attacks back on them
2702                                  */
2703                                 if ((r_ptr->flags3 & (RF3_UNDEAD | RF3_DEMON)) &&
2704                                         (r_ptr->level > p_ptr->lev / 2) &&
2705                                         (one_in_(2)))
2706                                 {
2707                                         note = NULL;
2708                                         msg_format(_("%^sの堕落した精神は攻撃を跳ね返した!",
2709                                                 (seen ? "%^s's corrupted mind backlashes your attack!" :
2710                                                 "%^ss corrupted mind backlashes your attack!")), m_name);
2711
2712                                         /* Saving throw */
2713                                         if (randint0(100 + r_ptr->level/2) < p_ptr->skill_sav)
2714                                         {
2715                                                 msg_print(_("しかし効力を跳ね返した!", "You resist the effects!"));
2716                                         }
2717                                         else
2718                                         {
2719                                                 /* Confuse, stun, terrify */
2720                                                 switch (randint1(4))
2721                                                 {
2722                                                         case 1:
2723                                                                 set_stun(p_ptr->stun + dam / 2);
2724                                                                 break;
2725                                                         case 2:
2726                                                                 set_confused(p_ptr->confused + dam / 2);
2727                                                                 break;
2728                                                         default:
2729                                                         {
2730                                                                 if (r_ptr->flags3 & RF3_NO_FEAR)
2731                                                                         note = _("には効果がなかった。", " is unaffected.");
2732                                                                 else
2733                                                                         set_afraid(p_ptr->afraid + dam);
2734                                                         }
2735                                                 }
2736                                         }
2737                                 }
2738                                 else
2739                                 {
2740                                         /* No obvious effect */
2741                                         note = _("には効果がなかった。", " is unaffected.");
2742                                         obvious = FALSE;
2743                                 }
2744                         }
2745                         else
2746                         {
2747                                 if (!common_saving_throw_charm(p_ptr, dam, m_ptr))
2748                                 {
2749                                         note = _("があなたに隷属した。", " is in your thrall!");
2750                                         set_pet(m_ptr);
2751                                 }
2752                                 else
2753                                 {
2754                                         switch (randint1(4))
2755                                         {
2756                                                 case 1:
2757                                                         do_stun = dam / 2;
2758                                                         break;
2759                                                 case 2:
2760                                                         do_conf = dam / 2;
2761                                                         break;
2762                                                 default:
2763                                                         do_fear = dam;
2764                                         }
2765                                 }
2766                         }
2767
2768                         /* No "real" damage */
2769                         dam = 0;
2770                         break;
2771                 }
2772
2773
2774
2775                 /* Ice -- Cold + Cuts + Stun */
2776                 case GF_ICE:
2777                 {
2778                         if (seen) obvious = TRUE;
2779
2780                         if (r_ptr->flagsr & RFR_RES_ALL)
2781                         {
2782                                 note = _("には完全な耐性がある!", " is immune.");
2783                                 dam = 0;
2784                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
2785                                 break;
2786                         }
2787                         do_stun = (randint1(15) + 1) / (r + 1);
2788                         if (r_ptr->flagsr & RFR_IM_COLD)
2789                         {
2790                                 note = _("にはかなり耐性がある!", " resists a lot.");
2791                                 dam /= 9;
2792                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_IM_COLD);
2793                         }
2794                         else if (r_ptr->flags3 & (RF3_HURT_COLD))
2795                         {
2796                                 note = _("はひどい痛手をうけた。", " is hit hard.");
2797                                 dam *= 2;
2798                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags3 |= (RF3_HURT_COLD);
2799                         }
2800                         break;
2801                 }
2802
2803
2804                 /* Drain Life */
2805                 case GF_HYPODYNAMIA:
2806                 {
2807                         if (seen) obvious = TRUE;
2808
2809                         if (r_ptr->flagsr & RFR_RES_ALL)
2810                         {
2811                                 note = _("には完全な耐性がある!", " is immune.");
2812                                 dam = 0;
2813                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
2814                                 break;
2815                         }
2816                         if (!monster_living(r_ptr))
2817                         {
2818                                 if (is_original_ap_and_seen(m_ptr))
2819                                 {
2820                                         if (r_ptr->flags3 & RF3_DEMON) r_ptr->r_flags3 |= (RF3_DEMON);
2821                                         if (r_ptr->flags3 & RF3_UNDEAD) r_ptr->r_flags3 |= (RF3_UNDEAD);
2822                                         if (r_ptr->flags3 & RF3_NONLIVING) r_ptr->r_flags3 |= (RF3_NONLIVING);
2823                                 }
2824                                 note = _("には効果がなかった。", " is unaffected.");
2825                                 obvious = FALSE;
2826                                 dam = 0;
2827                         }
2828                         else do_time = (dam+7)/8;
2829
2830                         break;
2831                 }
2832
2833                 /* Death Ray */
2834                 case GF_DEATH_RAY:
2835                 {
2836                         if (seen) obvious = TRUE;
2837
2838                         if (r_ptr->flagsr & RFR_RES_ALL)
2839                         {
2840                                 note = _("には完全な耐性がある!", " is immune.");
2841                                 dam = 0;
2842                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
2843                                 break;
2844                         }
2845                         if (!monster_living(r_ptr))
2846                         {
2847                                 if (is_original_ap_and_seen(m_ptr))
2848                                 {
2849                                         if (r_ptr->flags3 & RF3_DEMON) r_ptr->r_flags3 |= (RF3_DEMON);
2850                                         if (r_ptr->flags3 & RF3_UNDEAD) r_ptr->r_flags3 |= (RF3_UNDEAD);
2851                                         if (r_ptr->flags3 & RF3_NONLIVING) r_ptr->r_flags3 |= (RF3_NONLIVING);
2852                                 }
2853                                 note = _("には完全な耐性がある!", " is immune.");
2854                                 obvious = FALSE;
2855                                 dam = 0;
2856                         }
2857                         else if (((r_ptr->flags1 & RF1_UNIQUE) &&
2858                                  (randint1(888) != 666)) ||
2859                                  (((r_ptr->level + randint1(20)) > randint1((caster_lev / 2) + randint1(10))) &&
2860                                  randint1(100) != 66))
2861                         {
2862                                 note = _("には耐性がある!", " resists!");
2863                                 obvious = FALSE;
2864                                 dam = 0;
2865                         }
2866
2867                         break;
2868                 }
2869
2870                 /* Polymorph monster (Use "dam" as "power") */
2871                 case GF_OLD_POLY:
2872                 {
2873                         if (seen) obvious = TRUE;
2874
2875                         if (r_ptr->flagsr & RFR_RES_ALL)
2876                         {
2877                                 note = _("には効果がなかった。", " is unaffected.");
2878                                 dam = 0;
2879                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
2880                                 break;
2881                         }
2882                         /* Attempt to polymorph (see below) */
2883                         do_poly = TRUE;
2884
2885                         /* Powerful monsters can resist */
2886                         if ((r_ptr->flags1 & RF1_UNIQUE) ||
2887                                 (r_ptr->flags1 & RF1_QUESTOR) ||
2888                                 (r_ptr->level > randint1((dam - 10) < 1 ? 1 : (dam - 10)) + 10))
2889                         {
2890                                 note = _("には効果がなかった。", " is unaffected.");
2891                                 do_poly = FALSE;
2892                                 obvious = FALSE;
2893                         }
2894
2895                         /* No "real" damage */
2896                         dam = 0;
2897
2898                         break;
2899                 }
2900
2901
2902                 /* Clone monsters (Ignore "dam") */
2903                 case GF_OLD_CLONE:
2904                 {
2905                         if (seen) obvious = TRUE;
2906
2907                         if ((p_ptr->inside_arena) || is_pet(m_ptr) || (r_ptr->flags1 & (RF1_UNIQUE | RF1_QUESTOR)) || (r_ptr->flags7 & (RF7_NAZGUL | RF7_UNIQUE2)))
2908                         {
2909                                 note = _("には効果がなかった。", " is unaffected.");
2910                         }
2911                         else
2912                         {
2913                                 /* Heal fully */
2914                                 m_ptr->hp = m_ptr->maxhp;
2915
2916                                 /* Attempt to clone. */
2917                                 if (multiply_monster(c_ptr->m_idx, TRUE, 0L))
2918                                 {
2919                                         note = _("が分裂した!", " spawns!");
2920                                 }
2921                         }
2922
2923                         /* No "real" damage */
2924                         dam = 0;
2925
2926                         break;
2927                 }
2928
2929
2930                 /* Heal Monster (use "dam" as amount of healing) */
2931                 case GF_STAR_HEAL:
2932                 {
2933                         if (seen) obvious = TRUE;
2934
2935                         /* Wake up */
2936                         (void)set_monster_csleep(c_ptr->m_idx, 0);
2937
2938                         if (m_ptr->maxhp < m_ptr->max_maxhp)
2939                         {
2940                                 if (seen_msg) msg_format(_("%^sの強さが戻った。", "%^s recovers %s vitality."), m_name, m_poss);
2941                                 m_ptr->maxhp = m_ptr->max_maxhp;
2942                         }
2943
2944                         if (!dam)
2945                         {
2946                                 /* Redraw (later) if needed */
2947                                 if (p_ptr->health_who == c_ptr->m_idx) p_ptr->redraw |= (PR_HEALTH);
2948                                 if (p_ptr->riding == c_ptr->m_idx) p_ptr->redraw |= (PR_UHEALTH);
2949                                 break;
2950                         }
2951
2952                         /* Fall through */
2953                 }
2954                 case GF_OLD_HEAL:
2955                 {
2956                         if (seen) obvious = TRUE;
2957
2958                         /* Wake up */
2959                         (void)set_monster_csleep(c_ptr->m_idx, 0);
2960                         if (MON_STUNNED(m_ptr))
2961                         {
2962                                 if (seen_msg) msg_format(_("%^sは朦朧状態から立ち直った。", "%^s is no longer stunned."), m_name);
2963                                 (void)set_monster_stunned(c_ptr->m_idx, 0);
2964                         }
2965                         if (MON_CONFUSED(m_ptr))
2966                         {
2967                                 if (seen_msg) msg_format(_("%^sは混乱から立ち直った。", "%^s is no longer confused."), m_name);
2968                                 (void)set_monster_confused(c_ptr->m_idx, 0);
2969                         }
2970                         if (MON_MONFEAR(m_ptr))
2971                         {
2972                                 if (seen_msg) msg_format(_("%^sは勇気を取り戻した。", "%^s recovers %s courage."), m_name);
2973                                 (void)set_monster_monfear(c_ptr->m_idx, 0);
2974                         }
2975
2976                         /* Heal */
2977                         if (m_ptr->hp < 30000) m_ptr->hp += dam;
2978
2979                         /* No overflow */
2980                         if (m_ptr->hp > m_ptr->maxhp) m_ptr->hp = m_ptr->maxhp;
2981
2982                         if (!who)
2983                         {
2984                                 chg_virtue(V_VITALITY, 1);
2985
2986                                 if (r_ptr->flags1 & RF1_UNIQUE)
2987                                         chg_virtue(V_INDIVIDUALISM, 1);
2988
2989                                 if (is_friendly(m_ptr))
2990                                         chg_virtue(V_HONOUR, 1);
2991                                 else if (!(r_ptr->flags3 & RF3_EVIL))
2992                                 {
2993                                         if (r_ptr->flags3 & RF3_GOOD)
2994                                                 chg_virtue(V_COMPASSION, 2);
2995                                         else
2996                                                 chg_virtue(V_COMPASSION, 1);
2997                                 }
2998
2999                                 if (r_ptr->flags3 & RF3_ANIMAL)
3000                                         chg_virtue(V_NATURE, 1);
3001                         }
3002
3003                         if (m_ptr->r_idx == MON_LEPER)
3004                         {
3005                                 heal_leper = TRUE;
3006                                 if (!who) chg_virtue(V_COMPASSION, 5);
3007                         }
3008
3009                         /* Redraw (later) if needed */
3010                         if (p_ptr->health_who == c_ptr->m_idx) p_ptr->redraw |= (PR_HEALTH);
3011                         if (p_ptr->riding == c_ptr->m_idx) p_ptr->redraw |= (PR_UHEALTH);
3012
3013                         note = _("は体力を回復したようだ。", " looks healthier.");
3014
3015                         /* No "real" damage */
3016                         dam = 0;
3017                         break;
3018                 }
3019
3020
3021                 /* Speed Monster (Ignore "dam") */
3022                 case GF_OLD_SPEED:
3023                 {
3024                         if (seen) obvious = TRUE;
3025
3026                         /* Speed up */
3027                         if (set_monster_fast(c_ptr->m_idx, MON_FAST(m_ptr) + 100))
3028                         {
3029                                 note = _("の動きが速くなった。", " starts moving faster.");
3030                         }
3031
3032                         if (!who)
3033                         {
3034                                 if (r_ptr->flags1 & RF1_UNIQUE)
3035                                         chg_virtue(V_INDIVIDUALISM, 1);
3036                                 if (is_friendly(m_ptr))
3037                                         chg_virtue(V_HONOUR, 1);
3038                         }
3039
3040                         /* No "real" damage */
3041                         dam = 0;
3042                         break;
3043                 }
3044
3045
3046                 /* Slow Monster (Use "dam" as "power") */
3047                 case GF_OLD_SLOW:
3048                 {
3049                         if (seen) obvious = TRUE;
3050
3051                         if (r_ptr->flagsr & RFR_RES_ALL)
3052                         {
3053                                 note = _("には効果がなかった。", " is unaffected.");
3054                                 dam = 0;
3055                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
3056                                 break;
3057                         }
3058                         /* Powerful monsters can resist */
3059                         if ((r_ptr->flags1 & RF1_UNIQUE) ||
3060                                 (r_ptr->level > randint1((dam - 10) < 1 ? 1 : (dam - 10)) + 10))
3061                         {
3062                                 note = _("には効果がなかった。", " is unaffected.");
3063                                 obvious = FALSE;
3064                         }
3065
3066                         /* Normal monsters slow down */
3067                         else
3068                         {
3069                                 if (set_monster_slow(c_ptr->m_idx, MON_SLOW(m_ptr) + 50))
3070                                 {
3071                                         note = _("の動きが遅くなった。", " starts moving slower.");
3072                                 }
3073                         }
3074
3075                         /* No "real" damage */
3076                         dam = 0;
3077                         break;
3078                 }
3079
3080
3081                 /* Sleep (Use "dam" as "power") */
3082                 case GF_OLD_SLEEP:
3083                 {
3084                         if (seen) obvious = TRUE;
3085
3086                         if (r_ptr->flagsr & RFR_RES_ALL)
3087                         {
3088                                 note = _("には効果がなかった。", " is unaffected.");
3089                                 dam = 0;
3090                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
3091                                 break;
3092                         }
3093                         /* Attempt a saving throw */
3094                         if ((r_ptr->flags1 & RF1_UNIQUE) ||
3095                                 (r_ptr->flags3 & RF3_NO_SLEEP) ||
3096                                 (r_ptr->level > randint1((dam - 10) < 1 ? 1 : (dam - 10)) + 10))
3097                         {
3098                                 /* Memorize a flag */
3099                                 if (r_ptr->flags3 & RF3_NO_SLEEP)
3100                                 {
3101                                         if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags3 |= (RF3_NO_SLEEP);
3102                                 }
3103                                 /* No obvious effect */
3104                                 note = _("には効果がなかった。", " is unaffected.");
3105                                 obvious = FALSE;
3106                         }
3107                         else
3108                         {
3109                                 /* Go to sleep (much) later */
3110                                 note = _("は眠り込んでしまった!", " falls asleep!");
3111                                 do_sleep = 500;
3112                         }
3113
3114                         /* No "real" damage */
3115                         dam = 0;
3116                         break;
3117                 }
3118
3119
3120                 /* Sleep (Use "dam" as "power") */
3121                 case GF_STASIS_EVIL:
3122                 {
3123                         if (seen) obvious = TRUE;
3124
3125                         if (r_ptr->flagsr & RFR_RES_ALL)
3126                         {
3127                                 note = _("には効果がなかった!", " is immune.");
3128                                 dam = 0;
3129                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
3130                                 break;
3131                         }
3132                         /* Attempt a saving throw */
3133                         if ((r_ptr->flags1 & RF1_UNIQUE) ||
3134                                 !(r_ptr->flags3 & RF3_EVIL) ||
3135                                 (r_ptr->level > randint1((dam - 10) < 1 ? 1 : (dam - 10)) + 10))
3136                         {
3137                                 note = _("には効果がなかった。", " is unaffected.");
3138                                 obvious = FALSE;
3139                         }
3140                         else
3141                         {
3142                                 /* Go to sleep (much) later */
3143                                 note = _("は動けなくなった!", " is suspended!");
3144                                 do_sleep = 500;
3145                         }
3146
3147                         /* No "real" damage */
3148                         dam = 0;
3149                         break;
3150                 }
3151
3152                 /* Sleep (Use "dam" as "power") */
3153                 case GF_STASIS:
3154                 {
3155                         if (seen) obvious = TRUE;
3156
3157                         if (r_ptr->flagsr & RFR_RES_ALL)
3158                         {
3159                                 note = _("には効果がなかった。", " is unaffected.");
3160                                 dam = 0;
3161                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
3162                                 break;
3163                         }
3164                         /* Attempt a saving throw */
3165                         if ((r_ptr->flags1 & RF1_UNIQUE) ||
3166                                 (r_ptr->level > randint1((dam - 10) < 1 ? 1 : (dam - 10)) + 10))
3167                         {
3168                                 note = _("には効果がなかった。", " is unaffected.");
3169                                 obvious = FALSE;
3170                         }
3171                         else
3172                         {
3173                                 /* Go to sleep (much) later */
3174                                 note = _("は動けなくなった!", " is suspended!");
3175                                 do_sleep = 500;
3176                         }
3177
3178                         /* No "real" damage */
3179                         dam = 0;
3180                         break;
3181                 }
3182
3183                 /* Charm monster */
3184                 case GF_CHARM:
3185                 {
3186                         int vir;
3187                         vir = virtue_number(V_HARMONY);
3188                         if (vir)
3189                         {
3190                                 dam += p_ptr->virtues[vir-1]/10;
3191                         }
3192
3193                         vir = virtue_number(V_INDIVIDUALISM);
3194                         if (vir)
3195                         {
3196                                 dam -= p_ptr->virtues[vir-1]/20;
3197                         }
3198
3199                         if (seen) obvious = TRUE;
3200
3201                         /* Attempt a saving throw */
3202                         if (common_saving_throw_charm(p_ptr, dam, m_ptr))
3203                         {
3204
3205                                 /* Resist */
3206                                 /* No obvious effect */
3207                                 note = _("には効果がなかった。", " is unaffected.");
3208                                 obvious = FALSE;
3209
3210                                 if (one_in_(4)) m_ptr->mflag2 |= MFLAG2_NOPET;
3211                         }
3212                         else if (p_ptr->cursed & TRC_AGGRAVATE)
3213                         {
3214                                 note = _("はあなたに敵意を抱いている!", " hates you too much!");
3215                                 if (one_in_(4)) m_ptr->mflag2 |= MFLAG2_NOPET;
3216                         }
3217                         else
3218                         {
3219                                 note = _("は突然友好的になったようだ!", " suddenly seems friendly!");
3220                                 set_pet(m_ptr);
3221
3222                                 chg_virtue(V_INDIVIDUALISM, -1);
3223                                 if (r_ptr->flags3 & RF3_ANIMAL)
3224                                         chg_virtue(V_NATURE, 1);
3225                         }
3226
3227                         /* No "real" damage */
3228                         dam = 0;
3229                         break;
3230                 }
3231
3232                 /* Control undead */
3233                 case GF_CONTROL_UNDEAD:
3234                 {
3235                         int vir;
3236                         if (seen) obvious = TRUE;
3237
3238                         vir = virtue_number(V_UNLIFE);
3239                         if (vir)
3240                         {
3241                                 dam += p_ptr->virtues[vir-1]/10;
3242                         }
3243
3244                         vir = virtue_number(V_INDIVIDUALISM);
3245                         if (vir)
3246                         {
3247                                 dam -= p_ptr->virtues[vir-1]/20;
3248                         }
3249
3250                         /* Attempt a saving throw */
3251                         if (common_saving_throw_control(p_ptr, dam, m_ptr) ||
3252                                 !(r_ptr->flags3 & RF3_UNDEAD))
3253                         {
3254                                 /* No obvious effect */
3255                                 note = _("には効果がなかった。", " is unaffected.");
3256                                 obvious = FALSE;
3257                                 if (one_in_(4)) m_ptr->mflag2 |= MFLAG2_NOPET;
3258                         }
3259                         else if (p_ptr->cursed & TRC_AGGRAVATE)
3260                         {
3261                                 note = _("はあなたに敵意を抱いている!", " hates you too much!");
3262                                 if (one_in_(4)) m_ptr->mflag2 |= MFLAG2_NOPET;
3263                         }
3264                         else
3265                         {
3266                                 note = _("は既にあなたの奴隷だ!", " is in your thrall!");
3267                                 set_pet(m_ptr);
3268                         }
3269
3270                         /* No "real" damage */
3271                         dam = 0;
3272                         break;
3273                 }
3274
3275                 /* Control demon */
3276                 case GF_CONTROL_DEMON:
3277                 {
3278                         int vir;
3279                         if (seen) obvious = TRUE;
3280
3281                         vir = virtue_number(V_UNLIFE);
3282                         if (vir)
3283                         {
3284                                 dam += p_ptr->virtues[vir-1]/10;
3285                         }
3286
3287                         vir = virtue_number(V_INDIVIDUALISM);
3288                         if (vir)
3289                         {
3290                                 dam -= p_ptr->virtues[vir-1]/20;
3291                         }
3292
3293                         /* Attempt a saving throw */
3294                         if (common_saving_throw_control(p_ptr, dam, m_ptr) ||
3295                                 !(r_ptr->flags3 & RF3_DEMON))
3296                         {
3297                                 /* No obvious effect */
3298                                 note = _("には効果がなかった。", " is unaffected.");
3299                                 obvious = FALSE;
3300                                 if (one_in_(4)) m_ptr->mflag2 |= MFLAG2_NOPET;
3301                         }
3302                         else if (p_ptr->cursed & TRC_AGGRAVATE)
3303                         {
3304                                 note = _("はあなたに敵意を抱いている!", " hates you too much!");
3305                                 if (one_in_(4)) m_ptr->mflag2 |= MFLAG2_NOPET;
3306                         }
3307                         else
3308                         {
3309                                 note = _("は既にあなたの奴隷だ!", " is in your thrall!");
3310                                 set_pet(m_ptr);
3311                         }
3312
3313                         /* No "real" damage */
3314                         dam = 0;
3315                         break;
3316                 }
3317
3318                 /* Tame animal */
3319                 case GF_CONTROL_ANIMAL:
3320                 {
3321                         int vir;
3322                         if (seen) obvious = TRUE;
3323
3324                         vir = virtue_number(V_NATURE);
3325                         if (vir)
3326                         {
3327                                 dam += p_ptr->virtues[vir-1]/10;
3328                         }
3329
3330                         vir = virtue_number(V_INDIVIDUALISM);
3331                         if (vir)
3332                         {
3333                                 dam -= p_ptr->virtues[vir-1]/20;
3334                         }
3335
3336                         /* Attempt a saving throw */
3337                         if (common_saving_throw_control(p_ptr, dam, m_ptr) ||
3338                                 !(r_ptr->flags3 & RF3_ANIMAL))
3339                         {
3340                                 /* Resist */
3341                                 /* No obvious effect */
3342                                 note = _("には効果がなかった。", " is unaffected.");
3343                                 obvious = FALSE;
3344                                 if (one_in_(4)) m_ptr->mflag2 |= MFLAG2_NOPET;
3345                         }
3346                         else if (p_ptr->cursed & TRC_AGGRAVATE)
3347                         {
3348                                 note = _("はあなたに敵意を抱いている!", " hates you too much!");
3349                                 if (one_in_(4)) m_ptr->mflag2 |= MFLAG2_NOPET;
3350                         }
3351                         else
3352                         {
3353                                 note = _("はなついた。", " is tamed!");
3354                                 set_pet(m_ptr);
3355                                 if (r_ptr->flags3 & RF3_ANIMAL)
3356                                         chg_virtue(V_NATURE, 1);
3357                         }
3358
3359                         /* No "real" damage */
3360                         dam = 0;
3361                         break;
3362                 }
3363
3364                 /* Tame animal */
3365                 case GF_CHARM_LIVING:
3366                 {
3367                         int vir;
3368
3369                         vir = virtue_number(V_UNLIFE);
3370                         if (seen) obvious = TRUE;
3371
3372                         vir = virtue_number(V_UNLIFE);
3373                         if (vir)
3374                         {
3375                                 dam -= p_ptr->virtues[vir-1]/10;
3376                         }
3377
3378                         vir = virtue_number(V_INDIVIDUALISM);
3379                         if (vir)
3380                         {
3381                                 dam -= p_ptr->virtues[vir-1]/20;
3382                         }
3383
3384                         msg_format(_("%sを見つめた。", "You stare into %s."), m_name);
3385
3386                         /* Attempt a saving throw */
3387                         if (common_saving_throw_charm(p_ptr, dam, m_ptr) ||
3388                                 !monster_living(r_ptr))
3389                         {
3390                                 /* Resist */
3391                                 /* No obvious effect */
3392                                 note = _("には効果がなかった。", " is unaffected.");
3393                                 obvious = FALSE;
3394                                 if (one_in_(4)) m_ptr->mflag2 |= MFLAG2_NOPET;
3395                         }
3396                         else if (p_ptr->cursed & TRC_AGGRAVATE)
3397                         {
3398                                 note = _("はあなたに敵意を抱いている!", " hates you too much!");
3399                                 if (one_in_(4)) m_ptr->mflag2 |= MFLAG2_NOPET;
3400                         }
3401                         else
3402                         {
3403                                 note = _("を支配した。", " is tamed!");
3404                                 set_pet(m_ptr);
3405                                 if (r_ptr->flags3 & RF3_ANIMAL)
3406                                         chg_virtue(V_NATURE, 1);
3407                         }
3408
3409                         /* No "real" damage */
3410                         dam = 0;
3411                         break;
3412                 }
3413
3414                 /* Confusion (Use "dam" as "power") */
3415                 case GF_OLD_CONF:
3416                 {
3417                         if (seen) obvious = TRUE;
3418
3419                         if (r_ptr->flagsr & RFR_RES_ALL)
3420                         {
3421                                 note = _("には効果がなかった。", " is unaffected.");
3422                                 dam = 0;
3423                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
3424                                 break;
3425                         }
3426                         /* Get confused later */
3427                         do_conf = damroll(3, (dam / 2)) + 1;
3428
3429                         /* Attempt a saving throw */
3430                         if ((r_ptr->flags1 & (RF1_UNIQUE)) ||
3431                                 (r_ptr->flags3 & (RF3_NO_CONF)) ||
3432                                 (r_ptr->level > randint1((dam - 10) < 1 ? 1 : (dam - 10)) + 10))
3433                         {
3434                                 /* Memorize a flag */
3435                                 if (r_ptr->flags3 & (RF3_NO_CONF))
3436                                 {
3437                                         if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags3 |= (RF3_NO_CONF);
3438                                 }
3439
3440                                 /* Resist */
3441                                 do_conf = 0;
3442
3443                                 /* No obvious effect */
3444                                 note = _("には効果がなかった。", " is unaffected.");
3445                                 obvious = FALSE;
3446                         }
3447
3448                         /* No "real" damage */
3449                         dam = 0;
3450                         break;
3451                 }
3452
3453                 case GF_STUN:
3454                 {
3455                         if (seen) obvious = TRUE;
3456
3457                         if (r_ptr->flagsr & RFR_RES_ALL)
3458                         {
3459                                 note = _("には効果がなかった。", " is unaffected.");
3460                                 dam = 0;
3461                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
3462                                 break;
3463                         }
3464                         do_stun = damroll((caster_lev / 20) + 3 , (dam)) + 1;
3465
3466                         /* Attempt a saving throw */
3467                         if ((r_ptr->flags1 & (RF1_UNIQUE)) ||
3468                                 (r_ptr->level > randint1((dam - 10) < 1 ? 1 : (dam - 10)) + 10))
3469                         {
3470                                 /* Resist */
3471                                 do_stun = 0;
3472
3473                                 /* No obvious effect */
3474                                 note = _("には効果がなかった。", " is unaffected.");
3475                                 obvious = FALSE;
3476                         }
3477
3478                         /* No "real" damage */
3479                         dam = 0;
3480                         break;
3481                 }
3482
3483
3484
3485
3486                 /* Lite, but only hurts susceptible creatures */
3487                 case GF_LITE_WEAK:
3488                 {
3489                         if (!dam)
3490                         {
3491                                 skipped = TRUE;
3492                                 break;
3493                         }
3494                         if (r_ptr->flagsr & RFR_RES_ALL)
3495                         {
3496                                 dam = 0;
3497                                 break;
3498                         }
3499                         /* Hurt by light */
3500                         if (r_ptr->flags3 & (RF3_HURT_LITE))
3501                         {
3502                                 /* Obvious effect */
3503                                 if (seen) obvious = TRUE;
3504
3505                                 /* Memorize the effects */
3506                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags3 |= (RF3_HURT_LITE);
3507
3508                                 /* Special effect */
3509                                 note = _("は光に身をすくめた!", " cringes from the light!");
3510                                 note_dies = _("は光を受けてしぼんでしまった!", " shrivels away in the light!");
3511                         }
3512
3513                         /* Normally no damage */
3514                         else
3515                         {
3516                                 /* No damage */
3517                                 dam = 0;
3518                         }
3519
3520                         break;
3521                 }
3522
3523
3524
3525                 /* Lite -- opposite of Dark */
3526                 case GF_LITE:
3527                 {
3528                         if (seen) obvious = TRUE;
3529
3530                         if (r_ptr->flagsr & RFR_RES_ALL)
3531                         {
3532                                 note = _("には完全な耐性がある!", " is immune.");
3533                                 dam = 0;
3534                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
3535                                 break;
3536                         }
3537                         if (r_ptr->flagsr & RFR_RES_LITE)
3538                         {
3539                                 note = _("には耐性がある!", " resists!");
3540                                 dam *= 2; dam /= (randint1(6)+6);
3541                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_LITE);
3542                         }
3543                         else if (r_ptr->flags3 & (RF3_HURT_LITE))
3544                         {
3545                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags3 |= (RF3_HURT_LITE);
3546                                 note = _("は光に身をすくめた!", " cringes from the light!");
3547                                 note_dies = _("は光を受けてしぼんでしまった!", " shrivels away in the light!");
3548                                 dam *= 2;
3549                         }
3550                         break;
3551                 }
3552
3553
3554                 /* Dark -- opposite of Lite */
3555                 case GF_DARK:
3556                 {
3557                         if (seen) obvious = TRUE;
3558
3559                         if (r_ptr->flagsr & RFR_RES_ALL)
3560                         {
3561                                 note = _("には完全な耐性がある!", " is immune.");
3562                                 dam = 0;
3563                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
3564                                 break;
3565                         }
3566                         if (r_ptr->flagsr & RFR_RES_DARK)
3567                         {
3568                                 note = _("には耐性がある!", " resists!");
3569                                 dam *= 2; dam /= (randint1(6)+6);
3570                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_DARK);
3571                         }
3572                         break;
3573                 }
3574
3575
3576                 /* Stone to Mud */
3577                 case GF_KILL_WALL:
3578                 {
3579                         if (r_ptr->flagsr & RFR_RES_ALL)
3580                         {
3581                                 dam = 0;
3582                                 break;
3583                         }
3584                         /* Hurt by rock remover */
3585                         if (r_ptr->flags3 & (RF3_HURT_ROCK))
3586                         {
3587                                 /* Notice effect */
3588                                 if (seen) obvious = TRUE;
3589
3590                                 /* Memorize the effects */
3591                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags3 |= (RF3_HURT_ROCK);
3592
3593                                 /* Cute little message */
3594                                 note = _("の皮膚がただれた!", " loses some skin!");
3595                                 note_dies = _("はドロドロに溶けた!", " dissolves!");
3596                         }
3597
3598                         /* Usually, ignore the effects */
3599                         else
3600                         {
3601                                 /* No damage */
3602                                 dam = 0;
3603                         }
3604
3605                         break;
3606                 }
3607
3608
3609                 /* Teleport undead (Use "dam" as "power") */
3610                 case GF_AWAY_UNDEAD:
3611                 {
3612                         /* Only affect undead */
3613                         if (r_ptr->flags3 & (RF3_UNDEAD))
3614                         {
3615                                 bool resists_tele = FALSE;
3616
3617                                 if (r_ptr->flagsr & RFR_RES_TELE)
3618                                 {
3619                                         if ((r_ptr->flags1 & (RF1_UNIQUE)) || (r_ptr->flagsr & RFR_RES_ALL))
3620                                         {
3621                                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= RFR_RES_TELE;
3622                                                 note = _("には効果がなかった。", " is unaffected.");
3623                                                 resists_tele = TRUE;
3624                                         }
3625                                         else if (r_ptr->level > randint1(100))
3626                                         {
3627                                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= RFR_RES_TELE;
3628                                                 note = _("には耐性がある!", " resists!");
3629                                                 resists_tele = TRUE;
3630                                         }
3631                                 }
3632
3633                                 if (!resists_tele)
3634                                 {
3635                                         if (seen) obvious = TRUE;
3636                                         if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags3 |= (RF3_UNDEAD);
3637                                         do_dist = dam;
3638                                 }
3639                         }
3640
3641                         /* Others ignore */
3642                         else
3643                         {
3644                                 /* Irrelevant */
3645                                 skipped = TRUE;
3646                         }
3647
3648                         /* No "real" damage */
3649                         dam = 0;
3650                         break;
3651                 }
3652
3653
3654                 /* Teleport evil (Use "dam" as "power") */
3655                 case GF_AWAY_EVIL:
3656                 {
3657                         /* Only affect evil */
3658                         if (r_ptr->flags3 & (RF3_EVIL))
3659                         {
3660                                 bool resists_tele = FALSE;
3661
3662                                 if (r_ptr->flagsr & RFR_RES_TELE)
3663                                 {
3664                                         if ((r_ptr->flags1 & (RF1_UNIQUE)) || (r_ptr->flagsr & RFR_RES_ALL))
3665                                         {
3666                                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= RFR_RES_TELE;
3667                                                 note = _("には効果がなかった。", " is unaffected.");
3668                                                 resists_tele = TRUE;
3669                                         }
3670                                         else if (r_ptr->level > randint1(100))
3671                                         {
3672                                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= RFR_RES_TELE;
3673                                                 note = _("には耐性がある!", " resists!");
3674                                                 resists_tele = TRUE;
3675                                         }
3676                                 }
3677
3678                                 if (!resists_tele)
3679                                 {
3680                                         if (seen) obvious = TRUE;
3681                                         if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags3 |= (RF3_EVIL);
3682                                         do_dist = dam;
3683                                 }
3684                         }
3685
3686                         /* Others ignore */
3687                         else
3688                         {
3689                                 /* Irrelevant */
3690                                 skipped = TRUE;
3691                         }
3692
3693                         /* No "real" damage */
3694                         dam = 0;
3695                         break;
3696                 }
3697
3698
3699                 /* Teleport monster (Use "dam" as "power") */
3700                 case GF_AWAY_ALL:
3701                 {
3702                         bool resists_tele = FALSE;
3703                         if (r_ptr->flagsr & RFR_RES_TELE)
3704                         {
3705                                 if ((r_ptr->flags1 & (RF1_UNIQUE)) || (r_ptr->flagsr & RFR_RES_ALL))
3706                                 {
3707                                         if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= RFR_RES_TELE;
3708                                         note = _("には効果がなかった。", " is unaffected.");
3709                                         resists_tele = TRUE;
3710                                 }
3711                                 else if (r_ptr->level > randint1(100))
3712                                 {
3713                                         if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= RFR_RES_TELE;
3714                                         note = _("には耐性がある!", " resists!");
3715                                         resists_tele = TRUE;
3716                                 }
3717                         }
3718
3719                         if (!resists_tele)
3720                         {
3721                                 /* Obvious */
3722                                 if (seen) obvious = TRUE;
3723
3724                                 /* Prepare to teleport */
3725                                 do_dist = dam;
3726                         }
3727
3728                         /* No "real" damage */
3729                         dam = 0;
3730                         break;
3731                 }
3732
3733
3734                 /* Turn undead (Use "dam" as "power") */
3735                 case GF_TURN_UNDEAD:
3736                 {
3737                         if (r_ptr->flagsr & RFR_RES_ALL)
3738                         {
3739                                 skipped = TRUE;
3740                                 break;
3741                         }
3742                         /* Only affect undead */
3743                         if (r_ptr->flags3 & (RF3_UNDEAD))
3744                         {
3745                                 /* Obvious */
3746                                 if (seen) obvious = TRUE;
3747
3748                                 /* Learn about type */
3749                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags3 |= (RF3_UNDEAD);
3750
3751                                 /* Apply some fear */
3752                                 do_fear = damroll(3, (dam / 2)) + 1;
3753
3754                                 /* Attempt a saving throw */
3755                                 if (r_ptr->level > randint1((dam - 10) < 1 ? 1 : (dam - 10)) + 10)
3756                                 {
3757                                         /* No obvious effect */
3758                                         note = _("には効果がなかった。", " is unaffected.");
3759                                         obvious = FALSE;
3760                                         do_fear = 0;
3761                                 }
3762                         }
3763
3764                         /* Others ignore */
3765                         else
3766                         {
3767                                 /* Irrelevant */
3768                                 skipped = TRUE;
3769                         }
3770
3771                         /* No "real" damage */
3772                         dam = 0;
3773                         break;
3774                 }
3775
3776
3777                 /* Turn evil (Use "dam" as "power") */
3778                 case GF_TURN_EVIL:
3779                 {
3780                         if (r_ptr->flagsr & RFR_RES_ALL)
3781                         {
3782                                 skipped = TRUE;
3783                                 break;
3784                         }
3785                         /* Only affect evil */
3786                         if (r_ptr->flags3 & (RF3_EVIL))
3787                         {
3788                                 /* Obvious */
3789                                 if (seen) obvious = TRUE;
3790
3791                                 /* Learn about type */
3792                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags3 |= (RF3_EVIL);
3793
3794                                 /* Apply some fear */
3795                                 do_fear = damroll(3, (dam / 2)) + 1;
3796
3797                                 /* Attempt a saving throw */
3798                                 if (r_ptr->level > randint1((dam - 10) < 1 ? 1 : (dam - 10)) + 10)
3799                                 {
3800                                         /* No obvious effect */
3801                                         note = _("には効果がなかった。", " is unaffected.");
3802                                         obvious = FALSE;
3803                                         do_fear = 0;
3804                                 }
3805                         }
3806
3807                         /* Others ignore */
3808                         else
3809                         {
3810                                 /* Irrelevant */
3811                                 skipped = TRUE;
3812                         }
3813
3814                         /* No "real" damage */
3815                         dam = 0;
3816                         break;
3817                 }
3818
3819
3820                 /* Turn monster (Use "dam" as "power") */
3821                 case GF_TURN_ALL:
3822                 {
3823                         if (r_ptr->flagsr & RFR_RES_ALL)
3824                         {
3825                                 skipped = TRUE;
3826                                 break;
3827                         }
3828                         /* Obvious */
3829                         if (seen) obvious = TRUE;
3830
3831                         /* Apply some fear */
3832                         do_fear = damroll(3, (dam / 2)) + 1;
3833
3834                         /* Attempt a saving throw */
3835                         if ((r_ptr->flags1 & (RF1_UNIQUE)) ||
3836                                 (r_ptr->flags3 & (RF3_NO_FEAR)) ||
3837                                 (r_ptr->level > randint1((dam - 10) < 1 ? 1 : (dam - 10)) + 10))
3838                         {
3839                                 /* No obvious effect */
3840                                 note = _("には効果がなかった。", " is unaffected.");
3841                                 obvious = FALSE;
3842                                 do_fear = 0;
3843                         }
3844
3845                         /* No "real" damage */
3846                         dam = 0;
3847                         break;
3848                 }
3849
3850
3851                 /* Dispel undead */
3852                 case GF_DISP_UNDEAD:
3853                 {
3854                         if (r_ptr->flagsr & RFR_RES_ALL)
3855                         {
3856                                 skipped = TRUE;
3857                                 dam = 0;
3858                                 break;
3859                         }
3860                         /* Only affect undead */
3861                         if (r_ptr->flags3 & (RF3_UNDEAD))
3862                         {
3863                                 /* Obvious */
3864                                 if (seen) obvious = TRUE;
3865
3866                                 /* Learn about type */
3867                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags3 |= (RF3_UNDEAD);
3868
3869                                 note = _("は身震いした。", " shudders.");
3870                                 note_dies = _("はドロドロに溶けた!", " dissolves!");
3871                         }
3872
3873                         /* Others ignore */
3874                         else
3875                         {
3876                                 /* Irrelevant */
3877                                 skipped = TRUE;
3878
3879                                 /* No damage */
3880                                 dam = 0;
3881                         }
3882
3883                         break;
3884                 }
3885
3886
3887                 /* Dispel evil */
3888                 case GF_DISP_EVIL:
3889                 {
3890                         if (r_ptr->flagsr & RFR_RES_ALL)
3891                         {
3892                                 skipped = TRUE;
3893                                 dam = 0;
3894                                 break;
3895                         }
3896                         /* Only affect evil */
3897                         if (r_ptr->flags3 & (RF3_EVIL))
3898                         {
3899                                 /* Obvious */
3900                                 if (seen) obvious = TRUE;
3901
3902                                 /* Learn about type */
3903                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags3 |= (RF3_EVIL);
3904
3905                                 note = _("は身震いした。", " shudders.");
3906                                 note_dies = _("はドロドロに溶けた!", " dissolves!");
3907                         }
3908
3909                         /* Others ignore */
3910                         else
3911                         {
3912                                 /* Irrelevant */
3913                                 skipped = TRUE;
3914
3915                                 /* No damage */
3916                                 dam = 0;
3917                         }
3918
3919                         break;
3920                 }
3921
3922                 /* Dispel good */
3923                 case GF_DISP_GOOD:
3924                 {
3925                         if (r_ptr->flagsr & RFR_RES_ALL)
3926                         {
3927                                 skipped = TRUE;
3928                                 dam = 0;
3929                                 break;
3930                         }
3931                         /* Only affect good */
3932                         if (r_ptr->flags3 & (RF3_GOOD))
3933                         {
3934                                 /* Obvious */
3935                                 if (seen) obvious = TRUE;
3936
3937                                 /* Learn about type */
3938                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags3 |= (RF3_GOOD);
3939
3940                                 note = _("は身震いした。", " shudders.");
3941                                 note_dies = _("はドロドロに溶けた!", " dissolves!");
3942                         }
3943
3944                         /* Others ignore */
3945                         else
3946                         {
3947                                 /* Irrelevant */
3948                                 skipped = TRUE;
3949
3950                                 /* No damage */
3951                                 dam = 0;
3952                         }
3953
3954                         break;
3955                 }
3956
3957                 /* Dispel living */
3958                 case GF_DISP_LIVING:
3959                 {
3960                         if (r_ptr->flagsr & RFR_RES_ALL)
3961                         {
3962                                 skipped = TRUE;
3963                                 dam = 0;
3964                                 break;
3965                         }
3966                         /* Only affect non-undead */
3967                         if (monster_living(r_ptr))
3968                         {
3969                                 /* Obvious */
3970                                 if (seen) obvious = TRUE;
3971
3972                                 note = _("は身震いした。", " shudders.");
3973                                 note_dies = _("はドロドロに溶けた!", " dissolves!");
3974                         }
3975
3976                         /* Others ignore */
3977                         else
3978                         {
3979                                 /* Irrelevant */
3980                                 skipped = TRUE;
3981
3982                                 /* No damage */
3983                                 dam = 0;
3984                         }
3985
3986                         break;
3987                 }
3988
3989                 /* Dispel demons */
3990                 case GF_DISP_DEMON:
3991                 {
3992                         if (r_ptr->flagsr & RFR_RES_ALL)
3993                         {
3994                                 skipped = TRUE;
3995                                 dam = 0;
3996                                 break;
3997                         }
3998                         /* Only affect demons */
3999                         if (r_ptr->flags3 & (RF3_DEMON))
4000                         {
4001                                 /* Obvious */
4002                                 if (seen) obvious = TRUE;
4003
4004                                 /* Learn about type */
4005                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags3 |= (RF3_DEMON);
4006
4007                                 note = _("は身震いした。", " shudders.");
4008                                 note_dies = _("はドロドロに溶けた!", " dissolves!");
4009                         }
4010
4011                         /* Others ignore */
4012                         else
4013                         {
4014                                 /* Irrelevant */
4015                                 skipped = TRUE;
4016
4017                                 /* No damage */
4018                                 dam = 0;
4019                         }
4020
4021                         break;
4022                 }
4023
4024                 /* Dispel monster */
4025                 case GF_DISP_ALL:
4026                 {
4027                         if (r_ptr->flagsr & RFR_RES_ALL)
4028                         {
4029                                 skipped = TRUE;
4030                                 dam = 0;
4031                                 break;
4032                         }
4033                         /* Obvious */
4034                         if (seen) obvious = TRUE;
4035
4036                         note = _("は身震いした。", " shudders.");
4037                         note_dies = _("はドロドロに溶けた!", " dissolves!");
4038                         break;
4039                 }
4040
4041                 /* Drain mana */
4042                 case GF_DRAIN_MANA:
4043                 {
4044                         if (seen) obvious = TRUE;
4045
4046                         if (r_ptr->flagsr & RFR_RES_ALL)
4047                         {
4048                                 note = _("には完全な耐性がある!", " is immune.");
4049                                 skipped = TRUE;
4050                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
4051                                 break;
4052                         }
4053
4054                         if ((r_ptr->flags4 & ~(RF4_NOMAGIC_MASK)) || (r_ptr->a_ability_flags1 & ~(RF5_NOMAGIC_MASK)) || (r_ptr->a_ability_flags2 & ~(RF6_NOMAGIC_MASK)))
4055                         {
4056                                 if (who > 0)
4057                                 {
4058                                         /* Heal the monster */
4059                                         if (caster_ptr->hp < caster_ptr->maxhp)
4060                                         {
4061                                                 /* Heal */
4062                                                 caster_ptr->hp += dam;
4063                                                 if (caster_ptr->hp > caster_ptr->maxhp) caster_ptr->hp = caster_ptr->maxhp;
4064
4065                                                 /* Redraw (later) if needed */
4066                                                 if (p_ptr->health_who == who) p_ptr->redraw |= (PR_HEALTH);
4067                                                 if (p_ptr->riding == who) p_ptr->redraw |= (PR_UHEALTH);
4068
4069                                                 /* Special message */
4070                                                 if (see_s_msg)
4071                                                 {
4072                                                         /* Get the monster name */
4073                                                         monster_desc(killer, caster_ptr, 0);
4074                                                         msg_format(_("%^sは気分が良さそうだ。", "%^s appears healthier."), killer);
4075                                                 }
4076                                         }
4077                                 }
4078                                 else
4079                                 {
4080                                         msg_format(_("%sから精神エネルギーを吸いとった。", "You draw psychic energy from %s."), m_name);
4081                                         (void)hp_player(dam);
4082                                 }
4083                         }
4084                         else
4085                         {
4086                                 if (see_s_msg) msg_format(_("%sには効果がなかった。", "%s is unaffected."), m_name);
4087                         }
4088                         dam = 0;
4089                         break;
4090                 }
4091
4092                 /* Mind blast */
4093                 case GF_MIND_BLAST:
4094                 {
4095                         if (seen) obvious = TRUE;
4096                         if (!who) msg_format(_("%sをじっと睨んだ。", "You gaze intently at %s."), m_name);
4097
4098                         if (r_ptr->flagsr & RFR_RES_ALL)
4099                         {
4100                                 note = _("には完全な耐性がある!", " is immune.");
4101                                 skipped = TRUE;
4102                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
4103                                 break;
4104                         }
4105
4106                         /* Attempt a saving throw */
4107                         if ((r_ptr->flags1 & RF1_UNIQUE) ||
4108                                  (r_ptr->flags3 & RF3_NO_CONF) ||
4109                                  (r_ptr->level > randint1((caster_lev - 10) < 1 ? 1 : (caster_lev - 10)) + 10))
4110                         {
4111                                 /* Memorize a flag */
4112                                 if (r_ptr->flags3 & (RF3_NO_CONF))
4113                                 {
4114                                         if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags3 |= (RF3_NO_CONF);
4115                                 }
4116                                 note = _("には効果がなかった。", " is unaffected.");
4117                                 dam = 0;
4118                         }
4119                         else if (r_ptr->flags2 & RF2_EMPTY_MIND)
4120                         {
4121                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags2 |= (RF2_EMPTY_MIND);
4122                                 note = _("には完全な耐性がある!", " is immune.");
4123                                 dam = 0;
4124                         }
4125                         else if (r_ptr->flags2 & RF2_WEIRD_MIND)
4126                         {
4127                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags2 |= (RF2_WEIRD_MIND);
4128                                 note = _("には耐性がある。", " resists.");
4129                                 dam /= 3;
4130                         }
4131                         else
4132                         {
4133                                 note = _("は精神攻撃を食らった。", " is blasted by psionic energy.");
4134                                 note_dies = _("の精神は崩壊し、肉体は抜け殻となった。", " collapses, a mindless husk.");
4135
4136                                 if (who > 0) do_conf = randint0(4) + 4;
4137                                 else do_conf = randint0(8) + 8;
4138                         }
4139                         break;
4140                 }
4141
4142                 /* Brain smash */
4143                 case GF_BRAIN_SMASH:
4144                 {
4145                         if (seen) obvious = TRUE;
4146                         if (!who) msg_format(_("%sをじっと睨んだ。", "You gaze intently at %s."), m_name);
4147
4148                         if (r_ptr->flagsr & RFR_RES_ALL)
4149                         {
4150                                 note = _("には完全な耐性がある!", " is immune.");
4151                                 skipped = TRUE;
4152                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
4153                                 break;
4154                         }
4155
4156                         /* Attempt a saving throw */
4157                         if ((r_ptr->flags1 & RF1_UNIQUE) ||
4158                                  (r_ptr->flags3 & RF3_NO_CONF) ||
4159                                  (r_ptr->level > randint1((caster_lev - 10) < 1 ? 1 : (caster_lev - 10)) + 10))
4160                         {
4161                                 /* Memorize a flag */
4162                                 if (r_ptr->flags3 & (RF3_NO_CONF))
4163                                 {
4164                                         if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags3 |= (RF3_NO_CONF);
4165                                 }
4166                                 note = _("には効果がなかった。", " is unaffected.");
4167                                 dam = 0;
4168                         }
4169                         else if (r_ptr->flags2 & RF2_EMPTY_MIND)
4170                         {
4171                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags2 |= (RF2_EMPTY_MIND);
4172                                 note = _("には完全な耐性がある!", " is immune.");
4173                                 dam = 0;
4174                         }
4175                         else if (r_ptr->flags2 & RF2_WEIRD_MIND)
4176                         {
4177                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags2 |= (RF2_WEIRD_MIND);
4178                                 note = _("には耐性がある!", " resists!");
4179                                 dam /= 3;
4180                         }
4181                         else
4182                         {
4183                                 note = _("は精神攻撃を食らった。", " is blasted by psionic energy.");
4184                                 note_dies = _("の精神は崩壊し、肉体は抜け殻となった。", " collapses, a mindless husk.");
4185
4186                                 if (who > 0)
4187                                 {
4188                                         do_conf = randint0(4) + 4;
4189                                         do_stun = randint0(4) + 4;
4190                                 }
4191                                 else
4192                                 {
4193                                         do_conf = randint0(8) + 8;
4194                                         do_stun = randint0(8) + 8;
4195                                 }
4196                                 (void)set_monster_slow(c_ptr->m_idx, MON_SLOW(m_ptr) + 10);
4197                         }
4198                         break;
4199                 }
4200
4201                 /* CAUSE_1 */
4202                 case GF_CAUSE_1:
4203                 {
4204                         if (seen) obvious = TRUE;
4205                         if (!who) msg_format(_("%sを指差して呪いをかけた。", "You point at %s and curse."), m_name);
4206
4207                         if (r_ptr->flagsr & RFR_RES_ALL)
4208                         {
4209                                 note = _("には完全な耐性がある!", " is immune.");
4210                                 skipped = TRUE;
4211                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
4212                                 break;
4213                         }
4214
4215                         /* Attempt a saving throw */
4216                         if (randint0(100 + (caster_lev / 2)) < (r_ptr->level + 35))
4217                         {
4218                                 note = _("には効果がなかった。", " is unaffected.");
4219                                 dam = 0;
4220                         }
4221                         break;
4222                 }
4223
4224                 /* CAUSE_2 */
4225                 case GF_CAUSE_2:
4226                 {
4227                         if (seen) obvious = TRUE;
4228                         if (!who) msg_format(_("%sを指差して恐ろしげに呪いをかけた。", "You point at %s and curse horribly."), m_name);
4229
4230                         if (r_ptr->flagsr & RFR_RES_ALL)
4231                         {
4232                                 note = _("には完全な耐性がある!", " is immune.");
4233                                 skipped = TRUE;
4234                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
4235                                 break;
4236                         }
4237
4238                         /* Attempt a saving throw */
4239                         if (randint0(100 + (caster_lev / 2)) < (r_ptr->level + 35))
4240                         {
4241                                 note = _("には効果がなかった。", " is unaffected.");
4242                                 dam = 0;
4243                         }
4244                         break;
4245                 }
4246
4247                 /* CAUSE_3 */
4248                 case GF_CAUSE_3:
4249                 {
4250                         if (seen) obvious = TRUE;
4251                         if (!who) msg_format(_("%sを指差し、恐ろしげに呪文を唱えた!", "You point at %s, incanting terribly!"), m_name);
4252
4253                         if (r_ptr->flagsr & RFR_RES_ALL)
4254                         {
4255                                 note = _("には完全な耐性がある!", " is immune.");
4256                                 skipped = TRUE;
4257                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
4258                                 break;
4259                         }
4260
4261                         /* Attempt a saving throw */
4262                         if (randint0(100 + (caster_lev / 2)) < (r_ptr->level + 35))
4263                         {
4264                                 note = _("には効果がなかった。", " is unaffected.");
4265                                 dam = 0;
4266                         }
4267                         break;
4268                 }
4269
4270                 /* CAUSE_4 */
4271                 case GF_CAUSE_4:
4272                 {
4273                         if (seen) obvious = TRUE;
4274                         if (!who) 
4275                                 msg_format(_("%sの秘孔を突いて、「お前は既に死んでいる」と叫んだ。", 
4276                                                          "You point at %s, screaming the word, 'DIE!'."), m_name);
4277
4278                         if (r_ptr->flagsr & RFR_RES_ALL)
4279                         {
4280                                 note = _("には完全な耐性がある!", " is immune.");
4281                                 skipped = TRUE;
4282                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
4283                                 break;
4284                         }
4285
4286                         /* Attempt a saving throw */
4287                         if ((randint0(100 + (caster_lev / 2)) < (r_ptr->level + 35)) && ((who <= 0) || (caster_ptr->r_idx != MON_KENSHIROU)))
4288                         {
4289                                 note = _("には効果がなかった。", " is unaffected.");
4290                                 dam = 0;
4291                         }
4292                         break;
4293                 }
4294
4295                 /* HAND_DOOM */
4296                 case GF_HAND_DOOM:
4297                 {
4298                         if (seen) obvious = TRUE;
4299
4300                         if (r_ptr->flagsr & RFR_RES_ALL)
4301                         {
4302                                 note = _("には完全な耐性がある!", " is immune.");
4303                                 skipped = TRUE;
4304                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
4305                                 break;
4306                         }
4307
4308                         if (r_ptr->flags1 & RF1_UNIQUE)
4309                         {
4310                                 note = _("には効果がなかった。", " is unaffected.");
4311                                 dam = 0;
4312                         }
4313                         else
4314                         {
4315                                 if ((who > 0) ? ((caster_lev + randint1(dam)) > (r_ptr->level + 10 + randint1(20))) :
4316                                    (((caster_lev / 2) + randint1(dam)) > (r_ptr->level + randint1(200))))
4317                                 {
4318                                         dam = ((40 + randint1(20)) * m_ptr->hp) / 100;
4319
4320                                         if (m_ptr->hp < dam) dam = m_ptr->hp - 1;
4321                                 }
4322                                 else
4323                                 {
4324                                         note = _("は耐性を持っている!", "resists!");
4325                                         dam = 0;
4326                                 }
4327                         }
4328                         break;
4329                 }
4330
4331                 /* Capture monster */
4332                 case GF_CAPTURE:
4333                 {
4334                         int nokori_hp;
4335                         if ((p_ptr->inside_quest && (quest[p_ptr->inside_quest].type == QUEST_TYPE_KILL_ALL) && !is_pet(m_ptr)) ||
4336                                 (r_ptr->flags1 & (RF1_UNIQUE)) || (r_ptr->flags7 & (RF7_NAZGUL)) || (r_ptr->flags7 & (RF7_UNIQUE2)) || (r_ptr->flags1 & RF1_QUESTOR) || m_ptr->parent_m_idx)
4337                         {
4338                                 msg_format(_("%sには効果がなかった。", "%s is unaffected."), m_name);
4339                                 skipped = TRUE;
4340                                 break;
4341                         }
4342
4343                         if (is_pet(m_ptr)) nokori_hp = m_ptr->maxhp * 4L;
4344                         else if ((p_ptr->pclass == CLASS_BEASTMASTER) && monster_living(r_ptr))
4345                                 nokori_hp = m_ptr->maxhp * 3 / 10;
4346                         else
4347                                 nokori_hp = m_ptr->maxhp * 3 / 20;
4348
4349                         if (m_ptr->hp >= nokori_hp)
4350                         {
4351                                 msg_format(_("もっと弱らせないと。", "You need to weaken %s more."), m_name);
4352                                 skipped = TRUE;
4353                         }
4354                         else if (m_ptr->hp < randint0(nokori_hp))
4355                         {
4356                                 if (m_ptr->mflag2 & MFLAG2_CHAMELEON) choose_new_monster(c_ptr->m_idx, FALSE, MON_CHAMELEON);
4357                                 msg_format(_("%sを捕えた!", "You capture %^s!"), m_name);
4358                                 cap_mon = m_ptr->r_idx;
4359                                 cap_mspeed = m_ptr->mspeed;
4360                                 cap_hp = m_ptr->hp;
4361                                 cap_maxhp = m_ptr->max_maxhp;
4362                                 cap_nickname = m_ptr->nickname; /* Quark transfer */
4363                                 if (c_ptr->m_idx == p_ptr->riding)
4364                                 {
4365                                         if (rakuba(-1, FALSE))
4366                                         {
4367                                                 msg_format(_("地面に落とされた。", "You have fallen from %s."), m_name);
4368                                         }
4369                                 }
4370
4371                                 delete_monster_idx(c_ptr->m_idx);
4372
4373                                 return (TRUE);
4374                         }
4375                         else
4376                         {
4377                                 msg_format(_("うまく捕まえられなかった。", "You failed to capture %s."), m_name);
4378                                 skipped = TRUE;
4379                         }
4380                         break;
4381                 }
4382
4383                 /* Attack (Use "dam" as attack type) */
4384                 case GF_ATTACK:
4385                 {
4386                         /* Return this monster's death */
4387                         return py_attack(y, x, dam);
4388                 }
4389
4390                 /* Sleep (Use "dam" as "power") */
4391                 case GF_ENGETSU:
4392                 {
4393                         int effect = 0;
4394                         bool done = TRUE;
4395
4396                         if (seen) obvious = TRUE;
4397
4398                         if (r_ptr->flagsr & RFR_RES_ALL)
4399                         {
4400                                 note = _("には効果がなかった。", " is unaffected.");
4401                                 dam = 0;
4402                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
4403                                 break;
4404                         }
4405                         if (r_ptr->flags2 & RF2_EMPTY_MIND)
4406                         {
4407                                 note = _("には効果がなかった。", " is unaffected.");
4408                                 dam = 0;
4409                                 skipped = TRUE;
4410                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags2 |= (RF2_EMPTY_MIND);
4411                                 break;
4412                         }
4413                         if (MON_CSLEEP(m_ptr))
4414                         {
4415                                 note = _("には効果がなかった。", " is unaffected.");
4416                                 dam = 0;
4417                                 skipped = TRUE;
4418                                 break;
4419                         }
4420
4421                         if (one_in_(5)) effect = 1;
4422                         else if (one_in_(4)) effect = 2;
4423                         else if (one_in_(3)) effect = 3;
4424                         else done = FALSE;
4425
4426                         if (effect == 1)
4427                         {
4428                                 /* Powerful monsters can resist */
4429                                 if ((r_ptr->flags1 & RF1_UNIQUE) ||
4430                                         (r_ptr->level > randint1((dam - 10) < 1 ? 1 : (dam - 10)) + 10))
4431                                 {
4432                                         note = _("には効果がなかった。", " is unaffected.");
4433                                         obvious = FALSE;
4434                                 }
4435
4436                                 /* Normal monsters slow down */
4437                                 else
4438                                 {
4439                                         if (set_monster_slow(c_ptr->m_idx, MON_SLOW(m_ptr) + 50))
4440                                         {
4441                                                 note = _("の動きが遅くなった。", " starts moving slower.");
4442                                         }
4443                                 }
4444                         }
4445
4446                         else if (effect == 2)
4447                         {
4448                                 do_stun = damroll((p_ptr->lev / 10) + 3 , (dam)) + 1;
4449
4450                                 /* Attempt a saving throw */
4451                                 if ((r_ptr->flags1 & (RF1_UNIQUE)) ||
4452                                         (r_ptr->level > randint1((dam - 10) < 1 ? 1 : (dam - 10)) + 10))
4453                                 {
4454                                         /* Resist */
4455                                         do_stun = 0;
4456
4457                                         /* No obvious effect */
4458                                         note = _("には効果がなかった。", " is unaffected.");
4459                                         obvious = FALSE;
4460                                 }
4461                         }
4462
4463                         else if (effect == 3)
4464                         {
4465                                 /* Attempt a saving throw */
4466                                 if ((r_ptr->flags1 & RF1_UNIQUE) ||
4467                                         (r_ptr->flags3 & RF3_NO_SLEEP) ||
4468                                         (r_ptr->level > randint1((dam - 10) < 1 ? 1 : (dam - 10)) + 10))
4469                                 {
4470                                         /* Memorize a flag */
4471                                         if (r_ptr->flags3 & RF3_NO_SLEEP)
4472                                         {
4473                                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags3 |= (RF3_NO_SLEEP);
4474                                         }
4475
4476                                         /* No obvious effect */
4477                                         note = _("には効果がなかった。", " is unaffected.");
4478                                         obvious = FALSE;
4479                                 }
4480                                 else
4481                                 {
4482                                         /* Go to sleep (much) later */
4483                                         note = _("は眠り込んでしまった!", " falls asleep!");
4484                                         do_sleep = 500;
4485                                 }
4486                         }
4487
4488                         if (!done)
4489                         {
4490                                 note = _("には効果がなかった。", " is unaffected.");
4491                         }
4492
4493                         /* No "real" damage */
4494                         dam = 0;
4495                         break;
4496                 }
4497
4498                 /* GENOCIDE */
4499                 case GF_GENOCIDE:
4500                 {
4501                         if (seen) obvious = TRUE;
4502
4503                         if (r_ptr->flagsr & RFR_RES_ALL)
4504                         {
4505                                 note = _("には効果がなかった。", " is unaffected.");
4506                                 skipped = TRUE;
4507                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
4508                                 break;
4509                         }
4510
4511                         if (genocide_aux(c_ptr->m_idx, dam, !who, (r_ptr->level + 1) / 2, _("モンスター消滅", "Genocide One")))
4512                         {
4513                                 if (seen_msg) msg_format(_("%sは消滅した!", "%^s disappered!"), m_name);
4514                                 chg_virtue(V_VITALITY, -1);
4515                                 return TRUE;
4516                         }
4517
4518                         skipped = TRUE;
4519                         break;
4520                 }
4521
4522                 case GF_PHOTO:
4523                 {
4524                         if (!who) msg_format(_("%sを写真に撮った。", "You take a photograph of %s."), m_name);
4525                         /* Hurt by light */
4526                         if (r_ptr->flags3 & (RF3_HURT_LITE))
4527                         {
4528                                 /* Obvious effect */
4529                                 if (seen) obvious = TRUE;
4530
4531                                 /* Memorize the effects */
4532                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags3 |= (RF3_HURT_LITE);
4533
4534                                 /* Special effect */
4535                                 note = _("は光に身をすくめた!", " cringes from the light!");
4536                                 note_dies = _("は光を受けてしぼんでしまった!", " shrivels away in the light!");
4537                         }
4538
4539                         /* Normally no damage */
4540                         else
4541                         {
4542                                 /* No damage */
4543                                 dam = 0;
4544                         }
4545
4546                         photo = m_ptr->r_idx;
4547
4548                         break;
4549                 }
4550
4551
4552                 /* blood curse */
4553                 case GF_BLOOD_CURSE:
4554                 {
4555                         if (seen) obvious = TRUE;
4556
4557                         if (r_ptr->flagsr & RFR_RES_ALL)
4558                         {
4559                                 note = _("には完全な耐性がある!", " is immune.");
4560                                 dam = 0;
4561                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
4562                                 break;
4563                         }
4564                         break;
4565                 }
4566
4567                 case GF_CRUSADE:
4568                 {
4569                         bool success = FALSE;
4570                         if (seen) obvious = TRUE;
4571
4572                         if ((r_ptr->flags3 & (RF3_GOOD)) && !p_ptr->inside_arena)
4573                         {
4574                                 if (r_ptr->flags3 & (RF3_NO_CONF)) dam -= 50;
4575                                 if (dam < 1) dam = 1;
4576
4577                                 /* No need to tame your pet */
4578                                 if (is_pet(m_ptr))
4579                                 {
4580                                         note = _("の動きが速くなった。", " starts moving faster.");
4581                                         (void)set_monster_fast(c_ptr->m_idx, MON_FAST(m_ptr) + 100);
4582                                         success = TRUE;
4583                                 }
4584
4585                                 /* Attempt a saving throw */
4586                                 else if ((r_ptr->flags1 & (RF1_QUESTOR)) ||
4587                                         (r_ptr->flags1 & (RF1_UNIQUE)) ||
4588                                         (m_ptr->mflag2 & MFLAG2_NOPET) ||
4589                                         (p_ptr->cursed & TRC_AGGRAVATE) ||
4590                                          ((r_ptr->level+10) > randint1(dam)))
4591                                 {
4592                                         /* Resist */
4593                                         if (one_in_(4)) m_ptr->mflag2 |= MFLAG2_NOPET;
4594                                 }
4595                                 else
4596                                 {
4597                                         note = _("を支配した。", " is tamed!");
4598                                         set_pet(m_ptr);
4599                                         (void)set_monster_fast(c_ptr->m_idx, MON_FAST(m_ptr) + 100);
4600
4601                                         /* Learn about type */
4602                                         if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags3 |= (RF3_GOOD);
4603                                         success = TRUE;
4604                                 }
4605                         }
4606
4607                         if (!success)
4608                         {
4609                                 if (!(r_ptr->flags3 & RF3_NO_FEAR))
4610                                 {
4611                                         do_fear = randint1(90)+10;
4612                                 }
4613                                 else if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flags3 |= (RF3_NO_FEAR);
4614                         }
4615
4616                         /* No "real" damage */
4617                         dam = 0;
4618                         break;
4619                 }
4620
4621                 case GF_WOUNDS:
4622                 {
4623                         if (seen) obvious = TRUE;
4624
4625                         if (r_ptr->flagsr & RFR_RES_ALL)
4626                         {
4627                                 note = _("には完全な耐性がある!", " is immune.");
4628                                 skipped = TRUE;
4629                                 if (is_original_ap_and_seen(m_ptr)) r_ptr->r_flagsr |= (RFR_RES_ALL);
4630                                 break;
4631                         }
4632
4633                         /* Attempt a saving throw */
4634                         if (randint0(100 + dam) < (r_ptr->level + 50))
4635                         {
4636                                 note = _("には効果がなかった。", " is unaffected.");
4637                                 dam = 0;
4638                         }
4639                         break;
4640                 }
4641
4642                 /* Default */
4643                 default:
4644                 {
4645                         /* Irrelevant */
4646                         skipped = TRUE;
4647
4648                         /* No damage */
4649                         dam = 0;
4650
4651                         break;
4652                 }
4653         }
4654
4655
4656         /* Absolutely no effect */
4657         if (skipped) return (FALSE);
4658
4659         /* "Unique" monsters cannot be polymorphed */
4660         if (r_ptr->flags1 & (RF1_UNIQUE)) do_poly = FALSE;
4661
4662         /* Quest monsters cannot be polymorphed */
4663         if (r_ptr->flags1 & RF1_QUESTOR) do_poly = FALSE;
4664
4665         if (p_ptr->riding && (c_ptr->m_idx == p_ptr->riding)) do_poly = FALSE;
4666
4667         /* "Unique" and "quest" monsters can only be "killed" by the player. */
4668         if (((r_ptr->flags1 & (RF1_UNIQUE | RF1_QUESTOR)) || (r_ptr->flags7 & RF7_NAZGUL)) && !p_ptr->inside_battle)
4669         {
4670                 if (who && (dam > m_ptr->hp)) dam = m_ptr->hp;
4671         }
4672
4673         if (!who && slept)
4674         {
4675                 if (!(r_ptr->flags3 & RF3_EVIL) || one_in_(5)) chg_virtue(V_COMPASSION, -1);
4676                 if (!(r_ptr->flags3 & RF3_EVIL) || one_in_(5)) chg_virtue(V_HONOUR, -1);
4677         }
4678
4679         /* Modify the damage */
4680         tmp = dam;
4681         dam = mon_damage_mod(m_ptr, dam, (bool)(typ == GF_PSY_SPEAR));
4682         if ((tmp > 0) && (dam == 0)) note = _("はダメージを受けていない。", " is unharmed.");
4683
4684         /* Check for death */
4685         if (dam > m_ptr->hp)
4686         {
4687                 /* Extract method of death */
4688                 note = note_dies;
4689         }
4690         else
4691         {
4692                 /* Sound and Impact resisters never stun */
4693                 if (do_stun &&
4694                         !(r_ptr->flagsr & (RFR_RES_SOUN | RFR_RES_WALL)) &&
4695                         !(r_ptr->flags3 & RF3_NO_STUN))
4696                 {
4697                         /* Obvious */
4698                         if (seen) obvious = TRUE;
4699
4700                         /* Get stunned */
4701                         if (MON_STUNNED(m_ptr))
4702                         {
4703                                 note = _("はひどくもうろうとした。", " is more dazed.");
4704                                 tmp = MON_STUNNED(m_ptr) + (do_stun / 2);
4705                         }
4706                         else
4707                         {
4708                                 note = _("はもうろうとした。", " is dazed.");
4709                                 tmp = do_stun;
4710                         }
4711
4712                         /* Apply stun */
4713                         (void)set_monster_stunned(c_ptr->m_idx, tmp);
4714
4715                         /* Get angry */
4716                         get_angry = TRUE;
4717                 }
4718
4719                 /* Confusion and Chaos resisters (and sleepers) never confuse */
4720                 if (do_conf &&
4721                          !(r_ptr->flags3 & RF3_NO_CONF) &&
4722                          !(r_ptr->flagsr & RFR_EFF_RES_CHAO_MASK))
4723                 {
4724                         /* Obvious */
4725                         if (seen) obvious = TRUE;
4726
4727                         /* Already partially confused */
4728                         if (MON_CONFUSED(m_ptr))
4729                         {
4730                                 note = _("はさらに混乱したようだ。", " looks more confused.");
4731                                 tmp = MON_CONFUSED(m_ptr) + (do_conf / 2);
4732                         }
4733
4734                         /* Was not confused */
4735                         else
4736                         {
4737                                 note = _("は混乱したようだ。", " looks confused.");
4738                                 tmp = do_conf;
4739                         }
4740
4741                         /* Apply confusion */
4742                         (void)set_monster_confused(c_ptr->m_idx, tmp);
4743
4744                         /* Get angry */
4745                         get_angry = TRUE;
4746                 }
4747
4748                 if (do_time)
4749                 {
4750                         /* Obvious */
4751                         if (seen) obvious = TRUE;
4752
4753                         if (do_time >= m_ptr->maxhp) do_time = m_ptr->maxhp - 1;
4754
4755                         if (do_time)
4756                         {
4757                                 note = _("は弱くなったようだ。", " seems weakened.");
4758                                 m_ptr->maxhp -= do_time;
4759                                 if ((m_ptr->hp - dam) > m_ptr->maxhp) dam = m_ptr->hp - m_ptr->maxhp;
4760                         }
4761                         get_angry = TRUE;
4762                 }
4763
4764                 /* Mega-Hack -- Handle "polymorph" -- monsters get a saving throw */
4765                 if (do_poly && (randint1(90) > r_ptr->level))
4766                 {
4767                         if (polymorph_monster(y, x))
4768                         {
4769                                 /* Obvious */
4770                                 if (seen) obvious = TRUE;
4771
4772                                 /* Monster polymorphs */
4773                                 note = _("が変身した!", " changes!");
4774
4775                                 /* Turn off the damage */
4776                                 dam = 0;
4777                         }
4778                         else
4779                         {
4780                                 /* No polymorph */
4781                                 note = _("には効果がなかった。", " is unaffected.");
4782                         }
4783
4784                         /* Hack -- Get new monster */
4785                         m_ptr = &m_list[c_ptr->m_idx];
4786
4787                         /* Hack -- Get new race */
4788                         r_ptr = &r_info[m_ptr->r_idx];
4789                 }
4790
4791                 /* Handle "teleport" */
4792                 if (do_dist)
4793                 {
4794                         /* Obvious */
4795                         if (seen) obvious = TRUE;
4796
4797                         note = _("が消え去った!", " disappears!");
4798
4799                         if (!who) chg_virtue(V_VALOUR, -1);
4800
4801                         /* Teleport */
4802                         teleport_away(c_ptr->m_idx, do_dist,
4803                                                 (!who ? TELEPORT_DEC_VALOUR : 0L) | TELEPORT_PASSIVE);
4804
4805                         /* Hack -- get new location */
4806                         y = m_ptr->fy;
4807                         x = m_ptr->fx;
4808
4809                         /* Hack -- get new grid */
4810                         c_ptr = &cave[y][x];
4811                 }
4812
4813                 /* Fear */
4814                 if (do_fear)
4815                 {
4816                         /* Set fear */
4817                         (void)set_monster_monfear(c_ptr->m_idx, MON_MONFEAR(m_ptr) + do_fear);
4818
4819                         /* Get angry */
4820                         get_angry = TRUE;
4821                 }
4822         }
4823
4824         if (typ == GF_DRAIN_MANA)
4825         {
4826                 /* Drain mana does nothing */
4827         }
4828
4829         /* If another monster did the damage, hurt the monster by hand */
4830         else if (who)
4831         {
4832                 /* Redraw (later) if needed */
4833                 if (p_ptr->health_who == c_ptr->m_idx) p_ptr->redraw |= (PR_HEALTH);
4834                 if (p_ptr->riding == c_ptr->m_idx) p_ptr->redraw |= (PR_UHEALTH);
4835
4836                 /* Wake the monster up */
4837                 (void)set_monster_csleep(c_ptr->m_idx, 0);
4838
4839                 /* Hurt the monster */
4840                 m_ptr->hp -= dam;
4841
4842                 /* Dead monster */
4843                 if (m_ptr->hp < 0)
4844                 {
4845                         bool sad = FALSE;
4846
4847                         if (is_pet(m_ptr) && !(m_ptr->ml))
4848                                 sad = TRUE;
4849
4850                         /* Give detailed messages if destroyed */
4851                         if (known && note)
4852                         {
4853                                 monster_desc(m_name, m_ptr, MD_TRUE_NAME);
4854                                 if (see_s_msg)
4855                                 {
4856                                         msg_format("%^s%s", m_name, note);
4857                                 }
4858                                 else
4859                                 {
4860                                         mon_fight = TRUE;
4861                                 }
4862                         }
4863
4864                         if (who > 0) monster_gain_exp(who, m_ptr->r_idx);
4865
4866                         /* Generate treasure, etc */
4867                         monster_death(c_ptr->m_idx, FALSE);
4868
4869                         /* Delete the monster */
4870                         delete_monster_idx(c_ptr->m_idx);
4871
4872                         if (sad)
4873                         {
4874                                 msg_print(_("少し悲しい気分がした。", "You feel sad for a moment."));
4875                         }
4876                 }
4877
4878                 /* Damaged monster */
4879                 else
4880                 {
4881                         /* Give detailed messages if visible or destroyed */
4882                         if (note && seen_msg) msg_format("%^s%s", m_name, note);
4883
4884                         /* Hack -- Pain message */
4885                         else if (see_s_msg)
4886                         {
4887                                 message_pain(c_ptr->m_idx, dam);
4888                         }
4889                         else
4890                         {
4891                                 mon_fight = TRUE;
4892                         }
4893
4894                         /* Hack -- handle sleep */
4895                         if (do_sleep) (void)set_monster_csleep(c_ptr->m_idx, do_sleep);
4896                 }
4897         }
4898
4899         else if (heal_leper)
4900         {
4901                 if (seen_msg) msg_print(_("不潔な病人は病気が治った!", "The Mangy looking leper is healed!"));
4902
4903                 if (record_named_pet && is_pet(m_ptr) && m_ptr->nickname)
4904                 {
4905                         char m2_name[80];
4906
4907                         monster_desc(m2_name, m_ptr, MD_INDEF_VISIBLE);
4908                         do_cmd_write_nikki(NIKKI_NAMED_PET, RECORD_NAMED_PET_HEAL_LEPER, m2_name);
4909                 }
4910
4911                 delete_monster_idx(c_ptr->m_idx);
4912         }
4913
4914         /* If the player did it, give him experience, check fear */
4915         else
4916         {
4917                 bool fear = FALSE;
4918
4919                 /* Hurt the monster, check for fear and death */
4920                 if (mon_take_hit(c_ptr->m_idx, dam, &fear, note_dies))
4921                 {
4922                         /* Dead monster */
4923                 }
4924
4925                 /* Damaged monster */
4926                 else
4927                 {
4928                         /* HACK - anger the monster before showing the sleep message */
4929                         if (do_sleep) anger_monster(m_ptr);
4930
4931                         /* Give detailed messages if visible or destroyed */
4932                         if (note && seen_msg)
4933                                 msg_format(_("%s%s", "%^s%s"), m_name, note);
4934
4935                         /* Hack -- Pain message */
4936                         else if (known && (dam || !do_fear))
4937                         {
4938                                 message_pain(c_ptr->m_idx, dam);
4939                         }
4940
4941                         /* Anger monsters */
4942                         if (((dam > 0) || get_angry) && !do_sleep)
4943                                 anger_monster(m_ptr);
4944
4945                         /* Take note */
4946                         if ((fear || do_fear) && seen)
4947                         {
4948                                 sound(SOUND_FLEE);
4949
4950                                 msg_format(_("%^sは恐怖して逃げ出した!", "%^s flees in terror!"), m_name);
4951                         }
4952
4953                         /* Hack -- handle sleep */
4954                         if (do_sleep) (void)set_monster_csleep(c_ptr->m_idx, do_sleep);
4955                 }
4956         }
4957
4958         if ((typ == GF_BLOOD_CURSE) && one_in_(4))
4959         {
4960                 int curse_flg = (PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL | PROJECT_JUMP);
4961                 int count = 0;
4962                 do
4963                 {
4964                         switch (randint1(28))
4965                         {
4966                         case 1: case 2:
4967                                 if (!count)
4968                                 {
4969                                         msg_print(_("地面が揺れた...", "The ground trembles..."));
4970                                         earthquake(ty, tx, 4 + randint0(4));
4971                                         if (!one_in_(6)) break;
4972                                 }
4973                         case 3: case 4: case 5: case 6:
4974                                 if (!count)
4975                                 {
4976                                         int extra_dam = damroll(10, 10);
4977                                         msg_print(_("純粋な魔力の次元への扉が開いた!", "A portal opens to a plane of raw mana!"));
4978
4979                                         project(0, 8, ty, tx, extra_dam, GF_MANA, curse_flg, -1);
4980                                         if (!one_in_(6)) break;
4981                                 }
4982                         case 7: case 8:
4983                                 if (!count)
4984                                 {
4985                                         msg_print(_("空間が歪んだ!", "Space warps about you!"));
4986
4987                                         if (m_ptr->r_idx) teleport_away(c_ptr->m_idx, damroll(10, 10), TELEPORT_PASSIVE);
4988                                         if (one_in_(13)) count += activate_hi_summon(ty, tx, TRUE);
4989                                         if (!one_in_(6)) break;
4990                                 }
4991                         case 9: case 10: case 11:
4992                                 msg_print(_("エネルギーのうねりを感じた!", "You feel a surge of energy!"));
4993                                 project(0, 7, ty, tx, 50, GF_DISINTEGRATE, curse_flg, -1);
4994                                 if (!one_in_(6)) break;
4995                         case 12: case 13: case 14: case 15: case 16:
4996                                 aggravate_monsters(0);
4997                                 if (!one_in_(6)) break;
4998                         case 17: case 18:
4999                                 count += activate_hi_summon(ty, tx, TRUE);
5000                                 if (!one_in_(6)) break;
5001                         case 19: case 20: case 21: case 22:
5002                         {
5003                                 bool pet = !one_in_(3);
5004                                 BIT_FLAGS mode = PM_ALLOW_GROUP;
5005
5006                                 if (pet) mode |= PM_FORCE_PET;
5007                                 else mode |= (PM_NO_PET | PM_FORCE_FRIENDLY);
5008
5009                                 count += summon_specific((pet ? -1 : 0), p_ptr->y, p_ptr->x, (pet ? p_ptr->lev*2/3+randint1(p_ptr->lev/2) : dun_level), 0, mode);
5010                                 if (!one_in_(6)) break;
5011                         }
5012                         case 23: case 24: case 25:
5013                                 if (p_ptr->hold_exp && (randint0(100) < 75)) break;
5014                                 msg_print(_("経験値が体から吸い取られた気がする!", "You feel your experience draining away..."));
5015
5016                                 if (p_ptr->hold_exp) lose_exp(p_ptr->exp / 160);
5017                                 else lose_exp(p_ptr->exp / 16);
5018                                 if (!one_in_(6)) break;
5019                         case 26: case 27: case 28:
5020                         {
5021                                 int i = 0;
5022                                 if (one_in_(13))
5023                                 {
5024                                         while (i < 6)
5025                                         {
5026                                                 do
5027                                                 {
5028                                                         (void)do_dec_stat(i);
5029                                                 }
5030                                                 while (one_in_(2));
5031
5032                                                 i++;
5033                                         }
5034                                 }
5035                                 else
5036                                 {
5037                                         (void)do_dec_stat(randint0(6));
5038                                 }
5039                                 break;
5040                         }
5041                         }
5042                 }
5043                 while (one_in_(5));
5044         }
5045
5046         if (p_ptr->inside_battle)
5047         {
5048                 p_ptr->health_who = c_ptr->m_idx;
5049                 p_ptr->redraw |= (PR_HEALTH);
5050                 redraw_stuff();
5051         }
5052
5053         /* XXX XXX XXX Verify this code */
5054
5055         /* Update the monster */
5056         if (m_ptr->r_idx) update_mon(c_ptr->m_idx, FALSE);
5057
5058         /* Redraw the monster grid */
5059         lite_spot(y, x);
5060
5061
5062         /* Update monster recall window */
5063         if ((p_ptr->monster_race_idx == m_ptr->r_idx) && (seen || !m_ptr->r_idx))
5064         {
5065                 /* Window stuff */
5066                 p_ptr->window |= (PW_MONSTER);
5067         }
5068
5069         if ((dam > 0) && !is_pet(m_ptr) && !is_friendly(m_ptr))
5070         {
5071                 if (!who)
5072                 {
5073                         if (!(flg & PROJECT_NO_HANGEKI))
5074                         {
5075                                 set_target(m_ptr, monster_target_y, monster_target_x);
5076                         }
5077                 }
5078                 else if ((who > 0) && is_pet(caster_ptr) && !player_bold(m_ptr->target_y, m_ptr->target_x))
5079                 {
5080                         set_target(m_ptr, caster_ptr->fy, caster_ptr->fx);
5081                 }
5082         }
5083
5084         if (p_ptr->riding && (p_ptr->riding == c_ptr->m_idx) && (dam > 0))
5085         {
5086                 if (m_ptr->hp > m_ptr->maxhp/3) dam = (dam + 1) / 2;
5087                 rakubadam_m = (dam > 200) ? 200 : dam;
5088         }
5089
5090
5091         if (photo)
5092         {
5093                 object_type *q_ptr;
5094                 object_type forge;
5095
5096                 /* Get local object */
5097                 q_ptr = &forge;
5098
5099                 /* Prepare to make a Blade of Chaos */
5100                 object_prep(q_ptr, lookup_kind(TV_STATUE, SV_PHOTO));
5101
5102                 q_ptr->pval = photo;
5103
5104                 /* Mark the item as fully known */
5105                 q_ptr->ident |= (IDENT_MENTAL);
5106
5107                 /* Drop it in the dungeon */
5108                 (void)drop_near(q_ptr, -1, p_ptr->y, p_ptr->x);
5109         }
5110
5111         /* Track it */
5112         project_m_n++;
5113         project_m_x = x;
5114         project_m_y = y;
5115
5116         /* Return "Anything seen?" */
5117         return (obvious);
5118 }
5119
5120 /*!
5121  * @brief 汎用的なビーム/ボルト/ボール系によるプレイヤーへの効果処理 / Helper function for "project()" below.
5122  * @param who 魔法を発動したモンスター(0ならばプレイヤー) / Index of "source" monster (zero for "player")
5123  * @param who_name 効果を起こしたモンスターの名前
5124  * @param r 効果半径(ビーム/ボルト = 0 / ボール = 1以上) / Radius of explosion (0 = beam/bolt, 1 to 9 = ball)
5125  * @param y 目標Y座標 / Target y location (or location to travel "towards")
5126  * @param x 目標X座標 / Target x location (or location to travel "towards")
5127  * @param dam 基本威力 / Base damage roll to apply to affected monsters (or player)
5128  * @param typ 効果属性 / Type of damage to apply to monsters (and objects)
5129  * @param flg 効果フラグ
5130  * @param monspell 効果元のモンスター魔法ID
5131  * @return 何か一つでも効力があればTRUEを返す / TRUE if any "effects" of the projection were observed, else FALSE
5132  * @details
5133  * Handle a beam/bolt/ball causing damage to the player.
5134  * This routine takes a "source monster" (by index), a "distance", a default
5135  * "damage", and a "damage type".  See "project_m()" above.
5136  * If "rad" is non-zero, then the blast was centered elsewhere, and the damage
5137  * is reduced (see "project_m()" above).  This can happen if a monster breathes
5138  * at the player and hits a wall instead.
5139  * NOTE (Zangband): 'Bolt' attacks can be reflected back, so we need
5140  * to know if this is actually a ball or a bolt spell
5141  * We return "TRUE" if any "obvious" effects were observed.  XXX XXX Actually,
5142  * we just assume that the effects were obvious, for historical reasons.
5143  */
5144 static bool project_p(MONSTER_IDX who, cptr who_name, int r, POSITION y, POSITION x, HIT_POINT dam, EFFECT_ID typ, BIT_FLAGS flg, int monspell)
5145 {
5146         int k = 0;
5147         int rlev = 0;
5148
5149         /* Hack -- assume obvious */
5150         bool obvious = TRUE;
5151
5152         /* Player blind-ness */
5153         bool blind = (p_ptr->blind ? TRUE : FALSE);
5154
5155         /* Player needs a "description" (he is blind) */
5156         bool fuzzy = FALSE;
5157
5158         /* Source monster */
5159         monster_type *m_ptr = NULL;
5160
5161         /* Monster name (for attacks) */
5162         char m_name[80];
5163
5164         /* Monster name (for damage) */
5165         char killer[80];
5166
5167         /* Hack -- messages */
5168         cptr act = NULL;
5169
5170         int get_damage = 0;
5171
5172
5173         /* Player is not here */
5174         if (!player_bold(y, x)) return (FALSE);
5175
5176         if ((p_ptr->special_defense & NINJA_KAWARIMI) && dam && (randint0(55) < (p_ptr->lev*3/5+20)) && who && (who != p_ptr->riding))
5177         {
5178                 if (kawarimi(TRUE)) return FALSE;
5179         }
5180
5181         /* Player cannot hurt himself */
5182         if (!who) return (FALSE);
5183         if (who == p_ptr->riding) return (FALSE);
5184
5185         if ((p_ptr->reflect || ((p_ptr->special_defense & KATA_FUUJIN) && !p_ptr->blind)) && (flg & PROJECT_REFLECTABLE) && !one_in_(10))
5186         {
5187                 POSITION t_y, t_x;
5188                 int max_attempts = 10;
5189                 sound(SOUND_REFLECT);
5190
5191                 if (blind) 
5192                         msg_print(_("何かが跳ね返った!", "Something bounces!"));
5193                 else if (p_ptr->special_defense & KATA_FUUJIN) 
5194                         msg_print(_("風の如く武器を振るって弾き返した!", "The attack bounces!"));
5195                 else 
5196                         msg_print(_("攻撃が跳ね返った!", "The attack bounces!"));
5197
5198
5199                 /* Choose 'new' target */
5200                 if (who > 0)
5201                 {
5202                         do
5203                         {
5204                                 t_y = m_list[who].fy - 1 + randint1(3);
5205                                 t_x = m_list[who].fx - 1 + randint1(3);
5206                                 max_attempts--;
5207                         }
5208                         while (max_attempts && in_bounds2u(t_y, t_x) && !projectable(p_ptr->y, p_ptr->x, t_y, t_x));
5209
5210                         if (max_attempts < 1)
5211                         {
5212                                 t_y = m_list[who].fy;
5213                                 t_x = m_list[who].fx;
5214                         }
5215                 }
5216                 else
5217                 {
5218                         t_y = p_ptr->y - 1 + randint1(3);
5219                         t_x = p_ptr->x - 1 + randint1(3);
5220                 }
5221
5222                 project(0, 0, t_y, t_x, dam, typ, (PROJECT_STOP|PROJECT_KILL|PROJECT_REFLECTABLE), monspell);
5223
5224                 disturb(1, 1);
5225                 return TRUE;
5226         }
5227
5228         /* XXX XXX XXX */
5229         /* Limit maximum damage */
5230         if (dam > 1600) dam = 1600;
5231
5232         /* Reduce damage by distance */
5233         dam = (dam + r) / (r + 1);
5234
5235
5236         /* If the player is blind, be more descriptive */
5237         if (blind) fuzzy = TRUE;
5238
5239
5240         if (who > 0)
5241         {
5242                 /* Get the source monster */
5243                 m_ptr = &m_list[who];
5244                 /* Extract the monster level */
5245                 rlev = (((&r_info[m_ptr->r_idx])->level >= 1) ? (&r_info[m_ptr->r_idx])->level : 1);
5246
5247                 /* Get the monster name */
5248                 monster_desc(m_name, m_ptr, 0);
5249
5250                 /* Get the monster's real name (gotten before polymorph!) */
5251                 strcpy(killer, who_name);
5252         }
5253         else
5254         {
5255                 switch (who)
5256                 {
5257                 case PROJECT_WHO_UNCTRL_POWER:
5258                         strcpy(killer, _("制御できない力の氾流", "uncontrollable power storm"));
5259                         break;
5260
5261                 case PROJECT_WHO_GLASS_SHARDS:
5262                         strcpy(killer, _("ガラスの破片", "shards of glass"));
5263                         break;
5264
5265                 default:
5266                         strcpy(killer, _("罠", "a trap"));
5267                         break;
5268                 }
5269
5270                 /* Paranoia */
5271                 strcpy(m_name, killer);
5272         }
5273
5274         /* Analyze the damage */
5275         switch (typ)
5276         {
5277                 /* Standard damage -- hurts inventory too */
5278                 case GF_ACID:
5279                 {
5280                         if (fuzzy) msg_print(_("酸で攻撃された!", "You are hit by acid!"));                    
5281                         get_damage = acid_dam(dam, killer, monspell, FALSE);
5282                         break;
5283                 }
5284
5285                 /* Standard damage -- hurts inventory too */
5286                 case GF_FIRE:
5287                 {
5288                         if (fuzzy) msg_print(_("火炎で攻撃された!", "You are hit by fire!"));
5289                         get_damage = fire_dam(dam, killer, monspell, FALSE);
5290                         break;
5291                 }
5292
5293                 /* Standard damage -- hurts inventory too */
5294                 case GF_COLD:
5295                 {
5296                         if (fuzzy) msg_print(_("冷気で攻撃された!", "You are hit by cold!"));
5297                         get_damage = cold_dam(dam, killer, monspell, FALSE);
5298                         break;
5299                 }
5300
5301                 /* Standard damage -- hurts inventory too */
5302                 case GF_ELEC:
5303                 {
5304                         if (fuzzy) msg_print(_("電撃で攻撃された!", "You are hit by lightning!"));
5305                         get_damage = elec_dam(dam, killer, monspell, FALSE);
5306                         break;
5307                 }
5308
5309                 /* Standard damage -- also poisons player */
5310                 case GF_POIS:
5311                 {
5312                         bool double_resist = IS_OPPOSE_POIS();
5313                         if (fuzzy) msg_print(_("毒で攻撃された!", "You are hit by poison!"));
5314
5315                         if (p_ptr->resist_pois) dam = (dam + 2) / 3;
5316                         if (double_resist) dam = (dam + 2) / 3;
5317
5318                         if ((!(double_resist || p_ptr->resist_pois)) &&
5319                                  one_in_(HURT_CHANCE) && !CHECK_MULTISHADOW())
5320                         {
5321                                 do_dec_stat(A_CON);
5322                         }
5323
5324                         get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
5325
5326                         if (!(double_resist || p_ptr->resist_pois) && !CHECK_MULTISHADOW())
5327                         {
5328                                 set_poisoned(p_ptr->poisoned + randint0(dam) + 10);
5329                         }
5330                         break;
5331                 }
5332
5333                 /* Standard damage -- also poisons / mutates player */
5334                 case GF_NUKE:
5335                 {
5336                         bool double_resist = IS_OPPOSE_POIS();
5337                         if (fuzzy) msg_print(_("放射能で攻撃された!", "You are hit by radiation!"));
5338
5339                         if (p_ptr->resist_pois) dam = (2 * dam + 2) / 5;
5340                         if (double_resist) dam = (2 * dam + 2) / 5;
5341                         get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
5342                         if (!(double_resist || p_ptr->resist_pois) && !CHECK_MULTISHADOW())
5343                         {
5344                                 set_poisoned(p_ptr->poisoned + randint0(dam) + 10);
5345
5346                                 if (one_in_(5)) /* 6 */
5347                                 {
5348                                         msg_print(_("奇形的な変身を遂げた!", "You undergo a freakish metamorphosis!"));
5349                                         if (one_in_(4)) /* 4 */
5350                                                 do_poly_self();
5351                                         else
5352                                                 mutate_player();
5353                                 }
5354
5355                                 if (one_in_(6))
5356                                 {
5357                                         inven_damage(set_acid_destroy, 2);
5358                                 }
5359                         }
5360                         break;
5361                 }
5362
5363                 /* Standard damage */
5364                 case GF_MISSILE:
5365                 {
5366                         if (fuzzy) msg_print(_("何かで攻撃された!", "You are hit by something!"));
5367                         get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
5368                         break;
5369                 }
5370
5371                 /* Holy Orb -- Player only takes partial damage */
5372                 case GF_HOLY_FIRE:
5373                 {
5374                         if (fuzzy) msg_print(_("何かで攻撃された!", "You are hit by something!"));
5375                         if (p_ptr->align > 10)
5376                                 dam /= 2;
5377                         else if (p_ptr->align < -10)
5378                                 dam *= 2;
5379                         get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
5380                         break;
5381                 }
5382
5383                 case GF_HELL_FIRE:
5384                 {
5385                         if (fuzzy) msg_print(_("何かで攻撃された!", "You are hit by something!"));
5386                         if (p_ptr->align > 10)
5387                                 dam *= 2;
5388                         get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
5389                         break;
5390                 }
5391
5392                 /* Arrow -- XXX no dodging */
5393                 case GF_ARROW:
5394                 {
5395                         if (fuzzy)
5396                         {
5397                                 msg_print(_("何か鋭いもので攻撃された!", "You are hit by something sharp!"));
5398                         }
5399                         else if ((inventory[INVEN_RARM].name1 == ART_ZANTETSU) || (inventory[INVEN_LARM].name1 == ART_ZANTETSU))
5400                         {
5401                                 msg_print(_("矢を斬り捨てた!", "You cut down the arrow!"));
5402                                 break;
5403                         }
5404                         get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
5405                         break;
5406                 }
5407
5408                 /* Plasma -- XXX No resist */
5409                 case GF_PLASMA:
5410                 {
5411                         if (fuzzy) msg_print(_("何かとても熱いもので攻撃された!", "You are hit by something *HOT*!"));
5412                         get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
5413
5414                         if (!p_ptr->resist_sound && !CHECK_MULTISHADOW())
5415                         {
5416                                 int plus_stun = (randint1((dam > 40) ? 35 : (dam * 3 / 4 + 5)));
5417                                 (void)set_stun(p_ptr->stun + plus_stun);
5418                         }
5419
5420                         if (!(p_ptr->resist_fire ||
5421                                 IS_OPPOSE_FIRE() ||
5422                                 p_ptr->immune_fire))
5423                         {
5424                                 inven_damage(set_acid_destroy, 3);
5425                         }
5426
5427                         break;
5428                 }
5429
5430                 /* Nether -- drain experience */
5431                 case GF_NETHER:
5432                 {
5433                         if (fuzzy) msg_print(_("地獄の力で攻撃された!", "You are hit by nether forces!"));
5434                         if (p_ptr->resist_neth)
5435                         {
5436                                 if (!prace_is_(RACE_SPECTRE))
5437                                 {
5438                                         dam *= 6; dam /= (randint1(4) + 7);
5439                                 }
5440                         }
5441                         else if (!CHECK_MULTISHADOW()) drain_exp(200 + (p_ptr->exp / 100), 200 + (p_ptr->exp / 1000), 75);
5442
5443                         if (prace_is_(RACE_SPECTRE) && !CHECK_MULTISHADOW())
5444                         {
5445                                 msg_print(_("気分がよくなった。", "You feel invigorated!"));
5446                                 hp_player(dam / 4);
5447                                 learn_spell(monspell);
5448                         }
5449                         else
5450                         {
5451                                 get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
5452                         }
5453
5454                         break;
5455                 }
5456
5457                 /* Water -- stun/confuse */
5458                 case GF_WATER:
5459                 {
5460                         if (fuzzy) msg_print(_("何か湿ったもので攻撃された!", "You are hit by something wet!"));
5461                         if (!CHECK_MULTISHADOW())
5462                         {
5463                                 if (!p_ptr->resist_sound)
5464                                 {
5465                                         set_stun(p_ptr->stun + randint1(40));
5466                                 }
5467                                 if (!p_ptr->resist_conf)
5468                                 {
5469                                         set_confused(p_ptr->confused + randint1(5) + 5);
5470                                 }
5471
5472                                 if (one_in_(5))
5473                                 {
5474                                         inven_damage(set_cold_destroy, 3);
5475                                 }
5476                         }
5477
5478                         get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
5479                         break;
5480                 }
5481
5482                 /* Chaos -- many effects */
5483                 case GF_CHAOS:
5484                 {
5485                         if (fuzzy) msg_print(_("無秩序の波動で攻撃された!", "You are hit by a wave of anarchy!"));
5486                         if (p_ptr->resist_chaos)
5487                         {
5488                                 dam *= 6; dam /= (randint1(4) + 7);
5489                         }
5490
5491                         if (!CHECK_MULTISHADOW())
5492                         {
5493                                 if (!p_ptr->resist_conf)
5494                                 {
5495                                         (void)set_confused(p_ptr->confused + randint0(20) + 10);
5496                                 }
5497                                 if (!p_ptr->resist_chaos)
5498                                 {
5499                                         (void)set_image(p_ptr->image + randint1(10));
5500                                         if (one_in_(3))
5501                                         {
5502                                                 msg_print(_("あなたの身体はカオスの力で捻じ曲げられた!", "Your body is twisted by chaos!"));
5503                                                 (void)gain_random_mutation(0);
5504                                         }
5505                                 }
5506                                 if (!p_ptr->resist_neth && !p_ptr->resist_chaos)
5507                                 {
5508                                         drain_exp(5000 + (p_ptr->exp / 100), 500 + (p_ptr->exp / 1000), 75);
5509                                 }
5510
5511                                 if (!p_ptr->resist_chaos || one_in_(9))
5512                                 {
5513                                         inven_damage(set_elec_destroy, 2);
5514                                         inven_damage(set_fire_destroy, 2);
5515                                 }
5516                         }
5517
5518                         get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
5519                         break;
5520                 }
5521
5522                 /* Shards -- mostly cutting */
5523                 case GF_SHARDS:
5524                 {
5525                         if (fuzzy) msg_print(_("何か鋭いもので攻撃された!", "You are hit by something sharp!"));
5526                         if (p_ptr->resist_shard)
5527                         {
5528                                 dam *= 6; dam /= (randint1(4) + 7);
5529                         }
5530                         else if (!CHECK_MULTISHADOW())
5531                         {
5532                                 (void)set_cut(p_ptr->cut + dam);
5533                         }
5534
5535                         if (!p_ptr->resist_shard || one_in_(13))
5536                         {
5537                                 inven_damage(set_cold_destroy, 2);
5538                         }
5539
5540                         get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
5541                         break;
5542                 }
5543
5544                 /* Sound -- mostly stunning */
5545                 case GF_SOUND:
5546                 {
5547                         if (fuzzy) msg_print(_("轟音で攻撃された!", "You are hit by a loud noise!"));
5548                         if (p_ptr->resist_sound)
5549                         {
5550                                 dam *= 5; dam /= (randint1(4) + 7);
5551                         }
5552                         else if (!CHECK_MULTISHADOW())
5553                         {
5554                                 int plus_stun = (randint1((dam > 90) ? 35 : (dam / 3 + 5)));
5555                                 (void)set_stun(p_ptr->stun + plus_stun);
5556                         }
5557
5558                         if (!p_ptr->resist_sound || one_in_(13))
5559                         {
5560                                 inven_damage(set_cold_destroy, 2);
5561                         }
5562
5563                         get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
5564                         break;
5565                 }
5566
5567                 /* Pure confusion */
5568                 case GF_CONFUSION:
5569                 {
5570                         if (fuzzy) msg_print(_("何か混乱するもので攻撃された!", "You are hit by something puzzling!"));
5571                         if (p_ptr->resist_conf)
5572                         {
5573                                 dam *= 5; dam /= (randint1(4) + 7);
5574                         }
5575                         else if (!CHECK_MULTISHADOW())
5576                         {
5577                                 (void)set_confused(p_ptr->confused + randint1(20) + 10);
5578                         }
5579                         get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
5580                         break;
5581                 }
5582
5583                 /* Disenchantment -- see above */
5584                 case GF_DISENCHANT:
5585                 {
5586                         if (fuzzy) msg_print(_("何かさえないもので攻撃された!", "You are hit by something static!"));
5587                         if (p_ptr->resist_disen)
5588                         {
5589                                 dam *= 6; dam /= (randint1(4) + 7);
5590                         }
5591                         else if (!CHECK_MULTISHADOW())
5592                         {
5593                                 (void)apply_disenchant(0);
5594                         }
5595                         get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
5596                         break;
5597                 }
5598
5599                 /* Nexus -- see above */
5600                 case GF_NEXUS:
5601                 {
5602                         if (fuzzy) msg_print(_("何か奇妙なもので攻撃された!", "You are hit by something strange!"));
5603                         if (p_ptr->resist_nexus)
5604                         {
5605                                 dam *= 6; dam /= (randint1(4) + 7);
5606                         }
5607                         else if (!CHECK_MULTISHADOW())
5608                         {
5609                                 apply_nexus(m_ptr);
5610                         }
5611                         get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
5612                         break;
5613                 }
5614
5615                 /* Force -- mostly stun */
5616                 case GF_FORCE:
5617                 {
5618                         if (fuzzy) msg_print(_("運動エネルギーで攻撃された!", "You are hit by kinetic force!"));
5619                         if (!p_ptr->resist_sound && !CHECK_MULTISHADOW())
5620                         {
5621                                 (void)set_stun(p_ptr->stun + randint1(20));
5622                         }
5623                         get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
5624                         break;
5625                 }
5626
5627
5628                 /* Rocket -- stun, cut */
5629                 case GF_ROCKET:
5630                 {
5631                         if (fuzzy) msg_print(_("爆発があった!", "There is an explosion!"));
5632                         if (!p_ptr->resist_sound && !CHECK_MULTISHADOW())
5633                         {
5634                                 (void)set_stun(p_ptr->stun + randint1(20));
5635                         }
5636
5637                         if (p_ptr->resist_shard)
5638                         {
5639                                 dam /= 2;
5640                         }
5641                         else if (!CHECK_MULTISHADOW())
5642                         {
5643                                 (void)set_cut(p_ptr->cut + (dam / 2));
5644                         }
5645
5646                         if (!p_ptr->resist_shard || one_in_(12))
5647                         {
5648                                 inven_damage(set_cold_destroy, 3);
5649                         }
5650
5651                         get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
5652                         break;
5653                 }
5654
5655                 /* Inertia -- slowness */
5656                 case GF_INERTIAL:
5657                 {
5658                         if (fuzzy) msg_print(_("何か遅いもので攻撃された!", "You are hit by something slow!"));
5659                         if (!CHECK_MULTISHADOW()) (void)set_slow(p_ptr->slow + randint0(4) + 4, FALSE);
5660                         get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
5661                         break;
5662                 }
5663
5664                 /* Lite -- blinding */
5665                 case GF_LITE:
5666                 {
5667                         if (fuzzy) msg_print(_("何かで攻撃された!", "You are hit by something!"));
5668                         if (p_ptr->resist_lite)
5669                         {
5670                                 dam *= 4; dam /= (randint1(4) + 7);
5671                         }
5672                         else if (!blind && !p_ptr->resist_blind && !CHECK_MULTISHADOW())
5673                         {
5674                                 (void)set_blind(p_ptr->blind + randint1(5) + 2);
5675                         }
5676
5677                         if (prace_is_(RACE_VAMPIRE) || (p_ptr->mimic_form == MIMIC_VAMPIRE))
5678                         {
5679                                 if (!CHECK_MULTISHADOW()) msg_print(_("光で肉体が焦がされた!", "The light scorches your flesh!"));
5680                                 dam *= 2;
5681                         }
5682                         else if (prace_is_(RACE_S_FAIRY))
5683                         {
5684                                 dam = dam * 4 / 3;
5685                         }
5686
5687                         if (p_ptr->wraith_form) dam *= 2;
5688                         get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
5689
5690                         if (p_ptr->wraith_form && !CHECK_MULTISHADOW())
5691                         {
5692                                 p_ptr->wraith_form = 0;
5693                                 msg_print(_("閃光のため非物質的な影の存在でいられなくなった。",
5694                                         "The light forces you out of your incorporeal shadow form."));
5695
5696                                 p_ptr->redraw |= PR_MAP;
5697                                 /* Update monsters */
5698                                 p_ptr->update |= (PU_MONSTERS);
5699                                 /* Window stuff */
5700                                 p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
5701
5702                                 /* Redraw status bar */
5703                                 p_ptr->redraw |= (PR_STATUS);
5704
5705                         }
5706
5707                         break;
5708                 }
5709
5710                 /* Dark -- blinding */
5711                 case GF_DARK:
5712                 {
5713                         if (fuzzy) msg_print(_("何かで攻撃された!", "You are hit by something!"));
5714                         if (p_ptr->resist_dark)
5715                         {
5716                                 dam *= 4; dam /= (randint1(4) + 7);
5717
5718                                 if (prace_is_(RACE_VAMPIRE) || (p_ptr->mimic_form == MIMIC_VAMPIRE) || p_ptr->wraith_form) dam = 0;
5719                         }
5720                         else if (!blind && !p_ptr->resist_blind && !CHECK_MULTISHADOW())
5721                         {
5722                                 (void)set_blind(p_ptr->blind + randint1(5) + 2);
5723                         }
5724                         get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
5725                         break;
5726                 }
5727
5728                 /* Time -- bolt fewer effects XXX */
5729                 case GF_TIME:
5730                 {
5731                         if (fuzzy) msg_print(_("過去からの衝撃に攻撃された!", "You are hit by a blast from the past!"));
5732                         if (p_ptr->resist_time)
5733                         {
5734                                 dam *= 4;
5735                                 dam /= (randint1(4) + 7);
5736                                 msg_print(_("時間が通り過ぎていく気がする。", "You feel as if time is passing you by."));
5737                         }
5738                         else if (!CHECK_MULTISHADOW())
5739                         {
5740                                 switch (randint1(10))
5741                                 {
5742                                         case 1: case 2: case 3: case 4: case 5:
5743                                         {
5744                                                 if (p_ptr->prace == RACE_ANDROID) break;
5745                                                 msg_print(_("人生が逆戻りした気がする。", "You feel life has clocked back."));
5746                                                 lose_exp(100 + (p_ptr->exp / 100) * MON_DRAIN_LIFE);
5747                                                 break;
5748                                         }
5749
5750                                         case 6: case 7: case 8: case 9:
5751                                         {
5752                                                 switch (randint1(6))
5753                                                 {
5754                                                         case 1: k = A_STR; act = _("強く", "strong"); break;
5755                                                         case 2: k = A_INT; act = _("聡明で", "bright"); break;
5756                                                         case 3: k = A_WIS; act = _("賢明で", "wise"); break;
5757                                                         case 4: k = A_DEX; act = _("器用で", "agile"); break;
5758                                                         case 5: k = A_CON; act = _("健康で", "hale"); break;
5759                                                         case 6: k = A_CHR; act = _("美しく", "beautiful"); break;
5760                                                 }
5761
5762                                                 msg_format(_("あなたは以前ほど%sなくなってしまった...。", 
5763                                                                          "You're not as %s as you used to be..."), act);
5764
5765                                                 p_ptr->stat_cur[k] = (p_ptr->stat_cur[k] * 3) / 4;
5766                                                 if (p_ptr->stat_cur[k] < 3) p_ptr->stat_cur[k] = 3;
5767                                                 p_ptr->update |= (PU_BONUS);
5768                                                 break;
5769                                         }
5770
5771                                         case 10:
5772                                         {
5773                                                 msg_print(_("あなたは以前ほど力強くなくなってしまった...。", 
5774                                                                         "You're not as powerful as you used to be..."));
5775
5776                                                 for (k = 0; k < 6; k++)
5777                                                 {
5778                                                         p_ptr->stat_cur[k] = (p_ptr->stat_cur[k] * 7) / 8;
5779                                                         if (p_ptr->stat_cur[k] < 3) p_ptr->stat_cur[k] = 3;
5780                                                 }
5781                                                 p_ptr->update |= (PU_BONUS);
5782                                                 break;
5783                                         }
5784                                 }
5785                         }
5786
5787                         get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
5788                         break;
5789                 }
5790
5791                 /* Gravity -- stun plus slowness plus teleport */
5792                 case GF_GRAVITY:
5793                 {
5794                         if (fuzzy) msg_print(_("何か重いもので攻撃された!", "You are hit by something heavy!"));
5795                                 msg_print(_("周辺の重力がゆがんだ。", "Gravity warps around you."));
5796
5797                         if (!CHECK_MULTISHADOW())
5798                         {
5799                                 teleport_player(5, TELEPORT_PASSIVE);
5800                                 if (!p_ptr->levitation)
5801                                         (void)set_slow(p_ptr->slow + randint0(4) + 4, FALSE);
5802                                 if (!(p_ptr->resist_sound || p_ptr->levitation))
5803                                 {
5804                                         int plus_stun = (randint1((dam > 90) ? 35 : (dam / 3 + 5)));
5805                                         (void)set_stun(p_ptr->stun + plus_stun);
5806                                 }
5807                         }
5808                         if (p_ptr->levitation)
5809                         {
5810                                 dam = (dam * 2) / 3;
5811                         }
5812
5813                         if (!p_ptr->levitation || one_in_(13))
5814                         {
5815                                 inven_damage(set_cold_destroy, 2);
5816                         }
5817
5818                         get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
5819                         break;
5820                 }
5821
5822                 /* Standard damage */
5823                 case GF_DISINTEGRATE:
5824                 {
5825                         if (fuzzy) msg_print(_("純粋なエネルギーで攻撃された!", "You are hit by pure energy!"));
5826
5827                         get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
5828                         break;
5829                 }
5830
5831                 case GF_OLD_HEAL:
5832                 {
5833                         if (fuzzy) msg_print(_("何らかの攻撃によって気分がよくなった。", "You are hit by something invigorating!"));
5834
5835                         (void)hp_player(dam);
5836                         dam = 0;
5837                         break;
5838                 }
5839
5840                 case GF_OLD_SPEED:
5841                 {
5842                         if (fuzzy) msg_print(_("何かで攻撃された!", "You are hit by something!"));
5843                         (void)set_fast(p_ptr->fast + randint1(5), FALSE);
5844                         dam = 0;
5845                         break;
5846                 }
5847
5848                 case GF_OLD_SLOW:
5849                 {
5850                         if (fuzzy) msg_print(_("何か遅いもので攻撃された!", "You are hit by something slow!"));
5851                         (void)set_slow(p_ptr->slow + randint0(4) + 4, FALSE);
5852                         break;
5853                 }
5854
5855                 case GF_OLD_SLEEP:
5856                 {
5857                         if (p_ptr->free_act)  break;
5858                         if (fuzzy) msg_print(_("眠ってしまった!", "You fall asleep!"));
5859
5860                         if (ironman_nightmare)
5861                         {
5862                                 msg_print(_("恐ろしい光景が頭に浮かんできた。", "A horrible vision enters your mind."));
5863                                 /* Have some nightmares */
5864                                 sanity_blast(NULL, FALSE);
5865                         }
5866
5867                         set_paralyzed(p_ptr->paralyzed + dam);
5868                         dam = 0;
5869                         break;
5870                 }
5871
5872                 /* Pure damage */
5873                 case GF_MANA:
5874                 case GF_SEEKER:
5875                 case GF_SUPER_RAY:
5876                 {
5877                         if (fuzzy) msg_print(_("魔法のオーラで攻撃された!", "You are hit by an aura of magic!"));
5878                         get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
5879                         break;
5880                 }
5881
5882                 /* Pure damage */
5883                 case GF_PSY_SPEAR:
5884                 {
5885                         if (fuzzy) msg_print(_("エネルギーの塊で攻撃された!", "You are hit by an energy!"));
5886                         get_damage = take_hit(DAMAGE_FORCE, dam, killer, monspell);
5887                         break;
5888                 }
5889
5890                 /* Pure damage */
5891                 case GF_METEOR:
5892                 {
5893                         if (fuzzy) msg_print(_("何かが空からあなたの頭上に落ちてきた!", "Something falls from the sky on you!"));
5894
5895                         get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
5896                         if (!p_ptr->resist_shard || one_in_(13))
5897                         {
5898                                 if (!p_ptr->immune_fire) inven_damage(set_fire_destroy, 2);
5899                                 inven_damage(set_cold_destroy, 2);
5900                         }
5901
5902                         break;
5903                 }
5904
5905                 /* Ice -- cold plus stun plus cuts */
5906                 case GF_ICE:
5907                 {
5908                         if (fuzzy) msg_print(_("何か鋭く冷たいもので攻撃された!", "You are hit by something sharp and cold!"));
5909                         get_damage = cold_dam(dam, killer, monspell, FALSE);
5910                         if (!CHECK_MULTISHADOW())
5911                         {
5912                                 if (!p_ptr->resist_shard)
5913                                 {
5914                                         (void)set_cut(p_ptr->cut + damroll(5, 8));
5915                                 }
5916                                 if (!p_ptr->resist_sound)
5917                                 {
5918                                         (void)set_stun(p_ptr->stun + randint1(15));
5919                                 }
5920
5921                                 if ((!(p_ptr->resist_cold || IS_OPPOSE_COLD())) || one_in_(12))
5922                                 {
5923                                         if (!p_ptr->immune_cold) inven_damage(set_cold_destroy, 3);
5924                                 }
5925                         }
5926
5927                         break;
5928                 }
5929
5930                 /* Death Ray */
5931                 case GF_DEATH_RAY:
5932                 {
5933                         if (fuzzy) msg_print(_("何か非常に冷たいもので攻撃された!", "You are hit by something extremely cold!"));
5934
5935                         if (p_ptr->mimic_form)
5936                         {
5937                                 if (!(mimic_info[p_ptr->mimic_form].MIMIC_FLAGS & MIMIC_IS_NONLIVING))
5938                                         get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
5939                         }
5940                         else
5941                         {
5942
5943                         switch (p_ptr->prace)
5944                         {
5945                                 /* Some races are immune */
5946                                 case RACE_GOLEM:
5947                                 case RACE_SKELETON:
5948                                 case RACE_ZOMBIE:
5949                                 case RACE_VAMPIRE:
5950                                 case RACE_DEMON:
5951                                 case RACE_SPECTRE:
5952                                 {
5953                                         dam = 0;
5954                                         break;
5955                                 }
5956                                 /* Hurt a lot */
5957                                 default:
5958                                 {
5959                                         get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
5960                                         break;
5961                                 }
5962                         }
5963                         }
5964
5965                         break;
5966                 }
5967
5968                 /* Drain mana */
5969                 case GF_DRAIN_MANA:
5970                 {
5971                         if (CHECK_MULTISHADOW())
5972                         {
5973                                 msg_print(_("攻撃は幻影に命中し、あなたには届かなかった。", "The attack hits Shadow, you are unharmed!"));
5974                         }
5975                         else if (p_ptr->csp)
5976                         {
5977                                 /* Basic message */
5978                                 if (who > 0) 
5979                                         msg_format(_("%^sに精神エネルギーを吸い取られてしまった!", "%^s draws psychic energy from you!"), m_name);
5980                                 else 
5981                                         msg_print(_("精神エネルギーを吸い取られてしまった!", "Your psychic energy is drawn!"));
5982
5983                                 /* Full drain */
5984                                 if (dam >= p_ptr->csp)
5985                                 {
5986                                         dam = p_ptr->csp;
5987                                         p_ptr->csp = 0;
5988                                         p_ptr->csp_frac = 0;
5989                                 }
5990
5991                                 /* Partial drain */
5992                                 else
5993                                 {
5994                                         p_ptr->csp -= dam;
5995                                 }
5996
5997                                 learn_spell(monspell);
5998
5999                                 /* Redraw mana */
6000                                 p_ptr->redraw |= (PR_MANA);
6001
6002                                 /* Window stuff */
6003                                 p_ptr->window |= (PW_PLAYER);
6004                                 p_ptr->window |= (PW_SPELL);
6005
6006                                 if (who > 0)
6007                                 {
6008                                         /* Heal the monster */
6009                                         if (m_ptr->hp < m_ptr->maxhp)
6010                                         {
6011                                                 /* Heal */
6012                                                 m_ptr->hp += dam;
6013                                                 if (m_ptr->hp > m_ptr->maxhp) m_ptr->hp = m_ptr->maxhp;
6014
6015                                                 /* Redraw (later) if needed */
6016                                                 if (p_ptr->health_who == who) p_ptr->redraw |= (PR_HEALTH);
6017                                                 if (p_ptr->riding == who) p_ptr->redraw |= (PR_UHEALTH);
6018
6019                                                 /* Special message */
6020                                                 if (m_ptr->ml)
6021                                                 {
6022                                                         msg_format(_("%^sは気分が良さそうだ。", "%^s appears healthier."), m_name);
6023                                                 }
6024                                         }
6025                                 }
6026                         }
6027
6028                         dam = 0;
6029                         break;
6030                 }
6031
6032                 /* Mind blast */
6033                 case GF_MIND_BLAST:
6034                 {
6035                         if ((randint0(100 + rlev / 2) < MAX(5, p_ptr->skill_sav)) && !CHECK_MULTISHADOW())
6036                         {
6037                                 msg_print(_("しかし効力を跳ね返した!", "You resist the effects!"));
6038                                 learn_spell(monspell);
6039                         }
6040                         else
6041                         {
6042                                 if (!CHECK_MULTISHADOW())
6043                                 {
6044                                         msg_print(_("霊的エネルギーで精神が攻撃された。", "Your mind is blasted by psyonic energy."));
6045
6046                                         if (!p_ptr->resist_conf)
6047                                         {
6048                                                 (void)set_confused(p_ptr->confused + randint0(4) + 4);
6049                                         }
6050
6051                                         if (!p_ptr->resist_chaos && one_in_(3))
6052                                         {
6053                                                 (void)set_image(p_ptr->image + randint0(250) + 150);
6054                                         }
6055
6056                                         p_ptr->csp -= 50;
6057                                         if (p_ptr->csp < 0)
6058                                         {
6059                                                 p_ptr->csp = 0;
6060                                                 p_ptr->csp_frac = 0;
6061                                         }
6062                                         p_ptr->redraw |= PR_MANA;
6063                                 }
6064
6065                                 get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
6066                         }
6067                         break;
6068                 }
6069
6070                 /* Brain smash */
6071                 case GF_BRAIN_SMASH:
6072                 {
6073                         if ((randint0(100 + rlev / 2) < MAX(5, p_ptr->skill_sav)) && !CHECK_MULTISHADOW())
6074                         {
6075                                 msg_print(_("しかし効力を跳ね返した!", "You resist the effects!"));
6076                                 learn_spell(monspell);
6077                         }
6078                         else
6079                         {
6080                                 if (!CHECK_MULTISHADOW())
6081                                 {
6082                                         msg_print(_("霊的エネルギーで精神が攻撃された。", "Your mind is blasted by psyonic energy."));
6083
6084                                         p_ptr->csp -= 100;
6085                                         if (p_ptr->csp < 0)
6086                                         {
6087                                                 p_ptr->csp = 0;
6088                                                 p_ptr->csp_frac = 0;
6089                                         }
6090                                         p_ptr->redraw |= PR_MANA;
6091                                 }
6092
6093                                 get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
6094                                 if (!CHECK_MULTISHADOW())
6095                                 {
6096                                         if (!p_ptr->resist_blind)
6097                                         {
6098                                                 (void)set_blind(p_ptr->blind + 8 + randint0(8));
6099                                         }
6100                                         if (!p_ptr->resist_conf)
6101                                         {
6102                                                 (void)set_confused(p_ptr->confused + randint0(4) + 4);
6103                                         }
6104                                         if (!p_ptr->free_act)
6105                                         {
6106                                                 (void)set_paralyzed(p_ptr->paralyzed + randint0(4) + 4);
6107                                         }
6108                                         (void)set_slow(p_ptr->slow + randint0(4) + 4, FALSE);
6109
6110                                         while (randint0(100 + rlev / 2) > (MAX(5, p_ptr->skill_sav)))
6111                                                 (void)do_dec_stat(A_INT);
6112                                         while (randint0(100 + rlev / 2) > (MAX(5, p_ptr->skill_sav)))
6113                                                 (void)do_dec_stat(A_WIS);
6114
6115                                         if (!p_ptr->resist_chaos)
6116                                         {
6117                                                 (void)set_image(p_ptr->image + randint0(250) + 150);
6118                                         }
6119                                 }
6120                         }
6121                         break;
6122                 }
6123
6124                 /* cause 1 */
6125                 case GF_CAUSE_1:
6126                 {
6127                         if ((randint0(100 + rlev / 2) < p_ptr->skill_sav) && !CHECK_MULTISHADOW())
6128                         {
6129                                 msg_print(_("しかし効力を跳ね返した!", "You resist the effects!"));
6130                                 learn_spell(monspell);
6131                         }
6132                         else
6133                         {
6134                                 if (!CHECK_MULTISHADOW()) curse_equipment(15, 0);
6135                                 get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
6136                         }
6137                         break;
6138                 }
6139
6140                 /* cause 2 */
6141                 case GF_CAUSE_2:
6142                 {
6143                         if ((randint0(100 + rlev / 2) < p_ptr->skill_sav) && !CHECK_MULTISHADOW())
6144                         {
6145                                 msg_print(_("しかし効力を跳ね返した!", "You resist the effects!"));
6146                                 learn_spell(monspell);
6147                         }
6148                         else
6149                         {
6150                                 if (!CHECK_MULTISHADOW()) curse_equipment(25, MIN(rlev / 2 - 15, 5));
6151                                 get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
6152                         }
6153                         break;
6154                 }
6155
6156                 /* cause 3 */
6157                 case GF_CAUSE_3:
6158                 {
6159                         if ((randint0(100 + rlev / 2) < p_ptr->skill_sav) && !CHECK_MULTISHADOW())
6160                         {
6161                                 msg_print(_("しかし効力を跳ね返した!", "You resist the effects!"));
6162                                 learn_spell(monspell);
6163                         }
6164                         else
6165                         {
6166                                 if (!CHECK_MULTISHADOW()) curse_equipment(33, MIN(rlev / 2 - 15, 15));
6167                                 get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
6168                         }
6169                         break;
6170                 }
6171
6172                 /* cause 4 */
6173                 case GF_CAUSE_4:
6174                 {
6175                         if ((randint0(100 + rlev / 2) < p_ptr->skill_sav) && !(m_ptr->r_idx == MON_KENSHIROU) && !CHECK_MULTISHADOW())
6176                         {
6177                                 msg_print(_("しかし秘孔を跳ね返した!", "You resist the effects!"));
6178                                 learn_spell(monspell);
6179                         }
6180                         else
6181                         {
6182                                 get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
6183                                 if (!CHECK_MULTISHADOW()) (void)set_cut(p_ptr->cut + damroll(10, 10));
6184                         }
6185                         break;
6186                 }
6187
6188                 /* Hand of Doom */
6189                 case GF_HAND_DOOM:
6190                 {
6191                         if ((randint0(100 + rlev/2) < p_ptr->skill_sav) && !CHECK_MULTISHADOW())
6192                         {
6193                                 msg_print(_("しかし効力を跳ね返した!", "You resist the effects!"));
6194                                 learn_spell(monspell);
6195                         }
6196                         else
6197                         {
6198                                 if (!CHECK_MULTISHADOW())
6199                                 {
6200                                         msg_print(_("あなたは命が薄まっていくように感じた!", "You feel your life fade away!"));
6201                                         curse_equipment(40, 20);
6202                                 }
6203
6204                                 get_damage = take_hit(DAMAGE_ATTACK, dam, m_name, monspell);
6205
6206                                 if (p_ptr->chp < 1) p_ptr->chp = 1; /* Paranoia */
6207                         }
6208                         break;
6209                 }
6210
6211                 /* Default */
6212                 default:
6213                 {
6214                         /* No damage */
6215                         dam = 0;
6216
6217                         break;
6218                 }
6219         }
6220
6221         /* Hex - revenge damage stored */
6222         revenge_store(get_damage);
6223
6224         if ((p_ptr->tim_eyeeye || hex_spelling(HEX_EYE_FOR_EYE))
6225                 && (get_damage > 0) && !p_ptr->is_dead && (who > 0))
6226         {
6227                 char m_name_self[80];
6228
6229                 /* hisself */
6230                 monster_desc(m_name_self, m_ptr, MD_PRON_VISIBLE | MD_POSSESSIVE | MD_OBJECTIVE);
6231
6232                 msg_format(_("攻撃が%s自身を傷つけた!", "The attack of %s has wounded %s!"), m_name, m_name_self);
6233                 project(0, 0, m_ptr->fy, m_ptr->fx, get_damage, GF_MISSILE, PROJECT_KILL, -1);
6234                 if (p_ptr->tim_eyeeye) set_tim_eyeeye(p_ptr->tim_eyeeye-5, TRUE);
6235         }
6236
6237         if (p_ptr->riding && dam > 0)
6238         {
6239                 rakubadam_p = (dam > 200) ? 200 : dam;
6240         }
6241
6242
6243         /* Disturb */
6244         disturb(1, 1);
6245
6246
6247         if ((p_ptr->special_defense & NINJA_KAWARIMI) && dam && who && (who != p_ptr->riding))
6248         {
6249                 (void)kawarimi(FALSE);
6250         }
6251
6252         /* Return "Anything seen?" */
6253         return (obvious);
6254 }
6255
6256
6257 /*
6258  * Find the distance from (x, y) to a line.
6259  */
6260 POSITION dist_to_line(POSITION y, POSITION x, POSITION y1, POSITION x1, POSITION y2, POSITION x2)
6261 {
6262         /* Vector from (x, y) to (x1, y1) */
6263         POSITION py = y1 - y;
6264         POSITION px = x1 - x;
6265
6266         /* Normal vector */
6267         POSITION ny = x2 - x1;
6268         POSITION nx = y1 - y2;
6269
6270         /* Length of N */
6271         POSITION pd = distance(y1, x1, y, x);
6272         POSITION nd = distance(y1, x1, y2, x2);
6273
6274         if (pd > nd) return distance(y, x, y2, x2);
6275
6276         /* Component of P on N */
6277         nd = ((nd) ? ((py * ny + px * nx) / nd) : 0);
6278
6279         /* Absolute value */
6280         return((nd >= 0) ? nd : 0 - nd);
6281 }
6282
6283
6284
6285 /*
6286  * XXX XXX XXX
6287  * Modified version of los() for calculation of disintegration balls.
6288  * Disintegration effects are stopped by permanent walls.
6289  */
6290 bool in_disintegration_range(POSITION y1, POSITION x1, POSITION y2, POSITION x2)
6291 {
6292         /* Delta */
6293         POSITION dx, dy;
6294
6295         /* Absolute */
6296         POSITION ax, ay;
6297
6298         /* Signs */
6299         POSITION sx, sy;
6300
6301         /* Fractions */
6302         POSITION qx, qy;
6303
6304         /* Scanners */
6305         POSITION tx, ty;
6306
6307         /* Scale factors */
6308         POSITION f1, f2;
6309
6310         /* Slope, or 1/Slope, of LOS */
6311         POSITION m;
6312
6313
6314         /* Extract the offset */
6315         dy = y2 - y1;
6316         dx = x2 - x1;
6317
6318         /* Extract the absolute offset */
6319         ay = ABS(dy);
6320         ax = ABS(dx);
6321
6322
6323         /* Handle adjacent (or identical) grids */
6324         if ((ax < 2) && (ay < 2)) return (TRUE);
6325
6326
6327         /* Paranoia -- require "safe" origin */
6328         /* if (!in_bounds(y1, x1)) return (FALSE); */
6329
6330
6331         /* Directly South/North */
6332         if (!dx)
6333         {
6334                 /* South -- check for walls */
6335                 if (dy > 0)
6336                 {
6337                         for (ty = y1 + 1; ty < y2; ty++)
6338                         {
6339                                 if (cave_stop_disintegration(ty, x1)) return (FALSE);
6340                         }
6341                 }
6342
6343                 /* North -- check for walls */
6344                 else
6345                 {
6346                         for (ty = y1 - 1; ty > y2; ty--)
6347                         {
6348                                 if (cave_stop_disintegration(ty, x1)) return (FALSE);
6349                         }
6350                 }
6351
6352                 /* Assume los */
6353                 return (TRUE);
6354         }
6355
6356         /* Directly East/West */
6357         if (!dy)
6358         {
6359                 /* East -- check for walls */
6360                 if (dx > 0)
6361                 {
6362                         for (tx = x1 + 1; tx < x2; tx++)
6363                         {
6364                                 if (cave_stop_disintegration(y1, tx)) return (FALSE);
6365                         }
6366                 }
6367
6368                 /* West -- check for walls */
6369                 else
6370                 {
6371                         for (tx = x1 - 1; tx > x2; tx--)
6372                         {
6373                                 if (cave_stop_disintegration(y1, tx)) return (FALSE);
6374                         }
6375                 }
6376
6377                 /* Assume los */
6378                 return (TRUE);
6379         }
6380
6381
6382         /* Extract some signs */
6383         sx = (dx < 0) ? -1 : 1;
6384         sy = (dy < 0) ? -1 : 1;
6385
6386
6387         /* Vertical "knights" */
6388         if (ax == 1)
6389         {
6390                 if (ay == 2)
6391                 {
6392                         if (!cave_stop_disintegration(y1 + sy, x1)) return (TRUE);
6393                 }
6394         }
6395
6396         /* Horizontal "knights" */
6397         else if (ay == 1)
6398         {
6399                 if (ax == 2)
6400                 {
6401                         if (!cave_stop_disintegration(y1, x1 + sx)) return (TRUE);
6402                 }
6403         }
6404
6405
6406         /* Calculate scale factor div 2 */
6407         f2 = (ax * ay);
6408
6409         /* Calculate scale factor */
6410         f1 = f2 << 1;
6411
6412
6413         /* Travel horizontally */
6414         if (ax >= ay)
6415         {
6416                 /* Let m = dy / dx * 2 * (dy * dx) = 2 * dy * dy */
6417                 qy = ay * ay;
6418                 m = qy << 1;
6419
6420                 tx = x1 + sx;
6421
6422                 /* Consider the special case where slope == 1. */
6423                 if (qy == f2)
6424                 {
6425                         ty = y1 + sy;
6426                         qy -= f1;
6427                 }
6428                 else
6429                 {
6430                         ty = y1;
6431                 }
6432
6433                 /* Note (below) the case (qy == f2), where */
6434                 /* the LOS exactly meets the corner of a tile. */
6435                 while (x2 - tx)
6436                 {
6437                         if (cave_stop_disintegration(ty, tx)) return (FALSE);
6438
6439                         qy += m;
6440
6441                         if (qy < f2)
6442                         {
6443                                 tx += sx;
6444                         }
6445                         else if (qy > f2)
6446                         {
6447                                 ty += sy;
6448                                 if (cave_stop_disintegration(ty, tx)) return (FALSE);
6449                                 qy -= f1;
6450                                 tx += sx;
6451                         }
6452                         else
6453                         {
6454                                 ty += sy;
6455                                 qy -= f1;
6456                                 tx += sx;
6457                         }
6458                 }
6459         }
6460
6461         /* Travel vertically */
6462         else
6463         {
6464                 /* Let m = dx / dy * 2 * (dx * dy) = 2 * dx * dx */
6465                 qx = ax * ax;
6466                 m = qx << 1;
6467
6468                 ty = y1 + sy;
6469
6470                 if (qx == f2)
6471                 {
6472                         tx = x1 + sx;
6473                         qx -= f1;
6474                 }
6475                 else
6476                 {
6477                         tx = x1;
6478                 }
6479
6480                 /* Note (below) the case (qx == f2), where */
6481                 /* the LOS exactly meets the corner of a tile. */
6482                 while (y2 - ty)
6483                 {
6484                         if (cave_stop_disintegration(ty, tx)) return (FALSE);
6485
6486                         qx += m;
6487
6488                         if (qx < f2)
6489                         {
6490                                 ty += sy;
6491                         }
6492                         else if (qx > f2)
6493                         {
6494                                 tx += sx;
6495                                 if (cave_stop_disintegration(ty, tx)) return (FALSE);
6496                                 qx -= f1;
6497                                 ty += sy;
6498                         }
6499                         else
6500                         {
6501                                 tx += sx;
6502                                 qx -= f1;
6503                                 ty += sy;
6504                         }
6505                 }
6506         }
6507
6508         /* Assume los */
6509         return (TRUE);
6510 }
6511
6512
6513 /*
6514  * breath shape
6515  */
6516 void breath_shape(u16b *path_g, int dist, int *pgrids, POSITION *gx, POSITION *gy, POSITION *gm, POSITION *pgm_rad, POSITION rad, POSITION y1, POSITION x1, POSITION y2, POSITION x2, EFFECT_ID typ)
6517 {
6518         POSITION by = y1;
6519         POSITION bx = x1;
6520         int brad = 0;
6521         int brev = rad * rad / dist;
6522         int bdis = 0;
6523         int cdis;
6524         int path_n = 0;
6525         int mdis = distance(y1, x1, y2, x2) + rad;
6526
6527         while (bdis <= mdis)
6528         {
6529                 POSITION x, y;
6530
6531                 if ((0 < dist) && (path_n < dist))
6532                 {
6533                         POSITION ny = GRID_Y(path_g[path_n]);
6534                         POSITION nx = GRID_X(path_g[path_n]);
6535                         POSITION nd = distance(ny, nx, y1, x1);
6536
6537                         /* Get next base point */
6538                         if (bdis >= nd)
6539                         {
6540                                 by = ny;
6541                                 bx = nx;
6542                                 path_n++;
6543                         }
6544                 }
6545
6546                 /* Travel from center outward */
6547                 for (cdis = 0; cdis <= brad; cdis++)
6548                 {
6549                         /* Scan the maximal blast area of radius "cdis" */
6550                         for (y = by - cdis; y <= by + cdis; y++)
6551                         {
6552                                 for (x = bx - cdis; x <= bx + cdis; x++)
6553                                 {
6554                                         /* Ignore "illegal" locations */
6555                                         if (!in_bounds(y, x)) continue;
6556
6557                                         /* Enforce a circular "ripple" */
6558                                         if (distance(y1, x1, y, x) != bdis) continue;
6559
6560                                         /* Enforce an arc */
6561                                         if (distance(by, bx, y, x) != cdis) continue;
6562
6563                                         switch (typ)
6564                                         {
6565                                         case GF_LITE:
6566                                         case GF_LITE_WEAK:
6567                                                 /* Lights are stopped by opaque terrains */
6568                                                 if (!los(by, bx, y, x)) continue;
6569                                                 break;
6570                                         case GF_DISINTEGRATE:
6571                                                 /* Disintegration are stopped only by perma-walls */
6572                                                 if (!in_disintegration_range(by, bx, y, x)) continue;
6573                                                 break;
6574                                         default:
6575                                                 /* Ball explosions are stopped by walls */
6576                                                 if (!projectable(by, bx, y, x)) continue;
6577                                                 break;
6578                                         }
6579
6580                                         /* Save this grid */
6581                                         gy[*pgrids] = y;
6582                                         gx[*pgrids] = x;
6583                                         (*pgrids)++;
6584                                 }
6585                         }
6586                 }
6587
6588                 /* Encode some more "radius" info */
6589                 gm[bdis + 1] = *pgrids;
6590
6591                 /* Increase the size */
6592                 brad = rad * (path_n + brev) / (dist + brev);
6593
6594                 /* Find the next ripple */
6595                 bdis++;
6596         }
6597
6598         /* Store the effect size */
6599         *pgm_rad = bdis;
6600 }
6601
6602
6603 /*!
6604  * @brief 汎用的なビーム/ボルト/ボール系処理のルーチン Generic "beam"/"bolt"/"ball" projection routine.
6605  * @param who 魔法を発動したモンスター(0ならばプレイヤー) / Index of "source" monster (zero for "player")
6606  * @param rad 効果半径(ビーム/ボルト = 0 / ボール = 1以上) / Radius of explosion (0 = beam/bolt, 1 to 9 = ball)
6607  * @param y 目標Y座標 / Target y location (or location to travel "towards")
6608  * @param x 目標X座標 / Target x location (or location to travel "towards")
6609  * @param dam 基本威力 / Base damage roll to apply to affected monsters (or player)
6610  * @param typ 効果属性 / Type of damage to apply to monsters (and objects)
6611  * @param flg 効果フラグ / Extra bit flags (see PROJECT_xxxx in "defines.h")
6612  * @param monspell 効果元のモンスター魔法ID
6613  * @return 何か一つでも効力があればTRUEを返す / TRUE if any "effects" of the projection were observed, else FALSE
6614  * @details
6615  * <pre>
6616  * Allows a monster (or player) to project a beam/bolt/ball of a given kind
6617  * towards a given location (optionally passing over the heads of interposing
6618  * monsters), and have it do a given amount of damage to the monsters (and
6619  * optionally objects) within the given radius of the final location.
6620  *
6621  * A "bolt" travels from source to target and affects only the target grid.
6622  * A "beam" travels from source to target, affecting all grids passed through.
6623  * A "ball" travels from source to the target, exploding at the target, and
6624  *   affecting everything within the given radius of the target location.
6625  *
6626  * Traditionally, a "bolt" does not affect anything on the ground, and does
6627  * not pass over the heads of interposing monsters, much like a traditional
6628  * missile, and will "stop" abruptly at the "target" even if no monster is
6629  * positioned there, while a "ball", on the other hand, passes over the heads
6630  * of monsters between the source and target, and affects everything except
6631  * the source monster which lies within the final radius, while a "beam"
6632  * affects every monster between the source and target, except for the casting
6633  * monster (or player), and rarely affects things on the ground.
6634  *
6635  * Two special flags allow us to use this function in special ways, the
6636  * "PROJECT_HIDE" flag allows us to perform "invisible" projections, while
6637  * the "PROJECT_JUMP" flag allows us to affect a specific grid, without
6638  * actually projecting from the source monster (or player).
6639  *
6640  * The player will only get "experience" for monsters killed by himself
6641  * Unique monsters can only be destroyed by attacks from the player
6642  *
6643  * Only 256 grids can be affected per projection, limiting the effective
6644  * "radius" of standard ball attacks to nine units (diameter nineteen).
6645  *
6646  * One can project in a given "direction" by combining PROJECT_THRU with small
6647  * offsets to the initial location (see "line_spell()"), or by calculating
6648  * "virtual targets" far away from the player.
6649  *
6650  * One can also use PROJECT_THRU to send a beam/bolt along an angled path,
6651  * continuing until it actually hits somethings (useful for "stone to mud").
6652  *
6653  * Bolts and Beams explode INSIDE walls, so that they can destroy doors.
6654  *
6655  * Balls must explode BEFORE hitting walls, or they would affect monsters
6656  * on both sides of a wall.  Some bug reports indicate that this is still
6657  * happening in 2.7.8 for Windows, though it appears to be impossible.
6658  *
6659  * We "pre-calculate" the blast area only in part for efficiency.
6660  * More importantly, this lets us do "explosions" from the "inside" out.
6661  * This results in a more logical distribution of "blast" treasure.
6662  * It also produces a better (in my opinion) animation of the explosion.
6663  * It could be (but is not) used to have the treasure dropped by monsters
6664  * in the middle of the explosion fall "outwards", and then be damaged by
6665  * the blast as it spreads outwards towards the treasure drop location.
6666  *
6667  * Walls and doors are included in the blast area, so that they can be
6668  * "burned" or "melted" in later versions.
6669  *
6670  * This algorithm is intended to maximize simplicity, not necessarily
6671  * efficiency, since this function is not a bottleneck in the code.
6672  *
6673  * We apply the blast effect from ground zero outwards, in several passes,
6674  * first affecting features, then objects, then monsters, then the player.
6675  * This allows walls to be removed before checking the object or monster
6676  * in the wall, and protects objects which are dropped by monsters killed
6677  * in the blast, and allows the player to see all affects before he is
6678  * killed or teleported away.  The semantics of this method are open to
6679  * various interpretations, but they seem to work well in practice.
6680  *
6681  * We process the blast area from ground-zero outwards to allow for better
6682  * distribution of treasure dropped by monsters, and because it provides a
6683  * pleasing visual effect at low cost.
6684  *
6685  * Note that the damage done by "ball" explosions decreases with distance.
6686  * This decrease is rapid, grids at radius "dist" take "1/dist" damage.
6687  *
6688  * Notice the "napalm" effect of "beam" weapons.  First they "project" to
6689  * the target, and then the damage "flows" along this beam of destruction.
6690  * The damage at every grid is the same as at the "center" of a "ball"
6691  * explosion, since the "beam" grids are treated as if they ARE at the
6692  * center of a "ball" explosion.
6693  *
6694  * Currently, specifying "beam" plus "ball" means that locations which are
6695  * covered by the initial "beam", and also covered by the final "ball", except
6696  * for the final grid (the epicenter of the ball), will be "hit twice", once
6697  * by the initial beam, and once by the exploding ball.  For the grid right
6698  * next to the epicenter, this results in 150% damage being done.  The center
6699  * does not have this problem, for the same reason the final grid in a "beam"
6700  * plus "bolt" does not -- it is explicitly removed.  Simply removing "beam"
6701  * grids which are covered by the "ball" will NOT work, as then they will
6702  * receive LESS damage than they should.  Do not combine "beam" with "ball".
6703  *
6704  * The array "gy[],gx[]" with current size "grids" is used to hold the
6705  * collected locations of all grids in the "blast area" plus "beam path".
6706  *
6707  * Note the rather complex usage of the "gm[]" array.  First, gm[0] is always
6708  * zero.  Second, for N>1, gm[N] is always the index (in gy[],gx[]) of the
6709  * first blast grid (see above) with radius "N" from the blast center.  Note
6710  * that only the first gm[1] grids in the blast area thus take full damage.
6711  * Also, note that gm[rad+1] is always equal to "grids", which is the total
6712  * number of blast grids.
6713  *
6714  * Note that once the projection is complete, (y2,x2) holds the final location
6715  * of bolts/beams, and the "epicenter" of balls.
6716  *
6717  * Note also that "rad" specifies the "inclusive" radius of projection blast,
6718  * so that a "rad" of "one" actually covers 5 or 9 grids, depending on the
6719  * implementation of the "distance" function.  Also, a bolt can be properly
6720  * viewed as a "ball" with a "rad" of "zero".
6721  *
6722  * Note that if no "target" is reached before the beam/bolt/ball travels the
6723  * maximum distance allowed (MAX_RANGE), no "blast" will be induced.  This
6724  * may be relevant even for bolts, since they have a "1x1" mini-blast.
6725  *
6726  * Note that for consistency, we "pretend" that the bolt actually takes "time"
6727  * to move from point A to point B, even if the player cannot see part of the
6728  * projection path.  Note that in general, the player will *always* see part
6729  * of the path, since it either starts at the player or ends on the player.
6730  *
6731  * Hack -- we assume that every "projection" is "self-illuminating".
6732  *
6733  * Hack -- when only a single monster is affected, we automatically track
6734  * (and recall) that monster, unless "PROJECT_JUMP" is used.
6735  *
6736  * Note that all projections now "explode" at their final destination, even
6737  * if they were being projected at a more distant destination.  This means
6738  * that "ball" spells will *always* explode.
6739  *
6740  * Note that we must call "handle_stuff()" after affecting terrain features
6741  * in the blast radius, in case the "illumination" of the grid was changed,
6742  * and "update_view()" and "update_monsters()" need to be called.
6743  * </pre>
6744  */
6745 bool project(MONSTER_IDX who, POSITION rad, POSITION y, POSITION x, HIT_POINT dam, EFFECT_ID typ, BIT_FLAGS flg, int monspell)
6746 {
6747         int i, t, dist;
6748
6749         POSITION y1, x1;
6750         POSITION y2, x2;
6751         POSITION by, bx;
6752
6753         int dist_hack = 0;
6754
6755         POSITION y_saver, x_saver; /* For reflecting monsters */
6756
6757         int msec = delay_factor * delay_factor * delay_factor;
6758
6759         /* Assume the player sees nothing */
6760         bool notice = FALSE;
6761
6762         /* Assume the player has seen nothing */
6763         bool visual = FALSE;
6764
6765         /* Assume the player has seen no blast grids */
6766         bool drawn = FALSE;
6767
6768         /* Assume to be a normal ball spell */
6769         bool breath = FALSE;
6770
6771         /* Is the player blind? */
6772         bool blind = (p_ptr->blind ? TRUE : FALSE);
6773
6774         bool old_hide = FALSE;
6775
6776         /* Number of grids in the "path" */
6777         int path_n = 0;
6778
6779         /* Actual grids in the "path" */
6780         u16b path_g[512];
6781
6782         /* Number of grids in the "blast area" (including the "beam" path) */
6783         int grids = 0;
6784
6785         /* Coordinates of the affected grids */
6786         POSITION gx[1024], gy[1024];
6787
6788         /* Encoded "radius" info (see above) */
6789         POSITION gm[32];
6790
6791         /* Actual radius encoded in gm[] */
6792         POSITION gm_rad = rad;
6793
6794         bool jump = FALSE;
6795
6796         /* Attacker's name (prepared before polymorph)*/
6797         char who_name[80];
6798
6799         /* Can the player see the source of this effect? */
6800         bool see_s_msg = TRUE;
6801
6802         /* Initialize by null string */
6803         who_name[0] = '\0';
6804
6805         rakubadam_p = 0;
6806         rakubadam_m = 0;
6807
6808         /* Default target of monsterspell is player */
6809         monster_target_y = p_ptr->y;
6810         monster_target_x = p_ptr->x;
6811
6812         /* Hack -- Jump to target */
6813         if (flg & (PROJECT_JUMP))
6814         {
6815                 x1 = x;
6816                 y1 = y;
6817
6818                 /* Clear the flag */
6819                 flg &= ~(PROJECT_JUMP);
6820
6821                 jump = TRUE;
6822         }
6823
6824         /* Start at player */
6825         else if (who <= 0)
6826         {
6827                 x1 = p_ptr->x;
6828                 y1 = p_ptr->y;
6829         }
6830
6831         /* Start at monster */
6832         else if (who > 0)
6833         {
6834                 x1 = m_list[who].fx;
6835                 y1 = m_list[who].fy;
6836                 monster_desc(who_name, &m_list[who], MD_IGNORE_HALLU | MD_ASSUME_VISIBLE | MD_INDEF_VISIBLE);
6837         }
6838
6839         /* Oops */
6840         else
6841         {
6842                 x1 = x;
6843                 y1 = y;
6844         }
6845
6846         y_saver = y1;
6847         x_saver = x1;
6848
6849         /* Default "destination" */
6850         y2 = y;
6851         x2 = x;
6852
6853
6854         /* Hack -- verify stuff */
6855         if (flg & (PROJECT_THRU))
6856         {
6857                 if ((x1 == x2) && (y1 == y2))
6858                 {
6859                         flg &= ~(PROJECT_THRU);
6860                 }
6861         }
6862
6863         /* Handle a breath attack */
6864         if (rad < 0)
6865         {
6866                 rad = 0 - rad;
6867                 breath = TRUE;
6868                 if (flg & PROJECT_HIDE) old_hide = TRUE;
6869                 flg |= PROJECT_HIDE;
6870         }
6871
6872
6873         /* Hack -- Assume there will be no blast (max radius 32) */
6874         for (dist = 0; dist < 32; dist++) gm[dist] = 0;
6875
6876
6877         /* Initial grid */
6878         y = y1;
6879         x = x1;
6880         dist = 0;
6881
6882         /* Collect beam grids */
6883         if (flg & (PROJECT_BEAM))
6884         {
6885                 gy[grids] = y;
6886                 gx[grids] = x;
6887                 grids++;
6888         }
6889
6890         switch (typ)
6891         {
6892         case GF_LITE:
6893         case GF_LITE_WEAK:
6894                 if (breath || (flg & PROJECT_BEAM)) flg |= (PROJECT_LOS);
6895                 break;
6896         case GF_DISINTEGRATE:
6897                 flg |= (PROJECT_GRID);
6898                 if (breath || (flg & PROJECT_BEAM)) flg |= (PROJECT_DISI);
6899                 break;
6900         }
6901
6902         /* Calculate the projection path */
6903
6904         path_n = project_path(path_g, (project_length ? project_length : MAX_RANGE), y1, x1, y2, x2, flg);
6905
6906         /* Hack -- Handle stuff */
6907         handle_stuff();
6908
6909         /* Giga-Hack SEEKER & SUPER_RAY */
6910
6911         if( typ == GF_SEEKER )
6912         {
6913                 int j;
6914                 int last_i=0;
6915
6916                 /* Mega-Hack */
6917                 project_m_n = 0;
6918                 project_m_x = 0;
6919                 project_m_y = 0;
6920
6921                 for (i = 0; i < path_n; ++i)
6922                 {
6923                         int oy = y;
6924                         int ox = x;
6925
6926                         int ny = GRID_Y(path_g[i]);
6927                         int nx = GRID_X(path_g[i]);
6928
6929                         /* Advance */
6930                         y = ny;
6931                         x = nx;
6932
6933                         gy[grids] = y;
6934                         gx[grids] = x;
6935                         grids++;
6936
6937
6938                         /* Only do visuals if requested */
6939                         if (!blind && !(flg & (PROJECT_HIDE)))
6940                         {
6941                                 /* Only do visuals if the player can "see" the bolt */
6942                                 if (panel_contains(y, x) && player_has_los_bold(y, x))
6943                                 {
6944                                         u16b p;
6945
6946                                         byte a;
6947                                         char c;
6948
6949                                         /* Obtain the bolt pict */
6950                                         p = bolt_pict(oy, ox, y, x, typ);
6951
6952                                         /* Extract attr/char */
6953                                         a = PICT_A(p);
6954                                         c = PICT_C(p);
6955
6956                                         /* Visual effects */
6957                                         print_rel(c, a, y, x);
6958                                         move_cursor_relative(y, x);
6959                                         /*if (fresh_before)*/ Term_fresh();
6960                                         Term_xtra(TERM_XTRA_DELAY, msec);
6961                                         lite_spot(y, x);
6962                                         /*if (fresh_before)*/ Term_fresh();
6963
6964                                         /* Display "beam" grids */
6965                                         if (flg & (PROJECT_BEAM))
6966                                         {
6967                                                 /* Obtain the explosion pict */
6968                                                 p = bolt_pict(y, x, y, x, typ);
6969
6970                                                 /* Extract attr/char */
6971                                                 a = PICT_A(p);
6972                                                 c = PICT_C(p);
6973
6974                                                 /* Visual effects */
6975                                                 print_rel(c, a, y, x);
6976                                         }
6977
6978                                         /* Hack -- Activate delay */
6979                                         visual = TRUE;
6980                                 }
6981
6982                                 /* Hack -- delay anyway for consistency */
6983                                 else if (visual)
6984                                 {
6985                                         /* Delay for consistency */
6986                                         Term_xtra(TERM_XTRA_DELAY, msec);
6987                                 }
6988                         }
6989                         if(project_o(0,0,y,x,dam,GF_SEEKER))notice=TRUE;
6990                         if( is_mirror_grid(&cave[y][x]))
6991                         {
6992                           /* The target of monsterspell becomes tha mirror(broken) */
6993                                 monster_target_y=(s16b)y;
6994                                 monster_target_x=(s16b)x;
6995
6996                                 remove_mirror(y, x);
6997                                 next_mirror(&oy, &ox, y, x);
6998
6999                                 path_n = i+project_path(&(path_g[i+1]), (project_length ? project_length : MAX_RANGE), y, x, oy, ox, flg);
7000                                 for(j = last_i; j <= i; j++)
7001                                 {
7002                                         y = GRID_Y(path_g[j]);
7003                                         x = GRID_X(path_g[j]);
7004                                         if(project_m(0, 0, y, x, dam, GF_SEEKER, flg, TRUE)) notice=TRUE;
7005                                         if(!who && (project_m_n==1) && !jump ){
7006                                           if(cave[project_m_y][project_m_x].m_idx >0 ){
7007                                                 monster_type *m_ptr = &m_list[cave[project_m_y][project_m_x].m_idx];
7008
7009                                                 if (m_ptr->ml)
7010                                                 {
7011                                                   /* Hack -- auto-recall */
7012                                                   if (!p_ptr->image) monster_race_track(m_ptr->ap_r_idx);
7013
7014                                                   /* Hack - auto-track */
7015                                                   health_track(cave[project_m_y][project_m_x].m_idx);
7016                                                 }
7017                                           }
7018                                         }
7019                                         (void)project_f(0,0,y,x,dam,GF_SEEKER);
7020                                 }
7021                                 last_i = i;
7022                         }
7023                 }
7024                 for(i = last_i ; i < path_n ; i++)
7025                 {
7026                         int py, px;
7027                         py = GRID_Y(path_g[i]);
7028                         px = GRID_X(path_g[i]);
7029                         if(project_m(0, 0, py, px, dam, GF_SEEKER, flg, TRUE))
7030                                 notice = TRUE;
7031                         if(!who && (project_m_n==1) && !jump ){
7032                                 if(cave[project_m_y][project_m_x].m_idx > 0)
7033                                 {
7034                                         monster_type *m_ptr = &m_list[cave[project_m_y][project_m_x].m_idx];
7035
7036                                         if (m_ptr->ml)
7037                                         {
7038                                                 /* Hack -- auto-recall */
7039                                                 if (!p_ptr->image) monster_race_track(m_ptr->ap_r_idx);
7040
7041                                                 /* Hack - auto-track */
7042                                                 health_track(cave[project_m_y][project_m_x].m_idx);
7043                                         }
7044                                 }
7045                         }
7046                         (void)project_f(0, 0, py, px, dam, GF_SEEKER);
7047                 }
7048                 return notice;
7049         }
7050         else if(typ == GF_SUPER_RAY){
7051                 int j;
7052                 int second_step = 0;
7053
7054                 /* Mega-Hack */
7055                 project_m_n = 0;
7056                 project_m_x = 0;
7057                 project_m_y = 0;
7058
7059                 for (i = 0; i < path_n; ++i)
7060                 {
7061                         int oy = y;
7062                         int ox = x;
7063
7064                         int ny = GRID_Y(path_g[i]);
7065                         int nx = GRID_X(path_g[i]);
7066
7067                         /* Advance */
7068                         y = ny;
7069                         x = nx;
7070
7071                         gy[grids] = y;
7072                         gx[grids] = x;
7073                         grids++;
7074
7075
7076                         /* Only do visuals if requested */
7077                         if (!blind && !(flg & (PROJECT_HIDE)))
7078                         {
7079                                 /* Only do visuals if the player can "see" the bolt */
7080                                 if (panel_contains(y, x) && player_has_los_bold(y, x))
7081                                 {
7082                                         u16b p;
7083
7084                                         byte a;
7085                                         char c;
7086
7087                                         /* Obtain the bolt pict */
7088                                         p = bolt_pict(oy, ox, y, x, typ);
7089
7090                                         /* Extract attr/char */
7091                                         a = PICT_A(p);
7092                                         c = PICT_C(p);
7093
7094                                         /* Visual effects */
7095                                         print_rel(c, a, y, x);
7096                                         move_cursor_relative(y, x);
7097                                         /*if (fresh_before)*/ Term_fresh();
7098                                         Term_xtra(TERM_XTRA_DELAY, msec);
7099                                         lite_spot(y, x);
7100                                         /*if (fresh_before)*/ Term_fresh();
7101
7102                                         /* Display "beam" grids */
7103                                         if (flg & (PROJECT_BEAM))
7104                                         {
7105                                                 /* Obtain the explosion pict */
7106                                                 p = bolt_pict(y, x, y, x, typ);
7107
7108                                                 /* Extract attr/char */
7109                                                 a = PICT_A(p);
7110                                                 c = PICT_C(p);
7111
7112                                                 /* Visual effects */
7113                                                 print_rel(c, a, y, x);
7114                                         }
7115
7116                                         /* Hack -- Activate delay */
7117                                         visual = TRUE;
7118                                 }
7119
7120                                 /* Hack -- delay anyway for consistency */
7121                                 else if (visual)
7122                                 {
7123                                         /* Delay for consistency */
7124                                         Term_xtra(TERM_XTRA_DELAY, msec);
7125                                 }
7126                         }
7127                         if(project_o(0,0,y,x,dam,GF_SUPER_RAY) )notice=TRUE;
7128                         if (!cave_have_flag_bold(y, x, FF_PROJECT))
7129                         {
7130                                 if( second_step )continue;
7131                                 break;
7132                         }
7133                         if( is_mirror_grid(&cave[y][x]) && !second_step )
7134                         {
7135                           /* The target of monsterspell becomes tha mirror(broken) */
7136                                 monster_target_y=(s16b)y;
7137                                 monster_target_x=(s16b)x;
7138
7139                                 remove_mirror(y,x);
7140                                 for( j = 0; j <=i ; j++ )
7141                                 {
7142                                         y = GRID_Y(path_g[j]);
7143                                         x = GRID_X(path_g[j]);
7144                                         (void)project_f(0,0,y,x,dam,GF_SUPER_RAY);
7145                                 }
7146                                 path_n = i;
7147                                 second_step =i+1;
7148                                 path_n += project_path(&(path_g[path_n+1]), (project_length ? project_length : MAX_RANGE), y, x, y-1, x-1, flg);
7149                                 path_n += project_path(&(path_g[path_n+1]), (project_length ? project_length : MAX_RANGE), y, x, y-1, x  , flg);
7150                                 path_n += project_path(&(path_g[path_n+1]), (project_length ? project_length : MAX_RANGE), y, x, y-1, x+1, flg);
7151                                 path_n += project_path(&(path_g[path_n+1]), (project_length ? project_length : MAX_RANGE), y, x, y  , x-1, flg);
7152                                 path_n += project_path(&(path_g[path_n+1]), (project_length ? project_length : MAX_RANGE), y, x, y  , x+1, flg);
7153                                 path_n += project_path(&(path_g[path_n+1]), (project_length ? project_length : MAX_RANGE), y, x, y+1, x-1, flg);
7154                                 path_n += project_path(&(path_g[path_n+1]), (project_length ? project_length : MAX_RANGE), y, x, y+1, x  , flg);
7155                                 path_n += project_path(&(path_g[path_n+1]), (project_length ? project_length : MAX_RANGE), y, x, y+1, x+1, flg);
7156                         }
7157                 }
7158                 for( i = 0; i < path_n ; i++ )
7159                 {
7160                         int py, px;
7161                         py = GRID_Y(path_g[i]);
7162                         px = GRID_X(path_g[i]);
7163                         (void)project_m(0, 0, py, px, dam, GF_SUPER_RAY, flg, TRUE);
7164                         if(!who && (project_m_n == 1) && !jump){
7165                                 if(cave[project_m_y][project_m_x].m_idx >0 ){
7166                                         monster_type *m_ptr = &m_list[cave[project_m_y][project_m_x].m_idx];
7167
7168                                         if (m_ptr->ml)
7169                                         {
7170                                                 /* Hack -- auto-recall */
7171                                                 if (!p_ptr->image) monster_race_track(m_ptr->ap_r_idx);
7172
7173                                                 /* Hack - auto-track */
7174                                                 health_track(cave[project_m_y][project_m_x].m_idx);
7175                                         }
7176                                 }
7177                         }
7178                         (void)project_f(0, 0, py, px, dam, GF_SUPER_RAY);
7179                 }
7180                 return notice;
7181         }
7182
7183         /* Project along the path */
7184         for (i = 0; i < path_n; ++i)
7185         {
7186                 int oy = y;
7187                 int ox = x;
7188
7189                 int ny = GRID_Y(path_g[i]);
7190                 int nx = GRID_X(path_g[i]);
7191
7192                 if (flg & PROJECT_DISI)
7193                 {
7194                         /* Hack -- Balls explode before reaching walls */
7195                         if (cave_stop_disintegration(ny, nx) && (rad > 0)) break;
7196                 }
7197                 else if (flg & PROJECT_LOS)
7198                 {
7199                         /* Hack -- Balls explode before reaching walls */
7200                         if (!cave_los_bold(ny, nx) && (rad > 0)) break;
7201                 }
7202                 else
7203                 {
7204                         /* Hack -- Balls explode before reaching walls */
7205                         if (!cave_have_flag_bold(ny, nx, FF_PROJECT) && (rad > 0)) break;
7206                 }
7207
7208                 /* Advance */
7209                 y = ny;
7210                 x = nx;
7211
7212                 /* Collect beam grids */
7213                 if (flg & (PROJECT_BEAM))
7214                 {
7215                         gy[grids] = y;
7216                         gx[grids] = x;
7217                         grids++;
7218                 }
7219
7220                 /* Only do visuals if requested */
7221                 if (!blind && !(flg & (PROJECT_HIDE | PROJECT_FAST)))
7222                 {
7223                         /* Only do visuals if the player can "see" the bolt */
7224                         if (panel_contains(y, x) && player_has_los_bold(y, x))
7225                         {
7226                                 u16b p;
7227
7228                                 byte a;
7229                                 char c;
7230
7231                                 /* Obtain the bolt pict */
7232                                 p = bolt_pict(oy, ox, y, x, typ);
7233
7234                                 /* Extract attr/char */
7235                                 a = PICT_A(p);
7236                                 c = PICT_C(p);
7237
7238                                 /* Visual effects */
7239                                 print_rel(c, a, y, x);
7240                                 move_cursor_relative(y, x);
7241                                 /*if (fresh_before)*/ Term_fresh();
7242                                 Term_xtra(TERM_XTRA_DELAY, msec);
7243                                 lite_spot(y, x);
7244                                 /*if (fresh_before)*/ Term_fresh();
7245
7246                                 /* Display "beam" grids */
7247                                 if (flg & (PROJECT_BEAM))
7248                                 {
7249                                         /* Obtain the explosion pict */
7250                                         p = bolt_pict(y, x, y, x, typ);
7251
7252                                         /* Extract attr/char */
7253                                         a = PICT_A(p);
7254                                         c = PICT_C(p);
7255
7256                                         /* Visual effects */
7257                                         print_rel(c, a, y, x);
7258                                 }
7259
7260                                 /* Hack -- Activate delay */
7261                                 visual = TRUE;
7262                         }
7263
7264                         /* Hack -- delay anyway for consistency */
7265                         else if (visual)
7266                         {
7267                                 /* Delay for consistency */
7268                                 Term_xtra(TERM_XTRA_DELAY, msec);
7269                         }
7270                 }
7271         }
7272
7273         path_n = i;
7274
7275         /* Save the "blast epicenter" */
7276         by = y;
7277         bx = x;
7278
7279         if (breath && !path_n)
7280         {
7281                 breath = FALSE;
7282                 gm_rad = rad;
7283                 if (!old_hide)
7284                 {
7285                         flg &= ~(PROJECT_HIDE);
7286                 }
7287         }
7288
7289         /* Start the "explosion" */
7290         gm[0] = 0;
7291
7292         /* Hack -- make sure beams get to "explode" */
7293         gm[1] = grids;
7294
7295         dist = path_n;
7296         dist_hack = dist;
7297
7298         project_length = 0;
7299
7300         /* If we found a "target", explode there */
7301         if (dist <= MAX_RANGE)
7302         {
7303                 /* Mega-Hack -- remove the final "beam" grid */
7304                 if ((flg & (PROJECT_BEAM)) && (grids > 0)) grids--;
7305
7306                 /*
7307                  * Create a conical breath attack
7308                  *
7309                  *       ***
7310                  *   ********
7311                  * D********@**
7312                  *   ********
7313                  *       ***
7314                  */
7315
7316                 if (breath)
7317                 {
7318                         flg &= ~(PROJECT_HIDE);
7319
7320                         breath_shape(path_g, dist, &grids, gx, gy, gm, &gm_rad, rad, y1, x1, by, bx, typ);
7321                 }
7322                 else
7323                 {
7324                         /* Determine the blast area, work from the inside out */
7325                         for (dist = 0; dist <= rad; dist++)
7326                         {
7327                                 /* Scan the maximal blast area of radius "dist" */
7328                                 for (y = by - dist; y <= by + dist; y++)
7329                                 {
7330                                         for (x = bx - dist; x <= bx + dist; x++)
7331                                         {
7332                                                 /* Ignore "illegal" locations */
7333                                                 if (!in_bounds2(y, x)) continue;
7334
7335                                                 /* Enforce a "circular" explosion */
7336                                                 if (distance(by, bx, y, x) != dist) continue;
7337
7338                                                 switch (typ)
7339                                                 {
7340                                                 case GF_LITE:
7341                                                 case GF_LITE_WEAK:
7342                                                         /* Lights are stopped by opaque terrains */
7343                                                         if (!los(by, bx, y, x)) continue;
7344                                                         break;
7345                                                 case GF_DISINTEGRATE:
7346                                                         /* Disintegration are stopped only by perma-walls */
7347                                                         if (!in_disintegration_range(by, bx, y, x)) continue;
7348                                                         break;
7349                                                 default:
7350                                                         /* Ball explosions are stopped by walls */
7351                                                         if (!projectable(by, bx, y, x)) continue;
7352                                                         break;
7353                                                 }
7354
7355                                                 /* Save this grid */
7356                                                 gy[grids] = y;
7357                                                 gx[grids] = x;
7358                                                 grids++;
7359                                         }
7360                                 }
7361
7362                                 /* Encode some more "radius" info */
7363                                 gm[dist+1] = grids;
7364                         }
7365                 }
7366         }
7367
7368         /* Speed -- ignore "non-explosions" */
7369         if (!grids) return (FALSE);
7370
7371
7372         /* Display the "blast area" if requested */
7373         if (!blind && !(flg & (PROJECT_HIDE)))
7374         {
7375                 /* Then do the "blast", from inside out */
7376                 for (t = 0; t <= gm_rad; t++)
7377                 {
7378                         /* Dump everything with this radius */
7379                         for (i = gm[t]; i < gm[t+1]; i++)
7380                         {
7381                                 /* Extract the location */
7382                                 y = gy[i];
7383                                 x = gx[i];
7384
7385                                 /* Only do visuals if the player can "see" the blast */
7386                                 if (panel_contains(y, x) && player_has_los_bold(y, x))
7387                                 {
7388                                         u16b p;
7389
7390                                         byte a;
7391                                         char c;
7392
7393                                         drawn = TRUE;
7394
7395                                         /* Obtain the explosion pict */
7396                                         p = bolt_pict(y, x, y, x, typ);
7397
7398                                         /* Extract attr/char */
7399                                         a = PICT_A(p);
7400                                         c = PICT_C(p);
7401
7402                                         /* Visual effects -- Display */
7403                                         print_rel(c, a, y, x);
7404                                 }
7405                         }
7406
7407                         /* Hack -- center the cursor */
7408                         move_cursor_relative(by, bx);
7409
7410                         /* Flush each "radius" seperately */
7411                         /*if (fresh_before)*/ Term_fresh();
7412
7413                         /* Delay (efficiently) */
7414                         if (visual || drawn)
7415                         {
7416                                 Term_xtra(TERM_XTRA_DELAY, msec);
7417                         }
7418                 }
7419
7420                 /* Flush the erasing */
7421                 if (drawn)
7422                 {
7423                         /* Erase the explosion drawn above */
7424                         for (i = 0; i < grids; i++)
7425                         {
7426                                 /* Extract the location */
7427                                 y = gy[i];
7428                                 x = gx[i];
7429
7430                                 /* Hack -- Erase if needed */
7431                                 if (panel_contains(y, x) && player_has_los_bold(y, x))
7432                                 {
7433                                         lite_spot(y, x);
7434                                 }
7435                         }
7436
7437                         /* Hack -- center the cursor */
7438                         move_cursor_relative(by, bx);
7439
7440                         /* Flush the explosion */
7441                         /*if (fresh_before)*/ Term_fresh();
7442                 }
7443         }
7444
7445
7446         /* Update stuff if needed */
7447         if (p_ptr->update) update_stuff();
7448
7449
7450         if (flg & PROJECT_KILL)
7451         {
7452                 see_s_msg = (who > 0) ? is_seen(&m_list[who]) :
7453                         (!who ? TRUE : (player_can_see_bold(y1, x1) && projectable(p_ptr->y, p_ptr->x, y1, x1)));
7454         }
7455
7456
7457         /* Check features */
7458         if (flg & (PROJECT_GRID))
7459         {
7460                 /* Start with "dist" of zero */
7461                 dist = 0;
7462
7463                 /* Scan for features */
7464                 for (i = 0; i < grids; i++)
7465                 {
7466                         /* Hack -- Notice new "dist" values */
7467                         if (gm[dist+1] == i) dist++;
7468
7469                         /* Get the grid location */
7470                         y = gy[i];
7471                         x = gx[i];
7472
7473                         /* Find the closest point in the blast */
7474                         if (breath)
7475                         {
7476                                 int d = dist_to_line(y, x, y1, x1, by, bx);
7477
7478                                 /* Affect the grid */
7479                                 if (project_f(who, d, y, x, dam, typ)) notice = TRUE;
7480                         }
7481                         else
7482                         {
7483                                 /* Affect the grid */
7484                                 if (project_f(who, dist, y, x, dam, typ)) notice = TRUE;
7485                         }
7486                 }
7487         }
7488
7489         /* Update stuff if needed */
7490         if (p_ptr->update) update_stuff();
7491
7492         /* Check objects */
7493         if (flg & (PROJECT_ITEM))
7494         {
7495                 /* Start with "dist" of zero */
7496                 dist = 0;
7497
7498                 /* Scan for objects */
7499                 for (i = 0; i < grids; i++)
7500                 {
7501                         /* Hack -- Notice new "dist" values */
7502                         if (gm[dist+1] == i) dist++;
7503
7504                         /* Get the grid location */
7505                         y = gy[i];
7506                         x = gx[i];
7507
7508                         /* Find the closest point in the blast */
7509                         if (breath)
7510                         {
7511                                 int d = dist_to_line(y, x, y1, x1, by, bx);
7512
7513                                 /* Affect the object in the grid */
7514                                 if (project_o(who, d, y, x, dam, typ)) notice = TRUE;
7515                         }
7516                         else
7517                         {
7518                                 /* Affect the object in the grid */
7519                                 if (project_o(who, dist, y, x, dam, typ)) notice = TRUE;
7520                         }
7521                 }
7522         }
7523
7524
7525         /* Check monsters */
7526         if (flg & (PROJECT_KILL))
7527         {
7528                 /* Mega-Hack */
7529                 project_m_n = 0;
7530                 project_m_x = 0;
7531                 project_m_y = 0;
7532
7533                 /* Start with "dist" of zero */
7534                 dist = 0;
7535
7536                 /* Scan for monsters */
7537                 for (i = 0; i < grids; i++)
7538                 {
7539                         int effective_dist;
7540
7541                         /* Hack -- Notice new "dist" values */
7542                         if (gm[dist + 1] == i) dist++;
7543
7544                         /* Get the grid location */
7545                         y = gy[i];
7546                         x = gx[i];
7547
7548                         /* A single bolt may be reflected */
7549                         if (grids <= 1)
7550                         {
7551                                 monster_type *m_ptr = &m_list[cave[y][x].m_idx];
7552                                 monster_race *ref_ptr = &r_info[m_ptr->r_idx];
7553
7554                                 if ((flg & PROJECT_REFLECTABLE) && cave[y][x].m_idx && (ref_ptr->flags2 & RF2_REFLECTING) &&
7555                                         ((cave[y][x].m_idx != p_ptr->riding) || !(flg & PROJECT_PLAYER)) &&
7556                                         (!who || dist_hack > 1) && !one_in_(10))
7557                                 {
7558                                         POSITION t_y, t_x;
7559                                         int max_attempts = 10;
7560
7561                                         /* Choose 'new' target */
7562                                         do
7563                                         {
7564                                                 t_y = y_saver - 1 + randint1(3);
7565                                                 t_x = x_saver - 1 + randint1(3);
7566                                                 max_attempts--;
7567                                         }
7568                                         while (max_attempts && in_bounds2u(t_y, t_x) && !projectable(y, x, t_y, t_x));
7569
7570                                         if (max_attempts < 1)
7571                                         {
7572                                                 t_y = y_saver;
7573                                                 t_x = x_saver;
7574                                         }
7575
7576                                         sound(SOUND_REFLECT);
7577                                         if (is_seen(m_ptr))
7578                                         {
7579                                                 if ((m_ptr->r_idx == MON_KENSHIROU) || (m_ptr->r_idx == MON_RAOU))
7580                                                         msg_print(_("「北斗神拳奥義・二指真空把!」", "The attack bounces!"));
7581                                                 else if (m_ptr->r_idx == MON_DIO) 
7582                                                         msg_print(_("ディオ・ブランドーは指一本で攻撃を弾き返した!", "The attack bounces!"));
7583                                                 else 
7584                                                         msg_print(_("攻撃は跳ね返った!", "The attack bounces!"));
7585                                         }
7586                                         if (is_original_ap_and_seen(m_ptr)) ref_ptr->r_flags2 |= RF2_REFLECTING;
7587
7588                                         /* Reflected bolts randomly target either one */
7589                                         if (player_bold(y, x) || one_in_(2)) flg &= ~(PROJECT_PLAYER);
7590                                         else flg |= PROJECT_PLAYER;
7591
7592                                         /* The bolt is reflected */
7593                                         project(cave[y][x].m_idx, 0, t_y, t_x, dam, typ, flg, monspell);
7594
7595                                         /* Don't affect the monster any longer */
7596                                         continue;
7597                                 }
7598                         }
7599
7600
7601                         /* Find the closest point in the blast */
7602                         if (breath)
7603                         {
7604                                 effective_dist = dist_to_line(y, x, y1, x1, by, bx);
7605                         }
7606                         else
7607                         {
7608                                 effective_dist = dist;
7609                         }
7610
7611
7612                         /* There is the riding player on this monster */
7613                         if (p_ptr->riding && player_bold(y, x))
7614                         {
7615                                 /* Aimed on the player */
7616                                 if (flg & PROJECT_PLAYER)
7617                                 {
7618                                         if (flg & (PROJECT_BEAM | PROJECT_REFLECTABLE | PROJECT_AIMED))
7619                                         {
7620                                                 /*
7621                                                  * A beam or bolt is well aimed
7622                                                  * at the PLAYER!
7623                                                  * So don't affects the mount.
7624                                                  */
7625                                                 continue;
7626                                         }
7627                                         else
7628                                         {
7629                                                 /*
7630                                                  * The spell is not well aimed, 
7631                                                  * So partly affect the mount too.
7632                                                  */
7633                                                 effective_dist++;
7634                                         }
7635                                 }
7636
7637                                 /*
7638                                  * This grid is the original target.
7639                                  * Or aimed on your horse.
7640                                  */
7641                                 else if (((y == y2) && (x == x2)) || (flg & PROJECT_AIMED))
7642                                 {
7643                                         /* Hit the mount with full damage */
7644                                 }
7645
7646                                 /*
7647                                  * Otherwise this grid is not the
7648                                  * original target, it means that line
7649                                  * of fire is obstructed by this
7650                                  * monster.
7651                                  */
7652                                 /*
7653                                  * A beam or bolt will hit either
7654                                  * player or mount.  Choose randomly.
7655                                  */
7656                                 else if (flg & (PROJECT_BEAM | PROJECT_REFLECTABLE))
7657                                 {
7658                                         if (one_in_(2))
7659                                         {
7660                                                 /* Hit the mount with full damage */
7661                                         }
7662                                         else
7663                                         {
7664                                                 /* Hit the player later */
7665                                                 flg |= PROJECT_PLAYER;
7666
7667                                                 /* Don't affect the mount */
7668                                                 continue;
7669                                         }
7670                                 }
7671
7672                                 /*
7673                                  * The spell is not well aimed, so
7674                                  * partly affect both player and
7675                                  * mount.
7676                                  */
7677                                 else
7678                                 {
7679                                         effective_dist++;
7680                                 }
7681                         }
7682
7683                         /* Affect the monster in the grid */
7684                         if (project_m(who, effective_dist, y, x, dam, typ, flg, see_s_msg)) notice = TRUE;
7685                 }
7686
7687
7688                 /* Player affected one monster (without "jumping") */
7689                 if (!who && (project_m_n == 1) && !jump)
7690                 {
7691                         x = project_m_x;
7692                         y = project_m_y;
7693
7694                         /* Track if possible */
7695                         if (cave[y][x].m_idx > 0)
7696                         {
7697                                 monster_type *m_ptr = &m_list[cave[y][x].m_idx];
7698
7699                                 if (m_ptr->ml)
7700                                 {
7701                                         /* Hack -- auto-recall */
7702                                         if (!p_ptr->image) monster_race_track(m_ptr->ap_r_idx);
7703
7704                                         /* Hack - auto-track */
7705                                         if (m_ptr->ml) health_track(cave[y][x].m_idx);
7706                                 }
7707                         }
7708                 }
7709         }
7710
7711
7712         /* Check player */
7713         if (flg & (PROJECT_KILL))
7714         {
7715                 /* Start with "dist" of zero */
7716                 dist = 0;
7717
7718                 /* Scan for player */
7719                 for (i = 0; i < grids; i++)
7720                 {
7721                         int effective_dist;
7722
7723                         /* Hack -- Notice new "dist" values */
7724                         if (gm[dist+1] == i) dist++;
7725
7726                         /* Get the grid location */
7727                         y = gy[i];
7728                         x = gx[i];
7729
7730                         /* Affect the player? */
7731                         if (!player_bold(y, x)) continue;
7732
7733                         /* Find the closest point in the blast */
7734                         if (breath)
7735                         {
7736                                 effective_dist = dist_to_line(y, x, y1, x1, by, bx);
7737                         }
7738                         else
7739                         {
7740                                 effective_dist = dist;
7741                         }
7742
7743                         /* Target may be your horse */
7744                         if (p_ptr->riding)
7745                         {
7746                                 /* Aimed on the player */
7747                                 if (flg & PROJECT_PLAYER)
7748                                 {
7749                                         /* Hit the player with full damage */
7750                                 }
7751
7752                                 /*
7753                                  * Hack -- When this grid was not the
7754                                  * original target, a beam or bolt
7755                                  * would hit either player or mount,
7756                                  * and should be choosen randomly.
7757                                  *
7758                                  * But already choosen to hit the
7759                                  * mount at this point.
7760                                  *
7761                                  * Or aimed on your horse.
7762                                  */
7763                                 else if (flg & (PROJECT_BEAM | PROJECT_REFLECTABLE | PROJECT_AIMED))
7764                                 {
7765                                         /*
7766                                          * A beam or bolt is well aimed
7767                                          * at the mount!
7768                                          * So don't affects the player.
7769                                          */
7770                                         continue;
7771                                 }
7772                                 else
7773                                 {
7774                                         /*
7775                                          * The spell is not well aimed, 
7776                                          * So partly affect the player too.
7777                                          */
7778                                         effective_dist++;
7779                                 }
7780                         }
7781
7782                         /* Affect the player */
7783                         if (project_p(who, who_name, effective_dist, y, x, dam, typ, flg, monspell)) notice = TRUE;
7784                 }
7785         }
7786
7787         if (p_ptr->riding)
7788         {
7789                 char m_name[80];
7790
7791                 monster_desc(m_name, &m_list[p_ptr->riding], 0);
7792
7793                 if (rakubadam_m > 0)
7794                 {
7795                         if (rakuba(rakubadam_m, FALSE))
7796                         {
7797                                 msg_format(_("%^sに振り落とされた!", "%^s has thrown you off!"), m_name);
7798                         }
7799                 }
7800                 if (p_ptr->riding && rakubadam_p > 0)
7801                 {
7802                         if(rakuba(rakubadam_p, FALSE))
7803                         {
7804                                 msg_format(_("%^sから落ちてしまった!", "You have fallen from %s."), m_name);
7805                         }
7806                 }
7807         }
7808
7809         /* Return "something was noticed" */
7810         return (notice);
7811 }
7812
7813 /*!
7814  * @brief 鏡魔法「封魔結界」の効果処理
7815  * @param dam ダメージ量
7816  * @return 効果があったらTRUEを返す
7817  */
7818 bool binding_field(HIT_POINT dam)
7819 {
7820         POSITION mirror_x[10], mirror_y[10]; /* 鏡はもっと少ない */
7821         int mirror_num = 0;                       /* 鏡の数 */
7822         POSITION x, y;
7823         POSITION centersign;
7824         POSITION x1, x2, y1, y2;
7825         u16b p;
7826         int msec = delay_factor*delay_factor*delay_factor;
7827
7828         /* 三角形の頂点 */
7829         POSITION point_x[3];
7830         POSITION point_y[3];
7831
7832         /* Default target of monsterspell is player */
7833         monster_target_y = p_ptr->y;
7834         monster_target_x = p_ptr->x;
7835
7836         for (x = 0; x < cur_wid; x++)
7837         {
7838                 for (y = 0; y < cur_hgt; y++)
7839                 {
7840                         if (is_mirror_grid(&cave[y][x]) &&
7841                                 distance(p_ptr->y, p_ptr->x, y, x) <= MAX_RANGE &&
7842                                 distance(p_ptr->y, p_ptr->x, y, x) != 0 &&
7843                                 player_has_los_bold(y, x) &&
7844                                 projectable(p_ptr->y, p_ptr->x, y, x)
7845                                 ) {
7846                                 mirror_y[mirror_num] = y;
7847                                 mirror_x[mirror_num] = x;
7848                                 mirror_num++;
7849                         }
7850                 }
7851         }
7852
7853         if (mirror_num < 2)return FALSE;
7854
7855         point_x[0] = randint0(mirror_num);
7856         do {
7857                 point_x[1] = randint0(mirror_num);
7858         } while (point_x[0] == point_x[1]);
7859
7860         point_y[0] = mirror_y[point_x[0]];
7861         point_x[0] = mirror_x[point_x[0]];
7862         point_y[1] = mirror_y[point_x[1]];
7863         point_x[1] = mirror_x[point_x[1]];
7864         point_y[2] = p_ptr->y;
7865         point_x[2] = p_ptr->x;
7866
7867         x = point_x[0] + point_x[1] + point_x[2];
7868         y = point_y[0] + point_y[1] + point_y[2];
7869
7870         centersign = (point_x[0] * 3 - x)*(point_y[1] * 3 - y)
7871                 - (point_y[0] * 3 - y)*(point_x[1] * 3 - x);
7872         if (centersign == 0)return FALSE;
7873
7874         x1 = point_x[0] < point_x[1] ? point_x[0] : point_x[1];
7875         x1 = x1 < point_x[2] ? x1 : point_x[2];
7876         y1 = point_y[0] < point_y[1] ? point_y[0] : point_y[1];
7877         y1 = y1 < point_y[2] ? y1 : point_y[2];
7878
7879         x2 = point_x[0] > point_x[1] ? point_x[0] : point_x[1];
7880         x2 = x2 > point_x[2] ? x2 : point_x[2];
7881         y2 = point_y[0] > point_y[1] ? point_y[0] : point_y[1];
7882         y2 = y2 > point_y[2] ? y2 : point_y[2];
7883
7884         for (y = y1; y <= y2; y++) {
7885                 for (x = x1; x <= x2; x++) {
7886                         if (centersign*((point_x[0] - x)*(point_y[1] - y)
7887                                 - (point_y[0] - y)*(point_x[1] - x)) >= 0 &&
7888                                 centersign*((point_x[1] - x)*(point_y[2] - y)
7889                                         - (point_y[1] - y)*(point_x[2] - x)) >= 0 &&
7890                                 centersign*((point_x[2] - x)*(point_y[0] - y)
7891                                         - (point_y[2] - y)*(point_x[0] - x)) >= 0)
7892                         {
7893                                 if (player_has_los_bold(y, x) && projectable(p_ptr->y, p_ptr->x, y, x)) {
7894                                         /* Visual effects */
7895                                         if (!(p_ptr->blind)
7896                                                 && panel_contains(y, x)) {
7897                                                 p = bolt_pict(y, x, y, x, GF_MANA);
7898                                                 print_rel(PICT_C(p), PICT_A(p), y, x);
7899                                                 move_cursor_relative(y, x);
7900                                                 /*if (fresh_before)*/ Term_fresh();
7901                                                 Term_xtra(TERM_XTRA_DELAY, msec);
7902                                         }
7903                                 }
7904                         }
7905                 }
7906         }
7907         for (y = y1; y <= y2; y++) {
7908                 for (x = x1; x <= x2; x++) {
7909                         if (centersign*((point_x[0] - x)*(point_y[1] - y)
7910                                 - (point_y[0] - y)*(point_x[1] - x)) >= 0 &&
7911                                 centersign*((point_x[1] - x)*(point_y[2] - y)
7912                                         - (point_y[1] - y)*(point_x[2] - x)) >= 0 &&
7913                                 centersign*((point_x[2] - x)*(point_y[0] - y)
7914                                         - (point_y[2] - y)*(point_x[0] - x)) >= 0)
7915                         {
7916                                 if (player_has_los_bold(y, x) && projectable(p_ptr->y, p_ptr->x, y, x)) {
7917                                         (void)project_f(0, 0, y, x, dam, GF_MANA);
7918                                 }
7919                         }
7920                 }
7921         }
7922         for (y = y1; y <= y2; y++) {
7923                 for (x = x1; x <= x2; x++) {
7924                         if (centersign*((point_x[0] - x)*(point_y[1] - y)
7925                                 - (point_y[0] - y)*(point_x[1] - x)) >= 0 &&
7926                                 centersign*((point_x[1] - x)*(point_y[2] - y)
7927                                         - (point_y[1] - y)*(point_x[2] - x)) >= 0 &&
7928                                 centersign*((point_x[2] - x)*(point_y[0] - y)
7929                                         - (point_y[2] - y)*(point_x[0] - x)) >= 0)
7930                         {
7931                                 if (player_has_los_bold(y, x) && projectable(p_ptr->y, p_ptr->x, y, x)) {
7932                                         (void)project_o(0, 0, y, x, dam, GF_MANA);
7933                                 }
7934                         }
7935                 }
7936         }
7937         for (y = y1; y <= y2; y++) {
7938                 for (x = x1; x <= x2; x++) {
7939                         if (centersign*((point_x[0] - x)*(point_y[1] - y)
7940                                 - (point_y[0] - y)*(point_x[1] - x)) >= 0 &&
7941                                 centersign*((point_x[1] - x)*(point_y[2] - y)
7942                                         - (point_y[1] - y)*(point_x[2] - x)) >= 0 &&
7943                                 centersign*((point_x[2] - x)*(point_y[0] - y)
7944                                         - (point_y[2] - y)*(point_x[0] - x)) >= 0)
7945                         {
7946                                 if (player_has_los_bold(y, x) && projectable(p_ptr->y, p_ptr->x, y, x)) {
7947                                         (void)project_m(0, 0, y, x, dam, GF_MANA,
7948                                                 (PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL | PROJECT_JUMP), TRUE);
7949                                 }
7950                         }
7951                 }
7952         }
7953         if (one_in_(7)) {
7954                 msg_print(_("鏡が結界に耐えきれず、壊れてしまった。", "The field broke a mirror"));
7955                 remove_mirror(point_y[0], point_x[0]);
7956         }
7957
7958         return TRUE;
7959 }
7960
7961 /*!
7962  * @brief 鏡魔法「鏡の封印」の効果処理
7963  * @param dam ダメージ量
7964  * @return 効果があったらTRUEを返す
7965  */
7966 void seal_of_mirror(HIT_POINT dam)
7967 {
7968         POSITION x, y;
7969
7970         for (x = 0; x < cur_wid; x++)
7971         {
7972                 for (y = 0; y < cur_hgt; y++)
7973                 {
7974                         if (is_mirror_grid(&cave[y][x]))
7975                         {
7976                                 if (project_m(0, 0, y, x, dam, GF_GENOCIDE,
7977                                         (PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL | PROJECT_JUMP), TRUE))
7978                                 {
7979                                         if (!cave[y][x].m_idx)
7980                                         {
7981                                                 remove_mirror(y, x);
7982                                         }
7983                                 }
7984                         }
7985                 }
7986         }
7987         return;
7988 }
7989