OSDN Git Service

[Refactor] enum classの型名変更 PlayerRaceFood -> PlayerRaceFoodType
[hengbandforosx/hengbandosx.git] / src / object-use / quaff-execution.cpp
1 /*!
2  * @brief 薬を飲んだ時の各種効果処理
3  * @date 2020/07/04
4  * @author Hourier
5  * @todo 少し長い。switch/case文と効果処理を分離してもいいかも
6  */
7
8 #include "object-use/quaff-execution.h"
9 #include "avatar/avatar.h"
10 #include "birth/birth-stat.h"
11 #include "core/player-update-types.h"
12 #include "core/window-redrawer.h"
13 #include "game-option/birth-options.h"
14 #include "game-option/disturbance-options.h"
15 #include "inventory/inventory-object.h"
16 #include "main/sound-definitions-table.h"
17 #include "main/sound-of-music.h"
18 #include "mutation/mutation-investor-remover.h"
19 #include "object-use/item-use-checker.h"
20 #include "object/object-broken.h"
21 #include "object/object-info.h"
22 #include "object/object-kind.h"
23 #include "perception/object-perception.h"
24 #include "player-base/player-race.h"
25 #include "player-info/mimic-info-table.h"
26 #include "player-info/self-info.h"
27 #include "player-status/player-energy.h"
28 #include "player/attack-defense-types.h"
29 #include "player/digestion-processor.h"
30 #include "player/eldritch-horror.h"
31 #include "player/player-damage.h"
32 #include "player/player-status-flags.h"
33 #include "realm/realm-hex-numbers.h"
34 #include "spell-kind/spells-detection.h"
35 #include "spell-kind/spells-floor.h"
36 #include "spell-kind/spells-perception.h"
37 #include "spell-kind/spells-teleport.h"
38 #include "spell-realm/spells-hex.h"
39 #include "spell-realm/spells-song.h"
40 #include "spell/spells-status.h"
41 #include "status/bad-status-setter.h"
42 #include "status/base-status.h"
43 #include "status/body-improvement.h"
44 #include "status/buff-setter.h"
45 #include "status/element-resistance.h"
46 #include "status/experience.h"
47 #include "status/shape-changer.h"
48 #include "status/sight-setter.h"
49 #include "sv-definition/sv-potion-types.h"
50 #include "system/object-type-definition.h"
51 #include "system/player-type-definition.h"
52 #include "term/screen-processor.h"
53 #include "view/display-messages.h"
54
55 /*!
56  * @brief コンストラクタ
57  * @param player_ptr プレイヤーへの参照ポインタ
58  */
59 ObjectQuaffEntity::ObjectQuaffEntity(player_type *player_ptr)
60     : player_ptr(player_ptr)
61 {
62 }
63
64 /*!
65  * @brief 薬を飲む.
66  * @param item 飲む薬オブジェクトの所持品ID
67  * @details
68  * 効果発動のあと、食料タイプによって空腹度を少し充足する。
69  */
70 void ObjectQuaffEntity::execute(INVENTORY_IDX item)
71 {
72     PlayerEnergy(this->player_ptr).set_player_turn_energy(100);
73     if (!this->check_can_quaff()) {
74         return;
75     }
76
77     if (music_singing_any(this->player_ptr))
78         stop_singing(this->player_ptr);
79
80     SpellHex spell_hex(this->player_ptr);
81     if (spell_hex.is_spelling_any() && !spell_hex.is_spelling_specific(HEX_INHALE)) {
82         (void)SpellHex(this->player_ptr).stop_all_spells();
83     }
84
85     auto *o_ptr = ref_item(this->player_ptr, item);
86     object_type forge;
87     auto *q_ptr = &forge;
88     q_ptr->copy_from(o_ptr);
89     q_ptr->number = 1;
90     vary_item(this->player_ptr, item, -1);
91     sound(SOUND_QUAFF);
92     auto ident = false;
93     if (q_ptr->tval == ItemKindType::POTION) {
94         switch (q_ptr->sval) {
95         case SV_POTION_WATER:
96             msg_print(_("口の中がさっぱりした。", "That was refreshing."));
97             msg_print(_("のどの渇きが少しおさまった。", "You feel less thirsty."));
98             ident = true;
99             break;
100
101         case SV_POTION_APPLE_JUICE:
102             msg_print(_("甘くてサッパリとしていて、とてもおいしい。", "It's sweet, refreshing and very tasty."));
103             msg_print(_("のどの渇きが少しおさまった。", "You feel less thirsty."));
104             ident = true;
105             break;
106
107         case SV_POTION_SLIME_MOLD:
108             msg_print(_("なんとも不気味な味だ。", "That was strange."));
109             msg_print(_("のどの渇きが少しおさまった。", "You feel less thirsty."));
110             ident = true;
111             break;
112
113         case SV_POTION_SLOWNESS:
114             if (BadStatusSetter(this->player_ptr).slowness(randint1(25) + 15, false))
115                 ident = true;
116             break;
117
118         case SV_POTION_SALT_WATER: {
119             msg_print(_("うぇ!思わず吐いてしまった。", "The potion makes you vomit!"));
120             switch (PlayerRace(this->player_ptr).food()) {
121             case PlayerRaceFoodType::RATION:
122             case PlayerRaceFoodType::WATER:
123             case PlayerRaceFoodType::BLOOD:
124                 (void)set_food(this->player_ptr, PY_FOOD_STARVE - 1);
125                 break;
126             default:
127                 break;
128             }
129
130             BadStatusSetter bss(this->player_ptr);
131             (void)bss.poison(0);
132             (void)bss.mod_paralysis(4);
133             ident = true;
134             break;
135         }
136         case SV_POTION_POISON:
137             if (!(has_resist_pois(this->player_ptr) || is_oppose_pois(this->player_ptr))) {
138                 if (BadStatusSetter(this->player_ptr).mod_poison(randint0(15) + 10)) {
139                     ident = true;
140                 }
141             }
142             break;
143
144         case SV_POTION_BLINDNESS:
145             if (!has_resist_blind(this->player_ptr)) {
146                 if (BadStatusSetter(this->player_ptr).mod_blindness(randint0(100) + 100)) {
147                     ident = true;
148                 }
149             }
150             break;
151
152         case SV_POTION_BOOZE:
153             ident = booze();
154             break;
155
156         case SV_POTION_SLEEP:
157             if (this->player_ptr->free_act) {
158                 break;
159             }
160
161             msg_print(_("あなたは眠ってしまった。", "You fall asleep."));
162             if (ironman_nightmare) {
163                 msg_print(_("恐ろしい光景が頭に浮かんできた。", "A horrible vision enters your mind."));
164                 sanity_blast(this->player_ptr, nullptr, false);
165             }
166
167             if (BadStatusSetter(this->player_ptr).mod_paralysis(randint0(4) + 4)) {
168                 ident = true;
169             }
170
171             break;
172         case SV_POTION_LOSE_MEMORIES:
173             if (!this->player_ptr->hold_exp && (this->player_ptr->exp > 0)) {
174                 msg_print(_("過去の記憶が薄れていく気がする。", "You feel your memories fade."));
175                 chg_virtue(this->player_ptr, V_KNOWLEDGE, -5);
176
177                 lose_exp(this->player_ptr, this->player_ptr->exp / 4);
178                 ident = true;
179             }
180             break;
181
182         case SV_POTION_RUINATION:
183             msg_print(_("身も心も弱ってきて、精気が抜けていくようだ。", "Your nerves and muscles feel weak and lifeless!"));
184             take_hit(this->player_ptr, DAMAGE_LOSELIFE, damroll(10, 10), _("破滅の薬", "a potion of Ruination"));
185
186             (void)dec_stat(this->player_ptr, A_DEX, 25, true);
187             (void)dec_stat(this->player_ptr, A_WIS, 25, true);
188             (void)dec_stat(this->player_ptr, A_CON, 25, true);
189             (void)dec_stat(this->player_ptr, A_STR, 25, true);
190             (void)dec_stat(this->player_ptr, A_CHR, 25, true);
191             (void)dec_stat(this->player_ptr, A_INT, 25, true);
192             ident = true;
193             break;
194
195         case SV_POTION_DEC_STR:
196             if (do_dec_stat(this->player_ptr, A_STR))
197                 ident = true;
198             break;
199
200         case SV_POTION_DEC_INT:
201             if (do_dec_stat(this->player_ptr, A_INT))
202                 ident = true;
203             break;
204
205         case SV_POTION_DEC_WIS:
206             if (do_dec_stat(this->player_ptr, A_WIS))
207                 ident = true;
208             break;
209
210         case SV_POTION_DEC_DEX:
211             if (do_dec_stat(this->player_ptr, A_DEX))
212                 ident = true;
213             break;
214
215         case SV_POTION_DEC_CON:
216             if (do_dec_stat(this->player_ptr, A_CON))
217                 ident = true;
218             break;
219
220         case SV_POTION_DEC_CHR:
221             if (do_dec_stat(this->player_ptr, A_CHR))
222                 ident = true;
223             break;
224
225         case SV_POTION_DETONATIONS:
226             ident = detonation();
227             break;
228
229         case SV_POTION_DEATH:
230             chg_virtue(this->player_ptr, V_VITALITY, -1);
231             chg_virtue(this->player_ptr, V_UNLIFE, 5);
232             msg_print(_("死の予感が体中を駆けめぐった。", "A feeling of Death flows through your body."));
233             take_hit(this->player_ptr, DAMAGE_LOSELIFE, 5000, _("死の薬", "a potion of Death"));
234             ident = true;
235             break;
236
237         case SV_POTION_INFRAVISION:
238             if (set_tim_infra(this->player_ptr, this->player_ptr->tim_infra + 100 + randint1(100), false)) {
239                 ident = true;
240             }
241             break;
242
243         case SV_POTION_DETECT_INVIS:
244             if (set_tim_invis(this->player_ptr, this->player_ptr->tim_invis + 12 + randint1(12), false)) {
245                 ident = true;
246             }
247             break;
248
249         case SV_POTION_SLOW_POISON:
250             if (BadStatusSetter(this->player_ptr).poison(this->player_ptr->poisoned / 2))
251                 ident = true;
252             break;
253
254         case SV_POTION_CURE_POISON:
255             if (BadStatusSetter(this->player_ptr).poison(0))
256                 ident = true;
257             break;
258
259         case SV_POTION_BOLDNESS:
260             if (BadStatusSetter(this->player_ptr).afraidness(0))
261                 ident = true;
262             break;
263
264         case SV_POTION_SPEED:
265             if (!this->player_ptr->fast) {
266                 if (set_fast(this->player_ptr, randint1(25) + 15, false))
267                     ident = true;
268             } else {
269                 (void)set_fast(this->player_ptr, this->player_ptr->fast + 5, false);
270             }
271             break;
272
273         case SV_POTION_RESIST_HEAT:
274             if (set_oppose_fire(this->player_ptr, this->player_ptr->oppose_fire + randint1(10) + 10, false)) {
275                 ident = true;
276             }
277             break;
278
279         case SV_POTION_RESIST_COLD:
280             if (set_oppose_cold(this->player_ptr, this->player_ptr->oppose_cold + randint1(10) + 10, false)) {
281                 ident = true;
282             }
283             break;
284
285         case SV_POTION_HEROISM:
286             ident = heroism(this->player_ptr, 25);
287             break;
288
289         case SV_POTION_BESERK_STRENGTH:
290             ident = berserk(this->player_ptr, randint1(25) + 25);
291             break;
292
293         case SV_POTION_CURE_LIGHT:
294             ident = cure_light_wounds(this->player_ptr, 2, 8);
295             break;
296
297         case SV_POTION_CURE_SERIOUS:
298             ident = cure_serious_wounds(this->player_ptr, 4, 8);
299             break;
300
301         case SV_POTION_CURE_CRITICAL:
302             ident = cure_critical_wounds(this->player_ptr, damroll(6, 8));
303             break;
304
305         case SV_POTION_HEALING:
306             ident = cure_critical_wounds(this->player_ptr, 300);
307             break;
308
309         case SV_POTION_STAR_HEALING:
310             ident = cure_critical_wounds(this->player_ptr, 1200);
311             break;
312
313         case SV_POTION_LIFE:
314             ident = life_stream(this->player_ptr, true, true);
315             break;
316
317         case SV_POTION_RESTORE_MANA:
318             ident = restore_mana(this->player_ptr, true);
319             break;
320
321         case SV_POTION_RESTORE_EXP:
322             if (restore_level(this->player_ptr))
323                 ident = true;
324             break;
325
326         case SV_POTION_RES_STR:
327             if (do_res_stat(this->player_ptr, A_STR))
328                 ident = true;
329             break;
330
331         case SV_POTION_RES_INT:
332             if (do_res_stat(this->player_ptr, A_INT))
333                 ident = true;
334             break;
335
336         case SV_POTION_RES_WIS:
337             if (do_res_stat(this->player_ptr, A_WIS))
338                 ident = true;
339             break;
340
341         case SV_POTION_RES_DEX:
342             if (do_res_stat(this->player_ptr, A_DEX))
343                 ident = true;
344             break;
345
346         case SV_POTION_RES_CON:
347             if (do_res_stat(this->player_ptr, A_CON))
348                 ident = true;
349             break;
350
351         case SV_POTION_RES_CHR:
352             if (do_res_stat(this->player_ptr, A_CHR))
353                 ident = true;
354             break;
355
356         case SV_POTION_INC_STR:
357             if (do_inc_stat(this->player_ptr, A_STR))
358                 ident = true;
359             break;
360
361         case SV_POTION_INC_INT:
362             if (do_inc_stat(this->player_ptr, A_INT))
363                 ident = true;
364             break;
365
366         case SV_POTION_INC_WIS:
367             if (do_inc_stat(this->player_ptr, A_WIS))
368                 ident = true;
369             break;
370
371         case SV_POTION_INC_DEX:
372             if (do_inc_stat(this->player_ptr, A_DEX))
373                 ident = true;
374             break;
375
376         case SV_POTION_INC_CON:
377             if (do_inc_stat(this->player_ptr, A_CON))
378                 ident = true;
379             break;
380
381         case SV_POTION_INC_CHR:
382             if (do_inc_stat(this->player_ptr, A_CHR))
383                 ident = true;
384             break;
385
386         case SV_POTION_POLY_SELF:
387             do_poly_self(this->player_ptr);
388             ident = true;
389             break;
390
391         case SV_POTION_AUGMENTATION:
392             if (do_inc_stat(this->player_ptr, A_STR))
393                 ident = true;
394             if (do_inc_stat(this->player_ptr, A_INT))
395                 ident = true;
396             if (do_inc_stat(this->player_ptr, A_WIS))
397                 ident = true;
398             if (do_inc_stat(this->player_ptr, A_DEX))
399                 ident = true;
400             if (do_inc_stat(this->player_ptr, A_CON))
401                 ident = true;
402             if (do_inc_stat(this->player_ptr, A_CHR))
403                 ident = true;
404             break;
405
406         case SV_POTION_ENLIGHTENMENT:
407             msg_print(_("自分の置かれている状況が脳裏に浮かんできた...", "An image of your surroundings forms in your mind..."));
408             chg_virtue(this->player_ptr, V_KNOWLEDGE, 1);
409             chg_virtue(this->player_ptr, V_ENLIGHTEN, 1);
410             wiz_lite(this->player_ptr, false);
411             ident = true;
412             break;
413
414         case SV_POTION_STAR_ENLIGHTENMENT:
415             msg_print(_("更なる啓蒙を感じた...", "You begin to feel more enlightened..."));
416             chg_virtue(this->player_ptr, V_KNOWLEDGE, 1);
417             chg_virtue(this->player_ptr, V_ENLIGHTEN, 2);
418             msg_print(nullptr);
419             wiz_lite(this->player_ptr, false);
420             (void)do_inc_stat(this->player_ptr, A_INT);
421             (void)do_inc_stat(this->player_ptr, A_WIS);
422             (void)detect_traps(this->player_ptr, DETECT_RAD_DEFAULT, true);
423             (void)detect_doors(this->player_ptr, DETECT_RAD_DEFAULT);
424             (void)detect_stairs(this->player_ptr, DETECT_RAD_DEFAULT);
425             (void)detect_treasure(this->player_ptr, DETECT_RAD_DEFAULT);
426             (void)detect_objects_gold(this->player_ptr, DETECT_RAD_DEFAULT);
427             (void)detect_objects_normal(this->player_ptr, DETECT_RAD_DEFAULT);
428             identify_pack(this->player_ptr);
429             self_knowledge(this->player_ptr);
430             ident = true;
431             break;
432
433         case SV_POTION_SELF_KNOWLEDGE:
434             msg_print(_("自分自身のことが少しは分かった気がする...", "You begin to know yourself a little better..."));
435             msg_print(nullptr);
436             self_knowledge(this->player_ptr);
437             ident = true;
438             break;
439
440         case SV_POTION_EXPERIENCE:
441             if (this->player_ptr->prace == PlayerRaceType::ANDROID)
442                 break;
443             chg_virtue(this->player_ptr, V_ENLIGHTEN, 1);
444             if (this->player_ptr->exp < PY_MAX_EXP) {
445                 EXP ee = (this->player_ptr->exp / 2) + 10;
446                 if (ee > 100000L)
447                     ee = 100000L;
448                 msg_print(_("更に経験を積んだような気がする。", "You feel more experienced."));
449                 gain_exp(this->player_ptr, ee);
450                 ident = true;
451             }
452             break;
453
454         case SV_POTION_RESISTANCE:
455             (void)set_oppose_acid(this->player_ptr, this->player_ptr->oppose_acid + randint1(20) + 20, false);
456             (void)set_oppose_elec(this->player_ptr, this->player_ptr->oppose_elec + randint1(20) + 20, false);
457             (void)set_oppose_fire(this->player_ptr, this->player_ptr->oppose_fire + randint1(20) + 20, false);
458             (void)set_oppose_cold(this->player_ptr, this->player_ptr->oppose_cold + randint1(20) + 20, false);
459             (void)set_oppose_pois(this->player_ptr, this->player_ptr->oppose_pois + randint1(20) + 20, false);
460             ident = true;
461             break;
462
463         case SV_POTION_CURING:
464             if (true_healing(this->player_ptr, 50))
465                 ident = true;
466             break;
467
468         case SV_POTION_INVULNERABILITY:
469             (void)set_invuln(this->player_ptr, this->player_ptr->invuln + randint1(4) + 4, false);
470             ident = true;
471             break;
472
473         case SV_POTION_NEW_LIFE:
474             roll_hitdice(this->player_ptr, SPOP_NONE);
475             get_max_stats(this->player_ptr);
476             this->player_ptr->update |= PU_BONUS;
477             lose_all_mutations(this->player_ptr);
478             ident = true;
479             break;
480
481         case SV_POTION_NEO_TSUYOSHI:
482             (void)BadStatusSetter(this->player_ptr).hallucination(0);
483             (void)set_tsuyoshi(this->player_ptr, this->player_ptr->tsuyoshi + randint1(100) + 100, false);
484             ident = true;
485             break;
486
487         case SV_POTION_TSUYOSHI:
488             msg_print(_("「オクレ兄さん!」", "Brother OKURE!"));
489             msg_print(nullptr);
490             this->player_ptr->tsuyoshi = 1;
491             (void)set_tsuyoshi(this->player_ptr, 0, true);
492             if (!has_resist_chaos(this->player_ptr)) {
493                 (void)BadStatusSetter(this->player_ptr).hallucination(50 + randint1(50));
494             }
495             ident = true;
496             break;
497
498         case SV_POTION_POLYMORPH:
499             if (this->player_ptr->muta.any() && one_in_(23)) {
500                 lose_all_mutations(this->player_ptr);
501             } else {
502                 do {
503                     if (one_in_(2)) {
504                         if (gain_mutation(this->player_ptr, 0))
505                             ident = true;
506                     } else if (lose_mutation(this->player_ptr, 0))
507                         ident = true;
508                 } while (!ident || one_in_(2));
509             }
510             break;
511         }
512     }
513
514     if (PlayerRace(this->player_ptr).equals(PlayerRaceType::SKELETON)) {
515         msg_print(_("液体の一部はあなたのアゴを素通りして落ちた!", "Some of the fluid falls through your jaws!"));
516         (void)potion_smash_effect(this->player_ptr, 0, this->player_ptr->y, this->player_ptr->x, q_ptr->k_idx);
517     }
518
519     this->player_ptr->update |= PU_COMBINE | PU_REORDER;
520     if (!(q_ptr->is_aware())) {
521         chg_virtue(this->player_ptr, V_PATIENCE, -1);
522         chg_virtue(this->player_ptr, V_CHANCE, 1);
523         chg_virtue(this->player_ptr, V_KNOWLEDGE, -1);
524     }
525
526     /* The item has been tried */
527     object_tried(q_ptr);
528
529     /* An identification was made */
530     if (ident && !q_ptr->is_aware()) {
531         object_aware(this->player_ptr, q_ptr);
532         gain_exp(this->player_ptr, (k_info[q_ptr->k_idx].level + (this->player_ptr->lev >> 1)) / this->player_ptr->lev);
533     }
534
535     this->player_ptr->window_flags |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
536
537     if (PlayerRace(this->player_ptr).equals(PlayerRaceType::SKELETON))
538         return; //!< @note スケルトンは水分で飢えを満たせない
539
540     switch (PlayerRace(this->player_ptr).food()) {
541     case PlayerRaceFoodType::WATER:
542         msg_print(_("水分を取り込んだ。", "You are moistened."));
543         set_food(this->player_ptr, std::min<short>(this->player_ptr->food + q_ptr->pval + std::max<short>(0, q_ptr->pval * 10) + 2000, PY_FOOD_MAX - 1));
544         break;
545     case PlayerRaceFoodType::OIL:
546         if (q_ptr->tval == ItemKindType::FLASK) {
547             msg_print(_("オイルを補給した。", "You replenish yourself with the oil."));
548             set_food(this->player_ptr, this->player_ptr->food + 5000);
549         } else {
550             set_food(this->player_ptr, this->player_ptr->food + ((q_ptr->pval) / 20));
551         }
552         break;
553     case PlayerRaceFoodType::BLOOD:
554         (void)set_food(this->player_ptr, this->player_ptr->food + (q_ptr->pval / 10));
555         break;
556     case PlayerRaceFoodType::MANA:
557     case PlayerRaceFoodType::CORPSE:
558         set_food(this->player_ptr, this->player_ptr->food + ((q_ptr->pval) / 20));
559         break;
560     default:
561         (void)set_food(this->player_ptr, this->player_ptr->food + q_ptr->pval);
562         break;
563     }
564 }
565
566 bool ObjectQuaffEntity::check_can_quaff()
567 {
568     if (this->player_ptr->timewalk) {
569         if (flush_failure) {
570             flush();
571         }
572
573         msg_print(_("瓶から水が流れ出てこない!", "The potion doesn't flow out from the bottle."));
574         sound(SOUND_FAIL);
575         return false;
576     }
577
578     return ItemUseChecker(this->player_ptr).check_stun(_("朦朧としていて瓶の蓋を開けられなかった!", "You were not able to quaff it by the stun!"));
579 }
580
581 /*!
582  * @brief 酔っ払いの薬
583  * @param player_ptr プレイヤーへの参照ポインタ
584  * @return カオス耐性があるかその他の一部確率でFALSE、それ以外はTRUE
585  */
586 bool ObjectQuaffEntity::booze()
587 {
588     bool ident = false;
589     if (this->player_ptr->pclass != PlayerClassType::MONK)
590         chg_virtue(this->player_ptr, V_HARMONY, -1);
591     else if (!has_resist_conf(this->player_ptr))
592         this->player_ptr->special_attack |= ATTACK_SUIKEN;
593
594     BadStatusSetter bss(this->player_ptr);
595     if (!has_resist_conf(this->player_ptr) && bss.confusion(randint0(20) + 15)) {
596         ident = true;
597     }
598
599     if (has_resist_chaos(this->player_ptr)) {
600         return ident;
601     }
602
603     if (one_in_(2) && bss.mod_hallucination(randint0(150) + 150)) {
604         ident = true;
605     }
606
607     if (one_in_(13) && (this->player_ptr->pclass != PlayerClassType::MONK)) {
608         ident = true;
609         if (one_in_(3))
610             lose_all_info(this->player_ptr);
611         else
612             wiz_dark(this->player_ptr);
613
614         (void)teleport_player_aux(this->player_ptr, 100, false, i2enum<teleport_flags>(TELEPORT_NONMAGICAL | TELEPORT_PASSIVE));
615         wiz_dark(this->player_ptr);
616         msg_print(_("知らない場所で目が醒めた。頭痛がする。", "You wake up somewhere with a sore head..."));
617         msg_print(_("何も思い出せない。どうやってここへ来たのかも分からない!", "You can't remember a thing or how you got here!"));
618     }
619
620     return ident;
621 }
622
623 /*!
624  * @brief 爆発の薬の効果処理 / Fumble ramble
625  * @param player_ptr プレイヤーへの参照ポインタ
626  * @return 常にTRUE
627  */
628 bool ObjectQuaffEntity::detonation()
629 {
630     msg_print(_("体の中で激しい爆発が起きた!", "Massive explosions rupture your body!"));
631     take_hit(this->player_ptr, DAMAGE_NOESCAPE, damroll(50, 20), _("爆発の薬", "a potion of Detonation"));
632     BadStatusSetter bss(this->player_ptr);
633     (void)bss.mod_stun(75);
634     (void)bss.mod_cut(5000);
635     return true;
636 }