OSDN Git Service

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