OSDN Git Service

[Refactor] #37353 歌に関するマクロ定義を realm-song.h へ移動.
[hengband/hengband.git] / src / cmd-quaff.c
1 /*!
2  * @file cmd-quaff.c
3  * @brief プレイヤーの飲むコマンド実装
4  * @date 2018/09/07
5  * @details
6  * cmd6.cより分離。
7  */
8
9 #include "angband.h"
10 #include "util.h"
11
12 #include "birth.h"
13 #include "selfinfo.h"
14 #include "object-hook.h"
15 #include "mutation.h"
16 #include "avatar.h"
17 #include "spells.h"
18 #include "spells-status.h"
19 #include "player-status.h"
20 #include "player-effects.h"
21 #include "player-race.h"
22 #include "realm-hex.h"
23 #include "realm-song.h"
24 #include "spells-floor.h"
25 #include "object-broken.h"
26 #include "cmd-basic.h"
27 #include "floor.h"
28 #include "objectkind.h"
29
30 /*!
31  * @brief 薬を飲むコマンドのサブルーチン /
32  * Quaff a potion (from the pack or the floor)
33  * @param item 飲む薬オブジェクトの所持品ID
34  * @return なし
35  */
36 void do_cmd_quaff_potion_aux(INVENTORY_IDX item)
37 {
38         bool ident;
39         DEPTH lev;
40         object_type *o_ptr;
41         object_type forge;
42         object_type *q_ptr;
43
44         take_turn(p_ptr, 100);
45
46         if (p_ptr->timewalk)
47         {
48                 if (flush_failure) flush();
49                 msg_print(_("瓶から水が流れ出てこない!", "The potion doesn't flow out from a bottle."));
50
51                 sound(SOUND_FAIL);
52                 return;
53         }
54
55         if (music_singing_any()) stop_singing(p_ptr);
56         if (hex_spelling_any())
57         {
58                 if (!hex_spelling(HEX_INHAIL)) stop_hex_spell_all();
59         }
60
61         /* Get the item (in the pack) */
62         if (item >= 0)
63         {
64                 o_ptr = &p_ptr->inventory_list[item];
65         }
66
67         /* Get the item (on the floor) */
68         else
69         {
70                 o_ptr = &current_floor_ptr->o_list[0 - item];
71         }
72         q_ptr = &forge;
73
74         /* Obtain a local object */
75         object_copy(q_ptr, o_ptr);
76
77         /* Single object */
78         q_ptr->number = 1;
79
80         /* Reduce and describe p_ptr->inventory_list */
81         if (item >= 0)
82         {
83                 inven_item_increase(item, -1);
84                 inven_item_describe(item);
85                 inven_item_optimize(item);
86         }
87
88         /* Reduce and describe floor item */
89         else
90         {
91                 floor_item_increase(0 - item, -1);
92                 floor_item_describe(0 - item);
93                 floor_item_optimize(0 - item);
94         }
95
96         sound(SOUND_QUAFF);
97
98
99         /* Not identified yet */
100         ident = FALSE;
101
102         /* Object level */
103         lev = k_info[q_ptr->k_idx].level;
104
105         /* Analyze the potion */
106         if (q_ptr->tval == TV_POTION)
107         {
108                 switch (q_ptr->sval)
109                 {
110                         /* 飲みごたえをオリジナルより細かく表現 */
111                 case SV_POTION_WATER:
112                         msg_print(_("口の中がさっぱりした。", ""));
113                         msg_print(_("のどの渇きが少しおさまった。", "You feel less thirsty."));
114                         ident = TRUE;
115                         break;
116
117                 case SV_POTION_APPLE_JUICE:
118                         msg_print(_("甘くてサッパリとしていて、とてもおいしい。", ""));
119                         msg_print(_("のどの渇きが少しおさまった。", "You feel less thirsty."));
120                         ident = TRUE;
121                         break;
122
123                 case SV_POTION_SLIME_MOLD:
124                         msg_print(_("なんとも不気味な味だ。", ""));
125                         msg_print(_("のどの渇きが少しおさまった。", "You feel less thirsty."));
126                         ident = TRUE;
127                         break;
128
129                 case SV_POTION_SLOWNESS:
130                         if (set_slow(randint1(25) + 15, FALSE)) ident = TRUE;
131                         break;
132
133                 case SV_POTION_SALT_WATER:
134                         msg_print(_("うぇ!思わず吐いてしまった。", "The potion makes you vomit!"));
135
136                         if (!(prace_is_(RACE_GOLEM) ||
137                               prace_is_(RACE_ZOMBIE) ||
138                               prace_is_(RACE_DEMON) ||
139                               prace_is_(RACE_ANDROID) ||
140                               prace_is_(RACE_SPECTRE) ||
141                               (mimic_info[p_ptr->mimic_form].MIMIC_FLAGS & MIMIC_IS_NONLIVING)))
142                         {
143                                 /* Only living creatures get thirsty */
144                                 (void)set_food(PY_FOOD_STARVE - 1);
145                         }
146
147                         (void)set_poisoned(0);
148                         (void)set_paralyzed(p_ptr->paralyzed + 4);
149                         ident = TRUE;
150                         break;
151
152                 case SV_POTION_POISON:
153                         if (!(p_ptr->resist_pois || IS_OPPOSE_POIS()))
154                         {
155                                 if (set_poisoned(p_ptr->poisoned + randint0(15) + 10))
156                                 {
157                                         ident = TRUE;
158                                 }
159                         }
160                         break;
161
162                 case SV_POTION_BLINDNESS:
163                         if (!p_ptr->resist_blind)
164                         {
165                                 if (set_blind(p_ptr->blind + randint0(100) + 100))
166                                 {
167                                         ident = TRUE;
168                                 }
169                         }
170                         break;
171
172                 case SV_POTION_BOOZE:
173                         ident = booze(p_ptr);
174                         break;
175
176                 case SV_POTION_SLEEP:
177                         if (!p_ptr->free_act)
178                         {
179                                 msg_print(_("あなたは眠ってしまった。", "You fall asleep."));
180
181                                 if (ironman_nightmare)
182                                 {
183                                         msg_print(_("恐ろしい光景が頭に浮かんできた。", "A horrible vision enters your mind."));
184
185                                         /* Have some nightmares */
186                                         sanity_blast(NULL, FALSE);
187                                 }
188                                 if (set_paralyzed(p_ptr->paralyzed + randint0(4) + 4))
189                                 {
190                                         ident = TRUE;
191                                 }
192                         }
193                         break;
194
195                 case SV_POTION_LOSE_MEMORIES:
196                         if (!p_ptr->hold_exp && (p_ptr->exp > 0))
197                         {
198                                 msg_print(_("過去の記憶が薄れていく気がする。", "You feel your memories fade."));
199                                 chg_virtue(V_KNOWLEDGE, -5);
200
201                                 lose_exp(p_ptr->exp / 4);
202                                 ident = TRUE;
203                         }
204                         break;
205
206                 case SV_POTION_RUINATION:
207                         msg_print(_("身も心も弱ってきて、精気が抜けていくようだ。", "Your nerves and muscles feel weak and lifeless!"));
208                         take_hit(DAMAGE_LOSELIFE, damroll(10, 10), _("破滅の薬", "a potion of Ruination"), -1);
209
210                         (void)dec_stat(A_DEX, 25, TRUE);
211                         (void)dec_stat(A_WIS, 25, TRUE);
212                         (void)dec_stat(A_CON, 25, TRUE);
213                         (void)dec_stat(A_STR, 25, TRUE);
214                         (void)dec_stat(A_CHR, 25, TRUE);
215                         (void)dec_stat(A_INT, 25, TRUE);
216                         ident = TRUE;
217                         break;
218
219                 case SV_POTION_DEC_STR:
220                         if (do_dec_stat(A_STR)) ident = TRUE;
221                         break;
222
223                 case SV_POTION_DEC_INT:
224                         if (do_dec_stat(A_INT)) ident = TRUE;
225                         break;
226
227                 case SV_POTION_DEC_WIS:
228                         if (do_dec_stat(A_WIS)) ident = TRUE;
229                         break;
230
231                 case SV_POTION_DEC_DEX:
232                         if (do_dec_stat(A_DEX)) ident = TRUE;
233                         break;
234
235                 case SV_POTION_DEC_CON:
236                         if (do_dec_stat(A_CON)) ident = TRUE;
237                         break;
238
239                 case SV_POTION_DEC_CHR:
240                         if (do_dec_stat(A_CHR)) ident = TRUE;
241                         break;
242
243                 case SV_POTION_DETONATIONS:
244                         ident = detonation(p_ptr);
245                         break;
246
247                 case SV_POTION_DEATH:
248                         chg_virtue(V_VITALITY, -1);
249                         chg_virtue(V_UNLIFE, 5);
250                         msg_print(_("死の予感が体中を駆けめぐった。", "A feeling of Death flows through your body."));
251                         take_hit(DAMAGE_LOSELIFE, 5000, _("死の薬", "a potion of Death"), -1);
252                         ident = TRUE;
253                         break;
254
255                 case SV_POTION_INFRAVISION:
256                         if (set_tim_infra(p_ptr->tim_infra + 100 + randint1(100), FALSE))
257                         {
258                                 ident = TRUE;
259                         }
260                         break;
261
262                 case SV_POTION_DETECT_INVIS:
263                         if (set_tim_invis(p_ptr->tim_invis + 12 + randint1(12), FALSE))
264                         {
265                                 ident = TRUE;
266                         }
267                         break;
268
269                 case SV_POTION_SLOW_POISON:
270                         if (set_poisoned(p_ptr->poisoned / 2)) ident = TRUE;
271                         break;
272
273                 case SV_POTION_CURE_POISON:
274                         if (set_poisoned(0)) ident = TRUE;
275                         break;
276
277                 case SV_POTION_BOLDNESS:
278                         if (set_afraid(0)) ident = TRUE;
279                         break;
280
281                 case SV_POTION_SPEED:
282                         if (!p_ptr->fast)
283                         {
284                                 if (set_fast(randint1(25) + 15, FALSE)) ident = TRUE;
285                         }
286                         else
287                         {
288                                 (void)set_fast(p_ptr->fast + 5, FALSE);
289                         }
290                         break;
291
292                 case SV_POTION_RESIST_HEAT:
293                         if (set_oppose_fire(p_ptr->oppose_fire + randint1(10) + 10, FALSE))
294                         {
295                                 ident = TRUE;
296                         }
297                         break;
298
299                 case SV_POTION_RESIST_COLD:
300                         if (set_oppose_cold(p_ptr->oppose_cold + randint1(10) + 10, FALSE))
301                         {
302                                 ident = TRUE;
303                         }
304                         break;
305
306                 case SV_POTION_HEROISM:
307                         ident = heroism(25);
308                         break;
309
310                 case SV_POTION_BESERK_STRENGTH:
311                         ident = berserk(randint1(25) + 25);
312                         break;
313
314                 case SV_POTION_CURE_LIGHT:
315                         ident = cure_light_wounds(2, 8);
316                         break;
317
318                 case SV_POTION_CURE_SERIOUS:
319                         ident = cure_serious_wounds(4, 8);
320                         break;
321
322                 case SV_POTION_CURE_CRITICAL:
323                         ident = cure_critical_wounds(damroll(6, 8));
324                         break;
325
326                 case SV_POTION_HEALING:
327                         ident = cure_critical_wounds(300);
328                         break;
329
330                 case SV_POTION_STAR_HEALING:
331                         ident = cure_critical_wounds(1200);
332                         break;
333
334                 case SV_POTION_LIFE:
335                         ident = life_stream(TRUE, TRUE);
336                         break;
337
338                 case SV_POTION_RESTORE_MANA:
339                         ident = restore_mana(TRUE);
340                         break;
341
342                 case SV_POTION_RESTORE_EXP:
343                         if (restore_level()) ident = TRUE;
344                         break;
345
346                 case SV_POTION_RES_STR:
347                         if (do_res_stat(A_STR)) ident = TRUE;
348                         break;
349
350                 case SV_POTION_RES_INT:
351                         if (do_res_stat(A_INT)) ident = TRUE;
352                         break;
353
354                 case SV_POTION_RES_WIS:
355                         if (do_res_stat(A_WIS)) ident = TRUE;
356                         break;
357
358                 case SV_POTION_RES_DEX:
359                         if (do_res_stat(A_DEX)) ident = TRUE;
360                         break;
361
362                 case SV_POTION_RES_CON:
363                         if (do_res_stat(A_CON)) ident = TRUE;
364                         break;
365
366                 case SV_POTION_RES_CHR:
367                         if (do_res_stat(A_CHR)) ident = TRUE;
368                         break;
369
370                 case SV_POTION_INC_STR:
371                         if (do_inc_stat(A_STR)) ident = TRUE;
372                         break;
373
374                 case SV_POTION_INC_INT:
375                         if (do_inc_stat(A_INT)) ident = TRUE;
376                         break;
377
378                 case SV_POTION_INC_WIS:
379                         if (do_inc_stat(A_WIS)) ident = TRUE;
380                         break;
381
382                 case SV_POTION_INC_DEX:
383                         if (do_inc_stat(A_DEX)) ident = TRUE;
384                         break;
385
386                 case SV_POTION_INC_CON:
387                         if (do_inc_stat(A_CON)) ident = TRUE;
388                         break;
389
390                 case SV_POTION_INC_CHR:
391                         if (do_inc_stat(A_CHR)) ident = TRUE;
392                         break;
393
394                 case SV_POTION_AUGMENTATION:
395                         if (do_inc_stat(A_STR)) ident = TRUE;
396                         if (do_inc_stat(A_INT)) ident = TRUE;
397                         if (do_inc_stat(A_WIS)) ident = TRUE;
398                         if (do_inc_stat(A_DEX)) ident = TRUE;
399                         if (do_inc_stat(A_CON)) ident = TRUE;
400                         if (do_inc_stat(A_CHR)) ident = TRUE;
401                         break;
402
403                 case SV_POTION_ENLIGHTENMENT:
404                         msg_print(_("自分の置かれている状況が脳裏に浮かんできた...", "An image of your surroundings forms in your mind..."));
405                         chg_virtue(V_KNOWLEDGE, 1);
406                         chg_virtue(V_ENLIGHTEN, 1);
407                         wiz_lite(FALSE);
408                         ident = TRUE;
409                         break;
410
411                 case SV_POTION_STAR_ENLIGHTENMENT:
412                         msg_print(_("更なる啓蒙を感じた...", "You begin to feel more enlightened..."));
413                         chg_virtue(V_KNOWLEDGE, 1);
414                         chg_virtue(V_ENLIGHTEN, 2);
415                         msg_print(NULL);
416                         wiz_lite(FALSE);
417                         (void)do_inc_stat(A_INT);
418                         (void)do_inc_stat(A_WIS);
419                         (void)detect_traps(DETECT_RAD_DEFAULT, TRUE);
420                         (void)detect_doors(DETECT_RAD_DEFAULT);
421                         (void)detect_stairs(DETECT_RAD_DEFAULT);
422                         (void)detect_treasure(DETECT_RAD_DEFAULT);
423                         (void)detect_objects_gold(DETECT_RAD_DEFAULT);
424                         (void)detect_objects_normal(DETECT_RAD_DEFAULT);
425                         identify_pack();
426                         self_knowledge();
427                         ident = TRUE;
428                         break;
429
430                 case SV_POTION_SELF_KNOWLEDGE:
431                         msg_print(_("自分自身のことが少しは分かった気がする...", "You begin to know yourself a little better..."));
432                         msg_print(NULL);
433                         self_knowledge();
434                         ident = TRUE;
435                         break;
436
437                 case SV_POTION_EXPERIENCE:
438                         if (p_ptr->prace == RACE_ANDROID) break;
439                         chg_virtue(V_ENLIGHTEN, 1);
440                         if (p_ptr->exp < PY_MAX_EXP)
441                         {
442                                 EXP ee = (p_ptr->exp / 2) + 10;
443                                 if (ee > 100000L) ee = 100000L;
444                                 msg_print(_("更に経験を積んだような気がする。", "You feel more experienced."));
445                                 gain_exp(ee);
446                                 ident = TRUE;
447                         }
448                         break;
449
450                 case SV_POTION_RESISTANCE:
451                         (void)set_oppose_acid(p_ptr->oppose_acid + randint1(20) + 20, FALSE);
452                         (void)set_oppose_elec(p_ptr->oppose_elec + randint1(20) + 20, FALSE);
453                         (void)set_oppose_fire(p_ptr->oppose_fire + randint1(20) + 20, FALSE);
454                         (void)set_oppose_cold(p_ptr->oppose_cold + randint1(20) + 20, FALSE);
455                         (void)set_oppose_pois(p_ptr->oppose_pois + randint1(20) + 20, FALSE);
456                         ident = TRUE;
457                         break;
458
459                 case SV_POTION_CURING:
460                         if (true_healing(50)) ident = TRUE;
461                         break;
462
463                 case SV_POTION_INVULNERABILITY:
464                         (void)set_invuln(p_ptr->invuln + randint1(4) + 4, FALSE);
465                         ident = TRUE;
466                         break;
467
468                 case SV_POTION_NEW_LIFE:
469                         roll_hitdice(p_ptr, 0L);
470                         get_max_stats();
471                         p_ptr->update |= PU_BONUS;
472                         lose_all_mutations();
473                         ident = TRUE;
474                         break;
475
476                 case SV_POTION_NEO_TSUYOSHI:
477                         (void)set_image(0);
478                         (void)set_tsuyoshi(p_ptr->tsuyoshi + randint1(100) + 100, FALSE);
479                         ident = TRUE;
480                         break;
481
482                 case SV_POTION_TSUYOSHI:
483                         msg_print(_("「オクレ兄さん!」", "Brother OKURE!"));
484                         msg_print(NULL);
485                         p_ptr->tsuyoshi = 1;
486                         (void)set_tsuyoshi(0, TRUE);
487                         if (!p_ptr->resist_chaos)
488                         {
489                                 (void)set_image(50 + randint1(50));
490                         }
491                         ident = TRUE;
492                         break;
493                 
494                 case SV_POTION_POLYMORPH:
495                         if ((p_ptr->muta1 || p_ptr->muta2 || p_ptr->muta3) && one_in_(23))
496                         {
497                                 lose_all_mutations();
498                         }
499                         else
500                         {
501                                 do
502                                 {
503                                         if (one_in_(2))
504                                         {
505                                                 if(gain_mutation(p_ptr, 0)) ident = TRUE;
506                                         }
507                                         else if (lose_mutation(0)) ident = TRUE;
508                                 } while(!ident || one_in_(2));
509                         }
510                         break;
511                 }
512         }
513
514         if (prace_is_(RACE_SKELETON))
515         {
516                 msg_print(_("液体の一部はあなたのアゴを素通りして落ちた!", "Some of the fluid falls through your jaws!"));
517                 (void)potion_smash_effect(0, p_ptr->y, p_ptr->x, q_ptr->k_idx);
518         }
519         p_ptr->update |= (PU_COMBINE | PU_REORDER);
520
521         if (!(object_is_aware(q_ptr)))
522         {
523                 chg_virtue(V_PATIENCE, -1);
524                 chg_virtue(V_CHANCE, 1);
525                 chg_virtue(V_KNOWLEDGE, -1);
526         }
527
528         /* The item has been tried */
529         object_tried(q_ptr);
530
531         /* An identification was made */
532         if (ident && !object_is_aware(q_ptr))
533         {
534                 object_aware(q_ptr);
535                 gain_exp((lev + (p_ptr->lev >> 1)) / p_ptr->lev);
536         }
537
538         p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
539
540         /* Potions can feed the player */
541         switch (p_ptr->mimic_form)
542         {
543         case MIMIC_NONE:
544                 switch (p_ptr->prace)
545                 {
546                         case RACE_VAMPIRE:
547                                 (void)set_food(p_ptr->food + (q_ptr->pval / 10));
548                                 break;
549                         case RACE_SKELETON:
550                                 /* Do nothing */
551                                 break;
552                         case RACE_GOLEM:
553                         case RACE_ZOMBIE:
554                         case RACE_DEMON:
555                         case RACE_SPECTRE:
556                                 set_food(p_ptr->food + ((q_ptr->pval) / 20));
557                                 break;
558                         case RACE_ANDROID:
559                                 if (q_ptr->tval == TV_FLASK)
560                                 {
561                                         msg_print(_("オイルを補給した。", "You replenish yourself with the oil."));
562                                         set_food(p_ptr->food + 5000);
563                                 }
564                                 else
565                                 {
566                                         set_food(p_ptr->food + ((q_ptr->pval) / 20));
567                                 }
568                                 break;
569                         case RACE_ENT:
570                                 msg_print(_("水分を取り込んだ。", "You are moistened."));
571                                 set_food(MIN(p_ptr->food + q_ptr->pval + MAX(0, q_ptr->pval * 10) + 2000, PY_FOOD_MAX - 1));
572                                 break;
573                         default:
574                                 (void)set_food(p_ptr->food + q_ptr->pval);
575                                 break;
576                 }
577                 break;
578         case MIMIC_DEMON:
579         case MIMIC_DEMON_LORD:
580                 set_food(p_ptr->food + ((q_ptr->pval) / 20));
581                 break;
582         case MIMIC_VAMPIRE:
583                 (void)set_food(p_ptr->food + (q_ptr->pval / 10));
584                 break;
585         default:
586                 (void)set_food(p_ptr->food + q_ptr->pval);
587                 break;
588         }
589 }
590
591
592
593 /*!
594  * @brief 薬を飲むコマンドのメインルーチン /
595  * Quaff some potion (from the pack or floor)
596  * @return なし
597  */
598 void do_cmd_quaff_potion(void)
599 {
600         OBJECT_IDX item;
601         concptr q, s;
602
603         if (p_ptr->wild_mode)
604         {
605                 return;
606         }
607
608         if (cmd_limit_arena(p_ptr)) return;
609
610         if (p_ptr->special_defense & (KATA_MUSOU | KATA_KOUKIJIN))
611         {
612                 set_action(ACTION_NONE);
613         }
614
615         /* Restrict choices to potions */
616         item_tester_hook = item_tester_hook_quaff;
617
618         q = _("どの薬を飲みますか? ", "Quaff which potion? ");
619         s = _("飲める薬がない。", "You have no potions to quaff.");
620
621         if (!choose_object(&item, q, s, (USE_INVEN | USE_FLOOR))) return;
622
623         /* Quaff the potion */
624         do_cmd_quaff_potion_aux(item);
625 }