7 #include "object-use/quaff/quaff-effects.h"
8 #include "avatar/avatar.h"
9 #include "birth/birth-stat.h"
10 #include "core/player-update-types.h"
11 #include "game-option/birth-options.h"
12 #include "mutation/mutation-investor-remover.h"
13 #include "object/object-info.h"
14 #include "player-base/player-class.h"
15 #include "player-base/player-race.h"
16 #include "player-info/race-info.h"
17 #include "player-info/self-info.h"
18 #include "player/attack-defense-types.h"
19 #include "player/digestion-processor.h"
20 #include "player/eldritch-horror.h"
21 #include "player/player-damage.h"
22 #include "player/player-status-flags.h"
23 #include "spell-kind/spells-detection.h"
24 #include "spell-kind/spells-floor.h"
25 #include "spell-kind/spells-perception.h"
26 #include "spell-kind/spells-teleport.h"
27 #include "spell/spells-status.h"
28 #include "status/bad-status-setter.h"
29 #include "status/base-status.h"
30 #include "status/body-improvement.h"
31 #include "status/buff-setter.h"
32 #include "status/element-resistance.h"
33 #include "status/experience.h"
34 #include "status/shape-changer.h"
35 #include "status/sight-setter.h"
36 #include "sv-definition/sv-potion-types.h"
37 #include "system/angband.h"
38 #include "system/object-type-definition.h"
39 #include "system/player-type-definition.h"
40 #include "timed-effect/player-acceleration.h"
41 #include "timed-effect/player-poison.h"
42 #include "timed-effect/timed-effects.h"
43 #include "util/bit-flags-calculator.h"
44 #include "view/display-messages.h"
46 QuaffEffects::QuaffEffects(PlayerType *player_ptr)
47 : player_ptr(player_ptr)
51 bool QuaffEffects::influence(const ObjectType &o_ref)
53 if (o_ref.tval != ItemKindType::POTION) {
59 msg_print(_("口の中がさっぱりした。", "That was refreshing."));
60 msg_print(_("のどの渇きが少しおさまった。", "You feel less thirsty."));
62 case SV_POTION_APPLE_JUICE:
63 msg_print(_("甘くてサッパリとしていて、とてもおいしい。", "It's sweet, refreshing and very tasty."));
64 msg_print(_("のどの渇きが少しおさまった。", "You feel less thirsty."));
66 case SV_POTION_SLIME_MOLD:
67 msg_print(_("なんとも不気味な味だ。", "That was strange."));
68 msg_print(_("のどの渇きが少しおさまった。", "You feel less thirsty."));
70 case SV_POTION_SLOWNESS:
71 return BadStatusSetter(this->player_ptr).set_deceleration(randint1(25) + 15, false);
72 case SV_POTION_SALT_WATER:
73 return this->salt_water();
74 case SV_POTION_POISON:
75 return this->poison();
76 case SV_POTION_BLINDNESS:
77 return this->blindness();
83 case SV_POTION_LOSE_MEMORIES:
84 return this->lose_memories();
85 case SV_POTION_RUINATION:
86 return this->ruination();
87 case SV_POTION_DEC_STR:
88 return do_dec_stat(this->player_ptr, A_STR);
89 case SV_POTION_DEC_INT:
90 return do_dec_stat(this->player_ptr, A_INT);
91 case SV_POTION_DEC_WIS:
92 return do_dec_stat(this->player_ptr, A_WIS);
93 case SV_POTION_DEC_DEX:
94 return do_dec_stat(this->player_ptr, A_DEX);
95 case SV_POTION_DEC_CON:
96 return do_dec_stat(this->player_ptr, A_CON);
97 case SV_POTION_DEC_CHR:
98 return do_dec_stat(this->player_ptr, A_CHR);
99 case SV_POTION_DETONATIONS:
100 return this->detonation();
101 case SV_POTION_DEATH:
102 return this->death();
103 case SV_POTION_INFRAVISION:
104 return set_tim_infra(this->player_ptr, this->player_ptr->tim_infra + 100 + randint1(100), false);
105 case SV_POTION_DETECT_INVIS:
106 return set_tim_invis(this->player_ptr, this->player_ptr->tim_invis + 12 + randint1(12), false);
107 case SV_POTION_SLOW_POISON: {
108 const auto player_poison = this->player_ptr->effects()->poison();
109 return BadStatusSetter(this->player_ptr).poison(player_poison->current() / 2);
111 case SV_POTION_CURE_POISON:
112 return BadStatusSetter(this->player_ptr).poison(0);
113 case SV_POTION_BOLDNESS:
114 return BadStatusSetter(this->player_ptr).fear(0);
115 case SV_POTION_SPEED:
116 return this->speed();
117 case SV_POTION_RESIST_HEAT:
118 return set_oppose_fire(this->player_ptr, this->player_ptr->oppose_fire + randint1(10) + 10, false);
119 case SV_POTION_RESIST_COLD:
120 return set_oppose_cold(this->player_ptr, this->player_ptr->oppose_cold + randint1(10) + 10, false);
121 case SV_POTION_HEROISM:
122 return heroism(this->player_ptr, 25);
123 case SV_POTION_BESERK_STRENGTH:
124 return berserk(this->player_ptr, randint1(25) + 25);
125 case SV_POTION_CURE_LIGHT:
126 return cure_light_wounds(this->player_ptr, 2, 8);
127 case SV_POTION_CURE_SERIOUS:
128 return cure_serious_wounds(this->player_ptr, 4, 8);
129 case SV_POTION_CURE_CRITICAL:
130 return cure_critical_wounds(this->player_ptr, damroll(6, 8));
131 case SV_POTION_HEALING:
132 return cure_critical_wounds(this->player_ptr, 300);
133 case SV_POTION_STAR_HEALING:
134 return cure_critical_wounds(this->player_ptr, 1200);
136 return life_stream(this->player_ptr, true, true);
137 case SV_POTION_RESTORE_MANA:
138 return restore_mana(this->player_ptr, true);
139 case SV_POTION_RESTORE_EXP:
140 return restore_level(this->player_ptr);
141 case SV_POTION_RES_STR:
142 return do_res_stat(this->player_ptr, A_STR);
143 case SV_POTION_RES_INT:
144 return do_res_stat(this->player_ptr, A_INT);
145 case SV_POTION_RES_WIS:
146 return do_res_stat(this->player_ptr, A_WIS);
147 case SV_POTION_RES_DEX:
148 return do_res_stat(this->player_ptr, A_DEX);
149 case SV_POTION_RES_CON:
150 return do_res_stat(this->player_ptr, A_CON);
151 case SV_POTION_RES_CHR:
152 return do_res_stat(this->player_ptr, A_CHR);
153 case SV_POTION_INC_STR:
154 return do_inc_stat(this->player_ptr, A_STR);
155 case SV_POTION_INC_INT:
156 return do_inc_stat(this->player_ptr, A_INT);
157 case SV_POTION_INC_WIS:
158 return do_inc_stat(this->player_ptr, A_WIS);
159 case SV_POTION_INC_DEX:
160 return do_inc_stat(this->player_ptr, A_DEX);
161 case SV_POTION_INC_CON:
162 return do_inc_stat(this->player_ptr, A_CON);
163 case SV_POTION_INC_CHR:
164 return do_inc_stat(this->player_ptr, A_CHR);
165 case SV_POTION_POLY_SELF:
166 do_poly_self(this->player_ptr);
168 case SV_POTION_AUGMENTATION:
169 return this->augmentation();
170 case SV_POTION_ENLIGHTENMENT:
171 return this->enlightenment();
172 case SV_POTION_STAR_ENLIGHTENMENT:
173 return this->star_enlightenment();
174 case SV_POTION_SELF_KNOWLEDGE:
175 msg_print(_("自分自身のことが少しは分かった気がする...", "You begin to know yourself a little better..."));
177 self_knowledge(this->player_ptr);
179 case SV_POTION_EXPERIENCE:
180 return this->experience();
181 case SV_POTION_RESISTANCE:
182 return this->resistance();
183 case SV_POTION_CURING:
184 return true_healing(this->player_ptr, 50);
185 case SV_POTION_INVULNERABILITY:
186 (void)set_invuln(this->player_ptr, this->player_ptr->invuln + randint1(4) + 4, false);
188 case SV_POTION_NEW_LIFE:
189 return this->new_life();
190 case SV_POTION_NEO_TSUYOSHI:
191 return this->neo_tsuyoshi();
192 case SV_POTION_TSUYOSHI:
193 return this->tsuyoshi();
194 case SV_POTION_POLYMORPH:
195 return this->polymorph();
205 bool QuaffEffects::salt_water()
207 msg_print(_("うぇ!思わず吐いてしまった。", "The potion makes you vomit!"));
208 switch (PlayerRace(this->player_ptr).food()) {
209 case PlayerRaceFoodType::RATION:
210 case PlayerRaceFoodType::WATER:
211 case PlayerRaceFoodType::BLOOD:
212 (void)set_food(this->player_ptr, PY_FOOD_STARVE - 1);
218 BadStatusSetter bss(this->player_ptr);
220 (void)bss.mod_paralysis(4);
226 * @return 毒の効果を受けたらtrue
228 bool QuaffEffects::poison()
230 if (has_resist_pois(this->player_ptr) || is_oppose_pois(this->player_ptr)) {
234 return BadStatusSetter(this->player_ptr).mod_poison(randint0(15) + 10);
239 * @return 盲目になったらtrue
241 bool QuaffEffects::blindness()
243 if (has_resist_blind(this->player_ptr)) {
247 return BadStatusSetter(this->player_ptr).mod_blindness(randint0(100) + 100);
252 * @return カオス耐性があるかその他の一部確率でFALSE、それ以外はTRUE
254 bool QuaffEffects::booze()
257 auto is_monk = PlayerClass(this->player_ptr).equals(PlayerClassType::MONK);
259 chg_virtue(this->player_ptr, V_HARMONY, -1);
260 } else if (!has_resist_conf(this->player_ptr)) {
261 set_bits(this->player_ptr->special_attack, ATTACK_SUIKEN);
264 BadStatusSetter bss(this->player_ptr);
265 if (!has_resist_conf(this->player_ptr) && bss.confusion(randint0(20) + 15)) {
269 if (has_resist_chaos(this->player_ptr)) {
273 if (one_in_(2) && bss.mod_hallucination(randint0(150) + 150)) {
277 if (!is_monk || !one_in_(13)) {
283 lose_all_info(this->player_ptr);
285 wiz_dark(this->player_ptr);
288 (void)teleport_player_aux(this->player_ptr, 100, false, i2enum<teleport_flags>(TELEPORT_NONMAGICAL | TELEPORT_PASSIVE));
289 wiz_dark(this->player_ptr);
290 msg_print(_("知らない場所で目が醒めた。頭痛がする。", "You wake up somewhere with a sore head..."));
291 msg_print(_("何も思い出せない。どうやってここへ来たのかも分からない!", "You can't remember a thing or how you got here!"));
299 bool QuaffEffects::sleep()
301 if (this->player_ptr->free_act) {
305 msg_print(_("あなたは眠ってしまった。", "You fall asleep."));
306 if (ironman_nightmare) {
307 msg_print(_("恐ろしい光景が頭に浮かんできた。", "A horrible vision enters your mind."));
308 sanity_blast(this->player_ptr, nullptr, false);
311 return BadStatusSetter(this->player_ptr).mod_paralysis(randint0(4) + 4);
318 bool QuaffEffects::lose_memories()
320 if (this->player_ptr->hold_exp || (this->player_ptr->exp <= 0)) {
324 msg_print(_("過去の記憶が薄れていく気がする。", "You feel your memories fade."));
325 chg_virtue(this->player_ptr, V_KNOWLEDGE, -5);
326 lose_exp(this->player_ptr, this->player_ptr->exp / 4);
334 bool QuaffEffects::ruination()
336 msg_print(_("身も心も弱ってきて、精気が抜けていくようだ。", "Your nerves and muscles feel weak and lifeless!"));
337 take_hit(this->player_ptr, DAMAGE_LOSELIFE, damroll(10, 10), _("破滅の薬", "a potion of Ruination"));
338 (void)dec_stat(this->player_ptr, A_DEX, 25, true);
339 (void)dec_stat(this->player_ptr, A_WIS, 25, true);
340 (void)dec_stat(this->player_ptr, A_CON, 25, true);
341 (void)dec_stat(this->player_ptr, A_STR, 25, true);
342 (void)dec_stat(this->player_ptr, A_CHR, 25, true);
343 (void)dec_stat(this->player_ptr, A_INT, 25, true);
348 * @brief 爆発の薬 / Fumble ramble
351 bool QuaffEffects::detonation()
353 msg_print(_("体の中で激しい爆発が起きた!", "Massive explosions rupture your body!"));
354 take_hit(this->player_ptr, DAMAGE_NOESCAPE, damroll(50, 20), _("爆発の薬", "a potion of Detonation"));
355 BadStatusSetter bss(this->player_ptr);
356 (void)bss.mod_stun(75);
357 (void)bss.mod_cut(5000);
365 bool QuaffEffects::death()
367 chg_virtue(this->player_ptr, V_VITALITY, -1);
368 chg_virtue(this->player_ptr, V_UNLIFE, 5);
369 msg_print(_("死の予感が体中を駆けめぐった。", "A feeling of Death flows through your body."));
370 take_hit(this->player_ptr, DAMAGE_LOSELIFE, 5000, _("死の薬", "a potion of Death"));
376 * @return 加速したらtrue、加速効果が切れていない状態で重ね飲みしたらfalse
378 bool QuaffEffects::speed()
380 if (this->player_ptr->effects()->acceleration()->is_fast()) {
381 (void)mod_acceleration(this->player_ptr, 5, false);
385 return set_acceleration(this->player_ptr, randint1(25) + 15, false);
390 * @return アビリティスコアのどれか1つでも向上したらtrue
392 bool QuaffEffects::augmentation()
395 if (do_inc_stat(this->player_ptr, A_STR)) {
399 if (do_inc_stat(this->player_ptr, A_INT)) {
403 if (do_inc_stat(this->player_ptr, A_WIS)) {
407 if (do_inc_stat(this->player_ptr, A_DEX)) {
411 if (do_inc_stat(this->player_ptr, A_CON)) {
415 if (do_inc_stat(this->player_ptr, A_CHR)) {
426 bool QuaffEffects::enlightenment()
428 msg_print(_("自分の置かれている状況が脳裏に浮かんできた...", "An image of your surroundings forms in your mind..."));
429 chg_virtue(this->player_ptr, V_KNOWLEDGE, 1);
430 chg_virtue(this->player_ptr, V_ENLIGHTEN, 1);
431 wiz_lite(this->player_ptr, false);
439 bool QuaffEffects::star_enlightenment()
441 msg_print(_("更なる啓蒙を感じた...", "You begin to feel more enlightened..."));
442 chg_virtue(this->player_ptr, V_KNOWLEDGE, 1);
443 chg_virtue(this->player_ptr, V_ENLIGHTEN, 2);
445 wiz_lite(this->player_ptr, false);
446 (void)do_inc_stat(this->player_ptr, A_INT);
447 (void)do_inc_stat(this->player_ptr, A_WIS);
448 (void)detect_traps(this->player_ptr, DETECT_RAD_DEFAULT, true);
449 (void)detect_doors(this->player_ptr, DETECT_RAD_DEFAULT);
450 (void)detect_stairs(this->player_ptr, DETECT_RAD_DEFAULT);
451 (void)detect_treasure(this->player_ptr, DETECT_RAD_DEFAULT);
452 (void)detect_objects_gold(this->player_ptr, DETECT_RAD_DEFAULT);
453 (void)detect_objects_normal(this->player_ptr, DETECT_RAD_DEFAULT);
454 identify_pack(this->player_ptr);
455 self_knowledge(this->player_ptr);
461 * @return 経験値が増えたらtrue
463 bool QuaffEffects::experience()
465 if (PlayerRace(this->player_ptr).equals(PlayerRaceType::ANDROID)) {
469 chg_virtue(this->player_ptr, V_ENLIGHTEN, 1);
470 if (this->player_ptr->exp >= PY_MAX_EXP) {
474 auto ee = (this->player_ptr->exp / 2) + 10;
475 constexpr int max_exp = 100000;
480 msg_print(_("更に経験を積んだような気がする。", "You feel more experienced."));
481 gain_exp(this->player_ptr, ee);
487 * @return 経験値が増えたらtrue
489 bool QuaffEffects::resistance()
491 (void)set_oppose_acid(this->player_ptr, this->player_ptr->oppose_acid + randint1(20) + 20, false);
492 (void)set_oppose_elec(this->player_ptr, this->player_ptr->oppose_elec + randint1(20) + 20, false);
493 (void)set_oppose_fire(this->player_ptr, this->player_ptr->oppose_fire + randint1(20) + 20, false);
494 (void)set_oppose_cold(this->player_ptr, this->player_ptr->oppose_cold + randint1(20) + 20, false);
495 (void)set_oppose_pois(this->player_ptr, this->player_ptr->oppose_pois + randint1(20) + 20, false);
503 bool QuaffEffects::new_life()
505 roll_hitdice(this->player_ptr, SPOP_NONE);
506 get_max_stats(this->player_ptr);
507 this->player_ptr->update |= PU_BONUS;
508 lose_all_mutations(this->player_ptr);
513 * @brief ネオ・つよしスペシャルの薬
516 bool QuaffEffects::neo_tsuyoshi()
518 (void)BadStatusSetter(this->player_ptr).hallucination(0);
519 (void)set_tsuyoshi(this->player_ptr, this->player_ptr->tsuyoshi + randint1(100) + 100, false);
527 bool QuaffEffects::tsuyoshi()
529 msg_print(_("「オクレ兄さん!」", "Brother OKURE!"));
531 this->player_ptr->tsuyoshi = 1;
532 (void)set_tsuyoshi(this->player_ptr, 0, true);
533 if (!has_resist_chaos(this->player_ptr)) {
534 (void)BadStatusSetter(this->player_ptr).hallucination(50 + randint1(50));
542 * @return 突然変異を得たか失ったらtrue、そのままならfalse
544 bool QuaffEffects::polymorph()
546 if (this->player_ptr->muta.any() && one_in_(23)) {
547 lose_all_mutations(this->player_ptr);
554 if (gain_mutation(this->player_ptr, 0)) {
557 } else if (lose_mutation(this->player_ptr, 0)) {
560 } while (!ident || one_in_(2));