OSDN Git Service

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