OSDN Git Service

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