OSDN Git Service

Merge branch 'master' of git.osdn.net:/gitroot/hengband/hengband
[hengband/hengband.git] / src / cmd-item / cmd-smith.c
1 /*!
2  * @brief プレイヤーの鍛冶コマンド実装
3  * @date 2019/03/11
4  * @author deskull
5  */
6
7 #include "cmd-item/cmd-smith.h"
8 #include "action/action-limited.h"
9 #include "autopick/autopick.h"
10 #include "core/asking-player.h"
11 #include "core/player-update-types.h"
12 #include "core/window-redrawer.h"
13 #include "flavor/flavor-describer.h"
14 #include "flavor/object-flavor-types.h"
15 #include "floor/floor-object.h"
16 #include "game-option/text-display-options.h"
17 #include "io/command-repeater.h"
18 #include "io/input-key-acceptor.h"
19 #include "io/input-key-requester.h"
20 #include "main/sound-of-music.h"
21 #include "mind/mind-weaponsmith.h"
22 #include "object-enchant/object-ego.h"
23 #include "object-enchant/special-object-flags.h"
24 #include "object-enchant/tr-types.h"
25 #include "object-enchant/trc-types.h"
26 #include "object-hook/hook-armor.h"
27 #include "object-hook/hook-enchant.h"
28 #include "object-hook/hook-weapon.h"
29 #include "object/item-tester-hooker.h"
30 #include "object/item-use-flags.h"
31 #include "object/object-flags.h" // todo 相互参照している.
32 #include "object/object-generator.h"
33 #include "perception/object-perception.h"
34 #include "player/player-status.h"
35 #include "term/screen-processor.h"
36 #include "term/term-color-types.h"
37 #include "util/bit-flags-calculator.h"
38 #include "util/buffer-shaper.h"
39 #include "util/int-char-converter.h"
40 #include "view/display-messages.h"
41
42 /*!
43  * エッセンス情報の構造体 / A structure for smithing
44  */
45 typedef struct {
46     int add; /* TR flag number or special essence id */
47     concptr add_name; /* Name of this ability */
48     ESSENCE_IDX type; /* Menu number */
49     int essence; /* Index for carrying essences */
50     int value; /* Needed value to add this ability */
51 } essence_type;
52
53 /*!
54  * エッセンス情報テーブル Smithing type data for Weapon smith
55  */
56 #ifdef JP
57 static essence_type essence_info[] = { { TR_STR, "腕力", 4, TR_STR, 20 }, { TR_INT, "知能", 4, TR_INT, 20 }, { TR_WIS, "賢さ", 4, TR_WIS, 20 },
58     { TR_DEX, "器用さ", 4, TR_DEX, 20 }, { TR_CON, "耐久力", 4, TR_CON, 20 }, { TR_CHR, "魅力", 4, TR_CHR, 20 },
59     { TR_MAGIC_MASTERY, "魔力支配", 4, TR_MAGIC_MASTERY, 20 }, { TR_STEALTH, "隠密", 4, TR_STEALTH, 40 }, { TR_SEARCH, "探索", 4, TR_SEARCH, 15 },
60     { TR_INFRA, "赤外線視力", 4, TR_INFRA, 15 }, { TR_TUNNEL, "採掘", 4, TR_TUNNEL, 15 }, { TR_SPEED, "スピード", 4, TR_SPEED, 12 },
61     { TR_BLOWS, "追加攻撃", 1, TR_BLOWS, 20 }, { TR_CHAOTIC, "カオス攻撃", 1, TR_CHAOTIC, 15 }, { TR_VAMPIRIC, "吸血攻撃", 1, TR_VAMPIRIC, 60 },
62     { TR_IMPACT, "地震発動", 7, TR_IMPACT, 15 }, { TR_BRAND_POIS, "毒殺", 1, TR_BRAND_POIS, 20 }, { TR_BRAND_ACID, "溶解", 1, TR_BRAND_ACID, 20 },
63     { TR_BRAND_ELEC, "電撃", 1, TR_BRAND_ELEC, 20 }, { TR_BRAND_FIRE, "焼棄", 1, TR_BRAND_FIRE, 20 }, { TR_BRAND_COLD, "凍結", 1, TR_BRAND_COLD, 20 },
64     { TR_SUST_STR, "腕力維持", 3, TR_SUST_STR, 15 }, { TR_SUST_INT, "知能維持", 3, TR_SUST_STR, 15 }, { TR_SUST_WIS, "賢さ維持", 3, TR_SUST_STR, 15 },
65     { TR_SUST_DEX, "器用さ維持", 3, TR_SUST_STR, 15 }, { TR_SUST_CON, "耐久力維持", 3, TR_SUST_STR, 15 }, { TR_SUST_CHR, "魅力維持", 3, TR_SUST_STR, 15 },
66     { TR_IM_ACID, "酸免疫", 2, TR_IM_ACID, 20 }, { TR_IM_ELEC, "電撃免疫", 2, TR_IM_ACID, 20 }, { TR_IM_FIRE, "火炎免疫", 2, TR_IM_ACID, 20 },
67     { TR_IM_COLD, "冷気免疫", 2, TR_IM_ACID, 20 }, { TR_REFLECT, "反射", 2, TR_REFLECT, 20 }, { TR_FREE_ACT, "麻痺知らず", 3, TR_FREE_ACT, 20 },
68     { TR_HOLD_EXP, "経験値維持", 3, TR_HOLD_EXP, 20 }, { TR_RES_ACID, "耐酸", 2, TR_RES_ACID, 15 }, { TR_RES_ELEC, "耐電撃", 2, TR_RES_ELEC, 15 },
69     { TR_RES_FIRE, "耐火炎", 2, TR_RES_FIRE, 15 }, { TR_RES_COLD, "耐冷気", 2, TR_RES_COLD, 15 }, { TR_RES_POIS, "耐毒", 2, TR_RES_POIS, 25 },
70     { TR_RES_FEAR, "耐恐怖", 2, TR_RES_FEAR, 20 }, { TR_RES_LITE, "耐閃光", 2, TR_RES_LITE, 20 }, { TR_RES_DARK, "耐暗黒", 2, TR_RES_DARK, 20 },
71     { TR_RES_BLIND, "耐盲目", 2, TR_RES_BLIND, 20 }, { TR_RES_CONF, "耐混乱", 2, TR_RES_CONF, 20 }, { TR_RES_SOUND, "耐轟音", 2, TR_RES_SOUND, 20 },
72     { TR_RES_SHARDS, "耐破片", 2, TR_RES_SHARDS, 20 }, { TR_RES_NETHER, "耐地獄", 2, TR_RES_NETHER, 20 }, { TR_RES_NEXUS, "耐因果混乱", 2, TR_RES_NEXUS, 20 },
73     { TR_RES_CHAOS, "耐カオス", 2, TR_RES_CHAOS, 20 }, { TR_RES_DISEN, "耐劣化", 2, TR_RES_DISEN, 20 }, { TR_SH_FIRE, "", 0, -2, 0 },
74     { TR_SH_ELEC, "", 0, -2, 0 }, { TR_SH_COLD, "", 0, -2, 0 }, { TR_NO_MAGIC, "反魔法", 3, TR_NO_MAGIC, 15 }, { TR_WARNING, "警告", 3, TR_WARNING, 20 },
75     { TR_LEVITATION, "浮遊", 3, TR_LEVITATION, 20 }, { TR_LITE_1, "永久光源", 3, TR_LITE_1, 15 }, { TR_LITE_2, "", 0, -2, 0 }, { TR_LITE_3, "", 0, -2, 0 },
76     { TR_SEE_INVIS, "可視透明", 3, TR_SEE_INVIS, 20 }, { TR_TELEPATHY, "テレパシー", 6, TR_TELEPATHY, 15 }, { TR_SLOW_DIGEST, "遅消化", 3, TR_SLOW_DIGEST, 15 },
77     { TR_REGEN, "急速回復", 3, TR_REGEN, 20 }, { TR_TELEPORT, "テレポート", 3, TR_TELEPORT, 25 },
78
79     { TR_SLAY_EVIL, "邪悪倍打", 5, TR_SLAY_EVIL, 100 }, { TR_KILL_EVIL, "邪悪倍倍打", 0, TR_SLAY_EVIL, 60 },
80     { TR_SLAY_ANIMAL, "動物倍打", 5, TR_SLAY_ANIMAL, 20 }, { TR_KILL_ANIMAL, "動物倍倍打", 5, TR_SLAY_ANIMAL, 60 },
81     { TR_SLAY_UNDEAD, "不死倍打", 5, TR_SLAY_UNDEAD, 20 }, { TR_KILL_UNDEAD, "不死倍倍打", 5, TR_SLAY_UNDEAD, 60 },
82     { TR_SLAY_DEMON, "悪魔倍打", 5, TR_SLAY_DEMON, 20 }, { TR_KILL_DEMON, "悪魔倍倍打", 5, TR_SLAY_DEMON, 60 },
83     { TR_SLAY_ORC, "オーク倍打", 5, TR_SLAY_ORC, 15 }, { TR_KILL_ORC, "オーク倍倍打", 5, TR_SLAY_ORC, 60 },
84     { TR_SLAY_TROLL, "トロル倍打", 5, TR_SLAY_TROLL, 15 }, { TR_KILL_TROLL, "トロル倍倍打", 5, TR_SLAY_TROLL, 60 },
85     { TR_SLAY_GIANT, "巨人倍打", 5, TR_SLAY_GIANT, 20 }, { TR_KILL_GIANT, "巨人倍倍打", 5, TR_SLAY_GIANT, 60 },
86     { TR_SLAY_DRAGON, "竜倍打", 5, TR_SLAY_DRAGON, 20 }, { TR_KILL_DRAGON, "竜倍倍打", 5, TR_SLAY_DRAGON, 60 },
87     { TR_SLAY_HUMAN, "人間倍打", 5, TR_SLAY_HUMAN, 20 }, { TR_KILL_HUMAN, "人間倍倍打", 5, TR_SLAY_HUMAN, 60 },
88
89     { TR_ESP_ANIMAL, "動物ESP", 6, TR_SLAY_ANIMAL, 40 }, { TR_ESP_UNDEAD, "不死ESP", 6, TR_SLAY_UNDEAD, 40 }, { TR_ESP_DEMON, "悪魔ESP", 6, TR_SLAY_DEMON, 40 },
90     { TR_ESP_ORC, "オークESP", 6, TR_SLAY_ORC, 40 }, { TR_ESP_TROLL, "トロルESP", 6, TR_SLAY_TROLL, 40 }, { TR_ESP_GIANT, "巨人ESP", 6, TR_SLAY_GIANT, 40 },
91     { TR_ESP_DRAGON, "竜ESP", 6, TR_SLAY_DRAGON, 40 }, { TR_ESP_HUMAN, "人間ESP", 6, TR_SLAY_HUMAN, 40 },
92
93     { ESSENCE_ATTACK, "攻撃", 10, TR_ES_ATTACK, 30 }, { ESSENCE_AC, "防御", 10, TR_ES_AC, 15 }, { ESSENCE_TMP_RES_ACID, "酸耐性発動", 7, TR_RES_ACID, 50 },
94     { ESSENCE_TMP_RES_ELEC, "電撃耐性発動", 7, TR_RES_ELEC, 50 }, { ESSENCE_TMP_RES_FIRE, "火炎耐性発動", 7, TR_RES_FIRE, 50 },
95     { ESSENCE_TMP_RES_COLD, "冷気耐性発動", 7, TR_RES_COLD, 50 }, { ESSENCE_SH_FIRE, "火炎オーラ", 7, -1, 50 }, { ESSENCE_SH_ELEC, "電撃オーラ", 7, -1, 50 },
96     { ESSENCE_SH_COLD, "冷気オーラ", 7, -1, 50 }, { ESSENCE_RESISTANCE, "全耐性", 2, -1, 150 }, { ESSENCE_SUSTAIN, "装備保持", 10, -1, 10 },
97     { ESSENCE_SLAY_GLOVE, "殺戮の小手", 1, TR_ES_ATTACK, 200 },
98
99     { -1, NULL, 0, -1, 0 } };
100 #else
101 static essence_type essence_info[] = { { TR_STR, "strength", 4, TR_STR, 20 }, { TR_INT, "intelligence", 4, TR_INT, 20 }, { TR_WIS, "wisdom", 4, TR_WIS, 20 },
102     { TR_DEX, "dexterity", 4, TR_DEX, 20 }, { TR_CON, "constitution", 4, TR_CON, 20 }, { TR_CHR, "charisma", 4, TR_CHR, 20 },
103     { TR_MAGIC_MASTERY, "magic mastery", 4, TR_MAGIC_MASTERY, 20 }, { TR_STEALTH, "stealth", 4, TR_STEALTH, 40 }, { TR_SEARCH, "serching", 4, TR_SEARCH, 15 },
104     { TR_INFRA, "infravision", 4, TR_INFRA, 15 }, { TR_TUNNEL, "digging", 4, TR_TUNNEL, 15 }, { TR_SPEED, "speed", 4, TR_SPEED, 12 },
105     { TR_BLOWS, "extra attack", 1, TR_BLOWS, 20 }, { TR_CHAOTIC, "chaos brand", 1, TR_CHAOTIC, 15 }, { TR_VAMPIRIC, "vampiric brand", 1, TR_VAMPIRIC, 60 },
106     { TR_IMPACT, "quake activation", 7, TR_IMPACT, 15 }, { TR_BRAND_POIS, "poison brand", 1, TR_BRAND_POIS, 20 },
107     { TR_BRAND_ACID, "acid brand", 1, TR_BRAND_ACID, 20 }, { TR_BRAND_ELEC, "electric brand", 1, TR_BRAND_ELEC, 20 },
108     { TR_BRAND_FIRE, "fire brand", 1, TR_BRAND_FIRE, 20 }, { TR_BRAND_COLD, "cold brand", 1, TR_BRAND_COLD, 20 },
109     { TR_SUST_STR, "sustain strength", 3, TR_SUST_STR, 15 }, { TR_SUST_INT, "sustain intelligence", 3, TR_SUST_STR, 15 },
110     { TR_SUST_WIS, "sustain wisdom", 3, TR_SUST_STR, 15 }, { TR_SUST_DEX, "sustain dexterity", 3, TR_SUST_STR, 15 },
111     { TR_SUST_CON, "sustain constitution", 3, TR_SUST_STR, 15 }, { TR_SUST_CHR, "sustain charisma", 3, TR_SUST_STR, 15 },
112     { TR_IM_ACID, "acid immunity", 2, TR_IM_ACID, 20 }, { TR_IM_ELEC, "electric immunity", 2, TR_IM_ACID, 20 },
113     { TR_IM_FIRE, "fire immunity", 2, TR_IM_ACID, 20 }, { TR_IM_COLD, "cold immunity", 2, TR_IM_ACID, 20 }, { TR_REFLECT, "reflection", 2, TR_REFLECT, 20 },
114     { TR_FREE_ACT, "free action", 3, TR_FREE_ACT, 20 }, { TR_HOLD_EXP, "hold experience", 3, TR_HOLD_EXP, 20 },
115     { TR_RES_ACID, "resistance to acid", 2, TR_RES_ACID, 15 }, { TR_RES_ELEC, "resistance to electric", 2, TR_RES_ELEC, 15 },
116     { TR_RES_FIRE, "resistance to fire", 2, TR_RES_FIRE, 15 }, { TR_RES_COLD, "resistance to cold", 2, TR_RES_COLD, 15 },
117     { TR_RES_POIS, "resistance to poison", 2, TR_RES_POIS, 25 }, { TR_RES_FEAR, "resistance to fear", 2, TR_RES_FEAR, 20 },
118     { TR_RES_LITE, "resistance to light", 2, TR_RES_LITE, 20 }, { TR_RES_DARK, "resistance to dark", 2, TR_RES_DARK, 20 },
119     { TR_RES_BLIND, "resistance to blind", 2, TR_RES_BLIND, 20 }, { TR_RES_CONF, "resistance to confusion", 2, TR_RES_CONF, 20 },
120     { TR_RES_SOUND, "resistance to sound", 2, TR_RES_SOUND, 20 }, { TR_RES_SHARDS, "resistance to shard", 2, TR_RES_SHARDS, 20 },
121     { TR_RES_NETHER, "resistance to nether", 2, TR_RES_NETHER, 20 }, { TR_RES_NEXUS, "resistance to nexus", 2, TR_RES_NEXUS, 20 },
122     { TR_RES_CHAOS, "resistance to chaos", 2, TR_RES_CHAOS, 20 }, { TR_RES_DISEN, "resistance to disenchantment", 2, TR_RES_DISEN, 20 },
123     { TR_SH_FIRE, "", 0, -2, 0 }, { TR_SH_ELEC, "", 0, -2, 0 }, { TR_SH_COLD, "", 0, -2, 0 }, { TR_NO_MAGIC, "anti magic", 3, TR_NO_MAGIC, 15 },
124     { TR_WARNING, "warning", 3, TR_WARNING, 20 }, { TR_LEVITATION, "levitation", 3, TR_LEVITATION, 20 }, { TR_LITE_1, "permanent light", 3, TR_LITE_1, 15 },
125     { TR_LITE_2, "", 0, -2, 0 }, { TR_LITE_3, "", 0, -2, 0 }, { TR_SEE_INVIS, "see invisible", 3, TR_SEE_INVIS, 20 },
126     { TR_TELEPATHY, "telepathy", 6, TR_TELEPATHY, 15 }, { TR_SLOW_DIGEST, "slow digestion", 3, TR_SLOW_DIGEST, 15 },
127     { TR_REGEN, "regeneration", 3, TR_REGEN, 20 }, { TR_TELEPORT, "teleport", 3, TR_TELEPORT, 25 },
128
129     { TR_SLAY_EVIL, "slay evil", 5, TR_SLAY_EVIL, 100 }, { TR_SLAY_ANIMAL, "slay animal", 5, TR_SLAY_ANIMAL, 20 },
130     { TR_KILL_ANIMAL, "kill animal", 5, TR_SLAY_ANIMAL, 60 }, { TR_KILL_EVIL, "kill evil", 0, TR_SLAY_EVIL, 60 },
131     { TR_SLAY_UNDEAD, "slay undead", 5, TR_SLAY_UNDEAD, 20 }, { TR_KILL_UNDEAD, "kill undead", 5, TR_SLAY_UNDEAD, 60 },
132     { TR_SLAY_DEMON, "slay demon", 5, TR_SLAY_DEMON, 20 }, { TR_KILL_DEMON, "kill demon", 5, TR_SLAY_DEMON, 60 },
133     { TR_SLAY_ORC, "slay orc", 5, TR_SLAY_ORC, 15 }, { TR_KILL_ORC, "kill orc", 5, TR_SLAY_ORC, 60 }, { TR_SLAY_TROLL, "slay troll", 5, TR_SLAY_TROLL, 15 },
134     { TR_KILL_TROLL, "kill troll", 5, TR_SLAY_TROLL, 60 }, { TR_SLAY_GIANT, "slay giant", 5, TR_SLAY_GIANT, 20 },
135     { TR_KILL_GIANT, "kill giant", 5, TR_SLAY_GIANT, 60 }, { TR_SLAY_DRAGON, "slay dragon", 5, TR_SLAY_DRAGON, 20 },
136     { TR_KILL_DRAGON, "kill dragon", 5, TR_SLAY_DRAGON, 60 }, { TR_SLAY_HUMAN, "slay human", 5, TR_SLAY_HUMAN, 20 },
137     { TR_KILL_HUMAN, "kill human", 5, TR_SLAY_HUMAN, 60 },
138
139     { TR_ESP_ANIMAL, "sense animal", 6, TR_SLAY_ANIMAL, 40 }, { TR_ESP_UNDEAD, "sense undead", 6, TR_SLAY_UNDEAD, 40 },
140     { TR_ESP_DEMON, "sense demon", 6, TR_SLAY_DEMON, 40 }, { TR_ESP_ORC, "sense orc", 6, TR_SLAY_ORC, 40 },
141     { TR_ESP_TROLL, "sense troll", 6, TR_SLAY_TROLL, 40 }, { TR_ESP_GIANT, "sense giant", 6, TR_SLAY_GIANT, 40 },
142     { TR_ESP_DRAGON, "sense dragon", 6, TR_SLAY_DRAGON, 40 }, { TR_ESP_HUMAN, "sense human", 6, TR_SLAY_HUMAN, 40 },
143
144     { ESSENCE_ATTACK, "weapon enchant", 10, TR_ES_ATTACK, 30 }, { ESSENCE_AC, "armor enchant", 10, TR_ES_AC, 15 },
145     { ESSENCE_TMP_RES_ACID, "resist acid activation", 7, TR_RES_ACID, 50 }, { ESSENCE_TMP_RES_ELEC, "resist electricity activation", 7, TR_RES_ELEC, 50 },
146     { ESSENCE_TMP_RES_FIRE, "resist fire activation", 7, TR_RES_FIRE, 50 }, { ESSENCE_TMP_RES_COLD, "resist cold activation", 7, TR_RES_COLD, 50 },
147     { ESSENCE_SH_FIRE, "fiery sheath", 7, -1, 50 }, { ESSENCE_SH_ELEC, "electric sheath", 7, -1, 50 }, { ESSENCE_SH_COLD, "sheath of coldness", 7, -1, 50 },
148     { ESSENCE_RESISTANCE, "resistance", 2, -1, 150 }, { ESSENCE_SUSTAIN, "elements proof", 10, -1, 10 },
149     { ESSENCE_SLAY_GLOVE, "gauntlets of slaying", 1, TR_ES_ATTACK, 200 },
150
151     { -1, NULL, 0, -1, 0 } };
152 #endif
153
154 /*!
155  * エッセンス名テーブル / Essense names for Weapon smith
156  */
157 #ifdef JP
158 concptr essence_name[] = { "腕力", "知能", "賢さ", "器用さ", "耐久力", "魅力", "魔力支配", "", "隠密", "探索", "赤外線視力", "採掘", "スピード", "追加攻撃",
159     "カオス攻撃", "吸血攻撃", "動物倍打", "邪悪倍打", "不死倍打", "悪魔倍打", "オーク倍打", "トロル倍打", "巨人倍打", "竜倍打", "", "", "地震", "毒殺", "溶解",
160     "電撃", "焼棄", "凍結", "能力維持", "", "", "", "", "", "", "", "免疫", "", "", "", "", "反射", "麻痺知らず", "経験値維持", "耐酸", "耐電撃", "耐火炎",
161     "耐冷気", "耐毒", "耐恐怖", "耐閃光", "耐暗黒", "耐盲目", "耐混乱", "耐轟音", "耐破片", "耐地獄", "耐因果混乱", "耐カオス", "耐劣化", "", "", "人間倍打",
162     "", "", "反魔法", "", "", "警告", "", "", "", "浮遊", "永久光源", "可視透明", "テレパシー", "遅消化", "急速回復", "", "", "", "", "", "", "", "",
163     "テレポート", "", "", "攻撃", "防御",
164
165     NULL };
166
167 #else
168
169 concptr essence_name[] = { "strength", "intelligen.", "wisdom", "dexterity", "constitut.", "charisma", "magic mast.", "", "stealth", "serching", "infravision",
170     "digging", "speed", "extra atk", "chaos brand", "vampiric", "slay animal", "slay evil", "slay undead", "slay demon", "slay orc", "slay troll", "slay giant",
171     "slay dragon", "", "", "quake", "pois. brand", "acid brand", "elec. brand", "fire brand", "cold brand", "sustain", "", "", "", "", "", "", "", "immunity",
172     "", "", "", "", "reflection", "free action", "hold exp", "res. acid", "res. elec.", "res. fire", "res. cold", "res. poison", "res. fear", "res. light",
173     "res. dark", "res. blind", "res.confuse", "res. sound", "res. shard", "res. nether", "res. nexus", "res. chaos", "res. disen.", "", "", "slay human", "",
174     "", "anti magic", "", "", "warning", "", "", "", "levitation", "perm. light", "see invis.", "telepathy", "slow dige.", "regen.", "", "", "", "", "", "", "",
175     "", "teleport", "", "", "weapon enc.", "armor enc.",
176
177     NULL };
178 #endif
179
180 static concptr const kaji_tips[5] = {
181 #ifdef JP
182     "現在持っているエッセンスの一覧を表示する。",
183     "アイテムからエッセンスを取り出す。エッセンスを取られたアイテムは全く魔法がかかっていない初期状態に戻る。",
184     "既にエッセンスが付加されたアイテムからエッセンスのみ消し去る。エッセンスは手に入らない。",
185     "アイテムにエッセンスを付加する。既にエッセンスが付加されたアイテムやアーティファクトには付加できない。",
186     "武器や防具を強化したり、攻撃で傷つかないようにしたりする。エッセンスが付加されたアイテムやアーティファクトに対しても使用できる。",
187 #else
188     "Display essences you have.",
189     "Extract essences from an item. The item become non magical.",
190     "Remove added essences from an equipment which was improved before. The removed essence will be ruined.",
191     "Add essences to an item. The improved items or artifacts cannot be reimprove.",
192     "Enchant an equipment or make an equiment element-proofed. The improved items and artifacts can be enchanted too.",
193 #endif
194 };
195
196 /*!
197  * @brief 所持しているエッセンス一覧を表示する
198  * @return なし
199  */
200 static void display_essence(player_type *creature_ptr)
201 {
202     int i, num = 0;
203
204     screen_save();
205     for (i = 1; i < 22; i++) {
206         prt("", i, 0);
207     }
208     prt(_("エッセンス   個数     エッセンス   個数     エッセンス   個数", "Essence      Num      Essence      Num      Essence      Num "), 1, 8);
209     for (i = 0; essence_name[i]; i++) {
210         if (!essence_name[i][0])
211             continue;
212         prt(format("%-11s %5d", essence_name[i], creature_ptr->magic_num1[i]), 2 + num % 21, 8 + num / 21 * 22);
213         num++;
214     }
215     prt(_("現在所持しているエッセンス", "List of all essences you have."), 0, 0);
216     (void)inkey();
217     screen_load();
218     return;
219 }
220
221 /*!
222  * @brief エッセンスの抽出処理
223  * @param creature_ptr プレーヤーへの参照ポインタ
224  * @return なし
225  */
226 static void drain_essence(player_type *creature_ptr)
227 {
228     int drain_value[sizeof(creature_ptr->magic_num1) / sizeof(s32b)];
229     size_t i;
230     OBJECT_IDX item;
231     int dec = 4;
232     bool observe = FALSE;
233     int old_ds, old_dd, old_to_h, old_to_d, old_ac, old_to_a, old_pval, old_name2;
234     TIME_EFFECT old_timeout;
235     BIT_FLAGS old_flgs[TR_FLAG_SIZE], new_flgs[TR_FLAG_SIZE];
236     object_type *o_ptr;
237     concptr q, s;
238     POSITION iy, ix;
239     byte marked;
240     ITEM_NUMBER number;
241     OBJECT_IDX next_o_idx;
242     WEIGHT weight;
243
244     for (i = 0; i < sizeof(drain_value) / sizeof(int); i++)
245         drain_value[i] = 0;
246
247     item_tester_hook = object_is_weapon_armour_ammo;
248
249     q = _("どのアイテムから抽出しますか?", "Extract from which item? ");
250     s = _("抽出できるアイテムがありません。", "You have nothing you can extract from.");
251
252     o_ptr = choose_object(creature_ptr, &item, q, s, (USE_INVEN | USE_FLOOR | IGNORE_BOTHHAND_SLOT), 0);
253     if (!o_ptr)
254         return;
255
256     if (object_is_known(o_ptr) && !object_is_nameless(creature_ptr, o_ptr)) {
257         GAME_TEXT o_name[MAX_NLEN];
258         describe_flavor(creature_ptr, o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
259         if (!get_check(format(_("本当に%sから抽出してよろしいですか?", "Really extract from %s? "), o_name)))
260             return;
261     }
262
263     take_turn(creature_ptr, 100);
264
265     object_flags(creature_ptr, o_ptr, old_flgs);
266     if (have_flag(old_flgs, TR_KILL_DRAGON))
267         add_flag(old_flgs, TR_SLAY_DRAGON);
268     if (have_flag(old_flgs, TR_KILL_ANIMAL))
269         add_flag(old_flgs, TR_SLAY_ANIMAL);
270     if (have_flag(old_flgs, TR_KILL_EVIL))
271         add_flag(old_flgs, TR_SLAY_EVIL);
272     if (have_flag(old_flgs, TR_KILL_UNDEAD))
273         add_flag(old_flgs, TR_SLAY_UNDEAD);
274     if (have_flag(old_flgs, TR_KILL_DEMON))
275         add_flag(old_flgs, TR_SLAY_DEMON);
276     if (have_flag(old_flgs, TR_KILL_ORC))
277         add_flag(old_flgs, TR_SLAY_ORC);
278     if (have_flag(old_flgs, TR_KILL_TROLL))
279         add_flag(old_flgs, TR_SLAY_TROLL);
280     if (have_flag(old_flgs, TR_KILL_GIANT))
281         add_flag(old_flgs, TR_SLAY_GIANT);
282     if (have_flag(old_flgs, TR_KILL_HUMAN))
283         add_flag(old_flgs, TR_SLAY_HUMAN);
284
285     old_to_a = o_ptr->to_a;
286     old_ac = o_ptr->ac;
287     old_to_h = o_ptr->to_h;
288     old_to_d = o_ptr->to_d;
289     old_ds = o_ptr->ds;
290     old_dd = o_ptr->dd;
291     old_pval = o_ptr->pval;
292     old_name2 = o_ptr->name2;
293     old_timeout = o_ptr->timeout;
294     if (o_ptr->curse_flags & (TRC_CURSED | TRC_HEAVY_CURSE | TRC_PERMA_CURSE))
295         dec--;
296     if (have_flag(old_flgs, TR_ADD_L_CURSE))
297         dec--;
298     if (have_flag(old_flgs, TR_ADD_H_CURSE))
299         dec--;
300     if (have_flag(old_flgs, TR_AGGRAVATE))
301         dec--;
302     if (have_flag(old_flgs, TR_NO_TELE))
303         dec--;
304     if (have_flag(old_flgs, TR_DRAIN_EXP))
305         dec--;
306     if (have_flag(old_flgs, TR_DRAIN_HP))
307         dec--;
308     if (have_flag(old_flgs, TR_DRAIN_MANA))
309         dec--;
310     if (have_flag(old_flgs, TR_CALL_ANIMAL))
311         dec--;
312     if (have_flag(old_flgs, TR_CALL_DEMON))
313         dec--;
314     if (have_flag(old_flgs, TR_CALL_DRAGON))
315         dec--;
316     if (have_flag(old_flgs, TR_CALL_UNDEAD))
317         dec--;
318     if (have_flag(old_flgs, TR_COWARDICE))
319         dec--;
320     if (have_flag(old_flgs, TR_LOW_MELEE))
321         dec--;
322     if (have_flag(old_flgs, TR_LOW_AC))
323         dec--;
324     if (have_flag(old_flgs, TR_LOW_MAGIC))
325         dec--;
326     if (have_flag(old_flgs, TR_FAST_DIGEST))
327         dec--;
328     if (have_flag(old_flgs, TR_SLOW_REGEN))
329         dec--;
330     if (have_flag(old_flgs, TR_TY_CURSE))
331         dec--;
332
333     iy = o_ptr->iy;
334     ix = o_ptr->ix;
335     next_o_idx = o_ptr->next_o_idx;
336     marked = o_ptr->marked;
337     weight = o_ptr->weight;
338     number = o_ptr->number;
339
340     object_prep(creature_ptr, o_ptr, o_ptr->k_idx);
341
342     o_ptr->iy = iy;
343     o_ptr->ix = ix;
344     o_ptr->next_o_idx = next_o_idx;
345     o_ptr->marked = marked;
346     o_ptr->number = number;
347     if (o_ptr->tval == TV_DRAG_ARMOR)
348         o_ptr->timeout = old_timeout;
349     if (item >= 0)
350         creature_ptr->total_weight += (o_ptr->weight * o_ptr->number - weight * number);
351     o_ptr->ident |= (IDENT_FULL_KNOWN);
352     object_aware(creature_ptr, o_ptr);
353     object_known(o_ptr);
354
355     object_flags(creature_ptr, o_ptr, new_flgs);
356
357     for (i = 0; essence_info[i].add_name; i++) {
358         essence_type *es_ptr = &essence_info[i];
359         PARAMETER_VALUE pval = 0;
360
361         if (es_ptr->add < TR_FLAG_MAX && is_pval_flag(es_ptr->add) && old_pval)
362             pval = (have_flag(new_flgs, es_ptr->add)) ? old_pval - o_ptr->pval : old_pval;
363
364         if (es_ptr->add < TR_FLAG_MAX && (!have_flag(new_flgs, es_ptr->add) || pval) && have_flag(old_flgs, es_ptr->add)) {
365             if (pval) {
366                 drain_value[es_ptr->essence] += 10 * pval;
367             } else if (es_ptr->essence != -2) {
368                 drain_value[es_ptr->essence] += 10;
369             } else if (es_ptr->add == TR_SH_FIRE) {
370                 drain_value[TR_BRAND_FIRE] += 10;
371                 drain_value[TR_RES_FIRE] += 10;
372             } else if (es_ptr->add == TR_SH_ELEC) {
373                 drain_value[TR_BRAND_ELEC] += 10;
374                 drain_value[TR_RES_ELEC] += 10;
375             } else if (es_ptr->add == TR_SH_COLD) {
376                 drain_value[TR_BRAND_COLD] += 10;
377                 drain_value[TR_RES_COLD] += 10;
378             } else if (es_ptr->add == TR_LITE_2) {
379                 drain_value[TR_LITE_1] += 20;
380             } else if (es_ptr->add == TR_LITE_3) {
381                 drain_value[TR_LITE_1] += 30;
382             }
383         }
384     }
385
386     if ((have_flag(old_flgs, TR_FORCE_WEAPON)) && !(have_flag(new_flgs, TR_FORCE_WEAPON))) {
387         drain_value[TR_INT] += 5;
388         drain_value[TR_WIS] += 5;
389     }
390     if ((have_flag(old_flgs, TR_VORPAL)) && !(have_flag(new_flgs, TR_VORPAL))) {
391         drain_value[TR_BRAND_POIS] += 5;
392         drain_value[TR_BRAND_ACID] += 5;
393         drain_value[TR_BRAND_ELEC] += 5;
394         drain_value[TR_BRAND_FIRE] += 5;
395         drain_value[TR_BRAND_COLD] += 5;
396     }
397     if ((have_flag(old_flgs, TR_DEC_MANA)) && !(have_flag(new_flgs, TR_DEC_MANA))) {
398         drain_value[TR_INT] += 10;
399     }
400     if ((have_flag(old_flgs, TR_XTRA_MIGHT)) && !(have_flag(new_flgs, TR_XTRA_MIGHT))) {
401         drain_value[TR_STR] += 10;
402     }
403     if ((have_flag(old_flgs, TR_XTRA_SHOTS)) && !(have_flag(new_flgs, TR_XTRA_SHOTS))) {
404         drain_value[TR_DEX] += 10;
405     }
406     if (old_name2 == EGO_2WEAPON) {
407         drain_value[TR_DEX] += 20;
408     }
409     if (object_is_weapon_ammo(o_ptr)) {
410         if (old_ds > o_ptr->ds)
411             drain_value[TR_ES_ATTACK] += (old_ds - o_ptr->ds) * 10;
412
413         if (old_dd > o_ptr->dd)
414             drain_value[TR_ES_ATTACK] += (old_dd - o_ptr->dd) * 10;
415     }
416     if (old_to_h > o_ptr->to_h)
417         drain_value[TR_ES_ATTACK] += (old_to_h - o_ptr->to_h) * 10;
418     if (old_to_d > o_ptr->to_d)
419         drain_value[TR_ES_ATTACK] += (old_to_d - o_ptr->to_d) * 10;
420     if (old_ac > o_ptr->ac)
421         drain_value[TR_ES_AC] += (old_ac - o_ptr->ac) * 10;
422     if (old_to_a > o_ptr->to_a)
423         drain_value[TR_ES_AC] += (old_to_a - o_ptr->to_a) * 10;
424
425     for (i = 0; i < sizeof(drain_value) / sizeof(int); i++) {
426         drain_value[i] *= number;
427         drain_value[i] = drain_value[i] * dec / 4;
428         drain_value[i] = MAX(drain_value[i], 0);
429         if ((o_ptr->tval >= TV_SHOT) && (o_ptr->tval <= TV_BOLT))
430             drain_value[i] /= 10;
431         if (drain_value[i]) {
432             observe = TRUE;
433         }
434     }
435     if (!observe) {
436         msg_print(_("エッセンスは抽出できませんでした。", "You were not able to extract any essence."));
437     } else {
438         msg_print(_("抽出したエッセンス:", "Extracted essences:"));
439
440         for (i = 0; essence_name[i]; i++) {
441             if (!essence_name[i][0])
442                 continue;
443             if (!drain_value[i])
444                 continue;
445
446             creature_ptr->magic_num1[i] += drain_value[i];
447             creature_ptr->magic_num1[i] = MIN(20000, creature_ptr->magic_num1[i]);
448             msg_print(NULL);
449             msg_format("%s...%d%s", essence_name[i], drain_value[i], _("。", ". "));
450         }
451     }
452
453     /* Apply autodestroy/inscription to the drained item */
454     autopick_alter_item(creature_ptr, item, TRUE);
455     creature_ptr->update |= (PU_COMBINE | PU_REORDER);
456     creature_ptr->window |= (PW_INVEN);
457 }
458
459 /*!
460  * @brief 付加するエッセンスの大別を選択する
461  * @return 選んだエッセンスの大別ID
462  */
463 static COMMAND_CODE choose_essence(void)
464 {
465     COMMAND_CODE mode = 0;
466     char choice;
467     COMMAND_CODE menu_line = (use_menu ? 1 : 0);
468
469 #ifdef JP
470     concptr menu_name[] = { "武器属性", "耐性", "能力", "数値", "スレイ", "ESP", "その他" };
471 #else
472     concptr menu_name[] = { "Brand weapon", "Resistance", "Ability", "Magic number", "Slay", "ESP", "Others" };
473 #endif
474     const COMMAND_CODE mode_max = 7;
475
476     if (repeat_pull(&mode) && 1 <= mode && mode <= mode_max)
477         return mode;
478     mode = 0;
479     if (use_menu) {
480         screen_save();
481
482         while (!mode) {
483             int i;
484             for (i = 0; i < mode_max; i++)
485 #ifdef JP
486                 prt(format(" %s %s", (menu_line == 1 + i) ? "》" : "  ", menu_name[i]), 2 + i, 14);
487             prt("どの種類のエッセンス付加を行いますか?", 0, 0);
488 #else
489                 prt(format(" %s %s", (menu_line == 1 + i) ? "> " : "  ", menu_name[i]), 2 + i, 14);
490             prt("Choose from menu.", 0, 0);
491 #endif
492
493             choice = inkey();
494             switch (choice) {
495             case ESCAPE:
496             case 'z':
497             case 'Z':
498                 screen_load();
499                 return 0;
500             case '2':
501             case 'j':
502             case 'J':
503                 menu_line++;
504                 break;
505             case '8':
506             case 'k':
507             case 'K':
508                 menu_line += mode_max - 1;
509                 break;
510             case '\r':
511             case '\n':
512             case 'x':
513             case 'X':
514                 mode = menu_line;
515                 break;
516             }
517             if (menu_line > mode_max)
518                 menu_line -= mode_max;
519         }
520         screen_load();
521     } else {
522         screen_save();
523         while (!mode) {
524             int i;
525
526             for (i = 0; i < mode_max; i++)
527                 prt(format("  %c) %s", 'a' + i, menu_name[i]), 2 + i, 14);
528
529             if (!get_com(_("何を付加しますか:", "Command :"), &choice, TRUE)) {
530                 screen_load();
531                 return 0;
532             }
533
534             if (isupper(choice))
535                 choice = (char)tolower(choice);
536
537             if ('a' <= choice && choice <= 'a' + (char)mode_max - 1)
538                 mode = (int)choice - 'a' + 1;
539         }
540         screen_load();
541     }
542
543     repeat_push(mode);
544     return mode;
545 }
546
547 /*!
548  * @brief エッセンスを実際に付加する
549  * @param mode エッセンスの大別ID
550  * @return なし
551  */
552 static void add_essence(player_type *creature_ptr, ESSENCE_IDX mode)
553 {
554     OBJECT_IDX item;
555     int max_num = 0;
556     COMMAND_CODE i;
557     bool flag, redraw;
558     char choice;
559     concptr q, s;
560     object_type *o_ptr;
561     int ask = TRUE;
562     char out_val[160];
563     int num[22];
564     GAME_TEXT o_name[MAX_NLEN];
565     int use_essence;
566     essence_type *es_ptr;
567     bool able[22] = { 0 };
568     tval_type tval = 0;
569     int menu_line = (use_menu ? 1 : 0);
570
571     for (i = 0; essence_info[i].add_name; i++) {
572         es_ptr = &essence_info[i];
573
574         if (es_ptr->type != mode)
575             continue;
576         num[max_num++] = i;
577     }
578
579     if (!repeat_pull(&i) || i < 0 || i >= max_num) {
580         flag = FALSE;
581         redraw = FALSE;
582
583         (void)strnfmt(out_val, 78, _("('*'で一覧, ESCで中断) どの能力を付加しますか?", "(*=List, ESC=exit) Add which ability? "));
584         if (use_menu)
585             screen_save();
586
587         choice = (always_show_list || use_menu) ? ESCAPE : 1;
588         while (!flag) {
589             if (choice == ESCAPE)
590                 choice = ' ';
591             else if (!get_com(out_val, &choice, FALSE))
592                 break;
593
594             if (use_menu && choice != ' ') {
595                 switch (choice) {
596                 case '0': {
597                     screen_load();
598                     return;
599                 }
600
601                 case '8':
602                 case 'k':
603                 case 'K': {
604                     menu_line += (max_num - 1);
605                     break;
606                 }
607
608                 case '2':
609                 case 'j':
610                 case 'J': {
611                     menu_line++;
612                     break;
613                 }
614
615                 case '4':
616                 case 'h':
617                 case 'H': {
618                     menu_line = 1;
619                     break;
620                 }
621                 case '6':
622                 case 'l':
623                 case 'L': {
624                     menu_line = max_num;
625                     break;
626                 }
627
628                 case 'x':
629                 case 'X':
630                 case '\r':
631                 case '\n': {
632                     i = menu_line - 1;
633                     ask = FALSE;
634                     break;
635                 }
636                 }
637                 if (menu_line > max_num)
638                     menu_line -= max_num;
639             }
640             /* Request redraw */
641             if ((choice == ' ') || (choice == '*') || (choice == '?') || (use_menu && ask)) {
642                 /* Show the list */
643                 if (!redraw || use_menu) {
644                     byte y, x = 10;
645                     int ctr;
646                     char dummy[80], dummy2[80];
647                     byte col;
648
649                     strcpy(dummy, "");
650                     redraw = TRUE;
651                     if (!use_menu)
652                         screen_save();
653
654                     for (y = 1; y < 24; y++)
655                         prt("", y, x);
656
657                         /* Print header(s) */
658 #ifdef JP
659                     prt(format("   %-43s %6s/%s", "能力(必要エッセンス)", "必要数", "所持数"), 1, x);
660
661 #else
662                     prt(format("   %-43s %6s/%s", "Ability (needed essence)", "Needs", "Possess"), 1, x);
663 #endif
664                     /* Print list */
665                     for (ctr = 0; ctr < max_num; ctr++) {
666                         es_ptr = &essence_info[num[ctr]];
667
668                         if (use_menu) {
669                             if (ctr == (menu_line - 1))
670                                 strcpy(dummy, _("》 ", ">  "));
671                             else
672                                 strcpy(dummy, "   ");
673
674                         }
675                         /* letter/number for power selection */
676                         else {
677                             sprintf(dummy, "%c) ", I2A(ctr));
678                         }
679
680                         strcat(dummy, es_ptr->add_name);
681
682                         col = TERM_WHITE;
683                         able[ctr] = TRUE;
684
685                         if (es_ptr->essence != -1) {
686                             strcat(dummy, format("(%s)", essence_name[es_ptr->essence]));
687                             if (creature_ptr->magic_num1[es_ptr->essence] < es_ptr->value)
688                                 able[ctr] = FALSE;
689                         } else {
690                             switch (es_ptr->add) {
691                             case ESSENCE_SH_FIRE:
692                                 strcat(dummy, _("(焼棄+耐火炎)", "(brand fire + res.fire)"));
693                                 if (creature_ptr->magic_num1[TR_BRAND_FIRE] < es_ptr->value)
694                                     able[ctr] = FALSE;
695                                 if (creature_ptr->magic_num1[TR_RES_FIRE] < es_ptr->value)
696                                     able[ctr] = FALSE;
697                                 break;
698                             case ESSENCE_SH_ELEC:
699                                 strcat(dummy, _("(電撃+耐電撃)", "(brand elec. + res. elec.)"));
700                                 if (creature_ptr->magic_num1[TR_BRAND_ELEC] < es_ptr->value)
701                                     able[ctr] = FALSE;
702                                 if (creature_ptr->magic_num1[TR_RES_ELEC] < es_ptr->value)
703                                     able[ctr] = FALSE;
704                                 break;
705                             case ESSENCE_SH_COLD:
706                                 strcat(dummy, _("(凍結+耐冷気)", "(brand cold + res. cold)"));
707                                 if (creature_ptr->magic_num1[TR_BRAND_COLD] < es_ptr->value)
708                                     able[ctr] = FALSE;
709                                 if (creature_ptr->magic_num1[TR_RES_COLD] < es_ptr->value)
710                                     able[ctr] = FALSE;
711                                 break;
712                             case ESSENCE_RESISTANCE:
713                                 strcat(dummy, _("(耐火炎+耐冷気+耐電撃+耐酸)", "(r.fire+r.cold+r.elec+r.acid)"));
714                                 if (creature_ptr->magic_num1[TR_RES_FIRE] < es_ptr->value)
715                                     able[ctr] = FALSE;
716                                 if (creature_ptr->magic_num1[TR_RES_COLD] < es_ptr->value)
717                                     able[ctr] = FALSE;
718                                 if (creature_ptr->magic_num1[TR_RES_ELEC] < es_ptr->value)
719                                     able[ctr] = FALSE;
720                                 if (creature_ptr->magic_num1[TR_RES_ACID] < es_ptr->value)
721                                     able[ctr] = FALSE;
722                                 break;
723                             case ESSENCE_SUSTAIN:
724                                 strcat(dummy, _("(耐火炎+耐冷気+耐電撃+耐酸)", "(r.fire+r.cold+r.elec+r.acid)"));
725                                 if (creature_ptr->magic_num1[TR_RES_FIRE] < es_ptr->value)
726                                     able[ctr] = FALSE;
727                                 if (creature_ptr->magic_num1[TR_RES_COLD] < es_ptr->value)
728                                     able[ctr] = FALSE;
729                                 if (creature_ptr->magic_num1[TR_RES_ELEC] < es_ptr->value)
730                                     able[ctr] = FALSE;
731                                 if (creature_ptr->magic_num1[TR_RES_ACID] < es_ptr->value)
732                                     able[ctr] = FALSE;
733                                 break;
734                             }
735                         }
736
737                         if (!able[ctr])
738                             col = TERM_RED;
739
740                         if (es_ptr->essence != -1) {
741                             sprintf(dummy2, "%-49s %3d/%d", dummy, es_ptr->value, (int)creature_ptr->magic_num1[es_ptr->essence]);
742                         } else {
743                             sprintf(dummy2, "%-49s %3d/(\?\?)", dummy, es_ptr->value);
744                         }
745
746                         c_prt(col, dummy2, ctr + 2, x);
747                     }
748                 }
749
750                 /* Hide the list */
751                 else {
752                     /* Hide list */
753                     redraw = FALSE;
754                     screen_load();
755                 }
756
757                 /* Redo asking */
758                 continue;
759             }
760
761             if (!use_menu) {
762                 /* Note verify */
763                 ask = (isupper(choice));
764
765                 /* Lowercase */
766                 if (ask)
767                     choice = (char)tolower(choice);
768
769                 /* Extract request */
770                 i = (islower(choice) ? A2I(choice) : -1);
771             }
772
773             /* Totally Illegal */
774             if ((i < 0) || (i >= max_num) || !able[i]) {
775                 bell();
776                 continue;
777             }
778
779             /* Verify it */
780             if (ask) {
781                 char tmp_val[160];
782
783                 /* Prompt */
784                 (void)strnfmt(tmp_val, 78, _("%sを付加しますか? ", "Add the abilitiy of %s? "), essence_info[num[i]].add_name);
785
786                 /* Belay that order */
787                 if (!get_check(tmp_val))
788                     continue;
789             }
790
791             /* Stop the loop */
792             flag = TRUE;
793         }
794         if (redraw)
795             screen_load();
796
797         if (!flag)
798             return;
799
800         repeat_push(i);
801     }
802     es_ptr = &essence_info[num[i]];
803
804     if (es_ptr->add == ESSENCE_SLAY_GLOVE)
805         tval = TV_GLOVES;
806     else if (mode == 1 || mode == 5)
807         item_tester_hook = item_tester_hook_melee_ammo;
808     else if (es_ptr->add == ESSENCE_ATTACK)
809         item_tester_hook = object_allow_enchant_weapon;
810     else if (es_ptr->add == ESSENCE_AC)
811         item_tester_hook = object_is_armour;
812     else
813         item_tester_hook = object_is_weapon_armour_ammo;
814
815     q = _("どのアイテムを改良しますか?", "Improve which item? ");
816     s = _("改良できるアイテムがありません。", "You have nothing to improve.");
817
818     o_ptr = choose_object(creature_ptr, &item, q, s, (USE_INVEN | USE_FLOOR | IGNORE_BOTHHAND_SLOT), tval);
819     if (!o_ptr)
820         return;
821
822     if ((mode != 10) && (object_is_artifact(o_ptr) || object_is_smith(creature_ptr, o_ptr))) {
823         msg_print(_("そのアイテムはこれ以上改良できない。", "This item can not be improved any further."));
824         return;
825     }
826
827     describe_flavor(creature_ptr, o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
828
829     use_essence = es_ptr->value;
830     if ((o_ptr->tval >= TV_SHOT) && (o_ptr->tval <= TV_BOLT))
831         use_essence = (use_essence + 9) / 10;
832     if (o_ptr->number > 1) {
833         use_essence *= o_ptr->number;
834         msg_format(_("%d個あるのでエッセンスは%d必要です。", "For %d items, it will take %d essences."), o_ptr->number, use_essence);
835     }
836
837     if (es_ptr->essence != -1) {
838         if (creature_ptr->magic_num1[es_ptr->essence] < use_essence) {
839             msg_print(_("エッセンスが足りない。", "You don't have enough essences."));
840             return;
841         }
842         if (is_pval_flag(es_ptr->add)) {
843             if (o_ptr->pval < 0) {
844                 msg_print(_("このアイテムの能力修正を強化することはできない。", "You cannot increase magic number of this item."));
845                 return;
846             } else if (es_ptr->add == TR_BLOWS) {
847                 if (o_ptr->pval > 1) {
848                     if (!get_check(_("修正値は1になります。よろしいですか?", "The magic number of this weapon will become 1. Are you sure? ")))
849                         return;
850                 }
851
852                 o_ptr->pval = 1;
853                 msg_format(_("エッセンスを%d個使用します。", "It will take %d essences."), use_essence);
854             } else if (o_ptr->pval > 0) {
855                 use_essence *= o_ptr->pval;
856                 msg_format(_("エッセンスを%d個使用します。", "It will take %d essences."), use_essence);
857             } else {
858                 char tmp[80];
859                 char tmp_val[160];
860                 PARAMETER_VALUE pval;
861                 PARAMETER_VALUE limit = MIN(5, creature_ptr->magic_num1[es_ptr->essence] / es_ptr->value);
862
863                 sprintf(tmp, _("いくつ付加しますか? (1-%d): ", "Enchant how many? (1-%d): "), limit);
864                 strcpy(tmp_val, "1");
865
866                 if (!get_string(tmp, tmp_val, 1))
867                     return;
868                 pval = (PARAMETER_VALUE)atoi(tmp_val);
869                 if (pval > limit)
870                     pval = limit;
871                 else if (pval < 1)
872                     pval = 1;
873                 o_ptr->pval += pval;
874                 use_essence *= pval;
875                 msg_format(_("エッセンスを%d個使用します。", "It will take %d essences."), use_essence);
876             }
877
878             if (creature_ptr->magic_num1[es_ptr->essence] < use_essence) {
879                 msg_print(_("エッセンスが足りない。", "You don't have enough essences."));
880                 return;
881             }
882         } else if (es_ptr->add == ESSENCE_SLAY_GLOVE) {
883             char tmp_val[160];
884             int val;
885             HIT_PROB get_to_h;
886             HIT_POINT get_to_d;
887
888             strcpy(tmp_val, "1");
889             if (!get_string(format(_("いくつ付加しますか? (1-%d):", "Enchant how many? (1-%d):"), creature_ptr->lev / 7 + 3), tmp_val, 2))
890                 return;
891             val = atoi(tmp_val);
892             if (val > creature_ptr->lev / 7 + 3)
893                 val = creature_ptr->lev / 7 + 3;
894             else if (val < 1)
895                 val = 1;
896             use_essence *= val;
897             msg_format(_("エッセンスを%d個使用します。", "It will take %d essences."), use_essence);
898             if (creature_ptr->magic_num1[es_ptr->essence] < use_essence) {
899                 msg_print(_("エッセンスが足りない。", "You don't have enough essences."));
900                 return;
901             }
902             get_to_h = ((val + 1) / 2 + randint0(val / 2 + 1));
903             get_to_d = ((val + 1) / 2 + randint0(val / 2 + 1));
904             o_ptr->xtra4 = (get_to_h << 8) + get_to_d;
905             o_ptr->to_h += get_to_h;
906             o_ptr->to_d += get_to_d;
907         }
908         creature_ptr->magic_num1[es_ptr->essence] -= use_essence;
909         if (es_ptr->add == ESSENCE_ATTACK) {
910             if ((o_ptr->to_h >= creature_ptr->lev / 5 + 5) && (o_ptr->to_d >= creature_ptr->lev / 5 + 5)) {
911                 msg_print(_("改良に失敗した。", "You failed to enchant."));
912                 take_turn(creature_ptr, 100);
913                 return;
914             } else {
915                 if (o_ptr->to_h < creature_ptr->lev / 5 + 5)
916                     o_ptr->to_h++;
917                 if (o_ptr->to_d < creature_ptr->lev / 5 + 5)
918                     o_ptr->to_d++;
919             }
920         } else if (es_ptr->add == ESSENCE_AC) {
921             if (o_ptr->to_a >= creature_ptr->lev / 5 + 5) {
922                 msg_print(_("改良に失敗した。", "You failed to enchant."));
923                 take_turn(creature_ptr, 100);
924                 return;
925             } else {
926                 if (o_ptr->to_a < creature_ptr->lev / 5 + 5)
927                     o_ptr->to_a++;
928             }
929         } else {
930             o_ptr->xtra3 = es_ptr->add + 1;
931         }
932     } else {
933         bool success = TRUE;
934
935         switch (es_ptr->add) {
936         case ESSENCE_SH_FIRE:
937             if ((creature_ptr->magic_num1[TR_BRAND_FIRE] < use_essence) || (creature_ptr->magic_num1[TR_RES_FIRE] < use_essence)) {
938                 success = FALSE;
939                 break;
940             }
941             creature_ptr->magic_num1[TR_BRAND_FIRE] -= use_essence;
942             creature_ptr->magic_num1[TR_RES_FIRE] -= use_essence;
943             break;
944         case ESSENCE_SH_ELEC:
945             if ((creature_ptr->magic_num1[TR_BRAND_ELEC] < use_essence) || (creature_ptr->magic_num1[TR_RES_ELEC] < use_essence)) {
946                 success = FALSE;
947                 break;
948             }
949             creature_ptr->magic_num1[TR_BRAND_ELEC] -= use_essence;
950             creature_ptr->magic_num1[TR_RES_ELEC] -= use_essence;
951             break;
952         case ESSENCE_SH_COLD:
953             if ((creature_ptr->magic_num1[TR_BRAND_COLD] < use_essence) || (creature_ptr->magic_num1[TR_RES_COLD] < use_essence)) {
954                 success = FALSE;
955                 break;
956             }
957             creature_ptr->magic_num1[TR_BRAND_COLD] -= use_essence;
958             creature_ptr->magic_num1[TR_RES_COLD] -= use_essence;
959             break;
960         case ESSENCE_RESISTANCE:
961         case ESSENCE_SUSTAIN:
962             if ((creature_ptr->magic_num1[TR_RES_ACID] < use_essence) || (creature_ptr->magic_num1[TR_RES_ELEC] < use_essence)
963                 || (creature_ptr->magic_num1[TR_RES_FIRE] < use_essence) || (creature_ptr->magic_num1[TR_RES_COLD] < use_essence)) {
964                 success = FALSE;
965                 break;
966             }
967             creature_ptr->magic_num1[TR_RES_ACID] -= use_essence;
968             creature_ptr->magic_num1[TR_RES_ELEC] -= use_essence;
969             creature_ptr->magic_num1[TR_RES_FIRE] -= use_essence;
970             creature_ptr->magic_num1[TR_RES_COLD] -= use_essence;
971             break;
972         }
973         if (!success) {
974             msg_print(_("エッセンスが足りない。", "You don't have enough essences."));
975             return;
976         }
977         if (es_ptr->add == ESSENCE_SUSTAIN) {
978             add_flag(o_ptr->art_flags, TR_IGNORE_ACID);
979             add_flag(o_ptr->art_flags, TR_IGNORE_ELEC);
980             add_flag(o_ptr->art_flags, TR_IGNORE_FIRE);
981             add_flag(o_ptr->art_flags, TR_IGNORE_COLD);
982         } else {
983             o_ptr->xtra3 = es_ptr->add + 1;
984         }
985     }
986
987     take_turn(creature_ptr, 100);
988     _(msg_format("%sに%sの能力を付加しました。", o_name, es_ptr->add_name), msg_format("You have added ability of %s to %s.", es_ptr->add_name, o_name));
989     creature_ptr->update |= (PU_COMBINE | PU_REORDER);
990     creature_ptr->window |= (PW_INVEN);
991 }
992
993 /*!
994  * @brief エッセンスを消去する
995  * @return なし
996  */
997 static void erase_essence(player_type *creature_ptr)
998 {
999     OBJECT_IDX item;
1000     concptr q, s;
1001     object_type *o_ptr;
1002     GAME_TEXT o_name[MAX_NLEN];
1003     BIT_FLAGS flgs[TR_FLAG_SIZE];
1004
1005     item_tester_hook = object_is_smith;
1006
1007     q = _("どのアイテムのエッセンスを消去しますか?", "Remove from which item? ");
1008     s = _("エッセンスを付加したアイテムがありません。", "You have nothing to remove essence.");
1009
1010     o_ptr = choose_object(creature_ptr, &item, q, s, (USE_INVEN | USE_FLOOR), 0);
1011     if (!o_ptr)
1012         return;
1013
1014     describe_flavor(creature_ptr, o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
1015     if (!get_check(format(_("よろしいですか? [%s]", "Are you sure? [%s]"), o_name)))
1016         return;
1017
1018     take_turn(creature_ptr, 100);
1019
1020     if (o_ptr->xtra3 == 1 + ESSENCE_SLAY_GLOVE) {
1021         o_ptr->to_h -= (o_ptr->xtra4 >> 8);
1022         o_ptr->to_d -= (o_ptr->xtra4 & 0x000f);
1023         o_ptr->xtra4 = 0;
1024         if (o_ptr->to_h < 0)
1025             o_ptr->to_h = 0;
1026         if (o_ptr->to_d < 0)
1027             o_ptr->to_d = 0;
1028     }
1029     o_ptr->xtra3 = 0;
1030     object_flags(creature_ptr, o_ptr, flgs);
1031     if (!(have_pval_flags(flgs)))
1032         o_ptr->pval = 0;
1033     msg_print(_("エッセンスを取り去った。", "You removed all essence you have added."));
1034     creature_ptr->update |= (PU_COMBINE | PU_REORDER);
1035     creature_ptr->window |= (PW_INVEN);
1036 }
1037
1038 /*!
1039  * @brief 鍛冶コマンドのメインルーチン
1040  * @param only_browse TRUEならばエッセンス一覧の表示のみを行う
1041  * @return なし
1042  */
1043 void do_cmd_kaji(player_type *creature_ptr, bool only_browse)
1044 {
1045     COMMAND_CODE mode = 0;
1046     char choice;
1047
1048     COMMAND_CODE menu_line = (use_menu ? 1 : 0);
1049
1050     if (!only_browse) {
1051         if (cmd_limit_confused(creature_ptr))
1052             return;
1053         if (cmd_limit_blind(creature_ptr))
1054             return;
1055         if (cmd_limit_image(creature_ptr))
1056             return;
1057     }
1058
1059     if (!(repeat_pull(&mode) && 1 <= mode && mode <= 5)) {
1060         if (only_browse)
1061             screen_save();
1062         do {
1063             if (!only_browse)
1064                 screen_save();
1065             if (use_menu) {
1066                 while (!mode) {
1067 #ifdef JP
1068                     prt(format(" %s エッセンス一覧", (menu_line == 1) ? "》" : "  "), 2, 14);
1069                     prt(format(" %s エッセンス抽出", (menu_line == 2) ? "》" : "  "), 3, 14);
1070                     prt(format(" %s エッセンス消去", (menu_line == 3) ? "》" : "  "), 4, 14);
1071                     prt(format(" %s エッセンス付加", (menu_line == 4) ? "》" : "  "), 5, 14);
1072                     prt(format(" %s 武器/防具強化", (menu_line == 5) ? "》" : "  "), 6, 14);
1073                     prt(format("どの種類の技術を%sますか?", only_browse ? "調べ" : "使い"), 0, 0);
1074 #else
1075                     prt(format(" %s List essences", (menu_line == 1) ? "> " : "  "), 2, 14);
1076                     prt(format(" %s Extract essence", (menu_line == 2) ? "> " : "  "), 3, 14);
1077                     prt(format(" %s Remove essence", (menu_line == 3) ? "> " : "  "), 4, 14);
1078                     prt(format(" %s Add essence", (menu_line == 4) ? "> " : "  "), 5, 14);
1079                     prt(format(" %s Enchant weapon/armor", (menu_line == 5) ? "> " : "  "), 6, 14);
1080                     prt(format("Choose command from menu."), 0, 0);
1081 #endif
1082                     choice = inkey();
1083                     switch (choice) {
1084                     case ESCAPE:
1085                     case 'z':
1086                     case 'Z':
1087                         screen_load();
1088                         return;
1089                     case '2':
1090                     case 'j':
1091                     case 'J':
1092                         menu_line++;
1093                         break;
1094                     case '8':
1095                     case 'k':
1096                     case 'K':
1097                         menu_line += 4;
1098                         break;
1099                     case '\r':
1100                     case '\n':
1101                     case 'x':
1102                     case 'X':
1103                         mode = menu_line;
1104                         break;
1105                     }
1106                     if (menu_line > 5)
1107                         menu_line -= 5;
1108                 }
1109             }
1110
1111             else {
1112                 while (!mode) {
1113                     prt(_("  a) エッセンス一覧", "  a) List essences"), 2, 14);
1114                     prt(_("  b) エッセンス抽出", "  b) Extract essence"), 3, 14);
1115                     prt(_("  c) エッセンス消去", "  c) Remove essence"), 4, 14);
1116                     prt(_("  d) エッセンス付加", "  d) Add essence"), 5, 14);
1117                     prt(_("  e) 武器/防具強化", "  e) Enchant weapon/armor"), 6, 14);
1118 #ifdef JP
1119                     if (!get_com(format("どの能力を%sますか:", only_browse ? "調べ" : "使い"), &choice, TRUE))
1120 #else
1121                     if (!get_com("Command :", &choice, TRUE))
1122 #endif
1123                     {
1124                         screen_load();
1125                         return;
1126                     }
1127                     switch (choice) {
1128                     case 'A':
1129                     case 'a':
1130                         mode = 1;
1131                         break;
1132                     case 'B':
1133                     case 'b':
1134                         mode = 2;
1135                         break;
1136                     case 'C':
1137                     case 'c':
1138                         mode = 3;
1139                         break;
1140                     case 'D':
1141                     case 'd':
1142                         mode = 4;
1143                         break;
1144                     case 'E':
1145                     case 'e':
1146                         mode = 5;
1147                         break;
1148                     }
1149                 }
1150             }
1151
1152             if (only_browse) {
1153                 char temp[62 * 5];
1154                 int line, j;
1155
1156                 /* Clear lines, position cursor  (really should use strlen here) */
1157                 term_erase(14, 21, 255);
1158                 term_erase(14, 20, 255);
1159                 term_erase(14, 19, 255);
1160                 term_erase(14, 18, 255);
1161                 term_erase(14, 17, 255);
1162                 term_erase(14, 16, 255);
1163
1164                 shape_buffer(kaji_tips[mode - 1], 62, temp, sizeof(temp));
1165                 for (j = 0, line = 17; temp[j]; j += (1 + strlen(&temp[j]))) {
1166                     prt(&temp[j], line, 15);
1167                     line++;
1168                 }
1169                 mode = 0;
1170             }
1171             if (!only_browse)
1172                 screen_load();
1173         } while (only_browse);
1174         repeat_push(mode);
1175     }
1176     switch (mode) {
1177     case 1:
1178         display_essence(creature_ptr);
1179         break;
1180     case 2:
1181         drain_essence(creature_ptr);
1182         break;
1183     case 3:
1184         erase_essence(creature_ptr);
1185         break;
1186     case 4:
1187         mode = choose_essence();
1188         if (mode == 0)
1189             break;
1190         add_essence(creature_ptr, mode);
1191         break;
1192     case 5:
1193         add_essence(creature_ptr, 10);
1194         break;
1195     }
1196 }