OSDN Git Service

[Refactor] #39963 Separated effect-player-util.h from effect-player.c
[hengband/hengband.git] / src / effect / effect-player.c
1 /*!
2  * todo 単体で1000行を超えている。要分割
3  * @brief 魔法によるプレーヤーへの効果まとめ
4  * @date 2020/04/29
5  * @author Hourier
6  */
7
8 #include "angband.h"
9 #include "effect/effect-player-util.h"
10 #include "effect/effect-player.h"
11 #include "main/sound-definitions-table.h"
12 #include "player-damage.h"
13 #include "world.h"
14 #include "object-broken.h"
15 #include "artifact.h"
16 #include "player/mimic-info-table.h"
17 #include "realm/realm-hex.h"
18 #include "effect/spells-effect-util.h"
19 #include "player-move.h"
20 #include "player-effects.h"
21 #include "spells-status.h"
22 #include "monster-spell.h"
23 #include "mutation.h"
24 #include "object-curse.h"
25 #include "spell/spells-type.h"
26
27 typedef enum effect_player_check_result
28 {
29         EP_CHECK_FALSE = 0,
30         EP_CHECK_TRUE = 1,
31         EP_CHECK_CONTINUE = 2,
32 } ep_check_result;
33
34 /*!
35  * @brief effect_player_type構造体を初期化する
36  * @param ep_ptr 初期化前の構造体
37  * @param who 魔法を唱えたモンスター (0ならプレーヤー自身)
38  * @param dam 基本威力
39  * @param effect_type 効果属性
40  * @param flag 効果フラグ
41  * @param monspell 効果元のモンスター魔法ID
42  * @return 初期化後の構造体ポインタ
43  */
44 static effect_player_type *initialize_effect_player(effect_player_type *ep_ptr, MONSTER_IDX who, HIT_POINT dam, EFFECT_ID effect_type, BIT_FLAGS flag, int monspell)
45 {
46         ep_ptr->rlev = 0;
47         ep_ptr->m_ptr = NULL;
48         ep_ptr->get_damage = 0;
49         ep_ptr->who = who;
50         ep_ptr->dam = dam;
51         ep_ptr->effect_type = effect_type;
52         ep_ptr->flag = flag;
53         ep_ptr->monspell = monspell;
54         return ep_ptr;
55 }
56
57
58 /*!
59  * @brief ボルト魔法を反射する
60  * @param target_ptr プレーヤーへの参照ポインタ
61  * @param ep_ptr プレーヤー効果構造体への参照ポインタ
62  * @return 当たったらFALSE、反射したらTRUE
63  */
64 static bool process_bolt_reflection(player_type *target_ptr, effect_player_type *ep_ptr)
65 {
66         bool can_bolt_hit = target_ptr->reflect || (((target_ptr->special_defense & KATA_FUUJIN) != 0) && !target_ptr->blind);
67         can_bolt_hit &= (ep_ptr->flag & PROJECT_REFLECTABLE) != 0;
68         can_bolt_hit &= !one_in_(10);
69         if (!can_bolt_hit) return FALSE;
70
71         POSITION t_y, t_x;
72         int max_attempts = 10;
73         sound(SOUND_REFLECT);
74
75         if (target_ptr->blind)
76                 msg_print(_("何かが跳ね返った!", "Something bounces!"));
77         else if (target_ptr->special_defense & KATA_FUUJIN)
78                 msg_print(_("風の如く武器を振るって弾き返した!", "The attack bounces!"));
79         else
80                 msg_print(_("攻撃が跳ね返った!", "The attack bounces!"));
81
82         if (ep_ptr->who > 0)
83         {
84                 floor_type *floor_ptr = target_ptr->current_floor_ptr;
85                 monster_type m_type = floor_ptr->m_list[ep_ptr->who];
86                 do
87                 {
88                         t_y = m_type.fy - 1 + randint1(3);
89                         t_x = m_type.fx - 1 + randint1(3);
90                         max_attempts--;
91                 } while (max_attempts && in_bounds2u(floor_ptr, t_y, t_x) && !projectable(target_ptr, target_ptr->y, target_ptr->x, t_y, t_x));
92
93                 if (max_attempts < 1)
94                 {
95                         t_y = m_type.fy;
96                         t_x = m_type.fx;
97                 }
98         }
99         else
100         {
101                 t_y = target_ptr->y - 1 + randint1(3);
102                 t_x = target_ptr->x - 1 + randint1(3);
103         }
104
105         project(target_ptr, 0, 0, t_y, t_x, ep_ptr->dam, ep_ptr->effect_type, (PROJECT_STOP | PROJECT_KILL | PROJECT_REFLECTABLE), ep_ptr->monspell);
106         disturb(target_ptr, TRUE, TRUE);
107         return TRUE;
108 }
109
110
111 /*!
112  * @brief 反射・忍者の変わり身などでそもそも当たらない状況を判定する
113  * @param target_ptr プレーヤーへの参照ポインタ
114  * @param ep_ptr プレーヤー効果構造体への参照ポインタ
115  * @param y 目標Y座標
116  * @param x 目標X座標
117  * @return 当たらなかったらFALSE、反射したらTRUE、当たったらCONTINUE
118  */
119 static ep_check_result check_continue_player_effect(player_type *target_ptr, effect_player_type *ep_ptr, POSITION y, POSITION x)
120 {
121         if (!player_bold(target_ptr, y, x))
122                 return EP_CHECK_FALSE;
123
124         if (((target_ptr->special_defense & NINJA_KAWARIMI) != 0) &&
125                 (ep_ptr->dam > 0) &&
126                 (randint0(55) < (target_ptr->lev * 3 / 5 + 20)) &&
127                 (ep_ptr->who > 0) &&
128                 (ep_ptr->who != target_ptr->riding) &&
129                 kawarimi(target_ptr, TRUE))
130                 return EP_CHECK_FALSE;
131
132         if ((ep_ptr->who == 0) || (ep_ptr->who == target_ptr->riding))
133                 return EP_CHECK_FALSE;
134
135         if (process_bolt_reflection(target_ptr, ep_ptr))
136                 return EP_CHECK_TRUE;
137
138         return EP_CHECK_CONTINUE;
139 }
140
141
142 /*!
143  * @brief 魔法を発したモンスター名を記述する
144  * @param target_ptr プレーヤーへの参照ポインタ
145  * @param ep_ptr プレーヤー効果構造体への参照ポインタ
146  * @param who_name モンスター名
147  * @return なし
148  */
149 static void describe_effect_source(player_type *target_ptr, effect_player_type *ep_ptr, concptr who_name)
150 {
151         if (ep_ptr->who > 0)
152         {
153                 ep_ptr->m_ptr = &target_ptr->current_floor_ptr->m_list[ep_ptr->who];
154                 ep_ptr->rlev = (&r_info[ep_ptr->m_ptr->r_idx])->level >= 1 ? (&r_info[ep_ptr->m_ptr->r_idx])->level : 1;
155                 monster_desc(target_ptr, ep_ptr->m_name, ep_ptr->m_ptr, 0);
156                 strcpy(ep_ptr->killer, who_name);
157                 return;
158         }
159
160         switch (ep_ptr->who)
161         {
162         case PROJECT_WHO_UNCTRL_POWER:
163                 strcpy(ep_ptr->killer, _("制御できない力の氾流", "uncontrollable power storm"));
164                 break;
165         case PROJECT_WHO_GLASS_SHARDS:
166                 strcpy(ep_ptr->killer, _("ガラスの破片", "shards of glass"));
167                 break;
168         default:
169                 strcpy(ep_ptr->killer, _("罠", "a trap"));
170                 break;
171         }
172
173         strcpy(ep_ptr->m_name, ep_ptr->killer);
174 }
175
176
177 /*!
178  * @brief 魔法の効果によって様々なメッセーを出力したり与えるダメージの増減を行ったりする
179  * @param target_ptr プレーヤーへの参照ポインタ
180  * @param em_ptr プレーヤー効果構造体への参照ポインタ
181  * @return なし
182  */
183 void switch_effects_player(player_type *target_ptr, effect_player_type *ep_ptr)
184 {
185         switch (ep_ptr->effect_type)
186         {
187         case GF_ACID:
188         {
189                 if (target_ptr->blind) msg_print(_("酸で攻撃された!", "You are hit by acid!"));
190
191                 ep_ptr->get_damage = acid_dam(target_ptr, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell, FALSE);
192                 break;
193         }
194         case GF_FIRE:
195         {
196                 if (target_ptr->blind) msg_print(_("火炎で攻撃された!", "You are hit by fire!"));
197
198                 ep_ptr->get_damage = fire_dam(target_ptr, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell, FALSE);
199                 break;
200         }
201         case GF_COLD:
202         {
203                 if (target_ptr->blind) msg_print(_("冷気で攻撃された!", "You are hit by cold!"));
204
205                 ep_ptr->get_damage = cold_dam(target_ptr, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell, FALSE);
206                 break;
207         }
208         case GF_ELEC:
209         {
210                 if (target_ptr->blind) msg_print(_("電撃で攻撃された!", "You are hit by lightning!"));
211
212                 ep_ptr->get_damage = elec_dam(target_ptr, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell, FALSE);
213                 break;
214         }
215         case GF_POIS:
216         {
217                 bool double_resist = is_oppose_pois(target_ptr);
218                 if (target_ptr->blind) msg_print(_("毒で攻撃された!", "You are hit by poison!"));
219
220                 if (target_ptr->resist_pois) ep_ptr->dam = (ep_ptr->dam + 2) / 3;
221                 if (double_resist) ep_ptr->dam = (ep_ptr->dam + 2) / 3;
222
223                 if ((!(double_resist || target_ptr->resist_pois)) && one_in_(HURT_CHANCE) && !CHECK_MULTISHADOW(target_ptr))
224                 {
225                         do_dec_stat(target_ptr, A_CON);
226                 }
227
228                 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
229
230                 if (!(double_resist || target_ptr->resist_pois) && !CHECK_MULTISHADOW(target_ptr))
231                         set_poisoned(target_ptr, target_ptr->poisoned + randint0(ep_ptr->dam) + 10);
232
233                 break;
234         }
235         case GF_NUKE:
236         {
237                 bool double_resist = is_oppose_pois(target_ptr);
238                 if (target_ptr->blind) msg_print(_("放射能で攻撃された!", "You are hit by radiation!"));
239
240                 if (target_ptr->resist_pois) ep_ptr->dam = (2 * ep_ptr->dam + 2) / 5;
241                 if (double_resist) ep_ptr->dam = (2 * ep_ptr->dam + 2) / 5;
242                 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
243                 if ((double_resist || target_ptr->resist_pois) || CHECK_MULTISHADOW(target_ptr))
244                         break;
245
246                 set_poisoned(target_ptr, target_ptr->poisoned + randint0(ep_ptr->dam) + 10);
247
248                 if (one_in_(5)) /* 6 */
249                 {
250                         msg_print(_("奇形的な変身を遂げた!", "You undergo a freakish metamorphosis!"));
251                         if (one_in_(4)) /* 4 */
252                                 do_poly_self(target_ptr);
253                         else
254                                 status_shuffle(target_ptr);
255                 }
256
257                 if (one_in_(6))
258                 {
259                         inventory_damage(target_ptr, set_acid_destroy, 2);
260                 }
261
262                 break;
263         }
264         case GF_MISSILE:
265         {
266                 if (target_ptr->blind) msg_print(_("何かで攻撃された!", "You are hit by something!"));
267                 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
268                 break;
269         }
270         case GF_HOLY_FIRE:
271         {
272                 if (target_ptr->blind) msg_print(_("何かで攻撃された!", "You are hit by something!"));
273                 if (target_ptr->align > 10)
274                         ep_ptr->dam /= 2;
275                 else if (target_ptr->align < -10)
276                         ep_ptr->dam *= 2;
277                 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
278                 break;
279         }
280         case GF_HELL_FIRE:
281         {
282                 if (target_ptr->blind) msg_print(_("何かで攻撃された!", "You are hit by something!"));
283                 if (target_ptr->align > 10)
284                         ep_ptr->dam *= 2;
285                 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
286                 break;
287         }
288         case GF_ARROW:
289         {
290                 if (target_ptr->blind)
291                 {
292                         msg_print(_("何か鋭いもので攻撃された!", "You are hit by something sharp!"));
293                 }
294                 else if ((target_ptr->inventory_list[INVEN_RARM].name1 == ART_ZANTETSU) || (target_ptr->inventory_list[INVEN_LARM].name1 == ART_ZANTETSU))
295                 {
296                         msg_print(_("矢を斬り捨てた!", "You cut down the arrow!"));
297                         break;
298                 }
299
300                 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
301                 break;
302         }
303         case GF_PLASMA:
304         {
305                 if (target_ptr->blind) msg_print(_("何かとても熱いもので攻撃された!", "You are hit by something *HOT*!"));
306                 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
307
308                 if (!target_ptr->resist_sound && !CHECK_MULTISHADOW(target_ptr))
309                 {
310                         int plus_stun = (randint1((ep_ptr->dam > 40) ? 35 : (ep_ptr->dam * 3 / 4 + 5)));
311                         (void)set_stun(target_ptr, target_ptr->stun + plus_stun);
312                 }
313
314                 if (!(target_ptr->resist_fire || is_oppose_fire(target_ptr) || target_ptr->immune_fire))
315                 {
316                         inventory_damage(target_ptr, set_acid_destroy, 3);
317                 }
318
319                 break;
320         }
321         case GF_NETHER:
322         {
323                 if (target_ptr->blind) msg_print(_("地獄の力で攻撃された!", "You are hit by nether forces!"));
324                 if (target_ptr->resist_neth)
325                 {
326                         if (!PRACE_IS_(target_ptr, RACE_SPECTRE))
327                         {
328                                 ep_ptr->dam *= 6; ep_ptr->dam /= (randint1(4) + 7);
329                         }
330                 }
331                 else if (!CHECK_MULTISHADOW(target_ptr)) drain_exp(target_ptr, 200 + (target_ptr->exp / 100), 200 + (target_ptr->exp / 1000), 75);
332
333                 if (PRACE_IS_(target_ptr, RACE_SPECTRE) && !CHECK_MULTISHADOW(target_ptr))
334                 {
335                         msg_print(_("気分がよくなった。", "You feel invigorated!"));
336                         hp_player(target_ptr, ep_ptr->dam / 4);
337                         learn_spell(target_ptr, ep_ptr->monspell);
338                 }
339                 else
340                 {
341                         ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
342                 }
343
344                 break;
345         }
346         case GF_WATER:
347         {
348                 if (target_ptr->blind) msg_print(_("何か湿ったもので攻撃された!", "You are hit by something wet!"));
349                 if (CHECK_MULTISHADOW(target_ptr))
350                 {
351                         ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
352                         break;
353                 }
354
355                 if (!target_ptr->resist_sound && !target_ptr->resist_water)
356                 {
357                         set_stun(target_ptr, target_ptr->stun + randint1(40));
358                 }
359                 if (!target_ptr->resist_conf && !target_ptr->resist_water)
360                 {
361                         set_confused(target_ptr, target_ptr->confused + randint1(5) + 5);
362                 }
363
364                 if (one_in_(5) && !target_ptr->resist_water)
365                 {
366                         inventory_damage(target_ptr, set_cold_destroy, 3);
367                 }
368
369                 if (target_ptr->resist_water) ep_ptr->get_damage /= 4;
370
371                 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
372                 break;
373         }
374         case GF_CHAOS:
375         {
376                 if (target_ptr->blind) msg_print(_("無秩序の波動で攻撃された!", "You are hit by a wave of anarchy!"));
377                 if (target_ptr->resist_chaos)
378                 {
379                         ep_ptr->dam *= 6; ep_ptr->dam /= (randint1(4) + 7);
380                 }
381
382                 if (CHECK_MULTISHADOW(target_ptr))
383                 {
384                         ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
385                         break;
386                 }
387
388                 if (!target_ptr->resist_conf)
389                 {
390                         (void)set_confused(target_ptr, target_ptr->confused + randint0(20) + 10);
391                 }
392                 if (!target_ptr->resist_chaos)
393                 {
394                         (void)set_image(target_ptr, target_ptr->image + randint1(10));
395                         if (one_in_(3))
396                         {
397                                 msg_print(_("あなたの身体はカオスの力で捻じ曲げられた!", "Your body is twisted by chaos!"));
398                                 (void)gain_mutation(target_ptr, 0);
399                         }
400                 }
401                 if (!target_ptr->resist_neth && !target_ptr->resist_chaos)
402                 {
403                         drain_exp(target_ptr, 5000 + (target_ptr->exp / 100), 500 + (target_ptr->exp / 1000), 75);
404                 }
405
406                 if (!target_ptr->resist_chaos || one_in_(9))
407                 {
408                         inventory_damage(target_ptr, set_elec_destroy, 2);
409                         inventory_damage(target_ptr, set_fire_destroy, 2);
410                 }
411
412                 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
413                 break;
414         }
415         case GF_SHARDS:
416         {
417                 if (target_ptr->blind) msg_print(_("何か鋭いもので攻撃された!", "You are hit by something sharp!"));
418                 if (target_ptr->resist_shard)
419                 {
420                         ep_ptr->dam *= 6; ep_ptr->dam /= (randint1(4) + 7);
421                 }
422                 else if (!CHECK_MULTISHADOW(target_ptr))
423                 {
424                         (void)set_cut(target_ptr, target_ptr->cut + ep_ptr->dam);
425                 }
426
427                 if (!target_ptr->resist_shard || one_in_(13))
428                 {
429                         inventory_damage(target_ptr, set_cold_destroy, 2);
430                 }
431
432                 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
433                 break;
434         }
435         case GF_SOUND:
436         {
437                 if (target_ptr->blind) msg_print(_("轟音で攻撃された!", "You are hit by a loud noise!"));
438                 if (target_ptr->resist_sound)
439                 {
440                         ep_ptr->dam *= 5; ep_ptr->dam /= (randint1(4) + 7);
441                 }
442                 else if (!CHECK_MULTISHADOW(target_ptr))
443                 {
444                         int plus_stun = (randint1((ep_ptr->dam > 90) ? 35 : (ep_ptr->dam / 3 + 5)));
445                         (void)set_stun(target_ptr, target_ptr->stun + plus_stun);
446                 }
447
448                 if (!target_ptr->resist_sound || one_in_(13))
449                 {
450                         inventory_damage(target_ptr, set_cold_destroy, 2);
451                 }
452
453                 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
454                 break;
455         }
456         case GF_CONFUSION:
457         {
458                 if (target_ptr->blind) msg_print(_("何か混乱するもので攻撃された!", "You are hit by something puzzling!"));
459                 if (target_ptr->resist_conf)
460                 {
461                         ep_ptr->dam *= 5; ep_ptr->dam /= (randint1(4) + 7);
462                 }
463                 else if (!CHECK_MULTISHADOW(target_ptr))
464                 {
465                         (void)set_confused(target_ptr, target_ptr->confused + randint1(20) + 10);
466                 }
467                 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
468                 break;
469         }
470         case GF_DISENCHANT:
471         {
472                 if (target_ptr->blind) msg_print(_("何かさえないもので攻撃された!", "You are hit by something static!"));
473                 if (target_ptr->resist_disen)
474                 {
475                         ep_ptr->dam *= 6; ep_ptr->dam /= (randint1(4) + 7);
476                 }
477                 else if (!CHECK_MULTISHADOW(target_ptr))
478                 {
479                         (void)apply_disenchant(target_ptr, 0);
480                 }
481                 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
482                 break;
483         }
484         case GF_NEXUS:
485         {
486                 if (target_ptr->blind) msg_print(_("何か奇妙なもので攻撃された!", "You are hit by something strange!"));
487                 if (target_ptr->resist_nexus)
488                 {
489                         ep_ptr->dam *= 6; ep_ptr->dam /= (randint1(4) + 7);
490                 }
491                 else if (!CHECK_MULTISHADOW(target_ptr))
492                 {
493                         apply_nexus(ep_ptr->m_ptr, target_ptr);
494                 }
495
496                 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
497                 break;
498         }
499         case GF_FORCE:
500         {
501                 if (target_ptr->blind) msg_print(_("運動エネルギーで攻撃された!", "You are hit by kinetic force!"));
502                 if (!target_ptr->resist_sound && !CHECK_MULTISHADOW(target_ptr))
503                 {
504                         (void)set_stun(target_ptr, target_ptr->stun + randint1(20));
505                 }
506
507                 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
508                 break;
509         }
510         case GF_ROCKET:
511         {
512                 if (target_ptr->blind) msg_print(_("爆発があった!", "There is an explosion!"));
513                 if (!target_ptr->resist_sound && !CHECK_MULTISHADOW(target_ptr))
514                 {
515                         (void)set_stun(target_ptr, target_ptr->stun + randint1(20));
516                 }
517
518                 if (target_ptr->resist_shard)
519                 {
520                         ep_ptr->dam /= 2;
521                 }
522                 else if (!CHECK_MULTISHADOW(target_ptr))
523                 {
524                         (void)set_cut(target_ptr, target_ptr->cut + (ep_ptr->dam / 2));
525                 }
526
527                 if (!target_ptr->resist_shard || one_in_(12))
528                 {
529                         inventory_damage(target_ptr, set_cold_destroy, 3);
530                 }
531
532                 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
533                 break;
534         }
535         case GF_INERTIAL:
536         {
537                 if (target_ptr->blind) msg_print(_("何か遅いもので攻撃された!", "You are hit by something slow!"));
538                 if (!CHECK_MULTISHADOW(target_ptr)) (void)set_slow(target_ptr, target_ptr->slow + randint0(4) + 4, FALSE);
539
540                 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
541                 break;
542         }
543         case GF_LITE:
544         {
545                 if (target_ptr->blind) msg_print(_("何かで攻撃された!", "You are hit by something!"));
546                 if (target_ptr->resist_lite)
547                 {
548                         ep_ptr->dam *= 4; ep_ptr->dam /= (randint1(4) + 7);
549                 }
550                 else if (!target_ptr->blind && !target_ptr->resist_blind && !CHECK_MULTISHADOW(target_ptr))
551                 {
552                         (void)set_blind(target_ptr, target_ptr->blind + randint1(5) + 2);
553                 }
554
555                 if (PRACE_IS_(target_ptr, RACE_VAMPIRE) || (target_ptr->mimic_form == MIMIC_VAMPIRE))
556                 {
557                         if (!CHECK_MULTISHADOW(target_ptr)) msg_print(_("光で肉体が焦がされた!", "The light scorches your flesh!"));
558                         ep_ptr->dam *= 2;
559                 }
560                 else if (PRACE_IS_(target_ptr, RACE_S_FAIRY))
561                 {
562                         ep_ptr->dam = ep_ptr->dam * 4 / 3;
563                 }
564
565                 if (target_ptr->wraith_form) ep_ptr->dam *= 2;
566                 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
567
568                 if (!target_ptr->wraith_form || CHECK_MULTISHADOW(target_ptr))
569                         break;
570
571                 target_ptr->wraith_form = 0;
572                 msg_print(_("閃光のため非物質的な影の存在でいられなくなった。",
573                         "The light forces you out of your incorporeal shadow form."));
574
575                 target_ptr->redraw |= (PR_MAP | PR_STATUS);
576                 target_ptr->update |= (PU_MONSTERS);
577                 target_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
578                 break;
579         }
580         case GF_DARK:
581         {
582                 if (target_ptr->blind) msg_print(_("何かで攻撃された!", "You are hit by something!"));
583                 if (target_ptr->resist_dark)
584                 {
585                         ep_ptr->dam *= 4; ep_ptr->dam /= (randint1(4) + 7);
586
587                         if (PRACE_IS_(target_ptr, RACE_VAMPIRE) || (target_ptr->mimic_form == MIMIC_VAMPIRE) || target_ptr->wraith_form) ep_ptr->dam = 0;
588                 }
589                 else if (!target_ptr->blind && !target_ptr->resist_blind && !CHECK_MULTISHADOW(target_ptr))
590                 {
591                         (void)set_blind(target_ptr, target_ptr->blind + randint1(5) + 2);
592                 }
593
594                 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
595                 break;
596         }
597         case GF_TIME:
598         {
599                 if (target_ptr->blind) msg_print(_("過去からの衝撃に攻撃された!", "You are hit by a blast from the past!"));
600
601                 if (target_ptr->resist_time)
602                 {
603                         ep_ptr->dam *= 4;
604                         ep_ptr->dam /= (randint1(4) + 7);
605                         msg_print(_("時間が通り過ぎていく気がする。", "You feel as if time is passing you by."));
606                         ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
607                         break;
608                 }
609
610                 if (CHECK_MULTISHADOW(target_ptr))
611                 {
612                         ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
613                         break;
614                 }
615
616                 switch (randint1(10))
617                 {
618                 case 1:
619                 case 2:
620                 case 3:
621                 case 4:
622                 case 5:
623                 {
624                         if (target_ptr->prace == RACE_ANDROID) break;
625
626                         msg_print(_("人生が逆戻りした気がする。", "You feel like a chunk of the past has been ripped away."));
627                         lose_exp(target_ptr, 100 + (target_ptr->exp / 100) * MON_DRAIN_LIFE);
628                         break;
629                 }
630                 case 6:
631                 case 7:
632                 case 8:
633                 case 9:
634                 {
635                         int k = 0;
636                         concptr act = NULL;
637                         switch (randint1(6))
638                         {
639                         case 1: k = A_STR; act = _("強く", "strong"); break;
640                         case 2: k = A_INT; act = _("聡明で", "bright"); break;
641                         case 3: k = A_WIS; act = _("賢明で", "wise"); break;
642                         case 4: k = A_DEX; act = _("器用で", "agile"); break;
643                         case 5: k = A_CON; act = _("健康で", "hale"); break;
644                         case 6: k = A_CHR; act = _("美しく", "beautiful"); break;
645                         }
646
647                         msg_format(_("あなたは以前ほど%sなくなってしまった...。", "You're not as %s as you used to be..."), act);
648                         target_ptr->stat_cur[k] = (target_ptr->stat_cur[k] * 3) / 4;
649                         if (target_ptr->stat_cur[k] < 3) target_ptr->stat_cur[k] = 3;
650
651                         target_ptr->update |= (PU_BONUS);
652                         break;
653                 }
654                 case 10:
655                 {
656                         msg_print(_("あなたは以前ほど力強くなくなってしまった...。", "You're not as powerful as you used to be..."));
657                         for (int k = 0; k < A_MAX; k++)
658                         {
659                                 target_ptr->stat_cur[k] = (target_ptr->stat_cur[k] * 7) / 8;
660                                 if (target_ptr->stat_cur[k] < 3) target_ptr->stat_cur[k] = 3;
661                         }
662
663                         target_ptr->update |= (PU_BONUS);
664                         break;
665                 }
666                 }
667
668                 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
669                 break;
670         }
671         case GF_GRAVITY:
672         {
673                 if (target_ptr->blind) msg_print(_("何か重いもので攻撃された!", "You are hit by something heavy!"));
674                 msg_print(_("周辺の重力がゆがんだ。", "Gravity warps around you."));
675
676                 if (!CHECK_MULTISHADOW(target_ptr))
677                 {
678                         teleport_player(target_ptr, 5, TELEPORT_PASSIVE);
679                         if (!target_ptr->levitation)
680                                 (void)set_slow(target_ptr, target_ptr->slow + randint0(4) + 4, FALSE);
681                         if (!(target_ptr->resist_sound || target_ptr->levitation))
682                         {
683                                 int plus_stun = (randint1((ep_ptr->dam > 90) ? 35 : (ep_ptr->dam / 3 + 5)));
684                                 (void)set_stun(target_ptr, target_ptr->stun + plus_stun);
685                         }
686                 }
687
688                 if (target_ptr->levitation)
689                 {
690                         ep_ptr->dam = (ep_ptr->dam * 2) / 3;
691                 }
692
693                 if (!target_ptr->levitation || one_in_(13))
694                 {
695                         inventory_damage(target_ptr, set_cold_destroy, 2);
696                 }
697
698                 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
699                 break;
700         }
701         case GF_DISINTEGRATE:
702         {
703                 if (target_ptr->blind) msg_print(_("純粋なエネルギーで攻撃された!", "You are hit by pure energy!"));
704
705                 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
706                 break;
707         }
708         case GF_OLD_HEAL:
709         {
710                 if (target_ptr->blind) msg_print(_("何らかの攻撃によって気分がよくなった。", "You are hit by something invigorating!"));
711
712                 (void)hp_player(target_ptr, ep_ptr->dam);
713                 ep_ptr->dam = 0;
714                 break;
715         }
716         case GF_OLD_SPEED:
717         {
718                 if (target_ptr->blind) msg_print(_("何かで攻撃された!", "You are hit by something!"));
719                 (void)set_fast(target_ptr, target_ptr->fast + randint1(5), FALSE);
720                 ep_ptr->dam = 0;
721                 break;
722         }
723         case GF_OLD_SLOW:
724         {
725                 if (target_ptr->blind) msg_print(_("何か遅いもので攻撃された!", "You are hit by something slow!"));
726                 (void)set_slow(target_ptr, target_ptr->slow + randint0(4) + 4, FALSE);
727                 break;
728         }
729         case GF_OLD_SLEEP:
730         {
731                 if (target_ptr->free_act)  break;
732                 if (target_ptr->blind) msg_print(_("眠ってしまった!", "You fall asleep!"));
733
734                 if (ironman_nightmare)
735                 {
736                         msg_print(_("恐ろしい光景が頭に浮かんできた。", "A horrible vision enters your mind."));
737                         /* Have some nightmares */
738                         sanity_blast(target_ptr, NULL, FALSE);
739                 }
740
741                 set_paralyzed(target_ptr, target_ptr->paralyzed + ep_ptr->dam);
742                 ep_ptr->dam = 0;
743                 break;
744         }
745         case GF_MANA:
746         case GF_SEEKER:
747         case GF_SUPER_RAY:
748         {
749                 if (target_ptr->blind) msg_print(_("魔法のオーラで攻撃された!", "You are hit by an aura of magic!"));
750
751                 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
752                 break;
753         }
754         case GF_PSY_SPEAR:
755         {
756                 if (target_ptr->blind) msg_print(_("エネルギーの塊で攻撃された!", "You are hit by an energy!"));
757
758                 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_FORCE, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
759                 break;
760         }
761         case GF_METEOR:
762         {
763                 if (target_ptr->blind) msg_print(_("何かが空からあなたの頭上に落ちてきた!", "Something falls from the sky on you!"));
764
765                 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
766                 if (!target_ptr->resist_shard || one_in_(13))
767                 {
768                         if (!target_ptr->immune_fire) inventory_damage(target_ptr, set_fire_destroy, 2);
769                         inventory_damage(target_ptr, set_cold_destroy, 2);
770                 }
771
772                 break;
773         }
774         case GF_ICE:
775         {
776                 if (target_ptr->blind) msg_print(_("何か鋭く冷たいもので攻撃された!", "You are hit by something sharp and cold!"));
777
778                 ep_ptr->get_damage = cold_dam(target_ptr, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell, FALSE);
779                 if (CHECK_MULTISHADOW(target_ptr)) break;
780
781                 if (!target_ptr->resist_shard)
782                 {
783                         (void)set_cut(target_ptr, target_ptr->cut + damroll(5, 8));
784                 }
785
786                 if (!target_ptr->resist_sound)
787                 {
788                         (void)set_stun(target_ptr, target_ptr->stun + randint1(15));
789                 }
790
791                 if ((!(target_ptr->resist_cold || is_oppose_cold(target_ptr))) || one_in_(12))
792                 {
793                         if (!target_ptr->immune_cold) inventory_damage(target_ptr, set_cold_destroy, 3);
794                 }
795
796                 break;
797         }
798         case GF_DEATH_RAY:
799         {
800                 if (target_ptr->blind) msg_print(_("何か非常に冷たいもので攻撃された!", "You are hit by something extremely cold!"));
801
802                 if (target_ptr->mimic_form)
803                 {
804                         if (!(mimic_info[target_ptr->mimic_form].MIMIC_FLAGS & MIMIC_IS_NONLIVING))
805                                 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
806
807                         break;
808                 }
809
810                 switch (target_ptr->prace)
811                 {
812                 case RACE_GOLEM:
813                 case RACE_SKELETON:
814                 case RACE_ZOMBIE:
815                 case RACE_VAMPIRE:
816                 case RACE_DEMON:
817                 case RACE_SPECTRE:
818                 {
819                         ep_ptr->dam = 0;
820                         break;
821                 }
822                 default:
823                 {
824                         ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
825                         break;
826                 }
827                 }
828
829                 break;
830         }
831         case GF_DRAIN_MANA:
832         {
833                 if (CHECK_MULTISHADOW(target_ptr))
834                 {
835                         msg_print(_("攻撃は幻影に命中し、あなたには届かなかった。", "The attack hits Shadow, but you are unharmed!"));
836                         ep_ptr->dam = 0;
837                         break;
838                 }
839
840                 if (target_ptr->csp == 0)
841                 {
842                         ep_ptr->dam = 0;
843                         break;
844                 }
845
846                 if (ep_ptr->who > 0)
847                         msg_format(_("%^sに精神エネルギーを吸い取られてしまった!", "%^s draws psychic energy from you!"), ep_ptr->m_name);
848                 else
849                         msg_print(_("精神エネルギーを吸い取られてしまった!", "Your psychic energy is drawn!"));
850
851                 if (ep_ptr->dam >= target_ptr->csp)
852                 {
853                         ep_ptr->dam = target_ptr->csp;
854                         target_ptr->csp = 0;
855                         target_ptr->csp_frac = 0;
856                 }
857                 else
858                 {
859                         target_ptr->csp -= ep_ptr->dam;
860                 }
861
862                 learn_spell(target_ptr, ep_ptr->monspell);
863                 target_ptr->redraw |= (PR_MANA);
864                 target_ptr->window |= (PW_PLAYER | PW_SPELL);
865
866                 if ((ep_ptr->who <= 0) || (ep_ptr->m_ptr->hp >= ep_ptr->m_ptr->maxhp))
867                 {
868                         ep_ptr->dam = 0;
869                         break;
870                 }
871
872                 ep_ptr->m_ptr->hp += ep_ptr->dam;
873                 if (ep_ptr->m_ptr->hp > ep_ptr->m_ptr->maxhp) ep_ptr->m_ptr->hp = ep_ptr->m_ptr->maxhp;
874
875                 if (target_ptr->health_who == ep_ptr->who) target_ptr->redraw |= (PR_HEALTH);
876                 if (target_ptr->riding == ep_ptr->who) target_ptr->redraw |= (PR_UHEALTH);
877
878                 if (ep_ptr->m_ptr->ml)
879                 {
880                         msg_format(_("%^sは気分が良さそうだ。", "%^s appears healthier."), ep_ptr->m_name);
881                 }
882
883                 ep_ptr->dam = 0;
884                 break;
885         }
886         case GF_MIND_BLAST:
887         {
888                 if ((randint0(100 + ep_ptr->rlev / 2) < MAX(5, target_ptr->skill_sav)) && !CHECK_MULTISHADOW(target_ptr))
889                 {
890                         msg_print(_("しかし効力を跳ね返した!", "You resist the effects!"));
891                         learn_spell(target_ptr, ep_ptr->monspell);
892                         break;
893                 }
894
895                 if (CHECK_MULTISHADOW(target_ptr))
896                 {
897                         ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
898                         break;
899                 }
900
901                 msg_print(_("霊的エネルギーで精神が攻撃された。", "Your mind is blasted by psionic energy."));
902                 if (!target_ptr->resist_conf)
903                 {
904                         (void)set_confused(target_ptr, target_ptr->confused + randint0(4) + 4);
905                 }
906
907                 if (!target_ptr->resist_chaos && one_in_(3))
908                 {
909                         (void)set_image(target_ptr, target_ptr->image + randint0(250) + 150);
910                 }
911
912                 target_ptr->csp -= 50;
913                 if (target_ptr->csp < 0)
914                 {
915                         target_ptr->csp = 0;
916                         target_ptr->csp_frac = 0;
917                 }
918
919                 target_ptr->redraw |= PR_MANA;
920                 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
921                 break;
922         }
923         case GF_BRAIN_SMASH:
924         {
925                 if ((randint0(100 + ep_ptr->rlev / 2) < MAX(5, target_ptr->skill_sav)) && !CHECK_MULTISHADOW(target_ptr))
926                 {
927                         msg_print(_("しかし効力を跳ね返した!", "You resist the effects!"));
928                         learn_spell(target_ptr, ep_ptr->monspell);
929                         break;
930                 }
931
932                 if (!CHECK_MULTISHADOW(target_ptr))
933                 {
934                         msg_print(_("霊的エネルギーで精神が攻撃された。", "Your mind is blasted by psionic energy."));
935
936                         target_ptr->csp -= 100;
937                         if (target_ptr->csp < 0)
938                         {
939                                 target_ptr->csp = 0;
940                                 target_ptr->csp_frac = 0;
941                         }
942                         target_ptr->redraw |= PR_MANA;
943                 }
944
945                 ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
946                 if (CHECK_MULTISHADOW(target_ptr)) break;
947
948                 if (!target_ptr->resist_blind)
949                 {
950                         (void)set_blind(target_ptr, target_ptr->blind + 8 + randint0(8));
951                 }
952
953                 if (!target_ptr->resist_conf)
954                 {
955                         (void)set_confused(target_ptr, target_ptr->confused + randint0(4) + 4);
956                 }
957
958                 if (!target_ptr->free_act)
959                 {
960                         (void)set_paralyzed(target_ptr, target_ptr->paralyzed + randint0(4) + 4);
961                 }
962
963                 (void)set_slow(target_ptr, target_ptr->slow + randint0(4) + 4, FALSE);
964
965                 while (randint0(100 + ep_ptr->rlev / 2) > (MAX(5, target_ptr->skill_sav)))
966                         (void)do_dec_stat(target_ptr, A_INT);
967                 while (randint0(100 + ep_ptr->rlev / 2) > (MAX(5, target_ptr->skill_sav)))
968                         (void)do_dec_stat(target_ptr, A_WIS);
969
970                 if (!target_ptr->resist_chaos)
971                 {
972                         (void)set_image(target_ptr, target_ptr->image + randint0(250) + 150);
973                 }
974
975                 break;
976         }
977         case GF_CAUSE_1:
978         {
979                 if ((randint0(100 + ep_ptr->rlev / 2) < target_ptr->skill_sav) && !CHECK_MULTISHADOW(target_ptr))
980                 {
981                         msg_print(_("しかし効力を跳ね返した!", "You resist the effects!"));
982                         learn_spell(target_ptr, ep_ptr->monspell);
983                 }
984                 else
985                 {
986                         if (!CHECK_MULTISHADOW(target_ptr)) curse_equipment(target_ptr, 15, 0);
987                         ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
988                 }
989                 break;
990         }
991         case GF_CAUSE_2:
992         {
993                 if ((randint0(100 + ep_ptr->rlev / 2) < target_ptr->skill_sav) && !CHECK_MULTISHADOW(target_ptr))
994                 {
995                         msg_print(_("しかし効力を跳ね返した!", "You resist the effects!"));
996                         learn_spell(target_ptr, ep_ptr->monspell);
997                 }
998                 else
999                 {
1000                         if (!CHECK_MULTISHADOW(target_ptr)) curse_equipment(target_ptr, 25, MIN(ep_ptr->rlev / 2 - 15, 5));
1001                         ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
1002                 }
1003                 break;
1004         }
1005         case GF_CAUSE_3:
1006         {
1007                 if ((randint0(100 + ep_ptr->rlev / 2) < target_ptr->skill_sav) && !CHECK_MULTISHADOW(target_ptr))
1008                 {
1009                         msg_print(_("しかし効力を跳ね返した!", "You resist the effects!"));
1010                         learn_spell(target_ptr, ep_ptr->monspell);
1011                 }
1012                 else
1013                 {
1014                         if (!CHECK_MULTISHADOW(target_ptr)) curse_equipment(target_ptr, 33, MIN(ep_ptr->rlev / 2 - 15, 15));
1015                         ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
1016                 }
1017                 break;
1018         }
1019         case GF_CAUSE_4:
1020         {
1021                 if ((randint0(100 + ep_ptr->rlev / 2) < target_ptr->skill_sav) && !(ep_ptr->m_ptr->r_idx == MON_KENSHIROU) && !CHECK_MULTISHADOW(target_ptr))
1022                 {
1023                         msg_print(_("しかし秘孔を跳ね返した!", "You resist the effects!"));
1024                         learn_spell(target_ptr, ep_ptr->monspell);
1025                 }
1026                 else
1027                 {
1028                         ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->killer, ep_ptr->monspell);
1029                         if (!CHECK_MULTISHADOW(target_ptr)) (void)set_cut(target_ptr, target_ptr->cut + damroll(10, 10));
1030                 }
1031
1032                 break;
1033         }
1034         case GF_HAND_DOOM:
1035         {
1036                 if ((randint0(100 + ep_ptr->rlev / 2) < target_ptr->skill_sav) && !CHECK_MULTISHADOW(target_ptr))
1037                 {
1038                         msg_print(_("しかし効力を跳ね返した!", "You resist the effects!"));
1039                         learn_spell(target_ptr, ep_ptr->monspell);
1040                 }
1041                 else
1042                 {
1043                         if (!CHECK_MULTISHADOW(target_ptr))
1044                         {
1045                                 msg_print(_("あなたは命が薄まっていくように感じた!", "You feel your life fade away!"));
1046                                 curse_equipment(target_ptr, 40, 20);
1047                         }
1048
1049                         ep_ptr->get_damage = take_hit(target_ptr, DAMAGE_ATTACK, ep_ptr->dam, ep_ptr->m_name, ep_ptr->monspell);
1050
1051                         if (target_ptr->chp < 1) target_ptr->chp = 1;
1052                 }
1053
1054                 break;
1055         }
1056         default:
1057         {
1058                 ep_ptr->dam = 0;
1059                 break;
1060         }
1061         }
1062 }
1063
1064
1065 /*!
1066  * @brief 汎用的なビーム/ボルト/ボール系によるプレイヤーへの効果処理 / Helper function for "project()" below.
1067  * @param who 魔法を発動したモンスター(0ならばプレイヤー、負値ならば自然発生) / Index of "source" monster (zero for "player")
1068  * @param who_name 効果を起こしたモンスターの名前
1069  * @param r 効果半径(ビーム/ボルト = 0 / ボール = 1以上) / Radius of explosion (0 = beam/bolt, 1 to 9 = ball)
1070  * @param y 目標Y座標 / Target y location (or location to travel "towards")
1071  * @param x 目標X座標 / Target x location (or location to travel "towards")
1072  * @param dam 基本威力 / Base damage roll to apply to affected monsters (or player)
1073  * @param effect_type 効果属性 / Type of damage to apply to monsters (and objects)
1074  * @param flag 効果フラグ
1075  * @param monspell 効果元のモンスター魔法ID
1076  * @return 何か一つでも効力があればTRUEを返す / TRUE if any "effects" of the projection were observed, else FALSE
1077  */
1078 bool affect_player(MONSTER_IDX who, player_type *target_ptr, concptr who_name, int r, POSITION y, POSITION x, HIT_POINT dam, EFFECT_ID effect_type, BIT_FLAGS flag, int monspell)
1079 {
1080         effect_player_type tmp_effect;
1081         effect_player_type *ep_ptr = initialize_effect_player(&tmp_effect, who, dam, effect_type, flag, monspell);
1082         ep_check_result check_result = check_continue_player_effect(target_ptr, ep_ptr, y, x);
1083         if (check_result != EP_CHECK_CONTINUE) return check_result;
1084
1085         if (ep_ptr->dam > 1600) ep_ptr->dam = 1600;
1086
1087         ep_ptr->dam = (ep_ptr->dam + r) / (r + 1);
1088         describe_effect_source(target_ptr, ep_ptr, who_name);
1089         switch_effects_player(target_ptr, ep_ptr);
1090
1091         revenge_store(target_ptr, ep_ptr->get_damage);
1092         if ((target_ptr->tim_eyeeye || hex_spelling(target_ptr, HEX_EYE_FOR_EYE))
1093                 && (ep_ptr->get_damage > 0) && !target_ptr->is_dead && (ep_ptr->who > 0))
1094         {
1095                 GAME_TEXT m_name_self[80];
1096                 monster_desc(target_ptr, m_name_self, ep_ptr->m_ptr, MD_PRON_VISIBLE | MD_POSSESSIVE | MD_OBJECTIVE);
1097                 msg_format(_("攻撃が%s自身を傷つけた!", "The attack of %s has wounded %s!"), ep_ptr->m_name, m_name_self);
1098                 project(target_ptr, 0, 0, ep_ptr->m_ptr->fy, ep_ptr->m_ptr->fx, ep_ptr->get_damage, GF_MISSILE, PROJECT_KILL, -1);
1099                 if (target_ptr->tim_eyeeye) set_tim_eyeeye(target_ptr, target_ptr->tim_eyeeye - 5, TRUE);
1100         }
1101
1102         if (target_ptr->riding && ep_ptr->dam > 0)
1103         {
1104                 rakubadam_p = (ep_ptr->dam > 200) ? 200 : ep_ptr->dam;
1105         }
1106
1107         disturb(target_ptr, TRUE, TRUE);
1108         if ((target_ptr->special_defense & NINJA_KAWARIMI) && ep_ptr->dam && ep_ptr->who && (ep_ptr->who != target_ptr->riding))
1109         {
1110                 (void)kawarimi(target_ptr, FALSE);
1111         }
1112
1113         return TRUE;
1114 }