OSDN Git Service

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