OSDN Git Service

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