OSDN Git Service

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