2 * @brief モンスターからプレーヤーへの直接攻撃処理
7 #include "combat/monster-attack-player.h"
8 #include "cmd/cmd-attack.h"
9 #include "cmd/cmd-pet.h"
10 #include "combat/attack-accuracy.h"
11 #include "combat/attack-criticality.h"
12 #include "combat/combat-options-type.h"
13 #include "combat/hallucination-attacks-table.h"
14 #include "combat/insults-moans.h"
15 #include "combat/monster-attack-effect.h"
16 #include "combat/monster-attack-util.h"
17 #include "dungeon/dungeon.h"
18 #include "effect/effect-characteristics.h"
19 #include "main/sound-definitions-table.h"
20 #include "mind/racial-mirror-master.h"
21 #include "monster/monster-status.h"
22 #include "object/object2.h"
23 #include "object/object-flavor.h"
24 #include "object/object-hook.h"
25 #include "object/object-mark-types.h"
26 #include "player/avatar.h"
27 #include "player/mimic-info-table.h"
28 #include "player/player-damage.h"
29 #include "player/player-effects.h"
30 #include "player/player-move.h"
31 #include "player/player-skill.h"
32 #include "realm/realm-hex.h"
33 #include "spell/process-effect.h"
34 #include "spell/spells-floor.h"
35 #include "spell/spells-type.h"
36 #include "spell/spells2.h"
37 #include "spell/spells3.h"
39 static void show_jaian_song(monap_type *monap_ptr)
42 switch (randint1(15)) {
46 monap_ptr->act = "「♪お~れはジャイアン~~ガ~キだいしょう~」";
49 monap_ptr->act = "「♪て~んかむ~てきのお~とこだぜ~~」";
52 monap_ptr->act = "「♪の~び太スネ夫はメじゃないよ~~」";
55 monap_ptr->act = "「♪け~んかスポ~ツ~どんとこい~」";
58 monap_ptr->act = "「♪うた~も~~う~まいぜ~まかしとけ~」";
61 monap_ptr->act = "「♪ま~ちいちば~んのに~んきもの~~」";
64 monap_ptr->act = "「♪べんきょうしゅくだいメじゃないよ~~」";
67 monap_ptr->act = "「♪きはやさし~くて~ち~からもち~」";
70 monap_ptr->act = "「♪かお~も~~スタイルも~バツグンさ~」";
73 monap_ptr->act = "「♪がっこうい~ちの~あ~ばれんぼう~~」";
76 monap_ptr->act = "「♪ド~ラもドラミもメじゃないよ~~」";
79 monap_ptr->act = "「♪よじげんぽけっと~な~くたって~」";
82 monap_ptr->act = "「♪あし~の~~ながさ~は~まけないぜ~」";
86 monap_ptr->act = "horribly sings 'I AM GIAAAAAN. THE BOOOSS OF THE KIIIIDS.'";
90 static void monster_attack_show(monap_type *monap_ptr)
93 monap_ptr->abbreviate = -1;
95 if (monap_ptr->m_ptr->r_idx == MON_JAIAN) {
96 show_jaian_song(monap_ptr);
99 monap_ptr->act = _("は♪僕らは楽しい家族♪と歌っている。", "sings 'We are a happy family.'");
101 monap_ptr->act = _("は♪アイ ラブ ユー、ユー ラブ ミー♪と歌っている。", "sings 'I love you, you love me.'");
107 static void describe_monster_attack_method(monap_type *monap_ptr)
109 switch (monap_ptr->method) {
111 monap_ptr->act = _("殴られた。", "hits you.");
112 monap_ptr->do_cut = monap_ptr->do_stun = 1;
113 monap_ptr->touched = TRUE;
118 monap_ptr->act = _("触られた。", "touches you.");
119 monap_ptr->touched = TRUE;
124 monap_ptr->act = _("パンチされた。", "punches you.");
125 monap_ptr->touched = TRUE;
126 monap_ptr->do_stun = 1;
131 monap_ptr->act = _("蹴られた。", "kicks you.");
132 monap_ptr->touched = TRUE;
133 monap_ptr->do_stun = 1;
138 monap_ptr->act = _("ひっかかれた。", "claws you.");
139 monap_ptr->touched = TRUE;
140 monap_ptr->do_cut = 1;
145 monap_ptr->act = _("噛まれた。", "bites you.");
146 monap_ptr->do_cut = 1;
147 monap_ptr->touched = TRUE;
152 monap_ptr->act = _("刺された。", "stings you.");
153 monap_ptr->touched = TRUE;
158 monap_ptr->act = _("斬られた。", "slashes you.");
159 monap_ptr->touched = TRUE;
160 monap_ptr->do_cut = 1;
165 monap_ptr->act = _("角で突かれた。", "butts you.");
166 monap_ptr->do_stun = 1;
167 monap_ptr->touched = TRUE;
172 monap_ptr->act = _("体当たりされた。", "crushes you.");
173 monap_ptr->do_stun = 1;
174 monap_ptr->touched = TRUE;
179 monap_ptr->act = _("飲み込まれた。", "engulfs you.");
180 monap_ptr->touched = TRUE;
185 monap_ptr->abbreviate = -1;
186 monap_ptr->act = _("は請求書をよこした。", "charges you.");
187 monap_ptr->touched = TRUE;
189 /* このコメントはジョークが効いているので残しておく / Note! This is "charges", not "charges at". */
194 monap_ptr->abbreviate = -1;
195 monap_ptr->act = _("が体の上を這い回った。", "crawls on you.");
196 monap_ptr->touched = TRUE;
201 monap_ptr->act = _("よだれをたらされた。", "drools on you.");
206 monap_ptr->act = _("唾を吐かれた。", "spits on you.");
211 monap_ptr->abbreviate = -1;
212 monap_ptr->act = _("は爆発した。", "explodes.");
213 monap_ptr->explode = TRUE;
217 monap_ptr->act = _("にらまれた。", "gazes at you.");
221 monap_ptr->act = _("泣き叫ばれた。", "wails at you.");
226 monap_ptr->act = _("胞子を飛ばされた。", "releases spores at you.");
231 monap_ptr->abbreviate = -1;
232 monap_ptr->act = _("が XXX4 を発射した。", "projects XXX4's at you.");
236 monap_ptr->act = _("金をせがまれた。", "begs you for money.");
242 monap_ptr->abbreviate = -1;
244 monap_ptr->act = desc_insult[randint0(monap_ptr->m_ptr->r_idx == MON_DEBBY ? 10 : 8)];
250 monap_ptr->abbreviate = -1;
252 monap_ptr->act = desc_moan[randint0(4)];
257 monster_attack_show(monap_ptr);
264 * @brief 時間逆転攻撃による能力低下
265 * @param target_ptr プレーヤーへの参照ポインタ
266 * @monap_ptr モンスターからモンスターへの直接攻撃構造体への参照ポインタ
269 static void describe_disability(player_type *target_ptr, monap_type *monap_ptr)
271 int stat = randint0(6);
274 monap_ptr->act = _("強く", "strong");
277 monap_ptr->act = _("聡明で", "bright");
280 monap_ptr->act = _("賢明で", "wise");
283 monap_ptr->act = _("器用で", "agile");
286 monap_ptr->act = _("健康で", "hale");
289 monap_ptr->act = _("美しく", "beautiful");
293 msg_format(_("あなたは以前ほど%sなくなってしまった...。", "You're not as %s as you used to be..."), monap_ptr->act);
294 target_ptr->stat_cur[stat] = (target_ptr->stat_cur[stat] * 3) / 4;
295 if (target_ptr->stat_cur[stat] < 3)
296 target_ptr->stat_cur[stat] = 3;
299 static void process_monster_attack_time(player_type *target_ptr, monap_type *monap_ptr)
301 if (target_ptr->resist_time || check_multishadow(target_ptr))
304 switch (randint1(10)) {
310 if (target_ptr->prace == RACE_ANDROID)
312 msg_print(_("人生が逆戻りした気がする。", "You feel like a chunk of the past has been ripped away."));
313 lose_exp(target_ptr, 100 + (target_ptr->exp / 100) * MON_DRAIN_LIFE);
320 describe_disability(target_ptr, monap_ptr);
321 target_ptr->update |= (PU_BONUS);
325 msg_print(_("あなたは以前ほど力強くなくなってしまった...。", "You're not as powerful as you used to be..."));
326 for (int i = 0; i < A_MAX; i++) {
327 target_ptr->stat_cur[i] = (target_ptr->stat_cur[i] * 7) / 8;
328 if (target_ptr->stat_cur[i] < 3)
329 target_ptr->stat_cur[i] = 3;
332 target_ptr->update |= (PU_BONUS);
339 * @brief モンスターからプレイヤーへの打撃処理 / Attack the player via physical attacks.
340 * @param m_idx 打撃を行うモンスターのID
341 * @return 実際に攻撃処理を行った場合TRUEを返す
343 bool make_attack_normal(player_type *target_ptr, MONSTER_IDX m_idx)
345 monap_type tmp_monap;
346 monap_type *monap_ptr = initialize_monap_type(target_ptr, &tmp_monap, m_idx);
354 GAME_TEXT o_name[MAX_NLEN];
355 GAME_TEXT m_name[MAX_NLEN];
361 bool do_silly_attack = (one_in_(2) && target_ptr->image);
362 HIT_POINT get_damage = 0;
363 monster_race *r_ptr = &r_info[monap_ptr->m_ptr->r_idx];
364 if (r_ptr->flags1 & (RF1_NEVER_BLOW))
367 if (d_info[target_ptr->dungeon_idx].flags1 & DF1_NO_MELEE)
370 if (!is_hostile(monap_ptr->m_ptr))
373 rlev = ((r_ptr->level >= 1) ? r_ptr->level : 1);
374 monster_desc(target_ptr, m_name, monap_ptr->m_ptr, 0);
375 monster_desc(target_ptr, ddesc, monap_ptr->m_ptr, MD_WRONGDOER_NAME);
376 if (target_ptr->special_defense & KATA_IAI) {
377 msg_format(_("相手が襲いかかる前に素早く武器を振るった。", "You took sen, drew and cut in one motion before %s moved."), m_name);
378 if (do_cmd_attack(target_ptr, monap_ptr->m_ptr->fy, monap_ptr->m_ptr->fx, HISSATSU_IAI))
382 if ((target_ptr->special_defense & NINJA_KAWARIMI) && (randint0(55) < (target_ptr->lev * 3 / 5 + 20))) {
383 if (kawarimi(target_ptr, TRUE))
388 floor_type *floor_ptr = target_ptr->current_floor_ptr;
389 for (int ap_cnt = 0; ap_cnt < 4; ap_cnt++) {
390 bool obvious = FALSE;
392 HIT_POINT damage = 0;
393 int effect = r_ptr->blow[ap_cnt].effect;
394 monap_ptr->method = r_ptr->blow[ap_cnt].method;
395 int d_dice = r_ptr->blow[ap_cnt].d_dice;
396 int d_side = r_ptr->blow[ap_cnt].d_side;
398 if (!monster_is_valid(monap_ptr->m_ptr))
401 if (!monap_ptr->method)
404 if (is_pet(monap_ptr->m_ptr) && (r_ptr->flags1 & RF1_UNIQUE) && (monap_ptr->method == RBM_EXPLODE)) {
405 monap_ptr->method = RBM_HIT;
409 if (!target_ptr->playing || target_ptr->is_dead || (distance(target_ptr->y, target_ptr->x, monap_ptr->m_ptr->fy, monap_ptr->m_ptr->fx) > 1)
410 || target_ptr->leaving)
413 if (monap_ptr->method == RBM_SHOOT)
416 power = mbe_info[effect].power;
417 ac = target_ptr->ac + target_ptr->to_a;
418 if (!effect || check_hit_from_monster_to_player(target_ptr, power, rlev, MON_STUNNED(monap_ptr->m_ptr))) {
419 disturb(target_ptr, TRUE, TRUE);
420 if ((target_ptr->protevil > 0) && (r_ptr->flags3 & RF3_EVIL) && (target_ptr->lev >= rlev) && ((randint0(100) + target_ptr->lev) > 50)) {
421 if (is_original_ap_and_seen(target_ptr, monap_ptr->m_ptr))
422 r_ptr->r_flags3 |= RF3_EVIL;
425 if (monap_ptr->abbreviate)
428 msg_format("%^sは撃退された。", m_name);
430 monap_ptr->abbreviate = 1; /*2回目以降は省略 */
432 msg_format("%^s is repelled.", m_name);
438 monap_ptr->do_cut = 0;
439 monap_ptr->do_stun = 0;
440 describe_monster_attack_method(monap_ptr);
441 if (monap_ptr->act) {
442 if (do_silly_attack) {
444 monap_ptr->abbreviate = -1;
446 monap_ptr->act = silly_attacks[randint0(MAX_SILLY_ATTACK)];
449 if (monap_ptr->abbreviate == 0)
450 msg_format("%^sに%s", m_name, monap_ptr->act);
451 else if (monap_ptr->abbreviate == 1)
452 msg_format("%s", monap_ptr->act);
453 else /* if (monap_ptr->abbreviate == -1) */
454 msg_format("%^s%s", m_name, monap_ptr->act);
455 monap_ptr->abbreviate = 1; /*2回目以降は省略 */
457 msg_format("%^s %s%s", m_name, monap_ptr->act, do_silly_attack ? " you." : "");
462 damage = damroll(d_dice, d_side);
463 if (monap_ptr->explode)
472 case RBE_SUPERHURT: /* AC軽減あり / Player armor reduces total damage */
474 if (((randint1(rlev * 2 + 300) > (ac + 200)) || one_in_(13)) && !check_multishadow(target_ptr)) {
475 int tmp_damage = damage - (damage * ((ac < 150) ? ac : 150) / 250);
476 msg_print(_("痛恨の一撃!", "It was a critical hit!"));
477 tmp_damage = MAX(damage, tmp_damage * 2);
478 get_damage += take_hit(target_ptr, DAMAGE_ATTACK, tmp_damage, ddesc, -1);
483 case RBE_HURT: /* AC軽減あり / Player armor reduces total damage */
486 damage -= (damage * ((ac < 150) ? ac : 150) / 250);
487 get_damage += take_hit(target_ptr, DAMAGE_ATTACK, damage, ddesc, -1);
491 if (monap_ptr->explode)
494 if (!(target_ptr->resist_pois || is_oppose_pois(target_ptr)) && !check_multishadow(target_ptr)) {
495 if (set_poisoned(target_ptr, target_ptr->poisoned + randint1(rlev) + 5)) {
500 get_damage += take_hit(target_ptr, DAMAGE_ATTACK, damage, ddesc, -1);
501 update_smart_learn(target_ptr, m_idx, DRS_POIS);
505 if (monap_ptr->explode)
508 if (!target_ptr->resist_disen && !check_multishadow(target_ptr)) {
509 if (apply_disenchant(target_ptr, 0)) {
510 update_creature(target_ptr);
515 get_damage += take_hit(target_ptr, DAMAGE_ATTACK, damage, ddesc, -1);
516 update_smart_learn(target_ptr, m_idx, DRS_DISEN);
520 get_damage += take_hit(target_ptr, DAMAGE_ATTACK, damage, ddesc, -1);
521 if (target_ptr->is_dead || check_multishadow(target_ptr))
524 for (k = 0; k < 10; k++) {
525 INVENTORY_IDX i = (INVENTORY_IDX)randint0(INVEN_PACK);
526 o_ptr = &target_ptr->inventory_list[i];
530 if (((o_ptr->tval == TV_STAFF) || (o_ptr->tval == TV_WAND)) && (o_ptr->pval)) {
531 int heal = rlev * o_ptr->pval;
532 if (o_ptr->tval == TV_STAFF)
533 heal *= o_ptr->number;
535 heal = MIN(heal, monap_ptr->m_ptr->maxhp - monap_ptr->m_ptr->hp);
536 msg_print(_("ザックからエネルギーが吸い取られた!", "Energy drains from your pack!"));
538 monap_ptr->m_ptr->hp += (HIT_POINT)heal;
539 if (target_ptr->health_who == m_idx)
540 target_ptr->redraw |= (PR_HEALTH);
542 if (target_ptr->riding == m_idx)
543 target_ptr->redraw |= (PR_UHEALTH);
546 target_ptr->update |= (PU_COMBINE | PU_REORDER);
547 target_ptr->window |= (PW_INVEN);
555 get_damage += take_hit(target_ptr, DAMAGE_ATTACK, damage, ddesc, -1);
556 if (MON_CONFUSED(monap_ptr->m_ptr))
559 if (target_ptr->is_dead || check_multishadow(target_ptr))
563 if (!target_ptr->paralyzed && (randint0(100) < (adj_dex_safe[target_ptr->stat_ind[A_DEX]] + target_ptr->lev))) {
564 msg_print(_("しかし素早く財布を守った!", "You quickly protect your money pouch!"));
569 gold = (target_ptr->au / 10) + randint1(25);
573 gold = (target_ptr->au / 20) + randint1(3000);
574 if (gold > target_ptr->au)
575 gold = target_ptr->au;
576 target_ptr->au -= gold;
578 msg_print(_("しかし何も盗まれなかった。", "Nothing was stolen."));
579 } else if (target_ptr->au) {
580 msg_print(_("財布が軽くなった気がする。", "Your purse feels lighter."));
581 msg_format(_("$%ld のお金が盗まれた!", "%ld coins were stolen!"), (long)gold);
582 chg_virtue(target_ptr, V_SACRIFICE, 1);
584 msg_print(_("財布が軽くなった気がする。", "Your purse feels lighter."));
585 msg_print(_("お金が全部盗まれた!", "All of your coins were stolen!"));
586 chg_virtue(target_ptr, V_SACRIFICE, 2);
589 target_ptr->redraw |= (PR_GOLD);
590 target_ptr->window |= (PW_PLAYER);
597 get_damage += take_hit(target_ptr, DAMAGE_ATTACK, damage, ddesc, -1);
598 if (MON_CONFUSED(monap_ptr->m_ptr))
601 if (target_ptr->is_dead || check_multishadow(target_ptr))
604 if (!target_ptr->paralyzed && (randint0(100) < (adj_dex_safe[target_ptr->stat_ind[A_DEX]] + target_ptr->lev))) {
605 msg_print(_("しかしあわててザックを取り返した!", "You grab hold of your backpack!"));
611 for (k = 0; k < 10; k++) {
613 INVENTORY_IDX i = (INVENTORY_IDX)randint0(INVEN_PACK);
614 o_ptr = &target_ptr->inventory_list[i];
618 if (object_is_artifact(o_ptr))
621 object_desc(target_ptr, o_name, o_ptr, OD_OMIT_PREFIX);
623 msg_format("%s(%c)を%s盗まれた!", o_name, index_to_label(i), ((o_ptr->number > 1) ? "一つ" : ""));
625 msg_format("%sour %s (%c) was stolen!", ((o_ptr->number > 1) ? "One of y" : "Y"), o_name, index_to_label(i));
627 chg_virtue(target_ptr, V_SACRIFICE, 1);
628 o_idx = o_pop(floor_ptr);
631 j_ptr = &floor_ptr->o_list[o_idx];
632 object_copy(j_ptr, o_ptr);
634 if ((o_ptr->tval == TV_ROD) || (o_ptr->tval == TV_WAND)) {
635 j_ptr->pval = o_ptr->pval / o_ptr->number;
636 o_ptr->pval -= j_ptr->pval;
639 j_ptr->marked = OM_TOUCHED;
640 j_ptr->held_m_idx = m_idx;
641 j_ptr->next_o_idx = monap_ptr->m_ptr->hold_o_idx;
642 monap_ptr->m_ptr->hold_o_idx = o_idx;
645 inven_item_increase(target_ptr, i, -1);
646 inven_item_optimize(target_ptr, i);
656 get_damage += take_hit(target_ptr, DAMAGE_ATTACK, damage, ddesc, -1);
657 if (target_ptr->is_dead || check_multishadow(target_ptr))
660 for (k = 0; k < 10; k++) {
661 INVENTORY_IDX i = (INVENTORY_IDX)randint0(INVEN_PACK);
662 o_ptr = &target_ptr->inventory_list[i];
666 if ((o_ptr->tval != TV_FOOD) && !((o_ptr->tval == TV_CORPSE) && (o_ptr->sval)))
669 object_desc(target_ptr, o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
671 msg_format("%s(%c)を%s食べられてしまった!", o_name, index_to_label(i), ((o_ptr->number > 1) ? "一つ" : ""));
673 msg_format("%sour %s (%c) was eaten!", ((o_ptr->number > 1) ? "One of y" : "Y"), o_name, index_to_label(i));
675 inven_item_increase(target_ptr, i, -1);
676 inven_item_optimize(target_ptr, i);
684 o_ptr = &target_ptr->inventory_list[INVEN_LITE];
685 get_damage += take_hit(target_ptr, DAMAGE_ATTACK, damage, ddesc, -1);
686 if (target_ptr->is_dead || check_multishadow(target_ptr))
689 if ((o_ptr->xtra4 > 0) && (!object_is_fixed_artifact(o_ptr))) {
690 o_ptr->xtra4 -= (s16b)(250 + randint1(250));
691 if (o_ptr->xtra4 < 1)
694 if (!target_ptr->blind) {
695 msg_print(_("明かりが暗くなってしまった。", "Your light dims."));
699 target_ptr->window |= (PW_EQUIP);
705 if (monap_ptr->explode)
709 msg_print(_("酸を浴びせられた!", "You are covered in acid!"));
710 get_damage += acid_dam(target_ptr, damage, ddesc, -1, FALSE);
711 update_creature(target_ptr);
712 update_smart_learn(target_ptr, m_idx, DRS_ACID);
716 if (monap_ptr->explode)
719 msg_print(_("電撃を浴びせられた!", "You are struck by electricity!"));
720 get_damage += elec_dam(target_ptr, damage, ddesc, -1, FALSE);
721 update_smart_learn(target_ptr, m_idx, DRS_ELEC);
725 if (monap_ptr->explode)
728 msg_print(_("全身が炎に包まれた!", "You are enveloped in flames!"));
729 get_damage += fire_dam(target_ptr, damage, ddesc, -1, FALSE);
730 update_smart_learn(target_ptr, m_idx, DRS_FIRE);
734 if (monap_ptr->explode)
737 msg_print(_("全身が冷気で覆われた!", "You are covered with frost!"));
738 get_damage += cold_dam(target_ptr, damage, ddesc, -1, FALSE);
739 update_smart_learn(target_ptr, m_idx, DRS_COLD);
743 get_damage += take_hit(target_ptr, DAMAGE_ATTACK, damage, ddesc, -1);
744 if (target_ptr->is_dead)
747 if (!target_ptr->resist_blind && !check_multishadow(target_ptr)) {
748 if (set_blind(target_ptr, target_ptr->blind + 10 + randint1(rlev))) {
750 if (monap_ptr->m_ptr->r_idx == MON_DIO)
751 msg_print("どうだッ!この血の目潰しはッ!");
759 update_smart_learn(target_ptr, m_idx, DRS_BLIND);
763 if (monap_ptr->explode)
766 get_damage += take_hit(target_ptr, DAMAGE_ATTACK, damage, ddesc, -1);
767 if (target_ptr->is_dead)
770 if (!target_ptr->resist_conf && !check_multishadow(target_ptr)) {
771 if (set_confused(target_ptr, target_ptr->confused + 3 + randint1(rlev))) {
776 update_smart_learn(target_ptr, m_idx, DRS_CONF);
780 get_damage += take_hit(target_ptr, DAMAGE_ATTACK, damage, ddesc, -1);
781 if (target_ptr->is_dead)
784 if (check_multishadow(target_ptr)) {
786 } else if (target_ptr->resist_fear) {
787 msg_print(_("しかし恐怖に侵されなかった!", "You stand your ground!"));
789 } else if (randint0(100 + r_ptr->level / 2) < target_ptr->skill_sav) {
790 msg_print(_("しかし恐怖に侵されなかった!", "You stand your ground!"));
793 if (set_afraid(target_ptr, target_ptr->afraid + 3 + randint1(rlev))) {
798 update_smart_learn(target_ptr, m_idx, DRS_FEAR);
802 get_damage += take_hit(target_ptr, DAMAGE_ATTACK, damage, ddesc, -1);
804 if (target_ptr->is_dead)
807 if (check_multishadow(target_ptr)) {
809 } else if (target_ptr->free_act) {
810 msg_print(_("しかし効果がなかった!", "You are unaffected!"));
812 } else if (randint0(100 + r_ptr->level / 2) < target_ptr->skill_sav) {
813 msg_print(_("しかし効力を跳ね返した!", "You resist the effects!"));
816 if (!target_ptr->paralyzed) {
817 if (set_paralyzed(target_ptr, 3 + randint1(rlev))) {
823 update_smart_learn(target_ptr, m_idx, DRS_FREE);
827 get_damage += take_hit(target_ptr, DAMAGE_ATTACK, damage, ddesc, -1);
828 if (target_ptr->is_dead || check_multishadow(target_ptr))
831 if (do_dec_stat(target_ptr, A_STR))
837 get_damage += take_hit(target_ptr, DAMAGE_ATTACK, damage, ddesc, -1);
838 if (target_ptr->is_dead || check_multishadow(target_ptr))
841 if (do_dec_stat(target_ptr, A_INT))
847 get_damage += take_hit(target_ptr, DAMAGE_ATTACK, damage, ddesc, -1);
848 if (target_ptr->is_dead || check_multishadow(target_ptr))
851 if (do_dec_stat(target_ptr, A_WIS))
857 get_damage += take_hit(target_ptr, DAMAGE_ATTACK, damage, ddesc, -1);
858 if (target_ptr->is_dead || check_multishadow(target_ptr))
861 if (do_dec_stat(target_ptr, A_DEX))
867 get_damage += take_hit(target_ptr, DAMAGE_ATTACK, damage, ddesc, -1);
868 if (target_ptr->is_dead || check_multishadow(target_ptr))
871 if (do_dec_stat(target_ptr, A_CON))
877 get_damage += take_hit(target_ptr, DAMAGE_ATTACK, damage, ddesc, -1);
878 if (target_ptr->is_dead || check_multishadow(target_ptr))
881 if (do_dec_stat(target_ptr, A_CHR))
887 get_damage += take_hit(target_ptr, DAMAGE_ATTACK, damage, ddesc, -1);
888 if (target_ptr->is_dead || check_multishadow(target_ptr))
891 if (do_dec_stat(target_ptr, A_STR))
894 if (do_dec_stat(target_ptr, A_DEX))
897 if (do_dec_stat(target_ptr, A_CON))
900 if (do_dec_stat(target_ptr, A_INT))
903 if (do_dec_stat(target_ptr, A_WIS))
906 if (do_dec_stat(target_ptr, A_CHR))
913 damage -= (damage * ((ac < 150) ? ac : 150) / 250);
914 get_damage += take_hit(target_ptr, DAMAGE_ATTACK, damage, ddesc, -1);
915 if (damage > 23 || monap_ptr->explode)
916 earthquake(target_ptr, monap_ptr->m_ptr->fy, monap_ptr->m_ptr->fx, 8, m_idx);
921 s32b d = damroll(10, 6) + (target_ptr->exp / 100) * MON_DRAIN_LIFE;
923 get_damage += take_hit(target_ptr, DAMAGE_ATTACK, damage, ddesc, -1);
924 if (target_ptr->is_dead || check_multishadow(target_ptr))
927 (void)drain_exp(target_ptr, d, d / 10, 95);
931 s32b d = damroll(20, 6) + (target_ptr->exp / 100) * MON_DRAIN_LIFE;
933 get_damage += take_hit(target_ptr, DAMAGE_ATTACK, damage, ddesc, -1);
934 if (target_ptr->is_dead || check_multishadow(target_ptr))
937 (void)drain_exp(target_ptr, d, d / 10, 90);
941 s32b d = damroll(40, 6) + (target_ptr->exp / 100) * MON_DRAIN_LIFE;
943 get_damage += take_hit(target_ptr, DAMAGE_ATTACK, damage, ddesc, -1);
944 if (target_ptr->is_dead || check_multishadow(target_ptr))
947 (void)drain_exp(target_ptr, d, d / 10, 75);
951 s32b d = damroll(80, 6) + (target_ptr->exp / 100) * MON_DRAIN_LIFE;
953 get_damage += take_hit(target_ptr, DAMAGE_ATTACK, damage, ddesc, -1);
954 if (target_ptr->is_dead || check_multishadow(target_ptr))
957 (void)drain_exp(target_ptr, d, d / 10, 50);
961 get_damage += take_hit(target_ptr, DAMAGE_ATTACK, damage, ddesc, -1);
962 if (target_ptr->is_dead || check_multishadow(target_ptr))
965 if (!(target_ptr->resist_pois || is_oppose_pois(target_ptr))) {
966 if (set_poisoned(target_ptr, target_ptr->poisoned + randint1(rlev) + 5)) {
971 if ((randint1(100) < 11) && (target_ptr->prace != RACE_ANDROID)) {
972 bool perm = one_in_(10);
973 if (dec_stat(target_ptr, A_CON, randint1(10), perm)) {
974 msg_print(_("病があなたを蝕んでいる気がする。", "You feel sickly."));
982 if (monap_ptr->explode)
985 process_monster_attack_time(target_ptr, monap_ptr);
986 get_damage += take_hit(target_ptr, DAMAGE_ATTACK, damage, ddesc, -1);
990 s32b d = damroll(60, 6) + (target_ptr->exp / 100) * MON_DRAIN_LIFE;
993 get_damage += take_hit(target_ptr, DAMAGE_ATTACK, damage, ddesc, -1);
994 if (target_ptr->is_dead || check_multishadow(target_ptr))
997 resist_drain = !drain_exp(target_ptr, d, d / 10, 50);
998 if (target_ptr->mimic_form) {
999 if (mimic_info[target_ptr->mimic_form].MIMIC_FLAGS & MIMIC_IS_NONLIVING)
1000 resist_drain = TRUE;
1002 switch (target_ptr->prace) {
1010 resist_drain = TRUE;
1015 if ((damage > 5) && !resist_drain) {
1016 bool did_heal = FALSE;
1017 if (monap_ptr->m_ptr->hp < monap_ptr->m_ptr->maxhp)
1020 monap_ptr->m_ptr->hp += damroll(4, damage / 6);
1021 if (monap_ptr->m_ptr->hp > monap_ptr->m_ptr->maxhp)
1022 monap_ptr->m_ptr->hp = monap_ptr->m_ptr->maxhp;
1024 if (target_ptr->health_who == m_idx)
1025 target_ptr->redraw |= (PR_HEALTH);
1027 if (target_ptr->riding == m_idx)
1028 target_ptr->redraw |= (PR_UHEALTH);
1030 if (monap_ptr->m_ptr->ml && did_heal) {
1031 msg_format(_("%sは体力を回復したようだ。", "%^s appears healthier."), m_name);
1039 if (check_multishadow(target_ptr)) {
1040 msg_print(_("攻撃は幻影に命中し、あなたには届かなかった。", "The attack hits Shadow, but you are unharmed!"));
1042 monap_ptr->do_cut = 0;
1043 target_ptr->csp -= damage;
1044 if (target_ptr->csp < 0) {
1045 target_ptr->csp = 0;
1046 target_ptr->csp_frac = 0;
1049 target_ptr->redraw |= (PR_MANA);
1052 update_smart_learn(target_ptr, m_idx, DRS_MANA);
1056 get_damage += take_hit(target_ptr, DAMAGE_ATTACK, damage, ddesc, -1);
1057 if (target_ptr->is_dead)
1060 if (check_multishadow(target_ptr)) {
1063 if (set_slow(target_ptr, (target_ptr->slow + 4 + randint0(rlev / 10)), FALSE)) {
1071 get_damage += take_hit(target_ptr, DAMAGE_ATTACK, damage, ddesc, -1);
1072 if (target_ptr->is_dead)
1075 if (target_ptr->resist_sound || check_multishadow(target_ptr)) {
1078 if (set_stun(target_ptr, target_ptr->stun + 10 + randint1(r_ptr->level / 4))) {
1088 if (monap_ptr->do_cut && monap_ptr->do_stun) {
1089 if (randint0(100) < 50) {
1090 monap_ptr->do_cut = 0;
1093 monap_ptr->do_stun = 0;
1097 if (monap_ptr->do_cut) {
1099 tmp = calc_monster_critical(d_dice, d_side, damage);
1105 cut_plus = randint1(5);
1108 cut_plus = randint1(5) + 5;
1111 cut_plus = randint1(20) + 20;
1114 cut_plus = randint1(50) + 50;
1117 cut_plus = randint1(100) + 100;
1128 (void)set_cut(target_ptr, target_ptr->cut + cut_plus);
1131 if (monap_ptr->do_stun) {
1133 tmp = calc_monster_critical(d_dice, d_side, damage);
1139 stun_plus = randint1(5);
1142 stun_plus = randint1(5) + 10;
1145 stun_plus = randint1(10) + 20;
1148 stun_plus = randint1(15) + 30;
1151 stun_plus = randint1(20) + 40;
1162 (void)set_stun(target_ptr, target_ptr->stun + stun_plus);
1165 if (monap_ptr->explode) {
1166 sound(SOUND_EXPLODE);
1168 if (mon_take_hit(target_ptr, m_idx, monap_ptr->m_ptr->hp + 1, &fear, NULL)) {
1174 if (monap_ptr->touched) {
1175 if (target_ptr->sh_fire && alive && !target_ptr->is_dead) {
1176 if (!(r_ptr->flagsr & RFR_EFF_IM_FIRE_MASK)) {
1177 HIT_POINT dam = damroll(2, 6);
1178 dam = mon_damage_mod(target_ptr, monap_ptr->m_ptr, dam, FALSE);
1179 msg_format(_("%^sは突然熱くなった!", "%^s is suddenly very hot!"), m_name);
1180 if (mon_take_hit(target_ptr, m_idx, dam, &fear, _("は灰の山になった。", " turns into a pile of ash."))) {
1186 if (is_original_ap_and_seen(target_ptr, monap_ptr->m_ptr))
1187 r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_FIRE_MASK);
1191 if (target_ptr->sh_elec && alive && !target_ptr->is_dead) {
1192 if (!(r_ptr->flagsr & RFR_EFF_IM_ELEC_MASK)) {
1193 HIT_POINT dam = damroll(2, 6);
1194 dam = mon_damage_mod(target_ptr, monap_ptr->m_ptr, dam, FALSE);
1195 msg_format(_("%^sは電撃をくらった!", "%^s gets zapped!"), m_name);
1196 if (mon_take_hit(target_ptr, m_idx, dam, &fear, _("は燃え殻の山になった。", " turns into a pile of cinder."))) {
1201 if (is_original_ap_and_seen(target_ptr, monap_ptr->m_ptr))
1202 r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_ELEC_MASK);
1206 if (target_ptr->sh_cold && alive && !target_ptr->is_dead) {
1207 if (!(r_ptr->flagsr & RFR_EFF_IM_COLD_MASK)) {
1208 HIT_POINT dam = damroll(2, 6);
1209 dam = mon_damage_mod(target_ptr, monap_ptr->m_ptr, dam, FALSE);
1210 msg_format(_("%^sは冷気をくらった!", "%^s is very cold!"), m_name);
1211 if (mon_take_hit(target_ptr, m_idx, dam, &fear, _("は凍りついた。", " was frozen."))) {
1216 if (is_original_ap_and_seen(target_ptr, monap_ptr->m_ptr))
1217 r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_IM_COLD_MASK);
1221 if (target_ptr->dustrobe && alive && !target_ptr->is_dead) {
1222 if (!(r_ptr->flagsr & RFR_EFF_RES_SHAR_MASK)) {
1223 HIT_POINT dam = damroll(2, 6);
1224 dam = mon_damage_mod(target_ptr, monap_ptr->m_ptr, dam, FALSE);
1225 msg_format(_("%^sは鏡の破片をくらった!", "%^s gets zapped!"), m_name);
1226 if (mon_take_hit(target_ptr, m_idx, dam, &fear, _("はズタズタになった。", " had torn to pieces."))) {
1231 if (is_original_ap_and_seen(target_ptr, monap_ptr->m_ptr))
1232 r_ptr->r_flagsr |= (r_ptr->flagsr & RFR_EFF_RES_SHAR_MASK);
1235 if (is_mirror_grid(&floor_ptr->grid_array[target_ptr->y][target_ptr->x])) {
1236 teleport_player(target_ptr, 10, TELEPORT_SPONTANEOUS);
1240 if (target_ptr->tim_sh_holy && alive && !target_ptr->is_dead) {
1241 if (r_ptr->flags3 & RF3_EVIL) {
1242 if (!(r_ptr->flagsr & RFR_RES_ALL)) {
1243 HIT_POINT dam = damroll(2, 6);
1244 dam = mon_damage_mod(target_ptr, monap_ptr->m_ptr, dam, FALSE);
1245 msg_format(_("%^sは聖なるオーラで傷ついた!", "%^s is injured by holy power!"), m_name);
1246 if (mon_take_hit(target_ptr, m_idx, dam, &fear, _("は倒れた。", " is destroyed."))) {
1250 if (is_original_ap_and_seen(target_ptr, monap_ptr->m_ptr))
1251 r_ptr->r_flags3 |= RF3_EVIL;
1253 if (is_original_ap_and_seen(target_ptr, monap_ptr->m_ptr))
1254 r_ptr->r_flagsr |= RFR_RES_ALL;
1259 if (target_ptr->tim_sh_touki && alive && !target_ptr->is_dead) {
1260 if (!(r_ptr->flagsr & RFR_RES_ALL)) {
1261 HIT_POINT dam = damroll(2, 6);
1262 dam = mon_damage_mod(target_ptr, monap_ptr->m_ptr, dam, FALSE);
1263 msg_format(_("%^sが鋭い闘気のオーラで傷ついた!", "%^s is injured by the Force"), m_name);
1264 if (mon_take_hit(target_ptr, m_idx, dam, &fear, _("は倒れた。", " is destroyed."))) {
1269 if (is_original_ap_and_seen(target_ptr, monap_ptr->m_ptr))
1270 r_ptr->r_flagsr |= RFR_RES_ALL;
1274 if (hex_spelling(target_ptr, HEX_SHADOW_CLOAK) && alive && !target_ptr->is_dead) {
1276 object_type *o_armed_ptr = &target_ptr->inventory_list[INVEN_RARM];
1277 if (!(r_ptr->flagsr & RFR_RES_ALL || r_ptr->flagsr & RFR_RES_DARK)) {
1278 if (o_armed_ptr->k_idx) {
1279 int basedam = ((o_armed_ptr->dd + target_ptr->to_dd[0]) * (o_armed_ptr->ds + target_ptr->to_ds[0] + 1));
1280 dam = basedam / 2 + o_armed_ptr->to_d + target_ptr->to_d[0];
1283 o_armed_ptr = &target_ptr->inventory_list[INVEN_BODY];
1284 if ((o_armed_ptr->k_idx) && object_is_cursed(o_armed_ptr))
1287 dam = mon_damage_mod(target_ptr, monap_ptr->m_ptr, dam, FALSE);
1288 msg_format(_("影のオーラが%^sに反撃した!", "Enveloping shadows attack %^s."), m_name);
1289 if (mon_take_hit(target_ptr, m_idx, dam, &fear, _("は倒れた。", " is destroyed."))) {
1292 } else /* monster does not dead */
1295 BIT_FLAGS flg = PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL;
1297 = { { INVEN_HEAD, GF_OLD_CONF }, { INVEN_LARM, GF_OLD_SLEEP }, { INVEN_HANDS, GF_TURN_ALL }, { INVEN_FEET, GF_OLD_SLOW } };
1299 /* Some cursed armours gives an extra effect */
1300 for (j = 0; j < 4; j++) {
1301 o_armed_ptr = &target_ptr->inventory_list[typ[j][0]];
1302 if ((o_armed_ptr->k_idx) && object_is_cursed(o_armed_ptr) && object_is_armour(o_armed_ptr))
1303 project(target_ptr, 0, 0, monap_ptr->m_ptr->fy, monap_ptr->m_ptr->fx, (target_ptr->lev * 2), typ[j][1], flg, -1);
1307 if (is_original_ap_and_seen(target_ptr, monap_ptr->m_ptr))
1308 r_ptr->r_flagsr |= (RFR_RES_ALL | RFR_RES_DARK);
1314 switch (monap_ptr->method) {
1327 if (monap_ptr->m_ptr->ml) {
1328 disturb(target_ptr, TRUE, TRUE);
1330 if (monap_ptr->abbreviate)
1331 msg_format("%sかわした。", (target_ptr->special_attack & ATTACK_SUIKEN) ? "奇妙な動きで" : "");
1333 msg_format("%s%^sの攻撃をかわした。", (target_ptr->special_attack & ATTACK_SUIKEN) ? "奇妙な動きで" : "", m_name);
1335 monap_ptr->abbreviate = 1; /*2回目以降は省略 */
1337 msg_format("%^s misses you.", m_name);
1341 if (object_is_armour(&target_ptr->inventory_list[INVEN_RARM]) || object_is_armour(&target_ptr->inventory_list[INVEN_LARM])) {
1342 int cur = target_ptr->skill_exp[GINOU_SHIELD];
1343 int max = s_info[target_ptr->pclass].s_max[GINOU_SHIELD];
1345 DEPTH targetlevel = r_ptr->level;
1347 if ((cur / 100) < targetlevel) {
1348 if ((cur / 100 + 15) < targetlevel)
1349 inc += 1 + (targetlevel - (cur / 100 + 15));
1354 target_ptr->skill_exp[GINOU_SHIELD] = MIN(max, cur + inc);
1355 target_ptr->update |= (PU_BONUS);
1364 if (is_original_ap_and_seen(target_ptr, monap_ptr->m_ptr) && !do_silly_attack) {
1365 if (obvious || damage || (r_ptr->r_blows[ap_cnt] > 10)) {
1366 if (r_ptr->r_blows[ap_cnt] < MAX_UCHAR) {
1367 r_ptr->r_blows[ap_cnt]++;
1372 if (target_ptr->riding && damage) {
1373 char m_steed_name[MAX_NLEN];
1374 monster_desc(target_ptr, m_steed_name, &floor_ptr->m_list[target_ptr->riding], 0);
1375 if (process_fall_off_horse(target_ptr, (damage > 200) ? 200 : damage, FALSE)) {
1376 msg_format(_("%^sから落ちてしまった!", "You have fallen from %s."), m_steed_name);
1380 if (target_ptr->special_defense & NINJA_KAWARIMI) {
1381 if (kawarimi(target_ptr, FALSE))
1386 revenge_store(target_ptr, get_damage);
1387 if ((target_ptr->tim_eyeeye || hex_spelling(target_ptr, HEX_EYE_FOR_EYE)) && get_damage > 0 && !target_ptr->is_dead) {
1389 msg_format("攻撃が%s自身を傷つけた!", m_name);
1391 GAME_TEXT m_name_self[80];
1392 monster_desc(target_ptr, m_name_self, monap_ptr->m_ptr, MD_PRON_VISIBLE | MD_POSSESSIVE | MD_OBJECTIVE);
1393 msg_format("The attack of %s has wounded %s!", m_name, m_name_self);
1395 project(target_ptr, 0, 0, monap_ptr->m_ptr->fy, monap_ptr->m_ptr->fx, get_damage, GF_MISSILE, PROJECT_KILL, -1);
1396 if (target_ptr->tim_eyeeye)
1397 set_tim_eyeeye(target_ptr, target_ptr->tim_eyeeye - 5, TRUE);
1400 if ((target_ptr->counter || (target_ptr->special_defense & KATA_MUSOU)) && alive && !target_ptr->is_dead && monap_ptr->m_ptr->ml && (target_ptr->csp > 7)) {
1401 char m_target_name[MAX_NLEN];
1402 monster_desc(target_ptr, m_target_name, monap_ptr->m_ptr, 0);
1403 target_ptr->csp -= 7;
1404 msg_format(_("%^sに反撃した!", "You counterattacked %s!"), m_target_name);
1405 do_cmd_attack(target_ptr, monap_ptr->m_ptr->fy, monap_ptr->m_ptr->fx, HISSATSU_COUNTER);
1407 target_ptr->redraw |= (PR_MANA);
1410 if (blinked && alive && !target_ptr->is_dead) {
1411 if (teleport_barrier(target_ptr, m_idx)) {
1412 msg_print(_("泥棒は笑って逃げ...ようとしたがバリアに防がれた。", "The thief flees laughing...? But a magic barrier obstructs it."));
1414 msg_print(_("泥棒は笑って逃げた!", "The thief flees laughing!"));
1415 teleport_away(target_ptr, m_idx, MAX_SIGHT * 2 + 5, TELEPORT_SPONTANEOUS);
1419 if (target_ptr->is_dead && (r_ptr->r_deaths < MAX_SHORT) && !floor_ptr->inside_arena)
1422 if (monap_ptr->m_ptr->ml && fear && alive && !target_ptr->is_dead) {
1424 msg_format(_("%^sは恐怖で逃げ出した!", "%^s flees in terror!"), m_name);
1427 if (target_ptr->special_defense & KATA_IAI) {
1428 set_action(target_ptr, ACTION_NONE);