OSDN Git Service

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