OSDN Git Service

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