OSDN Git Service

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