OSDN Git Service

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