OSDN Git Service

#37287 (2.2.0.40) cmd1.c内のC4457警告に対応。 / Deal C4457 warning in cmd1.c.
[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         int 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         int 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         int item, amt = 1;
736
737         object_type *o_ptr;
738
739         cptr q, s;
740
741         if (p_ptr->special_defense & KATA_MUSOU)
742         {
743                 set_action(ACTION_NONE);
744         }
745
746         item_tester_no_ryoute = TRUE;
747         /* Get an item */
748 #ifdef JP
749         q = "どのアイテムを落としますか? ";
750         s = "落とせるアイテムを持っていない。";
751 #else
752         q = "Drop which item? ";
753         s = "You have nothing to drop.";
754 #endif
755
756         if (!get_item(&item, q, s, (USE_EQUIP | USE_INVEN))) return;
757
758         /* Get the item (in the pack) */
759         if (item >= 0)
760         {
761                 o_ptr = &inventory[item];
762         }
763
764         /* Get the item (on the floor) */
765         else
766         {
767                 o_ptr = &o_list[0 - item];
768         }
769
770
771         /* Hack -- Cannot remove cursed items */
772         if ((item >= INVEN_RARM) && object_is_cursed(o_ptr))
773         {
774                 /* Oops */
775                 msg_print(_("ふーむ、どうやら呪われているようだ。", "Hmmm, it seems to be cursed."));
776                 /* Nope */
777                 return;
778         }
779
780
781         /* See how many items */
782         if (o_ptr->number > 1)
783         {
784                 /* Get a quantity */
785                 amt = get_quantity(NULL, o_ptr->number);
786
787                 /* Allow user abort */
788                 if (amt <= 0) return;
789         }
790
791
792         /* Take a partial turn */
793         p_ptr->energy_use = 50;
794
795         /* Drop (some of) the item */
796         inven_drop(item, amt);
797
798         if (item >= INVEN_RARM)
799         {
800                 kamaenaoshi(item);
801                 calc_android_exp();
802         }
803
804         p_ptr->redraw |= (PR_EQUIPPY);
805 }
806
807 /*!
808  * @brief オブジェクトが高位の魔法書かどうかを判定する
809  * @param o_ptr 判定したいオブジェクトの構造体参照ポインタ
810  * @return オブジェクトが高位の魔法書ならばTRUEを返す
811  */
812 static bool high_level_book(object_type *o_ptr)
813 {
814         if ((o_ptr->tval == TV_LIFE_BOOK) ||
815             (o_ptr->tval == TV_SORCERY_BOOK) ||
816             (o_ptr->tval == TV_NATURE_BOOK) ||
817             (o_ptr->tval == TV_CHAOS_BOOK) ||
818             (o_ptr->tval == TV_DEATH_BOOK) ||
819             (o_ptr->tval == TV_TRUMP_BOOK) ||
820             (o_ptr->tval == TV_CRAFT_BOOK) ||
821             (o_ptr->tval == TV_DAEMON_BOOK) ||
822             (o_ptr->tval == TV_CRUSADE_BOOK) ||
823             (o_ptr->tval == TV_MUSIC_BOOK) ||
824                 (o_ptr->tval == TV_HEX_BOOK))
825         {
826                 if (o_ptr->sval > 1)
827                         return TRUE;
828                 else
829                         return FALSE;
830         }
831
832         return FALSE;
833 }
834
835
836 /*!
837  * @brief アイテムを破壊するコマンドのメインルーチン / Destroy an item
838  * @return なし
839  */
840 void do_cmd_destroy(void)
841 {
842         int                     item, amt = 1;
843         int                     old_number;
844
845         bool            force = FALSE;
846
847         object_type             *o_ptr;
848         object_type             forge;
849         object_type             *q_ptr = &forge;
850
851         char            o_name[MAX_NLEN];
852
853         char            out_val[MAX_NLEN+40];
854
855         cptr q, s;
856
857         if (p_ptr->special_defense & KATA_MUSOU)
858         {
859                 set_action(ACTION_NONE);
860         }
861
862         /* Hack -- force destruction */
863         if (command_arg > 0) force = TRUE;
864
865
866         /* Get an item */
867 #ifdef JP
868         q = "どのアイテムを壊しますか? ";
869         s = "壊せるアイテムを持っていない。";
870 #else
871         q = "Destroy which item? ";
872         s = "You have nothing to destroy.";
873 #endif
874
875         if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return;
876
877         /* Get the item (in the pack) */
878         if (item >= 0)
879         {
880                 o_ptr = &inventory[item];
881         }
882
883         /* Get the item (on the floor) */
884         else
885         {
886                 o_ptr = &o_list[0 - item];
887         }
888
889         /* Verify unless quantity given beforehand */
890         if (!force && (confirm_destroy || (object_value(o_ptr) > 0)))
891         {
892                 object_desc(o_name, o_ptr, OD_OMIT_PREFIX);
893
894                 /* Make a verification */
895                 sprintf(out_val, _("本当に%sを壊しますか? [y/n/Auto]", "Really destroy %s? [y/n/Auto]"), o_name);
896                 msg_print(NULL);
897
898                 /* HACK : Add the line to message buffer */
899                 message_add(out_val);
900                 p_ptr->window |= (PW_MESSAGE);
901                 window_stuff();
902
903                 /* Get an acceptable answer */
904                 while (TRUE)
905                 {
906                         char i;
907
908                         /* Prompt */
909                         prt(out_val, 0, 0);
910
911                         i = inkey();
912
913                         /* Erase the prompt */
914                         prt("", 0, 0);
915
916
917                         if (i == 'y' || i == 'Y')
918                         {
919                                 break;
920                         }
921                         if (i == ESCAPE || i == 'n' || i == 'N')
922                         {
923                                 /* Cancel */
924                                 return;
925                         }
926                         if (i == 'A')
927                         {
928                                 /* Add an auto-destroy preference line */
929                                 if (autopick_autoregister(o_ptr))
930                                 {
931                                         /* Auto-destroy it */
932                                         autopick_alter_item(item, TRUE);
933                                 }
934
935                                 /* The object is already destroyed. */
936                                 return;
937                         }
938                 } /* while (TRUE) */
939         }
940
941         /* See how many items */
942         if (o_ptr->number > 1)
943         {
944                 /* Get a quantity */
945                 amt = get_quantity(NULL, o_ptr->number);
946
947                 /* Allow user abort */
948                 if (amt <= 0) return;
949         }
950
951
952         /* Describe the object */
953         old_number = o_ptr->number;
954         o_ptr->number = amt;
955         object_desc(o_name, o_ptr, 0);
956         o_ptr->number = old_number;
957
958         /* Take a turn */
959         p_ptr->energy_use = 100;
960
961         /* Artifacts cannot be destroyed */
962         if (!can_player_destroy_object(o_ptr))
963         {
964                 p_ptr->energy_use = 0;
965
966                 /* Message */
967                 msg_format(_("%sは破壊不可能だ。", "You cannot destroy %s."), o_name);
968                 /* Done */
969                 return;
970         }
971
972         object_copy(q_ptr, o_ptr);
973
974         /* Message */
975         msg_format(_("%sを壊した。", "You destroy %s."), o_name);
976         sound(SOUND_DESTITEM);
977
978         /* Reduce the charges of rods/wands */
979         reduce_charges(o_ptr, amt);
980
981         /* Eliminate the item (from the pack) */
982         if (item >= 0)
983         {
984                 inven_item_increase(item, -amt);
985                 inven_item_describe(item);
986                 inven_item_optimize(item);
987         }
988
989         /* Eliminate the item (from the floor) */
990         else
991         {
992                 floor_item_increase(0 - item, -amt);
993                 floor_item_describe(0 - item);
994                 floor_item_optimize(0 - item);
995         }
996
997         if (high_level_book(q_ptr))
998         {
999                 bool gain_expr = FALSE;
1000
1001                 if (p_ptr->prace == RACE_ANDROID)
1002                 {
1003                 }
1004                 else if ((p_ptr->pclass == CLASS_WARRIOR) || (p_ptr->pclass == CLASS_BERSERKER))
1005                 {
1006                         gain_expr = TRUE;
1007                 }
1008                 else if (p_ptr->pclass == CLASS_PALADIN)
1009                 {
1010                         if (is_good_realm(p_ptr->realm1))
1011                         {
1012                                 if (!is_good_realm(tval2realm(q_ptr->tval))) gain_expr = TRUE;
1013                         }
1014                         else
1015                         {
1016                                 if (is_good_realm(tval2realm(q_ptr->tval))) gain_expr = TRUE;
1017                         }
1018                 }
1019
1020                 if (gain_expr && (p_ptr->exp < PY_MAX_EXP))
1021                 {
1022                         s32b tester_exp = p_ptr->max_exp / 20;
1023                         if (tester_exp > 10000) tester_exp = 10000;
1024                         if (q_ptr->sval < 3) tester_exp /= 4;
1025                         if (tester_exp<1) tester_exp = 1;
1026
1027                         msg_print(_("更に経験を積んだような気がする。", "You feel more experienced."));
1028                         gain_exp(tester_exp * amt);
1029                 }
1030                 if (high_level_book(q_ptr) && q_ptr->tval == TV_LIFE_BOOK)
1031                 {
1032                         chg_virtue(V_UNLIFE, 1);
1033                         chg_virtue(V_VITALITY, -1);
1034                 }
1035                 else if (high_level_book(q_ptr) && q_ptr->tval == TV_DEATH_BOOK)
1036                 {
1037                         chg_virtue(V_UNLIFE, -1);
1038                         chg_virtue(V_VITALITY, 1);
1039                 }
1040         
1041                 if (q_ptr->to_a || q_ptr->to_h || q_ptr->to_d)
1042                         chg_virtue(V_ENCHANT, -1);
1043         
1044                 if (object_value_real(q_ptr) > 30000)
1045                         chg_virtue(V_SACRIFICE, 2);
1046         
1047                 else if (object_value_real(q_ptr) > 10000)
1048                         chg_virtue(V_SACRIFICE, 1);
1049         }
1050
1051         if (q_ptr->to_a != 0 || q_ptr->to_d != 0 || q_ptr->to_h != 0)
1052                 chg_virtue(V_HARMONY, 1);
1053
1054         if (item >= INVEN_RARM) calc_android_exp();
1055 }
1056
1057
1058 /*!
1059  * @brief アイテムを調査するコマンドのメインルーチン / Observe an item which has been *identify*-ed
1060  * @return なし
1061  */
1062 void do_cmd_observe(void)
1063 {
1064         int                     item;
1065
1066         object_type             *o_ptr;
1067
1068         char            o_name[MAX_NLEN];
1069
1070         cptr q, s;
1071
1072         item_tester_no_ryoute = TRUE;
1073         /* Get an item */
1074 #ifdef JP
1075         q = "どのアイテムを調べますか? ";
1076         s = "調べられるアイテムがない。";
1077 #else
1078         q = "Examine which item? ";
1079         s = "You have nothing to examine.";
1080 #endif
1081
1082         if (!get_item(&item, q, s, (USE_EQUIP | USE_INVEN | USE_FLOOR))) return;
1083
1084         /* Get the item (in the pack) */
1085         if (item >= 0)
1086         {
1087                 o_ptr = &inventory[item];
1088         }
1089
1090         /* Get the item (on the floor) */
1091         else
1092         {
1093                 o_ptr = &o_list[0 - item];
1094         }
1095
1096
1097         /* Require full knowledge */
1098         if (!(o_ptr->ident & IDENT_MENTAL))
1099         {
1100                 msg_print(_("このアイテムについて特に知っていることはない。", "You have no special knowledge about that item."));
1101                 return;
1102         }
1103
1104
1105         /* Description */
1106         object_desc(o_name, o_ptr, 0);
1107
1108         /* Describe */
1109         msg_format(_("%sを調べている...", "Examining %s..."), o_name);
1110         /* Describe it fully */
1111         if (!screen_object(o_ptr, SCROBJ_FORCE_DETAIL)) msg_print(_("特に変わったところはないようだ。", "You see nothing special."));
1112 }
1113
1114
1115
1116 /*!
1117  * @brief アイテムの銘を消すコマンドのメインルーチン
1118  * Remove the inscription from an object XXX Mention item (when done)?
1119  * @return なし
1120  */
1121 void do_cmd_uninscribe(void)
1122 {
1123         int   item;
1124
1125         object_type *o_ptr;
1126
1127         cptr q, s;
1128
1129         item_tester_no_ryoute = TRUE;
1130         /* Get an item */
1131 #ifdef JP
1132         q = "どのアイテムの銘を消しますか? ";
1133         s = "銘を消せるアイテムがない。";
1134 #else
1135         q = "Un-inscribe which item? ";
1136         s = "You have nothing to un-inscribe.";
1137 #endif
1138
1139         if (!get_item(&item, q, s, (USE_EQUIP | USE_INVEN | USE_FLOOR))) return;
1140
1141         /* Get the item (in the pack) */
1142         if (item >= 0)
1143         {
1144                 o_ptr = &inventory[item];
1145         }
1146
1147         /* Get the item (on the floor) */
1148         else
1149         {
1150                 o_ptr = &o_list[0 - item];
1151         }
1152
1153         /* Nothing to remove */
1154         if (!o_ptr->inscription)
1155         {
1156                 msg_print(_("このアイテムには消すべき銘がない。", "That item had no inscription to remove."));
1157                 return;
1158         }
1159
1160         /* Message */
1161         msg_print(_("銘を消した。", "Inscription removed."));
1162
1163         /* Remove the incription */
1164         o_ptr->inscription = 0;
1165
1166         /* Combine the pack */
1167         p_ptr->notice |= (PN_COMBINE);
1168
1169         /* Window stuff */
1170         p_ptr->window |= (PW_INVEN | PW_EQUIP);
1171
1172         /* .や$の関係で, 再計算が必要なはず -- henkma */
1173         p_ptr->update |= (PU_BONUS);
1174
1175 }
1176
1177
1178 /*!
1179  * @brief アイテムの銘を刻むコマンドのメインルーチン
1180  * Inscribe an object with a comment
1181  * @return なし
1182  */
1183 void do_cmd_inscribe(void)
1184 {
1185         int                     item;
1186
1187         object_type             *o_ptr;
1188
1189         char            o_name[MAX_NLEN];
1190
1191         char            out_val[80];
1192
1193         cptr q, s;
1194
1195         item_tester_no_ryoute = TRUE;
1196         /* Get an item */
1197 #ifdef JP
1198         q = "どのアイテムに銘を刻みますか? ";
1199         s = "銘を刻めるアイテムがない。";
1200 #else
1201         q = "Inscribe which item? ";
1202         s = "You have nothing to inscribe.";
1203 #endif
1204
1205         if (!get_item(&item, q, s, (USE_EQUIP | USE_INVEN | USE_FLOOR))) return;
1206
1207         /* Get the item (in the pack) */
1208         if (item >= 0)
1209         {
1210                 o_ptr = &inventory[item];
1211         }
1212
1213         /* Get the item (on the floor) */
1214         else
1215         {
1216                 o_ptr = &o_list[0 - item];
1217         }
1218
1219         /* Describe the activity */
1220         object_desc(o_name, o_ptr, OD_OMIT_INSCRIPTION);
1221
1222         /* Message */
1223         msg_format(_("%sに銘を刻む。", "Inscribing %s."), o_name);
1224         msg_print(NULL);
1225
1226         /* Start with nothing */
1227         strcpy(out_val, "");
1228
1229         /* Use old inscription */
1230         if (o_ptr->inscription)
1231         {
1232                 /* Start with the old inscription */
1233                 strcpy(out_val, quark_str(o_ptr->inscription));
1234         }
1235
1236         /* Get a new inscription (possibly empty) */
1237         if (get_string(_("銘: ", "Inscription: "), out_val, 80))
1238         {
1239                 /* Save the inscription */
1240                 o_ptr->inscription = quark_add(out_val);
1241
1242                 /* Combine the pack */
1243                 p_ptr->notice |= (PN_COMBINE);
1244
1245                 /* Window stuff */
1246                 p_ptr->window |= (PW_INVEN | PW_EQUIP);
1247
1248                 /* .や$の関係で, 再計算が必要なはず -- henkma */
1249                 p_ptr->update |= (PU_BONUS);
1250         }
1251 }
1252
1253
1254
1255 /*!
1256  * @brief オブジェクトがランタンの燃料になるかどうかを判定する
1257  * An "item_tester_hook" for refilling lanterns
1258  * @param o_ptr 判定したいオブジェクトの構造体参照ポインタ
1259  * @return オブジェクトがランタンの燃料になるならばTRUEを返す
1260  */
1261 static bool item_tester_refill_lantern(object_type *o_ptr)
1262 {
1263         /* Flasks of oil are okay */
1264         if (o_ptr->tval == TV_FLASK) return (TRUE);
1265
1266         /* Laterns are okay */
1267         if ((o_ptr->tval == TV_LITE) &&
1268             (o_ptr->sval == SV_LITE_LANTERN)) return (TRUE);
1269
1270         /* Assume not okay */
1271         return (FALSE);
1272 }
1273
1274
1275 /*!
1276  * @brief ランタンに燃料を加えるコマンドのメインルーチン
1277  * Refill the players lamp (from the pack or floor)
1278  * @return なし
1279  */
1280 static void do_cmd_refill_lamp(void)
1281 {
1282         int item;
1283
1284         object_type *o_ptr;
1285         object_type *j_ptr;
1286
1287         cptr q, s;
1288
1289
1290         /* Restrict the choices */
1291         item_tester_hook = item_tester_refill_lantern;
1292
1293         /* Get an item */
1294 #ifdef JP
1295         q = "どの油つぼから注ぎますか? ";
1296         s = "油つぼがない。";
1297 #else
1298         q = "Refill with which flask? ";
1299         s = "You have no flasks of oil.";
1300 #endif
1301
1302         if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return;
1303
1304         /* Get the item (in the pack) */
1305         if (item >= 0)
1306         {
1307                 o_ptr = &inventory[item];
1308         }
1309
1310         /* Get the item (on the floor) */
1311         else
1312         {
1313                 o_ptr = &o_list[0 - item];
1314         }
1315
1316
1317         /* Take a partial turn */
1318         p_ptr->energy_use = 50;
1319
1320         /* Access the lantern */
1321         j_ptr = &inventory[INVEN_LITE];
1322
1323         /* Refuel */
1324         j_ptr->xtra4 += o_ptr->xtra4;
1325
1326         /* Message */
1327         msg_print(_("ランプに油を注いだ。", "You fuel your lamp."));
1328
1329         /* Comment */
1330         if ((o_ptr->name2 == EGO_LITE_DARKNESS) && (j_ptr->xtra4 > 0))
1331         {
1332                 j_ptr->xtra4 = 0;
1333                 msg_print(_("ランプが消えてしまった!", "Your lamp has gone out!"));
1334         }
1335         else if ((o_ptr->name2 == EGO_LITE_DARKNESS) || (j_ptr->name2 == EGO_LITE_DARKNESS))
1336         {
1337                 j_ptr->xtra4 = 0;
1338                 msg_print(_("しかしランプは全く光らない。", "Curiously, your lamp doesn't light."));
1339         }
1340         else if (j_ptr->xtra4 >= FUEL_LAMP)
1341         {
1342                 j_ptr->xtra4 = FUEL_LAMP;
1343                 msg_print(_("ランプの油は一杯だ。", "Your lamp is full."));
1344         }
1345
1346         /* Decrease the item (from the pack) */
1347         if (item >= 0)
1348         {
1349                 inven_item_increase(item, -1);
1350                 inven_item_describe(item);
1351                 inven_item_optimize(item);
1352         }
1353
1354         /* Decrease the item (from the floor) */
1355         else
1356         {
1357                 floor_item_increase(0 - item, -1);
1358                 floor_item_describe(0 - item);
1359                 floor_item_optimize(0 - item);
1360         }
1361
1362         /* Recalculate torch */
1363         p_ptr->update |= (PU_TORCH);
1364 }
1365
1366
1367 /*!
1368  * @brief オブジェクトが松明に束ねられるかどうかを判定する
1369  * An "item_tester_hook" for refilling torches
1370  * @param o_ptr 判定したいオブジェクトの構造体参照ポインタ
1371  * @return オブジェクトが松明に束ねられるならばTRUEを返す
1372  */
1373 static bool item_tester_refill_torch(object_type *o_ptr)
1374 {
1375         /* Torches are okay */
1376         if ((o_ptr->tval == TV_LITE) &&
1377             (o_ptr->sval == SV_LITE_TORCH)) return (TRUE);
1378
1379         /* Assume not okay */
1380         return (FALSE);
1381 }
1382
1383
1384 /*!
1385  * @brief 松明を束ねるコマンドのメインルーチン
1386  * Refuel the players torch (from the pack or floor)
1387  * @return なし
1388  */
1389 static void do_cmd_refill_torch(void)
1390 {
1391         int item;
1392
1393         object_type *o_ptr;
1394         object_type *j_ptr;
1395
1396         cptr q, s;
1397
1398
1399         /* Restrict the choices */
1400         item_tester_hook = item_tester_refill_torch;
1401
1402         /* Get an item */
1403 #ifdef JP
1404         q = "どの松明で明かりを強めますか? ";
1405         s = "他に松明がない。";
1406 #else
1407         q = "Refuel with which torch? ";
1408         s = "You have no extra torches.";
1409 #endif
1410
1411         if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return;
1412
1413         /* Get the item (in the pack) */
1414         if (item >= 0)
1415         {
1416                 o_ptr = &inventory[item];
1417         }
1418
1419         /* Get the item (on the floor) */
1420         else
1421         {
1422                 o_ptr = &o_list[0 - item];
1423         }
1424
1425
1426         /* Take a partial turn */
1427         p_ptr->energy_use = 50;
1428
1429         /* Access the primary torch */
1430         j_ptr = &inventory[INVEN_LITE];
1431
1432         /* Refuel */
1433         j_ptr->xtra4 += o_ptr->xtra4 + 5;
1434
1435         /* Message */
1436         msg_print(_("松明を結合した。", "You combine the torches."));
1437
1438         /* Comment */
1439         if ((o_ptr->name2 == EGO_LITE_DARKNESS) && (j_ptr->xtra4 > 0))
1440         {
1441                 j_ptr->xtra4 = 0;
1442                 msg_print(_("松明が消えてしまった!", "Your torch has gone out!"));
1443         }
1444         else if ((o_ptr->name2 == EGO_LITE_DARKNESS) || (j_ptr->name2 == EGO_LITE_DARKNESS))
1445         {
1446                 j_ptr->xtra4 = 0;
1447                 msg_print(_("しかし松明は全く光らない。", "Curiously, your torche don't light."));
1448         }
1449         /* Over-fuel message */
1450         else if (j_ptr->xtra4 >= FUEL_TORCH)
1451         {
1452                 j_ptr->xtra4 = FUEL_TORCH;
1453                 msg_print(_("松明の寿命は十分だ。", "Your torch is fully fueled."));
1454         }
1455
1456         /* Refuel message */
1457         else
1458         {
1459                 msg_print(_("松明はいっそう明るく輝いた。", "Your torch glows more brightly."));
1460         }
1461
1462         /* Decrease the item (from the pack) */
1463         if (item >= 0)
1464         {
1465                 inven_item_increase(item, -1);
1466                 inven_item_describe(item);
1467                 inven_item_optimize(item);
1468         }
1469
1470         /* Decrease the item (from the floor) */
1471         else
1472         {
1473                 floor_item_increase(0 - item, -1);
1474                 floor_item_describe(0 - item);
1475                 floor_item_optimize(0 - item);
1476         }
1477
1478         /* Recalculate torch */
1479         p_ptr->update |= (PU_TORCH);
1480 }
1481
1482
1483 /*!
1484  * @brief 燃料を補充するコマンドのメインルーチン
1485  * Refill the players lamp, or restock his torches
1486  * @return なし
1487  */
1488 void do_cmd_refill(void)
1489 {
1490         object_type *o_ptr;
1491
1492         /* Get the light */
1493         o_ptr = &inventory[INVEN_LITE];
1494
1495         if (p_ptr->special_defense & KATA_MUSOU)
1496         {
1497                 set_action(ACTION_NONE);
1498         }
1499
1500         /* It is nothing */
1501         if (o_ptr->tval != TV_LITE)
1502         {
1503                 msg_print(_("光源を装備していない。", "You are not wielding a light."));
1504         }
1505
1506         /* It's a lamp */
1507         else if (o_ptr->sval == SV_LITE_LANTERN)
1508         {
1509                 do_cmd_refill_lamp();
1510         }
1511
1512         /* It's a torch */
1513         else if (o_ptr->sval == SV_LITE_TORCH)
1514         {
1515                 do_cmd_refill_torch();
1516         }
1517
1518         /* No torch to refill */
1519         else
1520         {
1521                 msg_print(_("この光源は寿命を延ばせない。", "Your light cannot be refilled."));
1522         }
1523 }
1524
1525
1526 /*!
1527  * @brief ターゲットを設定するコマンドのメインルーチン
1528  * Target command
1529  * @return なし
1530  */
1531 void do_cmd_target(void)
1532 {
1533         /* Target set */
1534         if (target_set(TARGET_KILL))
1535         {
1536                 msg_print(_("ターゲット決定。", "Target Selected."));
1537         }
1538
1539         /* Target aborted */
1540         else
1541         {
1542                 msg_print(_("ターゲット解除。", "Target Aborted."));
1543         }
1544 }
1545
1546
1547
1548 /*!
1549  * @brief 周囲を見渡すコマンドのメインルーチン
1550  * Look command
1551  * @return なし
1552  */
1553 void do_cmd_look(void)
1554 {
1555         /*TEST*/
1556         p_ptr->window |= PW_MONSTER_LIST;
1557         window_stuff();
1558         /*TEST*/
1559
1560         /* Look around */
1561         if (target_set(TARGET_LOOK))
1562         {
1563                 msg_print(_("ターゲット決定。", "Target Selected."));
1564         }
1565 }
1566
1567
1568 /*!
1569  * @brief 位置を確認するコマンドのメインルーチン
1570  * Allow the player to examine other sectors on the map
1571  * @return なし
1572  */
1573 void do_cmd_locate(void)
1574 {
1575         int             dir, y1, x1, y2, x2;
1576
1577         char    tmp_val[80];
1578
1579         char    out_val[160];
1580
1581         int wid, hgt;
1582
1583         /* Get size */
1584         get_screen_size(&wid, &hgt);
1585
1586
1587         /* Start at current panel */
1588         y2 = y1 = panel_row_min;
1589         x2 = x1 = panel_col_min;
1590
1591         /* Show panels until done */
1592         while (1)
1593         {
1594                 /* Describe the location */
1595                 if ((y2 == y1) && (x2 == x1))
1596                 {
1597 #ifdef JP
1598                         strcpy(tmp_val, "真上");
1599 #else
1600                         tmp_val[0] = '\0';
1601 #endif
1602
1603                 }
1604                 else
1605                 {
1606 #ifdef JP
1607                         sprintf(tmp_val, "%s%s",
1608                                 ((y2 < y1) ? "北" : (y2 > y1) ? "南" : ""),
1609                                 ((x2 < x1) ? "西" : (x2 > x1) ? "東" : ""));
1610 #else
1611                         sprintf(tmp_val, "%s%s of",
1612                                 ((y2 < y1) ? " North" : (y2 > y1) ? " South" : ""),
1613                                 ((x2 < x1) ? " West" : (x2 > x1) ? " East" : ""));
1614 #endif
1615
1616                 }
1617
1618                 /* Prepare to ask which way to look */
1619                 sprintf(out_val, _("マップ位置 [%d(%02d),%d(%02d)] (プレイヤーの%s)  方向?", 
1620                                                "Map sector [%d(%02d),%d(%02d)], which is%s your sector.  Direction?"),
1621                         y2 / (hgt / 2), y2 % (hgt / 2),
1622                         x2 / (wid / 2), x2 % (wid / 2), tmp_val);
1623
1624                 /* Assume no direction */
1625                 dir = 0;
1626
1627                 /* Get a direction */
1628                 while (!dir)
1629                 {
1630                         char command;
1631
1632                         /* Get a command (or Cancel) */
1633                         if (!get_com(out_val, &command, TRUE)) break;
1634
1635                         /* Extract the action (if any) */
1636                         dir = get_keymap_dir(command);
1637
1638                         /* Error */
1639                         if (!dir) bell();
1640                 }
1641
1642                 /* No direction */
1643                 if (!dir) break;
1644
1645                 /* Apply the motion */
1646                 if (change_panel(ddy[dir], ddx[dir]))
1647                 {
1648                         y2 = panel_row_min;
1649                         x2 = panel_col_min;
1650                 }
1651         }
1652
1653
1654         /* Recenter the map around the player */
1655         verify_panel();
1656
1657         /* Update stuff */
1658         p_ptr->update |= (PU_MONSTERS);
1659
1660         /* Redraw map */
1661         p_ptr->redraw |= (PR_MAP);
1662
1663         /* Window stuff */
1664         p_ptr->window |= (PW_OVERHEAD | PW_DUNGEON);
1665
1666         /* Handle stuff */
1667         handle_stuff();
1668 }
1669
1670
1671
1672 /*!
1673  * @brief モンスター種族情報を特定の基準によりソートするための比較処理
1674  * Sorting hook -- Comp function -- see below
1675  * @param u モンスター種族情報の入れるポインタ
1676  * @param v 条件基準ID
1677  * @param a 比較するモンスター種族のID1
1678  * @param b 比較するモンスター種族のID2
1679  * @return 2の方が大きければTRUEを返す
1680  * We use "u" to point to array of monster indexes,
1681  * and "v" to select the type of sorting to perform on "u".
1682  */
1683 bool ang_sort_comp_hook(vptr u, vptr v, int a, int b)
1684 {
1685         u16b *who = (u16b*)(u);
1686
1687         u16b *why = (u16b*)(v);
1688
1689         int w1 = who[a];
1690         int w2 = who[b];
1691
1692         int z1, z2;
1693
1694         /* Sort by player kills */
1695         if (*why >= 4)
1696         {
1697                 /* Extract player kills */
1698                 z1 = r_info[w1].r_pkills;
1699                 z2 = r_info[w2].r_pkills;
1700
1701                 /* Compare player kills */
1702                 if (z1 < z2) return (TRUE);
1703                 if (z1 > z2) return (FALSE);
1704         }
1705
1706
1707         /* Sort by total kills */
1708         if (*why >= 3)
1709         {
1710                 /* Extract total kills */
1711                 z1 = r_info[w1].r_tkills;
1712                 z2 = r_info[w2].r_tkills;
1713
1714                 /* Compare total kills */
1715                 if (z1 < z2) return (TRUE);
1716                 if (z1 > z2) return (FALSE);
1717         }
1718
1719
1720         /* Sort by monster level */
1721         if (*why >= 2)
1722         {
1723                 /* Extract levels */
1724                 z1 = r_info[w1].level;
1725                 z2 = r_info[w2].level;
1726
1727                 /* Compare levels */
1728                 if (z1 < z2) return (TRUE);
1729                 if (z1 > z2) return (FALSE);
1730         }
1731
1732
1733         /* Sort by monster experience */
1734         if (*why >= 1)
1735         {
1736                 /* Extract experience */
1737                 z1 = r_info[w1].mexp;
1738                 z2 = r_info[w2].mexp;
1739
1740                 /* Compare experience */
1741                 if (z1 < z2) return (TRUE);
1742                 if (z1 > z2) return (FALSE);
1743         }
1744
1745
1746         /* Compare indexes */
1747         return (w1 <= w2);
1748 }
1749
1750
1751 /*!
1752  * @brief モンスター種族情報を特定の基準によりソートするためのスワップ処理
1753  * Sorting hook -- Swap function -- see below
1754  * @param u モンスター種族情報の入れるポインタ
1755  * @param v 未使用
1756  * @param a スワップするモンスター種族のID1
1757  * @param b スワップするモンスター種族のID2
1758  * @return なし
1759  * @details
1760  * We use "u" to point to array of monster indexes,
1761  * and "v" to select the type of sorting to perform.
1762  */
1763 void ang_sort_swap_hook(vptr u, vptr v, int a, int b)
1764 {
1765         u16b *who = (u16b*)(u);
1766
1767         u16b holder;
1768
1769         /* Unused */
1770         (void)v;
1771
1772         /* Swap */
1773         holder = who[a];
1774         who[a] = who[b];
1775         who[b] = holder;
1776 }
1777
1778
1779
1780 /*!
1781  * @brief モンスターの思い出を見るコマンドのメインルーチン
1782  * Identify a character, allow recall of monsters
1783  * @return なし
1784  * @details
1785  * <pre>
1786  * Several "special" responses recall "multiple" monsters:
1787  *   ^A (all monsters)
1788  *   ^U (all unique monsters)
1789  *   ^N (all non-unique monsters)
1790  *
1791  * The responses may be sorted in several ways, see below.
1792  *
1793  * Note that the player ghosts are ignored. XXX XXX XXX
1794  * </pre>
1795  */
1796 void do_cmd_query_symbol(void)
1797 {
1798         int             i, n, r_idx;
1799         char    sym, query;
1800         char    buf[128];
1801
1802         bool    all = FALSE;
1803         bool    uniq = FALSE;
1804         bool    norm = FALSE;
1805         bool    ride = FALSE;
1806         char    temp[80] = "";
1807
1808         bool    recall = FALSE;
1809
1810         u16b    why = 0;
1811         u16b    *who;
1812
1813         /* Get a character, or abort */
1814         if (!get_com(_("知りたい文字を入力して下さい(記号 or ^A全,^Uユ,^N非ユ,^R乗馬,^M名前): ", 
1815                                    "Enter character to be identified(^A:All,^U:Uniqs,^N:Non uniqs,^M:Name): "), &sym, FALSE)) return;
1816
1817         /* Find that character info, and describe it */
1818         for (i = 0; ident_info[i]; ++i)
1819         {
1820                 if (sym == ident_info[i][0]) break;
1821         }
1822
1823         /* Describe */
1824         if (sym == KTRL('A'))
1825         {
1826                 all = TRUE;
1827                 strcpy(buf, _("全モンスターのリスト", "Full monster list."));
1828         }
1829         else if (sym == KTRL('U'))
1830         {
1831                 all = uniq = TRUE;
1832                 strcpy(buf, _("ユニーク・モンスターのリスト", "Unique monster list."));
1833         }
1834         else if (sym == KTRL('N'))
1835         {
1836                 all = norm = TRUE;
1837                 strcpy(buf, _("ユニーク外モンスターのリスト", "Non-unique monster list."));
1838         }
1839         else if (sym == KTRL('R'))
1840         {
1841                 all = ride = TRUE;
1842                 strcpy(buf, _("乗馬可能モンスターのリスト", "Ridable monster list."));
1843         }
1844         /* XTRA HACK WHATSEARCH */
1845         else if (sym == KTRL('M'))
1846         {
1847                 all = TRUE;
1848                 if (!get_string(_("名前(英語の場合小文字で可)", "Enter name:"),temp, 70))
1849                 {
1850                         temp[0]=0;
1851                         return;
1852                 }
1853                 sprintf(buf, _("名前:%sにマッチ", "Monsters with a name \"%s\""),temp);
1854         }
1855         else if (ident_info[i])
1856         {
1857                 sprintf(buf, "%c - %s.", sym, ident_info[i] + 2);
1858         }
1859         else
1860         {
1861                 sprintf(buf, "%c - %s", sym, _("無効な文字", "Unknown Symbol"));
1862         }
1863
1864         /* Display the result */
1865         prt(buf, 0, 0);
1866
1867         /* Allocate the "who" array */
1868         C_MAKE(who, max_r_idx, u16b);
1869
1870         /* Collect matching monsters */
1871         for (n = 0, i = 1; i < max_r_idx; i++)
1872         {
1873                 monster_race *r_ptr = &r_info[i];
1874
1875                 /* Nothing to recall */
1876                 if (!cheat_know && !r_ptr->r_sights) continue;
1877
1878                 /* Require non-unique monsters if needed */
1879                 if (norm && (r_ptr->flags1 & (RF1_UNIQUE))) continue;
1880
1881                 /* Require unique monsters if needed */
1882                 if (uniq && !(r_ptr->flags1 & (RF1_UNIQUE))) continue;
1883
1884                 /* Require ridable monsters if needed */
1885                 if (ride && !(r_ptr->flags7 & (RF7_RIDING))) continue;
1886
1887                 /* XTRA HACK WHATSEARCH */
1888                 if (temp[0])
1889                 {
1890                   int xx;
1891                   char temp2[80];
1892   
1893                   for (xx=0; temp[xx] && xx<80; xx++)
1894                   {
1895 #ifdef JP
1896                     if (iskanji( temp[xx])) { xx++; continue; }
1897 #endif
1898                     if (isupper(temp[xx])) temp[xx]=tolower(temp[xx]);
1899                   }
1900   
1901 #ifdef JP
1902                   strcpy(temp2, r_name+r_ptr->E_name);
1903 #else
1904                   strcpy(temp2, r_name+r_ptr->name);
1905 #endif
1906                   for (xx=0; temp2[xx] && xx<80; xx++)
1907                     if (isupper(temp2[xx])) temp2[xx]=tolower(temp2[xx]);
1908   
1909 #ifdef JP
1910                   if (my_strstr(temp2, temp) || my_strstr(r_name + r_ptr->name, temp) )
1911 #else
1912                   if (my_strstr(temp2, temp))
1913 #endif
1914                           who[n++]=i;
1915                 }
1916
1917                 /* Collect "appropriate" monsters */
1918                 else if (all || (r_ptr->d_char == sym)) who[n++] = i;
1919         }
1920
1921         /* Nothing to recall */
1922         if (!n)
1923         {
1924                 /* Free the "who" array */
1925                 C_KILL(who, max_r_idx, u16b);
1926
1927                 return;
1928         }
1929
1930
1931         /* Prompt XXX XXX XXX */
1932         put_str(_("思い出を見ますか? (k:殺害順/y/n): ", "Recall details? (k/y/n): "), 0, _(36, 40));
1933
1934
1935         /* Query */
1936         query = inkey();
1937
1938         /* Restore */
1939         prt(buf, 0, 0);
1940
1941         why = 2;
1942
1943         /* Select the sort method */
1944         ang_sort_comp = ang_sort_comp_hook;
1945         ang_sort_swap = ang_sort_swap_hook;
1946
1947         /* Sort the array */
1948         ang_sort(who, &why, n);
1949
1950         /* Sort by kills (and level) */
1951         if (query == 'k')
1952         {
1953                 why = 4;
1954                 query = 'y';
1955         }
1956
1957         /* Catch "escape" */
1958         if (query != 'y')
1959         {
1960                 /* Free the "who" array */
1961                 C_KILL(who, max_r_idx, u16b);
1962
1963                 return;
1964         }
1965
1966         /* Sort if needed */
1967         if (why == 4)
1968         {
1969                 /* Select the sort method */
1970                 ang_sort_comp = ang_sort_comp_hook;
1971                 ang_sort_swap = ang_sort_swap_hook;
1972
1973                 /* Sort the array */
1974                 ang_sort(who, &why, n);
1975         }
1976
1977
1978         /* Start at the end */
1979         i = n - 1;
1980
1981         /* Scan the monster memory */
1982         while (1)
1983         {
1984                 /* Extract a race */
1985                 r_idx = who[i];
1986
1987                 /* Hack -- Auto-recall */
1988                 monster_race_track(r_idx);
1989
1990                 /* Hack -- Handle stuff */
1991                 handle_stuff();
1992
1993                 /* Interact */
1994                 while (1)
1995                 {
1996                         /* Recall */
1997                         if (recall)
1998                         {
1999                                 /* Save the screen */
2000                                 screen_save();
2001
2002                                 /* Recall on screen */
2003                                 screen_roff(who[i], 0);
2004                         }
2005
2006                         /* Hack -- Begin the prompt */
2007                         roff_top(r_idx);
2008
2009                         /* Hack -- Complete the prompt */
2010                         Term_addstr(-1, TERM_WHITE, _(" ['r'思い出, ESC]", " [(r)ecall, ESC]"));
2011
2012                         /* Command */
2013                         query = inkey();
2014
2015                         /* Unrecall */
2016                         if (recall)
2017                         {
2018                                 /* Restore */
2019                                 screen_load();
2020                         }
2021
2022                         /* Normal commands */
2023                         if (query != 'r') break;
2024
2025                         /* Toggle recall */
2026                         recall = !recall;
2027                 }
2028
2029                 /* Stop scanning */
2030                 if (query == ESCAPE) break;
2031
2032                 /* Move to "prev" monster */
2033                 if (query == '-')
2034                 {
2035                         if (++i == n)
2036                         {
2037                                 i = 0;
2038                                 if (!expand_list) break;
2039                         }
2040                 }
2041
2042                 /* Move to "next" monster */
2043                 else
2044                 {
2045                         if (i-- == 0)
2046                         {
2047                                 i = n - 1;
2048                                 if (!expand_list) break;
2049                         }
2050                 }
2051         }
2052
2053         /* Free the "who" array */
2054         C_KILL(who, max_r_idx, u16b);
2055
2056         /* Re-display the identity */
2057         prt(buf, 0, 0);
2058 }
2059
2060