OSDN Git Service

[Refactor] #37353 コメント整理 / Refactor comments.
[hengband/hengband.git] / src / cmd-item.c
1 /*!
2  *  @file cmd3.c
3  *  @brief プレイヤーのアイテムに関するコマンドの実装1 / Inventory commands
4  *  @date 2014/01/02
5  *  @author
6  * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke
7  *
8  * This software may be copied and distributed for educational, research,
9  * and not for profit purposes provided that this copyright and statement
10  * are included in all such copies.  Other copyrights may also apply.
11  */
12
13
14 #include "angband.h"
15 #include "selfinfo.h"
16 #include "cmd-activate.h"
17 #include "cmd-eat.h"
18 #include "cmd-quaff.h"
19 #include "cmd-read.h"
20 #include "cmd-usestaff.h"
21 #include "cmd-zaprod.h"
22 #include "cmd-zapwand.h"
23
24 #include "object-hook.h"
25
26
27 /*!
28  * @brief 持ち物一覧を表示するコマンドのメインルーチン / Display inventory
29  * @return なし 
30  */
31 void do_cmd_inven(void)
32 {
33         char out_val[160];
34
35
36         /* Note that we are in "inventory" mode */
37         command_wrk = FALSE;
38
39 #ifdef ALLOW_EASY_FLOOR
40
41         /* Note that we are in "inventory" mode */
42         if (easy_floor) command_wrk = (USE_INVEN);
43
44 #endif /* ALLOW_EASY_FLOOR */
45
46         /* Save screen */
47         screen_save();
48
49         /* Hack -- show empty slots */
50         item_tester_full = TRUE;
51
52         /* Display the inventory */
53         (void)show_inven(0);
54
55         /* Hack -- hide empty slots */
56         item_tester_full = FALSE;
57
58 #ifdef JP
59         sprintf(out_val, "持ち物: 合計 %3d.%1d kg (限界の%ld%%) コマンド: ",
60             (int)lbtokg1(p_ptr->total_weight) , (int)lbtokg2(p_ptr->total_weight) ,
61             (long int)((p_ptr->total_weight * 100) / weight_limit()));
62 #else
63         sprintf(out_val, "Inventory: carrying %d.%d pounds (%ld%% of capacity). Command: ",
64             (int)(p_ptr->total_weight / 10), (int)(p_ptr->total_weight % 10),
65             (p_ptr->total_weight * 100) / weight_limit());
66 #endif
67
68
69         /* Get a command */
70         prt(out_val, 0, 0);
71
72         /* Get a new command */
73         command_new = inkey();
74
75         /* Load screen */
76         screen_load();
77
78
79         /* Process "Escape" */
80         if (command_new == ESCAPE)
81         {
82                 int wid, hgt;
83
84                 /* Get size */
85                 Term_get_size(&wid, &hgt);
86
87                 /* Reset stuff */
88                 command_new = 0;
89                 command_gap = wid - 30;
90         }
91
92         /* Process normal keys */
93         else
94         {
95                 /* Hack -- Use "display" mode */
96                 command_see = TRUE;
97         }
98 }
99
100
101 /*!
102  * @brief 装備一覧を表示するコマンドのメインルーチン / Display equipment
103  * @return なし 
104  */
105 void do_cmd_equip(void)
106 {
107         char out_val[160];
108
109
110         /* Note that we are in "equipment" mode */
111         command_wrk = TRUE;
112
113 #ifdef ALLOW_EASY_FLOOR
114
115         /* Note that we are in "equipment" mode */
116         if (easy_floor) command_wrk = (USE_EQUIP);
117
118 #endif /* ALLOW_EASY_FLOOR  */
119
120         /* Save the screen */
121         screen_save();
122
123         /* Hack -- show empty slots */
124         item_tester_full = TRUE;
125
126         /* Display the equipment */
127         (void)show_equip(0);
128
129         /* Hack -- undo the hack above */
130         item_tester_full = FALSE;
131
132         /* Build a prompt */
133 #ifdef JP
134         sprintf(out_val, "装備: 合計 %3d.%1d kg (限界の%ld%%) コマンド: ",
135             (int)lbtokg1(p_ptr->total_weight) , (int)lbtokg2(p_ptr->total_weight) ,
136             (long int)((p_ptr->total_weight * 100) / weight_limit()));
137 #else
138         sprintf(out_val, "Equipment: carrying %d.%d pounds (%ld%% of capacity). Command: ",
139             (int)(p_ptr->total_weight / 10), (int)(p_ptr->total_weight % 10),
140             (long int)((p_ptr->total_weight * 100) / weight_limit()));
141 #endif
142
143
144         /* Get a command */
145         prt(out_val, 0, 0);
146
147         /* Get a new command */
148         command_new = inkey();
149
150         /* Restore the screen */
151         screen_load();
152
153
154         /* Process "Escape" */
155         if (command_new == ESCAPE)
156         {
157                 int wid, hgt;
158
159                 /* Get size */
160                 Term_get_size(&wid, &hgt);
161
162                 /* Reset stuff */
163                 command_new = 0;
164                 command_gap = wid - 30;
165         }
166
167         /* Process normal keys */
168         else
169         {
170                 /* Enter "display" mode */
171                 command_see = TRUE;
172         }
173 }
174
175
176
177
178 bool select_ring_slot = FALSE;
179
180 /*!
181  * @brief 装備するコマンドのメインルーチン / Wield or wear a single item from the pack or floor
182  * @return なし 
183  */
184 void do_cmd_wield(void)
185 {
186         OBJECT_IDX item, slot;
187
188         object_type forge;
189         object_type *q_ptr;
190
191         object_type *o_ptr;
192
193         cptr act;
194
195         char o_name[MAX_NLEN];
196
197         cptr q, s;
198
199         OBJECT_IDX need_switch_wielding = 0;
200
201         if (p_ptr->special_defense & KATA_MUSOU)
202         {
203                 set_action(ACTION_NONE);
204         }
205
206         /* Restrict the choices */
207         item_tester_hook = item_tester_hook_wear;
208
209         /* Get an item */
210         q = _("どれを装備しますか? ", "Wear/Wield which item? ");
211         s = _("装備可能なアイテムがない。", "You have nothing you can wear or wield.");
212
213         if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return;
214
215         /* Get the item (in the pack) */
216         if (item >= 0)
217         {
218                 o_ptr = &inventory[item];
219         }
220
221         /* Get the item (on the floor) */
222         else
223         {
224                 o_ptr = &o_list[0 - item];
225         }
226
227
228         /* Check the slot */
229         slot = wield_slot(o_ptr);
230
231         switch (o_ptr->tval)
232         {
233         /* Shields and some misc. items */
234         case TV_CAPTURE:
235         case TV_SHIELD:
236         case TV_CARD:
237                 /* Dual wielding */
238                 if (buki_motteruka(INVEN_RARM) && buki_motteruka(INVEN_LARM))
239                 {
240                         /* Restrict the choices */
241                         item_tester_hook = item_tester_hook_melee_weapon;
242                         item_tester_no_ryoute = TRUE;
243
244                         /* Choose a weapon from the equipment only */
245                         q = _("どちらの武器と取り替えますか?", "Replace which weapon? ");
246                         s = _("おっと。", "Oops.");
247                         if (!get_item(&slot, q, s, (USE_EQUIP))) return;
248                         if (slot == INVEN_RARM) need_switch_wielding = INVEN_LARM;
249                 }
250
251                 else if (buki_motteruka(INVEN_LARM)) slot = INVEN_RARM;
252
253                 /* Both arms are already used by non-weapon */
254                 else if (inventory[INVEN_RARM].k_idx && !object_is_melee_weapon(&inventory[INVEN_RARM]) &&
255                          inventory[INVEN_LARM].k_idx && !object_is_melee_weapon(&inventory[INVEN_LARM]))
256                 {
257                         /* Restrict the choices */
258                         item_tester_hook = item_tester_hook_mochikae;
259
260                         /* Choose a hand */
261                         q = _("どちらの手に装備しますか?", "Equip which hand? ");
262                         s = _("おっと。", "Oops.");
263                         if (!get_item(&slot, q, s, (USE_EQUIP))) return;
264                 }
265                 break;
266
267         /* Melee weapons */
268         case TV_DIGGING:
269         case TV_HAFTED:
270         case TV_POLEARM:
271         case TV_SWORD:
272                 /* Asking for dual wielding */
273                 if (slot == INVEN_LARM)
274                 {
275                         if (!get_check(_("二刀流で戦いますか?", "Dual wielding? "))) slot = INVEN_RARM;
276                 }
277
278                 else if (!inventory[INVEN_RARM].k_idx && buki_motteruka(INVEN_LARM))
279                 {
280                         if (!get_check(_("二刀流で戦いますか?", "Dual wielding? "))) slot = INVEN_LARM;
281                 }
282
283                 /* Both arms are already used */
284                 else if (inventory[INVEN_LARM].k_idx && inventory[INVEN_RARM].k_idx)
285                 {
286                         /* Restrict the choices */
287                         item_tester_hook = item_tester_hook_mochikae;
288
289                         /* Choose a hand */
290                         q = _("どちらの手に装備しますか?", "Equip which hand? ");
291                         s = _("おっと。", "Oops.");
292                         
293                         if (!get_item(&slot, q, s, (USE_EQUIP))) return;
294                         if ((slot == INVEN_LARM) && !buki_motteruka(INVEN_RARM))
295                                 need_switch_wielding = INVEN_RARM;
296                 }
297                 break;
298
299         /* Rings */
300         case TV_RING:
301                 /* Choose a ring slot */
302                 if (inventory[INVEN_LEFT].k_idx && inventory[INVEN_RIGHT].k_idx)
303                 {
304                         q = _("どちらの指輪と取り替えますか?", "Replace which ring? ");
305                 }
306                 else
307                 {
308                         q = _("どちらの手に装備しますか?", "Equip which hand? ");
309                 }
310                 s = _("おっと。", "Oops.");
311
312                 /* Restrict the choices */
313                 select_ring_slot = TRUE;
314                 item_tester_no_ryoute = TRUE;
315
316                 if (!get_item(&slot, q, s, (USE_EQUIP)))
317                 {
318                         select_ring_slot = FALSE;
319                         return;
320                 }
321                 select_ring_slot = FALSE;
322                 break;
323         }
324
325         /* Prevent wielding into a cursed slot */
326         if (object_is_cursed(&inventory[slot]))
327         {
328                 /* Describe it */
329                 object_desc(o_name, &inventory[slot], (OD_OMIT_PREFIX | OD_NAME_ONLY));
330
331 #ifdef JP
332                 msg_format("%s%sは呪われているようだ。",
333                            describe_use(slot) , o_name );
334 #else
335                 msg_format("The %s you are %s appears to be cursed.",
336                            o_name, describe_use(slot));
337 #endif
338
339                 /* Cancel the command */
340                 return;
341         }
342
343         if (confirm_wear &&
344                 ((object_is_cursed(o_ptr) && object_is_known(o_ptr)) ||
345                 ((o_ptr->ident & IDENT_SENSE) &&
346                         (FEEL_BROKEN <= o_ptr->feeling) && (o_ptr->feeling <= FEEL_CURSED))))
347         {
348                 char dummy[MAX_NLEN+80];
349
350                 /* Describe it */
351                 object_desc(o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
352                 sprintf(dummy, _("本当に%s{呪われている}を使いますか?", "Really use the %s {cursed}? "), o_name);
353
354                 if (!get_check(dummy)) return;
355         }
356
357         if ((o_ptr->name1 == ART_STONEMASK) && object_is_known(o_ptr) && (p_ptr->prace != RACE_VAMPIRE) && (p_ptr->prace != RACE_ANDROID))
358         {
359                 char dummy[MAX_NLEN+80];
360
361                 /* Describe it */
362                 object_desc(o_name, o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
363
364 #ifdef JP
365                 sprintf(dummy, "%sを装備すると吸血鬼になります。よろしいですか?", o_name);
366 #else
367                 msg_format("%s will transforms you into a vampire permanently when equiped.", o_name);
368                 sprintf(dummy, "Do you become a vampire?");
369 #endif
370
371                 if (!get_check(dummy)) return;
372         }
373
374         if (need_switch_wielding && !object_is_cursed(&inventory[need_switch_wielding]))
375         {
376                 object_type *slot_o_ptr = &inventory[slot];
377                 object_type *switch_o_ptr = &inventory[need_switch_wielding];
378                 object_type object_tmp;
379                 object_type *otmp_ptr = &object_tmp;
380                 char switch_name[MAX_NLEN];
381
382                 object_desc(switch_name, switch_o_ptr, (OD_OMIT_PREFIX | OD_NAME_ONLY));
383
384                 object_copy(otmp_ptr, switch_o_ptr);
385                 object_copy(switch_o_ptr, slot_o_ptr);
386                 object_copy(slot_o_ptr, otmp_ptr);
387                 
388                 msg_format(_("%sを%sに構えなおした。", "You wield %s at %s hand."), switch_name, 
389                                         (slot == INVEN_RARM) ? (left_hander ? _("左手", "left") : _("右手", "right")) : 
390                                                                                    (left_hander ? _("右手", "right") : _("左手", "left")));
391                 slot = need_switch_wielding;
392         }
393
394         check_find_art_quest_completion(o_ptr);
395
396         if (p_ptr->pseikaku == SEIKAKU_MUNCHKIN)
397         {
398                 identify_item(o_ptr);
399
400                 /* Auto-inscription */
401                 autopick_alter_item(item, FALSE);
402         }
403
404         p_ptr->energy_use = 100;
405
406         /* Get local object */
407         q_ptr = &forge;
408
409         /* Obtain local object */
410         object_copy(q_ptr, o_ptr);
411
412         /* Modify quantity */
413         q_ptr->number = 1;
414
415         /* Decrease the item (from the pack) */
416         if (item >= 0)
417         {
418                 inven_item_increase(item, -1);
419                 inven_item_optimize(item);
420         }
421
422         /* Decrease the item (from the floor) */
423         else
424         {
425                 floor_item_increase(0 - item, -1);
426                 floor_item_optimize(0 - item);
427         }
428
429         /* Access the wield slot */
430         o_ptr = &inventory[slot];
431
432         /* Take off existing item */
433         if (o_ptr->k_idx)
434         {
435                 /* Take off existing item */
436                 (void)inven_takeoff(slot, 255);
437         }
438
439         /* Wear the new stuff */
440         object_copy(o_ptr, q_ptr);
441
442         /* Player touches it */
443         o_ptr->marked |= OM_TOUCHED;
444
445         /* Increase the weight */
446         p_ptr->total_weight += q_ptr->weight;
447
448         /* Increment the equip counter by hand */
449         equip_cnt++;
450
451 #ifdef JP
452 #define STR_WIELD_RARM "%s(%c)を右手に装備した。"
453 #define STR_WIELD_LARM "%s(%c)を左手に装備した。"
454 #define STR_WIELD_ARMS "%s(%c)を両手で構えた。"
455 #else
456 #define STR_WIELD_RARM "You are wielding %s (%c) in your right hand."
457 #define STR_WIELD_LARM "You are wielding %s (%c) in your left hand."
458 #define STR_WIELD_ARMS "You are wielding %s (%c) with both hands."
459 #endif
460
461         /* Where is the item now */
462         switch (slot)
463         {
464         case INVEN_RARM:
465                 if (object_allow_two_hands_wielding(o_ptr) && (empty_hands(FALSE) == EMPTY_HAND_LARM) && CAN_TWO_HANDS_WIELDING())
466                         act = STR_WIELD_ARMS;
467                 else
468                         act = (left_hander ? STR_WIELD_LARM : STR_WIELD_RARM);
469                 break;
470
471         case INVEN_LARM:
472                 if (object_allow_two_hands_wielding(o_ptr) && (empty_hands(FALSE) == EMPTY_HAND_RARM) && CAN_TWO_HANDS_WIELDING())
473                         act = STR_WIELD_ARMS;
474                 else
475                         act = (left_hander ? STR_WIELD_RARM : STR_WIELD_LARM);
476                 break;
477
478         case INVEN_BOW:
479                 act = _("%s(%c)を射撃用に装備した。", "You are shooting with %s (%c).");
480                 break;
481
482         case INVEN_LITE:
483                 act = _("%s(%c)を光源にした。", "Your light source is %s (%c).");
484                 break;
485
486         default:
487                 act = _("%s(%c)を装備した。", "You are wearing %s (%c).");
488                 break;
489         }
490
491         /* Describe the result */
492         object_desc(o_name, o_ptr, 0);
493
494         msg_format(act, o_name, index_to_label(slot));
495
496
497         /* Cursed! */
498         if (object_is_cursed(o_ptr))
499         {
500                 /* Warn the player */
501                 msg_print(_("うわ! すさまじく冷たい!", "Oops! It feels deathly cold!"));
502                 chg_virtue(V_HARMONY, -1);
503
504                 /* Note the curse */
505                 o_ptr->ident |= (IDENT_SENSE);
506         }
507
508         /* The Stone Mask make the player turn into a vampire! */
509         if ((o_ptr->name1 == ART_STONEMASK) && (p_ptr->prace != RACE_VAMPIRE) && (p_ptr->prace != RACE_ANDROID))
510         {
511                 /* Turn into a vampire */
512                 change_race(RACE_VAMPIRE, "");
513         }
514
515         /* Recalculate bonuses */
516         p_ptr->update |= (PU_BONUS);
517
518         /* Recalculate torch */
519         p_ptr->update |= (PU_TORCH);
520
521         /* Recalculate mana */
522         p_ptr->update |= (PU_MANA);
523
524         p_ptr->redraw |= (PR_EQUIPPY);
525
526         p_ptr->window |= (PW_INVEN | PW_EQUIP | PW_PLAYER);
527
528         calc_android_exp();
529 }
530
531 /*!
532  * @brief 持ち替え処理
533  * @param item 持ち替えを行いたい装備部位ID
534  * @return なし
535  */
536 void kamaenaoshi(INVENTORY_IDX item)
537 {
538         object_type *o_ptr, *new_o_ptr;
539         char o_name[MAX_NLEN];
540
541         if (item == INVEN_RARM)
542         {
543                 if (buki_motteruka(INVEN_LARM))
544                 {
545                         o_ptr = &inventory[INVEN_LARM];
546                         object_desc(o_name, o_ptr, 0);
547
548                         if (!object_is_cursed(o_ptr))
549                         {
550                                 new_o_ptr = &inventory[INVEN_RARM];
551                                 object_copy(new_o_ptr, o_ptr);
552                                 p_ptr->total_weight += o_ptr->weight;
553                                 inven_item_increase(INVEN_LARM, -((int)o_ptr->number));
554                                 inven_item_optimize(INVEN_LARM);
555                                 if (object_allow_two_hands_wielding(o_ptr) && CAN_TWO_HANDS_WIELDING())
556                                         msg_format(_("%sを両手で構えた。", "You are wielding %s with both hands."), o_name);
557                                  else
558                                 msg_format(_("%sを%sで構えた。", "You are wielding %s in your %s hand."), o_name, 
559                                                         (left_hander ? _("左手", "left") : _("右手", "right")));
560                         }
561                         else
562                         {
563                                 if (object_allow_two_hands_wielding(o_ptr) && CAN_TWO_HANDS_WIELDING())
564                                         msg_format(_("%sを両手で構えた。", "You are wielding %s with both hands."), o_name);
565                         }
566                 }
567         }
568         else if (item == INVEN_LARM)
569         {
570                 o_ptr = &inventory[INVEN_RARM];
571                 if (o_ptr->k_idx) object_desc(o_name, o_ptr, 0);
572
573                 if (buki_motteruka(INVEN_RARM))
574                 {
575                         if (object_allow_two_hands_wielding(o_ptr) && CAN_TWO_HANDS_WIELDING())
576                                 msg_format(_("%sを両手で構えた。", "You are wielding %s with both hands."), o_name);
577                 }
578                 else if (!(empty_hands(FALSE) & EMPTY_HAND_RARM) && !object_is_cursed(o_ptr))
579                 {
580                         new_o_ptr = &inventory[INVEN_LARM];
581                         object_copy(new_o_ptr, o_ptr);
582                         p_ptr->total_weight += o_ptr->weight;
583                         inven_item_increase(INVEN_RARM, -((int)o_ptr->number));
584                         inven_item_optimize(INVEN_RARM);
585                         msg_format(_("%sを持ち替えた。", "You switched hand of %s."), o_name);
586                 }
587         }
588 }
589
590
591 /*!
592  * @brief 装備を外すコマンドのメインルーチン / Take off an item
593  * @return なし
594  */
595 void do_cmd_takeoff(void)
596 {
597         OBJECT_IDX item;
598         object_type *o_ptr;
599         cptr q, s;
600
601         if (p_ptr->special_defense & KATA_MUSOU)
602         {
603                 set_action(ACTION_NONE);
604         }
605
606         item_tester_no_ryoute = TRUE;
607
608         /* Get an item */
609         q = _("どれを装備からはずしますか? ", "Take off which item? ");
610         s = _("はずせる装備がない。", "You are not wearing anything to take off.");
611
612         if (!get_item(&item, q, s, (USE_EQUIP))) return;
613
614         /* Get the item (in the pack) */
615         if (item >= 0)
616         {
617                 o_ptr = &inventory[item];
618         }
619
620         /* Get the item (on the floor) */
621         else
622         {
623                 o_ptr = &o_list[0 - item];
624         }
625
626
627         /* Item is cursed */
628         if (object_is_cursed(o_ptr))
629         {
630                 if ((o_ptr->curse_flags & TRC_PERMA_CURSE) || (p_ptr->pclass != CLASS_BERSERKER))
631                 {
632                         /* Oops */
633                         msg_print(_("ふーむ、どうやら呪われているようだ。", "Hmmm, it seems to be cursed."));
634
635                         /* Nope */
636                         return;
637                 }
638
639                 if (((o_ptr->curse_flags & TRC_HEAVY_CURSE) && one_in_(7)) || one_in_(4))
640                 {
641                         msg_print(_("呪われた装備を力づくで剥がした!", "You teared a cursed equipment off by sheer strength!"));
642
643                         /* Hack -- Assume felt */
644                         o_ptr->ident |= (IDENT_SENSE);
645
646                         o_ptr->curse_flags = 0L;
647
648                         /* Take note */
649                         o_ptr->feeling = FEEL_NONE;
650
651                         /* Recalculate the bonuses */
652                         p_ptr->update |= (PU_BONUS);
653
654                         p_ptr->window |= (PW_EQUIP);
655
656                         msg_print(_("呪いを打ち破った。", "You break the curse."));
657                 }
658                 else
659                 {
660                         msg_print(_("装備を外せなかった。", "You couldn't remove the equipment."));
661                         p_ptr->energy_use = 50;
662                         return;
663                 }
664         }
665
666         /* Take a partial turn */
667         p_ptr->energy_use = 50;
668
669         /* Take off the item */
670         (void)inven_takeoff(item, 255);
671         kamaenaoshi(item);
672         calc_android_exp();
673         p_ptr->redraw |= (PR_EQUIPPY);
674 }
675
676
677 /*!
678  * @brief アイテムを落とすコマンドのメインルーチン / Drop an item
679  * @return なし
680  */
681 void do_cmd_drop(void)
682 {
683         OBJECT_IDX item;
684         int amt = 1;
685
686         object_type *o_ptr;
687
688         cptr q, s;
689
690         if (p_ptr->special_defense & KATA_MUSOU)
691         {
692                 set_action(ACTION_NONE);
693         }
694
695         item_tester_no_ryoute = TRUE;
696         /* Get an item */
697         q = _("どのアイテムを落としますか? ", "Drop which item? ");
698         s = _("落とせるアイテムを持っていない。", "You have nothing to drop.");
699
700         if (!get_item(&item, q, s, (USE_EQUIP | USE_INVEN))) return;
701
702         /* Get the item (in the pack) */
703         if (item >= 0)
704         {
705                 o_ptr = &inventory[item];
706         }
707
708         /* Get the item (on the floor) */
709         else
710         {
711                 o_ptr = &o_list[0 - item];
712         }
713
714
715         /* Hack -- Cannot remove cursed items */
716         if ((item >= INVEN_RARM) && object_is_cursed(o_ptr))
717         {
718                 /* Oops */
719                 msg_print(_("ふーむ、どうやら呪われているようだ。", "Hmmm, it seems to be cursed."));
720                 /* Nope */
721                 return;
722         }
723
724
725         /* See how many items */
726         if (o_ptr->number > 1)
727         {
728                 /* Get a quantity */
729                 amt = get_quantity(NULL, o_ptr->number);
730
731                 /* Allow user abort */
732                 if (amt <= 0) return;
733         }
734
735
736         /* Take a partial turn */
737         p_ptr->energy_use = 50;
738
739         /* Drop (some of) the item */
740         inven_drop(item, amt);
741
742         if (item >= INVEN_RARM)
743         {
744                 kamaenaoshi(item);
745                 calc_android_exp();
746         }
747
748         p_ptr->redraw |= (PR_EQUIPPY);
749 }
750
751 /*!
752  * @brief オブジェクトが高位の魔法書かどうかを判定する
753  * @param o_ptr 判定したいオブジェクトの構造体参照ポインタ
754  * @return オブジェクトが高位の魔法書ならばTRUEを返す
755  */
756 static bool high_level_book(object_type *o_ptr)
757 {
758         if ((o_ptr->tval == TV_LIFE_BOOK) ||
759             (o_ptr->tval == TV_SORCERY_BOOK) ||
760             (o_ptr->tval == TV_NATURE_BOOK) ||
761             (o_ptr->tval == TV_CHAOS_BOOK) ||
762             (o_ptr->tval == TV_DEATH_BOOK) ||
763             (o_ptr->tval == TV_TRUMP_BOOK) ||
764             (o_ptr->tval == TV_CRAFT_BOOK) ||
765             (o_ptr->tval == TV_DAEMON_BOOK) ||
766             (o_ptr->tval == TV_CRUSADE_BOOK) ||
767             (o_ptr->tval == TV_MUSIC_BOOK) ||
768                 (o_ptr->tval == TV_HEX_BOOK))
769         {
770                 if (o_ptr->sval > 1)
771                         return TRUE;
772                 else
773                         return FALSE;
774         }
775
776         return FALSE;
777 }
778
779
780 /*!
781  * @brief アイテムを破壊するコマンドのメインルーチン / Destroy an item
782  * @return なし
783  */
784 void do_cmd_destroy(void)
785 {
786         OBJECT_IDX item;
787         QUANTITY amt = 1;
788         QUANTITY old_number;
789
790         bool force = FALSE;
791
792         object_type *o_ptr;
793         object_type forge;
794         object_type *q_ptr = &forge;
795
796         char o_name[MAX_NLEN];
797         char out_val[MAX_NLEN+40];
798
799         cptr q, s;
800
801         if (p_ptr->special_defense & KATA_MUSOU)
802         {
803                 set_action(ACTION_NONE);
804         }
805
806         /* Hack -- force destruction */
807         if (command_arg > 0) force = TRUE;
808
809         /* Get an item */
810         q = _("どのアイテムを壊しますか? ", "Destroy which item? ");
811         s = _("壊せるアイテムを持っていない。", "You have nothing to destroy.");
812
813         if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return;
814
815         /* Get the item (in the pack) */
816         if (item >= 0)
817         {
818                 o_ptr = &inventory[item];
819         }
820
821         /* Get the item (on the floor) */
822         else
823         {
824                 o_ptr = &o_list[0 - item];
825         }
826
827         /* Verify unless quantity given beforehand */
828         if (!force && (confirm_destroy || (object_value(o_ptr) > 0)))
829         {
830                 object_desc(o_name, o_ptr, OD_OMIT_PREFIX);
831
832                 /* Make a verification */
833                 sprintf(out_val, _("本当に%sを壊しますか? [y/n/Auto]", "Really destroy %s? [y/n/Auto]"), o_name);
834                 msg_print(NULL);
835
836                 /* HACK : Add the line to message buffer */
837                 message_add(out_val);
838                 p_ptr->window |= (PW_MESSAGE);
839                 window_stuff();
840
841                 /* Get an acceptable answer */
842                 while (TRUE)
843                 {
844                         char i;
845
846                         /* Prompt */
847                         prt(out_val, 0, 0);
848
849                         i = inkey();
850
851                         /* Erase the prompt */
852                         prt("", 0, 0);
853
854
855                         if (i == 'y' || i == 'Y')
856                         {
857                                 break;
858                         }
859                         if (i == ESCAPE || i == 'n' || i == 'N')
860                         {
861                                 /* Cancel */
862                                 return;
863                         }
864                         if (i == 'A')
865                         {
866                                 /* Add an auto-destroy preference line */
867                                 if (autopick_autoregister(o_ptr))
868                                 {
869                                         /* Auto-destroy it */
870                                         autopick_alter_item(item, TRUE);
871                                 }
872
873                                 /* The object is already destroyed. */
874                                 return;
875                         }
876                 } /* while (TRUE) */
877         }
878
879         /* See how many items */
880         if (o_ptr->number > 1)
881         {
882                 /* Get a quantity */
883                 amt = get_quantity(NULL, o_ptr->number);
884
885                 /* Allow user abort */
886                 if (amt <= 0) return;
887         }
888
889
890         /* Describe the object */
891         old_number = o_ptr->number;
892         o_ptr->number = amt;
893         object_desc(o_name, o_ptr, 0);
894         o_ptr->number = old_number;
895
896         p_ptr->energy_use = 100;
897
898         /* Artifacts cannot be destroyed */
899         if (!can_player_destroy_object(o_ptr))
900         {
901                 p_ptr->energy_use = 0;
902
903                 msg_format(_("%sは破壊不可能だ。", "You cannot destroy %s."), o_name);
904                 return;
905         }
906
907         object_copy(q_ptr, o_ptr);
908
909         msg_format(_("%sを壊した。", "You destroy %s."), o_name);
910         sound(SOUND_DESTITEM);
911
912         /* Reduce the charges of rods/wands */
913         reduce_charges(o_ptr, amt);
914
915         /* Eliminate the item (from the pack) */
916         if (item >= 0)
917         {
918                 inven_item_increase(item, -amt);
919                 inven_item_describe(item);
920                 inven_item_optimize(item);
921         }
922
923         /* Eliminate the item (from the floor) */
924         else
925         {
926                 floor_item_increase(0 - item, -amt);
927                 floor_item_describe(0 - item);
928                 floor_item_optimize(0 - item);
929         }
930
931         if (high_level_book(q_ptr))
932         {
933                 bool gain_expr = FALSE;
934
935                 if (p_ptr->prace == RACE_ANDROID)
936                 {
937                 }
938                 else if ((p_ptr->pclass == CLASS_WARRIOR) || (p_ptr->pclass == CLASS_BERSERKER))
939                 {
940                         gain_expr = TRUE;
941                 }
942                 else if (p_ptr->pclass == CLASS_PALADIN)
943                 {
944                         if (is_good_realm(p_ptr->realm1))
945                         {
946                                 if (!is_good_realm(tval2realm(q_ptr->tval))) gain_expr = TRUE;
947                         }
948                         else
949                         {
950                                 if (is_good_realm(tval2realm(q_ptr->tval))) gain_expr = TRUE;
951                         }
952                 }
953
954                 if (gain_expr && (p_ptr->exp < PY_MAX_EXP))
955                 {
956                         s32b tester_exp = p_ptr->max_exp / 20;
957                         if (tester_exp > 10000) tester_exp = 10000;
958                         if (q_ptr->sval < 3) tester_exp /= 4;
959                         if (tester_exp<1) tester_exp = 1;
960
961                         msg_print(_("更に経験を積んだような気がする。", "You feel more experienced."));
962                         gain_exp(tester_exp * amt);
963                 }
964                 if (high_level_book(q_ptr) && q_ptr->tval == TV_LIFE_BOOK)
965                 {
966                         chg_virtue(V_UNLIFE, 1);
967                         chg_virtue(V_VITALITY, -1);
968                 }
969                 else if (high_level_book(q_ptr) && q_ptr->tval == TV_DEATH_BOOK)
970                 {
971                         chg_virtue(V_UNLIFE, -1);
972                         chg_virtue(V_VITALITY, 1);
973                 }
974         
975                 if (q_ptr->to_a || q_ptr->to_h || q_ptr->to_d)
976                         chg_virtue(V_ENCHANT, -1);
977         
978                 if (object_value_real(q_ptr) > 30000)
979                         chg_virtue(V_SACRIFICE, 2);
980         
981                 else if (object_value_real(q_ptr) > 10000)
982                         chg_virtue(V_SACRIFICE, 1);
983         }
984
985         if (q_ptr->to_a != 0 || q_ptr->to_d != 0 || q_ptr->to_h != 0)
986                 chg_virtue(V_HARMONY, 1);
987
988         if (item >= INVEN_RARM) calc_android_exp();
989 }
990
991
992 /*!
993  * @brief アイテムを調査するコマンドのメインルーチン / Observe an item which has been *identify*-ed
994  * @return なし
995  */
996 void do_cmd_observe(void)
997 {
998         OBJECT_IDX item;
999         object_type             *o_ptr;
1000         char            o_name[MAX_NLEN];
1001
1002         cptr q, s;
1003
1004         item_tester_no_ryoute = TRUE;
1005
1006         /* Get an item */
1007         q = _("どのアイテムを調べますか? ", "Examine which item? ");
1008         s = _("調べられるアイテムがない。", "You have nothing to examine.");
1009
1010         if (!get_item(&item, q, s, (USE_EQUIP | USE_INVEN | USE_FLOOR))) return;
1011
1012         /* Get the item (in the pack) */
1013         if (item >= 0)
1014         {
1015                 o_ptr = &inventory[item];
1016         }
1017
1018         /* Get the item (on the floor) */
1019         else
1020         {
1021                 o_ptr = &o_list[0 - item];
1022         }
1023
1024
1025         /* Require full knowledge */
1026         if (!(o_ptr->ident & IDENT_MENTAL))
1027         {
1028                 msg_print(_("このアイテムについて特に知っていることはない。", "You have no special knowledge about that item."));
1029                 return;
1030         }
1031
1032
1033         /* Description */
1034         object_desc(o_name, o_ptr, 0);
1035
1036         /* Describe */
1037         msg_format(_("%sを調べている...", "Examining %s..."), o_name);
1038         /* Describe it fully */
1039         if (!screen_object(o_ptr, SCROBJ_FORCE_DETAIL)) msg_print(_("特に変わったところはないようだ。", "You see nothing special."));
1040 }
1041
1042
1043
1044 /*!
1045  * @brief アイテムの銘を消すコマンドのメインルーチン
1046  * Remove the inscription from an object XXX Mention item (when done)?
1047  * @return なし
1048  */
1049 void do_cmd_uninscribe(void)
1050 {
1051         OBJECT_IDX item;
1052         object_type *o_ptr;
1053         cptr q, s;
1054
1055         item_tester_no_ryoute = TRUE;
1056         /* Get an item */
1057         q = _("どのアイテムの銘を消しますか? ", "Un-inscribe which item? ");
1058         s = _("銘を消せるアイテムがない。", "You have nothing to un-inscribe.");
1059
1060         if (!get_item(&item, q, s, (USE_EQUIP | USE_INVEN | USE_FLOOR))) return;
1061
1062         /* Get the item (in the pack) */
1063         if (item >= 0)
1064         {
1065                 o_ptr = &inventory[item];
1066         }
1067
1068         /* Get the item (on the floor) */
1069         else
1070         {
1071                 o_ptr = &o_list[0 - item];
1072         }
1073
1074         /* Nothing to remove */
1075         if (!o_ptr->inscription)
1076         {
1077                 msg_print(_("このアイテムには消すべき銘がない。", "That item had no inscription to remove."));
1078                 return;
1079         }
1080
1081         msg_print(_("銘を消した。", "Inscription removed."));
1082
1083         /* Remove the incription */
1084         o_ptr->inscription = 0;
1085
1086         /* Combine the pack */
1087         p_ptr->notice |= (PN_COMBINE);
1088
1089         p_ptr->window |= (PW_INVEN | PW_EQUIP);
1090
1091         /* .や$の関係で, 再計算が必要なはず -- henkma */
1092         p_ptr->update |= (PU_BONUS);
1093
1094 }
1095
1096
1097 /*!
1098  * @brief アイテムの銘を刻むコマンドのメインルーチン
1099  * Inscribe an object with a comment
1100  * @return なし
1101  */
1102 void do_cmd_inscribe(void)
1103 {
1104         OBJECT_IDX item;
1105         object_type             *o_ptr;
1106         char            o_name[MAX_NLEN];
1107         char            out_val[80];
1108         cptr q, s;
1109
1110         item_tester_no_ryoute = TRUE;
1111         /* Get an item */
1112         q = _("どのアイテムに銘を刻みますか? ", "Inscribe which item? ");
1113         s = _("銘を刻めるアイテムがない。", "You have nothing to inscribe.");
1114
1115         if (!get_item(&item, q, s, (USE_EQUIP | USE_INVEN | USE_FLOOR))) return;
1116
1117         /* Get the item (in the pack) */
1118         if (item >= 0)
1119         {
1120                 o_ptr = &inventory[item];
1121         }
1122
1123         /* Get the item (on the floor) */
1124         else
1125         {
1126                 o_ptr = &o_list[0 - item];
1127         }
1128
1129         /* Describe the activity */
1130         object_desc(o_name, o_ptr, OD_OMIT_INSCRIPTION);
1131
1132         msg_format(_("%sに銘を刻む。", "Inscribing %s."), o_name);
1133         msg_print(NULL);
1134
1135         /* Start with nothing */
1136         strcpy(out_val, "");
1137
1138         /* Use old inscription */
1139         if (o_ptr->inscription)
1140         {
1141                 /* Start with the old inscription */
1142                 strcpy(out_val, quark_str(o_ptr->inscription));
1143         }
1144
1145         /* Get a new inscription (possibly empty) */
1146         if (get_string(_("銘: ", "Inscription: "), out_val, 80))
1147         {
1148                 /* Save the inscription */
1149                 o_ptr->inscription = quark_add(out_val);
1150
1151                 /* Combine the pack */
1152                 p_ptr->notice |= (PN_COMBINE);
1153
1154                 p_ptr->window |= (PW_INVEN | PW_EQUIP);
1155
1156                 /* .や$の関係で, 再計算が必要なはず -- henkma */
1157                 p_ptr->update |= (PU_BONUS);
1158         }
1159 }
1160
1161
1162
1163 /*!
1164  * @brief オブジェクトがランタンの燃料になるかどうかを判定する
1165  * An "item_tester_hook" for refilling lanterns
1166  * @param o_ptr 判定したいオブジェクトの構造体参照ポインタ
1167  * @return オブジェクトがランタンの燃料になるならばTRUEを返す
1168  */
1169 static bool item_tester_refill_lantern(object_type *o_ptr)
1170 {
1171         /* Flasks of oil are okay */
1172         if (o_ptr->tval == TV_FLASK) return (TRUE);
1173
1174         /* Laterns are okay */
1175         if ((o_ptr->tval == TV_LITE) &&
1176             (o_ptr->sval == SV_LITE_LANTERN)) return (TRUE);
1177
1178         /* Assume not okay */
1179         return (FALSE);
1180 }
1181
1182
1183 /*!
1184  * @brief ランタンに燃料を加えるコマンドのメインルーチン
1185  * Refill the players lamp (from the pack or floor)
1186  * @return なし
1187  */
1188 static void do_cmd_refill_lamp(void)
1189 {
1190         OBJECT_IDX item;
1191
1192         object_type *o_ptr;
1193         object_type *j_ptr;
1194
1195         cptr q, s;
1196
1197
1198         /* Restrict the choices */
1199         item_tester_hook = item_tester_refill_lantern;
1200
1201         /* Get an item */
1202 #ifdef JP
1203         q = "どの油つぼから注ぎますか? ";
1204         s = "油つぼがない。";
1205 #else
1206         q = "Refill with which flask? ";
1207         s = "You have no flasks of oil.";
1208 #endif
1209
1210         if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return;
1211
1212         /* Get the item (in the pack) */
1213         if (item >= 0)
1214         {
1215                 o_ptr = &inventory[item];
1216         }
1217
1218         /* Get the item (on the floor) */
1219         else
1220         {
1221                 o_ptr = &o_list[0 - item];
1222         }
1223
1224
1225         /* Take a partial turn */
1226         p_ptr->energy_use = 50;
1227
1228         /* Access the lantern */
1229         j_ptr = &inventory[INVEN_LITE];
1230
1231         /* Refuel */
1232         j_ptr->xtra4 += o_ptr->xtra4;
1233
1234         msg_print(_("ランプに油を注いだ。", "You fuel your lamp."));
1235
1236         /* Comment */
1237         if ((o_ptr->name2 == EGO_LITE_DARKNESS) && (j_ptr->xtra4 > 0))
1238         {
1239                 j_ptr->xtra4 = 0;
1240                 msg_print(_("ランプが消えてしまった!", "Your lamp has gone out!"));
1241         }
1242         else if ((o_ptr->name2 == EGO_LITE_DARKNESS) || (j_ptr->name2 == EGO_LITE_DARKNESS))
1243         {
1244                 j_ptr->xtra4 = 0;
1245                 msg_print(_("しかしランプは全く光らない。", "Curiously, your lamp doesn't light."));
1246         }
1247         else if (j_ptr->xtra4 >= FUEL_LAMP)
1248         {
1249                 j_ptr->xtra4 = FUEL_LAMP;
1250                 msg_print(_("ランプの油は一杯だ。", "Your lamp is full."));
1251         }
1252
1253         /* Decrease the item (from the pack) */
1254         if (item >= 0)
1255         {
1256                 inven_item_increase(item, -1);
1257                 inven_item_describe(item);
1258                 inven_item_optimize(item);
1259         }
1260
1261         /* Decrease the item (from the floor) */
1262         else
1263         {
1264                 floor_item_increase(0 - item, -1);
1265                 floor_item_describe(0 - item);
1266                 floor_item_optimize(0 - item);
1267         }
1268
1269         /* Recalculate torch */
1270         p_ptr->update |= (PU_TORCH);
1271 }
1272
1273
1274 /*!
1275  * @brief オブジェクトが松明に束ねられるかどうかを判定する
1276  * An "item_tester_hook" for refilling torches
1277  * @param o_ptr 判定したいオブジェクトの構造体参照ポインタ
1278  * @return オブジェクトが松明に束ねられるならばTRUEを返す
1279  */
1280 static bool item_tester_refill_torch(object_type *o_ptr)
1281 {
1282         /* Torches are okay */
1283         if ((o_ptr->tval == TV_LITE) &&
1284             (o_ptr->sval == SV_LITE_TORCH)) return (TRUE);
1285
1286         /* Assume not okay */
1287         return (FALSE);
1288 }
1289
1290
1291 /*!
1292  * @brief 松明を束ねるコマンドのメインルーチン
1293  * Refuel the players torch (from the pack or floor)
1294  * @return なし
1295  */
1296 static void do_cmd_refill_torch(void)
1297 {
1298         OBJECT_IDX item;
1299
1300         object_type *o_ptr;
1301         object_type *j_ptr;
1302
1303         cptr q, s;
1304
1305
1306         /* Restrict the choices */
1307         item_tester_hook = item_tester_refill_torch;
1308
1309         /* Get an item */
1310 #ifdef JP
1311         q = "どの松明で明かりを強めますか? ";
1312         s = "他に松明がない。";
1313 #else
1314         q = "Refuel with which torch? ";
1315         s = "You have no extra torches.";
1316 #endif
1317
1318         if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return;
1319
1320         /* Get the item (in the pack) */
1321         if (item >= 0)
1322         {
1323                 o_ptr = &inventory[item];
1324         }
1325
1326         /* Get the item (on the floor) */
1327         else
1328         {
1329                 o_ptr = &o_list[0 - item];
1330         }
1331
1332
1333         /* Take a partial turn */
1334         p_ptr->energy_use = 50;
1335
1336         /* Access the primary torch */
1337         j_ptr = &inventory[INVEN_LITE];
1338
1339         /* Refuel */
1340         j_ptr->xtra4 += o_ptr->xtra4 + 5;
1341
1342         msg_print(_("松明を結合した。", "You combine the torches."));
1343
1344         /* Comment */
1345         if ((o_ptr->name2 == EGO_LITE_DARKNESS) && (j_ptr->xtra4 > 0))
1346         {
1347                 j_ptr->xtra4 = 0;
1348                 msg_print(_("松明が消えてしまった!", "Your torch has gone out!"));
1349         }
1350         else if ((o_ptr->name2 == EGO_LITE_DARKNESS) || (j_ptr->name2 == EGO_LITE_DARKNESS))
1351         {
1352                 j_ptr->xtra4 = 0;
1353                 msg_print(_("しかし松明は全く光らない。", "Curiously, your torche don't light."));
1354         }
1355         /* Over-fuel message */
1356         else if (j_ptr->xtra4 >= FUEL_TORCH)
1357         {
1358                 j_ptr->xtra4 = FUEL_TORCH;
1359                 msg_print(_("松明の寿命は十分だ。", "Your torch is fully fueled."));
1360         }
1361
1362         /* Refuel message */
1363         else
1364         {
1365                 msg_print(_("松明はいっそう明るく輝いた。", "Your torch glows more brightly."));
1366         }
1367
1368         /* Decrease the item (from the pack) */
1369         if (item >= 0)
1370         {
1371                 inven_item_increase(item, -1);
1372                 inven_item_describe(item);
1373                 inven_item_optimize(item);
1374         }
1375
1376         /* Decrease the item (from the floor) */
1377         else
1378         {
1379                 floor_item_increase(0 - item, -1);
1380                 floor_item_describe(0 - item);
1381                 floor_item_optimize(0 - item);
1382         }
1383
1384         /* Recalculate torch */
1385         p_ptr->update |= (PU_TORCH);
1386 }
1387
1388
1389 /*!
1390  * @brief 燃料を補充するコマンドのメインルーチン
1391  * Refill the players lamp, or restock his torches
1392  * @return なし
1393  */
1394 void do_cmd_refill(void)
1395 {
1396         object_type *o_ptr;
1397
1398         /* Get the light */
1399         o_ptr = &inventory[INVEN_LITE];
1400
1401         if (p_ptr->special_defense & KATA_MUSOU)
1402         {
1403                 set_action(ACTION_NONE);
1404         }
1405
1406         /* It is nothing */
1407         if (o_ptr->tval != TV_LITE)
1408         {
1409                 msg_print(_("光源を装備していない。", "You are not wielding a light."));
1410         }
1411
1412         /* It's a lamp */
1413         else if (o_ptr->sval == SV_LITE_LANTERN)
1414         {
1415                 do_cmd_refill_lamp();
1416         }
1417
1418         /* It's a torch */
1419         else if (o_ptr->sval == SV_LITE_TORCH)
1420         {
1421                 do_cmd_refill_torch();
1422         }
1423
1424         /* No torch to refill */
1425         else
1426         {
1427                 msg_print(_("この光源は寿命を延ばせない。", "Your light cannot be refilled."));
1428         }
1429 }
1430
1431
1432 /*!
1433  * @brief ターゲットを設定するコマンドのメインルーチン
1434  * Target command
1435  * @return なし
1436  */
1437 void do_cmd_target(void)
1438 {
1439         /* Target set */
1440         if (target_set(TARGET_KILL))
1441         {
1442                 msg_print(_("ターゲット決定。", "Target Selected."));
1443         }
1444
1445         /* Target aborted */
1446         else
1447         {
1448                 msg_print(_("ターゲット解除。", "Target Aborted."));
1449         }
1450 }
1451
1452
1453
1454 /*!
1455  * @brief 周囲を見渡すコマンドのメインルーチン
1456  * Look command
1457  * @return なし
1458  */
1459 void do_cmd_look(void)
1460 {
1461         /*TEST*/
1462         p_ptr->window |= PW_MONSTER_LIST;
1463         window_stuff();
1464         /*TEST*/
1465
1466         /* Look around */
1467         if (target_set(TARGET_LOOK))
1468         {
1469                 msg_print(_("ターゲット決定。", "Target Selected."));
1470         }
1471 }
1472
1473
1474 /*!
1475  * @brief 位置を確認するコマンドのメインルーチン
1476  * Allow the player to examine other sectors on the map
1477  * @return なし
1478  */
1479 void do_cmd_locate(void)
1480 {
1481         int             dir, y1, x1, y2, x2;
1482
1483         char    tmp_val[80];
1484
1485         char    out_val[160];
1486
1487         int wid, hgt;
1488
1489         /* Get size */
1490         get_screen_size(&wid, &hgt);
1491
1492
1493         /* Start at current panel */
1494         y2 = y1 = panel_row_min;
1495         x2 = x1 = panel_col_min;
1496
1497         /* Show panels until done */
1498         while (1)
1499         {
1500                 /* Describe the location */
1501                 if ((y2 == y1) && (x2 == x1))
1502                 {
1503 #ifdef JP
1504                         strcpy(tmp_val, "真上");
1505 #else
1506                         tmp_val[0] = '\0';
1507 #endif
1508
1509                 }
1510                 else
1511                 {
1512 #ifdef JP
1513                         sprintf(tmp_val, "%s%s",
1514                                 ((y2 < y1) ? "北" : (y2 > y1) ? "南" : ""),
1515                                 ((x2 < x1) ? "西" : (x2 > x1) ? "東" : ""));
1516 #else
1517                         sprintf(tmp_val, "%s%s of",
1518                                 ((y2 < y1) ? " North" : (y2 > y1) ? " South" : ""),
1519                                 ((x2 < x1) ? " West" : (x2 > x1) ? " East" : ""));
1520 #endif
1521
1522                 }
1523
1524                 /* Prepare to ask which way to look */
1525                 sprintf(out_val, _("マップ位置 [%d(%02d),%d(%02d)] (プレイヤーの%s)  方向?", 
1526                                                "Map sector [%d(%02d),%d(%02d)], which is%s your sector.  Direction?"),
1527                         y2 / (hgt / 2), y2 % (hgt / 2),
1528                         x2 / (wid / 2), x2 % (wid / 2), tmp_val);
1529
1530                 /* Assume no direction */
1531                 dir = 0;
1532
1533                 /* Get a direction */
1534                 while (!dir)
1535                 {
1536                         char command;
1537
1538                         /* Get a command (or Cancel) */
1539                         if (!get_com(out_val, &command, TRUE)) break;
1540
1541                         /* Extract the action (if any) */
1542                         dir = get_keymap_dir(command);
1543
1544                         /* Error */
1545                         if (!dir) bell();
1546                 }
1547
1548                 /* No direction */
1549                 if (!dir) break;
1550
1551                 /* Apply the motion */
1552                 if (change_panel(ddy[dir], ddx[dir]))
1553                 {
1554                         y2 = panel_row_min;
1555                         x2 = panel_col_min;
1556                 }
1557         }
1558
1559
1560         /* Recenter the map around the player */
1561         verify_panel();
1562
1563         p_ptr->update |= (PU_MONSTERS);
1564
1565         /* Redraw map */
1566         p_ptr->redraw |= (PR_MAP);
1567
1568         p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
1569
1570         /* Handle stuff */
1571         handle_stuff();
1572 }
1573
1574
1575
1576 /*!
1577  * @brief モンスター種族情報を特定の基準によりソートするための比較処理
1578  * Sorting hook -- Comp function -- see below
1579  * @param u モンスター種族情報の入れるポインタ
1580  * @param v 条件基準ID
1581  * @param a 比較するモンスター種族のID1
1582  * @param b 比較するモンスター種族のID2
1583  * @return 2の方が大きければTRUEを返す
1584  * We use "u" to point to array of monster indexes,
1585  * and "v" to select the type of sorting to perform on "u".
1586  */
1587 bool ang_sort_comp_hook(vptr u, vptr v, int a, int b)
1588 {
1589         u16b *who = (u16b*)(u);
1590
1591         u16b *why = (u16b*)(v);
1592
1593         int w1 = who[a];
1594         int w2 = who[b];
1595
1596         int z1, z2;
1597
1598         /* Sort by player kills */
1599         if (*why >= 4)
1600         {
1601                 /* Extract player kills */
1602                 z1 = r_info[w1].r_pkills;
1603                 z2 = r_info[w2].r_pkills;
1604
1605                 /* Compare player kills */
1606                 if (z1 < z2) return (TRUE);
1607                 if (z1 > z2) return (FALSE);
1608         }
1609
1610
1611         /* Sort by total kills */
1612         if (*why >= 3)
1613         {
1614                 /* Extract total kills */
1615                 z1 = r_info[w1].r_tkills;
1616                 z2 = r_info[w2].r_tkills;
1617
1618                 /* Compare total kills */
1619                 if (z1 < z2) return (TRUE);
1620                 if (z1 > z2) return (FALSE);
1621         }
1622
1623
1624         /* Sort by monster level */
1625         if (*why >= 2)
1626         {
1627                 /* Extract levels */
1628                 z1 = r_info[w1].level;
1629                 z2 = r_info[w2].level;
1630
1631                 /* Compare levels */
1632                 if (z1 < z2) return (TRUE);
1633                 if (z1 > z2) return (FALSE);
1634         }
1635
1636
1637         /* Sort by monster experience */
1638         if (*why >= 1)
1639         {
1640                 /* Extract experience */
1641                 z1 = r_info[w1].mexp;
1642                 z2 = r_info[w2].mexp;
1643
1644                 /* Compare experience */
1645                 if (z1 < z2) return (TRUE);
1646                 if (z1 > z2) return (FALSE);
1647         }
1648
1649
1650         /* Compare indexes */
1651         return (w1 <= w2);
1652 }
1653
1654
1655 /*!
1656  * @brief モンスター種族情報を特定の基準によりソートするためのスワップ処理
1657  * Sorting hook -- Swap function -- see below
1658  * @param u モンスター種族情報の入れるポインタ
1659  * @param v 未使用
1660  * @param a スワップするモンスター種族のID1
1661  * @param b スワップするモンスター種族のID2
1662  * @return なし
1663  * @details
1664  * We use "u" to point to array of monster indexes,
1665  * and "v" to select the type of sorting to perform.
1666  */
1667 void ang_sort_swap_hook(vptr u, vptr v, int a, int b)
1668 {
1669         u16b *who = (u16b*)(u);
1670
1671         u16b holder;
1672
1673         /* Unused */
1674         (void)v;
1675
1676         /* Swap */
1677         holder = who[a];
1678         who[a] = who[b];
1679         who[b] = holder;
1680 }
1681
1682
1683
1684 /*!
1685  * @brief モンスターの思い出を見るコマンドのメインルーチン
1686  * Identify a character, allow recall of monsters
1687  * @return なし
1688  * @details
1689  * <pre>
1690  * Several "special" responses recall "multiple" monsters:
1691  *   ^A (all monsters)
1692  *   ^U (all unique monsters)
1693  *   ^N (all non-unique monsters)
1694  *
1695  * The responses may be sorted in several ways, see below.
1696  *
1697  * Note that the player ghosts are ignored. XXX XXX XXX
1698  * </pre>
1699  */
1700 void do_cmd_query_symbol(void)
1701 {
1702         IDX i;
1703         int n;
1704         MONRACE_IDX r_idx;
1705         char    sym, query;
1706         char    buf[128];
1707
1708         bool    all = FALSE;
1709         bool    uniq = FALSE;
1710         bool    norm = FALSE;
1711         bool    ride = FALSE;
1712         char    temp[80] = "";
1713
1714         bool    recall = FALSE;
1715
1716         u16b    why = 0;
1717         IDX     *who;
1718
1719         /* Get a character, or abort */
1720         if (!get_com(_("知りたい文字を入力して下さい(記号 or ^A全,^Uユ,^N非ユ,^R乗馬,^M名前): ", 
1721                                    "Enter character to be identified(^A:All,^U:Uniqs,^N:Non uniqs,^M:Name): "), &sym, FALSE)) return;
1722
1723         /* Find that character info, and describe it */
1724         for (i = 0; ident_info[i]; ++i)
1725         {
1726                 if (sym == ident_info[i][0]) break;
1727         }
1728
1729         /* Describe */
1730         if (sym == KTRL('A'))
1731         {
1732                 all = TRUE;
1733                 strcpy(buf, _("全モンスターのリスト", "Full monster list."));
1734         }
1735         else if (sym == KTRL('U'))
1736         {
1737                 all = uniq = TRUE;
1738                 strcpy(buf, _("ユニーク・モンスターのリスト", "Unique monster list."));
1739         }
1740         else if (sym == KTRL('N'))
1741         {
1742                 all = norm = TRUE;
1743                 strcpy(buf, _("ユニーク外モンスターのリスト", "Non-unique monster list."));
1744         }
1745         else if (sym == KTRL('R'))
1746         {
1747                 all = ride = TRUE;
1748                 strcpy(buf, _("乗馬可能モンスターのリスト", "Ridable monster list."));
1749         }
1750         /* XTRA HACK WHATSEARCH */
1751         else if (sym == KTRL('M'))
1752         {
1753                 all = TRUE;
1754                 if (!get_string(_("名前(英語の場合小文字で可)", "Enter name:"),temp, 70))
1755                 {
1756                         temp[0]=0;
1757                         return;
1758                 }
1759                 sprintf(buf, _("名前:%sにマッチ", "Monsters with a name \"%s\""),temp);
1760         }
1761         else if (ident_info[i])
1762         {
1763                 sprintf(buf, "%c - %s.", sym, ident_info[i] + 2);
1764         }
1765         else
1766         {
1767                 sprintf(buf, "%c - %s", sym, _("無効な文字", "Unknown Symbol"));
1768         }
1769
1770         /* Display the result */
1771         prt(buf, 0, 0);
1772
1773         /* Allocate the "who" array */
1774         C_MAKE(who, max_r_idx, IDX);
1775
1776         /* Collect matching monsters */
1777         for (n = 0, i = 1; i < max_r_idx; i++)
1778         {
1779                 monster_race *r_ptr = &r_info[i];
1780
1781                 /* Nothing to recall */
1782                 if (!cheat_know && !r_ptr->r_sights) continue;
1783
1784                 /* Require non-unique monsters if needed */
1785                 if (norm && (r_ptr->flags1 & (RF1_UNIQUE))) continue;
1786
1787                 /* Require unique monsters if needed */
1788                 if (uniq && !(r_ptr->flags1 & (RF1_UNIQUE))) continue;
1789
1790                 /* Require ridable monsters if needed */
1791                 if (ride && !(r_ptr->flags7 & (RF7_RIDING))) continue;
1792
1793                 /* XTRA HACK WHATSEARCH */
1794                 if (temp[0])
1795                 {
1796                         TERM_LEN xx;
1797                         char temp2[80];
1798
1799                         for (xx = 0; temp[xx] && xx < 80; xx++)
1800                         {
1801 #ifdef JP
1802                                 if (iskanji(temp[xx])) { xx++; continue; }
1803 #endif
1804                                 if (isupper(temp[xx])) temp[xx] = (char)tolower(temp[xx]);
1805                         }
1806
1807 #ifdef JP
1808                         strcpy(temp2, r_name + r_ptr->E_name);
1809 #else
1810                         strcpy(temp2, r_name + r_ptr->name);
1811 #endif
1812                         for (xx = 0; temp2[xx] && xx < 80; xx++)
1813                                 if (isupper(temp2[xx])) temp2[xx] = (char)tolower(temp2[xx]);
1814
1815 #ifdef JP
1816                         if (my_strstr(temp2, temp) || my_strstr(r_name + r_ptr->name, temp))
1817 #else
1818                         if (my_strstr(temp2, temp))
1819 #endif
1820                                 who[n++] = i;
1821                 }
1822
1823                 /* Collect "appropriate" monsters */
1824                 else if (all || (r_ptr->d_char == sym)) who[n++] = i;
1825         }
1826
1827         /* Nothing to recall */
1828         if (!n)
1829         {
1830                 /* Free the "who" array */
1831                 C_KILL(who, max_r_idx, IDX);
1832
1833                 return;
1834         }
1835
1836
1837         /* Prompt XXX XXX XXX */
1838         put_str(_("思い出を見ますか? (k:殺害順/y/n): ", "Recall details? (k/y/n): "), 0, _(36, 40));
1839
1840
1841         /* Query */
1842         query = inkey();
1843
1844         /* Restore */
1845         prt(buf, 0, 0);
1846
1847         why = 2;
1848
1849         /* Select the sort method */
1850         ang_sort_comp = ang_sort_comp_hook;
1851         ang_sort_swap = ang_sort_swap_hook;
1852
1853         /* Sort the array */
1854         ang_sort(who, &why, n);
1855
1856         /* Sort by kills (and level) */
1857         if (query == 'k')
1858         {
1859                 why = 4;
1860                 query = 'y';
1861         }
1862
1863         /* Catch "escape" */
1864         if (query != 'y')
1865         {
1866                 /* Free the "who" array */
1867                 C_KILL(who, max_r_idx, IDX);
1868
1869                 return;
1870         }
1871
1872         /* Sort if needed */
1873         if (why == 4)
1874         {
1875                 /* Select the sort method */
1876                 ang_sort_comp = ang_sort_comp_hook;
1877                 ang_sort_swap = ang_sort_swap_hook;
1878
1879                 /* Sort the array */
1880                 ang_sort(who, &why, n);
1881         }
1882
1883
1884         /* Start at the end */
1885         i = n - 1;
1886
1887         /* Scan the monster memory */
1888         while (1)
1889         {
1890                 /* Extract a race */
1891                 r_idx = who[i];
1892
1893                 /* Hack -- Auto-recall */
1894                 monster_race_track(r_idx);
1895
1896                 /* Hack -- Handle stuff */
1897                 handle_stuff();
1898
1899                 /* Interact */
1900                 while (1)
1901                 {
1902                         /* Recall */
1903                         if (recall)
1904                         {
1905                                 /* Save the screen */
1906                                 screen_save();
1907
1908                                 /* Recall on screen */
1909                                 screen_roff(who[i], 0);
1910                         }
1911
1912                         /* Hack -- Begin the prompt */
1913                         roff_top(r_idx);
1914
1915                         /* Hack -- Complete the prompt */
1916                         Term_addstr(-1, TERM_WHITE, _(" ['r'思い出, ESC]", " [(r)ecall, ESC]"));
1917
1918                         /* Command */
1919                         query = inkey();
1920
1921                         /* Unrecall */
1922                         if (recall)
1923                         {
1924                                 /* Restore */
1925                                 screen_load();
1926                         }
1927
1928                         /* Normal commands */
1929                         if (query != 'r') break;
1930
1931                         /* Toggle recall */
1932                         recall = !recall;
1933                 }
1934
1935                 /* Stop scanning */
1936                 if (query == ESCAPE) break;
1937
1938                 /* Move to "prev" monster */
1939                 if (query == '-')
1940                 {
1941                         if (++i == n)
1942                         {
1943                                 i = 0;
1944                                 if (!expand_list) break;
1945                         }
1946                 }
1947
1948                 /* Move to "next" monster */
1949                 else
1950                 {
1951                         if (i-- == 0)
1952                         {
1953                                 i = n - 1;
1954                                 if (!expand_list) break;
1955                         }
1956                 }
1957         }
1958
1959         /* Free the "who" array */
1960         C_KILL(who, max_r_idx, IDX);
1961
1962         /* Re-display the identity */
1963         prt(buf, 0, 0);
1964 }
1965
1966 /*!
1967  * @brief アイテムを汎用的に「使う」コマンドのメインルーチン /
1968  * Use an item
1969  * @return なし
1970  * @details
1971  * XXX - Add actions for other item types
1972  */
1973 void do_cmd_use(void)
1974 {
1975         OBJECT_IDX item;
1976         object_type *o_ptr;
1977         cptr        q, s;
1978
1979         if (p_ptr->special_defense & (KATA_MUSOU | KATA_KOUKIJIN))
1980         {
1981                 set_action(ACTION_NONE);
1982         }
1983
1984         item_tester_no_ryoute = TRUE;
1985         /* Prepare the hook */
1986         item_tester_hook = item_tester_hook_use;
1987
1988         /* Get an item */
1989         q = _("どれを使いますか?", "Use which item? ");
1990         s = _("使えるものがありません。", "You have nothing to use.");
1991
1992         if (!get_item(&item, q, s, (USE_INVEN | USE_EQUIP | USE_FLOOR))) return;
1993
1994         /* Get the item (in the pack) */
1995         if (item >= 0)
1996         {
1997                 o_ptr = &inventory[item];
1998         }
1999         /* Get the item (on the floor) */
2000         else
2001         {
2002                 o_ptr = &o_list[0 - item];
2003         }
2004
2005         switch (o_ptr->tval)
2006         {
2007                 /* Spike a door */
2008                 case TV_SPIKE:
2009                 {
2010                         do_cmd_spike();
2011                         break;
2012                 }
2013
2014                 /* Eat some food */
2015                 case TV_FOOD:
2016                 {
2017                         do_cmd_eat_food_aux(item);
2018                         break;
2019                 }
2020
2021                 /* Aim a wand */
2022                 case TV_WAND:
2023                 {
2024                         do_cmd_aim_wand_aux(item);
2025                         break;
2026                 }
2027
2028                 /* Use a staff */
2029                 case TV_STAFF:
2030                 {
2031                         do_cmd_use_staff_aux(item);
2032                         break;
2033                 }
2034
2035                 /* Zap a rod */
2036                 case TV_ROD:
2037                 {
2038                         do_cmd_zap_rod_aux(item);
2039                         break;
2040                 }
2041
2042                 /* Quaff a potion */
2043                 case TV_POTION:
2044                 {
2045                         do_cmd_quaff_potion_aux(item);
2046                         break;
2047                 }
2048
2049                 /* Read a scroll */
2050                 case TV_SCROLL:
2051                 {
2052                         /* Check some conditions */
2053                         if (p_ptr->blind)
2054                         {
2055                                 msg_print(_("目が見えない。", "You can't see anything."));
2056                                 return;
2057                         }
2058                         if (no_lite())
2059                         {
2060                                 msg_print(_("明かりがないので、暗くて読めない。", "You have no light to read by."));
2061                                 return;
2062                         }
2063                         if (p_ptr->confused)
2064                         {
2065                                 msg_print(_("混乱していて読めない!", "You are too confused!"));
2066                                 return;
2067                         }
2068
2069                   do_cmd_read_scroll_aux(item, TRUE);
2070                   break;
2071                 }
2072
2073                 /* Fire ammo */
2074                 case TV_SHOT:
2075                 case TV_ARROW:
2076                 case TV_BOLT:
2077                 {
2078                         do_cmd_fire_aux(item, &inventory[INVEN_BOW]);
2079                         break;
2080                 }
2081
2082                 /* Activate an artifact */
2083                 default:
2084                 {
2085                         do_cmd_activate_aux(item);
2086                         break;
2087                 }
2088         }
2089 }
2090