OSDN Git Service

[Refactor] player_type から total_weight を削除し calc_inventory_weight() を反映. / Remove...
[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 (has_flag(old_flgs, TR_KILL_DRAGON))
267         add_flag(old_flgs, TR_SLAY_DRAGON);
268     if (has_flag(old_flgs, TR_KILL_ANIMAL))
269         add_flag(old_flgs, TR_SLAY_ANIMAL);
270     if (has_flag(old_flgs, TR_KILL_EVIL))
271         add_flag(old_flgs, TR_SLAY_EVIL);
272     if (has_flag(old_flgs, TR_KILL_UNDEAD))
273         add_flag(old_flgs, TR_SLAY_UNDEAD);
274     if (has_flag(old_flgs, TR_KILL_DEMON))
275         add_flag(old_flgs, TR_SLAY_DEMON);
276     if (has_flag(old_flgs, TR_KILL_ORC))
277         add_flag(old_flgs, TR_SLAY_ORC);
278     if (has_flag(old_flgs, TR_KILL_TROLL))
279         add_flag(old_flgs, TR_SLAY_TROLL);
280     if (has_flag(old_flgs, TR_KILL_GIANT))
281         add_flag(old_flgs, TR_SLAY_GIANT);
282     if (has_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 (has_flag(old_flgs, TR_ADD_L_CURSE))
297         dec--;
298     if (has_flag(old_flgs, TR_ADD_H_CURSE))
299         dec--;
300     if (has_flag(old_flgs, TR_AGGRAVATE))
301         dec--;
302     if (has_flag(old_flgs, TR_NO_TELE))
303         dec--;
304     if (has_flag(old_flgs, TR_DRAIN_EXP))
305         dec--;
306     if (has_flag(old_flgs, TR_DRAIN_HP))
307         dec--;
308     if (has_flag(old_flgs, TR_DRAIN_MANA))
309         dec--;
310     if (has_flag(old_flgs, TR_CALL_ANIMAL))
311         dec--;
312     if (has_flag(old_flgs, TR_CALL_DEMON))
313         dec--;
314     if (has_flag(old_flgs, TR_CALL_DRAGON))
315         dec--;
316     if (has_flag(old_flgs, TR_CALL_UNDEAD))
317         dec--;
318     if (has_flag(old_flgs, TR_COWARDICE))
319         dec--;
320     if (has_flag(old_flgs, TR_LOW_MELEE))
321         dec--;
322     if (has_flag(old_flgs, TR_LOW_AC))
323         dec--;
324     if (has_flag(old_flgs, TR_LOW_MAGIC))
325         dec--;
326     if (has_flag(old_flgs, TR_FAST_DIGEST))
327         dec--;
328     if (has_flag(old_flgs, TR_SLOW_REGEN))
329         dec--;
330     if (has_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     o_ptr->ident |= (IDENT_FULL_KNOWN);
350     object_aware(creature_ptr, o_ptr);
351     object_known(o_ptr);
352
353     object_flags(creature_ptr, o_ptr, new_flgs);
354
355     for (i = 0; essence_info[i].add_name; i++) {
356         essence_type *es_ptr = &essence_info[i];
357         PARAMETER_VALUE pval = 0;
358
359         if (es_ptr->add < TR_FLAG_MAX && is_pval_flag(es_ptr->add) && old_pval)
360             pval = (has_flag(new_flgs, es_ptr->add)) ? old_pval - o_ptr->pval : old_pval;
361
362         if (es_ptr->add < TR_FLAG_MAX && (!has_flag(new_flgs, es_ptr->add) || pval) && has_flag(old_flgs, es_ptr->add)) {
363             if (pval) {
364                 drain_value[es_ptr->essence] += 10 * pval;
365             } else if (es_ptr->essence != -2) {
366                 drain_value[es_ptr->essence] += 10;
367             } else if (es_ptr->add == TR_SH_FIRE) {
368                 drain_value[TR_BRAND_FIRE] += 10;
369                 drain_value[TR_RES_FIRE] += 10;
370             } else if (es_ptr->add == TR_SH_ELEC) {
371                 drain_value[TR_BRAND_ELEC] += 10;
372                 drain_value[TR_RES_ELEC] += 10;
373             } else if (es_ptr->add == TR_SH_COLD) {
374                 drain_value[TR_BRAND_COLD] += 10;
375                 drain_value[TR_RES_COLD] += 10;
376             } else if (es_ptr->add == TR_LITE_2) {
377                 drain_value[TR_LITE_1] += 20;
378             } else if (es_ptr->add == TR_LITE_3) {
379                 drain_value[TR_LITE_1] += 30;
380             }
381         }
382     }
383
384     if ((has_flag(old_flgs, TR_FORCE_WEAPON)) && !(has_flag(new_flgs, TR_FORCE_WEAPON))) {
385         drain_value[TR_INT] += 5;
386         drain_value[TR_WIS] += 5;
387     }
388     if ((has_flag(old_flgs, TR_VORPAL)) && !(has_flag(new_flgs, TR_VORPAL))) {
389         drain_value[TR_BRAND_POIS] += 5;
390         drain_value[TR_BRAND_ACID] += 5;
391         drain_value[TR_BRAND_ELEC] += 5;
392         drain_value[TR_BRAND_FIRE] += 5;
393         drain_value[TR_BRAND_COLD] += 5;
394     }
395     if ((has_flag(old_flgs, TR_DEC_MANA)) && !(has_flag(new_flgs, TR_DEC_MANA))) {
396         drain_value[TR_INT] += 10;
397     }
398     if ((has_flag(old_flgs, TR_XTRA_MIGHT)) && !(has_flag(new_flgs, TR_XTRA_MIGHT))) {
399         drain_value[TR_STR] += 10;
400     }
401     if ((has_flag(old_flgs, TR_XTRA_SHOTS)) && !(has_flag(new_flgs, TR_XTRA_SHOTS))) {
402         drain_value[TR_DEX] += 10;
403     }
404     if (old_name2 == EGO_2WEAPON) {
405         drain_value[TR_DEX] += 20;
406     }
407     if (object_is_weapon_ammo(o_ptr)) {
408         if (old_ds > o_ptr->ds)
409             drain_value[TR_ES_ATTACK] += (old_ds - o_ptr->ds) * 10;
410
411         if (old_dd > o_ptr->dd)
412             drain_value[TR_ES_ATTACK] += (old_dd - o_ptr->dd) * 10;
413     }
414     if (old_to_h > o_ptr->to_h)
415         drain_value[TR_ES_ATTACK] += (old_to_h - o_ptr->to_h) * 10;
416     if (old_to_d > o_ptr->to_d)
417         drain_value[TR_ES_ATTACK] += (old_to_d - o_ptr->to_d) * 10;
418     if (old_ac > o_ptr->ac)
419         drain_value[TR_ES_AC] += (old_ac - o_ptr->ac) * 10;
420     if (old_to_a > o_ptr->to_a)
421         drain_value[TR_ES_AC] += (old_to_a - o_ptr->to_a) * 10;
422
423     for (i = 0; i < sizeof(drain_value) / sizeof(int); i++) {
424         drain_value[i] *= number;
425         drain_value[i] = drain_value[i] * dec / 4;
426         drain_value[i] = MAX(drain_value[i], 0);
427         if ((o_ptr->tval >= TV_SHOT) && (o_ptr->tval <= TV_BOLT))
428             drain_value[i] /= 10;
429         if (drain_value[i]) {
430             observe = TRUE;
431         }
432     }
433     if (!observe) {
434         msg_print(_("エッセンスは抽出できませんでした。", "You were not able to extract any essence."));
435     } else {
436         msg_print(_("抽出したエッセンス:", "Extracted essences:"));
437
438         for (i = 0; essence_name[i]; i++) {
439             if (!essence_name[i][0])
440                 continue;
441             if (!drain_value[i])
442                 continue;
443
444             creature_ptr->magic_num1[i] += drain_value[i];
445             creature_ptr->magic_num1[i] = MIN(20000, creature_ptr->magic_num1[i]);
446             msg_print(NULL);
447             msg_format("%s...%d%s", essence_name[i], drain_value[i], _("。", ". "));
448         }
449     }
450
451     /* Apply autodestroy/inscription to the drained item */
452     autopick_alter_item(creature_ptr, item, TRUE);
453     creature_ptr->update |= (PU_COMBINE | PU_REORDER);
454     creature_ptr->window |= (PW_INVEN);
455 }
456
457 /*!
458  * @brief 付加するエッセンスの大別を選択する
459  * @return 選んだエッセンスの大別ID
460  */
461 static COMMAND_CODE choose_essence(void)
462 {
463     COMMAND_CODE mode = 0;
464     char choice;
465     COMMAND_CODE menu_line = (use_menu ? 1 : 0);
466
467 #ifdef JP
468     concptr menu_name[] = { "武器属性", "耐性", "能力", "数値", "スレイ", "ESP", "その他" };
469 #else
470     concptr menu_name[] = { "Brand weapon", "Resistance", "Ability", "Magic number", "Slay", "ESP", "Others" };
471 #endif
472     const COMMAND_CODE mode_max = 7;
473
474     if (repeat_pull(&mode) && 1 <= mode && mode <= mode_max)
475         return mode;
476     mode = 0;
477     if (use_menu) {
478         screen_save();
479
480         while (!mode) {
481             int i;
482             for (i = 0; i < mode_max; i++)
483 #ifdef JP
484                 prt(format(" %s %s", (menu_line == 1 + i) ? "》" : "  ", menu_name[i]), 2 + i, 14);
485             prt("どの種類のエッセンス付加を行いますか?", 0, 0);
486 #else
487                 prt(format(" %s %s", (menu_line == 1 + i) ? "> " : "  ", menu_name[i]), 2 + i, 14);
488             prt("Choose from menu.", 0, 0);
489 #endif
490
491             choice = inkey();
492             switch (choice) {
493             case ESCAPE:
494             case 'z':
495             case 'Z':
496                 screen_load();
497                 return 0;
498             case '2':
499             case 'j':
500             case 'J':
501                 menu_line++;
502                 break;
503             case '8':
504             case 'k':
505             case 'K':
506                 menu_line += mode_max - 1;
507                 break;
508             case '\r':
509             case '\n':
510             case 'x':
511             case 'X':
512                 mode = menu_line;
513                 break;
514             }
515             if (menu_line > mode_max)
516                 menu_line -= mode_max;
517         }
518         screen_load();
519     } else {
520         screen_save();
521         while (!mode) {
522             int i;
523
524             for (i = 0; i < mode_max; i++)
525                 prt(format("  %c) %s", 'a' + i, menu_name[i]), 2 + i, 14);
526
527             if (!get_com(_("何を付加しますか:", "Command :"), &choice, TRUE)) {
528                 screen_load();
529                 return 0;
530             }
531
532             if (isupper(choice))
533                 choice = (char)tolower(choice);
534
535             if ('a' <= choice && choice <= 'a' + (char)mode_max - 1)
536                 mode = (int)choice - 'a' + 1;
537         }
538         screen_load();
539     }
540
541     repeat_push(mode);
542     return mode;
543 }
544
545 /*!
546  * @brief エッセンスを実際に付加する
547  * @param mode エッセンスの大別ID
548  * @return なし
549  */
550 static void add_essence(player_type *creature_ptr, ESSENCE_IDX mode)
551 {
552     OBJECT_IDX item;
553     int max_num = 0;
554     COMMAND_CODE i;
555     bool flag, redraw;
556     char choice;
557     concptr q, s;
558     object_type *o_ptr;
559     int ask = TRUE;
560     char out_val[160];
561     int num[22];
562     GAME_TEXT o_name[MAX_NLEN];
563     int use_essence;
564     essence_type *es_ptr;
565     bool able[22] = { 0 };
566     tval_type tval = 0;
567     int menu_line = (use_menu ? 1 : 0);
568
569     for (i = 0; essence_info[i].add_name; i++) {
570         es_ptr = &essence_info[i];
571
572         if (es_ptr->type != mode)
573             continue;
574         num[max_num++] = i;
575     }
576
577     if (!repeat_pull(&i) || i < 0 || i >= max_num) {
578         flag = FALSE;
579         redraw = FALSE;
580
581         (void)strnfmt(out_val, 78, _("('*'で一覧, ESCで中断) どの能力を付加しますか?", "(*=List, ESC=exit) Add which ability? "));
582         if (use_menu)
583             screen_save();
584
585         choice = (always_show_list || use_menu) ? ESCAPE : 1;
586         while (!flag) {
587             if (choice == ESCAPE)
588                 choice = ' ';
589             else if (!get_com(out_val, &choice, FALSE))
590                 break;
591
592             if (use_menu && choice != ' ') {
593                 switch (choice) {
594                 case '0': {
595                     screen_load();
596                     return;
597                 }
598
599                 case '8':
600                 case 'k':
601                 case 'K': {
602                     menu_line += (max_num - 1);
603                     break;
604                 }
605
606                 case '2':
607                 case 'j':
608                 case 'J': {
609                     menu_line++;
610                     break;
611                 }
612
613                 case '4':
614                 case 'h':
615                 case 'H': {
616                     menu_line = 1;
617                     break;
618                 }
619                 case '6':
620                 case 'l':
621                 case 'L': {
622                     menu_line = max_num;
623                     break;
624                 }
625
626                 case 'x':
627                 case 'X':
628                 case '\r':
629                 case '\n': {
630                     i = menu_line - 1;
631                     ask = FALSE;
632                     break;
633                 }
634                 }
635                 if (menu_line > max_num)
636                     menu_line -= max_num;
637             }
638             /* Request redraw */
639             if ((choice == ' ') || (choice == '*') || (choice == '?') || (use_menu && ask)) {
640                 /* Show the list */
641                 if (!redraw || use_menu) {
642                     byte y, x = 10;
643                     int ctr;
644                     char dummy[80], dummy2[80];
645                     byte col;
646
647                     strcpy(dummy, "");
648                     redraw = TRUE;
649                     if (!use_menu)
650                         screen_save();
651
652                     for (y = 1; y < 24; y++)
653                         prt("", y, x);
654
655                         /* Print header(s) */
656 #ifdef JP
657                     prt(format("   %-43s %6s/%s", "能力(必要エッセンス)", "必要数", "所持数"), 1, x);
658
659 #else
660                     prt(format("   %-43s %6s/%s", "Ability (needed essence)", "Needs", "Possess"), 1, x);
661 #endif
662                     /* Print list */
663                     for (ctr = 0; ctr < max_num; ctr++) {
664                         es_ptr = &essence_info[num[ctr]];
665
666                         if (use_menu) {
667                             if (ctr == (menu_line - 1))
668                                 strcpy(dummy, _("》 ", ">  "));
669                             else
670                                 strcpy(dummy, "   ");
671
672                         }
673                         /* letter/number for power selection */
674                         else {
675                             sprintf(dummy, "%c) ", I2A(ctr));
676                         }
677
678                         strcat(dummy, es_ptr->add_name);
679
680                         col = TERM_WHITE;
681                         able[ctr] = TRUE;
682
683                         if (es_ptr->essence != -1) {
684                             strcat(dummy, format("(%s)", essence_name[es_ptr->essence]));
685                             if (creature_ptr->magic_num1[es_ptr->essence] < es_ptr->value)
686                                 able[ctr] = FALSE;
687                         } else {
688                             switch (es_ptr->add) {
689                             case ESSENCE_SH_FIRE:
690                                 strcat(dummy, _("(焼棄+耐火炎)", "(brand fire + res.fire)"));
691                                 if (creature_ptr->magic_num1[TR_BRAND_FIRE] < es_ptr->value)
692                                     able[ctr] = FALSE;
693                                 if (creature_ptr->magic_num1[TR_RES_FIRE] < es_ptr->value)
694                                     able[ctr] = FALSE;
695                                 break;
696                             case ESSENCE_SH_ELEC:
697                                 strcat(dummy, _("(電撃+耐電撃)", "(brand elec. + res. elec.)"));
698                                 if (creature_ptr->magic_num1[TR_BRAND_ELEC] < es_ptr->value)
699                                     able[ctr] = FALSE;
700                                 if (creature_ptr->magic_num1[TR_RES_ELEC] < es_ptr->value)
701                                     able[ctr] = FALSE;
702                                 break;
703                             case ESSENCE_SH_COLD:
704                                 strcat(dummy, _("(凍結+耐冷気)", "(brand cold + res. cold)"));
705                                 if (creature_ptr->magic_num1[TR_BRAND_COLD] < es_ptr->value)
706                                     able[ctr] = FALSE;
707                                 if (creature_ptr->magic_num1[TR_RES_COLD] < es_ptr->value)
708                                     able[ctr] = FALSE;
709                                 break;
710                             case ESSENCE_RESISTANCE:
711                                 strcat(dummy, _("(耐火炎+耐冷気+耐電撃+耐酸)", "(r.fire+r.cold+r.elec+r.acid)"));
712                                 if (creature_ptr->magic_num1[TR_RES_FIRE] < es_ptr->value)
713                                     able[ctr] = FALSE;
714                                 if (creature_ptr->magic_num1[TR_RES_COLD] < es_ptr->value)
715                                     able[ctr] = FALSE;
716                                 if (creature_ptr->magic_num1[TR_RES_ELEC] < es_ptr->value)
717                                     able[ctr] = FALSE;
718                                 if (creature_ptr->magic_num1[TR_RES_ACID] < es_ptr->value)
719                                     able[ctr] = FALSE;
720                                 break;
721                             case ESSENCE_SUSTAIN:
722                                 strcat(dummy, _("(耐火炎+耐冷気+耐電撃+耐酸)", "(r.fire+r.cold+r.elec+r.acid)"));
723                                 if (creature_ptr->magic_num1[TR_RES_FIRE] < es_ptr->value)
724                                     able[ctr] = FALSE;
725                                 if (creature_ptr->magic_num1[TR_RES_COLD] < es_ptr->value)
726                                     able[ctr] = FALSE;
727                                 if (creature_ptr->magic_num1[TR_RES_ELEC] < es_ptr->value)
728                                     able[ctr] = FALSE;
729                                 if (creature_ptr->magic_num1[TR_RES_ACID] < es_ptr->value)
730                                     able[ctr] = FALSE;
731                                 break;
732                             }
733                         }
734
735                         if (!able[ctr])
736                             col = TERM_RED;
737
738                         if (es_ptr->essence != -1) {
739                             sprintf(dummy2, "%-49s %3d/%d", dummy, es_ptr->value, (int)creature_ptr->magic_num1[es_ptr->essence]);
740                         } else {
741                             sprintf(dummy2, "%-49s %3d/(\?\?)", dummy, es_ptr->value);
742                         }
743
744                         c_prt(col, dummy2, ctr + 2, x);
745                     }
746                 }
747
748                 /* Hide the list */
749                 else {
750                     /* Hide list */
751                     redraw = FALSE;
752                     screen_load();
753                 }
754
755                 /* Redo asking */
756                 continue;
757             }
758
759             if (!use_menu) {
760                 /* Note verify */
761                 ask = (isupper(choice));
762
763                 /* Lowercase */
764                 if (ask)
765                     choice = (char)tolower(choice);
766
767                 /* Extract request */
768                 i = (islower(choice) ? A2I(choice) : -1);
769             }
770
771             /* Totally Illegal */
772             if ((i < 0) || (i >= max_num) || !able[i]) {
773                 bell();
774                 continue;
775             }
776
777             /* Verify it */
778             if (ask) {
779                 char tmp_val[160];
780
781                 /* Prompt */
782                 (void)strnfmt(tmp_val, 78, _("%sを付加しますか? ", "Add the abilitiy of %s? "), essence_info[num[i]].add_name);
783
784                 /* Belay that order */
785                 if (!get_check(tmp_val))
786                     continue;
787             }
788
789             /* Stop the loop */
790             flag = TRUE;
791         }
792         if (redraw)
793             screen_load();
794
795         if (!flag)
796             return;
797
798         repeat_push(i);
799     }
800     es_ptr = &essence_info[num[i]];
801
802     if (es_ptr->add == ESSENCE_SLAY_GLOVE)
803         tval = TV_GLOVES;
804     else if (mode == 1 || mode == 5)
805         item_tester_hook = item_tester_hook_melee_ammo;
806     else if (es_ptr->add == ESSENCE_ATTACK)
807         item_tester_hook = object_allow_enchant_weapon;
808     else if (es_ptr->add == ESSENCE_AC)
809         item_tester_hook = object_is_armour;
810     else
811         item_tester_hook = object_is_weapon_armour_ammo;
812
813     q = _("どのアイテムを改良しますか?", "Improve which item? ");
814     s = _("改良できるアイテムがありません。", "You have nothing to improve.");
815
816     o_ptr = choose_object(creature_ptr, &item, q, s, (USE_INVEN | USE_FLOOR | IGNORE_BOTHHAND_SLOT), tval);
817     if (!o_ptr)
818         return;
819
820     if ((mode != 10) && (object_is_artifact(o_ptr) || object_is_smith(creature_ptr, o_ptr))) {
821         msg_print(_("そのアイテムはこれ以上改良できない。", "This item can not be improved any further."));
822         return;
823     }
824
825     describe_flavor(creature_ptr, o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
826
827     use_essence = es_ptr->value;
828     if ((o_ptr->tval >= TV_SHOT) && (o_ptr->tval <= TV_BOLT))
829         use_essence = (use_essence + 9) / 10;
830     if (o_ptr->number > 1) {
831         use_essence *= o_ptr->number;
832         msg_format(_("%d個あるのでエッセンスは%d必要です。", "For %d items, it will take %d essences."), o_ptr->number, use_essence);
833     }
834
835     if (es_ptr->essence != -1) {
836         if (creature_ptr->magic_num1[es_ptr->essence] < use_essence) {
837             msg_print(_("エッセンスが足りない。", "You don't have enough essences."));
838             return;
839         }
840         if (is_pval_flag(es_ptr->add)) {
841             if (o_ptr->pval < 0) {
842                 msg_print(_("このアイテムの能力修正を強化することはできない。", "You cannot increase magic number of this item."));
843                 return;
844             } else if (es_ptr->add == TR_BLOWS) {
845                 if (o_ptr->pval > 1) {
846                     if (!get_check(_("修正値は1になります。よろしいですか?", "The magic number of this weapon will become 1. Are you sure? ")))
847                         return;
848                 }
849
850                 o_ptr->pval = 1;
851                 msg_format(_("エッセンスを%d個使用します。", "It will take %d essences."), use_essence);
852             } else if (o_ptr->pval > 0) {
853                 use_essence *= o_ptr->pval;
854                 msg_format(_("エッセンスを%d個使用します。", "It will take %d essences."), use_essence);
855             } else {
856                 char tmp[80];
857                 char tmp_val[160];
858                 PARAMETER_VALUE pval;
859                 PARAMETER_VALUE limit = MIN(5, creature_ptr->magic_num1[es_ptr->essence] / es_ptr->value);
860
861                 sprintf(tmp, _("いくつ付加しますか? (1-%d): ", "Enchant how many? (1-%d): "), limit);
862                 strcpy(tmp_val, "1");
863
864                 if (!get_string(tmp, tmp_val, 1))
865                     return;
866                 pval = (PARAMETER_VALUE)atoi(tmp_val);
867                 if (pval > limit)
868                     pval = limit;
869                 else if (pval < 1)
870                     pval = 1;
871                 o_ptr->pval += pval;
872                 use_essence *= pval;
873                 msg_format(_("エッセンスを%d個使用します。", "It will take %d essences."), use_essence);
874             }
875
876             if (creature_ptr->magic_num1[es_ptr->essence] < use_essence) {
877                 msg_print(_("エッセンスが足りない。", "You don't have enough essences."));
878                 return;
879             }
880         } else if (es_ptr->add == ESSENCE_SLAY_GLOVE) {
881             char tmp_val[160];
882             int val;
883             HIT_PROB get_to_h;
884             HIT_POINT get_to_d;
885
886             strcpy(tmp_val, "1");
887             if (!get_string(format(_("いくつ付加しますか? (1-%d):", "Enchant how many? (1-%d):"), creature_ptr->lev / 7 + 3), tmp_val, 2))
888                 return;
889             val = atoi(tmp_val);
890             if (val > creature_ptr->lev / 7 + 3)
891                 val = creature_ptr->lev / 7 + 3;
892             else if (val < 1)
893                 val = 1;
894             use_essence *= val;
895             msg_format(_("エッセンスを%d個使用します。", "It will take %d essences."), use_essence);
896             if (creature_ptr->magic_num1[es_ptr->essence] < use_essence) {
897                 msg_print(_("エッセンスが足りない。", "You don't have enough essences."));
898                 return;
899             }
900             get_to_h = ((val + 1) / 2 + randint0(val / 2 + 1));
901             get_to_d = ((val + 1) / 2 + randint0(val / 2 + 1));
902             o_ptr->xtra4 = (get_to_h << 8) + get_to_d;
903             o_ptr->to_h += get_to_h;
904             o_ptr->to_d += get_to_d;
905         }
906         creature_ptr->magic_num1[es_ptr->essence] -= use_essence;
907         if (es_ptr->add == ESSENCE_ATTACK) {
908             if ((o_ptr->to_h >= creature_ptr->lev / 5 + 5) && (o_ptr->to_d >= creature_ptr->lev / 5 + 5)) {
909                 msg_print(_("改良に失敗した。", "You failed to enchant."));
910                 take_turn(creature_ptr, 100);
911                 return;
912             } else {
913                 if (o_ptr->to_h < creature_ptr->lev / 5 + 5)
914                     o_ptr->to_h++;
915                 if (o_ptr->to_d < creature_ptr->lev / 5 + 5)
916                     o_ptr->to_d++;
917             }
918         } else if (es_ptr->add == ESSENCE_AC) {
919             if (o_ptr->to_a >= creature_ptr->lev / 5 + 5) {
920                 msg_print(_("改良に失敗した。", "You failed to enchant."));
921                 take_turn(creature_ptr, 100);
922                 return;
923             } else {
924                 if (o_ptr->to_a < creature_ptr->lev / 5 + 5)
925                     o_ptr->to_a++;
926             }
927         } else {
928             o_ptr->xtra3 = es_ptr->add + 1;
929         }
930     } else {
931         bool success = TRUE;
932
933         switch (es_ptr->add) {
934         case ESSENCE_SH_FIRE:
935             if ((creature_ptr->magic_num1[TR_BRAND_FIRE] < use_essence) || (creature_ptr->magic_num1[TR_RES_FIRE] < use_essence)) {
936                 success = FALSE;
937                 break;
938             }
939             creature_ptr->magic_num1[TR_BRAND_FIRE] -= use_essence;
940             creature_ptr->magic_num1[TR_RES_FIRE] -= use_essence;
941             break;
942         case ESSENCE_SH_ELEC:
943             if ((creature_ptr->magic_num1[TR_BRAND_ELEC] < use_essence) || (creature_ptr->magic_num1[TR_RES_ELEC] < use_essence)) {
944                 success = FALSE;
945                 break;
946             }
947             creature_ptr->magic_num1[TR_BRAND_ELEC] -= use_essence;
948             creature_ptr->magic_num1[TR_RES_ELEC] -= use_essence;
949             break;
950         case ESSENCE_SH_COLD:
951             if ((creature_ptr->magic_num1[TR_BRAND_COLD] < use_essence) || (creature_ptr->magic_num1[TR_RES_COLD] < use_essence)) {
952                 success = FALSE;
953                 break;
954             }
955             creature_ptr->magic_num1[TR_BRAND_COLD] -= use_essence;
956             creature_ptr->magic_num1[TR_RES_COLD] -= use_essence;
957             break;
958         case ESSENCE_RESISTANCE:
959         case ESSENCE_SUSTAIN:
960             if ((creature_ptr->magic_num1[TR_RES_ACID] < use_essence) || (creature_ptr->magic_num1[TR_RES_ELEC] < use_essence)
961                 || (creature_ptr->magic_num1[TR_RES_FIRE] < use_essence) || (creature_ptr->magic_num1[TR_RES_COLD] < use_essence)) {
962                 success = FALSE;
963                 break;
964             }
965             creature_ptr->magic_num1[TR_RES_ACID] -= use_essence;
966             creature_ptr->magic_num1[TR_RES_ELEC] -= use_essence;
967             creature_ptr->magic_num1[TR_RES_FIRE] -= use_essence;
968             creature_ptr->magic_num1[TR_RES_COLD] -= use_essence;
969             break;
970         }
971         if (!success) {
972             msg_print(_("エッセンスが足りない。", "You don't have enough essences."));
973             return;
974         }
975         if (es_ptr->add == ESSENCE_SUSTAIN) {
976             add_flag(o_ptr->art_flags, TR_IGNORE_ACID);
977             add_flag(o_ptr->art_flags, TR_IGNORE_ELEC);
978             add_flag(o_ptr->art_flags, TR_IGNORE_FIRE);
979             add_flag(o_ptr->art_flags, TR_IGNORE_COLD);
980         } else {
981             o_ptr->xtra3 = es_ptr->add + 1;
982         }
983     }
984
985     take_turn(creature_ptr, 100);
986     _(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));
987     creature_ptr->update |= (PU_COMBINE | PU_REORDER);
988     creature_ptr->window |= (PW_INVEN);
989 }
990
991 /*!
992  * @brief エッセンスを消去する
993  * @return なし
994  */
995 static void erase_essence(player_type *creature_ptr)
996 {
997     OBJECT_IDX item;
998     concptr q, s;
999     object_type *o_ptr;
1000     GAME_TEXT o_name[MAX_NLEN];
1001     BIT_FLAGS flgs[TR_FLAG_SIZE];
1002
1003     item_tester_hook = object_is_smith;
1004
1005     q = _("どのアイテムのエッセンスを消去しますか?", "Remove from which item? ");
1006     s = _("エッセンスを付加したアイテムがありません。", "You have nothing to remove essence.");
1007
1008     o_ptr = choose_object(creature_ptr, &item, q, s, (USE_INVEN | USE_FLOOR), 0);
1009     if (!o_ptr)
1010         return;
1011
1012     describe_flavor(creature_ptr, o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
1013     if (!get_check(format(_("よろしいですか? [%s]", "Are you sure? [%s]"), o_name)))
1014         return;
1015
1016     take_turn(creature_ptr, 100);
1017
1018     if (o_ptr->xtra3 == 1 + ESSENCE_SLAY_GLOVE) {
1019         o_ptr->to_h -= (o_ptr->xtra4 >> 8);
1020         o_ptr->to_d -= (o_ptr->xtra4 & 0x000f);
1021         o_ptr->xtra4 = 0;
1022         if (o_ptr->to_h < 0)
1023             o_ptr->to_h = 0;
1024         if (o_ptr->to_d < 0)
1025             o_ptr->to_d = 0;
1026     }
1027     o_ptr->xtra3 = 0;
1028     object_flags(creature_ptr, o_ptr, flgs);
1029     if (!(has_pval_flags(flgs)))
1030         o_ptr->pval = 0;
1031     msg_print(_("エッセンスを取り去った。", "You removed all essence you have added."));
1032     creature_ptr->update |= (PU_COMBINE | PU_REORDER);
1033     creature_ptr->window |= (PW_INVEN);
1034 }
1035
1036 /*!
1037  * @brief 鍛冶コマンドのメインルーチン
1038  * @param only_browse TRUEならばエッセンス一覧の表示のみを行う
1039  * @return なし
1040  */
1041 void do_cmd_kaji(player_type *creature_ptr, bool only_browse)
1042 {
1043     COMMAND_CODE mode = 0;
1044     char choice;
1045
1046     COMMAND_CODE menu_line = (use_menu ? 1 : 0);
1047
1048     if (!only_browse) {
1049         if (cmd_limit_confused(creature_ptr))
1050             return;
1051         if (cmd_limit_blind(creature_ptr))
1052             return;
1053         if (cmd_limit_image(creature_ptr))
1054             return;
1055     }
1056
1057     if (!(repeat_pull(&mode) && 1 <= mode && mode <= 5)) {
1058         if (only_browse)
1059             screen_save();
1060         do {
1061             if (!only_browse)
1062                 screen_save();
1063             if (use_menu) {
1064                 while (!mode) {
1065 #ifdef JP
1066                     prt(format(" %s エッセンス一覧", (menu_line == 1) ? "》" : "  "), 2, 14);
1067                     prt(format(" %s エッセンス抽出", (menu_line == 2) ? "》" : "  "), 3, 14);
1068                     prt(format(" %s エッセンス消去", (menu_line == 3) ? "》" : "  "), 4, 14);
1069                     prt(format(" %s エッセンス付加", (menu_line == 4) ? "》" : "  "), 5, 14);
1070                     prt(format(" %s 武器/防具強化", (menu_line == 5) ? "》" : "  "), 6, 14);
1071                     prt(format("どの種類の技術を%sますか?", only_browse ? "調べ" : "使い"), 0, 0);
1072 #else
1073                     prt(format(" %s List essences", (menu_line == 1) ? "> " : "  "), 2, 14);
1074                     prt(format(" %s Extract essence", (menu_line == 2) ? "> " : "  "), 3, 14);
1075                     prt(format(" %s Remove essence", (menu_line == 3) ? "> " : "  "), 4, 14);
1076                     prt(format(" %s Add essence", (menu_line == 4) ? "> " : "  "), 5, 14);
1077                     prt(format(" %s Enchant weapon/armor", (menu_line == 5) ? "> " : "  "), 6, 14);
1078                     prt(format("Choose command from menu."), 0, 0);
1079 #endif
1080                     choice = inkey();
1081                     switch (choice) {
1082                     case ESCAPE:
1083                     case 'z':
1084                     case 'Z':
1085                         screen_load();
1086                         return;
1087                     case '2':
1088                     case 'j':
1089                     case 'J':
1090                         menu_line++;
1091                         break;
1092                     case '8':
1093                     case 'k':
1094                     case 'K':
1095                         menu_line += 4;
1096                         break;
1097                     case '\r':
1098                     case '\n':
1099                     case 'x':
1100                     case 'X':
1101                         mode = menu_line;
1102                         break;
1103                     }
1104                     if (menu_line > 5)
1105                         menu_line -= 5;
1106                 }
1107             }
1108
1109             else {
1110                 while (!mode) {
1111                     prt(_("  a) エッセンス一覧", "  a) List essences"), 2, 14);
1112                     prt(_("  b) エッセンス抽出", "  b) Extract essence"), 3, 14);
1113                     prt(_("  c) エッセンス消去", "  c) Remove essence"), 4, 14);
1114                     prt(_("  d) エッセンス付加", "  d) Add essence"), 5, 14);
1115                     prt(_("  e) 武器/防具強化", "  e) Enchant weapon/armor"), 6, 14);
1116 #ifdef JP
1117                     if (!get_com(format("どの能力を%sますか:", only_browse ? "調べ" : "使い"), &choice, TRUE))
1118 #else
1119                     if (!get_com("Command :", &choice, TRUE))
1120 #endif
1121                     {
1122                         screen_load();
1123                         return;
1124                     }
1125                     switch (choice) {
1126                     case 'A':
1127                     case 'a':
1128                         mode = 1;
1129                         break;
1130                     case 'B':
1131                     case 'b':
1132                         mode = 2;
1133                         break;
1134                     case 'C':
1135                     case 'c':
1136                         mode = 3;
1137                         break;
1138                     case 'D':
1139                     case 'd':
1140                         mode = 4;
1141                         break;
1142                     case 'E':
1143                     case 'e':
1144                         mode = 5;
1145                         break;
1146                     }
1147                 }
1148             }
1149
1150             if (only_browse) {
1151                 char temp[62 * 5];
1152                 int line, j;
1153
1154                 /* Clear lines, position cursor  (really should use strlen here) */
1155                 term_erase(14, 21, 255);
1156                 term_erase(14, 20, 255);
1157                 term_erase(14, 19, 255);
1158                 term_erase(14, 18, 255);
1159                 term_erase(14, 17, 255);
1160                 term_erase(14, 16, 255);
1161
1162                 shape_buffer(kaji_tips[mode - 1], 62, temp, sizeof(temp));
1163                 for (j = 0, line = 17; temp[j]; j += (1 + strlen(&temp[j]))) {
1164                     prt(&temp[j], line, 15);
1165                     line++;
1166                 }
1167                 mode = 0;
1168             }
1169             if (!only_browse)
1170                 screen_load();
1171         } while (only_browse);
1172         repeat_push(mode);
1173     }
1174     switch (mode) {
1175     case 1:
1176         display_essence(creature_ptr);
1177         break;
1178     case 2:
1179         drain_essence(creature_ptr);
1180         break;
1181     case 3:
1182         erase_essence(creature_ptr);
1183         break;
1184     case 4:
1185         mode = choose_essence();
1186         if (mode == 0)
1187             break;
1188         add_essence(creature_ptr, mode);
1189         break;
1190     case 5:
1191         add_essence(creature_ptr, 10);
1192         break;
1193     }
1194 }