OSDN Git Service

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