OSDN Git Service

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