OSDN Git Service

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