OSDN Git Service

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