OSDN Git Service

Merge pull request #3532 from sikabane-works/release/3.0.0.87-alpha
[hengbandforosx/hengbandosx.git] / src / monster-attack / monster-attack-lose.cpp
1 #include "monster-attack/monster-attack-lose.h"
2 #include "mind/mind-mirror-master.h"
3 #include "monster-attack/monster-attack-player.h"
4 #include "monster-attack/monster-attack-status.h"
5 #include "player-base/player-race.h"
6 #include "player/player-damage.h"
7 #include "player/player-status-flags.h"
8 #include "player/player-status-resist.h"
9 #include "status/bad-status-setter.h"
10 #include "status/base-status.h"
11 #include "status/element-resistance.h"
12 #include "system/player-type-definition.h"
13 #include "view/display-messages.h"
14
15 /*!
16  * @brief 病気ダメージを計算する (毒耐性があれば、(1d4 + 4) / 9になる。二重耐性なら更に(1d4 + 4) / 9)
17  * @param player_ptr プレイヤーへの参照ポインタ
18  * @param monap_ptr モンスターからプレイヤーへの直接攻撃構造体への参照ポインタ
19  * @details 10% (毒の一次耐性があれば4%、二重耐性ならば1.6%)の確率で耐久が低下し、更に1/10の確率で永久低下する
20  */
21 void calc_blow_disease(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
22 {
23     if (has_resist_pois(player_ptr)) {
24         monap_ptr->damage = monap_ptr->damage * (randint1(4) + 4) / 9;
25     }
26
27     if (is_oppose_pois(player_ptr)) {
28         monap_ptr->damage = monap_ptr->damage * (randint1(4) + 4) / 9;
29     }
30
31     monap_ptr->get_damage += take_hit(player_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc);
32     if (player_ptr->is_dead || check_multishadow(player_ptr)) {
33         return;
34     }
35
36     if (!(has_resist_pois(player_ptr) || is_oppose_pois(player_ptr)) && BadStatusSetter(player_ptr).mod_poison(randint1(monap_ptr->rlev) + 5)) {
37         monap_ptr->obvious = true;
38     }
39
40     bool disease_possibility = randint1(100) > calc_nuke_damage_rate(player_ptr);
41     if (disease_possibility || (randint1(100) > 10) || PlayerRace(player_ptr).equals(PlayerRaceType::ANDROID)) {
42         return;
43     }
44
45     bool perm = one_in_(10);
46     if (dec_stat(player_ptr, A_CON, randint1(10), perm)) {
47         msg_print(_("病があなたを蝕んでいる気がする。", "You feel sickly."));
48         monap_ptr->obvious = true;
49     }
50 }
51
52 /*!
53  * @brief 腕力低下ダメージを計算する (維持があれば、(1d4 + 4) / 9になる)
54  * @param player_ptr プレイヤーへの参照ポインタ
55  * @param monap_ptr モンスターからプレイヤーへの直接攻撃構造体への参照ポインタ
56  */
57 void calc_blow_lose_strength(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
58 {
59     if (has_sustain_str(player_ptr)) {
60         monap_ptr->get_damage = monap_ptr->get_damage * (randint1(4) + 4) / 9;
61     }
62
63     monap_ptr->get_damage += take_hit(player_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc);
64     if (player_ptr->is_dead || check_multishadow(player_ptr)) {
65         return;
66     }
67
68     if (do_dec_stat(player_ptr, A_STR)) {
69         monap_ptr->obvious = true;
70     }
71 }
72
73 /*!
74  * @brief 知能低下ダメージを計算する (維持があれば、(1d4 + 4) / 9になる)
75  * @param player_ptr プレイヤーへの参照ポインタ
76  * @param monap_ptr モンスターからプレイヤーへの直接攻撃構造体への参照ポインタ
77  */
78 void calc_blow_lose_intelligence(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
79 {
80     if (has_sustain_int(player_ptr)) {
81         monap_ptr->get_damage = monap_ptr->get_damage * (randint1(4) + 4) / 9;
82     }
83
84     monap_ptr->get_damage += take_hit(player_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc);
85     if (player_ptr->is_dead || check_multishadow(player_ptr)) {
86         return;
87     }
88
89     if (do_dec_stat(player_ptr, A_INT)) {
90         monap_ptr->obvious = true;
91     }
92 }
93
94 /*!
95  * @brief 賢さ低下ダメージを計算する (維持があれば、(1d4 + 4) / 9になる)
96  * @param player_ptr プレイヤーへの参照ポインタ
97  * @param monap_ptr モンスターからプレイヤーへの直接攻撃構造体への参照ポインタ
98  */
99 void calc_blow_lose_wisdom(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
100 {
101     if (has_sustain_wis(player_ptr)) {
102         monap_ptr->get_damage = monap_ptr->get_damage * (randint1(4) + 4) / 9;
103     }
104
105     monap_ptr->get_damage += take_hit(player_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc);
106     if (player_ptr->is_dead || check_multishadow(player_ptr)) {
107         return;
108     }
109
110     if (do_dec_stat(player_ptr, A_WIS)) {
111         monap_ptr->obvious = true;
112     }
113 }
114
115 /*!
116  * @brief 器用低下ダメージを計算する (維持があれば、(1d4 + 4) / 9になる)
117  * @param player_ptr プレイヤーへの参照ポインタ
118  * @param monap_ptr モンスターからプレイヤーへの直接攻撃構造体への参照ポインタ
119  */
120 void calc_blow_lose_dexterity(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
121 {
122     if (has_sustain_dex(player_ptr)) {
123         monap_ptr->get_damage = monap_ptr->get_damage * (randint1(4) + 4) / 9;
124     }
125
126     monap_ptr->get_damage += take_hit(player_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc);
127     if (player_ptr->is_dead || check_multishadow(player_ptr)) {
128         return;
129     }
130
131     if (do_dec_stat(player_ptr, A_DEX)) {
132         monap_ptr->obvious = true;
133     }
134 }
135
136 /*!
137  * @brief 耐久低下ダメージを計算する (維持があれば、(1d4 + 4) / 9になる)
138  * @param player_ptr プレイヤーへの参照ポインタ
139  * @param monap_ptr モンスターからプレイヤーへの直接攻撃構造体への参照ポインタ
140  */
141 void calc_blow_lose_constitution(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
142 {
143     if (has_sustain_con(player_ptr)) {
144         monap_ptr->get_damage = monap_ptr->get_damage * (randint1(4) + 4) / 9;
145     }
146
147     monap_ptr->get_damage += take_hit(player_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc);
148     if (player_ptr->is_dead || check_multishadow(player_ptr)) {
149         return;
150     }
151
152     if (do_dec_stat(player_ptr, A_CON)) {
153         monap_ptr->obvious = true;
154     }
155 }
156
157 /*!
158  * @brief 魅力低下ダメージを計算する (維持があれば、(1d4 + 4) / 9になる)
159  * @param player_ptr プレイヤーへの参照ポインタ
160  * @param monap_ptr モンスターからプレイヤーへの直接攻撃構造体への参照ポインタ
161  */
162 void calc_blow_lose_charisma(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
163 {
164     if (has_sustain_chr(player_ptr)) {
165         monap_ptr->get_damage = monap_ptr->get_damage * (randint1(4) + 4) / 9;
166     }
167
168     monap_ptr->get_damage += take_hit(player_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc);
169     if (player_ptr->is_dead || check_multishadow(player_ptr)) {
170         return;
171     }
172
173     if (do_dec_stat(player_ptr, A_CHR)) {
174         monap_ptr->obvious = true;
175     }
176 }
177
178 /*!
179  * @brief 全能力低下ダメージを計算する (維持があれば、1つに付き-3%軽減する)
180  * @param player_ptr プレイヤーへの参照ポインタ
181  * @param monap_ptr モンスターからプレイヤーへの直接攻撃構造体への参照ポインタ
182  */
183 void calc_blow_lose_all(PlayerType *player_ptr, MonsterAttackPlayer *monap_ptr)
184 {
185     int damage_ratio = 100;
186     if (has_sustain_str(player_ptr)) {
187         damage_ratio -= 3;
188     }
189
190     if (has_sustain_int(player_ptr)) {
191         damage_ratio -= 3;
192     }
193
194     if (has_sustain_wis(player_ptr)) {
195         damage_ratio -= 3;
196     }
197
198     if (has_sustain_dex(player_ptr)) {
199         damage_ratio -= 3;
200     }
201
202     if (has_sustain_con(player_ptr)) {
203         damage_ratio -= 3;
204     }
205
206     if (has_sustain_chr(player_ptr)) {
207         damage_ratio -= 3;
208     }
209
210     monap_ptr->damage = monap_ptr->damage * damage_ratio / 100;
211     monap_ptr->get_damage += take_hit(player_ptr, DAMAGE_ATTACK, monap_ptr->damage, monap_ptr->ddesc);
212     if (player_ptr->is_dead || check_multishadow(player_ptr)) {
213         return;
214     }
215
216     process_lose_all_attack(player_ptr, monap_ptr);
217 }