OSDN Git Service

[Refactor] #38932 文字コードを UTF-8(BOM) / LF に統一。 / Unify UTF-8(BOM) + LF.
[hengband/hengband.git] / src / cmd-quaff.c
index 5a4d695..c4586ae 100644 (file)
-/*!\r
- * @file cmd-quaff.c\r
- * @brief プレイヤーの飲むコマンド実装\r
- * @date 2018/09/07\r
- * @details\r
- * cmd6.cより分離。\r
- */\r
-\r
-#include "angband.h"\r
-#include "selfinfo.h"\r
-#include "object-hook.h"\r
-#include "mutation.h"\r
-#include "avatar.h"\r
-#include "spells-status.h"\r
-#include "realm-hex.h"\r
-\r
-/*!\r
- * @brief 薬を飲むコマンドのサブルーチン /\r
- * Quaff a potion (from the pack or the floor)\r
- * @param item 飲む薬オブジェクトの所持品ID\r
- * @return なし\r
- */\r
-void do_cmd_quaff_potion_aux(INVENTORY_IDX item)\r
-{\r
-       bool ident;\r
-       DEPTH lev;\r
-       object_type *o_ptr;\r
-       object_type forge;\r
-       object_type *q_ptr;\r
-\r
-\r
-       if (p_ptr->timewalk)\r
-       {\r
-               if (flush_failure) flush();\r
-               msg_print(_("瓶から水が流れ出てこない!", "The potion doesn't flow out from a bottle."));\r
-\r
-               sound(SOUND_FAIL);\r
-               return;\r
-       }\r
-\r
-       if (music_singing_any()) stop_singing();\r
-       if (hex_spelling_any())\r
-       {\r
-               if (!hex_spelling(HEX_INHAIL)) stop_hex_spell_all();\r
-       }\r
-\r
-       /* Get the item (in the pack) */\r
-       if (item >= 0)\r
-       {\r
-               o_ptr = &inventory[item];\r
-       }\r
-\r
-       /* Get the item (on the floor) */\r
-       else\r
-       {\r
-               o_ptr = &o_list[0 - item];\r
-       }\r
-       q_ptr = &forge;\r
-\r
-       /* Obtain a local object */\r
-       object_copy(q_ptr, o_ptr);\r
-\r
-       /* Single object */\r
-       q_ptr->number = 1;\r
-\r
-       /* Reduce and describe inventory */\r
-       if (item >= 0)\r
-       {\r
-               inven_item_increase(item, -1);\r
-               inven_item_describe(item);\r
-               inven_item_optimize(item);\r
-       }\r
-\r
-       /* Reduce and describe floor item */\r
-       else\r
-       {\r
-               floor_item_increase(0 - item, -1);\r
-               floor_item_describe(0 - item);\r
-               floor_item_optimize(0 - item);\r
-       }\r
-\r
-       sound(SOUND_QUAFF);\r
-\r
-\r
-       /* Not identified yet */\r
-       ident = FALSE;\r
-\r
-       /* Object level */\r
-       lev = k_info[q_ptr->k_idx].level;\r
-\r
-       /* Analyze the potion */\r
-       if (q_ptr->tval == TV_POTION)\r
-       {\r
-               switch (q_ptr->sval)\r
-               {\r
-                       /* 飲みごたえをオリジナルより細かく表現 */\r
-               case SV_POTION_WATER:\r
-                       msg_print(_("口の中がさっぱりした。", ""));\r
-                       msg_print(_("のどの渇きが少しおさまった。", "You feel less thirsty."));\r
-                       ident = TRUE;\r
-                       break;\r
-\r
-               case SV_POTION_APPLE_JUICE:\r
-                       msg_print(_("甘くてサッパリとしていて、とてもおいしい。", ""));\r
-                       msg_print(_("のどの渇きが少しおさまった。", "You feel less thirsty."));\r
-                       ident = TRUE;\r
-                       break;\r
-\r
-               case SV_POTION_SLIME_MOLD:\r
-                       msg_print(_("なんとも不気味な味だ。", ""));\r
-                       msg_print(_("のどの渇きが少しおさまった。", "You feel less thirsty."));\r
-                       ident = TRUE;\r
-                       break;\r
-\r
-               case SV_POTION_SLOWNESS:\r
-                       if (set_slow(randint1(25) + 15, FALSE)) ident = TRUE;\r
-                       break;\r
-\r
-               case SV_POTION_SALT_WATER:\r
-                       msg_print(_("うぇ!思わず吐いてしまった。", "The potion makes you vomit!"));\r
-\r
-                       if (!(prace_is_(RACE_GOLEM) ||\r
-                             prace_is_(RACE_ZOMBIE) ||\r
-                             prace_is_(RACE_DEMON) ||\r
-                             prace_is_(RACE_ANDROID) ||\r
-                             prace_is_(RACE_SPECTRE) ||\r
-                             (mimic_info[p_ptr->mimic_form].MIMIC_FLAGS & MIMIC_IS_NONLIVING)))\r
-                       {\r
-                               /* Only living creatures get thirsty */\r
-                               (void)set_food(PY_FOOD_STARVE - 1);\r
-                       }\r
-\r
-                       (void)set_poisoned(0);\r
-                       (void)set_paralyzed(p_ptr->paralyzed + 4);\r
-                       ident = TRUE;\r
-                       break;\r
-\r
-               case SV_POTION_POISON:\r
-                       if (!(p_ptr->resist_pois || IS_OPPOSE_POIS()))\r
-                       {\r
-                               if (set_poisoned(p_ptr->poisoned + randint0(15) + 10))\r
-                               {\r
-                                       ident = TRUE;\r
-                               }\r
-                       }\r
-                       break;\r
-\r
-               case SV_POTION_BLINDNESS:\r
-                       if (!p_ptr->resist_blind)\r
-                       {\r
-                               if (set_blind(p_ptr->blind + randint0(100) + 100))\r
-                               {\r
-                                       ident = TRUE;\r
-                               }\r
-                       }\r
-                       break;\r
-\r
-               case SV_POTION_BOOZE:\r
-                       ident = booze(p_ptr);\r
-                       break;\r
-\r
-               case SV_POTION_SLEEP:\r
-                       if (!p_ptr->free_act)\r
-                       {\r
-                               msg_print(_("あなたは眠ってしまった。", "You fall asleep."));\r
-\r
-                               if (ironman_nightmare)\r
-                               {\r
-                                       msg_print(_("恐ろしい光景が頭に浮かんできた。", "A horrible vision enters your mind."));\r
-\r
-                                       /* Have some nightmares */\r
-                                       sanity_blast(NULL, FALSE);\r
-                               }\r
-                               if (set_paralyzed(p_ptr->paralyzed + randint0(4) + 4))\r
-                               {\r
-                                       ident = TRUE;\r
-                               }\r
-                       }\r
-                       break;\r
-\r
-               case SV_POTION_LOSE_MEMORIES:\r
-                       if (!p_ptr->hold_exp && (p_ptr->exp > 0))\r
-                       {\r
-                               msg_print(_("過去の記憶が薄れていく気がする。", "You feel your memories fade."));\r
-                               chg_virtue(V_KNOWLEDGE, -5);\r
-\r
-                               lose_exp(p_ptr->exp / 4);\r
-                               ident = TRUE;\r
-                       }\r
-                       break;\r
-\r
-               case SV_POTION_RUINATION:\r
-                       msg_print(_("身も心も弱ってきて、精気が抜けていくようだ。", "Your nerves and muscles feel weak and lifeless!"));\r
-                       take_hit(DAMAGE_LOSELIFE, damroll(10, 10), _("破滅の薬", "a potion of Ruination"), -1);\r
-\r
-                       (void)dec_stat(A_DEX, 25, TRUE);\r
-                       (void)dec_stat(A_WIS, 25, TRUE);\r
-                       (void)dec_stat(A_CON, 25, TRUE);\r
-                       (void)dec_stat(A_STR, 25, TRUE);\r
-                       (void)dec_stat(A_CHR, 25, TRUE);\r
-                       (void)dec_stat(A_INT, 25, TRUE);\r
-                       ident = TRUE;\r
-                       break;\r
-\r
-               case SV_POTION_DEC_STR:\r
-                       if (do_dec_stat(A_STR)) ident = TRUE;\r
-                       break;\r
-\r
-               case SV_POTION_DEC_INT:\r
-                       if (do_dec_stat(A_INT)) ident = TRUE;\r
-                       break;\r
-\r
-               case SV_POTION_DEC_WIS:\r
-                       if (do_dec_stat(A_WIS)) ident = TRUE;\r
-                       break;\r
-\r
-               case SV_POTION_DEC_DEX:\r
-                       if (do_dec_stat(A_DEX)) ident = TRUE;\r
-                       break;\r
-\r
-               case SV_POTION_DEC_CON:\r
-                       if (do_dec_stat(A_CON)) ident = TRUE;\r
-                       break;\r
-\r
-               case SV_POTION_DEC_CHR:\r
-                       if (do_dec_stat(A_CHR)) ident = TRUE;\r
-                       break;\r
-\r
-               case SV_POTION_DETONATIONS:\r
-                       ident = detonation(p_ptr);\r
-                       break;\r
-\r
-               case SV_POTION_DEATH:\r
-                       chg_virtue(V_VITALITY, -1);\r
-                       chg_virtue(V_UNLIFE, 5);\r
-                       msg_print(_("死の予感が体中を駆けめぐった。", "A feeling of Death flows through your body."));\r
-                       take_hit(DAMAGE_LOSELIFE, 5000, _("死の薬", "a potion of Death"), -1);\r
-                       ident = TRUE;\r
-                       break;\r
-\r
-               case SV_POTION_INFRAVISION:\r
-                       if (set_tim_infra(p_ptr->tim_infra + 100 + randint1(100), FALSE))\r
-                       {\r
-                               ident = TRUE;\r
-                       }\r
-                       break;\r
-\r
-               case SV_POTION_DETECT_INVIS:\r
-                       if (set_tim_invis(p_ptr->tim_invis + 12 + randint1(12), FALSE))\r
-                       {\r
-                               ident = TRUE;\r
-                       }\r
-                       break;\r
-\r
-               case SV_POTION_SLOW_POISON:\r
-                       if (set_poisoned(p_ptr->poisoned / 2)) ident = TRUE;\r
-                       break;\r
-\r
-               case SV_POTION_CURE_POISON:\r
-                       if (set_poisoned(0)) ident = TRUE;\r
-                       break;\r
-\r
-               case SV_POTION_BOLDNESS:\r
-                       if (set_afraid(0)) ident = TRUE;\r
-                       break;\r
-\r
-               case SV_POTION_SPEED:\r
-                       if (!p_ptr->fast)\r
-                       {\r
-                               if (set_fast(randint1(25) + 15, FALSE)) ident = TRUE;\r
-                       }\r
-                       else\r
-                       {\r
-                               (void)set_fast(p_ptr->fast + 5, FALSE);\r
-                       }\r
-                       break;\r
-\r
-               case SV_POTION_RESIST_HEAT:\r
-                       if (set_oppose_fire(p_ptr->oppose_fire + randint1(10) + 10, FALSE))\r
-                       {\r
-                               ident = TRUE;\r
-                       }\r
-                       break;\r
-\r
-               case SV_POTION_RESIST_COLD:\r
-                       if (set_oppose_cold(p_ptr->oppose_cold + randint1(10) + 10, FALSE))\r
-                       {\r
-                               ident = TRUE;\r
-                       }\r
-                       break;\r
-\r
-               case SV_POTION_HEROISM:\r
-                       ident = heroism(25);\r
-                       break;\r
-\r
-               case SV_POTION_BESERK_STRENGTH:\r
-                       ident = berserk(randint1(25) + 25);\r
-                       break;\r
-\r
-               case SV_POTION_CURE_LIGHT:\r
-                       ident = cure_light_wounds(2, 8);\r
-                       break;\r
-\r
-               case SV_POTION_CURE_SERIOUS:\r
-                       ident = cure_serious_wounds(4, 8);\r
-                       break;\r
-\r
-               case SV_POTION_CURE_CRITICAL:\r
-                       ident = cure_critical_wounds(damroll(6, 8));\r
-                       break;\r
-\r
-               case SV_POTION_HEALING:\r
-                       ident = cure_critical_wounds(300);\r
-                       break;\r
-\r
-               case SV_POTION_STAR_HEALING:\r
-                       ident = cure_critical_wounds(1200);\r
-                       break;\r
-\r
-               case SV_POTION_LIFE:\r
-                       ident = life_stream(TRUE, TRUE);\r
-                       break;\r
-\r
-               case SV_POTION_RESTORE_MANA:\r
-                       ident = restore_mana(TRUE);\r
-                       break;\r
-\r
-               case SV_POTION_RESTORE_EXP:\r
-                       if (restore_level()) ident = TRUE;\r
-                       break;\r
-\r
-               case SV_POTION_RES_STR:\r
-                       if (do_res_stat(A_STR)) ident = TRUE;\r
-                       break;\r
-\r
-               case SV_POTION_RES_INT:\r
-                       if (do_res_stat(A_INT)) ident = TRUE;\r
-                       break;\r
-\r
-               case SV_POTION_RES_WIS:\r
-                       if (do_res_stat(A_WIS)) ident = TRUE;\r
-                       break;\r
-\r
-               case SV_POTION_RES_DEX:\r
-                       if (do_res_stat(A_DEX)) ident = TRUE;\r
-                       break;\r
-\r
-               case SV_POTION_RES_CON:\r
-                       if (do_res_stat(A_CON)) ident = TRUE;\r
-                       break;\r
-\r
-               case SV_POTION_RES_CHR:\r
-                       if (do_res_stat(A_CHR)) ident = TRUE;\r
-                       break;\r
-\r
-               case SV_POTION_INC_STR:\r
-                       if (do_inc_stat(A_STR)) ident = TRUE;\r
-                       break;\r
-\r
-               case SV_POTION_INC_INT:\r
-                       if (do_inc_stat(A_INT)) ident = TRUE;\r
-                       break;\r
-\r
-               case SV_POTION_INC_WIS:\r
-                       if (do_inc_stat(A_WIS)) ident = TRUE;\r
-                       break;\r
-\r
-               case SV_POTION_INC_DEX:\r
-                       if (do_inc_stat(A_DEX)) ident = TRUE;\r
-                       break;\r
-\r
-               case SV_POTION_INC_CON:\r
-                       if (do_inc_stat(A_CON)) ident = TRUE;\r
-                       break;\r
-\r
-               case SV_POTION_INC_CHR:\r
-                       if (do_inc_stat(A_CHR)) ident = TRUE;\r
-                       break;\r
-\r
-               case SV_POTION_AUGMENTATION:\r
-                       if (do_inc_stat(A_STR)) ident = TRUE;\r
-                       if (do_inc_stat(A_INT)) ident = TRUE;\r
-                       if (do_inc_stat(A_WIS)) ident = TRUE;\r
-                       if (do_inc_stat(A_DEX)) ident = TRUE;\r
-                       if (do_inc_stat(A_CON)) ident = TRUE;\r
-                       if (do_inc_stat(A_CHR)) ident = TRUE;\r
-                       break;\r
-\r
-               case SV_POTION_ENLIGHTENMENT:\r
-                       msg_print(_("自分の置かれている状況が脳裏に浮かんできた...", "An image of your surroundings forms in your mind..."));\r
-                       chg_virtue(V_KNOWLEDGE, 1);\r
-                       chg_virtue(V_ENLIGHTEN, 1);\r
-                       wiz_lite(FALSE);\r
-                       ident = TRUE;\r
-                       break;\r
-\r
-               case SV_POTION_STAR_ENLIGHTENMENT:\r
-                       msg_print(_("更なる啓蒙を感じた...", "You begin to feel more enlightened..."));\r
-                       chg_virtue(V_KNOWLEDGE, 1);\r
-                       chg_virtue(V_ENLIGHTEN, 2);\r
-                       msg_print(NULL);\r
-                       wiz_lite(FALSE);\r
-                       (void)do_inc_stat(A_INT);\r
-                       (void)do_inc_stat(A_WIS);\r
-                       (void)detect_traps(DETECT_RAD_DEFAULT, TRUE);\r
-                       (void)detect_doors(DETECT_RAD_DEFAULT);\r
-                       (void)detect_stairs(DETECT_RAD_DEFAULT);\r
-                       (void)detect_treasure(DETECT_RAD_DEFAULT);\r
-                       (void)detect_objects_gold(DETECT_RAD_DEFAULT);\r
-                       (void)detect_objects_normal(DETECT_RAD_DEFAULT);\r
-                       identify_pack();\r
-                       self_knowledge();\r
-                       ident = TRUE;\r
-                       break;\r
-\r
-               case SV_POTION_SELF_KNOWLEDGE:\r
-                       msg_print(_("自分自身のことが少しは分かった気がする...", "You begin to know yourself a little better..."));\r
-                       msg_print(NULL);\r
-                       self_knowledge();\r
-                       ident = TRUE;\r
-                       break;\r
-\r
-               case SV_POTION_EXPERIENCE:\r
-                       if (p_ptr->prace == RACE_ANDROID) break;\r
-                       chg_virtue(V_ENLIGHTEN, 1);\r
-                       if (p_ptr->exp < PY_MAX_EXP)\r
-                       {\r
-                               s32b ee = (p_ptr->exp / 2) + 10;\r
-                               if (ee > 100000L) ee = 100000L;\r
-                               msg_print(_("更に経験を積んだような気がする。", "You feel more experienced."));\r
-                               gain_exp(ee);\r
-                               ident = TRUE;\r
-                       }\r
-                       break;\r
-\r
-               case SV_POTION_RESISTANCE:\r
-                       (void)set_oppose_acid(p_ptr->oppose_acid + randint1(20) + 20, FALSE);\r
-                       (void)set_oppose_elec(p_ptr->oppose_elec + randint1(20) + 20, FALSE);\r
-                       (void)set_oppose_fire(p_ptr->oppose_fire + randint1(20) + 20, FALSE);\r
-                       (void)set_oppose_cold(p_ptr->oppose_cold + randint1(20) + 20, FALSE);\r
-                       (void)set_oppose_pois(p_ptr->oppose_pois + randint1(20) + 20, FALSE);\r
-                       ident = TRUE;\r
-                       break;\r
-\r
-               case SV_POTION_CURING:\r
-                       if (true_healing(50)) ident = TRUE;\r
-                       break;\r
-\r
-               case SV_POTION_INVULNERABILITY:\r
-                       (void)set_invuln(p_ptr->invuln + randint1(4) + 4, FALSE);\r
-                       ident = TRUE;\r
-                       break;\r
-\r
-               case SV_POTION_NEW_LIFE:\r
-                       roll_hitdice(0L);\r
-                       get_max_stats();\r
-                       p_ptr->update |= PU_BONUS;\r
-                       lose_all_mutations();\r
-                       ident = TRUE;\r
-                       break;\r
-\r
-               case SV_POTION_NEO_TSUYOSHI:\r
-                       (void)set_image(0);\r
-                       (void)set_tsuyoshi(p_ptr->tsuyoshi + randint1(100) + 100, FALSE);\r
-                       ident = TRUE;\r
-                       break;\r
-\r
-               case SV_POTION_TSUYOSHI:\r
-                       msg_print(_("「オクレ兄さん!」", "Brother OKURE!"));\r
-                       msg_print(NULL);\r
-                       p_ptr->tsuyoshi = 1;\r
-                       (void)set_tsuyoshi(0, TRUE);\r
-                       if (!p_ptr->resist_chaos)\r
-                       {\r
-                               (void)set_image(50 + randint1(50));\r
-                       }\r
-                       ident = TRUE;\r
-                       break;\r
-               \r
-               case SV_POTION_POLYMORPH:\r
-                       if ((p_ptr->muta1 || p_ptr->muta2 || p_ptr->muta3) && one_in_(23))\r
-                       {\r
-                               lose_all_mutations();\r
-                       }\r
-                       else\r
-                       {\r
-                               do\r
-                               {\r
-                                       if (one_in_(2))\r
-                                       {\r
-                                               if(gain_random_mutation(0)) ident = TRUE;\r
-                                       }\r
-                                       else if (lose_mutation(0)) ident = TRUE;\r
-                               } while(!ident || one_in_(2));\r
-                       }\r
-                       break;\r
-               }\r
-       }\r
-\r
-       if (prace_is_(RACE_SKELETON))\r
-       {\r
-               msg_print(_("液体の一部はあなたのアゴを素通りして落ちた!", "Some of the fluid falls through your jaws!"));\r
-               (void)potion_smash_effect(0, p_ptr->y, p_ptr->x, q_ptr->k_idx);\r
-       }\r
-       p_ptr->update |= (PU_COMBINE | PU_REORDER);\r
-\r
-       if (!(object_is_aware(q_ptr)))\r
-       {\r
-               chg_virtue(V_PATIENCE, -1);\r
-               chg_virtue(V_CHANCE, 1);\r
-               chg_virtue(V_KNOWLEDGE, -1);\r
-       }\r
-\r
-       /* The item has been tried */\r
-       object_tried(q_ptr);\r
-\r
-       /* An identification was made */\r
-       if (ident && !object_is_aware(q_ptr))\r
-       {\r
-               object_aware(q_ptr);\r
-               gain_exp((lev + (p_ptr->lev >> 1)) / p_ptr->lev);\r
-       }\r
-\r
-       p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);\r
-\r
-       /* Potions can feed the player */\r
-       switch (p_ptr->mimic_form)\r
-       {\r
-       case MIMIC_NONE:\r
-               switch (p_ptr->prace)\r
-               {\r
-                       case RACE_VAMPIRE:\r
-                               (void)set_food(p_ptr->food + (q_ptr->pval / 10));\r
-                               break;\r
-                       case RACE_SKELETON:\r
-                               /* Do nothing */\r
-                               break;\r
-                       case RACE_GOLEM:\r
-                       case RACE_ZOMBIE:\r
-                       case RACE_DEMON:\r
-                       case RACE_SPECTRE:\r
-                               set_food(p_ptr->food + ((q_ptr->pval) / 20));\r
-                               break;\r
-                       case RACE_ANDROID:\r
-                               if (q_ptr->tval == TV_FLASK)\r
-                               {\r
-                                       msg_print(_("オイルを補給した。", "You replenish yourself with the oil."));\r
-                                       set_food(p_ptr->food + 5000);\r
-                               }\r
-                               else\r
-                               {\r
-                                       set_food(p_ptr->food + ((q_ptr->pval) / 20));\r
-                               }\r
-                               break;\r
-                       case RACE_ENT:\r
-                               msg_print(_("水分を取り込んだ。", "You are moistened."));\r
-                               set_food(MIN(p_ptr->food + q_ptr->pval + MAX(0, q_ptr->pval * 10) + 2000, PY_FOOD_MAX - 1));\r
-                               break;\r
-                       default:\r
-                               (void)set_food(p_ptr->food + q_ptr->pval);\r
-                               break;\r
-               }\r
-               break;\r
-       case MIMIC_DEMON:\r
-       case MIMIC_DEMON_LORD:\r
-               set_food(p_ptr->food + ((q_ptr->pval) / 20));\r
-               break;\r
-       case MIMIC_VAMPIRE:\r
-               (void)set_food(p_ptr->food + (q_ptr->pval / 10));\r
-               break;\r
-       default:\r
-               (void)set_food(p_ptr->food + q_ptr->pval);\r
-               break;\r
-       }\r
-}\r
-\r
-\r
-\r
-/*!\r
- * @brief 薬を飲むコマンドのメインルーチン /\r
- * Quaff some potion (from the pack or floor)\r
- * @return なし\r
- */\r
-void do_cmd_quaff_potion(void)\r
-{\r
-       OBJECT_IDX item;\r
-       concptr q, s;\r
-\r
-       if (p_ptr->wild_mode)\r
-       {\r
-               return;\r
-       }\r
-\r
-       if (cmd_limit_arena(p_ptr)) return;\r
-\r
-       if (p_ptr->special_defense & (KATA_MUSOU | KATA_KOUKIJIN))\r
-       {\r
-               set_action(ACTION_NONE);\r
-       }\r
-\r
-       /* Restrict choices to potions */\r
-       item_tester_hook = item_tester_hook_quaff;\r
-\r
-       q = _("どの薬を飲みますか? ", "Quaff which potion? ");\r
-       s = _("飲める薬がない。", "You have no potions to quaff.");\r
-\r
-       if (!choose_object(&item, q, s, (USE_INVEN | USE_FLOOR))) return;\r
-\r
-       /* Quaff the potion */\r
-       do_cmd_quaff_potion_aux(item);\r
-}\r
+/*!
+ * @file cmd-quaff.c
+ * @brief プレイヤーの飲むコマンド実装
+ * @date 2018/09/07
+ * @details
+ * cmd6.cより分離。
+ */
+
+#include "angband.h"
+#include "selfinfo.h"
+#include "object-hook.h"
+#include "mutation.h"
+#include "avatar.h"
+#include "spells-status.h"
+#include "realm-hex.h"
+
+/*!
+ * @brief 薬を飲むコマンドのサブルーチン /
+ * Quaff a potion (from the pack or the floor)
+ * @param item 飲む薬オブジェクトの所持品ID
+ * @return なし
+ */
+void do_cmd_quaff_potion_aux(INVENTORY_IDX item)
+{
+       bool ident;
+       DEPTH lev;
+       object_type *o_ptr;
+       object_type forge;
+       object_type *q_ptr;
+
+
+       if (p_ptr->timewalk)
+       {
+               if (flush_failure) flush();
+               msg_print(_("瓶から水が流れ出てこない!", "The potion doesn't flow out from a bottle."));
+
+               sound(SOUND_FAIL);
+               return;
+       }
+
+       if (music_singing_any()) stop_singing();
+       if (hex_spelling_any())
+       {
+               if (!hex_spelling(HEX_INHAIL)) stop_hex_spell_all();
+       }
+
+       /* Get the item (in the pack) */
+       if (item >= 0)
+       {
+               o_ptr = &inventory[item];
+       }
+
+       /* Get the item (on the floor) */
+       else
+       {
+               o_ptr = &o_list[0 - item];
+       }
+       q_ptr = &forge;
+
+       /* Obtain a local object */
+       object_copy(q_ptr, o_ptr);
+
+       /* Single object */
+       q_ptr->number = 1;
+
+       /* Reduce and describe inventory */
+       if (item >= 0)
+       {
+               inven_item_increase(item, -1);
+               inven_item_describe(item);
+               inven_item_optimize(item);
+       }
+
+       /* Reduce and describe floor item */
+       else
+       {
+               floor_item_increase(0 - item, -1);
+               floor_item_describe(0 - item);
+               floor_item_optimize(0 - item);
+       }
+
+       sound(SOUND_QUAFF);
+
+
+       /* Not identified yet */
+       ident = FALSE;
+
+       /* Object level */
+       lev = k_info[q_ptr->k_idx].level;
+
+       /* Analyze the potion */
+       if (q_ptr->tval == TV_POTION)
+       {
+               switch (q_ptr->sval)
+               {
+                       /* 飲みごたえをオリジナルより細かく表現 */
+               case SV_POTION_WATER:
+                       msg_print(_("口の中がさっぱりした。", ""));
+                       msg_print(_("のどの渇きが少しおさまった。", "You feel less thirsty."));
+                       ident = TRUE;
+                       break;
+
+               case SV_POTION_APPLE_JUICE:
+                       msg_print(_("甘くてサッパリとしていて、とてもおいしい。", ""));
+                       msg_print(_("のどの渇きが少しおさまった。", "You feel less thirsty."));
+                       ident = TRUE;
+                       break;
+
+               case SV_POTION_SLIME_MOLD:
+                       msg_print(_("なんとも不気味な味だ。", ""));
+                       msg_print(_("のどの渇きが少しおさまった。", "You feel less thirsty."));
+                       ident = TRUE;
+                       break;
+
+               case SV_POTION_SLOWNESS:
+                       if (set_slow(randint1(25) + 15, FALSE)) ident = TRUE;
+                       break;
+
+               case SV_POTION_SALT_WATER:
+                       msg_print(_("うぇ!思わず吐いてしまった。", "The potion makes you vomit!"));
+
+                       if (!(prace_is_(RACE_GOLEM) ||
+                             prace_is_(RACE_ZOMBIE) ||
+                             prace_is_(RACE_DEMON) ||
+                             prace_is_(RACE_ANDROID) ||
+                             prace_is_(RACE_SPECTRE) ||
+                             (mimic_info[p_ptr->mimic_form].MIMIC_FLAGS & MIMIC_IS_NONLIVING)))
+                       {
+                               /* Only living creatures get thirsty */
+                               (void)set_food(PY_FOOD_STARVE - 1);
+                       }
+
+                       (void)set_poisoned(0);
+                       (void)set_paralyzed(p_ptr->paralyzed + 4);
+                       ident = TRUE;
+                       break;
+
+               case SV_POTION_POISON:
+                       if (!(p_ptr->resist_pois || IS_OPPOSE_POIS()))
+                       {
+                               if (set_poisoned(p_ptr->poisoned + randint0(15) + 10))
+                               {
+                                       ident = TRUE;
+                               }
+                       }
+                       break;
+
+               case SV_POTION_BLINDNESS:
+                       if (!p_ptr->resist_blind)
+                       {
+                               if (set_blind(p_ptr->blind + randint0(100) + 100))
+                               {
+                                       ident = TRUE;
+                               }
+                       }
+                       break;
+
+               case SV_POTION_BOOZE:
+                       ident = booze(p_ptr);
+                       break;
+
+               case SV_POTION_SLEEP:
+                       if (!p_ptr->free_act)
+                       {
+                               msg_print(_("あなたは眠ってしまった。", "You fall asleep."));
+
+                               if (ironman_nightmare)
+                               {
+                                       msg_print(_("恐ろしい光景が頭に浮かんできた。", "A horrible vision enters your mind."));
+
+                                       /* Have some nightmares */
+                                       sanity_blast(NULL, FALSE);
+                               }
+                               if (set_paralyzed(p_ptr->paralyzed + randint0(4) + 4))
+                               {
+                                       ident = TRUE;
+                               }
+                       }
+                       break;
+
+               case SV_POTION_LOSE_MEMORIES:
+                       if (!p_ptr->hold_exp && (p_ptr->exp > 0))
+                       {
+                               msg_print(_("過去の記憶が薄れていく気がする。", "You feel your memories fade."));
+                               chg_virtue(V_KNOWLEDGE, -5);
+
+                               lose_exp(p_ptr->exp / 4);
+                               ident = TRUE;
+                       }
+                       break;
+
+               case SV_POTION_RUINATION:
+                       msg_print(_("身も心も弱ってきて、精気が抜けていくようだ。", "Your nerves and muscles feel weak and lifeless!"));
+                       take_hit(DAMAGE_LOSELIFE, damroll(10, 10), _("破滅の薬", "a potion of Ruination"), -1);
+
+                       (void)dec_stat(A_DEX, 25, TRUE);
+                       (void)dec_stat(A_WIS, 25, TRUE);
+                       (void)dec_stat(A_CON, 25, TRUE);
+                       (void)dec_stat(A_STR, 25, TRUE);
+                       (void)dec_stat(A_CHR, 25, TRUE);
+                       (void)dec_stat(A_INT, 25, TRUE);
+                       ident = TRUE;
+                       break;
+
+               case SV_POTION_DEC_STR:
+                       if (do_dec_stat(A_STR)) ident = TRUE;
+                       break;
+
+               case SV_POTION_DEC_INT:
+                       if (do_dec_stat(A_INT)) ident = TRUE;
+                       break;
+
+               case SV_POTION_DEC_WIS:
+                       if (do_dec_stat(A_WIS)) ident = TRUE;
+                       break;
+
+               case SV_POTION_DEC_DEX:
+                       if (do_dec_stat(A_DEX)) ident = TRUE;
+                       break;
+
+               case SV_POTION_DEC_CON:
+                       if (do_dec_stat(A_CON)) ident = TRUE;
+                       break;
+
+               case SV_POTION_DEC_CHR:
+                       if (do_dec_stat(A_CHR)) ident = TRUE;
+                       break;
+
+               case SV_POTION_DETONATIONS:
+                       ident = detonation(p_ptr);
+                       break;
+
+               case SV_POTION_DEATH:
+                       chg_virtue(V_VITALITY, -1);
+                       chg_virtue(V_UNLIFE, 5);
+                       msg_print(_("死の予感が体中を駆けめぐった。", "A feeling of Death flows through your body."));
+                       take_hit(DAMAGE_LOSELIFE, 5000, _("死の薬", "a potion of Death"), -1);
+                       ident = TRUE;
+                       break;
+
+               case SV_POTION_INFRAVISION:
+                       if (set_tim_infra(p_ptr->tim_infra + 100 + randint1(100), FALSE))
+                       {
+                               ident = TRUE;
+                       }
+                       break;
+
+               case SV_POTION_DETECT_INVIS:
+                       if (set_tim_invis(p_ptr->tim_invis + 12 + randint1(12), FALSE))
+                       {
+                               ident = TRUE;
+                       }
+                       break;
+
+               case SV_POTION_SLOW_POISON:
+                       if (set_poisoned(p_ptr->poisoned / 2)) ident = TRUE;
+                       break;
+
+               case SV_POTION_CURE_POISON:
+                       if (set_poisoned(0)) ident = TRUE;
+                       break;
+
+               case SV_POTION_BOLDNESS:
+                       if (set_afraid(0)) ident = TRUE;
+                       break;
+
+               case SV_POTION_SPEED:
+                       if (!p_ptr->fast)
+                       {
+                               if (set_fast(randint1(25) + 15, FALSE)) ident = TRUE;
+                       }
+                       else
+                       {
+                               (void)set_fast(p_ptr->fast + 5, FALSE);
+                       }
+                       break;
+
+               case SV_POTION_RESIST_HEAT:
+                       if (set_oppose_fire(p_ptr->oppose_fire + randint1(10) + 10, FALSE))
+                       {
+                               ident = TRUE;
+                       }
+                       break;
+
+               case SV_POTION_RESIST_COLD:
+                       if (set_oppose_cold(p_ptr->oppose_cold + randint1(10) + 10, FALSE))
+                       {
+                               ident = TRUE;
+                       }
+                       break;
+
+               case SV_POTION_HEROISM:
+                       ident = heroism(25);
+                       break;
+
+               case SV_POTION_BESERK_STRENGTH:
+                       ident = berserk(randint1(25) + 25);
+                       break;
+
+               case SV_POTION_CURE_LIGHT:
+                       ident = cure_light_wounds(2, 8);
+                       break;
+
+               case SV_POTION_CURE_SERIOUS:
+                       ident = cure_serious_wounds(4, 8);
+                       break;
+
+               case SV_POTION_CURE_CRITICAL:
+                       ident = cure_critical_wounds(damroll(6, 8));
+                       break;
+
+               case SV_POTION_HEALING:
+                       ident = cure_critical_wounds(300);
+                       break;
+
+               case SV_POTION_STAR_HEALING:
+                       ident = cure_critical_wounds(1200);
+                       break;
+
+               case SV_POTION_LIFE:
+                       ident = life_stream(TRUE, TRUE);
+                       break;
+
+               case SV_POTION_RESTORE_MANA:
+                       ident = restore_mana(TRUE);
+                       break;
+
+               case SV_POTION_RESTORE_EXP:
+                       if (restore_level()) ident = TRUE;
+                       break;
+
+               case SV_POTION_RES_STR:
+                       if (do_res_stat(A_STR)) ident = TRUE;
+                       break;
+
+               case SV_POTION_RES_INT:
+                       if (do_res_stat(A_INT)) ident = TRUE;
+                       break;
+
+               case SV_POTION_RES_WIS:
+                       if (do_res_stat(A_WIS)) ident = TRUE;
+                       break;
+
+               case SV_POTION_RES_DEX:
+                       if (do_res_stat(A_DEX)) ident = TRUE;
+                       break;
+
+               case SV_POTION_RES_CON:
+                       if (do_res_stat(A_CON)) ident = TRUE;
+                       break;
+
+               case SV_POTION_RES_CHR:
+                       if (do_res_stat(A_CHR)) ident = TRUE;
+                       break;
+
+               case SV_POTION_INC_STR:
+                       if (do_inc_stat(A_STR)) ident = TRUE;
+                       break;
+
+               case SV_POTION_INC_INT:
+                       if (do_inc_stat(A_INT)) ident = TRUE;
+                       break;
+
+               case SV_POTION_INC_WIS:
+                       if (do_inc_stat(A_WIS)) ident = TRUE;
+                       break;
+
+               case SV_POTION_INC_DEX:
+                       if (do_inc_stat(A_DEX)) ident = TRUE;
+                       break;
+
+               case SV_POTION_INC_CON:
+                       if (do_inc_stat(A_CON)) ident = TRUE;
+                       break;
+
+               case SV_POTION_INC_CHR:
+                       if (do_inc_stat(A_CHR)) ident = TRUE;
+                       break;
+
+               case SV_POTION_AUGMENTATION:
+                       if (do_inc_stat(A_STR)) ident = TRUE;
+                       if (do_inc_stat(A_INT)) ident = TRUE;
+                       if (do_inc_stat(A_WIS)) ident = TRUE;
+                       if (do_inc_stat(A_DEX)) ident = TRUE;
+                       if (do_inc_stat(A_CON)) ident = TRUE;
+                       if (do_inc_stat(A_CHR)) ident = TRUE;
+                       break;
+
+               case SV_POTION_ENLIGHTENMENT:
+                       msg_print(_("自分の置かれている状況が脳裏に浮かんできた...", "An image of your surroundings forms in your mind..."));
+                       chg_virtue(V_KNOWLEDGE, 1);
+                       chg_virtue(V_ENLIGHTEN, 1);
+                       wiz_lite(FALSE);
+                       ident = TRUE;
+                       break;
+
+               case SV_POTION_STAR_ENLIGHTENMENT:
+                       msg_print(_("更なる啓蒙を感じた...", "You begin to feel more enlightened..."));
+                       chg_virtue(V_KNOWLEDGE, 1);
+                       chg_virtue(V_ENLIGHTEN, 2);
+                       msg_print(NULL);
+                       wiz_lite(FALSE);
+                       (void)do_inc_stat(A_INT);
+                       (void)do_inc_stat(A_WIS);
+                       (void)detect_traps(DETECT_RAD_DEFAULT, TRUE);
+                       (void)detect_doors(DETECT_RAD_DEFAULT);
+                       (void)detect_stairs(DETECT_RAD_DEFAULT);
+                       (void)detect_treasure(DETECT_RAD_DEFAULT);
+                       (void)detect_objects_gold(DETECT_RAD_DEFAULT);
+                       (void)detect_objects_normal(DETECT_RAD_DEFAULT);
+                       identify_pack();
+                       self_knowledge();
+                       ident = TRUE;
+                       break;
+
+               case SV_POTION_SELF_KNOWLEDGE:
+                       msg_print(_("自分自身のことが少しは分かった気がする...", "You begin to know yourself a little better..."));
+                       msg_print(NULL);
+                       self_knowledge();
+                       ident = TRUE;
+                       break;
+
+               case SV_POTION_EXPERIENCE:
+                       if (p_ptr->prace == RACE_ANDROID) break;
+                       chg_virtue(V_ENLIGHTEN, 1);
+                       if (p_ptr->exp < PY_MAX_EXP)
+                       {
+                               s32b ee = (p_ptr->exp / 2) + 10;
+                               if (ee > 100000L) ee = 100000L;
+                               msg_print(_("更に経験を積んだような気がする。", "You feel more experienced."));
+                               gain_exp(ee);
+                               ident = TRUE;
+                       }
+                       break;
+
+               case SV_POTION_RESISTANCE:
+                       (void)set_oppose_acid(p_ptr->oppose_acid + randint1(20) + 20, FALSE);
+                       (void)set_oppose_elec(p_ptr->oppose_elec + randint1(20) + 20, FALSE);
+                       (void)set_oppose_fire(p_ptr->oppose_fire + randint1(20) + 20, FALSE);
+                       (void)set_oppose_cold(p_ptr->oppose_cold + randint1(20) + 20, FALSE);
+                       (void)set_oppose_pois(p_ptr->oppose_pois + randint1(20) + 20, FALSE);
+                       ident = TRUE;
+                       break;
+
+               case SV_POTION_CURING:
+                       if (true_healing(50)) ident = TRUE;
+                       break;
+
+               case SV_POTION_INVULNERABILITY:
+                       (void)set_invuln(p_ptr->invuln + randint1(4) + 4, FALSE);
+                       ident = TRUE;
+                       break;
+
+               case SV_POTION_NEW_LIFE:
+                       roll_hitdice(0L);
+                       get_max_stats();
+                       p_ptr->update |= PU_BONUS;
+                       lose_all_mutations();
+                       ident = TRUE;
+                       break;
+
+               case SV_POTION_NEO_TSUYOSHI:
+                       (void)set_image(0);
+                       (void)set_tsuyoshi(p_ptr->tsuyoshi + randint1(100) + 100, FALSE);
+                       ident = TRUE;
+                       break;
+
+               case SV_POTION_TSUYOSHI:
+                       msg_print(_("「オクレ兄さん!」", "Brother OKURE!"));
+                       msg_print(NULL);
+                       p_ptr->tsuyoshi = 1;
+                       (void)set_tsuyoshi(0, TRUE);
+                       if (!p_ptr->resist_chaos)
+                       {
+                               (void)set_image(50 + randint1(50));
+                       }
+                       ident = TRUE;
+                       break;
+               
+               case SV_POTION_POLYMORPH:
+                       if ((p_ptr->muta1 || p_ptr->muta2 || p_ptr->muta3) && one_in_(23))
+                       {
+                               lose_all_mutations();
+                       }
+                       else
+                       {
+                               do
+                               {
+                                       if (one_in_(2))
+                                       {
+                                               if(gain_random_mutation(0)) ident = TRUE;
+                                       }
+                                       else if (lose_mutation(0)) ident = TRUE;
+                               } while(!ident || one_in_(2));
+                       }
+                       break;
+               }
+       }
+
+       if (prace_is_(RACE_SKELETON))
+       {
+               msg_print(_("液体の一部はあなたのアゴを素通りして落ちた!", "Some of the fluid falls through your jaws!"));
+               (void)potion_smash_effect(0, p_ptr->y, p_ptr->x, q_ptr->k_idx);
+       }
+       p_ptr->update |= (PU_COMBINE | PU_REORDER);
+
+       if (!(object_is_aware(q_ptr)))
+       {
+               chg_virtue(V_PATIENCE, -1);
+               chg_virtue(V_CHANCE, 1);
+               chg_virtue(V_KNOWLEDGE, -1);
+       }
+
+       /* The item has been tried */
+       object_tried(q_ptr);
+
+       /* An identification was made */
+       if (ident && !object_is_aware(q_ptr))
+       {
+               object_aware(q_ptr);
+               gain_exp((lev + (p_ptr->lev >> 1)) / p_ptr->lev);
+       }
+
+       p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
+
+       /* Potions can feed the player */
+       switch (p_ptr->mimic_form)
+       {
+       case MIMIC_NONE:
+               switch (p_ptr->prace)
+               {
+                       case RACE_VAMPIRE:
+                               (void)set_food(p_ptr->food + (q_ptr->pval / 10));
+                               break;
+                       case RACE_SKELETON:
+                               /* Do nothing */
+                               break;
+                       case RACE_GOLEM:
+                       case RACE_ZOMBIE:
+                       case RACE_DEMON:
+                       case RACE_SPECTRE:
+                               set_food(p_ptr->food + ((q_ptr->pval) / 20));
+                               break;
+                       case RACE_ANDROID:
+                               if (q_ptr->tval == TV_FLASK)
+                               {
+                                       msg_print(_("オイルを補給した。", "You replenish yourself with the oil."));
+                                       set_food(p_ptr->food + 5000);
+                               }
+                               else
+                               {
+                                       set_food(p_ptr->food + ((q_ptr->pval) / 20));
+                               }
+                               break;
+                       case RACE_ENT:
+                               msg_print(_("水分を取り込んだ。", "You are moistened."));
+                               set_food(MIN(p_ptr->food + q_ptr->pval + MAX(0, q_ptr->pval * 10) + 2000, PY_FOOD_MAX - 1));
+                               break;
+                       default:
+                               (void)set_food(p_ptr->food + q_ptr->pval);
+                               break;
+               }
+               break;
+       case MIMIC_DEMON:
+       case MIMIC_DEMON_LORD:
+               set_food(p_ptr->food + ((q_ptr->pval) / 20));
+               break;
+       case MIMIC_VAMPIRE:
+               (void)set_food(p_ptr->food + (q_ptr->pval / 10));
+               break;
+       default:
+               (void)set_food(p_ptr->food + q_ptr->pval);
+               break;
+       }
+}
+
+
+
+/*!
+ * @brief 薬を飲むコマンドのメインルーチン /
+ * Quaff some potion (from the pack or floor)
+ * @return なし
+ */
+void do_cmd_quaff_potion(void)
+{
+       OBJECT_IDX item;
+       concptr q, s;
+
+       if (p_ptr->wild_mode)
+       {
+               return;
+       }
+
+       if (cmd_limit_arena(p_ptr)) return;
+
+       if (p_ptr->special_defense & (KATA_MUSOU | KATA_KOUKIJIN))
+       {
+               set_action(ACTION_NONE);
+       }
+
+       /* Restrict choices to potions */
+       item_tester_hook = item_tester_hook_quaff;
+
+       q = _("どの薬を飲みますか? ", "Quaff which potion? ");
+       s = _("飲める薬がない。", "You have no potions to quaff.");
+
+       if (!choose_object(&item, q, s, (USE_INVEN | USE_FLOOR))) return;
+
+       /* Quaff the potion */
+       do_cmd_quaff_potion_aux(item);
+}