OSDN Git Service

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