2 * @brief モンスターからプレーヤーへの直接攻撃をその種別において振り分ける
5 * @details 長い処理はインクルード先の別ファイルにて行っている
8 #include "monster-attack/monster-attack-switcher.h"
9 #include "inventory/inventory-slot-types.h"
10 #include "mind/drs-types.h"
11 #include "mind/mind-mirror-master.h"
12 #include "monster-attack/monster-attack-status.h"
13 #include "monster-attack/monster-eating.h"
14 #include "monster/monster-status.h"
15 #include "monster/monster-update.h"
16 #include "player/player-damage.h"
17 #include "player/player-status-flags.h"
18 #include "player/player-status-resist.h"
19 #include "spell-kind/earthquake.h"
20 #include "spell-kind/spells-equipment.h"
21 #include "status/bad-status-setter.h"
22 #include "status/base-status.h"
23 #include "status/element-resistance.h"
24 #include "status/experience.h"
25 #include "system/object-type-definition.h"
26 #include "view/display-messages.h"
30 * @param target_ptr プレーヤーへの参照ポインタ
31 * @param monap_ptr モンスターからプレーヤーへの直接攻撃構造体への参照ポインタ
33 * @detail 減衰の計算式がpoisではなくnukeなのは仕様 (1/3では減衰が強すぎると判断したため)
35 static void calc_blow_poison(player_type *target_ptr, monap_type *monap_ptr)
37 if (monap_ptr->explode)
40 if (!(target_ptr->resist_pois || is_oppose_pois(target_ptr)) && !check_multishadow(target_ptr)
41 && set_poisoned(target_ptr, target_ptr->poisoned + randint1(monap_ptr->rlev) + 5))
42 monap_ptr->obvious = TRUE;
44 monap_ptr->damage = monap_ptr->damage * calc_nuke_damage_rate(target_ptr) / 100;
45 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
46 update_smart_learn(target_ptr, monap_ptr->m_idx, DRS_POIS);
50 * @brief 劣化ダメージを計算する (耐性があれば、(1d4 + 4) / 9になる)
51 * @param target_ptr プレーヤーへの参照ポインタ
52 * @param monap_ptr モンスターからプレーヤーへの直接攻撃構造体への参照ポインタ
55 static void calc_blow_disenchant(player_type *target_ptr, monap_type *monap_ptr)
57 if (monap_ptr->explode)
60 if (!target_ptr->resist_disen && !check_multishadow(target_ptr) && apply_disenchant(target_ptr, 0)) {
61 update_creature(target_ptr);
62 monap_ptr->obvious = TRUE;
65 if (is_resist_disen(target_ptr))
66 monap_ptr->damage = monap_ptr->damage * (randint1(4) + 4) / 9;
68 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
69 update_smart_learn(target_ptr, monap_ptr->m_idx, DRS_DISEN);
72 void switch_monster_blow_to_player(player_type *target_ptr, monap_type *monap_ptr)
74 switch (monap_ptr->effect) {
76 monap_ptr->obvious = TRUE;
77 monap_ptr->damage = 0;
79 case RBE_SUPERHURT: { /* AC軽減あり / Player armor reduces total damage */
80 if (((randint1(monap_ptr->rlev * 2 + 300) > (monap_ptr->ac + 200)) || one_in_(13)) && !check_multishadow(target_ptr)) {
81 int tmp_damage = monap_ptr->damage - (monap_ptr->damage * ((monap_ptr->ac < 150) ? monap_ptr->ac : 150) / 250);
82 msg_print(_("痛恨の一撃!", "It was a critical hit!"));
83 tmp_damage = MAX(monap_ptr->damage, tmp_damage * 2);
84 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, tmp_damage, monap_ptr->ddesc, -1);
89 case RBE_HURT: { /* AC軽減あり / Player armor reduces total damage */
90 monap_ptr->obvious = TRUE;
91 monap_ptr->damage -= (monap_ptr->damage * ((monap_ptr->ac < 150) ? monap_ptr->ac : 150) / 250);
92 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
96 calc_blow_poison(target_ptr, monap_ptr);
99 calc_blow_disenchant(target_ptr, monap_ptr);
102 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
103 if (target_ptr->is_dead || check_multishadow(target_ptr))
106 for (int i = 0; i < 10; i++) {
107 INVENTORY_IDX i_idx = (INVENTORY_IDX)randint0(INVEN_PACK);
108 monap_ptr->o_ptr = &target_ptr->inventory_list[i_idx];
109 if (monap_ptr->o_ptr->k_idx == 0)
112 if (process_un_power(target_ptr, monap_ptr))
119 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
120 if (monster_confused_remaining(monap_ptr->m_ptr))
123 if (target_ptr->is_dead || check_multishadow(target_ptr))
126 monap_ptr->obvious = TRUE;
127 process_eat_gold(target_ptr, monap_ptr);
131 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
132 if (!check_eat_item(target_ptr, monap_ptr))
135 process_eat_item(target_ptr, monap_ptr);
140 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
141 if (target_ptr->is_dead || check_multishadow(target_ptr))
144 process_eat_food(target_ptr, monap_ptr);
148 monap_ptr->o_ptr = &target_ptr->inventory_list[INVEN_LITE];
149 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
150 if (target_ptr->is_dead || check_multishadow(target_ptr))
153 process_eat_lite(target_ptr, monap_ptr);
157 if (monap_ptr->explode)
160 monap_ptr->obvious = TRUE;
161 msg_print(_("酸を浴びせられた!", "You are covered in acid!"));
162 monap_ptr->get_damage += acid_dam(target_ptr, monap_ptr->damage, monap_ptr->ddesc, -1, FALSE);
163 update_creature(target_ptr);
164 update_smart_learn(target_ptr, monap_ptr->m_idx, DRS_ACID);
168 if (monap_ptr->explode)
170 monap_ptr->obvious = TRUE;
171 msg_print(_("電撃を浴びせられた!", "You are struck by electricity!"));
172 monap_ptr->get_damage += elec_dam(target_ptr, monap_ptr->damage, monap_ptr->ddesc, -1, FALSE);
173 update_smart_learn(target_ptr, monap_ptr->m_idx, DRS_ELEC);
177 if (monap_ptr->explode)
179 monap_ptr->obvious = TRUE;
180 msg_print(_("全身が炎に包まれた!", "You are enveloped in flames!"));
181 monap_ptr->get_damage += fire_dam(target_ptr, monap_ptr->damage, monap_ptr->ddesc, -1, FALSE);
182 update_smart_learn(target_ptr, monap_ptr->m_idx, DRS_FIRE);
186 if (monap_ptr->explode)
188 monap_ptr->obvious = TRUE;
189 msg_print(_("全身が冷気で覆われた!", "You are covered with frost!"));
190 monap_ptr->get_damage += cold_dam(target_ptr, monap_ptr->damage, monap_ptr->ddesc, -1, FALSE);
191 update_smart_learn(target_ptr, monap_ptr->m_idx, DRS_COLD);
195 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
196 if (target_ptr->is_dead)
199 process_blind_attack(target_ptr, monap_ptr);
200 update_smart_learn(target_ptr, monap_ptr->m_idx, DRS_BLIND);
204 if (monap_ptr->explode)
207 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
208 if (target_ptr->is_dead)
211 if (!target_ptr->resist_conf && !check_multishadow(target_ptr)) {
212 if (set_confused(target_ptr, target_ptr->confused + 3 + randint1(monap_ptr->rlev))) {
213 monap_ptr->obvious = TRUE;
217 update_smart_learn(target_ptr, monap_ptr->m_idx, DRS_CONF);
221 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
222 if (target_ptr->is_dead)
225 process_terrify_attack(target_ptr, monap_ptr);
226 update_smart_learn(target_ptr, monap_ptr->m_idx, DRS_FEAR);
230 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
232 if (target_ptr->is_dead)
235 process_paralyze_attack(target_ptr, monap_ptr);
236 update_smart_learn(target_ptr, monap_ptr->m_idx, DRS_FREE);
240 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
241 if (target_ptr->is_dead || check_multishadow(target_ptr))
244 if (do_dec_stat(target_ptr, A_STR))
245 monap_ptr->obvious = TRUE;
250 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
251 if (target_ptr->is_dead || check_multishadow(target_ptr))
254 if (do_dec_stat(target_ptr, A_INT))
255 monap_ptr->obvious = TRUE;
260 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
261 if (target_ptr->is_dead || check_multishadow(target_ptr))
264 if (do_dec_stat(target_ptr, A_WIS))
265 monap_ptr->obvious = TRUE;
270 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
271 if (target_ptr->is_dead || check_multishadow(target_ptr))
274 if (do_dec_stat(target_ptr, A_DEX))
275 monap_ptr->obvious = TRUE;
280 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
281 if (target_ptr->is_dead || check_multishadow(target_ptr))
284 if (do_dec_stat(target_ptr, A_CON))
285 monap_ptr->obvious = TRUE;
290 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
291 if (target_ptr->is_dead || check_multishadow(target_ptr))
294 if (do_dec_stat(target_ptr, A_CHR))
295 monap_ptr->obvious = TRUE;
300 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
301 if (target_ptr->is_dead || check_multishadow(target_ptr))
304 process_lose_all_attack(target_ptr, monap_ptr);
307 case RBE_SHATTER: { /* AC軽減あり / Player armor reduces total damage */
308 monap_ptr->obvious = TRUE;
309 monap_ptr->damage -= (monap_ptr->damage * ((monap_ptr->ac < 150) ? monap_ptr->ac : 150) / 250);
310 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
311 if (monap_ptr->damage > 23 || monap_ptr->explode)
312 earthquake(target_ptr, monap_ptr->m_ptr->fy, monap_ptr->m_ptr->fx, 8, monap_ptr->m_idx);
317 s32b d = damroll(10, 6) + (target_ptr->exp / 100) * MON_DRAIN_LIFE;
318 monap_ptr->obvious = TRUE;
319 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
320 if (target_ptr->is_dead || check_multishadow(target_ptr))
323 (void)drain_exp(target_ptr, d, d / 10, 95);
327 s32b d = damroll(20, 6) + (target_ptr->exp / 100) * MON_DRAIN_LIFE;
328 monap_ptr->obvious = TRUE;
329 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
330 if (target_ptr->is_dead || check_multishadow(target_ptr))
333 (void)drain_exp(target_ptr, d, d / 10, 90);
337 s32b d = damroll(40, 6) + (target_ptr->exp / 100) * MON_DRAIN_LIFE;
338 monap_ptr->obvious = TRUE;
339 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
340 if (target_ptr->is_dead || check_multishadow(target_ptr))
343 (void)drain_exp(target_ptr, d, d / 10, 75);
347 s32b d = damroll(80, 6) + (target_ptr->exp / 100) * MON_DRAIN_LIFE;
348 monap_ptr->obvious = TRUE;
349 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
350 if (target_ptr->is_dead || check_multishadow(target_ptr))
353 (void)drain_exp(target_ptr, d, d / 10, 50);
357 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
358 if (target_ptr->is_dead || check_multishadow(target_ptr))
361 if (!(target_ptr->resist_pois || is_oppose_pois(target_ptr))) {
362 if (set_poisoned(target_ptr, target_ptr->poisoned + randint1(monap_ptr->rlev) + 5)) {
363 monap_ptr->obvious = TRUE;
367 if ((randint1(100) < 11) && (target_ptr->prace != RACE_ANDROID)) {
368 bool perm = one_in_(10);
369 if (dec_stat(target_ptr, A_CON, randint1(10), perm)) {
370 msg_print(_("病があなたを蝕んでいる気がする。", "You feel sickly."));
371 monap_ptr->obvious = TRUE;
378 if (monap_ptr->explode)
381 process_monster_attack_time(target_ptr, monap_ptr);
382 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
386 s32b d = damroll(60, 6) + (target_ptr->exp / 100) * MON_DRAIN_LIFE;
387 monap_ptr->obvious = TRUE;
388 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
389 if (target_ptr->is_dead || check_multishadow(target_ptr))
392 bool resist_drain = check_drain_hp(target_ptr, d);
393 process_drain_life(target_ptr, monap_ptr, resist_drain);
397 monap_ptr->obvious = TRUE;
398 process_drain_mana(target_ptr, monap_ptr);
399 update_smart_learn(target_ptr, monap_ptr->m_idx, DRS_MANA);
403 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
404 if (target_ptr->is_dead)
407 if (check_multishadow(target_ptr)) {
410 if (set_slow(target_ptr, (target_ptr->slow + 4 + randint0(monap_ptr->rlev / 10)), FALSE)) {
411 monap_ptr->obvious = TRUE;
418 monap_ptr->get_damage += take_hit(target_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc, -1);
419 if (target_ptr->is_dead)
422 process_stun_attack(target_ptr, monap_ptr);