OSDN Git Service

4683a919127b5eb6932c6271ca1e59e5482b8120
[hengbandforosx/hengbandosx.git] / src / cmd-item / cmd-equipment.c
1 #include "cmd-item/cmd-equipment.h"
2 #include "action/weapon-shield.h"
3 #include "artifact/fixed-art-types.h"
4 #include "autopick/autopick.h"
5 #include "core/asking-player.h"
6 #include "core/player-redraw-types.h"
7 #include "core/player-update-types.h"
8 #include "core/window-redrawer.h"
9 #include "dungeon/quest.h" // todo 違和感、何故アイテムを装備するとクエストの成功判定が走るのか?.
10 #include "flavor/flavor-describer.h"
11 #include "flavor/object-flavor-types.h"
12 #include "floor/floor-object.h"
13 #include "game-option/birth-options.h"
14 #include "game-option/input-options.h"
15 #include "inventory/inventory-describer.h"
16 #include "inventory/inventory-object.h"
17 #include "inventory/inventory-slot-types.h"
18 #include "io/input-key-acceptor.h"
19 #include "io/input-key-requester.h"
20 #include "object-enchant/item-feeling.h"
21 #include "object-enchant/special-object-flags.h"
22 #include "object-enchant/trc-types.h"
23 #include "object-hook/hook-armor.h"
24 #include "object-hook/hook-checker.h"
25 #include "object-hook/hook-weapon.h"
26 #include "object/item-tester-hooker.h"
27 #include "object/item-use-flags.h"
28 #include "object/object-generator.h"
29 #include "object/object-info.h"
30 #include "object/object-mark-types.h"
31 #include "perception/object-perception.h"
32 #include "player-info/avatar.h"
33 #include "player/attack-defense-types.h"
34 #include "player/special-defense-types.h"
35 #include "racial/racial-android.h"
36 #include "spell-kind/spells-perception.h"
37 #include "status/action-setter.h"
38 #include "status/shape-changer.h"
39 #include "system/object-type-definition.h"
40 #include "term/screen-processor.h"
41 #include "util/int-char-converter.h"
42 #include "view/display-inventory.h"
43 #include "view/display-messages.h"
44
45 /*!
46  * @brief 装備一覧を表示するコマンドのメインルーチン / Display equipment
47  * @return なし
48  */
49 void do_cmd_equip(player_type *creature_ptr)
50 {
51     char out_val[160];
52     command_wrk = TRUE;
53     if (easy_floor)
54         command_wrk = USE_EQUIP;
55
56     screen_save();
57     (void)show_equipment(creature_ptr, 0, USE_FULL, 0);
58     WEIGHT weight = calc_inventory_weight(creature_ptr);
59     WEIGHT weight_lim = calc_weight_limit(creature_ptr);
60 #ifdef JP
61     sprintf(out_val, "装備: 合計 %3d.%1d kg (限界の%ld%%) コマンド: ", (int)lbtokg1(weight), (int)lbtokg2(weight), (long int)((weight * 100) / weight_lim));
62 #else
63     sprintf(out_val, "Equipment: carrying %d.%d pounds (%ld%% of capacity). Command: ", (int)(weight / 10), (int)(weight % 10),
64         (long int)((weight * 100) / weight_lim));
65 #endif
66
67     prt(out_val, 0, 0);
68     command_new = inkey();
69     screen_load();
70
71     if (command_new != ESCAPE) {
72         command_see = TRUE;
73         return;
74     }
75
76     TERM_LEN wid, hgt;
77     term_get_size(&wid, &hgt);
78     command_new = 0;
79     command_gap = wid - 30;
80 }
81
82
83 /*!
84  * @brief 装備するコマンドのメインルーチン / Wield or wear a single item from the pack or floor
85  * @param creature_ptr プレーヤーへの参照ポインタ
86  * @return なし
87  */
88 void do_cmd_wield(player_type *creature_ptr)
89 {
90     OBJECT_IDX item, slot;
91     object_type forge;
92     object_type *q_ptr;
93     object_type *o_ptr;
94     concptr act;
95     GAME_TEXT o_name[MAX_NLEN];
96     OBJECT_IDX need_switch_wielding = 0;
97     if (creature_ptr->special_defense & KATA_MUSOU)
98         set_action(creature_ptr, ACTION_NONE);
99
100     item_tester_hook = item_tester_hook_wear;
101     concptr q = _("どれを装備しますか? ", "Wear/Wield which item? ");
102     concptr s = _("装備可能なアイテムがない。", "You have nothing you can wear or wield.");
103     o_ptr = choose_object(creature_ptr, &item, q, s, (USE_INVEN | USE_FLOOR), 0);
104     if (!o_ptr)
105         return;
106
107     slot = wield_slot(creature_ptr, o_ptr);
108
109     switch (o_ptr->tval) {
110     case TV_CAPTURE:
111     case TV_SHIELD:
112     case TV_CARD:
113         if (has_melee_weapon(creature_ptr, INVEN_MAIN_HAND) && has_melee_weapon(creature_ptr, INVEN_SUB_HAND)) {
114             item_tester_hook = item_tester_hook_melee_weapon;
115             q = _("どちらの武器と取り替えますか?", "Replace which weapon? ");
116             s = _("おっと。", "Oops.");
117             if (!choose_object(creature_ptr, &slot, q, s, (USE_EQUIP | IGNORE_BOTHHAND_SLOT), 0))
118                 return;
119
120             if (slot == INVEN_MAIN_HAND)
121                 need_switch_wielding = INVEN_SUB_HAND;
122         } else if (has_melee_weapon(creature_ptr, INVEN_SUB_HAND))
123             slot = INVEN_MAIN_HAND;
124         else if (creature_ptr->inventory_list[INVEN_MAIN_HAND].k_idx && !object_is_melee_weapon(&creature_ptr->inventory_list[INVEN_MAIN_HAND])
125             && creature_ptr->inventory_list[INVEN_SUB_HAND].k_idx && !object_is_melee_weapon(&creature_ptr->inventory_list[INVEN_SUB_HAND])) {
126             item_tester_hook = item_tester_hook_mochikae;
127             q = _("どちらの手に装備しますか?", "Equip which hand? ");
128             s = _("おっと。", "Oops.");
129             if (!choose_object(creature_ptr, &slot, q, s, (USE_EQUIP), 0))
130                 return;
131         }
132
133         break;
134     case TV_DIGGING:
135     case TV_HAFTED:
136     case TV_POLEARM:
137     case TV_SWORD:
138         if (slot == INVEN_SUB_HAND) {
139             if (!get_check(_("二刀流で戦いますか?", "Dual wielding? ")))
140                 slot = INVEN_MAIN_HAND;
141         } else if (!creature_ptr->inventory_list[INVEN_MAIN_HAND].k_idx && has_melee_weapon(creature_ptr, INVEN_SUB_HAND)) {
142             if (!get_check(_("二刀流で戦いますか?", "Dual wielding? ")))
143                 slot = INVEN_SUB_HAND;
144         } else if (creature_ptr->inventory_list[INVEN_SUB_HAND].k_idx && creature_ptr->inventory_list[INVEN_MAIN_HAND].k_idx) {
145             item_tester_hook = item_tester_hook_mochikae;
146             q = _("どちらの手に装備しますか?", "Equip which hand? ");
147             s = _("おっと。", "Oops.");
148             if (!choose_object(creature_ptr, &slot, q, s, (USE_EQUIP), 0))
149                 return;
150
151             if ((slot == INVEN_SUB_HAND) && !has_melee_weapon(creature_ptr, INVEN_MAIN_HAND))
152                 need_switch_wielding = INVEN_MAIN_HAND;
153         }
154
155         break;
156     case TV_RING:
157         if (creature_ptr->inventory_list[INVEN_SUB_RING].k_idx && creature_ptr->inventory_list[INVEN_MAIN_RING].k_idx)
158             q = _("どちらの指輪と取り替えますか?", "Replace which ring? ");
159         else
160             q = _("どちらの手に装備しますか?", "Equip which hand? ");
161
162         s = _("おっと。", "Oops.");
163         creature_ptr->select_ring_slot = TRUE;
164         if (!choose_object(creature_ptr, &slot, q, s, (USE_EQUIP | IGNORE_BOTHHAND_SLOT), 0)) {
165             creature_ptr->select_ring_slot = FALSE;
166             return;
167         }
168
169         creature_ptr->select_ring_slot = FALSE;
170         break;
171     }
172
173     if (object_is_cursed(&creature_ptr->inventory_list[slot])) {
174         describe_flavor(creature_ptr, o_name, &creature_ptr->inventory_list[slot], OD_OMIT_PREFIX | OD_NAME_ONLY);
175 #ifdef JP
176         msg_format("%s%sは呪われているようだ。", describe_use(creature_ptr, slot), o_name);
177 #else
178         msg_format("The %s you are %s appears to be cursed.", o_name, describe_use(creature_ptr, slot));
179 #endif
180         return;
181     }
182
183     if (confirm_wear
184         && ((object_is_cursed(o_ptr) && object_is_known(o_ptr))
185             || ((o_ptr->ident & IDENT_SENSE) && (FEEL_BROKEN <= o_ptr->feeling) && (o_ptr->feeling <= FEEL_CURSED)))) {
186         char dummy[MAX_NLEN + 80];
187         describe_flavor(creature_ptr, o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
188         sprintf(dummy, _("本当に%s{呪われている}を使いますか?", "Really use the %s {cursed}? "), o_name);
189
190         if (!get_check(dummy))
191             return;
192     }
193
194     if ((o_ptr->name1 == ART_STONEMASK) && object_is_known(o_ptr) && (creature_ptr->prace != RACE_VAMPIRE) && (creature_ptr->prace != RACE_ANDROID)) {
195         char dummy[MAX_NLEN + 100];
196         describe_flavor(creature_ptr, o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
197         sprintf(dummy,
198             _("%sを装備すると吸血鬼になります。よろしいですか?", "%s will transform you into a vampire permanently when equipped. Do you become a vampire?"),
199             o_name);
200
201         if (!get_check(dummy))
202             return;
203     }
204
205     if (need_switch_wielding && !object_is_cursed(&creature_ptr->inventory_list[need_switch_wielding])) {
206         object_type *slot_o_ptr = &creature_ptr->inventory_list[slot];
207         object_type *switch_o_ptr = &creature_ptr->inventory_list[need_switch_wielding];
208         object_type object_tmp;
209         object_type *otmp_ptr = &object_tmp;
210         GAME_TEXT switch_name[MAX_NLEN];
211         describe_flavor(creature_ptr, switch_name, switch_o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
212         object_copy(otmp_ptr, switch_o_ptr);
213         object_copy(switch_o_ptr, slot_o_ptr);
214         object_copy(slot_o_ptr, otmp_ptr);
215         msg_format(_("%sを%sに構えなおした。", "You wield %s at %s hand."), switch_name,
216             (slot == INVEN_MAIN_HAND) ? (left_hander ? _("左手", "left") : _("右手", "right")) : (left_hander ? _("右手", "right") : _("左手", "left")));
217         slot = need_switch_wielding;
218     }
219
220     check_find_art_quest_completion(creature_ptr, o_ptr);
221     if (creature_ptr->pseikaku == PERSONALITY_MUNCHKIN) {
222         identify_item(creature_ptr, o_ptr);
223         autopick_alter_item(creature_ptr, item, FALSE);
224     }
225
226     take_turn(creature_ptr, 100);
227     q_ptr = &forge;
228     object_copy(q_ptr, o_ptr);
229     q_ptr->number = 1;
230     if (item >= 0) {
231         inven_item_increase(creature_ptr, item, -1);
232         inven_item_optimize(creature_ptr, item);
233     } else {
234         floor_item_increase(creature_ptr->current_floor_ptr, 0 - item, -1);
235         floor_item_optimize(creature_ptr, 0 - item);
236     }
237
238     o_ptr = &creature_ptr->inventory_list[slot];
239     if (o_ptr->k_idx)
240         (void)inven_takeoff(creature_ptr, slot, 255);
241
242     object_copy(o_ptr, q_ptr);
243     o_ptr->marked |= OM_TOUCHED;
244     creature_ptr->equip_cnt++;
245
246 #define STR_WIELD_HAND_RIGHT _("%s(%c)を右手に装備した。", "You are wielding %s (%c) in your right hand.")
247 #define STR_WIELD_HAND_LEFT _("%s(%c)を左手に装備した。", "You are wielding %s (%c) in your left hand.")
248 #define STR_WIELD_HANDS_TWO _("%s(%c)を両手で構えた。", "You are wielding %s (%c) with both hands.")
249
250     switch (slot) {
251     case INVEN_MAIN_HAND:
252         if (object_allow_two_hands_wielding(o_ptr) && (empty_hands(creature_ptr, FALSE) == EMPTY_HAND_SUB) && can_two_hands_wielding(creature_ptr))
253             act = STR_WIELD_HANDS_TWO;
254         else
255             act = (left_hander ? STR_WIELD_HAND_LEFT : STR_WIELD_HAND_RIGHT);
256
257         break;
258     case INVEN_SUB_HAND:
259         if (object_allow_two_hands_wielding(o_ptr) && (empty_hands(creature_ptr, FALSE) == EMPTY_HAND_MAIN) && can_two_hands_wielding(creature_ptr))
260             act = STR_WIELD_HANDS_TWO;
261         else
262             act = (left_hander ? STR_WIELD_HAND_RIGHT : STR_WIELD_HAND_LEFT);
263
264         break;
265     case INVEN_BOW:
266         act = _("%s(%c)を射撃用に装備した。", "You are shooting with %s (%c).");
267         break;
268     case INVEN_LITE:
269         act = _("%s(%c)を光源にした。", "Your light source is %s (%c).");
270         break;
271     default:
272         act = _("%s(%c)を装備した。", "You are wearing %s (%c).");
273         break;
274     }
275
276     describe_flavor(creature_ptr, o_name, o_ptr, 0);
277     msg_format(act, o_name, index_to_label(slot));
278     if (object_is_cursed(o_ptr)) {
279         msg_print(_("うわ! すさまじく冷たい!", "Oops! It feels deathly cold!"));
280         chg_virtue(creature_ptr, V_HARMONY, -1);
281         o_ptr->ident |= (IDENT_SENSE);
282     }
283
284     if ((o_ptr->name1 == ART_STONEMASK) && (creature_ptr->prace != RACE_VAMPIRE) && (creature_ptr->prace != RACE_ANDROID))
285         change_race(creature_ptr, RACE_VAMPIRE, "");
286
287     calc_android_exp(creature_ptr);
288     creature_ptr->update |= PU_BONUS | PU_TORCH | PU_MANA;
289     creature_ptr->redraw |= PR_EQUIPPY;
290     creature_ptr->window_flags |= PW_INVEN | PW_EQUIP | PW_PLAYER;
291 }
292
293 /*!
294  * @brief 装備を外すコマンドのメインルーチン / Take off an item
295  * @return なし
296  */
297 void do_cmd_takeoff(player_type *creature_ptr)
298 {
299     OBJECT_IDX item;
300     object_type *o_ptr;
301     if (creature_ptr->special_defense & KATA_MUSOU)
302         set_action(creature_ptr, ACTION_NONE);
303
304     concptr q = _("どれを装備からはずしますか? ", "Take off which item? ");
305     concptr s = _("はずせる装備がない。", "You are not wearing anything to take off.");
306     o_ptr = choose_object(creature_ptr, &item, q, s, (USE_EQUIP | IGNORE_BOTHHAND_SLOT), 0);
307     if (!o_ptr)
308         return;
309
310     if (object_is_cursed(o_ptr)) {
311         if ((o_ptr->curse_flags & TRC_PERMA_CURSE) || (creature_ptr->pclass != CLASS_BERSERKER)) {
312             msg_print(_("ふーむ、どうやら呪われているようだ。", "Hmmm, it seems to be cursed."));
313             return;
314         }
315
316         if (((o_ptr->curse_flags & TRC_HEAVY_CURSE) && one_in_(7)) || one_in_(4)) {
317             msg_print(_("呪われた装備を力づくで剥がした!", "You tore off a piece of cursed equipment by sheer strength!"));
318             o_ptr->ident |= (IDENT_SENSE);
319             o_ptr->curse_flags = 0L;
320             o_ptr->feeling = FEEL_NONE;
321             creature_ptr->update |= PU_BONUS;
322             creature_ptr->window_flags |= PW_EQUIP;
323             msg_print(_("呪いを打ち破った。", "You break the curse."));
324         } else {
325             msg_print(_("装備を外せなかった。", "You couldn't remove the equipment."));
326             take_turn(creature_ptr, 50);
327             return;
328         }
329     }
330
331     take_turn(creature_ptr, 50);
332     (void)inven_takeoff(creature_ptr, item, 255);
333     verify_equip_slot(creature_ptr, item);
334     calc_android_exp(creature_ptr);
335     creature_ptr->update |= PU_BONUS | PU_TORCH | PU_MANA;
336     creature_ptr->redraw |= PR_EQUIPPY;
337     creature_ptr->window_flags |= PW_INVEN | PW_EQUIP | PW_PLAYER;
338 }