OSDN Git Service

[Refactor] #1389 Changed monap_type from struct to class MonsterAttackPlayer
[hengbandforosx/hengbandosx.git] / src / monster-attack / monster-attack-status.cpp
1 /*!
2  * @brief プレイヤーのステータス (麻痺等)に影響を与えるモンスターの打撃処理
3  * @date 2020/05/31
4  * @author Hourier
5  */
6
7 #include "monster-attack/monster-attack-status.h"
8 #include "core/player-update-types.h"
9 #include "mind/mind-mirror-master.h"
10 #include "monster-attack/monster-attack-util.h"
11 #include "monster-race/monster-race.h"
12 #include "monster-race/race-indice-types.h"
13 #include "player/player-status-flags.h"
14 #include "status/bad-status-setter.h"
15 #include "status/base-status.h"
16 #include "status/experience.h"
17 #include "system/monster-race-definition.h"
18 #include "system/monster-type-definition.h"
19 #include "system/player-type-definition.h"
20 #include "timed-effect/timed-effects.h"
21 #include "view/display-messages.h"
22
23 void process_blind_attack(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
24 {
25     if (has_resist_blind(player_ptr) || check_multishadow(player_ptr)) {
26         return;
27     }
28
29     auto is_dio = monap_ptr->m_ptr->r_idx == MON_DIO;
30     auto dio_msg = _("どうだッ!この血の目潰しはッ!", "How is it! This blood-blinding!");
31     if (is_dio && player_ptr->prace == PlayerRaceType::SKELETON) {
32         msg_print(dio_msg);
33         msg_print(_("しかし、あなたには元々目はなかった!", "However, you don't have eyes!"));
34         return;
35     }
36
37     if (!BadStatusSetter(player_ptr).mod_blindness(10 + randint1(monap_ptr->rlev))) {
38         return;
39     }
40
41     if (is_dio) {
42         msg_print(dio_msg);
43     }
44
45     monap_ptr->obvious = true;
46 }
47
48 void process_terrify_attack(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
49 {
50     if (check_multishadow(player_ptr)) {
51         return;
52     }
53
54     auto *r_ptr = &r_info[monap_ptr->m_ptr->r_idx];
55     if (has_resist_fear(player_ptr)) {
56         msg_print(_("しかし恐怖に侵されなかった!", "You stand your ground!"));
57         monap_ptr->obvious = true;
58         return;
59     }
60
61     if (randint0(100 + r_ptr->level / 2) < player_ptr->skill_sav) {
62         msg_print(_("しかし恐怖に侵されなかった!", "You stand your ground!"));
63         monap_ptr->obvious = true;
64         return;
65     }
66
67     if (BadStatusSetter(player_ptr).mod_afraidness(3 + randint1(monap_ptr->rlev))) {
68         monap_ptr->obvious = true;
69     }
70 }
71
72 void process_paralyze_attack(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
73 {
74     if (check_multishadow(player_ptr)) {
75         return;
76     }
77
78     auto *r_ptr = &r_info[monap_ptr->m_ptr->r_idx];
79     if (player_ptr->free_act) {
80         msg_print(_("しかし効果がなかった!", "You are unaffected!"));
81         monap_ptr->obvious = true;
82         return;
83     }
84
85     if (randint0(100 + r_ptr->level / 2) < player_ptr->skill_sav) {
86         msg_print(_("しかし効力を跳ね返した!", "You resist the effects!"));
87         monap_ptr->obvious = true;
88         return;
89     }
90
91     if (!player_ptr->paralyzed && BadStatusSetter(player_ptr).paralysis(3 + randint1(monap_ptr->rlev))) {
92         monap_ptr->obvious = true;
93     }
94 }
95
96 void process_lose_all_attack(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
97 {
98     if (do_dec_stat(player_ptr, A_STR)) {
99         monap_ptr->obvious = true;
100     }
101
102     if (do_dec_stat(player_ptr, A_DEX)) {
103         monap_ptr->obvious = true;
104     }
105
106     if (do_dec_stat(player_ptr, A_CON)) {
107         monap_ptr->obvious = true;
108     }
109
110     if (do_dec_stat(player_ptr, A_INT)) {
111         monap_ptr->obvious = true;
112     }
113
114     if (do_dec_stat(player_ptr, A_WIS)) {
115         monap_ptr->obvious = true;
116     }
117
118     if (do_dec_stat(player_ptr, A_CHR)) {
119         monap_ptr->obvious = true;
120     }
121 }
122
123 void process_stun_attack(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
124 {
125     if (has_resist_sound(player_ptr) || check_multishadow(player_ptr)) {
126         return;
127     }
128
129     auto *r_ptr = &r_info[monap_ptr->m_ptr->r_idx];
130     if (BadStatusSetter(player_ptr).mod_stun(10 + randint1(r_ptr->level / 4))) {
131         monap_ptr->obvious = true;
132     }
133 }
134
135 /*!
136  * @brief 時間逆転攻撃による能力低下
137  * @param player_ptr プレイヤーへの参照ポインタ
138  * @monap_ptr モンスターからモンスターへの直接攻撃構造体への参照ポインタ
139  */
140 static void describe_disability(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
141 {
142     int stat = randint0(6);
143     switch (stat) {
144     case A_STR:
145         monap_ptr->act = _("強く", "strong");
146         break;
147     case A_INT:
148         monap_ptr->act = _("聡明で", "bright");
149         break;
150     case A_WIS:
151         monap_ptr->act = _("賢明で", "wise");
152         break;
153     case A_DEX:
154         monap_ptr->act = _("器用で", "agile");
155         break;
156     case A_CON:
157         monap_ptr->act = _("健康で", "hale");
158         break;
159     case A_CHR:
160         monap_ptr->act = _("美しく", "beautiful");
161         break;
162     }
163
164     msg_format(_("あなたは以前ほど%sなくなってしまった...。", "You're not as %s as you used to be..."), monap_ptr->act);
165     player_ptr->stat_cur[stat] = (player_ptr->stat_cur[stat] * 3) / 4;
166     if (player_ptr->stat_cur[stat] < 3) {
167         player_ptr->stat_cur[stat] = 3;
168     }
169 }
170
171 void process_monster_attack_time(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
172 {
173     if (has_resist_time(player_ptr) || check_multishadow(player_ptr)) {
174         return;
175     }
176
177     switch (randint1(10)) {
178     case 1:
179     case 2:
180     case 3:
181     case 4:
182     case 5:
183         if (player_ptr->prace == PlayerRaceType::ANDROID) {
184             break;
185         }
186
187         msg_print(_("人生が逆戻りした気がする。", "You feel like a chunk of the past has been ripped away."));
188         lose_exp(player_ptr, 100 + (player_ptr->exp / 100) * MON_DRAIN_LIFE);
189         break;
190     case 6:
191     case 7:
192     case 8:
193     case 9:
194         describe_disability(player_ptr, monap_ptr);
195         player_ptr->update |= (PU_BONUS);
196         break;
197     case 10:
198         msg_print(_("あなたは以前ほど力強くなくなってしまった...。", "You're not as powerful as you used to be..."));
199         for (auto i = 0; i < A_MAX; i++) {
200             player_ptr->stat_cur[i] = (player_ptr->stat_cur[i] * 7) / 8;
201             if (player_ptr->stat_cur[i] < 3) {
202                 player_ptr->stat_cur[i] = 3;
203             }
204         }
205
206         player_ptr->update |= PU_BONUS;
207         break;
208     }
209 }