OSDN Git Service

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