OSDN Git Service

a7884840c4d0df8062aa083f2a36962d40c99cb7
[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(int y, int x, int ny, int 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, int range, int y1, int x1, int y2, int 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 int project_m_x; /*!< 処理中のモンスターX座標 */
600 static int project_m_y; /*!< 処理中のモンスターY座標 */
601 /* Mega-Hack -- monsters target */
602 static s16b monster_target_x; /*!< モンスターの攻撃目標X座標 */
603 static s16b 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(int who, int r, int y, int x, int dam, int typ)
1202 {
1203         cave_type *c_ptr = &cave[y][x];
1204
1205         s16b 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(int who, int r, int y, int x, int 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         int 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, int y, int x, int 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                 byte 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                                         dam *= 6; dam /= (randint1(4) + 7);
5469                         }
5470                         else if (!CHECK_MULTISHADOW()) drain_exp(200 + (p_ptr->exp / 100), 200 + (p_ptr->exp / 1000), 75);
5471
5472                         if (prace_is_(RACE_SPECTRE) && !CHECK_MULTISHADOW())
5473                         {
5474                 msg_print(_("気分がよくなった。", "You feel invigorated!"));
5475                                 hp_player(dam / 4);
5476                                 learn_spell(monspell);
5477                         }
5478                         else
5479                         {
5480                                 get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
5481                         }
5482
5483                         break;
5484                 }
5485
5486                 /* Water -- stun/confuse */
5487                 case GF_WATER:
5488                 {
5489                         if (fuzzy) msg_print(_("何か湿ったもので攻撃された!", "You are hit by something wet!"));
5490             if (!CHECK_MULTISHADOW())
5491                         {
5492                                 if (!p_ptr->resist_sound)
5493                                 {
5494                                         set_stun(p_ptr->stun + randint1(40));
5495                                 }
5496                                 if (!p_ptr->resist_conf)
5497                                 {
5498                                         set_confused(p_ptr->confused + randint1(5) + 5);
5499                                 }
5500
5501                                 if (one_in_(5))
5502                                 {
5503                                         inven_damage(set_cold_destroy, 3);
5504                                 }
5505                         }
5506
5507                         get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
5508                         break;
5509                 }
5510
5511                 /* Chaos -- many effects */
5512                 case GF_CHAOS:
5513                 {
5514             if (fuzzy) msg_print(_("無秩序の波動で攻撃された!", "You are hit by a wave of anarchy!"));
5515                         if (p_ptr->resist_chaos)
5516                         {
5517                                 dam *= 6; dam /= (randint1(4) + 7);
5518                         }
5519
5520                         if (!CHECK_MULTISHADOW())
5521                         {
5522                                 if (!p_ptr->resist_conf)
5523                                 {
5524                                         (void)set_confused(p_ptr->confused + randint0(20) + 10);
5525                                 }
5526                                 if (!p_ptr->resist_chaos)
5527                                 {
5528                                         (void)set_image(p_ptr->image + randint1(10));
5529                                         if (one_in_(3))
5530                                         {
5531                         msg_print(_("あなたの身体はカオスの力で捻じ曲げられた!", "Your body is twisted by chaos!"));
5532                                                 (void)gain_random_mutation(0);
5533                                         }
5534                                 }
5535                                 if (!p_ptr->resist_neth && !p_ptr->resist_chaos)
5536                                 {
5537                                         drain_exp(5000 + (p_ptr->exp / 100), 500 + (p_ptr->exp / 1000), 75);
5538                                 }
5539
5540                                 if (!p_ptr->resist_chaos || one_in_(9))
5541                                 {
5542                                         inven_damage(set_elec_destroy, 2);
5543                                         inven_damage(set_fire_destroy, 2);
5544                                 }
5545                         }
5546
5547                         get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
5548                         break;
5549                 }
5550
5551                 /* Shards -- mostly cutting */
5552                 case GF_SHARDS:
5553                 {
5554                         if (fuzzy) msg_print(_("何か鋭いもので攻撃された!", "You are hit by something sharp!"));
5555                         if (p_ptr->resist_shard)
5556                         {
5557                                 dam *= 6; dam /= (randint1(4) + 7);
5558                         }
5559                         else if (!CHECK_MULTISHADOW())
5560                         {
5561                                 (void)set_cut(p_ptr->cut + dam);
5562                         }
5563
5564                         if (!p_ptr->resist_shard || one_in_(13))
5565                         {
5566                                 inven_damage(set_cold_destroy, 2);
5567                         }
5568
5569                         get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
5570                         break;
5571                 }
5572
5573                 /* Sound -- mostly stunning */
5574                 case GF_SOUND:
5575                 {
5576                         if (fuzzy) msg_print(_("轟音で攻撃された!", "You are hit by a loud noise!"));
5577                         if (p_ptr->resist_sound)
5578                         {
5579                                 dam *= 5; dam /= (randint1(4) + 7);
5580                         }
5581                         else if (!CHECK_MULTISHADOW())
5582                         {
5583                                 int plus_stun = (randint1((dam > 90) ? 35 : (dam / 3 + 5)));
5584                                 (void)set_stun(p_ptr->stun + plus_stun);
5585                         }
5586
5587                         if (!p_ptr->resist_sound || one_in_(13))
5588                         {
5589                                 inven_damage(set_cold_destroy, 2);
5590                         }
5591
5592                         get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
5593                         break;
5594                 }
5595
5596                 /* Pure confusion */
5597                 case GF_CONFUSION:
5598                 {
5599                         if (fuzzy) msg_print(_("何か混乱するもので攻撃された!", "You are hit by something puzzling!"));
5600                         if (p_ptr->resist_conf)
5601                         {
5602                                 dam *= 5; dam /= (randint1(4) + 7);
5603                         }
5604                         else if (!CHECK_MULTISHADOW())
5605                         {
5606                                 (void)set_confused(p_ptr->confused + randint1(20) + 10);
5607                         }
5608                         get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
5609                         break;
5610                 }
5611
5612                 /* Disenchantment -- see above */
5613                 case GF_DISENCHANT:
5614                 {
5615                         if (fuzzy) msg_print(_("何かさえないもので攻撃された!", "You are hit by something static!"));
5616                         if (p_ptr->resist_disen)
5617                         {
5618                                 dam *= 6; dam /= (randint1(4) + 7);
5619                         }
5620                         else if (!CHECK_MULTISHADOW())
5621                         {
5622                                 (void)apply_disenchant(0);
5623                         }
5624                         get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
5625                         break;
5626                 }
5627
5628                 /* Nexus -- see above */
5629                 case GF_NEXUS:
5630                 {
5631                         if (fuzzy) msg_print(_("何か奇妙なもので攻撃された!", "You are hit by something strange!"));
5632                         if (p_ptr->resist_nexus)
5633                         {
5634                                 dam *= 6; dam /= (randint1(4) + 7);
5635                         }
5636                         else if (!CHECK_MULTISHADOW())
5637                         {
5638                                 apply_nexus(m_ptr);
5639                         }
5640                         get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
5641                         break;
5642                 }
5643
5644                 /* Force -- mostly stun */
5645                 case GF_FORCE:
5646                 {
5647                         if (fuzzy) msg_print(_("運動エネルギーで攻撃された!", "You are hit by kinetic force!"));
5648                         if (!p_ptr->resist_sound && !CHECK_MULTISHADOW())
5649                         {
5650                                 (void)set_stun(p_ptr->stun + randint1(20));
5651                         }
5652                         get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
5653                         break;
5654                 }
5655
5656
5657                 /* Rocket -- stun, cut */
5658                 case GF_ROCKET:
5659                 {
5660                         if (fuzzy) msg_print(_("爆発があった!", "There is an explosion!"));
5661                         if (!p_ptr->resist_sound && !CHECK_MULTISHADOW())
5662                         {
5663                                 (void)set_stun(p_ptr->stun + randint1(20));
5664                         }
5665
5666                         if (p_ptr->resist_shard)
5667                         {
5668                                 dam /= 2;
5669                         }
5670                         else if (!CHECK_MULTISHADOW())
5671                         {
5672                                 (void)set_cut(p_ptr->cut + (dam / 2));
5673                         }
5674
5675                         if (!p_ptr->resist_shard || one_in_(12))
5676                         {
5677                                 inven_damage(set_cold_destroy, 3);
5678                         }
5679
5680                         get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
5681                         break;
5682                 }
5683
5684                 /* Inertia -- slowness */
5685                 case GF_INERTIAL:
5686                 {
5687                         if (fuzzy) msg_print(_("何か遅いもので攻撃された!", "You are hit by something slow!"));
5688                         if (!CHECK_MULTISHADOW()) (void)set_slow(p_ptr->slow + randint0(4) + 4, FALSE);
5689                         get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
5690                         break;
5691                 }
5692
5693                 /* Lite -- blinding */
5694                 case GF_LITE:
5695                 {
5696                         if (fuzzy) msg_print(_("何かで攻撃された!", "You are hit by something!"));
5697                         if (p_ptr->resist_lite)
5698                         {
5699                                 dam *= 4; dam /= (randint1(4) + 7);
5700                         }
5701                         else if (!blind && !p_ptr->resist_blind && !CHECK_MULTISHADOW())
5702                         {
5703                                 (void)set_blind(p_ptr->blind + randint1(5) + 2);
5704                         }
5705
5706                         if (prace_is_(RACE_VAMPIRE) || (p_ptr->mimic_form == MIMIC_VAMPIRE))
5707                         {
5708                 if (!CHECK_MULTISHADOW()) msg_print(_("光で肉体が焦がされた!", "The light scorches your flesh!"));
5709                                 dam *= 2;
5710                         }
5711                         else if (prace_is_(RACE_S_FAIRY))
5712                         {
5713                                 dam = dam * 4 / 3;
5714                         }
5715
5716                         if (p_ptr->wraith_form) dam *= 2;
5717                         get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
5718
5719                         if (p_ptr->wraith_form && !CHECK_MULTISHADOW())
5720                         {
5721                                 p_ptr->wraith_form = 0;
5722                                 msg_print(_("閃光のため非物質的な影の存在でいられなくなった。",
5723                     "The light forces you out of your incorporeal shadow form."));
5724
5725                                 p_ptr->redraw |= PR_MAP;
5726                                 /* Update monsters */
5727                                 p_ptr->update |= (PU_MONSTERS);
5728                                 /* Window stuff */
5729                                 p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
5730
5731                                 /* Redraw status bar */
5732                                 p_ptr->redraw |= (PR_STATUS);
5733
5734                         }
5735
5736                         break;
5737                 }
5738
5739                 /* Dark -- blinding */
5740                 case GF_DARK:
5741                 {
5742                         if (fuzzy) msg_print(_("何かで攻撃された!", "You are hit by something!"));
5743                         if (p_ptr->resist_dark)
5744                         {
5745                                 dam *= 4; dam /= (randint1(4) + 7);
5746
5747                                 if (prace_is_(RACE_VAMPIRE) || (p_ptr->mimic_form == MIMIC_VAMPIRE) || p_ptr->wraith_form) dam = 0;
5748                         }
5749                         else if (!blind && !p_ptr->resist_blind && !CHECK_MULTISHADOW())
5750                         {
5751                                 (void)set_blind(p_ptr->blind + randint1(5) + 2);
5752                         }
5753                         get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
5754                         break;
5755                 }
5756
5757                 /* Time -- bolt fewer effects XXX */
5758                 case GF_TIME:
5759                 {
5760                         if (fuzzy) msg_print(_("過去からの衝撃に攻撃された!", "You are hit by a blast from the past!"));
5761                         if (p_ptr->resist_time)
5762                         {
5763                                 dam *= 4;
5764                                 dam /= (randint1(4) + 7);
5765                 msg_print(_("時間が通り過ぎていく気がする。", "You feel as if time is passing you by."));
5766                         }
5767                         else if (!CHECK_MULTISHADOW())
5768                         {
5769                                 switch (randint1(10))
5770                                 {
5771                                         case 1: case 2: case 3: case 4: case 5:
5772                                         {
5773                                                 if (p_ptr->prace == RACE_ANDROID) break;
5774                         msg_print(_("人生が逆戻りした気がする。", "You feel life has clocked back."));
5775                                                 lose_exp(100 + (p_ptr->exp / 100) * MON_DRAIN_LIFE);
5776                                                 break;
5777                                         }
5778
5779                                         case 6: case 7: case 8: case 9:
5780                                         {
5781                                                 switch (randint1(6))
5782                                                 {
5783                             case 1: k = A_STR; act = _("強く", "strong"); break;
5784                             case 2: k = A_INT; act = _("聡明で", "bright"); break;
5785                             case 3: k = A_WIS; act = _("賢明で", "wise"); break;
5786                             case 4: k = A_DEX; act = _("器用で", "agile"); break;
5787                             case 5: k = A_CON; act = _("健康で", "hale"); break;
5788                             case 6: k = A_CHR; act = _("美しく", "beautiful"); break;
5789                                                 }
5790
5791                                                 msg_format(_("あなたは以前ほど%sなくなってしまった...。", 
5792                                      "You're not as %s as you used to be..."), act);
5793
5794                                                 p_ptr->stat_cur[k] = (p_ptr->stat_cur[k] * 3) / 4;
5795                                                 if (p_ptr->stat_cur[k] < 3) p_ptr->stat_cur[k] = 3;
5796                                                 p_ptr->update |= (PU_BONUS);
5797                                                 break;
5798                                         }
5799
5800                                         case 10:
5801                                         {
5802                                                 msg_print(_("あなたは以前ほど力強くなくなってしまった...。", 
5803                                     "You're not as powerful as you used to be..."));
5804
5805                                                 for (k = 0; k < 6; k++)
5806                                                 {
5807                                                         p_ptr->stat_cur[k] = (p_ptr->stat_cur[k] * 7) / 8;
5808                                                         if (p_ptr->stat_cur[k] < 3) p_ptr->stat_cur[k] = 3;
5809                                                 }
5810                                                 p_ptr->update |= (PU_BONUS);
5811                                                 break;
5812                                         }
5813                                 }
5814                         }
5815
5816                         get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
5817                         break;
5818                 }
5819
5820                 /* Gravity -- stun plus slowness plus teleport */
5821                 case GF_GRAVITY:
5822                 {
5823                         if (fuzzy) msg_print(_("何か重いもので攻撃された!", "You are hit by something heavy!"));
5824                                 msg_print(_("周辺の重力がゆがんだ。", "Gravity warps around you."));
5825
5826                         if (!CHECK_MULTISHADOW())
5827                         {
5828                                 teleport_player(5, TELEPORT_PASSIVE);
5829                                 if (!p_ptr->levitation)
5830                                         (void)set_slow(p_ptr->slow + randint0(4) + 4, FALSE);
5831                                 if (!(p_ptr->resist_sound || p_ptr->levitation))
5832                                 {
5833                                         int plus_stun = (randint1((dam > 90) ? 35 : (dam / 3 + 5)));
5834                                         (void)set_stun(p_ptr->stun + plus_stun);
5835                                 }
5836                         }
5837                         if (p_ptr->levitation)
5838                         {
5839                                 dam = (dam * 2) / 3;
5840                         }
5841
5842                         if (!p_ptr->levitation || one_in_(13))
5843                         {
5844                                 inven_damage(set_cold_destroy, 2);
5845                         }
5846
5847                         get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
5848                         break;
5849                 }
5850
5851                 /* Standard damage */
5852                 case GF_DISINTEGRATE:
5853                 {
5854                         if (fuzzy) msg_print(_("純粋なエネルギーで攻撃された!", "You are hit by pure energy!"));
5855
5856                         get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
5857                         break;
5858                 }
5859
5860                 case GF_OLD_HEAL:
5861                 {
5862                         if (fuzzy) msg_print(_("何らかの攻撃によって気分がよくなった。", "You are hit by something invigorating!"));
5863
5864                         (void)hp_player(dam);
5865                         dam = 0;
5866                         break;
5867                 }
5868
5869                 case GF_OLD_SPEED:
5870                 {
5871                         if (fuzzy) msg_print(_("何かで攻撃された!", "You are hit by something!"));
5872                         (void)set_fast(p_ptr->fast + randint1(5), FALSE);
5873                         dam = 0;
5874                         break;
5875                 }
5876
5877                 case GF_OLD_SLOW:
5878                 {
5879                         if (fuzzy) msg_print(_("何か遅いもので攻撃された!", "You are hit by something slow!"));
5880                         (void)set_slow(p_ptr->slow + randint0(4) + 4, FALSE);
5881                         break;
5882                 }
5883
5884                 case GF_OLD_SLEEP:
5885                 {
5886                         if (p_ptr->free_act)  break;
5887             if (fuzzy) msg_print(_("眠ってしまった!", "You fall asleep!"));
5888
5889                         if (ironman_nightmare)
5890                         {
5891                 msg_print(_("恐ろしい光景が頭に浮かんできた。", "A horrible vision enters your mind."));
5892                                 /* Have some nightmares */
5893                                 sanity_blast(NULL, FALSE);
5894                         }
5895
5896                         set_paralyzed(p_ptr->paralyzed + dam);
5897                         dam = 0;
5898                         break;
5899                 }
5900
5901                 /* Pure damage */
5902                 case GF_MANA:
5903                 case GF_SEEKER:
5904                 case GF_SUPER_RAY:
5905                 {
5906                         if (fuzzy) msg_print(_("魔法のオーラで攻撃された!", "You are hit by an aura of magic!"));
5907                         get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
5908                         break;
5909                 }
5910
5911                 /* Pure damage */
5912                 case GF_PSY_SPEAR:
5913                 {
5914                         if (fuzzy) msg_print(_("エネルギーの塊で攻撃された!", "You are hit by an energy!"));
5915                         get_damage = take_hit(DAMAGE_FORCE, dam, killer, monspell);
5916                         break;
5917                 }
5918
5919                 /* Pure damage */
5920                 case GF_METEOR:
5921                 {
5922                         if (fuzzy) msg_print(_("何かが空からあなたの頭上に落ちてきた!", "Something falls from the sky on you!"));
5923
5924                         get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
5925                         if (!p_ptr->resist_shard || one_in_(13))
5926                         {
5927                                 if (!p_ptr->immune_fire) inven_damage(set_fire_destroy, 2);
5928                                 inven_damage(set_cold_destroy, 2);
5929                         }
5930
5931                         break;
5932                 }
5933
5934                 /* Ice -- cold plus stun plus cuts */
5935                 case GF_ICE:
5936                 {
5937                         if (fuzzy) msg_print(_("何か鋭く冷たいもので攻撃された!", "You are hit by something sharp and cold!"));
5938                         get_damage = cold_dam(dam, killer, monspell, FALSE);
5939                         if (!CHECK_MULTISHADOW())
5940                         {
5941                                 if (!p_ptr->resist_shard)
5942                                 {
5943                                         (void)set_cut(p_ptr->cut + damroll(5, 8));
5944                                 }
5945                                 if (!p_ptr->resist_sound)
5946                                 {
5947                                         (void)set_stun(p_ptr->stun + randint1(15));
5948                                 }
5949
5950                                 if ((!(p_ptr->resist_cold || IS_OPPOSE_COLD())) || one_in_(12))
5951                                 {
5952                                         if (!p_ptr->immune_cold) inven_damage(set_cold_destroy, 3);
5953                                 }
5954                         }
5955
5956                         break;
5957                 }
5958
5959                 /* Death Ray */
5960                 case GF_DEATH_RAY:
5961                 {
5962                         if (fuzzy) msg_print(_("何か非常に冷たいもので攻撃された!", "You are hit by something extremely cold!"));
5963
5964                         if (p_ptr->mimic_form)
5965                         {
5966                                 if (!(mimic_info[p_ptr->mimic_form].MIMIC_FLAGS & MIMIC_IS_NONLIVING))
5967                                         get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
5968                         }
5969                         else
5970                         {
5971
5972                         switch (p_ptr->prace)
5973                         {
5974                                 /* Some races are immune */
5975                                 case RACE_GOLEM:
5976                                 case RACE_SKELETON:
5977                                 case RACE_ZOMBIE:
5978                                 case RACE_VAMPIRE:
5979                                 case RACE_DEMON:
5980                                 case RACE_SPECTRE:
5981                                 {
5982                                         dam = 0;
5983                                         break;
5984                                 }
5985                                 /* Hurt a lot */
5986                                 default:
5987                                 {
5988                                         get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
5989                                         break;
5990                                 }
5991                         }
5992                         }
5993
5994                         break;
5995                 }
5996
5997                 /* Drain mana */
5998                 case GF_DRAIN_MANA:
5999                 {
6000                         if (CHECK_MULTISHADOW())
6001                         {
6002                 msg_print(_("攻撃は幻影に命中し、あなたには届かなかった。", "The attack hits Shadow, you are unharmed!"));
6003                         }
6004                         else if (p_ptr->csp)
6005                         {
6006                                 /* Basic message */
6007                                 if (who > 0) 
6008                     msg_format(_("%^sに精神エネルギーを吸い取られてしまった!", "%^s draws psychic energy from you!"), m_name);
6009                                 else 
6010                     msg_print(_("精神エネルギーを吸い取られてしまった!", "Your psychic energy is drawn!"));
6011
6012                                 /* Full drain */
6013                                 if (dam >= p_ptr->csp)
6014                                 {
6015                                         dam = p_ptr->csp;
6016                                         p_ptr->csp = 0;
6017                                         p_ptr->csp_frac = 0;
6018                                 }
6019
6020                                 /* Partial drain */
6021                                 else
6022                                 {
6023                                         p_ptr->csp -= dam;
6024                                 }
6025
6026                                 learn_spell(monspell);
6027
6028                                 /* Redraw mana */
6029                                 p_ptr->redraw |= (PR_MANA);
6030
6031                                 /* Window stuff */
6032                                 p_ptr->window |= (PW_PLAYER);
6033                                 p_ptr->window |= (PW_SPELL);
6034
6035                                 if (who > 0)
6036                                 {
6037                                         /* Heal the monster */
6038                                         if (m_ptr->hp < m_ptr->maxhp)
6039                                         {
6040                                                 /* Heal */
6041                                                 m_ptr->hp += dam;
6042                                                 if (m_ptr->hp > m_ptr->maxhp) m_ptr->hp = m_ptr->maxhp;
6043
6044                                                 /* Redraw (later) if needed */
6045                                                 if (p_ptr->health_who == who) p_ptr->redraw |= (PR_HEALTH);
6046                                                 if (p_ptr->riding == who) p_ptr->redraw |= (PR_UHEALTH);
6047
6048                                                 /* Special message */
6049                                                 if (m_ptr->ml)
6050                                                 {
6051                             msg_format(_("%^sは気分が良さそうだ。", "%^s appears healthier."), m_name);
6052                                                 }
6053                                         }
6054                                 }
6055                         }
6056
6057                         dam = 0;
6058                         break;
6059                 }
6060
6061                 /* Mind blast */
6062                 case GF_MIND_BLAST:
6063                 {
6064                         if ((randint0(100 + rlev / 2) < MAX(5, p_ptr->skill_sav)) && !CHECK_MULTISHADOW())
6065                         {
6066                 msg_print(_("しかし効力を跳ね返した!", "You resist the effects!"));
6067                                 learn_spell(monspell);
6068                         }
6069                         else
6070                         {
6071                                 if (!CHECK_MULTISHADOW())
6072                                 {
6073                     msg_print(_("霊的エネルギーで精神が攻撃された。", "Your mind is blasted by psyonic energy."));
6074
6075                                         if (!p_ptr->resist_conf)
6076                                         {
6077                                                 (void)set_confused(p_ptr->confused + randint0(4) + 4);
6078                                         }
6079
6080                                         if (!p_ptr->resist_chaos && one_in_(3))
6081                                         {
6082                                                 (void)set_image(p_ptr->image + randint0(250) + 150);
6083                                         }
6084
6085                                         p_ptr->csp -= 50;
6086                                         if (p_ptr->csp < 0)
6087                                         {
6088                                                 p_ptr->csp = 0;
6089                                                 p_ptr->csp_frac = 0;
6090                                         }
6091                                         p_ptr->redraw |= PR_MANA;
6092                                 }
6093
6094                                 get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
6095                         }
6096                         break;
6097                 }
6098
6099                 /* Brain smash */
6100                 case GF_BRAIN_SMASH:
6101                 {
6102                         if ((randint0(100 + rlev / 2) < MAX(5, p_ptr->skill_sav)) && !CHECK_MULTISHADOW())
6103             {
6104                 msg_print(_("しかし効力を跳ね返した!", "You resist the effects!"));
6105                                 learn_spell(monspell);
6106                         }
6107                         else
6108                         {
6109                                 if (!CHECK_MULTISHADOW())
6110                 {
6111                     msg_print(_("霊的エネルギーで精神が攻撃された。", "Your mind is blasted by psyonic energy."));
6112
6113                                         p_ptr->csp -= 100;
6114                                         if (p_ptr->csp < 0)
6115                                         {
6116                                                 p_ptr->csp = 0;
6117                                                 p_ptr->csp_frac = 0;
6118                                         }
6119                                         p_ptr->redraw |= PR_MANA;
6120                                 }
6121
6122                                 get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
6123                                 if (!CHECK_MULTISHADOW())
6124                                 {
6125                                         if (!p_ptr->resist_blind)
6126                                         {
6127                                                 (void)set_blind(p_ptr->blind + 8 + randint0(8));
6128                                         }
6129                                         if (!p_ptr->resist_conf)
6130                                         {
6131                                                 (void)set_confused(p_ptr->confused + randint0(4) + 4);
6132                                         }
6133                                         if (!p_ptr->free_act)
6134                                         {
6135                                                 (void)set_paralyzed(p_ptr->paralyzed + randint0(4) + 4);
6136                                         }
6137                                         (void)set_slow(p_ptr->slow + randint0(4) + 4, FALSE);
6138
6139                                         while (randint0(100 + rlev / 2) > (MAX(5, p_ptr->skill_sav)))
6140                                                 (void)do_dec_stat(A_INT);
6141                                         while (randint0(100 + rlev / 2) > (MAX(5, p_ptr->skill_sav)))
6142                                                 (void)do_dec_stat(A_WIS);
6143
6144                                         if (!p_ptr->resist_chaos)
6145                                         {
6146                                                 (void)set_image(p_ptr->image + randint0(250) + 150);
6147                                         }
6148                                 }
6149                         }
6150                         break;
6151                 }
6152
6153                 /* cause 1 */
6154                 case GF_CAUSE_1:
6155                 {
6156                         if ((randint0(100 + rlev / 2) < p_ptr->skill_sav) && !CHECK_MULTISHADOW())
6157             {
6158                 msg_print(_("しかし効力を跳ね返した!", "You resist the effects!"));
6159                                 learn_spell(monspell);
6160                         }
6161                         else
6162                         {
6163                                 if (!CHECK_MULTISHADOW()) curse_equipment(15, 0);
6164                                 get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
6165                         }
6166                         break;
6167                 }
6168
6169                 /* cause 2 */
6170                 case GF_CAUSE_2:
6171                 {
6172                         if ((randint0(100 + rlev / 2) < p_ptr->skill_sav) && !CHECK_MULTISHADOW())
6173             {
6174                 msg_print(_("しかし効力を跳ね返した!", "You resist the effects!"));
6175                                 learn_spell(monspell);
6176                         }
6177                         else
6178                         {
6179                                 if (!CHECK_MULTISHADOW()) curse_equipment(25, MIN(rlev / 2 - 15, 5));
6180                                 get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
6181                         }
6182                         break;
6183                 }
6184
6185                 /* cause 3 */
6186                 case GF_CAUSE_3:
6187                 {
6188                         if ((randint0(100 + rlev / 2) < p_ptr->skill_sav) && !CHECK_MULTISHADOW())
6189             {
6190                 msg_print(_("しかし効力を跳ね返した!", "You resist the effects!"));
6191                                 learn_spell(monspell);
6192                         }
6193                         else
6194                         {
6195                                 if (!CHECK_MULTISHADOW()) curse_equipment(33, MIN(rlev / 2 - 15, 15));
6196                                 get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
6197                         }
6198                         break;
6199                 }
6200
6201                 /* cause 4 */
6202                 case GF_CAUSE_4:
6203                 {
6204                         if ((randint0(100 + rlev / 2) < p_ptr->skill_sav) && !(m_ptr->r_idx == MON_KENSHIROU) && !CHECK_MULTISHADOW())
6205                         {
6206                 msg_print(_("しかし秘孔を跳ね返した!", "You resist the effects!"));
6207                                 learn_spell(monspell);
6208                         }
6209                         else
6210                         {
6211                                 get_damage = take_hit(DAMAGE_ATTACK, dam, killer, monspell);
6212                                 if (!CHECK_MULTISHADOW()) (void)set_cut(p_ptr->cut + damroll(10, 10));
6213                         }
6214                         break;
6215                 }
6216
6217                 /* Hand of Doom */
6218                 case GF_HAND_DOOM:
6219                 {
6220                         if ((randint0(100 + rlev/2) < p_ptr->skill_sav) && !CHECK_MULTISHADOW())
6221             {
6222                 msg_print(_("しかし効力を跳ね返した!", "You resist the effects!"));
6223                                 learn_spell(monspell);
6224                         }
6225                         else
6226                         {
6227                                 if (!CHECK_MULTISHADOW())
6228                                 {
6229                     msg_print(_("あなたは命が薄まっていくように感じた!", "You feel your life fade away!"));
6230                                         curse_equipment(40, 20);
6231                                 }
6232
6233                                 get_damage = take_hit(DAMAGE_ATTACK, dam, m_name, monspell);
6234
6235                                 if (p_ptr->chp < 1) p_ptr->chp = 1; /* Paranoia */
6236                         }
6237                         break;
6238                 }
6239
6240                 /* Default */
6241                 default:
6242                 {
6243                         /* No damage */
6244                         dam = 0;
6245
6246                         break;
6247                 }
6248         }
6249
6250         /* Hex - revenge damage stored */
6251         revenge_store(get_damage);
6252
6253         if ((p_ptr->tim_eyeeye || hex_spelling(HEX_EYE_FOR_EYE))
6254                 && (get_damage > 0) && !p_ptr->is_dead && (who > 0))
6255         {
6256                 char m_name_self[80];
6257
6258                 /* hisself */
6259                 monster_desc(m_name_self, m_ptr, MD_PRON_VISIBLE | MD_POSSESSIVE | MD_OBJECTIVE);
6260
6261                 msg_format(_("攻撃が%s自身を傷つけた!", "The attack of %s has wounded %s!"), m_name, m_name_self);
6262                 project(0, 0, m_ptr->fy, m_ptr->fx, get_damage, GF_MISSILE, PROJECT_KILL, -1);
6263                 if (p_ptr->tim_eyeeye) set_tim_eyeeye(p_ptr->tim_eyeeye-5, TRUE);
6264         }
6265
6266         if (p_ptr->riding && dam > 0)
6267         {
6268                 rakubadam_p = (dam > 200) ? 200 : dam;
6269         }
6270
6271
6272         /* Disturb */
6273         disturb(1, 1);
6274
6275
6276         if ((p_ptr->special_defense & NINJA_KAWARIMI) && dam && who && (who != p_ptr->riding))
6277         {
6278                 (void)kawarimi(FALSE);
6279         }
6280
6281         /* Return "Anything seen?" */
6282         return (obvious);
6283 }
6284
6285
6286 /*
6287  * Find the distance from (x, y) to a line.
6288  */
6289 int dist_to_line(int y, int x, int y1, int x1, int y2, int x2)
6290 {
6291         /* Vector from (x, y) to (x1, y1) */
6292         int py = y1 - y;
6293         int px = x1 - x;
6294
6295         /* Normal vector */
6296         int ny = x2 - x1;
6297         int nx = y1 - y2;
6298
6299    /* Length of N */
6300         int pd = distance(y1, x1, y, x);
6301         int nd = distance(y1, x1, y2, x2);
6302
6303         if (pd > nd) return distance(y, x, y2, x2);
6304
6305         /* Component of P on N */
6306         nd = ((nd) ? ((py * ny + px * nx) / nd) : 0);
6307
6308    /* Absolute value */
6309    return((nd >= 0) ? nd : 0 - nd);
6310 }
6311
6312
6313
6314 /*
6315  * XXX XXX XXX
6316  * Modified version of los() for calculation of disintegration balls.
6317  * Disintegration effects are stopped by permanent walls.
6318  */
6319 bool in_disintegration_range(int y1, int x1, int y2, int x2)
6320 {
6321         /* Delta */
6322         int dx, dy;
6323
6324         /* Absolute */
6325         int ax, ay;
6326
6327         /* Signs */
6328         int sx, sy;
6329
6330         /* Fractions */
6331         int qx, qy;
6332
6333         /* Scanners */
6334         int tx, ty;
6335
6336         /* Scale factors */
6337         int f1, f2;
6338
6339         /* Slope, or 1/Slope, of LOS */
6340         int m;
6341
6342
6343         /* Extract the offset */
6344         dy = y2 - y1;
6345         dx = x2 - x1;
6346
6347         /* Extract the absolute offset */
6348         ay = ABS(dy);
6349         ax = ABS(dx);
6350
6351
6352         /* Handle adjacent (or identical) grids */
6353         if ((ax < 2) && (ay < 2)) return (TRUE);
6354
6355
6356         /* Paranoia -- require "safe" origin */
6357         /* if (!in_bounds(y1, x1)) return (FALSE); */
6358
6359
6360         /* Directly South/North */
6361         if (!dx)
6362         {
6363                 /* South -- check for walls */
6364                 if (dy > 0)
6365                 {
6366                         for (ty = y1 + 1; ty < y2; ty++)
6367                         {
6368                                 if (cave_stop_disintegration(ty, x1)) return (FALSE);
6369                         }
6370                 }
6371
6372                 /* North -- check for walls */
6373                 else
6374                 {
6375                         for (ty = y1 - 1; ty > y2; ty--)
6376                         {
6377                                 if (cave_stop_disintegration(ty, x1)) return (FALSE);
6378                         }
6379                 }
6380
6381                 /* Assume los */
6382                 return (TRUE);
6383         }
6384
6385         /* Directly East/West */
6386         if (!dy)
6387         {
6388                 /* East -- check for walls */
6389                 if (dx > 0)
6390                 {
6391                         for (tx = x1 + 1; tx < x2; tx++)
6392                         {
6393                                 if (cave_stop_disintegration(y1, tx)) return (FALSE);
6394                         }
6395                 }
6396
6397                 /* West -- check for walls */
6398                 else
6399                 {
6400                         for (tx = x1 - 1; tx > x2; tx--)
6401                         {
6402                                 if (cave_stop_disintegration(y1, tx)) return (FALSE);
6403                         }
6404                 }
6405
6406                 /* Assume los */
6407                 return (TRUE);
6408         }
6409
6410
6411         /* Extract some signs */
6412         sx = (dx < 0) ? -1 : 1;
6413         sy = (dy < 0) ? -1 : 1;
6414
6415
6416         /* Vertical "knights" */
6417         if (ax == 1)
6418         {
6419                 if (ay == 2)
6420                 {
6421                         if (!cave_stop_disintegration(y1 + sy, x1)) return (TRUE);
6422                 }
6423         }
6424
6425         /* Horizontal "knights" */
6426         else if (ay == 1)
6427         {
6428                 if (ax == 2)
6429                 {
6430                         if (!cave_stop_disintegration(y1, x1 + sx)) return (TRUE);
6431                 }
6432         }
6433
6434
6435         /* Calculate scale factor div 2 */
6436         f2 = (ax * ay);
6437
6438         /* Calculate scale factor */
6439         f1 = f2 << 1;
6440
6441
6442         /* Travel horizontally */
6443         if (ax >= ay)
6444         {
6445                 /* Let m = dy / dx * 2 * (dy * dx) = 2 * dy * dy */
6446                 qy = ay * ay;
6447                 m = qy << 1;
6448
6449                 tx = x1 + sx;
6450
6451                 /* Consider the special case where slope == 1. */
6452                 if (qy == f2)
6453                 {
6454                         ty = y1 + sy;
6455                         qy -= f1;
6456                 }
6457                 else
6458                 {
6459                         ty = y1;
6460                 }
6461
6462                 /* Note (below) the case (qy == f2), where */
6463                 /* the LOS exactly meets the corner of a tile. */
6464                 while (x2 - tx)
6465                 {
6466                         if (cave_stop_disintegration(ty, tx)) return (FALSE);
6467
6468                         qy += m;
6469
6470                         if (qy < f2)
6471                         {
6472                                 tx += sx;
6473                         }
6474                         else if (qy > f2)
6475                         {
6476                                 ty += sy;
6477                                 if (cave_stop_disintegration(ty, tx)) return (FALSE);
6478                                 qy -= f1;
6479                                 tx += sx;
6480                         }
6481                         else
6482                         {
6483                                 ty += sy;
6484                                 qy -= f1;
6485                                 tx += sx;
6486                         }
6487                 }
6488         }
6489
6490         /* Travel vertically */
6491         else
6492         {
6493                 /* Let m = dx / dy * 2 * (dx * dy) = 2 * dx * dx */
6494                 qx = ax * ax;
6495                 m = qx << 1;
6496
6497                 ty = y1 + sy;
6498
6499                 if (qx == f2)
6500                 {
6501                         tx = x1 + sx;
6502                         qx -= f1;
6503                 }
6504                 else
6505                 {
6506                         tx = x1;
6507                 }
6508
6509                 /* Note (below) the case (qx == f2), where */
6510                 /* the LOS exactly meets the corner of a tile. */
6511                 while (y2 - ty)
6512                 {
6513                         if (cave_stop_disintegration(ty, tx)) return (FALSE);
6514
6515                         qx += m;
6516
6517                         if (qx < f2)
6518                         {
6519                                 ty += sy;
6520                         }
6521                         else if (qx > f2)
6522                         {
6523                                 tx += sx;
6524                                 if (cave_stop_disintegration(ty, tx)) return (FALSE);
6525                                 qx -= f1;
6526                                 ty += sy;
6527                         }
6528                         else
6529                         {
6530                                 tx += sx;
6531                                 qx -= f1;
6532                                 ty += sy;
6533                         }
6534                 }
6535         }
6536
6537         /* Assume los */
6538         return (TRUE);
6539 }
6540
6541
6542 /*
6543  * breath shape
6544  */
6545 void breath_shape(u16b *path_g, int dist, int *pgrids, byte *gx, byte *gy, byte *gm, int *pgm_rad, int rad, int y1, int x1, int y2, int x2, int typ)
6546 {
6547         int by = y1;
6548         int bx = x1;
6549         int brad = 0;
6550         int brev = rad * rad / dist;
6551         int bdis = 0;
6552         int cdis;
6553         int path_n = 0;
6554         int mdis = distance(y1, x1, y2, x2) + rad;
6555
6556         while (bdis <= mdis)
6557         {
6558                 int x, y;
6559
6560                 if ((0 < dist) && (path_n < dist))
6561                 {
6562                         int ny = GRID_Y(path_g[path_n]);
6563                         int nx = GRID_X(path_g[path_n]);
6564                         int nd = distance(ny, nx, y1, x1);
6565
6566                         /* Get next base point */
6567                         if (bdis >= nd)
6568                         {
6569                                 by = ny;
6570                                 bx = nx;
6571                                 path_n++;
6572                         }
6573                 }
6574
6575                 /* Travel from center outward */
6576                 for (cdis = 0; cdis <= brad; cdis++)
6577                 {
6578                         /* Scan the maximal blast area of radius "cdis" */
6579                         for (y = by - cdis; y <= by + cdis; y++)
6580                         {
6581                                 for (x = bx - cdis; x <= bx + cdis; x++)
6582                                 {
6583                                         /* Ignore "illegal" locations */
6584                                         if (!in_bounds(y, x)) continue;
6585
6586                                         /* Enforce a circular "ripple" */
6587                                         if (distance(y1, x1, y, x) != bdis) continue;
6588
6589                                         /* Enforce an arc */
6590                                         if (distance(by, bx, y, x) != cdis) continue;
6591
6592                                         switch (typ)
6593                                         {
6594                                         case GF_LITE:
6595                                         case GF_LITE_WEAK:
6596                                                 /* Lights are stopped by opaque terrains */
6597                                                 if (!los(by, bx, y, x)) continue;
6598                                                 break;
6599                                         case GF_DISINTEGRATE:
6600                                                 /* Disintegration are stopped only by perma-walls */
6601                                                 if (!in_disintegration_range(by, bx, y, x)) continue;
6602                                                 break;
6603                                         default:
6604                                                 /* Ball explosions are stopped by walls */
6605                                                 if (!projectable(by, bx, y, x)) continue;
6606                                                 break;
6607                                         }
6608
6609                                         /* Save this grid */
6610                                         gy[*pgrids] = y;
6611                                         gx[*pgrids] = x;
6612                                         (*pgrids)++;
6613                                 }
6614                         }
6615                 }
6616
6617                 /* Encode some more "radius" info */
6618                 gm[bdis + 1] = *pgrids;
6619
6620                 /* Increase the size */
6621                 brad = rad * (path_n + brev) / (dist + brev);
6622
6623                 /* Find the next ripple */
6624                 bdis++;
6625         }
6626
6627         /* Store the effect size */
6628         *pgm_rad = bdis;
6629 }
6630
6631
6632 /*!
6633  * @brief 汎用的なビーム/ボルト/ボール系処理のルーチン Generic "beam"/"bolt"/"ball" projection routine.
6634  * @param who 魔法を発動したモンスター(0ならばプレイヤー) / Index of "source" monster (zero for "player")
6635  * @param rad 効果半径(ビーム/ボルト = 0 / ボール = 1以上) / Radius of explosion (0 = beam/bolt, 1 to 9 = ball)
6636  * @param y 目標Y座標 / Target y location (or location to travel "towards")
6637  * @param x 目標X座標 / Target x location (or location to travel "towards")
6638  * @param dam 基本威力 / Base damage roll to apply to affected monsters (or player)
6639  * @param typ 効果属性 / Type of damage to apply to monsters (and objects)
6640  * @param flg 効果フラグ / Extra bit flags (see PROJECT_xxxx in "defines.h")
6641  * @param monspell 効果元のモンスター魔法ID
6642  * @return 何か一つでも効力があればTRUEを返す / TRUE if any "effects" of the projection were observed, else FALSE
6643  * @details
6644  * <pre>
6645  * Allows a monster (or player) to project a beam/bolt/ball of a given kind
6646  * towards a given location (optionally passing over the heads of interposing
6647  * monsters), and have it do a given amount of damage to the monsters (and
6648  * optionally objects) within the given radius of the final location.
6649  *
6650  * A "bolt" travels from source to target and affects only the target grid.
6651  * A "beam" travels from source to target, affecting all grids passed through.
6652  * A "ball" travels from source to the target, exploding at the target, and
6653  *   affecting everything within the given radius of the target location.
6654  *
6655  * Traditionally, a "bolt" does not affect anything on the ground, and does
6656  * not pass over the heads of interposing monsters, much like a traditional
6657  * missile, and will "stop" abruptly at the "target" even if no monster is
6658  * positioned there, while a "ball", on the other hand, passes over the heads
6659  * of monsters between the source and target, and affects everything except
6660  * the source monster which lies within the final radius, while a "beam"
6661  * affects every monster between the source and target, except for the casting
6662  * monster (or player), and rarely affects things on the ground.
6663  *
6664  * Two special flags allow us to use this function in special ways, the
6665  * "PROJECT_HIDE" flag allows us to perform "invisible" projections, while
6666  * the "PROJECT_JUMP" flag allows us to affect a specific grid, without
6667  * actually projecting from the source monster (or player).
6668  *
6669  * The player will only get "experience" for monsters killed by himself
6670  * Unique monsters can only be destroyed by attacks from the player
6671  *
6672  * Only 256 grids can be affected per projection, limiting the effective
6673  * "radius" of standard ball attacks to nine units (diameter nineteen).
6674  *
6675  * One can project in a given "direction" by combining PROJECT_THRU with small
6676  * offsets to the initial location (see "line_spell()"), or by calculating
6677  * "virtual targets" far away from the player.
6678  *
6679  * One can also use PROJECT_THRU to send a beam/bolt along an angled path,
6680  * continuing until it actually hits somethings (useful for "stone to mud").
6681  *
6682  * Bolts and Beams explode INSIDE walls, so that they can destroy doors.
6683  *
6684  * Balls must explode BEFORE hitting walls, or they would affect monsters
6685  * on both sides of a wall.  Some bug reports indicate that this is still
6686  * happening in 2.7.8 for Windows, though it appears to be impossible.
6687  *
6688  * We "pre-calculate" the blast area only in part for efficiency.
6689  * More importantly, this lets us do "explosions" from the "inside" out.
6690  * This results in a more logical distribution of "blast" treasure.
6691  * It also produces a better (in my opinion) animation of the explosion.
6692  * It could be (but is not) used to have the treasure dropped by monsters
6693  * in the middle of the explosion fall "outwards", and then be damaged by
6694  * the blast as it spreads outwards towards the treasure drop location.
6695  *
6696  * Walls and doors are included in the blast area, so that they can be
6697  * "burned" or "melted" in later versions.
6698  *
6699  * This algorithm is intended to maximize simplicity, not necessarily
6700  * efficiency, since this function is not a bottleneck in the code.
6701  *
6702  * We apply the blast effect from ground zero outwards, in several passes,
6703  * first affecting features, then objects, then monsters, then the player.
6704  * This allows walls to be removed before checking the object or monster
6705  * in the wall, and protects objects which are dropped by monsters killed
6706  * in the blast, and allows the player to see all affects before he is
6707  * killed or teleported away.  The semantics of this method are open to
6708  * various interpretations, but they seem to work well in practice.
6709  *
6710  * We process the blast area from ground-zero outwards to allow for better
6711  * distribution of treasure dropped by monsters, and because it provides a
6712  * pleasing visual effect at low cost.
6713  *
6714  * Note that the damage done by "ball" explosions decreases with distance.
6715  * This decrease is rapid, grids at radius "dist" take "1/dist" damage.
6716  *
6717  * Notice the "napalm" effect of "beam" weapons.  First they "project" to
6718  * the target, and then the damage "flows" along this beam of destruction.
6719  * The damage at every grid is the same as at the "center" of a "ball"
6720  * explosion, since the "beam" grids are treated as if they ARE at the
6721  * center of a "ball" explosion.
6722  *
6723  * Currently, specifying "beam" plus "ball" means that locations which are
6724  * covered by the initial "beam", and also covered by the final "ball", except
6725  * for the final grid (the epicenter of the ball), will be "hit twice", once
6726  * by the initial beam, and once by the exploding ball.  For the grid right
6727  * next to the epicenter, this results in 150% damage being done.  The center
6728  * does not have this problem, for the same reason the final grid in a "beam"
6729  * plus "bolt" does not -- it is explicitly removed.  Simply removing "beam"
6730  * grids which are covered by the "ball" will NOT work, as then they will
6731  * receive LESS damage than they should.  Do not combine "beam" with "ball".
6732  *
6733  * The array "gy[],gx[]" with current size "grids" is used to hold the
6734  * collected locations of all grids in the "blast area" plus "beam path".
6735  *
6736  * Note the rather complex usage of the "gm[]" array.  First, gm[0] is always
6737  * zero.  Second, for N>1, gm[N] is always the index (in gy[],gx[]) of the
6738  * first blast grid (see above) with radius "N" from the blast center.  Note
6739  * that only the first gm[1] grids in the blast area thus take full damage.
6740  * Also, note that gm[rad+1] is always equal to "grids", which is the total
6741  * number of blast grids.
6742  *
6743  * Note that once the projection is complete, (y2,x2) holds the final location
6744  * of bolts/beams, and the "epicenter" of balls.
6745  *
6746  * Note also that "rad" specifies the "inclusive" radius of projection blast,
6747  * so that a "rad" of "one" actually covers 5 or 9 grids, depending on the
6748  * implementation of the "distance" function.  Also, a bolt can be properly
6749  * viewed as a "ball" with a "rad" of "zero".
6750  *
6751  * Note that if no "target" is reached before the beam/bolt/ball travels the
6752  * maximum distance allowed (MAX_RANGE), no "blast" will be induced.  This
6753  * may be relevant even for bolts, since they have a "1x1" mini-blast.
6754  *
6755  * Note that for consistency, we "pretend" that the bolt actually takes "time"
6756  * to move from point A to point B, even if the player cannot see part of the
6757  * projection path.  Note that in general, the player will *always* see part
6758  * of the path, since it either starts at the player or ends on the player.
6759  *
6760  * Hack -- we assume that every "projection" is "self-illuminating".
6761  *
6762  * Hack -- when only a single monster is affected, we automatically track
6763  * (and recall) that monster, unless "PROJECT_JUMP" is used.
6764  *
6765  * Note that all projections now "explode" at their final destination, even
6766  * if they were being projected at a more distant destination.  This means
6767  * that "ball" spells will *always* explode.
6768  *
6769  * Note that we must call "handle_stuff()" after affecting terrain features
6770  * in the blast radius, in case the "illumination" of the grid was changed,
6771  * and "update_view()" and "update_monsters()" need to be called.
6772  * </pre>
6773  */
6774 bool project(int who, int rad, int y, int x, int dam, int typ, int flg, int monspell)
6775 {
6776         int i, t, dist;
6777
6778         int y1, x1;
6779         int y2, x2;
6780         int by, bx;
6781
6782         int dist_hack = 0;
6783
6784         int y_saver, x_saver; /* For reflecting monsters */
6785
6786         int msec = delay_factor * delay_factor * delay_factor;
6787
6788         /* Assume the player sees nothing */
6789         bool notice = FALSE;
6790
6791         /* Assume the player has seen nothing */
6792         bool visual = FALSE;
6793
6794         /* Assume the player has seen no blast grids */
6795         bool drawn = FALSE;
6796
6797         /* Assume to be a normal ball spell */
6798         bool breath = FALSE;
6799
6800         /* Is the player blind? */
6801         bool blind = (p_ptr->blind ? TRUE : FALSE);
6802
6803         bool old_hide = FALSE;
6804
6805         /* Number of grids in the "path" */
6806         int path_n = 0;
6807
6808         /* Actual grids in the "path" */
6809         u16b path_g[512];
6810
6811         /* Number of grids in the "blast area" (including the "beam" path) */
6812         int grids = 0;
6813
6814         /* Coordinates of the affected grids */
6815         byte gx[1024], gy[1024];
6816
6817         /* Encoded "radius" info (see above) */
6818         byte gm[32];
6819
6820         /* Actual radius encoded in gm[] */
6821         int gm_rad = rad;
6822
6823         bool jump = FALSE;
6824
6825         /* Attacker's name (prepared before polymorph)*/
6826         char who_name[80];
6827
6828         /* Can the player see the source of this effect? */
6829         bool see_s_msg = TRUE;
6830
6831         /* Initialize by null string */
6832         who_name[0] = '\0';
6833
6834         rakubadam_p = 0;
6835         rakubadam_m = 0;
6836
6837         /* Default target of monsterspell is player */
6838         monster_target_y=p_ptr->y;
6839         monster_target_x=p_ptr->x;
6840
6841         /* Hack -- Jump to target */
6842         if (flg & (PROJECT_JUMP))
6843         {
6844                 x1 = x;
6845                 y1 = y;
6846
6847                 /* Clear the flag */
6848                 flg &= ~(PROJECT_JUMP);
6849
6850                 jump = TRUE;
6851         }
6852
6853         /* Start at player */
6854         else if (who <= 0)
6855         {
6856                 x1 = p_ptr->x;
6857                 y1 = p_ptr->y;
6858         }
6859
6860         /* Start at monster */
6861         else if (who > 0)
6862         {
6863                 x1 = m_list[who].fx;
6864                 y1 = m_list[who].fy;
6865                 monster_desc(who_name, &m_list[who], MD_IGNORE_HALLU | MD_ASSUME_VISIBLE | MD_INDEF_VISIBLE);
6866         }
6867
6868         /* Oops */
6869         else
6870         {
6871                 x1 = x;
6872                 y1 = y;
6873         }
6874
6875         y_saver = y1;
6876         x_saver = x1;
6877
6878         /* Default "destination" */
6879         y2 = y;
6880         x2 = x;
6881
6882
6883         /* Hack -- verify stuff */
6884         if (flg & (PROJECT_THRU))
6885         {
6886                 if ((x1 == x2) && (y1 == y2))
6887                 {
6888                         flg &= ~(PROJECT_THRU);
6889                 }
6890         }
6891
6892         /* Handle a breath attack */
6893         if (rad < 0)
6894         {
6895                 rad = 0 - rad;
6896                 breath = TRUE;
6897                 if (flg & PROJECT_HIDE) old_hide = TRUE;
6898                 flg |= PROJECT_HIDE;
6899         }
6900
6901
6902         /* Hack -- Assume there will be no blast (max radius 32) */
6903         for (dist = 0; dist < 32; dist++) gm[dist] = 0;
6904
6905
6906         /* Initial grid */
6907         y = y1;
6908         x = x1;
6909         dist = 0;
6910
6911         /* Collect beam grids */
6912         if (flg & (PROJECT_BEAM))
6913         {
6914                 gy[grids] = y;
6915                 gx[grids] = x;
6916                 grids++;
6917         }
6918
6919         switch (typ)
6920         {
6921         case GF_LITE:
6922         case GF_LITE_WEAK:
6923                 if (breath || (flg & PROJECT_BEAM)) flg |= (PROJECT_LOS);
6924                 break;
6925         case GF_DISINTEGRATE:
6926                 flg |= (PROJECT_GRID);
6927                 if (breath || (flg & PROJECT_BEAM)) flg |= (PROJECT_DISI);
6928                 break;
6929         }
6930
6931         /* Calculate the projection path */
6932
6933         path_n = project_path(path_g, (project_length ? project_length : MAX_RANGE), y1, x1, y2, x2, flg);
6934
6935         /* Hack -- Handle stuff */
6936         handle_stuff();
6937
6938         /* Giga-Hack SEEKER & SUPER_RAY */
6939
6940         if( typ == GF_SEEKER )
6941         {
6942                 int j;
6943                 int last_i=0;
6944
6945                 /* Mega-Hack */
6946                 project_m_n = 0;
6947                 project_m_x = 0;
6948                 project_m_y = 0;
6949
6950                 for (i = 0; i < path_n; ++i)
6951                 {
6952                         int oy = y;
6953                         int ox = x;
6954
6955                         int ny = GRID_Y(path_g[i]);
6956                         int nx = GRID_X(path_g[i]);
6957
6958                         /* Advance */
6959                         y = ny;
6960                         x = nx;
6961
6962                         gy[grids] = y;
6963                         gx[grids] = x;
6964                         grids++;
6965
6966
6967                         /* Only do visuals if requested */
6968                         if (!blind && !(flg & (PROJECT_HIDE)))
6969                         {
6970                                 /* Only do visuals if the player can "see" the bolt */
6971                                 if (panel_contains(y, x) && player_has_los_bold(y, x))
6972                                 {
6973                                         u16b p;
6974
6975                                         byte a;
6976                                         char c;
6977
6978                                         /* Obtain the bolt pict */
6979                                         p = bolt_pict(oy, ox, y, x, typ);
6980
6981                                         /* Extract attr/char */
6982                                         a = PICT_A(p);
6983                                         c = PICT_C(p);
6984
6985                                         /* Visual effects */
6986                                         print_rel(c, a, y, x);
6987                                         move_cursor_relative(y, x);
6988                                         /*if (fresh_before)*/ Term_fresh();
6989                                         Term_xtra(TERM_XTRA_DELAY, msec);
6990                                         lite_spot(y, x);
6991                                         /*if (fresh_before)*/ Term_fresh();
6992
6993                                         /* Display "beam" grids */
6994                                         if (flg & (PROJECT_BEAM))
6995                                         {
6996                                                 /* Obtain the explosion pict */
6997                                                 p = bolt_pict(y, x, y, x, typ);
6998
6999                                                 /* Extract attr/char */
7000                                                 a = PICT_A(p);
7001                                                 c = PICT_C(p);
7002
7003                                                 /* Visual effects */
7004                                                 print_rel(c, a, y, x);
7005                                         }
7006
7007                                         /* Hack -- Activate delay */
7008                                         visual = TRUE;
7009                                 }
7010
7011                                 /* Hack -- delay anyway for consistency */
7012                                 else if (visual)
7013                                 {
7014                                         /* Delay for consistency */
7015                                         Term_xtra(TERM_XTRA_DELAY, msec);
7016                                 }
7017                         }
7018                         if(project_o(0,0,y,x,dam,GF_SEEKER))notice=TRUE;
7019                         if( is_mirror_grid(&cave[y][x]))
7020                         {
7021                           /* The target of monsterspell becomes tha mirror(broken) */
7022                                 monster_target_y=(s16b)y;
7023                                 monster_target_x=(s16b)x;
7024
7025                                 remove_mirror(y, x);
7026                                 next_mirror(&oy, &ox, y, x);
7027
7028                                 path_n = i+project_path(&(path_g[i+1]), (project_length ? project_length : MAX_RANGE), y, x, oy, ox, flg);
7029                                 for(j = last_i; j <= i; j++)
7030                                 {
7031                                         y = GRID_Y(path_g[j]);
7032                                         x = GRID_X(path_g[j]);
7033                                         if(project_m(0,0,y,x,dam,GF_SEEKER,flg,TRUE))notice=TRUE;
7034                                         if(!who && (project_m_n==1) && !jump ){
7035                                           if(cave[project_m_y][project_m_x].m_idx >0 ){
7036                                             monster_type *m_ptr = &m_list[cave[project_m_y][project_m_x].m_idx];
7037
7038                                             if (m_ptr->ml)
7039                                             {
7040                                               /* Hack -- auto-recall */
7041                                               if (!p_ptr->image) monster_race_track(m_ptr->ap_r_idx);
7042
7043                                               /* Hack - auto-track */
7044                                               health_track(cave[project_m_y][project_m_x].m_idx);
7045                                             }
7046                                           }
7047                                         }
7048                                         (void)project_f(0,0,y,x,dam,GF_SEEKER);
7049                                 }
7050                                 last_i = i;
7051                         }
7052                 }
7053                 for(i = last_i ; i < path_n ; i++)
7054                 {
7055                         int py, px;
7056                         py = GRID_Y(path_g[i]);
7057                         px = GRID_X(path_g[i]);
7058                         if(project_m(0, 0, py, px, dam, GF_SEEKER, flg, TRUE))
7059                                 notice = TRUE;
7060                         if(!who && (project_m_n==1) && !jump ){
7061                                 if(cave[project_m_y][project_m_x].m_idx > 0)
7062                                 {
7063                                         monster_type *m_ptr = &m_list[cave[project_m_y][project_m_x].m_idx];
7064
7065                                         if (m_ptr->ml)
7066                                         {
7067                                                 /* Hack -- auto-recall */
7068                                                 if (!p_ptr->image) monster_race_track(m_ptr->ap_r_idx);
7069
7070                                                 /* Hack - auto-track */
7071                                                 health_track(cave[project_m_y][project_m_x].m_idx);
7072                                         }
7073                                 }
7074                         }
7075                         (void)project_f(0, 0, py, px, dam, GF_SEEKER);
7076                 }
7077                 return notice;
7078         }
7079         else if(typ == GF_SUPER_RAY){
7080                 int j;
7081                 int second_step = 0;
7082
7083                 /* Mega-Hack */
7084                 project_m_n = 0;
7085                 project_m_x = 0;
7086                 project_m_y = 0;
7087
7088                 for (i = 0; i < path_n; ++i)
7089                 {
7090                         int oy = y;
7091                         int ox = x;
7092
7093                         int ny = GRID_Y(path_g[i]);
7094                         int nx = GRID_X(path_g[i]);
7095
7096                         /* Advance */
7097                         y = ny;
7098                         x = nx;
7099
7100                         gy[grids] = y;
7101                         gx[grids] = x;
7102                         grids++;
7103
7104
7105                         /* Only do visuals if requested */
7106                         if (!blind && !(flg & (PROJECT_HIDE)))
7107                         {
7108                                 /* Only do visuals if the player can "see" the bolt */
7109                                 if (panel_contains(y, x) && player_has_los_bold(y, x))
7110                                 {
7111                                         u16b p;
7112
7113                                         byte a;
7114                                         char c;
7115
7116                                         /* Obtain the bolt pict */
7117                                         p = bolt_pict(oy, ox, y, x, typ);
7118
7119                                         /* Extract attr/char */
7120                                         a = PICT_A(p);
7121                                         c = PICT_C(p);
7122
7123                                         /* Visual effects */
7124                                         print_rel(c, a, y, x);
7125                                         move_cursor_relative(y, x);
7126                                         /*if (fresh_before)*/ Term_fresh();
7127                                         Term_xtra(TERM_XTRA_DELAY, msec);
7128                                         lite_spot(y, x);
7129                                         /*if (fresh_before)*/ Term_fresh();
7130
7131                                         /* Display "beam" grids */
7132                                         if (flg & (PROJECT_BEAM))
7133                                         {
7134                                                 /* Obtain the explosion pict */
7135                                                 p = bolt_pict(y, x, y, x, typ);
7136
7137                                                 /* Extract attr/char */
7138                                                 a = PICT_A(p);
7139                                                 c = PICT_C(p);
7140
7141                                                 /* Visual effects */
7142                                                 print_rel(c, a, y, x);
7143                                         }
7144
7145                                         /* Hack -- Activate delay */
7146                                         visual = TRUE;
7147                                 }
7148
7149                                 /* Hack -- delay anyway for consistency */
7150                                 else if (visual)
7151                                 {
7152                                         /* Delay for consistency */
7153                                         Term_xtra(TERM_XTRA_DELAY, msec);
7154                                 }
7155                         }
7156                         if(project_o(0,0,y,x,dam,GF_SUPER_RAY) )notice=TRUE;
7157                         if (!cave_have_flag_bold(y, x, FF_PROJECT))
7158                         {
7159                                 if( second_step )continue;
7160                                 break;
7161                         }
7162                         if( is_mirror_grid(&cave[y][x]) && !second_step )
7163                         {
7164                           /* The target of monsterspell becomes tha mirror(broken) */
7165                                 monster_target_y=(s16b)y;
7166                                 monster_target_x=(s16b)x;
7167
7168                                 remove_mirror(y,x);
7169                                 for( j = 0; j <=i ; j++ )
7170                                 {
7171                                         y = GRID_Y(path_g[j]);
7172                                         x = GRID_X(path_g[j]);
7173                                         (void)project_f(0,0,y,x,dam,GF_SUPER_RAY);
7174                                 }
7175                                 path_n = i;
7176                                 second_step =i+1;
7177                                 path_n += project_path(&(path_g[path_n+1]), (project_length ? project_length : MAX_RANGE), y, x, y-1, x-1, flg);
7178                                 path_n += project_path(&(path_g[path_n+1]), (project_length ? project_length : MAX_RANGE), y, x, y-1, x  , flg);
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  , x-1, flg);
7181                                 path_n += project_path(&(path_g[path_n+1]), (project_length ? project_length : MAX_RANGE), y, x, y  , x+1, flg);
7182                                 path_n += project_path(&(path_g[path_n+1]), (project_length ? project_length : MAX_RANGE), y, x, y+1, x-1, flg);
7183                                 path_n += project_path(&(path_g[path_n+1]), (project_length ? project_length : MAX_RANGE), y, x, y+1, x  , 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                         }
7186                 }
7187                 for( i = 0; i < path_n ; i++ )
7188                 {
7189                         int py, px;
7190                         py = GRID_Y(path_g[i]);
7191                         px = GRID_X(path_g[i]);
7192                         (void)project_m(0, 0, py, px, dam, GF_SUPER_RAY, flg, TRUE);
7193                         if(!who && (project_m_n == 1) && !jump){
7194                                 if(cave[project_m_y][project_m_x].m_idx >0 ){
7195                                         monster_type *m_ptr = &m_list[cave[project_m_y][project_m_x].m_idx];
7196
7197                                         if (m_ptr->ml)
7198                                         {
7199                                                 /* Hack -- auto-recall */
7200                                                 if (!p_ptr->image) monster_race_track(m_ptr->ap_r_idx);
7201
7202                                                 /* Hack - auto-track */
7203                                                 health_track(cave[project_m_y][project_m_x].m_idx);
7204                                         }
7205                                 }
7206                         }
7207                         (void)project_f(0, 0, py, px, dam, GF_SUPER_RAY);
7208                 }
7209                 return notice;
7210         }
7211
7212         /* Project along the path */
7213         for (i = 0; i < path_n; ++i)
7214         {
7215                 int oy = y;
7216                 int ox = x;
7217
7218                 int ny = GRID_Y(path_g[i]);
7219                 int nx = GRID_X(path_g[i]);
7220
7221                 if (flg & PROJECT_DISI)
7222                 {
7223                         /* Hack -- Balls explode before reaching walls */
7224                         if (cave_stop_disintegration(ny, nx) && (rad > 0)) break;
7225                 }
7226                 else if (flg & PROJECT_LOS)
7227                 {
7228                         /* Hack -- Balls explode before reaching walls */
7229                         if (!cave_los_bold(ny, nx) && (rad > 0)) break;
7230                 }
7231                 else
7232                 {
7233                         /* Hack -- Balls explode before reaching walls */
7234                         if (!cave_have_flag_bold(ny, nx, FF_PROJECT) && (rad > 0)) break;
7235                 }
7236
7237                 /* Advance */
7238                 y = ny;
7239                 x = nx;
7240
7241                 /* Collect beam grids */
7242                 if (flg & (PROJECT_BEAM))
7243                 {
7244                         gy[grids] = y;
7245                         gx[grids] = x;
7246                         grids++;
7247                 }
7248
7249                 /* Only do visuals if requested */
7250                 if (!blind && !(flg & (PROJECT_HIDE | PROJECT_FAST)))
7251                 {
7252                         /* Only do visuals if the player can "see" the bolt */
7253                         if (panel_contains(y, x) && player_has_los_bold(y, x))
7254                         {
7255                                 u16b p;
7256
7257                                 byte a;
7258                                 char c;
7259
7260                                 /* Obtain the bolt pict */
7261                                 p = bolt_pict(oy, ox, y, x, typ);
7262
7263                                 /* Extract attr/char */
7264                                 a = PICT_A(p);
7265                                 c = PICT_C(p);
7266
7267                                 /* Visual effects */
7268                                 print_rel(c, a, y, x);
7269                                 move_cursor_relative(y, x);
7270                                 /*if (fresh_before)*/ Term_fresh();
7271                                 Term_xtra(TERM_XTRA_DELAY, msec);
7272                                 lite_spot(y, x);
7273                                 /*if (fresh_before)*/ Term_fresh();
7274
7275                                 /* Display "beam" grids */
7276                                 if (flg & (PROJECT_BEAM))
7277                                 {
7278                                         /* Obtain the explosion pict */
7279                                         p = bolt_pict(y, x, y, x, typ);
7280
7281                                         /* Extract attr/char */
7282                                         a = PICT_A(p);
7283                                         c = PICT_C(p);
7284
7285                                         /* Visual effects */
7286                                         print_rel(c, a, y, x);
7287                                 }
7288
7289                                 /* Hack -- Activate delay */
7290                                 visual = TRUE;
7291                         }
7292
7293                         /* Hack -- delay anyway for consistency */
7294                         else if (visual)
7295                         {
7296                                 /* Delay for consistency */
7297                                 Term_xtra(TERM_XTRA_DELAY, msec);
7298                         }
7299                 }
7300         }
7301
7302         path_n = i;
7303
7304         /* Save the "blast epicenter" */
7305         by = y;
7306         bx = x;
7307
7308         if (breath && !path_n)
7309         {
7310                 breath = FALSE;
7311                 gm_rad = rad;
7312                 if (!old_hide)
7313                 {
7314                         flg &= ~(PROJECT_HIDE);
7315                 }
7316         }
7317
7318         /* Start the "explosion" */
7319         gm[0] = 0;
7320
7321         /* Hack -- make sure beams get to "explode" */
7322         gm[1] = grids;
7323
7324         dist = path_n;
7325         dist_hack = dist;
7326
7327         project_length = 0;
7328
7329         /* If we found a "target", explode there */
7330         if (dist <= MAX_RANGE)
7331         {
7332                 /* Mega-Hack -- remove the final "beam" grid */
7333                 if ((flg & (PROJECT_BEAM)) && (grids > 0)) grids--;
7334
7335                 /*
7336                  * Create a conical breath attack
7337                  *
7338                  *         ***
7339                  *     ********
7340                  * D********@**
7341                  *     ********
7342                  *         ***
7343                  */
7344
7345                 if (breath)
7346                 {
7347                         flg &= ~(PROJECT_HIDE);
7348
7349                         breath_shape(path_g, dist, &grids, gx, gy, gm, &gm_rad, rad, y1, x1, by, bx, typ);
7350                 }
7351                 else
7352                 {
7353                         /* Determine the blast area, work from the inside out */
7354                         for (dist = 0; dist <= rad; dist++)
7355                         {
7356                                 /* Scan the maximal blast area of radius "dist" */
7357                                 for (y = by - dist; y <= by + dist; y++)
7358                                 {
7359                                         for (x = bx - dist; x <= bx + dist; x++)
7360                                         {
7361                                                 /* Ignore "illegal" locations */
7362                                                 if (!in_bounds2(y, x)) continue;
7363
7364                                                 /* Enforce a "circular" explosion */
7365                                                 if (distance(by, bx, y, x) != dist) continue;
7366
7367                                                 switch (typ)
7368                                                 {
7369                                                 case GF_LITE:
7370                                                 case GF_LITE_WEAK:
7371                                                         /* Lights are stopped by opaque terrains */
7372                                                         if (!los(by, bx, y, x)) continue;
7373                                                         break;
7374                                                 case GF_DISINTEGRATE:
7375                                                         /* Disintegration are stopped only by perma-walls */
7376                                                         if (!in_disintegration_range(by, bx, y, x)) continue;
7377                                                         break;
7378                                                 default:
7379                                                         /* Ball explosions are stopped by walls */
7380                                                         if (!projectable(by, bx, y, x)) continue;
7381                                                         break;
7382                                                 }
7383
7384                                                 /* Save this grid */
7385                                                 gy[grids] = y;
7386                                                 gx[grids] = x;
7387                                                 grids++;
7388                                         }
7389                                 }
7390
7391                                 /* Encode some more "radius" info */
7392                                 gm[dist+1] = grids;
7393                         }
7394                 }
7395         }
7396
7397         /* Speed -- ignore "non-explosions" */
7398         if (!grids) return (FALSE);
7399
7400
7401         /* Display the "blast area" if requested */
7402         if (!blind && !(flg & (PROJECT_HIDE)))
7403         {
7404                 /* Then do the "blast", from inside out */
7405                 for (t = 0; t <= gm_rad; t++)
7406                 {
7407                         /* Dump everything with this radius */
7408                         for (i = gm[t]; i < gm[t+1]; i++)
7409                         {
7410                                 /* Extract the location */
7411                                 y = gy[i];
7412                                 x = gx[i];
7413
7414                                 /* Only do visuals if the player can "see" the blast */
7415                                 if (panel_contains(y, x) && player_has_los_bold(y, x))
7416                                 {
7417                                         u16b p;
7418
7419                                         byte a;
7420                                         char c;
7421
7422                                         drawn = TRUE;
7423
7424                                         /* Obtain the explosion pict */
7425                                         p = bolt_pict(y, x, y, x, typ);
7426
7427                                         /* Extract attr/char */
7428                                         a = PICT_A(p);
7429                                         c = PICT_C(p);
7430
7431                                         /* Visual effects -- Display */
7432                                         print_rel(c, a, y, x);
7433                                 }
7434                         }
7435
7436                         /* Hack -- center the cursor */
7437                         move_cursor_relative(by, bx);
7438
7439                         /* Flush each "radius" seperately */
7440                         /*if (fresh_before)*/ Term_fresh();
7441
7442                         /* Delay (efficiently) */
7443                         if (visual || drawn)
7444                         {
7445                                 Term_xtra(TERM_XTRA_DELAY, msec);
7446                         }
7447                 }
7448
7449                 /* Flush the erasing */
7450                 if (drawn)
7451                 {
7452                         /* Erase the explosion drawn above */
7453                         for (i = 0; i < grids; i++)
7454                         {
7455                                 /* Extract the location */
7456                                 y = gy[i];
7457                                 x = gx[i];
7458
7459                                 /* Hack -- Erase if needed */
7460                                 if (panel_contains(y, x) && player_has_los_bold(y, x))
7461                                 {
7462                                         lite_spot(y, x);
7463                                 }
7464                         }
7465
7466                         /* Hack -- center the cursor */
7467                         move_cursor_relative(by, bx);
7468
7469                         /* Flush the explosion */
7470                         /*if (fresh_before)*/ Term_fresh();
7471                 }
7472         }
7473
7474
7475         /* Update stuff if needed */
7476         if (p_ptr->update) update_stuff();
7477
7478
7479         if (flg & PROJECT_KILL)
7480         {
7481                 see_s_msg = (who > 0) ? is_seen(&m_list[who]) :
7482                         (!who ? TRUE : (player_can_see_bold(y1, x1) && projectable(p_ptr->y, p_ptr->x, y1, x1)));
7483         }
7484
7485
7486         /* Check features */
7487         if (flg & (PROJECT_GRID))
7488         {
7489                 /* Start with "dist" of zero */
7490                 dist = 0;
7491
7492                 /* Scan for features */
7493                 for (i = 0; i < grids; i++)
7494                 {
7495                         /* Hack -- Notice new "dist" values */
7496                         if (gm[dist+1] == i) dist++;
7497
7498                         /* Get the grid location */
7499                         y = gy[i];
7500                         x = gx[i];
7501
7502                         /* Find the closest point in the blast */
7503                         if (breath)
7504                         {
7505                                 int d = dist_to_line(y, x, y1, x1, by, bx);
7506
7507                                 /* Affect the grid */
7508                                 if (project_f(who, d, y, x, dam, typ)) notice = TRUE;
7509                         }
7510                         else
7511                         {
7512                                 /* Affect the grid */
7513                                 if (project_f(who, dist, y, x, dam, typ)) notice = TRUE;
7514                         }
7515                 }
7516         }
7517
7518         /* Update stuff if needed */
7519         if (p_ptr->update) update_stuff();
7520
7521         /* Check objects */
7522         if (flg & (PROJECT_ITEM))
7523         {
7524                 /* Start with "dist" of zero */
7525                 dist = 0;
7526
7527                 /* Scan for objects */
7528                 for (i = 0; i < grids; i++)
7529                 {
7530                         /* Hack -- Notice new "dist" values */
7531                         if (gm[dist+1] == i) dist++;
7532
7533                         /* Get the grid location */
7534                         y = gy[i];
7535                         x = gx[i];
7536
7537                         /* Find the closest point in the blast */
7538                         if (breath)
7539                         {
7540                                 int d = dist_to_line(y, x, y1, x1, by, bx);
7541
7542                                 /* Affect the object in the grid */
7543                                 if (project_o(who, d, y, x, dam, typ)) notice = TRUE;
7544                         }
7545                         else
7546                         {
7547                                 /* Affect the object in the grid */
7548                                 if (project_o(who, dist, y, x, dam, typ)) notice = TRUE;
7549                         }
7550                 }
7551         }
7552
7553
7554         /* Check monsters */
7555         if (flg & (PROJECT_KILL))
7556         {
7557                 /* Mega-Hack */
7558                 project_m_n = 0;
7559                 project_m_x = 0;
7560                 project_m_y = 0;
7561
7562                 /* Start with "dist" of zero */
7563                 dist = 0;
7564
7565                 /* Scan for monsters */
7566                 for (i = 0; i < grids; i++)
7567                 {
7568                         int effective_dist;
7569
7570                         /* Hack -- Notice new "dist" values */
7571                         if (gm[dist + 1] == i) dist++;
7572
7573                         /* Get the grid location */
7574                         y = gy[i];
7575                         x = gx[i];
7576
7577                         /* A single bolt may be reflected */
7578                         if (grids <= 1)
7579                         {
7580                                 monster_type *m_ptr = &m_list[cave[y][x].m_idx];
7581                                 monster_race *ref_ptr = &r_info[m_ptr->r_idx];
7582
7583                                 if ((flg & PROJECT_REFLECTABLE) && cave[y][x].m_idx && (ref_ptr->flags2 & RF2_REFLECTING) &&
7584                                     ((cave[y][x].m_idx != p_ptr->riding) || !(flg & PROJECT_PLAYER)) &&
7585                                     (!who || dist_hack > 1) && !one_in_(10))
7586                                 {
7587                                         byte t_y, t_x;
7588                                         int max_attempts = 10;
7589
7590                                         /* Choose 'new' target */
7591                                         do
7592                                         {
7593                                                 t_y = y_saver - 1 + randint1(3);
7594                                                 t_x = x_saver - 1 + randint1(3);
7595                                                 max_attempts--;
7596                                         }
7597                                         while (max_attempts && in_bounds2u(t_y, t_x) && !projectable(y, x, t_y, t_x));
7598
7599                                         if (max_attempts < 1)
7600                                         {
7601                                                 t_y = y_saver;
7602                                                 t_x = x_saver;
7603                                         }
7604
7605                                         if (is_seen(m_ptr))
7606                                         {
7607                                                 if ((m_ptr->r_idx == MON_KENSHIROU) || (m_ptr->r_idx == MON_RAOU))
7608                             msg_print(_("「北斗神拳奥義・二指真空把!」", "The attack bounces!"));
7609                                                 else if (m_ptr->r_idx == MON_DIO) 
7610                             msg_print(_("ディオ・ブランドーは指一本で攻撃を弾き返した!", "The attack bounces!"));
7611                                                 else 
7612                             msg_print(_("攻撃は跳ね返った!", "The attack bounces!"));
7613                                         }
7614                                         if (is_original_ap_and_seen(m_ptr)) ref_ptr->r_flags2 |= RF2_REFLECTING;
7615
7616                                         /* Reflected bolts randomly target either one */
7617                                         if (player_bold(y, x) || one_in_(2)) flg &= ~(PROJECT_PLAYER);
7618                                         else flg |= PROJECT_PLAYER;
7619
7620                                         /* The bolt is reflected */
7621                                         project(cave[y][x].m_idx, 0, t_y, t_x, dam, typ, flg, monspell);
7622
7623                                         /* Don't affect the monster any longer */
7624                                         continue;
7625                                 }
7626                         }
7627
7628
7629                         /* Find the closest point in the blast */
7630                         if (breath)
7631                         {
7632                                 effective_dist = dist_to_line(y, x, y1, x1, by, bx);
7633                         }
7634                         else
7635                         {
7636                                 effective_dist = dist;
7637                         }
7638
7639
7640                         /* There is the riding player on this monster */
7641                         if (p_ptr->riding && player_bold(y, x))
7642                         {
7643                                 /* Aimed on the player */
7644                                 if (flg & PROJECT_PLAYER)
7645                                 {
7646                                         if (flg & (PROJECT_BEAM | PROJECT_REFLECTABLE | PROJECT_AIMED))
7647                                         {
7648                                                 /*
7649                                                  * A beam or bolt is well aimed
7650                                                  * at the PLAYER!
7651                                                  * So don't affects the mount.
7652                                                  */
7653                                                 continue;
7654                                         }
7655                                         else
7656                                         {
7657                                                 /*
7658                                                  * The spell is not well aimed, 
7659                                                  * So partly affect the mount too.
7660                                                  */
7661                                                 effective_dist++;
7662                                         }
7663                                 }
7664
7665                                 /*
7666                                  * This grid is the original target.
7667                                  * Or aimed on your horse.
7668                                  */
7669                                 else if (((y == y2) && (x == x2)) || (flg & PROJECT_AIMED))
7670                                 {
7671                                         /* Hit the mount with full damage */
7672                                 }
7673
7674                                 /*
7675                                  * Otherwise this grid is not the
7676                                  * original target, it means that line
7677                                  * of fire is obstructed by this
7678                                  * monster.
7679                                  */
7680                                 /*
7681                                  * A beam or bolt will hit either
7682                                  * player or mount.  Choose randomly.
7683                                  */
7684                                 else if (flg & (PROJECT_BEAM | PROJECT_REFLECTABLE))
7685                                 {
7686                                         if (one_in_(2))
7687                                         {
7688                                                 /* Hit the mount with full damage */
7689                                         }
7690                                         else
7691                                         {
7692                                                 /* Hit the player later */
7693                                                 flg |= PROJECT_PLAYER;
7694
7695                                                 /* Don't affect the mount */
7696                                                 continue;
7697                                         }
7698                                 }
7699
7700                                 /*
7701                                  * The spell is not well aimed, so
7702                                  * partly affect both player and
7703                                  * mount.
7704                                  */
7705                                 else
7706                                 {
7707                                         effective_dist++;
7708                                 }
7709                         }
7710
7711                         /* Affect the monster in the grid */
7712                         if (project_m(who, effective_dist, y, x, dam, typ, flg, see_s_msg)) notice = TRUE;
7713                 }
7714
7715
7716                 /* Player affected one monster (without "jumping") */
7717                 if (!who && (project_m_n == 1) && !jump)
7718                 {
7719                         /* Location */
7720                         x = project_m_x;
7721                         y = project_m_y;
7722
7723                         /* Track if possible */
7724                         if (cave[y][x].m_idx > 0)
7725                         {
7726                                 monster_type *m_ptr = &m_list[cave[y][x].m_idx];
7727
7728                                 if (m_ptr->ml)
7729                                 {
7730                                         /* Hack -- auto-recall */
7731                                         if (!p_ptr->image) monster_race_track(m_ptr->ap_r_idx);
7732
7733                                         /* Hack - auto-track */
7734                                         if (m_ptr->ml) health_track(cave[y][x].m_idx);
7735                                 }
7736                         }
7737                 }
7738         }
7739
7740
7741         /* Check player */
7742         if (flg & (PROJECT_KILL))
7743         {
7744                 /* Start with "dist" of zero */
7745                 dist = 0;
7746
7747                 /* Scan for player */
7748                 for (i = 0; i < grids; i++)
7749                 {
7750                         int effective_dist;
7751
7752                         /* Hack -- Notice new "dist" values */
7753                         if (gm[dist+1] == i) dist++;
7754
7755                         /* Get the grid location */
7756                         y = gy[i];
7757                         x = gx[i];
7758
7759                         /* Affect the player? */
7760                         if (!player_bold(y, x)) continue;
7761
7762                         /* Find the closest point in the blast */
7763                         if (breath)
7764                         {
7765                                 effective_dist = dist_to_line(y, x, y1, x1, by, bx);
7766                         }
7767                         else
7768                         {
7769                                 effective_dist = dist;
7770                         }
7771
7772                         /* Target may be your horse */
7773                         if (p_ptr->riding)
7774                         {
7775                                 /* Aimed on the player */
7776                                 if (flg & PROJECT_PLAYER)
7777                                 {
7778                                         /* Hit the player with full damage */
7779                                 }
7780
7781                                 /*
7782                                  * Hack -- When this grid was not the
7783                                  * original target, a beam or bolt
7784                                  * would hit either player or mount,
7785                                  * and should be choosen randomly.
7786                                  *
7787                                  * But already choosen to hit the
7788                                  * mount at this point.
7789                                  *
7790                                  * Or aimed on your horse.
7791                                  */
7792                                 else if (flg & (PROJECT_BEAM | PROJECT_REFLECTABLE | PROJECT_AIMED))
7793                                 {
7794                                         /*
7795                                          * A beam or bolt is well aimed
7796                                          * at the mount!
7797                                          * So don't affects the player.
7798                                          */
7799                                         continue;
7800                                 }
7801                                 else
7802                                 {
7803                                         /*
7804                                          * The spell is not well aimed, 
7805                                          * So partly affect the player too.
7806                                          */
7807                                         effective_dist++;
7808                                 }
7809                         }
7810
7811                         /* Affect the player */
7812                         if (project_p(who, who_name, effective_dist, y, x, dam, typ, flg, monspell)) notice = TRUE;
7813                 }
7814         }
7815
7816         if (p_ptr->riding)
7817         {
7818                 char m_name[80];
7819
7820                 monster_desc(m_name, &m_list[p_ptr->riding], 0);
7821
7822                 if (rakubadam_m > 0)
7823                 {
7824                         if (rakuba(rakubadam_m, FALSE))
7825                         {
7826                 msg_format(_("%^sに振り落とされた!", "%^s has thrown you off!"), m_name);
7827                         }
7828                 }
7829                 if (p_ptr->riding && rakubadam_p > 0)
7830                 {
7831                         if(rakuba(rakubadam_p, FALSE))
7832                         {
7833                 msg_format(_("%^sから落ちてしまった!", "You have fallen from %s."), m_name);
7834                         }
7835                 }
7836         }
7837
7838         /* Return "something was noticed" */
7839         return (notice);
7840 }
7841
7842 /*!
7843  * @brief 鏡魔法「封魔結界」の効果処理
7844  * @param dam ダメージ量
7845  * @return 効果があったらTRUEを返す
7846  */
7847 bool binding_field( int dam )
7848 {
7849         int mirror_x[10],mirror_y[10]; /* 鏡はもっと少ない */
7850         int mirror_num=0;              /* 鏡の数 */
7851         int x,y;
7852         int centersign;
7853         int x1,x2,y1,y2;
7854         u16b p;
7855         int msec= delay_factor*delay_factor*delay_factor;
7856
7857         /* 三角形の頂点 */
7858         int point_x[3];
7859         int point_y[3];
7860
7861         /* Default target of monsterspell is player */
7862         monster_target_y=p_ptr->y;
7863         monster_target_x=p_ptr->x;
7864
7865         for( x=0 ; x < cur_wid ; x++ )
7866         {
7867                 for( y=0 ; y < cur_hgt ; y++ )
7868                 {
7869                         if( is_mirror_grid(&cave[y][x]) &&
7870                             distance(p_ptr->y,p_ptr->x,y,x) <= MAX_RANGE &&
7871                             distance(p_ptr->y,p_ptr->x,y,x) != 0 &&
7872                             player_has_los_bold(y,x) &&
7873                             projectable(p_ptr->y, p_ptr->x, y, x)
7874                             ){
7875                                 mirror_y[mirror_num]=y;
7876                                 mirror_x[mirror_num]=x;
7877                                 mirror_num++;
7878                         }
7879                 }
7880         }
7881
7882         if( mirror_num < 2 )return FALSE;
7883
7884         point_x[0] = randint0( mirror_num );
7885         do {
7886           point_x[1] = randint0( mirror_num );
7887         }
7888         while( point_x[0] == point_x[1] );
7889
7890         point_y[0]=mirror_y[point_x[0]];
7891         point_x[0]=mirror_x[point_x[0]];
7892         point_y[1]=mirror_y[point_x[1]];
7893         point_x[1]=mirror_x[point_x[1]];
7894         point_y[2]=p_ptr->y;
7895         point_x[2]=p_ptr->x;
7896
7897         x=point_x[0]+point_x[1]+point_x[2];
7898         y=point_y[0]+point_y[1]+point_y[2];
7899
7900         centersign = (point_x[0]*3-x)*(point_y[1]*3-y)
7901                 - (point_y[0]*3-y)*(point_x[1]*3-x);
7902         if( centersign == 0 )return FALSE;
7903                             
7904         x1 = point_x[0] < point_x[1] ? point_x[0] : point_x[1];
7905         x1 = x1 < point_x[2] ? x1 : point_x[2];
7906         y1 = point_y[0] < point_y[1] ? point_y[0] : point_y[1];
7907         y1 = y1 < point_y[2] ? y1 : point_y[2];
7908
7909         x2 = point_x[0] > point_x[1] ? point_x[0] : point_x[1];
7910         x2 = x2 > point_x[2] ? x2 : point_x[2];
7911         y2 = point_y[0] > point_y[1] ? point_y[0] : point_y[1];
7912         y2 = y2 > point_y[2] ? y2 : point_y[2];
7913
7914         for( y=y1 ; y <=y2 ; y++ ){
7915                 for( x=x1 ; x <=x2 ; x++ ){
7916                         if( centersign*( (point_x[0]-x)*(point_y[1]-y)
7917                                          -(point_y[0]-y)*(point_x[1]-x)) >=0 &&
7918                             centersign*( (point_x[1]-x)*(point_y[2]-y)
7919                                          -(point_y[1]-y)*(point_x[2]-x)) >=0 &&
7920                             centersign*( (point_x[2]-x)*(point_y[0]-y)
7921                                          -(point_y[2]-y)*(point_x[0]-x)) >=0 )
7922                         {
7923                                 if (player_has_los_bold(y, x) && projectable(p_ptr->y, p_ptr->x, y, x)) {
7924                                         /* Visual effects */
7925                                         if(!(p_ptr->blind)
7926                                            && panel_contains(y,x)){
7927                                           p = bolt_pict(y,x,y,x, GF_MANA );
7928                                           print_rel(PICT_C(p), PICT_A(p),y,x);
7929                                           move_cursor_relative(y, x);
7930                                           /*if (fresh_before)*/ Term_fresh();
7931                                           Term_xtra(TERM_XTRA_DELAY, msec);
7932                                         }
7933                                 }
7934                         }
7935                 }
7936         }
7937         for( y=y1 ; y <=y2 ; y++ ){
7938                 for( x=x1 ; x <=x2 ; x++ ){
7939                         if( centersign*( (point_x[0]-x)*(point_y[1]-y)
7940                                          -(point_y[0]-y)*(point_x[1]-x)) >=0 &&
7941                             centersign*( (point_x[1]-x)*(point_y[2]-y)
7942                                          -(point_y[1]-y)*(point_x[2]-x)) >=0 &&
7943                             centersign*( (point_x[2]-x)*(point_y[0]-y)
7944                                          -(point_y[2]-y)*(point_x[0]-x)) >=0 )
7945                         {
7946                                 if (player_has_los_bold(y, x) && projectable(p_ptr->y, p_ptr->x, y, x)) {
7947                                         (void)project_f(0,0,y,x,dam,GF_MANA); 
7948                                 }
7949                         }
7950                 }
7951         }
7952         for( y=y1 ; y <=y2 ; y++ ){
7953                 for( x=x1 ; x <=x2 ; x++ ){
7954                         if( centersign*( (point_x[0]-x)*(point_y[1]-y)
7955                                          -(point_y[0]-y)*(point_x[1]-x)) >=0 &&
7956                             centersign*( (point_x[1]-x)*(point_y[2]-y)
7957                                          -(point_y[1]-y)*(point_x[2]-x)) >=0 &&
7958                             centersign*( (point_x[2]-x)*(point_y[0]-y)
7959                                          -(point_y[2]-y)*(point_x[0]-x)) >=0 )
7960                         {
7961                                 if (player_has_los_bold(y, x) && projectable(p_ptr->y, p_ptr->x, y, x)) {
7962                                         (void)project_o(0,0,y,x,dam,GF_MANA); 
7963                                 }
7964                         }
7965                 }
7966         }
7967         for( y=y1 ; y <=y2 ; y++ ){
7968                 for( x=x1 ; x <=x2 ; x++ ){
7969                         if( centersign*( (point_x[0]-x)*(point_y[1]-y)
7970                                          -(point_y[0]-y)*(point_x[1]-x)) >=0 &&
7971                             centersign*( (point_x[1]-x)*(point_y[2]-y)
7972                                          -(point_y[1]-y)*(point_x[2]-x)) >=0 &&
7973                             centersign*( (point_x[2]-x)*(point_y[0]-y)
7974                                          -(point_y[2]-y)*(point_x[0]-x)) >=0 )
7975                         {
7976                                 if (player_has_los_bold(y, x) && projectable(p_ptr->y, p_ptr->x, y, x)) {
7977                                         (void)project_m(0,0,y,x,dam,GF_MANA,
7978                                           (PROJECT_GRID|PROJECT_ITEM|PROJECT_KILL|PROJECT_JUMP),TRUE);
7979                                 }
7980                         }
7981                 }
7982         }
7983         if( one_in_(7) ){
7984         msg_print(_("鏡が結界に耐えきれず、壊れてしまった。", "The field broke a mirror"));
7985                 remove_mirror(point_y[0],point_x[0]);
7986         }
7987
7988         return TRUE;
7989 }
7990
7991 /*!
7992  * @brief 鏡魔法「鏡の封印」の効果処理
7993  * @param dam ダメージ量
7994  * @return 効果があったらTRUEを返す
7995  */
7996 void seal_of_mirror( int dam )
7997 {
7998         int x,y;
7999
8000         for( x = 0 ; x < cur_wid ; x++ )
8001         {
8002                 for( y = 0 ; y < cur_hgt ; y++ )
8003                 {
8004                         if( is_mirror_grid(&cave[y][x]))
8005                         {
8006                                 if(project_m(0,0,y,x,dam,GF_GENOCIDE,
8007                                                          (PROJECT_GRID|PROJECT_ITEM|PROJECT_KILL|PROJECT_JUMP),TRUE))
8008                                 {
8009                                         if( !cave[y][x].m_idx )
8010                                         {
8011                                                 remove_mirror(y,x);
8012                                         }
8013                                 }
8014                         }
8015                 }
8016         }
8017         return;
8018 }
8019