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