OSDN Git Service

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