OSDN Git Service

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