OSDN Git Service

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