OSDN Git Service

52110e73bf5d530be3695ceae6dc47f02f9835f2
[jnethack/source.git] / src / invent.c
1 /* NetHack 3.6  invent.c        $NHDT-Date: 1555196229 2019/04/13 22:57:09 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.253 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /*-Copyright (c) Derek S. Ray, 2015. */
4 /* NetHack may be freely redistributed.  See license for details. */
5
6 /* JNetHack Copyright */
7 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000  */
8 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2019            */
9 /* JNetHack may be freely redistributed.  See license for details. */
10
11 #include "hack.h"
12
13 #ifndef C /* same as cmd.c */
14 #define C(c) (0x1f & (c))
15 #endif
16
17 #define NOINVSYM '#'
18 #define CONTAINED_SYM '>' /* designator for inside a container */
19 #define HANDS_SYM '-'
20
21 STATIC_DCL void FDECL(loot_classify, (Loot *, struct obj *));
22 STATIC_DCL char *FDECL(loot_xname, (struct obj *));
23 STATIC_DCL int FDECL(CFDECLSPEC sortloot_cmp, (const genericptr,
24                                                const genericptr));
25 STATIC_DCL void NDECL(reorder_invent);
26 STATIC_DCL void FDECL(noarmor, (BOOLEAN_P));
27 STATIC_DCL void FDECL(invdisp_nothing, (const char *, const char *));
28 STATIC_DCL boolean FDECL(worn_wield_only, (struct obj *));
29 STATIC_DCL boolean FDECL(only_here, (struct obj *));
30 STATIC_DCL void FDECL(compactify, (char *));
31 STATIC_DCL boolean FDECL(taking_off, (const char *));
32 STATIC_DCL boolean FDECL(putting_on, (const char *));
33 STATIC_PTR int FDECL(ckvalidcat, (struct obj *));
34 STATIC_PTR int FDECL(ckunpaid, (struct obj *));
35 STATIC_PTR char *FDECL(safeq_xprname, (struct obj *));
36 STATIC_PTR char *FDECL(safeq_shortxprname, (struct obj *));
37 STATIC_DCL char FDECL(display_pickinv, (const char *, const char *,
38                                         const char *, BOOLEAN_P, long *));
39 STATIC_DCL char FDECL(display_used_invlets, (CHAR_P));
40 STATIC_DCL boolean FDECL(this_type_only, (struct obj *));
41 STATIC_DCL void NDECL(dounpaid);
42 STATIC_DCL struct obj *FDECL(find_unpaid, (struct obj *, struct obj **));
43 STATIC_DCL void FDECL(menu_identify, (int));
44 STATIC_DCL boolean FDECL(tool_in_use, (struct obj *));
45 STATIC_DCL char FDECL(obj_to_let, (struct obj *));
46
47 static int lastinvnr = 51; /* 0 ... 51 (never saved&restored) */
48
49 /* wizards can wish for venom, which will become an invisible inventory
50  * item without this.  putting it in inv_order would mean venom would
51  * suddenly become a choice for all the inventory-class commands, which
52  * would probably cause mass confusion.  the test for inventory venom
53  * is only WIZARD and not wizard because the wizard can leave venom lying
54  * around on a bones level for normal players to find.  [Note to the
55  * confused:  'WIZARD' used to be a compile-time conditional so this was
56  * guarded by #ifdef WIZARD/.../#endif.]
57  */
58 static char venom_inv[] = { VENOM_CLASS, 0 }; /* (constant) */
59
60 /* sortloot() classification; called at most once [per sort] for each object */
61 STATIC_OVL void
62 loot_classify(sort_item, obj)
63 Loot *sort_item;
64 struct obj *obj;
65 {
66     /* we may eventually make this a settable option to always use
67        with sortloot instead of only when the 'sortpack' option isn't
68        set; it is similar to sortpack's inv_order but items most
69        likely to be picked up are moved to the front */
70     static char def_srt_order[MAXOCLASSES] = {
71         COIN_CLASS, AMULET_CLASS, RING_CLASS, WAND_CLASS, POTION_CLASS,
72         SCROLL_CLASS, SPBOOK_CLASS, GEM_CLASS, FOOD_CLASS, TOOL_CLASS,
73         WEAPON_CLASS, ARMOR_CLASS, ROCK_CLASS, BALL_CLASS, CHAIN_CLASS, 0,
74     };
75     static char armcat[8];
76     const char *classorder;
77     char *p;
78     int k, otyp = obj->otyp, oclass = obj->oclass;
79     boolean seen, discovered = objects[otyp].oc_name_known ? TRUE : FALSE;
80
81     /*
82      * For the value types assigned by this classification, sortloot()
83      * will put lower valued ones before higher valued ones.
84      */
85     if (!Blind)
86         obj->dknown = 1; /* xname(obj) does this; we want it sooner */
87     seen = obj->dknown ? TRUE : FALSE,
88     /* class order */
89     classorder = flags.sortpack ? flags.inv_order : def_srt_order;
90     p = index(classorder, oclass);
91     if (p)
92         k = 1 + (int) (p - classorder);
93     else
94         k = 1 + (int) strlen(classorder) + (oclass != VENOM_CLASS);
95     sort_item->orderclass = (xchar) k;
96     /* subclass designation; only a few classes have subclasses
97        and the non-armor ones we use are fairly arbitrary */
98     switch (oclass) {
99     case ARMOR_CLASS:
100         if (!armcat[7]) {
101             /* one-time init; we use a different order than the subclass
102                values defined by objclass.h */
103             armcat[ARM_HELM]   = 1; /* [2] */
104             armcat[ARM_GLOVES] = 2; /* [3] */
105             armcat[ARM_BOOTS]  = 3; /* [4] */
106             armcat[ARM_SHIELD] = 4; /* [1] */
107             armcat[ARM_CLOAK]  = 5; /* [5] */
108             armcat[ARM_SHIRT]  = 6; /* [6] */
109             armcat[ARM_SUIT]   = 7; /* [0] */
110             armcat[7]          = 8; /* sanity protection */
111         }
112         k = objects[otyp].oc_armcat;
113         /* oc_armcat overloads oc_subtyp which is an 'schar' so guard
114            against somebody assigning something unexpected to it */
115         if (k < 0 || k >= 7)
116             k = 7;
117         k = armcat[k];
118         break;
119     case WEAPON_CLASS:
120         /* for weapons, group by ammo (arrows, bolts), launcher (bows),
121            missile (darts, boomerangs), stackable (daggers, knives, spears),
122            'other' (swords, axes, &c), polearms */
123         k = objects[otyp].oc_skill;
124         k = (k < 0) ? ((k >= -P_CROSSBOW && k <= -P_BOW) ? 1 : 3)
125                     : ((k >= P_BOW && k <= P_CROSSBOW) ? 2
126                        : (k == P_SPEAR || k == P_DAGGER || k == P_KNIFE) ? 4
127                           : !is_pole(obj) ? 5 : 6);
128         break;
129     case TOOL_CLASS:
130         if (seen && discovered
131             && (otyp == BAG_OF_TRICKS || otyp == HORN_OF_PLENTY))
132             k = 2; /* known pseudo-container */
133         else if (Is_container(obj))
134             k = 1; /* regular container or unknown bag of tricks */
135         else
136             switch (otyp) {
137             case WOODEN_FLUTE:
138             case MAGIC_FLUTE:
139             case TOOLED_HORN:
140             case FROST_HORN:
141             case FIRE_HORN:
142             case WOODEN_HARP:
143             case MAGIC_HARP:
144             case BUGLE:
145             case LEATHER_DRUM:
146             case DRUM_OF_EARTHQUAKE:
147             case HORN_OF_PLENTY: /* not a musical instrument */
148                 k = 3; /* instrument or unknown horn of plenty */
149             default:
150                 k = 4; /* 'other' tool */
151             }
152         break;
153     case FOOD_CLASS:
154         /* [what about separating "partly eaten" within each group?] */
155         switch (otyp) {
156         case SLIME_MOLD:
157             k = 1;
158             break;
159         default:
160             /* [maybe separate one-bite foods from rations and such?] */
161             k = obj->globby ? 6 : 2;
162             break;
163         case TIN:
164             k = 3;
165             break;
166         case EGG:
167             k = 4;
168             break;
169         case CORPSE:
170             k = 5;
171             break;
172         }
173         break;
174     case GEM_CLASS:
175         /*
176          * Normally subclass takes priority over discovery status, but
177          * that would give away information for gems (assuming we'll
178          * group them as valuable gems, next glass, then gray stones,
179          * and finally rocks once they're all fully identified).
180          *
181          * Order:
182          *  1) unseen gems and glass ("gem")
183          *  2) seen but undiscovered gems and glass ("blue gem"),
184          *  3) discovered gems ("sapphire"),
185          *  4) discovered glass ("worthless pieced of blue glass"),
186          *  5) unseen gray stones and rocks ("stone"),
187          *  6) seen but undiscovered gray stones ("gray stone"),
188          *  7) discovered gray stones ("touchstone"),
189          *  8) seen rocks ("rock").
190          */
191         switch (objects[obj->otyp].oc_material) {
192         case GEMSTONE:
193             k = !seen ? 1 : !discovered ? 2 : 3;
194             break;
195         case GLASS:
196             k = !seen ? 1 : !discovered ? 2 : 4;
197             break;
198         default: /* MINERAL */
199             k = !seen ? 5 : (obj->otyp != ROCK) ? (!discovered ? 6 : 7) : 8;
200             break;
201         }
202         break;
203     default:
204         /* other classes don't have subclasses; we assign a nonzero
205            value because sortloot() uses 0 to mean 'not yet classified' */
206         k = 1; /* any non-zero would do */
207         break;
208     }
209     sort_item->subclass = (xchar) k;
210     /* discovery status */
211     k = !seen ? 1 /* unseen */
212         : (discovered || !OBJ_DESCR(objects[otyp])) ? 4
213           : (objects[otyp].oc_uname) ? 3 /* named (partially discovered) */
214             : 2; /* undiscovered */
215     sort_item->disco = (xchar) k;
216 }
217
218 /* sortloot() formatting routine; for alphabetizing, not shown to user */
219 STATIC_OVL char *
220 loot_xname(obj)
221 struct obj *obj;
222 {
223     struct obj saveo;
224     boolean save_debug;
225     char *res, *save_oname;
226
227     /*
228      * Deal with things that xname() includes as a prefix.  We don't
229      * want such because they change alphabetical ordering.  First,
230      * remember 'obj's current settings.
231      */
232     saveo.odiluted = obj->odiluted;
233     saveo.blessed = obj->blessed, saveo.cursed = obj->cursed;
234     saveo.spe = obj->spe;
235     saveo.owt = obj->owt;
236     save_oname = has_oname(obj) ? ONAME(obj) : 0;
237     save_debug = flags.debug;
238     /* suppress "diluted" for potions and "holy/unholy" for water;
239        sortloot() will deal with them using other criteria than name */
240     if (obj->oclass == POTION_CLASS) {
241         obj->odiluted = 0;
242         if (obj->otyp == POT_WATER)
243             obj->blessed = 0, obj->cursed = 0;
244     }
245     /* make "wet towel" and "moist towel" format as "towel" so that all
246        three group together */
247     if (obj->otyp == TOWEL)
248         obj->spe = 0;
249     /* group "<size> glob of <foo>" by <foo> rather than by <size> */
250     if (obj->globby)
251         obj->owt = 200; /* 200: weight of combined glob from ten creatures
252                            (five or fewer is "small", more than fifteen is
253                            "large", in between has no prefix) */
254     /* suppress user-assigned name */
255     if (save_oname && !obj->oartifact)
256         ONAME(obj) = 0;
257     /* avoid wizard mode formatting variations */
258     if (wizard) { /* flags.debug */
259         /* paranoia:  before toggling off wizard mode, guard against a
260            panic in xname() producing a normal mode panic save file */
261         program_state.something_worth_saving = 0;
262         flags.debug = FALSE;
263     }
264
265     res = cxname_singular(obj);
266
267     if (save_debug) {
268         flags.debug = TRUE;
269         program_state.something_worth_saving = 1;
270     }
271     /* restore the object */
272     if (obj->oclass == POTION_CLASS) {
273         obj->odiluted = saveo.odiluted;
274         if (obj->otyp == POT_WATER)
275             obj->blessed = saveo.blessed, obj->cursed = saveo.cursed;
276     }
277     if (obj->otyp == TOWEL) {
278         obj->spe = saveo.spe;
279         /* give "towel" a suffix that will force wet ones to come first,
280            moist ones next, and dry ones last regardless of whether
281            they've been flagged as having spe known */
282         Strcat(res, is_wet_towel(obj) ? ((obj->spe >= 3) ? "x" : "y") : "z");
283     }
284     if (obj->globby) {
285         obj->owt = saveo.owt;
286         /* we've suppressed the size prefix (above); there normally won't
287            be more than one of a given creature type because they coalesce,
288            but globs with different bless/curse state won't merge so it is
289            feasible to have multiple at the same location; add a suffix to
290            get such sorted by size (small first) */
291         Strcat(res, (obj->owt <= 100) ? "a"
292                     : (obj->owt <= 300) ? "b"
293                       : (obj->owt <= 500) ? "c"
294                         : "d");
295     }
296     if (save_oname && !obj->oartifact)
297         ONAME(obj) = save_oname;
298
299     return res;
300 }
301
302 /* set by sortloot() for use by sortloot_cmp(); reset by sortloot when done */
303 static unsigned sortlootmode = 0;
304
305 /* qsort comparison routine for sortloot() */
306 STATIC_OVL int CFDECLSPEC
307 sortloot_cmp(vptr1, vptr2)
308 const genericptr vptr1;
309 const genericptr vptr2;
310 {
311     struct sortloot_item *sli1 = (struct sortloot_item *) vptr1,
312                          *sli2 = (struct sortloot_item *) vptr2;
313     struct obj *obj1 = sli1->obj,
314                *obj2 = sli2->obj;
315     char *nam1, *nam2;
316     int val1, val2, c, namcmp;
317
318     /* order by object class unless we're doing by-invlet without sortpack */
319     if ((sortlootmode & (SORTLOOT_PACK | SORTLOOT_INVLET))
320         != SORTLOOT_INVLET) {
321         /* Classify each object at most once no matter how many
322            comparisons it is involved in. */
323         if (!sli1->orderclass)
324             loot_classify(sli1, obj1);
325         if (!sli2->orderclass)
326             loot_classify(sli2, obj2);
327
328         /* Sort by class. */
329         val1 = sli1->orderclass;
330         val2 = sli2->orderclass;
331         if (val1 != val2)
332             return (int) (val1 - val2);
333
334         /* skip sub-classes when ordering by sortpack+invlet */
335         if ((sortlootmode & SORTLOOT_INVLET) == 0) {
336             /* Class matches; sort by subclass. */
337             val1 = sli1->subclass;
338             val2 = sli2->subclass;
339             if (val1 != val2)
340                 return val1 - val2;
341
342             /* Class and subclass match; sort by discovery status:
343              * first unseen, then seen but not named or discovered,
344              * then named, lastly discovered.
345              * 1) potion
346              * 2) pink potion
347              * 3) dark green potion called confusion
348              * 4) potion of healing
349              * Multiple entries within each group will be put into
350              * alphabetical order below.
351              */
352             val1 = sli1->disco;
353             val2 = sli2->disco;
354             if (val1 != val2)
355                 return val1 - val2;
356         }
357     }
358
359     /* order by assigned inventory letter */
360     if ((sortlootmode & SORTLOOT_INVLET) != 0) {
361         c = obj1->invlet;
362         val1 = ('a' <= c && c <= 'z') ? (c - 'a' + 2)
363                : ('A' <= c && c <= 'Z') ? (c - 'A' + 2 + 26)
364                  : (c == '$') ? 1
365                    : (c == '#') ? 1 + 52 + 1
366                      : 1 + 52 + 1 + 1; /* none of the above */
367         c = obj2->invlet;
368         val2 = ('a' <= c && c <= 'z') ? (c - 'a' + 2)
369                : ('A' <= c && c <= 'Z') ? (c - 'A' + 2 + 26)
370                  : (c == '$') ? 1
371                    : (c == '#') ? 1 + 52 + 1
372                      : 1 + 52 + 1 + 1; /* none of the above */
373         if (val1 != val2)
374             return val1 - val2;
375     }
376
377     if ((sortlootmode & SORTLOOT_LOOT) == 0)
378         goto tiebreak;
379
380     /*
381      * Sort object names in lexicographical order, ignoring quantity.
382      *
383      * Each obj gets formatted at most once (per sort) no matter how many
384      * comparisons it gets subjected to.
385      */
386     nam1 = sli1->str;
387     if (!nam1)
388         nam1 = sli1->str = dupstr(loot_xname(obj1));
389     nam2 = sli2->str;
390     if (!nam2)
391         nam2 = sli2->str = dupstr(loot_xname(obj2));
392     if ((namcmp = strcmpi(nam1, nam2)) != 0)
393         return namcmp;
394
395     /* Sort by BUCX. */
396     val1 = obj1->bknown ? (obj1->blessed ? 3 : !obj1->cursed ? 2 : 1) : 0;
397     val2 = obj2->bknown ? (obj2->blessed ? 3 : !obj2->cursed ? 2 : 1) : 0;
398     if (val1 != val2)
399         return val2 - val1; /* bigger is better */
400
401     /* Sort by greasing.  This will put the objects in degreasing order. */
402     val1 = obj1->greased;
403     val2 = obj2->greased;
404     if (val1 != val2)
405         return val2 - val1; /* bigger is better */
406
407     /* Sort by erosion.  The effective amount is what matters. */
408     val1 = greatest_erosion(obj1);
409     val2 = greatest_erosion(obj2);
410     if (val1 != val2)
411         return val1 - val2; /* bigger is WORSE */
412
413     /* Sort by erodeproofing.  Map known-invulnerable to 1, and both
414        known-vulnerable and unknown-vulnerability to 0, because that's
415        how they're displayed. */
416     val1 = obj1->rknown && obj1->oerodeproof;
417     val2 = obj2->rknown && obj2->oerodeproof;
418     if (val1 != val2)
419         return val2 - val1; /* bigger is better */
420
421     /* Sort by enchantment.  Map unknown to -1000, which is comfortably
422        below the range of obj->spe.  oc_uses_known means that obj->known
423        matters, which usually indirectly means that obj->spe is relevant.
424        Lots of objects use obj->spe for some other purpose (see obj.h). */
425     if (objects[obj1->otyp].oc_uses_known
426         /* exclude eggs (laid by you) and tins (homemade, pureed, &c) */
427         && obj1->oclass != FOOD_CLASS) {
428         val1 = obj1->known ? obj1->spe : -1000;
429         val2 = obj2->known ? obj2->spe : -1000;
430         if (val1 != val2)
431             return val2 - val1; /* bigger is better */
432     }
433
434  tiebreak:
435     /* They're identical, as far as we're concerned.  We want
436        to force a deterministic order, and do so by producing a
437        stable sort: maintain the original order of equal items. */
438     return (sli1->indx - sli2->indx);
439 }
440
441 /*
442  * sortloot() - the story so far...
443  *
444  *      The original implementation constructed and returned an array
445  *      of pointers to objects in the requested order.  Callers had to
446  *      count the number of objects, allocate the array, pass one
447  *      object at a time to the routine which populates it, traverse
448  *      the objects via stepping through the array, then free the
449  *      array.  The ordering process used a basic insertion sort which
450  *      is fine for short lists but inefficient for long ones.
451  *
452  *      3.6.0 (and continuing with 3.6.1) changed all that so that
453  *      sortloot was self-contained as far as callers were concerned.
454  *      It reordered the linked list into the requested order and then
455  *      normal list traversal was used to process it.  It also switched
456  *      to qsort() on the assumption that the C library implementation
457  *      put some effort into sorting efficiently.  It also checked
458  *      whether the list was already sorted as it got ready to do the
459  *      sorting, so re-examining inventory or a pile of objects without
460  *      having changed anything would gobble up less CPU than a full
461  *      sort.  But it had at least two problems (aside from the ordinary
462  *      complement of bugs):
463  *      1) some players wanted to get the original order back when they
464  *      changed the 'sortloot' option back to 'none', but the list
465  *      reordering made that infeasible;
466  *      2) object identification giving the 'ID whole pack' result
467  *      would call makeknown() on each newly ID'd object, that would
468  *      call update_inventory() to update the persistent inventory
469  *      window if one existed, the interface would call the inventory
470  *      display routine which would call sortloot() which might change
471  *      the order of the list being traversed by the identify code,
472  *      possibly skipping the ID of some objects.  That could have been
473  *      avoided by suppressing 'perm_invent' during identification
474  *      (fragile) or by avoiding sortloot() during inventory display
475  *      (more robust).
476  *
477  *      3.6.2 reverts to the temporary array of ordered obj pointers
478  *      but has sortloot() do the counting and allocation.  Callers
479  *      need to use array traversal instead of linked list traversal
480  *      and need to free the temporary array when done.  And the
481  *      array contains 'struct sortloot_item' (aka 'Loot') entries
482  *      instead of simple 'struct obj *' entries.
483  */
484 Loot *
485 sortloot(olist, mode, by_nexthere, filterfunc)
486 struct obj **olist; /* previous version might have changed *olist, we don't */
487 unsigned mode; /* flags for sortloot_cmp() */
488 boolean by_nexthere; /* T: traverse via obj->nexthere, F: via obj->nobj */
489 boolean FDECL((*filterfunc), (OBJ_P));
490 {
491     Loot *sliarray;
492     struct obj *o;
493     unsigned n, i;
494     boolean augment_filter;
495
496     for (n = 0, o = *olist; o; o = by_nexthere ? o->nexthere : o->nobj)
497         ++n;
498     /* note: if there is a filter function, this might overallocate */
499     sliarray = (Loot *) alloc((n + 1) * sizeof *sliarray);
500
501     /* the 'keep cockatrice corpses' flag is overloaded with sort mode */
502     augment_filter = (mode & SORTLOOT_PETRIFY) ? TRUE : FALSE;
503     mode &= ~SORTLOOT_PETRIFY; /* remove flag, leaving mode */
504     /* populate aliarray[0..n-1] */
505     for (i = 0, o = *olist; o; o = by_nexthere ? o->nexthere : o->nobj) {
506         if (filterfunc && !(*filterfunc)(o)
507             /* caller may be asking us to override filterfunc (in order
508                to do a cockatrice corpse touch check during pickup even
509                if/when the filter rejects food class) */
510             && (!augment_filter || o->otyp != CORPSE
511                 || !touch_petrifies(&mons[o->corpsenm])))
512             continue;
513         sliarray[i].obj = o, sliarray[i].indx = (int) i;
514         sliarray[i].str = (char *) 0;
515         sliarray[i].orderclass = sliarray[i].subclass = sliarray[i].disco = 0;
516         ++i;
517     }
518     n = i;
519     /* add a terminator so that we don't have to pass 'n' back to caller */
520     sliarray[n].obj = (struct obj *) 0, sliarray[n].indx = -1;
521     sliarray[n].str = (char *) 0;
522     sliarray[n].orderclass = sliarray[n].subclass = sliarray[n].disco = 0;
523
524     /* do the sort; if no sorting is requested, we'll just return
525        a sortloot_item array reflecting the current ordering */
526     if (mode && n > 1) {
527         sortlootmode = mode; /* extra input for sortloot_cmp() */
528         qsort((genericptr_t) sliarray, n, sizeof *sliarray, sortloot_cmp);
529         sortlootmode = 0; /* reset static mode flags */
530         /* if sortloot_cmp formatted any objects, discard their strings now */
531         for (i = 0; i < n; ++i)
532             if (sliarray[i].str)
533                 free((genericptr_t) sliarray[i].str), sliarray[i].str = 0;
534     }
535     return sliarray;
536 }
537
538 /* sortloot() callers should use this to free up memory it allocates */
539 void
540 unsortloot(loot_array_p)
541 Loot **loot_array_p;
542 {
543     if (*loot_array_p)
544         free((genericptr_t) *loot_array_p), *loot_array_p = (Loot *) 0;
545 }
546
547 #if 0 /* 3.6.0 'revamp' */
548 void
549 sortloot(olist, mode, by_nexthere)
550 struct obj **olist;
551 unsigned mode; /* flags for sortloot_cmp() */
552 boolean by_nexthere; /* T: traverse via obj->nexthere, F: via obj->nobj */
553 {
554     struct sortloot_item *sliarray, osli, nsli;
555     struct obj *o, **nxt_p;
556     unsigned n, i;
557     boolean already_sorted = TRUE;
558
559     sortlootmode = mode; /* extra input for sortloot_cmp() */
560     for (n = osli.indx = 0, osli.obj = *olist; (o = osli.obj) != 0;
561          osli = nsli) {
562         nsli.obj = by_nexthere ? o->nexthere : o->nobj;
563         nsli.indx = (int) ++n;
564         if (nsli.obj && already_sorted
565             && sortloot_cmp((genericptr_t) &osli, (genericptr_t) &nsli) > 0)
566             already_sorted = FALSE;
567     }
568     if (n > 1 && !already_sorted) {
569         sliarray = (struct sortloot_item *) alloc(n * sizeof *sliarray);
570         for (i = 0, o = *olist; o;
571              ++i, o = by_nexthere ? o->nexthere : o->nobj)
572             sliarray[i].obj = o, sliarray[i].indx = (int) i;
573
574         qsort((genericptr_t) sliarray, n, sizeof *sliarray, sortloot_cmp);
575         for (i = 0; i < n; ++i) {
576             o = sliarray[i].obj;
577             nxt_p = by_nexthere ? &(o->nexthere) : &(o->nobj);
578             *nxt_p = (i < n - 1) ? sliarray[i + 1].obj : (struct obj *) 0;
579         }
580         *olist = sliarray[0].obj;
581         free((genericptr_t) sliarray);
582     }
583     sortlootmode = 0;
584 }
585 #endif /*0*/
586
587 void
588 assigninvlet(otmp)
589 register struct obj *otmp;
590 {
591     boolean inuse[52];
592     register int i;
593     register struct obj *obj;
594
595     /* there should be at most one of these in inventory... */
596     if (otmp->oclass == COIN_CLASS) {
597         otmp->invlet = GOLD_SYM;
598         return;
599     }
600
601     for (i = 0; i < 52; i++)
602         inuse[i] = FALSE;
603     for (obj = invent; obj; obj = obj->nobj)
604         if (obj != otmp) {
605             i = obj->invlet;
606             if ('a' <= i && i <= 'z')
607                 inuse[i - 'a'] = TRUE;
608             else if ('A' <= i && i <= 'Z')
609                 inuse[i - 'A' + 26] = TRUE;
610             if (i == otmp->invlet)
611                 otmp->invlet = 0;
612         }
613     if ((i = otmp->invlet)
614         && (('a' <= i && i <= 'z') || ('A' <= i && i <= 'Z')))
615         return;
616     for (i = lastinvnr + 1; i != lastinvnr; i++) {
617         if (i == 52) {
618             i = -1;
619             continue;
620         }
621         if (!inuse[i])
622             break;
623     }
624     otmp->invlet =
625         (inuse[i] ? NOINVSYM : (i < 26) ? ('a' + i) : ('A' + i - 26));
626     lastinvnr = i;
627 }
628
629 /* note: assumes ASCII; toggling a bit puts lowercase in front of uppercase */
630 #define inv_rank(o) ((o)->invlet ^ 040)
631
632 /* sort the inventory; used by addinv() and doorganize() */
633 STATIC_OVL void
634 reorder_invent()
635 {
636     struct obj *otmp, *prev, *next;
637     boolean need_more_sorting;
638
639     do {
640         /*
641          * We expect at most one item to be out of order, so this
642          * isn't nearly as inefficient as it may first appear.
643          */
644         need_more_sorting = FALSE;
645         for (otmp = invent, prev = 0; otmp;) {
646             next = otmp->nobj;
647             if (next && inv_rank(next) < inv_rank(otmp)) {
648                 need_more_sorting = TRUE;
649                 if (prev)
650                     prev->nobj = next;
651                 else
652                     invent = next;
653                 otmp->nobj = next->nobj;
654                 next->nobj = otmp;
655                 prev = next;
656             } else {
657                 prev = otmp;
658                 otmp = next;
659             }
660         }
661     } while (need_more_sorting);
662 }
663
664 #undef inv_rank
665
666 /* scan a list of objects to see whether another object will merge with
667    one of them; used in pickup.c when all 52 inventory slots are in use,
668    to figure out whether another object could still be picked up */
669 struct obj *
670 merge_choice(objlist, obj)
671 struct obj *objlist, *obj;
672 {
673     struct monst *shkp;
674     int save_nocharge;
675
676     if (obj->otyp == SCR_SCARE_MONSTER) /* punt on these */
677         return (struct obj *) 0;
678     /* if this is an item on the shop floor, the attributes it will
679        have when carried are different from what they are now; prevent
680        that from eliciting an incorrect result from mergable() */
681     save_nocharge = obj->no_charge;
682     if (objlist == invent && obj->where == OBJ_FLOOR
683         && (shkp = shop_keeper(inside_shop(obj->ox, obj->oy))) != 0) {
684         if (obj->no_charge)
685             obj->no_charge = 0;
686         /* A billable object won't have its `unpaid' bit set, so would
687            erroneously seem to be a candidate to merge with a similar
688            ordinary object.  That's no good, because once it's really
689            picked up, it won't merge after all.  It might merge with
690            another unpaid object, but we can't check that here (depends
691            too much upon shk's bill) and if it doesn't merge it would
692            end up in the '#' overflow inventory slot, so reject it now. */
693         else if (inhishop(shkp))
694             return (struct obj *) 0;
695     }
696     while (objlist) {
697         if (mergable(objlist, obj))
698             break;
699         objlist = objlist->nobj;
700     }
701     obj->no_charge = save_nocharge;
702     return objlist;
703 }
704
705 /* merge obj with otmp and delete obj if types agree */
706 int
707 merged(potmp, pobj)
708 struct obj **potmp, **pobj;
709 {
710     register struct obj *otmp = *potmp, *obj = *pobj;
711
712     if (mergable(otmp, obj)) {
713         /* Approximate age: we do it this way because if we were to
714          * do it "accurately" (merge only when ages are identical)
715          * we'd wind up never merging any corpses.
716          * otmp->age = otmp->age*(1-proportion) + obj->age*proportion;
717          *
718          * Don't do the age manipulation if lit.  We would need
719          * to stop the burn on both items, then merge the age,
720          * then restart the burn.  Glob ages are averaged in the
721          * absorb routine, which uses weight rather than quantity
722          * to adjust for proportion (glob quantity is always 1).
723          */
724         if (!obj->lamplit && !obj->globby)
725             otmp->age = ((otmp->age * otmp->quan) + (obj->age * obj->quan))
726                         / (otmp->quan + obj->quan);
727
728         otmp->quan += obj->quan;
729         /* temporary special case for gold objects!!!! */
730         if (otmp->oclass == COIN_CLASS)
731             otmp->owt = weight(otmp), otmp->bknown = 0;
732         /* and puddings!!!1!!one! */
733         else if (!Is_pudding(otmp))
734             otmp->owt += obj->owt;
735         if (!has_oname(otmp) && has_oname(obj))
736             otmp = *potmp = oname(otmp, ONAME(obj));
737         obj_extract_self(obj);
738
739         /* really should merge the timeouts */
740         if (obj->lamplit)
741             obj_merge_light_sources(obj, otmp);
742         if (obj->timed)
743             obj_stop_timers(obj); /* follows lights */
744
745         /* fixup for `#adjust' merging wielded darts, daggers, &c */
746         if (obj->owornmask && carried(otmp)) {
747             long wmask = otmp->owornmask | obj->owornmask;
748
749             /* Both the items might be worn in competing slots;
750                merger preference (regardless of which is which):
751              primary weapon + alternate weapon -> primary weapon;
752              primary weapon + quiver -> primary weapon;
753              alternate weapon + quiver -> alternate weapon.
754                (Prior to 3.3.0, it was not possible for the two
755                stacks to be worn in different slots and `obj'
756                didn't need to be unworn when merging.) */
757             if (wmask & W_WEP)
758                 wmask = W_WEP;
759             else if (wmask & W_SWAPWEP)
760                 wmask = W_SWAPWEP;
761             else if (wmask & W_QUIVER)
762                 wmask = W_QUIVER;
763             else {
764                 impossible("merging strangely worn items (%lx)", wmask);
765                 wmask = otmp->owornmask;
766             }
767             if ((otmp->owornmask & ~wmask) != 0L)
768                 setnotworn(otmp);
769             setworn(otmp, wmask);
770             setnotworn(obj);
771 #if 0
772         /* (this should not be necessary, since items
773             already in a monster's inventory don't ever get
774             merged into other objects [only vice versa]) */
775         } else if (obj->owornmask && mcarried(otmp)) {
776             if (obj == MON_WEP(otmp->ocarry)) {
777                 MON_WEP(otmp->ocarry) = otmp;
778                 otmp->owornmask = W_WEP;
779             }
780 #endif /*0*/
781         }
782
783         /* handle puddings a bit differently; absorption will free the
784            other object automatically so we can just return out from here */
785         if (obj->globby) {
786             pudding_merge_message(otmp, obj);
787             obj_absorb(potmp, pobj);
788             return 1;
789         }
790
791         obfree(obj, otmp); /* free(obj), bill->otmp */
792         return 1;
793     }
794     return 0;
795 }
796
797 /*
798  * Adjust hero intrinsics as if this object was being added to the hero's
799  * inventory.  Called _before_ the object has been added to the hero's
800  * inventory.
801  *
802  * This is called when adding objects to the hero's inventory normally (via
803  * addinv) or when an object in the hero's inventory has been polymorphed
804  * in-place.
805  *
806  * It may be valid to merge this code with with addinv_core2().
807  */
808 void
809 addinv_core1(obj)
810 struct obj *obj;
811 {
812     if (obj->oclass == COIN_CLASS) {
813         context.botl = 1;
814     } else if (obj->otyp == AMULET_OF_YENDOR) {
815         if (u.uhave.amulet)
816             impossible("already have amulet?");
817         u.uhave.amulet = 1;
818         u.uachieve.amulet = 1;
819     } else if (obj->otyp == CANDELABRUM_OF_INVOCATION) {
820         if (u.uhave.menorah)
821             impossible("already have candelabrum?");
822         u.uhave.menorah = 1;
823         u.uachieve.menorah = 1;
824     } else if (obj->otyp == BELL_OF_OPENING) {
825         if (u.uhave.bell)
826             impossible("already have silver bell?");
827         u.uhave.bell = 1;
828         u.uachieve.bell = 1;
829     } else if (obj->otyp == SPE_BOOK_OF_THE_DEAD) {
830         if (u.uhave.book)
831             impossible("already have the book?");
832         u.uhave.book = 1;
833         u.uachieve.book = 1;
834     } else if (obj->oartifact) {
835         if (is_quest_artifact(obj)) {
836             if (u.uhave.questart)
837                 impossible("already have quest artifact?");
838             u.uhave.questart = 1;
839             artitouch(obj);
840         }
841         set_artifact_intrinsic(obj, 1, W_ART);
842     }
843
844     /* "special achievements" aren't discoverable during play, they
845        end up being recorded in XLOGFILE at end of game, nowhere else;
846        record_achieve_special overloads corpsenm which is ordinarily
847        initialized to NON_PM (-1) rather than to 0; any special prize
848        must never be a corpse, egg, tin, figurine, or statue because
849        their use of obj->corpsenm for monster type would conflict,
850        nor be a leash (corpsenm overloaded for m_id of leashed
851        monster) or a novel (corpsenm overloaded for novel index) */
852     if (is_mines_prize(obj)) {
853         u.uachieve.mines_luckstone = 1;
854         obj->record_achieve_special = NON_PM;
855         obj->nomerge = 0;
856     } else if (is_soko_prize(obj)) {
857         u.uachieve.finish_sokoban = 1;
858         obj->record_achieve_special = NON_PM;
859         obj->nomerge = 0;
860     }
861 }
862
863 /*
864  * Adjust hero intrinsics as if this object was being added to the hero's
865  * inventory.  Called _after_ the object has been added to the hero's
866  * inventory.
867  *
868  * This is called when adding objects to the hero's inventory normally (via
869  * addinv) or when an object in the hero's inventory has been polymorphed
870  * in-place.
871  */
872 void
873 addinv_core2(obj)
874 struct obj *obj;
875 {
876     if (confers_luck(obj)) {
877         /* new luckstone must be in inventory by this point
878          * for correct calculation */
879         set_moreluck();
880     }
881 }
882
883 /*
884  * Add obj to the hero's inventory.  Make sure the object is "free".
885  * Adjust hero attributes as necessary.
886  */
887 struct obj *
888 addinv(obj)
889 struct obj *obj;
890 {
891     struct obj *otmp, *prev;
892     int saved_otyp = (int) obj->otyp; /* for panic */
893     boolean obj_was_thrown;
894
895     if (obj->where != OBJ_FREE)
896         panic("addinv: obj not free");
897     /* normally addtobill() clears no_charge when items in a shop are
898        picked up, but won't do so if the shop has become untended */
899     obj->no_charge = 0; /* should not be set in hero's invent */
900     if (Has_contents(obj))
901         picked_container(obj); /* clear no_charge */
902     obj_was_thrown = obj->was_thrown;
903     obj->was_thrown = 0;       /* not meaningful for invent */
904
905     addinv_core1(obj);
906
907     /* merge with quiver in preference to any other inventory slot
908        in case quiver and wielded weapon are both eligible; adding
909        extra to quivered stack is more useful than to wielded one */
910     if (uquiver && merged(&uquiver, &obj)) {
911         obj = uquiver;
912         if (!obj)
913             panic("addinv: null obj after quiver merge otyp=%d", saved_otyp);
914         goto added;
915     }
916     /* merge if possible; find end of chain in the process */
917     for (prev = 0, otmp = invent; otmp; prev = otmp, otmp = otmp->nobj)
918         if (merged(&otmp, &obj)) {
919             obj = otmp;
920             if (!obj)
921                 panic("addinv: null obj after merge otyp=%d", saved_otyp);
922             goto added;
923         }
924     /* didn't merge, so insert into chain */
925     assigninvlet(obj);
926     if (flags.invlet_constant || !prev) {
927         obj->nobj = invent; /* insert at beginning */
928         invent = obj;
929         if (flags.invlet_constant)
930             reorder_invent();
931     } else {
932         prev->nobj = obj; /* insert at end */
933         obj->nobj = 0;
934     }
935     obj->where = OBJ_INVENT;
936
937     /* fill empty quiver if obj was thrown */
938     if (flags.pickup_thrown && !uquiver && obj_was_thrown
939         /* if Mjollnir is thrown and fails to return, we want to
940            auto-pick it when we move to its spot, but not into quiver;
941            aklyses behave like Mjollnir when thrown while wielded, but
942            we lack sufficient information here make them exceptions */
943         && obj->oartifact != ART_MJOLLNIR
944         && (throwing_weapon(obj) || is_ammo(obj)))
945         setuqwep(obj);
946  added:
947     addinv_core2(obj);
948     carry_obj_effects(obj); /* carrying affects the obj */
949     update_inventory();
950     return obj;
951 }
952
953 /*
954  * Some objects are affected by being carried.
955  * Make those adjustments here. Called _after_ the object
956  * has been added to the hero's or monster's inventory,
957  * and after hero's intrinsics have been updated.
958  */
959 void
960 carry_obj_effects(obj)
961 struct obj *obj;
962 {
963     /* Cursed figurines can spontaneously transform when carried. */
964     if (obj->otyp == FIGURINE) {
965         if (obj->cursed && obj->corpsenm != NON_PM
966             && !dead_species(obj->corpsenm, TRUE)) {
967             attach_fig_transform_timeout(obj);
968         }
969     }
970 }
971
972 /* Add an item to the inventory unless we're fumbling or it refuses to be
973  * held (via touch_artifact), and give a message.
974  * If there aren't any free inventory slots, we'll drop it instead.
975  * If both success and failure messages are NULL, then we're just doing the
976  * fumbling/slot-limit checking for a silent grab.  In any case,
977  * touch_artifact will print its own messages if they are warranted.
978  */
979 struct obj *
980 hold_another_object(obj, drop_fmt, drop_arg, hold_msg)
981 struct obj *obj;
982 const char *drop_fmt, *drop_arg, *hold_msg;
983 {
984     char buf[BUFSZ];
985
986     if (!Blind)
987         obj->dknown = 1; /* maximize mergibility */
988     if (obj->oartifact) {
989         /* place_object may change these */
990         boolean crysknife = (obj->otyp == CRYSKNIFE);
991         int oerode = obj->oerodeproof;
992         boolean wasUpolyd = Upolyd;
993
994         /* in case touching this object turns out to be fatal */
995         place_object(obj, u.ux, u.uy);
996
997         if (!touch_artifact(obj, &youmonst)) {
998             obj_extract_self(obj); /* remove it from the floor */
999             dropy(obj);            /* now put it back again :-) */
1000             return obj;
1001         } else if (wasUpolyd && !Upolyd) {
1002             /* loose your grip if you revert your form */
1003             if (drop_fmt)
1004                 pline(drop_fmt, drop_arg);
1005             obj_extract_self(obj);
1006             dropy(obj);
1007             return obj;
1008         }
1009         obj_extract_self(obj);
1010         if (crysknife) {
1011             obj->otyp = CRYSKNIFE;
1012             obj->oerodeproof = oerode;
1013         }
1014     }
1015     if (Fumbling) {
1016         obj->nomerge = 1;
1017         obj = addinv(obj); /* dropping expects obj to be in invent */
1018         goto drop_it;
1019     } else {
1020         long oquan = obj->quan;
1021         int prev_encumbr = near_capacity(); /* before addinv() */
1022
1023         /* encumbrance only matters if it would now become worse
1024            than max( current_value, stressed ) */
1025         if (prev_encumbr < MOD_ENCUMBER)
1026             prev_encumbr = MOD_ENCUMBER;
1027         /* addinv() may redraw the entire inventory, overwriting
1028            drop_arg when it comes from something like doname() */
1029         if (drop_arg)
1030             drop_arg = strcpy(buf, drop_arg);
1031
1032         obj = addinv(obj);
1033         if (inv_cnt(FALSE) > 52 || ((obj->otyp != LOADSTONE || !obj->cursed)
1034                                     && near_capacity() > prev_encumbr)) {
1035             /* undo any merge which took place */
1036             if (obj->quan > oquan)
1037                 obj = splitobj(obj, oquan);
1038             goto drop_it;
1039         } else {
1040             if (flags.autoquiver && !uquiver && !obj->owornmask
1041                 && (is_missile(obj) || ammo_and_launcher(obj, uwep)
1042                     || ammo_and_launcher(obj, uswapwep)))
1043                 setuqwep(obj);
1044             if (hold_msg || drop_fmt)
1045                 prinv(hold_msg, obj, oquan);
1046         }
1047     }
1048     return obj;
1049
1050  drop_it:
1051     if (drop_fmt)
1052         pline(drop_fmt, drop_arg);
1053     obj->nomerge = 0;
1054     if (can_reach_floor(TRUE)) {
1055         dropx(obj);
1056     } else {
1057         freeinv(obj);
1058         hitfloor(obj, FALSE);
1059     }
1060     return (struct obj *) 0; /* might be gone */
1061 }
1062
1063 /* useup() all of an item regardless of its quantity */
1064 void
1065 useupall(obj)
1066 struct obj *obj;
1067 {
1068     setnotworn(obj);
1069     freeinv(obj);
1070     obfree(obj, (struct obj *) 0); /* deletes contents also */
1071 }
1072
1073 void
1074 useup(obj)
1075 register struct obj *obj;
1076 {
1077     /* Note:  This works correctly for containers because they (containers)
1078        don't merge. */
1079     if (obj->quan > 1L) {
1080         obj->in_use = FALSE; /* no longer in use */
1081         obj->quan--;
1082         obj->owt = weight(obj);
1083         update_inventory();
1084     } else {
1085         useupall(obj);
1086     }
1087 }
1088
1089 /* use one charge from an item and possibly incur shop debt for it */
1090 void
1091 consume_obj_charge(obj, maybe_unpaid)
1092 struct obj *obj;
1093 boolean maybe_unpaid; /* false if caller handles shop billing */
1094 {
1095     if (maybe_unpaid)
1096         check_unpaid(obj);
1097     obj->spe -= 1;
1098     if (obj->known)
1099         update_inventory();
1100 }
1101
1102 /*
1103  * Adjust hero's attributes as if this object was being removed from the
1104  * hero's inventory.  This should only be called from freeinv() and
1105  * where we are polymorphing an object already in the hero's inventory.
1106  *
1107  * Should think of a better name...
1108  */
1109 void
1110 freeinv_core(obj)
1111 struct obj *obj;
1112 {
1113     if (obj->oclass == COIN_CLASS) {
1114         context.botl = 1;
1115         return;
1116     } else if (obj->otyp == AMULET_OF_YENDOR) {
1117         if (!u.uhave.amulet)
1118             impossible("don't have amulet?");
1119         u.uhave.amulet = 0;
1120     } else if (obj->otyp == CANDELABRUM_OF_INVOCATION) {
1121         if (!u.uhave.menorah)
1122             impossible("don't have candelabrum?");
1123         u.uhave.menorah = 0;
1124     } else if (obj->otyp == BELL_OF_OPENING) {
1125         if (!u.uhave.bell)
1126             impossible("don't have silver bell?");
1127         u.uhave.bell = 0;
1128     } else if (obj->otyp == SPE_BOOK_OF_THE_DEAD) {
1129         if (!u.uhave.book)
1130             impossible("don't have the book?");
1131         u.uhave.book = 0;
1132     } else if (obj->oartifact) {
1133         if (is_quest_artifact(obj)) {
1134             if (!u.uhave.questart)
1135                 impossible("don't have quest artifact?");
1136             u.uhave.questart = 0;
1137         }
1138         set_artifact_intrinsic(obj, 0, W_ART);
1139     }
1140
1141     if (obj->otyp == LOADSTONE) {
1142         curse(obj);
1143     } else if (confers_luck(obj)) {
1144         set_moreluck();
1145         context.botl = 1;
1146     } else if (obj->otyp == FIGURINE && obj->timed) {
1147         (void) stop_timer(FIG_TRANSFORM, obj_to_any(obj));
1148     }
1149 }
1150
1151 /* remove an object from the hero's inventory */
1152 void
1153 freeinv(obj)
1154 register struct obj *obj;
1155 {
1156     extract_nobj(obj, &invent);
1157     freeinv_core(obj);
1158     update_inventory();
1159 }
1160
1161 void
1162 delallobj(x, y)
1163 int x, y;
1164 {
1165     struct obj *otmp, *otmp2;
1166
1167     for (otmp = level.objects[x][y]; otmp; otmp = otmp2) {
1168         if (otmp == uball)
1169             unpunish();
1170         /* after unpunish(), or might get deallocated chain */
1171         otmp2 = otmp->nexthere;
1172         if (otmp == uchain)
1173             continue;
1174         delobj(otmp);
1175     }
1176 }
1177
1178 /* destroy object in fobj chain (if unpaid, it remains on the bill) */
1179 void
1180 delobj(obj)
1181 register struct obj *obj;
1182 {
1183     boolean update_map;
1184
1185     if (obj->otyp == AMULET_OF_YENDOR
1186         || obj->otyp == CANDELABRUM_OF_INVOCATION
1187         || obj->otyp == BELL_OF_OPENING
1188         || obj->otyp == SPE_BOOK_OF_THE_DEAD) {
1189         /* player might be doing something stupid, but we
1190          * can't guarantee that.  assume special artifacts
1191          * are indestructible via drawbridges, and exploding
1192          * chests, and golem creation, and ...
1193          */
1194         return;
1195     }
1196     update_map = (obj->where == OBJ_FLOOR);
1197     obj_extract_self(obj);
1198     if (update_map)
1199         newsym(obj->ox, obj->oy);
1200     obfree(obj, (struct obj *) 0); /* frees contents also */
1201 }
1202
1203 /* try to find a particular type of object at designated map location */
1204 struct obj *
1205 sobj_at(otyp, x, y)
1206 int otyp;
1207 int x, y;
1208 {
1209     register struct obj *otmp;
1210
1211     for (otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere)
1212         if (otmp->otyp == otyp)
1213             break;
1214
1215     return otmp;
1216 }
1217
1218 /* sobj_at(&c) traversal -- find next object of specified type */
1219 struct obj *
1220 nxtobj(obj, type, by_nexthere)
1221 struct obj *obj;
1222 int type;
1223 boolean by_nexthere;
1224 {
1225     register struct obj *otmp;
1226
1227     otmp = obj; /* start with the object after this one */
1228     do {
1229         otmp = !by_nexthere ? otmp->nobj : otmp->nexthere;
1230         if (!otmp)
1231             break;
1232     } while (otmp->otyp != type);
1233
1234     return otmp;
1235 }
1236
1237 struct obj *
1238 carrying(type)
1239 register int type;
1240 {
1241     register struct obj *otmp;
1242
1243     for (otmp = invent; otmp; otmp = otmp->nobj)
1244         if (otmp->otyp == type)
1245             return  otmp;
1246     return (struct obj *) 0;
1247 }
1248
1249 /* Fictional and not-so-fictional currencies.
1250  * http://concord.wikia.com/wiki/List_of_Fictional_Currencies
1251  */
1252 static const char *const currencies[] = {
1253 #if 0 /*JP*/
1254     "Altarian Dollar",       /* The Hitchhiker's Guide to the Galaxy */
1255     "Ankh-Morpork Dollar",   /* Discworld */
1256     "auric",                 /* The Domination of Draka */
1257     "buckazoid",             /* Space Quest */
1258     "cirbozoid",             /* Starslip */
1259     "credit chit",           /* Deus Ex */
1260     "cubit",                 /* Battlestar Galactica */
1261     "Flanian Pobble Bead",   /* The Hitchhiker's Guide to the Galaxy */
1262     "fretzer",               /* Jules Verne */
1263     "imperial credit",       /* Star Wars */
1264     "Hong Kong Luna Dollar", /* The Moon is a Harsh Mistress */
1265     "kongbuck",              /* Snow Crash */
1266     "nanite",                /* System Shock 2 */
1267     "quatloo",               /* Star Trek, Sim City */
1268     "simoleon",              /* Sim City */
1269     "solari",                /* Spaceballs */
1270     "spacebuck",             /* Spaceballs */
1271     "sporebuck",             /* Spore */
1272     "Triganic Pu",           /* The Hitchhiker's Guide to the Galaxy */
1273     "woolong",               /* Cowboy Bebop */
1274     "zorkmid",               /* Zork, NetHack */
1275 #else
1276     "\83A\83\8b\83^\83C\83\8b\81E\83h\83\8b",      /* The Hitchhiker's Guide to the Galaxy */
1277     "\83A\83\93\83N\83\82\83\8b\83|\81[\83N\81E\83h\83\8b", /* Discworld */
1278     "\83\86\81[\83\8a\83b\83N",            /* The Domination of Draka */
1279     "\83o\83b\83J\83]\83C\83h",          /* Space Quest */
1280     "\83T\81[\83{\83]\83C\83h",          /* Starslip */
1281     "\83N\83\8c\83W\83b\83g\81E\83`\83b\83g",    /* Deus Ex */
1282     "\83L\83\85\81[\83r\83b\83g",          /* Battlestar Galactica */
1283     "\83t\83\8c\83j\83A\83\93\81E\83s\83b\83u\83\8b\81E\83r\81[\83h", /* The Hitchhiker's Guide to the Galaxy */
1284     "\83t\83\8c\83b\83c\83@",            /* Jules Verne */
1285     "\92é\8d\91\83N\83\8c\83W\83b\83g",        /* Star Wars */
1286     "\8d\81\8d`\8c\8e\83h\83\8b",            /* The Moon is a Harsh Mistress */
1287     "\83R\83\93\83o\83b\83N",            /* Snow Crash */
1288     "\83i\81[\83i\83C\83g",            /* System Shock 2 */
1289     "\83N\83@\83g\83\8d",              /* Star Trek, Sim City */
1290     "\83V\83\82\83\8c\83I\83\93",            /* Sim City */
1291     "\83\\83\89\83\8a",                /* Spaceballs */
1292     "\83X\83y\81[\83X\83o\83b\83N",        /* Spaceballs */
1293     "\83X\83|\83A\83o\83b\83N",          /* Spore */
1294     "\83g\83\89\83C\83K\83j\83b\83N\81E\83v\81[",  /* The Hitchhiker's Guide to the Galaxy */
1295     "\83E\81[\83\8d\83\93",              /* Cowboy Bebop */
1296     "\83S\81[\83\8b\83h",              /* Zork, NetHack */
1297 #endif
1298 };
1299
1300 const char *
1301 currency(amount)
1302 long amount;
1303 {
1304     const char *res;
1305
1306 #if 0 /*JP*/
1307     res = Hallucination ? currencies[rn2(SIZE(currencies))] : "zorkmid";
1308     if (amount != 1L)
1309         res = makeplural(res);
1310 #else
1311     res = Hallucination ? currencies[rn2(SIZE(currencies))] : "\83S\81[\83\8b\83h";
1312 #endif
1313     return res;
1314 }
1315
1316 boolean
1317 have_lizard()
1318 {
1319     register struct obj *otmp;
1320
1321     for (otmp = invent; otmp; otmp = otmp->nobj)
1322         if (otmp->otyp == CORPSE && otmp->corpsenm == PM_LIZARD)
1323             return  TRUE;
1324     return FALSE;
1325 }
1326
1327 /* 3.6 tribute */
1328 struct obj *
1329 u_have_novel()
1330 {
1331     register struct obj *otmp;
1332
1333     for (otmp = invent; otmp; otmp = otmp->nobj)
1334         if (otmp->otyp == SPE_NOVEL)
1335             return otmp;
1336     return (struct obj *) 0;
1337 }
1338
1339 struct obj *
1340 o_on(id, objchn)
1341 unsigned int id;
1342 register struct obj *objchn;
1343 {
1344     struct obj *temp;
1345
1346     while (objchn) {
1347         if (objchn->o_id == id)
1348             return objchn;
1349         if (Has_contents(objchn) && (temp = o_on(id, objchn->cobj)))
1350             return temp;
1351         objchn = objchn->nobj;
1352     }
1353     return (struct obj *) 0;
1354 }
1355
1356 boolean
1357 obj_here(obj, x, y)
1358 register struct obj *obj;
1359 int x, y;
1360 {
1361     register struct obj *otmp;
1362
1363     for (otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere)
1364         if (obj == otmp)
1365             return TRUE;
1366     return FALSE;
1367 }
1368
1369 struct obj *
1370 g_at(x, y)
1371 register int x, y;
1372 {
1373     register struct obj *obj = level.objects[x][y];
1374
1375     while (obj) {
1376         if (obj->oclass == COIN_CLASS)
1377             return obj;
1378         obj = obj->nexthere;
1379     }
1380     return (struct obj *) 0;
1381 }
1382
1383 /* compact a string of inventory letters by dashing runs of letters */
1384 STATIC_OVL void
1385 compactify(buf)
1386 register char *buf;
1387 {
1388     register int i1 = 1, i2 = 1;
1389     register char ilet, ilet1, ilet2;
1390
1391     ilet2 = buf[0];
1392     ilet1 = buf[1];
1393     buf[++i2] = buf[++i1];
1394     ilet = buf[i1];
1395     while (ilet) {
1396         if (ilet == ilet1 + 1) {
1397             if (ilet1 == ilet2 + 1)
1398                 buf[i2 - 1] = ilet1 = '-';
1399             else if (ilet2 == '-') {
1400                 buf[i2 - 1] = ++ilet1;
1401                 buf[i2] = buf[++i1];
1402                 ilet = buf[i1];
1403                 continue;
1404             }
1405         } else if (ilet == NOINVSYM) {
1406             /* compact three or more consecutive '#'
1407                characters into "#-#" */
1408             if (i2 >= 2 && buf[i2 - 2] == NOINVSYM && buf[i2 - 1] == NOINVSYM)
1409                 buf[i2 - 1] = '-';
1410             else if (i2 >= 3 && buf[i2 - 3] == NOINVSYM && buf[i2 - 2] == '-'
1411                      && buf[i2 - 1] == NOINVSYM)
1412                 --i2;
1413         }
1414         ilet2 = ilet1;
1415         ilet1 = ilet;
1416         buf[++i2] = buf[++i1];
1417         ilet = buf[i1];
1418     }
1419 }
1420
1421 /* some objects shouldn't be split when count given to getobj or askchain */
1422 boolean
1423 splittable(obj)
1424 struct obj *obj;
1425 {
1426     return !((obj->otyp == LOADSTONE && obj->cursed)
1427              || (obj == uwep && welded(uwep)));
1428 }
1429
1430 /* match the prompt for either 'T' or 'R' command */
1431 STATIC_OVL boolean
1432 taking_off(action)
1433 const char *action;
1434 {
1435     return !strcmp(action, "take off") || !strcmp(action, "remove");
1436 }
1437
1438 /* match the prompt for either 'W' or 'P' command */
1439 STATIC_OVL boolean
1440 putting_on(action)
1441 const char *action;
1442 {
1443     return !strcmp(action, "wear") || !strcmp(action, "put on");
1444 }
1445
1446 /*
1447  * getobj returns:
1448  *      struct obj *xxx:        object to do something with.
1449  *      (struct obj *) 0        error return: no object.
1450  *      &zeroobj                explicitly no object (as in w-).
1451 !!!! test if gold can be used in unusual ways (eaten etc.)
1452 !!!! may be able to remove "usegold"
1453  */
1454 /*JP
1455 ** word \82É\82Í\89p\8cê\82Å\93®\8e\8c\82ª\93ü\82é\81D
1456 **
1457 ** \93ú\96{\8cê\82Å\82Í\81C\81u\82Ç\82ê\82ð\8f\91\82«\82Ü\82·\82©\81v\82æ\82è\81u\82Ç\82ê\82É\8f\91\82«\82Ü\82·\82©\81v\82Ì\95û\82ª\8e©\91R\82È\82Ì\82Å\81C
1458 ** \8dÅ\8f\89\82Ì\88ê\95\8e\9a\82É\81u\82É\81v\82â\81u\82Ì\81v\82ð\8ew\92è\82µ\82½\8fê\8d\87\82Í\8f\95\8e\8c\82ð\95Ï\8dX\82·\82é\81D
1459 **
1460 */
1461 struct obj *
1462 getobj(let, word)
1463 register const char *let, *word;
1464 {
1465     register struct obj *otmp;
1466     register char ilet = 0;
1467     char buf[BUFSZ], qbuf[QBUFSZ];
1468     char lets[BUFSZ], altlets[BUFSZ], *ap;
1469     register int foo = 0;
1470     register char *bp = buf;
1471     xchar allowcnt = 0; /* 0, 1 or 2 */
1472     boolean usegold = FALSE; /* can't use gold because its illegal */
1473     boolean allowall = FALSE;
1474     boolean allownone = FALSE;
1475     boolean useboulder = FALSE;
1476     xchar foox = 0;
1477     long cnt;
1478     boolean cntgiven = FALSE;
1479     boolean msggiven = FALSE;
1480     boolean oneloop = FALSE;
1481     long dummymask;
1482     Loot *sortedinvent, *srtinv;
1483
1484 #if 1 /*JP*/
1485     const char *jword;
1486     const char *joshi;
1487     const char *what;
1488
1489     struct trans_verb *tv = trans_verb(word);
1490
1491     jword = tv->jp;
1492     what = tv->what;
1493     joshi = tv->particle;
1494 #endif
1495     if (*let == ALLOW_COUNT)
1496         let++, allowcnt = 1;
1497     if (*let == COIN_CLASS)
1498         let++, usegold = TRUE;
1499
1500     /* Equivalent of an "ugly check" for gold */
1501     if (usegold && !strcmp(word, "eat")
1502         && (!metallivorous(youmonst.data)
1503             || youmonst.data == &mons[PM_RUST_MONSTER]))
1504         usegold = FALSE;
1505
1506     if (*let == ALL_CLASSES)
1507         let++, allowall = TRUE;
1508     if (*let == ALLOW_NONE)
1509         let++, allownone = TRUE;
1510     /* "ugly check" for reading fortune cookies, part 1.
1511      * The normal 'ugly check' keeps the object on the inventory list.
1512      * We don't want to do that for shirts/cookies, so the check for
1513      * them is handled a bit differently (and also requires that we set
1514      * allowall in the caller).
1515      */
1516     if (allowall && !strcmp(word, "read"))
1517         allowall = FALSE;
1518
1519     /* another ugly check: show boulders (not statues) */
1520     if (*let == WEAPON_CLASS && !strcmp(word, "throw")
1521         && throws_rocks(youmonst.data))
1522         useboulder = TRUE;
1523
1524     if (allownone)
1525         *bp++ = HANDS_SYM, *bp++ = ' '; /* '-' */
1526     ap = altlets;
1527
1528     if (!flags.invlet_constant)
1529         reassign();
1530
1531     /* force invent to be in invlet order before collecting candidate
1532        inventory letters */
1533     sortedinvent = sortloot(&invent, SORTLOOT_INVLET, FALSE,
1534                             (boolean FDECL((*), (OBJ_P))) 0);
1535
1536     for (srtinv = sortedinvent; (otmp = srtinv->obj) != 0; ++srtinv) {
1537         if (&bp[foo] == &buf[sizeof buf - 1]
1538             || ap == &altlets[sizeof altlets - 1]) {
1539             /* we must have a huge number of NOINVSYM items somehow */
1540             impossible("getobj: inventory overflow");
1541             break;
1542         }
1543
1544         if (!*let || index(let, otmp->oclass)
1545             || (usegold && otmp->invlet == GOLD_SYM)
1546             || (useboulder && otmp->otyp == BOULDER)) {
1547             register int otyp = otmp->otyp;
1548
1549             bp[foo++] = otmp->invlet;
1550 /* clang-format off */
1551 /* *INDENT-OFF* */
1552             /* ugly check: remove inappropriate things */
1553             if (
1554                 (taking_off(word) /* exclude if not worn */
1555                  && !(otmp->owornmask & (W_ARMOR | W_ACCESSORY)))
1556              || (putting_on(word) /* exclude if already worn */
1557                  && (otmp->owornmask & (W_ARMOR | W_ACCESSORY)))
1558 #if 0 /* 3.4.1 -- include currently wielded weapon among 'wield' choices */
1559              || (!strcmp(word, "wield")
1560                  && (otmp->owornmask & W_WEP))
1561 #endif
1562              || (!strcmp(word, "ready")    /* exclude when wielded... */
1563                  && ((otmp == uwep || (otmp == uswapwep && u.twoweap))
1564                      && otmp->quan == 1L)) /* ...unless more than one */
1565              || ((!strcmp(word, "dip") || !strcmp(word, "grease"))
1566                  && inaccessible_equipment(otmp, (const char *) 0, FALSE))
1567              ) {
1568                 foo--;
1569                 foox++;
1570             }
1571             /* Second ugly check; unlike the first it won't trigger an
1572              * "else" in "you don't have anything else to ___".
1573              */
1574             else if (
1575                 (putting_on(word)
1576                  && ((otmp->oclass == FOOD_CLASS && otmp->otyp != MEAT_RING)
1577                      || (otmp->oclass == TOOL_CLASS && otyp != BLINDFOLD
1578                          && otyp != TOWEL && otyp != LENSES)))
1579              || (!strcmp(word, "wield")
1580                  && (otmp->oclass == TOOL_CLASS && !is_weptool(otmp)))
1581              || (!strcmp(word, "eat") && !is_edible(otmp))
1582              || (!strcmp(word, "sacrifice")
1583                  && (otyp != CORPSE && otyp != AMULET_OF_YENDOR
1584                      && otyp != FAKE_AMULET_OF_YENDOR))
1585              || (!strcmp(word, "write with")
1586                  && (otmp->oclass == TOOL_CLASS
1587                      && otyp != MAGIC_MARKER && otyp != TOWEL))
1588              || (!strcmp(word, "tin")
1589                  && (otyp != CORPSE || !tinnable(otmp)))
1590              || (!strcmp(word, "rub")
1591                  && ((otmp->oclass == TOOL_CLASS && otyp != OIL_LAMP
1592                       && otyp != MAGIC_LAMP && otyp != BRASS_LANTERN)
1593                      || (otmp->oclass == GEM_CLASS && !is_graystone(otmp))))
1594              || (!strcmp(word, "use or apply")
1595                  /* Picks, axes, pole-weapons, bullwhips */
1596                  && ((otmp->oclass == WEAPON_CLASS
1597                       && !is_pick(otmp) && !is_axe(otmp)
1598                       && !is_pole(otmp) && otyp != BULLWHIP)
1599                      || (otmp->oclass == POTION_CLASS
1600                          /* only applicable potion is oil, and it will only
1601                             be offered as a choice when already discovered */
1602                          && (otyp != POT_OIL || !otmp->dknown
1603                              || !objects[POT_OIL].oc_name_known))
1604                      || (otmp->oclass == FOOD_CLASS
1605                          && otyp != CREAM_PIE && otyp != EUCALYPTUS_LEAF)
1606                      || (otmp->oclass == GEM_CLASS && !is_graystone(otmp))))
1607              || (!strcmp(word, "invoke")
1608                  && !otmp->oartifact
1609                  && !objects[otyp].oc_unique
1610                  && (otyp != FAKE_AMULET_OF_YENDOR || otmp->known)
1611                  && otyp != CRYSTAL_BALL /* synonym for apply */
1612                  /* note: presenting the possibility of invoking non-artifact
1613                     mirrors and/or lamps is simply a cruel deception... */
1614                  && otyp != MIRROR
1615                  && otyp != MAGIC_LAMP
1616                  && (otyp != OIL_LAMP /* don't list known oil lamp */
1617                      || (otmp->dknown && objects[OIL_LAMP].oc_name_known)))
1618              || (!strcmp(word, "untrap with")
1619                  && ((otmp->oclass == TOOL_CLASS && otyp != CAN_OF_GREASE)
1620                      || (otmp->oclass == POTION_CLASS
1621                          /* only applicable potion is oil, and it will only
1622                             be offered as a choice when already discovered */
1623                          && (otyp != POT_OIL || !otmp->dknown
1624                              || !objects[POT_OIL].oc_name_known))))
1625              || (!strcmp(word, "tip") && !Is_container(otmp)
1626                  /* include horn of plenty if sufficiently discovered */
1627                  && (otmp->otyp != HORN_OF_PLENTY || !otmp->dknown
1628                      || !objects[HORN_OF_PLENTY].oc_name_known))
1629              || (!strcmp(word, "charge") && !is_chargeable(otmp))
1630              || (!strcmp(word, "open") && otyp != TIN)
1631              || (!strcmp(word, "call") && !objtyp_is_callable(otyp))
1632              || (!strcmp(word, "adjust") && otmp->oclass == COIN_CLASS
1633                  && !usegold)
1634              ) {
1635                 foo--;
1636             }
1637             /* Third ugly check:  acceptable but not listed as likely
1638              * candidates in the prompt or in the inventory subset if
1639              * player responds with '?'.
1640              */
1641             else if (
1642              /* ugly check for unworn armor that can't be worn */
1643                 (putting_on(word) && *let == ARMOR_CLASS
1644                  && !canwearobj(otmp, &dummymask, FALSE))
1645              /* or armor with 'P' or 'R' or accessory with 'W' or 'T' */
1646              || ((putting_on(word) || taking_off(word))
1647                  && ((*let == ARMOR_CLASS) ^ (otmp->oclass == ARMOR_CLASS)))
1648              /* or unsuitable items rubbed on known touchstone */
1649              || (!strncmp(word, "rub on the stone", 16)
1650                  && *let == GEM_CLASS && otmp->dknown
1651                  && objects[otyp].oc_name_known)
1652              /* suppress corpses on astral, amulets elsewhere */
1653              || (!strcmp(word, "sacrifice")
1654                  /* (!astral && amulet) || (astral && !amulet) */
1655                  && (!Is_astralevel(&u.uz) ^ (otmp->oclass != AMULET_CLASS)))
1656              /* suppress container being stashed into */
1657              || (!strcmp(word, "stash") && !ck_bag(otmp))
1658              /* worn armor (shirt, suit) covered by worn armor (suit, cloak)
1659                 or accessory (ring) covered by cursed worn armor (gloves) */
1660              || (taking_off(word)
1661                  && inaccessible_equipment(otmp, (const char *) 0,
1662                                       (boolean) (otmp->oclass == RING_CLASS)))
1663              || (!strcmp(word, "write on")
1664                  && (!(otyp == SCR_BLANK_PAPER || otyp == SPE_BLANK_PAPER)
1665                      || !otmp->dknown || !objects[otyp].oc_name_known))
1666              ) {
1667                 /* acceptable but not listed as likely candidate */
1668                 foo--;
1669                 allowall = TRUE;
1670                 *ap++ = otmp->invlet;
1671             }
1672 /* *INDENT-ON* */
1673 /* clang-format on */
1674         } else {
1675             /* "ugly check" for reading fortune cookies, part 2 */
1676             if ((!strcmp(word, "read") && is_readable(otmp)))
1677                 allowall = usegold = TRUE;
1678         }
1679     }
1680     unsortloot(&sortedinvent);
1681
1682     bp[foo] = 0;
1683     if (foo == 0 && bp > buf && bp[-1] == ' ')
1684         *--bp = 0;
1685     Strcpy(lets, bp); /* necessary since we destroy buf */
1686     if (foo > 5)      /* compactify string */
1687         compactify(bp);
1688     *ap = '\0';
1689
1690     if (!foo && !allowall && !allownone) {
1691 /*JP
1692         You("don't have anything %sto %s.", foox ? "else " : "", word);
1693 */
1694         You("%s%s\82à\82Ì\82ð\8e\9d\82Á\82Ä\82¢\82È\82¢\81D", foox ? "\91¼\82É" : "", jconj(jword, "\82ê\82é"));
1695         return (struct obj *) 0;
1696     } else if (!strcmp(word, "write on")) { /* ugly check for magic marker */
1697         /* we wanted all scrolls and books in altlets[], but that came with
1698            'allowall' which we don't want since it prevents "silly thing"
1699            result if anything other than scroll or spellbook is chosen */
1700         allowall = FALSE;
1701     }
1702     for (;;) {
1703         cnt = 0;
1704         cntgiven = FALSE;
1705 /*JP
1706         Sprintf(qbuf, "What do you want to %s?", word);
1707 */
1708         Sprintf(qbuf, "%s%s%s\82©\81H", what, joshi, jpolite(jword));
1709         if (in_doagain)
1710             ilet = readchar();
1711         else if (iflags.force_invmenu) {
1712             /* don't overwrite a possible quitchars */
1713             if (!oneloop)
1714                 ilet = *let ? '?' : '*';
1715             if (!msggiven)
1716                 putmsghistory(qbuf, FALSE);
1717             msggiven = TRUE;
1718             oneloop = TRUE;
1719         } else {
1720             if (!buf[0])
1721                 Strcat(qbuf, " [*]");
1722             else
1723                 Sprintf(eos(qbuf), " [%s or ?*]", buf);
1724             ilet = yn_function(qbuf, (char *) 0, '\0');
1725         }
1726         if (digit(ilet)) {
1727             long tmpcnt = 0;
1728
1729             if (!allowcnt) {
1730 /*JP
1731             pline("No count allowed with this command.");
1732 */
1733             pline("\82±\82Ì\83R\83}\83\93\83h\82É\90\94\8e\9a\82Í\82Â\82©\82¦\82È\82¢\81D");
1734                 continue;
1735             }
1736             ilet = get_count(NULL, ilet, LARGEST_INT, &tmpcnt, TRUE);
1737             if (tmpcnt) {
1738                 cnt = tmpcnt;
1739                 cntgiven = TRUE;
1740             }
1741         }
1742         if (index(quitchars, ilet)) {
1743             if (flags.verbose)
1744                 pline1(Never_mind);
1745             return (struct obj *) 0;
1746         }
1747         if (ilet == HANDS_SYM) { /* '-' */
1748             if (!allownone) {
1749 #if 0 /*JP*/
1750                 char *suf = (char *) 0;
1751
1752                 strcpy(buf, word);
1753                 if ((bp = strstr(buf, " on the ")) != 0) {
1754                     /* rub on the stone[s] */
1755                     *bp = '\0';
1756                     suf = (bp + 1);
1757                 }
1758                 if ((bp = strstr(buf, " or ")) != 0) {
1759                     *bp = '\0';
1760                     bp = (rn2(2) ? buf : (bp + 4));
1761                 } else
1762                     bp = buf;
1763                 You("mime %s something%s%s.", ing_suffix(bp), suf ? " " : "",
1764                     suf ? suf : "");
1765 #else
1766                 You("\89½\82©\82ð%s\82Ó\82è\82ð\82µ\82½\81D", bp);
1767 #endif
1768             }
1769             return (allownone ? (struct obj *) &zeroobj : (struct obj *) 0);
1770         }
1771  redo_menu:
1772         /* since gold is now kept in inventory, we need to do processing for
1773            select-from-invent before checking whether gold has been picked */
1774         if (ilet == '?' || ilet == '*') {
1775             char *allowed_choices = (ilet == '?') ? lets : (char *) 0;
1776             long ctmp = 0;
1777             char menuquery[QBUFSZ];
1778
1779             menuquery[0] = qbuf[0] = '\0';
1780             if (iflags.force_invmenu)
1781                 Sprintf(menuquery, "What do you want to %s?", word);
1782             if (!strcmp(word, "grease"))
1783                 Sprintf(qbuf, "your %s", makeplural(body_part(FINGER)));
1784             else if (!strcmp(word, "write with"))
1785                 Sprintf(qbuf, "your %s", body_part(FINGERTIP));
1786             else if (!strcmp(word, "wield"))
1787                 Sprintf(qbuf, "your %s %s%s", uarmg ? "gloved" : "bare",
1788                         makeplural(body_part(HAND)),
1789                         !uwep ? " (wielded)" : "");
1790             else if (!strcmp(word, "ready"))
1791                 Sprintf(qbuf, "empty quiver%s",
1792                         !uquiver ? " (nothing readied)" : "");
1793
1794             if (ilet == '?' && !*lets && *altlets)
1795                 allowed_choices = altlets;
1796             ilet = display_pickinv(allowed_choices, *qbuf ? qbuf : (char *) 0,
1797                                    menuquery,
1798                                    TRUE, allowcnt ? &ctmp : (long *) 0);
1799             if (!ilet)
1800                 continue;
1801             if (ilet == HANDS_SYM)
1802                 return (struct obj *) &zeroobj; /* cast away 'const' */
1803             if (ilet == '\033') {
1804                 if (flags.verbose)
1805                     pline1(Never_mind);
1806                 return (struct obj *) 0;
1807             }
1808             if (ilet == '*')
1809                 goto redo_menu;
1810             if (allowcnt && ctmp >= 0) {
1811                 cnt = ctmp;
1812                 cntgiven = TRUE;
1813             }
1814             /* they typed a letter (not a space) at the prompt */
1815         }
1816         /* find the item which was picked */
1817         for (otmp = invent; otmp; otmp = otmp->nobj)
1818             if (otmp->invlet == ilet)
1819                 break;
1820         /* some items have restrictions */
1821         if (ilet == def_oc_syms[COIN_CLASS].sym
1822             /* guard against the [hypothetical] chace of having more
1823                than one invent slot of gold and picking the non-'$' one */
1824             || (otmp && otmp->oclass == COIN_CLASS)) {
1825             if (!usegold) {
1826 /*JP
1827                 You("cannot %s gold.", word);
1828 */
1829                 You("\8bà\89Ý%s%s\82±\82Æ\82Í\82Å\82«\82È\82¢\81D", joshi, jword);
1830                 return (struct obj *) 0;
1831             }
1832             /* Historic note: early Nethack had a bug which was
1833              * first reported for Larn, where trying to drop 2^32-n
1834              * gold pieces was allowed, and did interesting things
1835              * to your money supply.  The LRS is the tax bureau
1836              * from Larn.
1837              */
1838             if (cntgiven && cnt <= 0) {
1839                 if (cnt < 0)
1840                     pline_The(
1841 /*JP
1842                   "LRS would be very interested to know you have that much.");
1843 */
1844                   "\82»\82Ì\8bZ\82Í\82Æ\82 \82é\83Q\81[\83\80\82Ì\83J\83W\83m\82Å\8eg\82¦\82½\82¯\82Ç\81C\82à\82Í\82â\8eg\82¦\82È\82¢\82æ\81D");
1845                 return (struct obj *) 0;
1846             }
1847         }
1848         if (cntgiven && !strcmp(word, "throw")) {
1849             /* permit counts for throwing gold, but don't accept
1850              * counts for other things since the throw code will
1851              * split off a single item anyway */
1852             if (cnt == 0)
1853                 return (struct obj *) 0;
1854             if (cnt > 1 && (ilet != def_oc_syms[COIN_CLASS].sym
1855                 && !(otmp && otmp->oclass == COIN_CLASS))) {
1856 /*JP
1857                 You("can only throw one item at a time.");
1858 */
1859                 You("\93¯\8e\9e\82É\82½\82­\82³\82ñ\82Ì\82à\82Ì\82ð\93\8a\82°\82ç\82ê\82È\82¢\81D");
1860                 continue;
1861             }
1862         }
1863         context.botl = 1; /* May have changed the amount of money */
1864         savech(ilet);
1865         /* [we used to set otmp (by finding ilet in invent) here, but
1866            that's been moved above so that otmp can be checked earlier] */
1867         /* verify the chosen object */
1868         if (!otmp) {
1869 /*JP
1870             You("don't have that object.");
1871 */
1872             You("\82»\82ñ\82È\82à\82Ì\82Í\8e\9d\82Á\82Ä\82¢\82È\82¢\81D");
1873             if (in_doagain)
1874                 return (struct obj *) 0;
1875             continue;
1876         } else if (cnt < 0 || otmp->quan < cnt) {
1877 /*JP
1878             You("don't have that many!  You have only %ld.", otmp->quan);
1879 */
1880             pline("\82»\82ñ\82È\82É\82½\82­\82³\82ñ\82Í\8e\9d\82Á\82Ä\82¢\82È\82¢\81I\82¹\82¢\82º\82¢%ld\8cÂ\82Á\82Ä\82Æ\82±\82¾\81D", otmp->quan);
1881             if (in_doagain)
1882                 return (struct obj *) 0;
1883             continue;
1884         }
1885         break;
1886     }
1887     if (!allowall && let && !index(let, otmp->oclass)
1888         && !(usegold && otmp->oclass == COIN_CLASS)) {
1889 #if 0 /*JP*/
1890         silly_thing(word, otmp);
1891 #else
1892         silly_thing(jword, otmp);
1893 #endif
1894         return (struct obj *) 0;
1895     }
1896     if (cntgiven) {
1897         if (cnt == 0)
1898             return (struct obj *) 0;
1899         if (cnt != otmp->quan) {
1900             /* don't split a stack of cursed loadstones */
1901             if (splittable(otmp))
1902                 otmp = splitobj(otmp, cnt);
1903             else if (otmp->otyp == LOADSTONE && otmp->cursed)
1904                 /* kludge for canletgo()'s can't-drop-this message */
1905                 otmp->corpsenm = (int) cnt;
1906         }
1907     }
1908     return otmp;
1909 }
1910
1911 void
1912 silly_thing(word, otmp)
1913 const char *word;
1914 struct obj *otmp;
1915 {
1916 #if 1 /* 'P','R' vs 'W','T' handling is obsolete */
1917     nhUse(otmp);
1918 #else
1919     const char *s1, *s2, *s3;
1920     int ocls = otmp->oclass, otyp = otmp->otyp;
1921
1922     s1 = s2 = s3 = 0;
1923     /* check for attempted use of accessory commands ('P','R') on armor
1924        and for corresponding armor commands ('W','T') on accessories */
1925     if (ocls == ARMOR_CLASS) {
1926 #if 0 /*JP*/
1927         if (!strcmp(word, "put on"))
1928             s1 = "W", s2 = "wear", s3 = "";
1929         else if (!strcmp(word, "remove"))
1930             s1 = "T", s2 = "take", s3 = " off";
1931 #else
1932         if (!strcmp(word, "\90g\82É\82Â\82¯\82é"))
1933             s1 = "W", s2 = "\90g\82É\82Â\82¯\82é", s3 = "";
1934         else if (!strcmp(word, "\82Í\82¸\82·"))
1935             s1 = "T", s2 = "\82Í\82¸\82·", s3 = "";
1936 #endif
1937     } else if ((ocls == RING_CLASS || otyp == MEAT_RING)
1938                || ocls == AMULET_CLASS
1939                || (otyp == BLINDFOLD || otyp == TOWEL || otyp == LENSES)) {
1940 #if 0 /*JP*/
1941         if (!strcmp(word, "wear"))
1942             s1 = "P", s2 = "put", s3 = " on";
1943         else if (!strcmp(word, "take off"))
1944             s1 = "R", s2 = "remove", s3 = "";
1945 #else
1946         if (!strcmp(word, "\90g\82É\82Â\82¯\82é"))
1947             s1 = "P", s2 = "\90g\82É\82Â\82¯\82é", s3 = "";
1948         else if (!strcmp(word, "\82Í\82¸\82·"))
1949             s1 = "R", s2 = "\82Í\82¸\82·", s3 = "";
1950 #endif
1951     }
1952     if (s1)
1953 #if 0 /*JP*/
1954         pline("Use the '%s' command to %s %s%s.", s1, s2,
1955               !(is_plural(otmp) || pair_of(otmp)) ? "that" : "those", s3);
1956 #else
1957         pline("\82»\82ê\82ð%s\82É\82Í'%s'\83R\83}\83\93\83h\82ð\8eg\82¤\82±\82Æ\81D", s2, s1);
1958 #endif
1959     else
1960 #endif
1961         pline(silly_thing_to, word);
1962 }
1963
1964 STATIC_PTR int
1965 ckvalidcat(otmp)
1966 struct obj *otmp;
1967 {
1968     /* use allow_category() from pickup.c */
1969     return (int) allow_category(otmp);
1970 }
1971
1972 STATIC_PTR int
1973 ckunpaid(otmp)
1974 struct obj *otmp;
1975 {
1976     return (otmp->unpaid || (Has_contents(otmp) && count_unpaid(otmp->cobj)));
1977 }
1978
1979 boolean
1980 wearing_armor()
1981 {
1982     return (boolean) (uarm || uarmc || uarmf || uarmg
1983                       || uarmh || uarms || uarmu);
1984 }
1985
1986 boolean
1987 is_worn(otmp)
1988 struct obj *otmp;
1989 {
1990     return (otmp->owornmask & (W_ARMOR | W_ACCESSORY | W_SADDLE | W_WEAPON))
1991             ? TRUE
1992             : FALSE;
1993 }
1994
1995 /* extra xprname() input that askchain() can't pass through safe_qbuf() */
1996 STATIC_VAR struct xprnctx {
1997     char let;
1998     boolean dot;
1999 } safeq_xprn_ctx;
2000
2001 /* safe_qbuf() -> short_oname() callback */
2002 STATIC_PTR char *
2003 safeq_xprname(obj)
2004 struct obj *obj;
2005 {
2006     return xprname(obj, (char *) 0, safeq_xprn_ctx.let, safeq_xprn_ctx.dot,
2007                    0L, 0L);
2008 }
2009
2010 /* alternate safe_qbuf() -> short_oname() callback */
2011 STATIC_PTR char *
2012 safeq_shortxprname(obj)
2013 struct obj *obj;
2014 {
2015     return xprname(obj, ansimpleoname(obj), safeq_xprn_ctx.let,
2016                    safeq_xprn_ctx.dot, 0L, 0L);
2017 }
2018
2019 static NEARDATA const char removeables[] = { ARMOR_CLASS, WEAPON_CLASS,
2020                                              RING_CLASS,  AMULET_CLASS,
2021                                              TOOL_CLASS,  0 };
2022
2023 /* Interactive version of getobj - used for Drop, Identify, and Takeoff (A).
2024    Return the number of times fn was called successfully.
2025    If combo is TRUE, we just use this to get a category list. */
2026 /*JP CHECK: 3.6.0 \82Ì\8cÄ\82Ñ\8fo\82µ\8c³
2027 do.c:962:        || (result = ggetobj("drop", drop, 0, FALSE, (unsigned *) 0)) < -1)
2028 do.c:1009:        i = ggetobj("drop", drop, 0, TRUE, &ggoresults);
2029 do_wear.c:2955:        || (result = ggetobj("take off", select_off, 0, FALSE,
2030 do_wear.c:3007:        if (ggetobj("take off", select_off, 0, TRUE, (unsigned *) 0) == -2)
2031 invent.c:2014:                n = ggetobj("identify", identify, id_limit, FALSE,
2032 */
2033 int
2034 ggetobj(word, fn, mx, combo, resultflags)
2035 const char *word;
2036 int FDECL((*fn), (OBJ_P)), mx;
2037 boolean combo; /* combination menu flag */
2038 unsigned *resultflags;
2039 {
2040     int FDECL((*ckfn), (OBJ_P)) = (int FDECL((*), (OBJ_P))) 0;
2041     boolean FDECL((*ofilter), (OBJ_P)) = (boolean FDECL((*), (OBJ_P))) 0;
2042     boolean takeoff, ident, allflag, m_seen;
2043     int itemcount;
2044     int oletct, iletct, unpaid, oc_of_sym;
2045     char sym, *ip, olets[MAXOCLASSES + 5], ilets[MAXOCLASSES + 10];
2046     char extra_removeables[3 + 1]; /* uwep,uswapwep,uquiver */
2047     char buf[BUFSZ] = DUMMY, qbuf[QBUFSZ];
2048 #if 1 /*JP*/
2049     const char *joshi = "\82ð";
2050     const char *jword;
2051
2052     const struct trans_verb *tv = trans_verb(word);
2053     jword = tv->jp;
2054     joshi = tv->particle;
2055 #endif
2056
2057     if (!invent) {
2058 /*JP
2059         You("have nothing to %s.", word);
2060 */
2061         You("%s\82à\82Ì\82Í\8e\9d\82Á\82Ä\82¢\82È\82¢\81D", jcan(jword));
2062         if (resultflags)
2063             *resultflags = ALL_FINISHED;
2064         return 0;
2065     }
2066     if (resultflags)
2067         *resultflags = 0;
2068     takeoff = ident = allflag = m_seen = FALSE;
2069     add_valid_menu_class(0); /* reset */
2070     if (taking_off(word)) {
2071         takeoff = TRUE;
2072         ofilter = is_worn;
2073     } else if (!strcmp(word, "identify")) {
2074         ident = TRUE;
2075         ofilter = not_fully_identified;
2076     }
2077
2078     iletct = collect_obj_classes(ilets, invent, FALSE, ofilter, &itemcount);
2079     unpaid = count_unpaid(invent);
2080
2081     if (ident && !iletct) {
2082         return -1; /* no further identifications */
2083     } else if (invent) {
2084         ilets[iletct++] = ' ';
2085         if (unpaid)
2086             ilets[iletct++] = 'u';
2087         if (count_buc(invent, BUC_BLESSED, ofilter))
2088             ilets[iletct++] = 'B';
2089         if (count_buc(invent, BUC_UNCURSED, ofilter))
2090             ilets[iletct++] = 'U';
2091         if (count_buc(invent, BUC_CURSED, ofilter))
2092             ilets[iletct++] = 'C';
2093         if (count_buc(invent, BUC_UNKNOWN, ofilter))
2094             ilets[iletct++] = 'X';
2095         ilets[iletct++] = 'a';
2096     }
2097     ilets[iletct++] = 'i';
2098     if (!combo)
2099         ilets[iletct++] = 'm'; /* allow menu presentation on request */
2100     ilets[iletct] = '\0';
2101
2102     for (;;) {
2103 #if 0 /*JP*/
2104         Sprintf(qbuf, "What kinds of thing do you want to %s? [%s]",
2105                 word, ilets);
2106 #else
2107         Sprintf(qbuf,"\82Ç\82Ì\8eí\97Þ\82Ì\82à\82Ì%s%s\82©\81H[%s]", joshi,
2108                 jpolite(jword), ilets);
2109 #endif
2110         getlin(qbuf, buf);
2111         if (buf[0] == '\033')
2112             return 0;
2113         if (index(buf, 'i')) {
2114             char ailets[1+26+26+1+5+1]; /* $ + a-z + A-Z + # + slop + \0 */
2115             struct obj *otmp;
2116
2117             /* applicable inventory letters; if empty, show entire invent */
2118             ailets[0] = '\0';
2119             if (ofilter)
2120                 for (otmp = invent; otmp; otmp = otmp->nobj)
2121                     /* index() check: limit overflow items to one '#' */
2122                     if ((*ofilter)(otmp) && !index(ailets, otmp->invlet))
2123                         (void) strkitten(ailets, otmp->invlet);
2124             if (display_inventory(ailets, TRUE) == '\033')
2125                 return 0;
2126         } else
2127             break;
2128     }
2129
2130     extra_removeables[0] = '\0';
2131     if (takeoff) {
2132         /* arbitrary types of items can be placed in the weapon slots
2133            [any duplicate entries in extra_removeables[] won't matter] */
2134         if (uwep)
2135             (void) strkitten(extra_removeables, uwep->oclass);
2136         if (uswapwep)
2137             (void) strkitten(extra_removeables, uswapwep->oclass);
2138         if (uquiver)
2139             (void) strkitten(extra_removeables, uquiver->oclass);
2140     }
2141
2142     ip = buf;
2143     olets[oletct = 0] = '\0';
2144     while ((sym = *ip++) != '\0') {
2145         if (sym == ' ')
2146             continue;
2147         oc_of_sym = def_char_to_objclass(sym);
2148         if (takeoff && oc_of_sym != MAXOCLASSES) {
2149             if (index(extra_removeables, oc_of_sym)) {
2150                 ; /* skip rest of takeoff checks */
2151             } else if (!index(removeables, oc_of_sym)) {
2152 /*JP
2153                 pline("Not applicable.");
2154 */
2155                 pline("\82»\82ê\82Í\82Å\82«\82È\82¢\81D");
2156                 return 0;
2157             } else if (oc_of_sym == ARMOR_CLASS && !wearing_armor()) {
2158                 noarmor(FALSE);
2159                 return 0;
2160             } else if (oc_of_sym == WEAPON_CLASS && !uwep && !uswapwep
2161                        && !uquiver) {
2162 /*JP
2163                 You("are not wielding anything.");
2164 */
2165                 You("\89½\82à\91\95\94õ\82µ\82Ä\82¢\82È\82¢\81D");
2166                 return 0;
2167             } else if (oc_of_sym == RING_CLASS && !uright && !uleft) {
2168 /*JP
2169                 You("are not wearing rings.");
2170 */
2171                 You("\8ew\97Ö\82ð\90g\82É\82Â\82¯\82Ä\82¢\82È\82¢\81D");
2172                 return 0;
2173             } else if (oc_of_sym == AMULET_CLASS && !uamul) {
2174 /*JP
2175                 You("are not wearing an amulet.");
2176 */
2177                 You("\96\82\8f\9c\82¯\82ð\90g\82É\82Â\82¯\82Ä\82¢\82È\82¢\81D");
2178                 return 0;
2179             } else if (oc_of_sym == TOOL_CLASS && !ublindf) {
2180 /*JP
2181                 You("are not wearing a blindfold.");
2182 */
2183                 You("\96Ú\89B\82µ\82ð\82µ\82Ä\82¢\82È\82¢\81D");
2184                 return 0;
2185             }
2186         }
2187
2188         if (oc_of_sym == COIN_CLASS && !combo) {
2189             context.botl = 1;
2190         } else if (sym == 'a') {
2191             allflag = TRUE;
2192         } else if (sym == 'A') {
2193             ; /* same as the default */
2194         } else if (sym == 'u') {
2195             add_valid_menu_class('u');
2196             ckfn = ckunpaid;
2197         } else if (index("BUCX", sym)) {
2198             add_valid_menu_class(sym); /* 'B','U','C',or 'X' */
2199             ckfn = ckvalidcat;
2200         } else if (sym == 'm') {
2201             m_seen = TRUE;
2202         } else if (oc_of_sym == MAXOCLASSES) {
2203 /*JP
2204             You("don't have any %c's.", sym);
2205 */
2206             You("%c\82É\91®\82·\82é\95¨\82ð\8e\9d\82Á\82Ä\82¢\82È\82¢\81D", sym);
2207         } else if (oc_of_sym != VENOM_CLASS) { /* suppress venom */
2208             if (!index(olets, oc_of_sym)) {
2209                 add_valid_menu_class(oc_of_sym);
2210                 olets[oletct++] = oc_of_sym;
2211                 olets[oletct] = 0;
2212             }
2213         }
2214     }
2215
2216     if (m_seen) {
2217         return (allflag
2218                 || (!oletct && ckfn != ckunpaid && ckfn != ckvalidcat))
2219                ? -2 : -3;
2220     } else if (flags.menu_style != MENU_TRADITIONAL && combo && !allflag) {
2221         return 0;
2222 #if 0
2223     /* !!!! test gold dropping */
2224     } else if (allowgold == 2 && !oletct) {
2225         return 1; /* you dropped gold (or at least tried to)  */
2226 #endif
2227     } else {
2228         int cnt = askchain(&invent, olets, allflag, fn, ckfn, mx, word);
2229         /*
2230          * askchain() has already finished the job in this case
2231          * so set a special flag to convey that back to the caller
2232          * so that it won't continue processing.
2233          * Fix for bug C331-1 reported by Irina Rempt-Drijfhout.
2234          */
2235         if (combo && allflag && resultflags)
2236             *resultflags |= ALL_FINISHED;
2237         return cnt;
2238     }
2239 }
2240
2241 /*
2242  * Walk through the chain starting at objchn and ask for all objects
2243  * with olet in olets (if nonNULL) and satisfying ckfn (if nonnull)
2244  * whether the action in question (i.e., fn) has to be performed.
2245  * If allflag then no questions are asked.  Mx gives the max number
2246  * of objects to be treated.  Return the number of objects treated.
2247  */
2248 /*JP CHECK: 3.6.0 \82Å\82Ì\8cÄ\82Ñ\8fo\82µ\8c³
2249 invent.c:1886:        int cnt = askchain(&invent, olets, allflag, fn, ckfn, mx, word);
2250 pickup.c:3145:        if (askchain(objlist, (one_by_one ? (char *) 0 : selection), allflag,
2251   word\82É\82Í\93®\8e\8c\82ª\89p\8cê\82Å\93ü\82é\81B
2252 */
2253 int
2254 askchain(objchn, olets, allflag, fn, ckfn, mx, word)
2255 struct obj **objchn; /* *objchn might change */
2256 int allflag, mx;
2257 const char *olets, *word; /* olets is an Obj Class char array */
2258 int FDECL((*fn), (OBJ_P)), FDECL((*ckfn), (OBJ_P));
2259 {
2260     struct obj *otmp, *otmpo;
2261     register char sym, ilet;
2262     int cnt = 0, dud = 0, tmp;
2263     boolean takeoff, nodot, ident, take_out, put_in, first, ininv, bycat;
2264     char qbuf[QBUFSZ], qpfx[QBUFSZ];
2265     Loot *sortedchn = 0;
2266
2267     takeoff = taking_off(word);
2268     ident = !strcmp(word, "identify");
2269     take_out = !strcmp(word, "take out");
2270     put_in = !strcmp(word, "put in");
2271     nodot = (!strcmp(word, "nodot") || !strcmp(word, "drop") || ident
2272              || takeoff || take_out || put_in);
2273     ininv = (*objchn == invent);
2274     bycat = (menu_class_present('u')
2275              || menu_class_present('B') || menu_class_present('U')
2276              || menu_class_present('C') || menu_class_present('X'));
2277
2278     /* someday maybe we'll sort by 'olets' too (temporarily replace
2279        flags.packorder and pass SORTLOOT_PACK), but not yet... */
2280     sortedchn = sortloot(objchn, SORTLOOT_INVLET, FALSE,
2281                          (boolean FDECL((*), (OBJ_P))) 0);
2282
2283     first = TRUE;
2284     /*
2285      * Interrogate in the object class order specified.
2286      * For example, if a person specifies =/ then first all rings
2287      * will be asked about followed by all wands.  -dgk
2288      */
2289  nextclass:
2290     ilet = 'a' - 1;
2291     if (*objchn && (*objchn)->oclass == COIN_CLASS)
2292         ilet--;                     /* extra iteration */
2293     /*
2294      * Multiple Drop can change the invent chain while it operates
2295      * (dropping a burning potion of oil while levitating creates
2296      * an explosion which can destroy inventory items), so simple
2297      * list traversal
2298      *  for (otmp = *objchn; otmp; otmp = otmp2) {
2299      *      otmp2 = otmp->nobj;
2300      *      ...
2301      *  }
2302      * is inadequate here.  Use each object's bypass bit to keep
2303      * track of which list elements have already been processed.
2304      */
2305     bypass_objlist(*objchn, FALSE); /* clear chain's bypass bits */
2306     while ((otmp = nxt_unbypassed_loot(sortedchn, *objchn)) != 0) {
2307         if (ilet == 'z')
2308             ilet = 'A';
2309         else if (ilet == 'Z')
2310             ilet = NOINVSYM; /* '#' */
2311         else
2312             ilet++;
2313         if (olets && *olets && otmp->oclass != *olets)
2314             continue;
2315         if (takeoff && !is_worn(otmp))
2316             continue;
2317         if (ident && !not_fully_identified(otmp))
2318             continue;
2319         if (ckfn && !(*ckfn)(otmp))
2320             continue;
2321         if (bycat && !ckvalidcat(otmp))
2322             continue;
2323         if (!allflag) {
2324             safeq_xprn_ctx.let = ilet;
2325             safeq_xprn_ctx.dot = !nodot;
2326             *qpfx = '\0';
2327             if (first) {
2328                 /* traditional_loot() skips prompting when only one
2329                    class of objects is involved, so prefix the first
2330                    object being queried here with an explanation why */
2331                 if (take_out || put_in)
2332                     Sprintf(qpfx, "%s: ", word), *qpfx = highc(*qpfx);
2333                 first = FALSE;
2334             }
2335 #if 0 /*JP*/
2336             (void) safe_qbuf(qbuf, qpfx, "?", otmp,
2337                              ininv ? safeq_xprname : doname,
2338                              ininv ? safeq_shortxprname : ansimpleoname,
2339                              "item");
2340 #else
2341             (void) safe_qbuf(qbuf, qpfx, "\81H", otmp,
2342                              ininv ? safeq_xprname : doname,
2343                              ininv ? safeq_shortxprname : ansimpleoname,
2344                              "\83A\83C\83e\83\80");
2345 #endif
2346             sym = (takeoff || ident || otmp->quan < 2L) ? nyaq(qbuf)
2347                                                         : nyNaq(qbuf);
2348         } else
2349             sym = 'y';
2350
2351         otmpo = otmp;
2352         if (sym == '#') {
2353             /* Number was entered; split the object unless it corresponds
2354                to 'none' or 'all'.  2 special cases: cursed loadstones and
2355                welded weapons (eg, multiple daggers) will remain as merged
2356                unit; done to avoid splitting an object that won't be
2357                droppable (even if we're picking up rather than dropping). */
2358             if (!yn_number) {
2359                 sym = 'n';
2360             } else {
2361                 sym = 'y';
2362                 if (yn_number < otmp->quan && splittable(otmp))
2363                     otmp = splitobj(otmp, yn_number);
2364             }
2365         }
2366         switch (sym) {
2367         case 'a':
2368             allflag = 1;
2369             /*FALLTHRU*/
2370         case 'y':
2371             tmp = (*fn)(otmp);
2372             if (tmp < 0) {
2373                 if (container_gone(fn)) {
2374                     /* otmp caused magic bag to explode;
2375                        both are now gone */
2376                     otmp = 0; /* and return */
2377                 } else if (otmp && otmp != otmpo) {
2378                     /* split occurred, merge again */
2379                     (void) merged(&otmpo, &otmp);
2380                 }
2381                 goto ret;
2382             }
2383             cnt += tmp;
2384             if (--mx == 0)
2385                 goto ret;
2386             /*FALLTHRU*/
2387         case 'n':
2388             if (nodot)
2389                 dud++;
2390         default:
2391             break;
2392         case 'q':
2393             /* special case for seffects() */
2394             if (ident)
2395                 cnt = -1;
2396             goto ret;
2397         }
2398     }
2399     if (olets && *olets && *++olets)
2400         goto nextclass;
2401
2402     if (!takeoff && (dud || cnt))
2403 /*JP
2404         pline("That was all.");
2405 */
2406         pline("\82±\82ê\82Å\91S\95\94\82¾\81D");
2407     else if (!dud && !cnt)
2408 /*JP
2409         pline("No applicable objects.");
2410 */
2411         pline("\82»\82ê\82Í\82Å\82«\82È\82¢\81D");
2412  ret:
2413     unsortloot(&sortedchn);
2414     bypass_objlist(*objchn, FALSE);
2415     return cnt;
2416 }
2417
2418 /*
2419  *      Object identification routines:
2420  */
2421
2422 /* make an object actually be identified; no display updating */
2423 void
2424 fully_identify_obj(otmp)
2425 struct obj *otmp;
2426 {
2427     makeknown(otmp->otyp);
2428     if (otmp->oartifact)
2429         discover_artifact((xchar) otmp->oartifact);
2430     otmp->known = otmp->dknown = otmp->bknown = otmp->rknown = 1;
2431     if (Is_container(otmp) || otmp->otyp == STATUE)
2432         otmp->cknown = otmp->lknown = 1;
2433     if (otmp->otyp == EGG && otmp->corpsenm != NON_PM)
2434         learn_egg_type(otmp->corpsenm);
2435 }
2436
2437 /* ggetobj callback routine; identify an object and give immediate feedback */
2438 int
2439 identify(otmp)
2440 struct obj *otmp;
2441 {
2442     fully_identify_obj(otmp);
2443     prinv((char *) 0, otmp, 0L);
2444     return 1;
2445 }
2446
2447 /* menu of unidentified objects; select and identify up to id_limit of them */
2448 STATIC_OVL void
2449 menu_identify(id_limit)
2450 int id_limit;
2451 {
2452     menu_item *pick_list;
2453     int n, i, first = 1, tryct = 5;
2454     char buf[BUFSZ];
2455     /* assumptions:  id_limit > 0 and at least one unID'd item is present */
2456
2457     while (id_limit) {
2458 #if 0 /*JP:T*/
2459         Sprintf(buf, "What would you like to identify %s?",
2460                 first ? "first" : "next");
2461 #else
2462         Sprintf(buf, "\82Ç\82ê\82ð%s\82É\8e¯\95Ê\82µ\82Ü\82·\82©\81H",
2463                 first ? "\8dÅ\8f\89" : "\8e\9f");
2464 #endif
2465         n = query_objlist(buf, &invent, (SIGNAL_NOMENU | SIGNAL_ESCAPE
2466                                          | USE_INVLET | INVORDER_SORT),
2467                           &pick_list, PICK_ANY, not_fully_identified);
2468
2469         if (n > 0) {
2470             if (n > id_limit)
2471                 n = id_limit;
2472             for (i = 0; i < n; i++, id_limit--)
2473                 (void) identify(pick_list[i].item.a_obj);
2474             free((genericptr_t) pick_list);
2475             mark_synch(); /* Before we loop to pop open another menu */
2476             first = 0;
2477         } else if (n == -2) { /* player used ESC to quit menu */
2478             break;
2479         } else if (n == -1) { /* no eligible items found */
2480 /*JP
2481             pline("That was all.");
2482 */
2483             pline("\82±\82ê\82Å\91S\95\94\82¾\81D");
2484             break;
2485         } else if (!--tryct) { /* stop re-prompting */
2486             pline1(thats_enough_tries);
2487             break;
2488         } else { /* try again */
2489 /*JP
2490             pline("Choose an item; use ESC to decline.");
2491 */
2492             pline("\83A\83C\83e\83\80\82ð\91I\82ñ\82Å\82­\82¾\82³\82¢;\82â\82ß\82é\82È\82çESC\81D");
2493         }
2494     }
2495 }
2496 /* count the unidentified items */
2497 int
2498 count_unidentified(objchn)
2499 struct obj *objchn;
2500 {
2501     int unid_cnt = 0;
2502     struct obj *obj;
2503
2504     for (obj = objchn; obj; obj = obj->nobj)
2505         if (not_fully_identified(obj))
2506             ++unid_cnt;
2507     return unid_cnt;
2508 }
2509
2510 /* dialog with user to identify a given number of items; 0 means all */
2511 void
2512 identify_pack(id_limit, learning_id)
2513 int id_limit;
2514 boolean learning_id; /* true if we just read unknown identify scroll */
2515 {
2516     struct obj *obj;
2517     int n, unid_cnt = count_unidentified(invent);
2518
2519     if (!unid_cnt) {
2520 #if 0 /*JP:T*/
2521         You("have already identified all %sof your possessions.",
2522             learning_id ? "the rest " : "");
2523 #else
2524         You("%s\91S\82Ä\82Ì\8f\8a\97L\95¨\82ð\8e¯\95Ê\82µ\82Ä\82µ\82Ü\82Á\82Ä\82¢\82é\81D",
2525             learning_id ? "\8ec\82è" : "");
2526 #endif
2527     } else if (!id_limit || id_limit >= unid_cnt) {
2528         /* identify everything */
2529         /* TODO:  use fully_identify_obj and cornline/menu/whatever here */
2530         for (obj = invent; obj; obj = obj->nobj) {
2531             if (not_fully_identified(obj)) {
2532                 (void) identify(obj);
2533                 if (unid_cnt == 1)
2534                     break;
2535             }
2536         }
2537     } else {
2538         /* identify up to `id_limit' items */
2539         n = 0;
2540         if (flags.menu_style == MENU_TRADITIONAL)
2541             do {
2542                 n = ggetobj("identify", identify, id_limit, FALSE,
2543                             (unsigned *) 0);
2544                 if (n < 0)
2545                     break; /* quit or no eligible items */
2546             } while ((id_limit -= n) > 0);
2547         if (n == 0 || n < -1)
2548             menu_identify(id_limit);
2549     }
2550     update_inventory();
2551 }
2552
2553 /* called when regaining sight; mark inventory objects which were picked
2554    up while blind as now having been seen */
2555 void
2556 learn_unseen_invent()
2557 {
2558     struct obj *otmp;
2559
2560     if (Blind)
2561         return; /* sanity check */
2562
2563     for (otmp = invent; otmp; otmp = otmp->nobj) {
2564         if (otmp->dknown)
2565             continue; /* already seen */
2566         /* set dknown, perhaps bknown (for priest[ess]) */
2567         (void) xname(otmp);
2568         /*
2569          * If object->eknown gets implemented (see learnwand(zap.c)),
2570          * handle deferred discovery here.
2571          */
2572     }
2573     update_inventory();
2574 }
2575
2576 /* should of course only be called for things in invent */
2577 STATIC_OVL char
2578 obj_to_let(obj)
2579 struct obj *obj;
2580 {
2581     if (!flags.invlet_constant) {
2582         obj->invlet = NOINVSYM;
2583         reassign();
2584     }
2585     return obj->invlet;
2586 }
2587
2588 /*
2589  * Print the indicated quantity of the given object.  If quan == 0L then use
2590  * the current quantity.
2591  */
2592 void
2593 prinv(prefix, obj, quan)
2594 const char *prefix;
2595 struct obj *obj;
2596 long quan;
2597 {
2598     if (!prefix)
2599         prefix = "";
2600 #if 0 /*JP*/
2601     pline("%s%s%s", prefix, *prefix ? " " : "",
2602           xprname(obj, (char *) 0, obj_to_let(obj), TRUE, 0L, quan));
2603 #else
2604     pline("%s%s",
2605           xprname(obj, (char *)0, obj_to_let(obj), *prefix ? FALSE : TRUE, 0L, quan),
2606           prefix);
2607 #endif
2608 }
2609
2610 char *
2611 xprname(obj, txt, let, dot, cost, quan)
2612 struct obj *obj;
2613 const char *txt; /* text to print instead of obj */
2614 char let;        /* inventory letter */
2615 boolean dot;     /* append period; (dot && cost => Iu) */
2616 long cost;       /* cost (for inventory of unpaid or expended items) */
2617 long quan;       /* if non-0, print this quantity, not obj->quan */
2618 {
2619 #ifdef LINT /* handle static char li[BUFSZ]; */
2620     char li[BUFSZ];
2621 #else
2622     static char li[BUFSZ];
2623 #endif
2624     boolean use_invlet = (flags.invlet_constant
2625                           && let != CONTAINED_SYM && let != HANDS_SYM);
2626     long savequan = 0;
2627
2628     if (quan && obj) {
2629         savequan = obj->quan;
2630         obj->quan = quan;
2631     }
2632     /*
2633      * If let is:
2634      *  -  Then obj == null and 'txt' refers to hands or fingers.
2635      *  *  Then obj == null and we are printing a total amount.
2636      *  >  Then the object is contained and doesn't have an inventory letter.
2637      */
2638     if (cost != 0 || let == '*') {
2639         /* if dot is true, we're doing Iu, otherwise Ix */
2640 #if 0 /*JP*/
2641         Sprintf(li,
2642                 iflags.menu_tab_sep ? "%c - %s\t%6ld %s"
2643                                     : "%c - %-45s %6ld %s",
2644                 (dot && use_invlet ? obj->invlet : let),
2645                 (txt ? txt : doname(obj)), cost, currency(cost));
2646 #else
2647         Sprintf(li,
2648                 iflags.menu_tab_sep ? "%c - %s\t%6ld%s"
2649                                     : "%c - %-45s %6ld%s",
2650                 (dot && use_invlet ? obj->invlet : let),
2651                 (txt ? txt : doname(obj)), cost, currency(cost));
2652 #endif
2653     } else {
2654         /* ordinary inventory display or pickup message */
2655         Sprintf(li, "%c - %s%s", (use_invlet ? obj->invlet : let),
2656 /*JP
2657                 (txt ? txt : doname(obj)), (dot ? "." : ""));
2658 */
2659                 (txt ? txt : doname(obj)), (dot ? "\81D" : ""));
2660     }
2661     if (savequan)
2662         obj->quan = savequan;
2663
2664     return li;
2665 }
2666
2667 /* the 'i' command */
2668 int
2669 ddoinv()
2670 {
2671     (void) display_inventory((char *) 0, FALSE);
2672     return 0;
2673 }
2674
2675 /*
2676  * find_unpaid()
2677  *
2678  * Scan the given list of objects.  If last_found is NULL, return the first
2679  * unpaid object found.  If last_found is not NULL, then skip over unpaid
2680  * objects until last_found is reached, then set last_found to NULL so the
2681  * next unpaid object is returned.  This routine recursively follows
2682  * containers.
2683  */
2684 STATIC_OVL struct obj *
2685 find_unpaid(list, last_found)
2686 struct obj *list, **last_found;
2687 {
2688     struct obj *obj;
2689
2690     while (list) {
2691         if (list->unpaid) {
2692             if (*last_found) {
2693                 /* still looking for previous unpaid object */
2694                 if (list == *last_found)
2695                     *last_found = (struct obj *) 0;
2696             } else
2697                 return ((*last_found = list));
2698         }
2699         if (Has_contents(list)) {
2700             if ((obj = find_unpaid(list->cobj, last_found)) != 0)
2701                 return obj;
2702         }
2703         list = list->nobj;
2704     }
2705     return (struct obj *) 0;
2706 }
2707
2708 /* for perm_invent when operating on a partial inventory display, so that
2709    the persistent one doesn't get shrunk during filtering for item selection
2710    then regrown to full inventory, possibly being resized in the process */
2711 static winid cached_pickinv_win = WIN_ERR;
2712
2713 void
2714 free_pickinv_cache()
2715 {
2716     if (cached_pickinv_win != WIN_ERR) {
2717         destroy_nhwindow(cached_pickinv_win);
2718         cached_pickinv_win = WIN_ERR;
2719     }
2720 }
2721
2722 /*
2723  * Internal function used by display_inventory and getobj that can display
2724  * inventory and return a count as well as a letter. If out_cnt is not null,
2725  * any count returned from the menu selection is placed here.
2726  */
2727 STATIC_OVL char
2728 display_pickinv(lets, xtra_choice, query, want_reply, out_cnt)
2729 register const char *lets;
2730 const char *xtra_choice; /* "fingers", pick hands rather than an object */
2731 const char *query;
2732 boolean want_reply;
2733 long *out_cnt;
2734 {
2735 /*JP
2736     static const char not_carrying_anything[] = "Not carrying anything";
2737 */
2738     static const char not_carrying_anything[] = "\89½\82à\8e\9d\82Á\82Ä\82¢\82È\82¢";
2739     struct obj *otmp, wizid_fakeobj;
2740     char ilet, ret;
2741     char *invlet = flags.inv_order;
2742     int n, classcount;
2743     winid win;                        /* windows being used */
2744     anything any;
2745     menu_item *selected;
2746     unsigned sortflags;
2747     Loot *sortedinvent, *srtinv;
2748     boolean wizid = FALSE;
2749
2750     if (lets && !*lets)
2751         lets = 0; /* simplify tests: (lets) instead of (lets && *lets) */
2752
2753     if (iflags.perm_invent && (lets || xtra_choice)) {
2754         /* partial inventory in perm_invent setting; don't operate on
2755            full inventory window, use an alternate one instead; create
2756            the first time needed and keep it for re-use as needed later */
2757         if (cached_pickinv_win == WIN_ERR)
2758             cached_pickinv_win = create_nhwindow(NHW_MENU);
2759         win = cached_pickinv_win;
2760     } else
2761         win = WIN_INVEN;
2762
2763     /*
2764      * Exit early if no inventory -- but keep going if we are doing
2765      * a permanent inventory update.  We need to keep going so the
2766      * permanent inventory window updates itself to remove the last
2767      * item(s) dropped.  One down side:  the addition of the exception
2768      * for permanent inventory window updates _can_ pop the window
2769      * up when it's not displayed -- even if it's empty -- because we
2770      * don't know at this level if its up or not.  This may not be
2771      * an issue if empty checks are done before hand and the call
2772      * to here is short circuited away.
2773      *
2774      * 2: our count here is only to distinguish between 0 and 1 and
2775      * more than 1; for the last one, we don't need a precise number.
2776      * For perm_invent update we force 'more than 1'.
2777      */
2778     n = (iflags.perm_invent && !lets && !want_reply) ? 2
2779         : lets ? (int) strlen(lets)
2780                : !invent ? 0 : !invent->nobj ? 1 : 2;
2781     /* for xtra_choice, there's another 'item' not included in initial 'n';
2782        for !lets (full invent) and for override_ID (wizard mode identify),
2783        skip message_menu handling of single item even if item count was 1 */
2784     if (xtra_choice || (n == 1 && (!lets || iflags.override_ID)))
2785         ++n;
2786
2787     if (n == 0) {
2788 /*JP
2789         pline("%s.", not_carrying_anything);
2790 */
2791         pline("%s\81D", not_carrying_anything);
2792         return 0;
2793     }
2794
2795     /* oxymoron? temporarily assign permanent inventory letters */
2796     if (!flags.invlet_constant)
2797         reassign();
2798
2799     if (n == 1 && !iflags.force_invmenu) {
2800         /* when only one item of interest, use pline instead of menus;
2801            we actually use a fake message-line menu in order to allow
2802            the user to perform selection at the --More-- prompt for tty */
2803         ret = '\0';
2804         if (xtra_choice) {
2805             /* xtra_choice is "bare hands" (wield), "fingertip" (Engrave),
2806                "nothing" (ready Quiver), or "fingers" (apply grease) */
2807             ret = message_menu(HANDS_SYM, PICK_ONE,
2808                                xprname((struct obj *) 0, xtra_choice,
2809                                        HANDS_SYM, TRUE, 0L, 0L)); /* '-' */
2810         } else {
2811             for (otmp = invent; otmp; otmp = otmp->nobj)
2812                 if (!lets || otmp->invlet == lets[0])
2813                     break;
2814             if (otmp)
2815                 ret = message_menu(otmp->invlet,
2816                                    want_reply ? PICK_ONE : PICK_NONE,
2817                                    xprname(otmp, (char *) 0, lets[0],
2818                                            TRUE, 0L, 0L));
2819         }
2820         if (out_cnt)
2821             *out_cnt = -1L; /* select all */
2822         return ret;
2823     }
2824
2825     sortflags = (flags.sortloot == 'f') ? SORTLOOT_LOOT : SORTLOOT_INVLET;
2826     if (flags.sortpack)
2827         sortflags |= SORTLOOT_PACK;
2828     sortedinvent = sortloot(&invent, sortflags, FALSE,
2829                             (boolean FDECL((*), (OBJ_P))) 0);
2830
2831     start_menu(win);
2832     any = zeroany;
2833     if (wizard && iflags.override_ID) {
2834         int unid_cnt;
2835         char prompt[QBUFSZ];
2836
2837         unid_cnt = count_unidentified(invent);
2838         Sprintf(prompt, "Debug Identify"); /* 'title' rather than 'prompt' */
2839         if (unid_cnt)
2840             Sprintf(eos(prompt),
2841                     " -- unidentified or partially identified item%s",
2842                     plur(unid_cnt));
2843         add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, prompt, MENU_UNSELECTED);
2844         if (!unid_cnt) {
2845             add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE,
2846                      "(all items are permanently identified already)",
2847                      MENU_UNSELECTED);
2848         } else {
2849             any.a_obj = &wizid_fakeobj;
2850             Sprintf(prompt, "select %s to permanently identify",
2851                     (unid_cnt == 1) ? "it": "any or all of them");
2852             /* wiz_identify stuffed the wiz_identify command character (^I)
2853                into iflags.override_ID for our use as an accelerator;
2854                it could be ambiguous if player has assigned a letter to
2855                the #wizidentify command */
2856             if (unid_cnt > 1)
2857                 Sprintf(eos(prompt), " (%s for all)",
2858                         visctrl(iflags.override_ID));
2859             add_menu(win, NO_GLYPH, &any, '_', iflags.override_ID, ATR_NONE,
2860                      prompt, MENU_UNSELECTED);
2861             wizid = TRUE;
2862         }
2863    } else if (xtra_choice) {
2864         /* wizard override ID and xtra_choice are mutually exclusive */
2865         if (flags.sortpack)
2866             add_menu(win, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
2867                      "Miscellaneous", MENU_UNSELECTED);
2868         any.a_char = HANDS_SYM; /* '-' */
2869         add_menu(win, NO_GLYPH, &any, HANDS_SYM, 0, ATR_NONE,
2870                  xtra_choice, MENU_UNSELECTED);
2871     }
2872  nextclass:
2873     classcount = 0;
2874     for (srtinv = sortedinvent; (otmp = srtinv->obj) != 0; ++srtinv) {
2875         if (lets && !index(lets, otmp->invlet))
2876             continue;
2877         if (!flags.sortpack || otmp->oclass == *invlet) {
2878             if (wizid && !not_fully_identified(otmp))
2879                 continue;
2880             any = zeroany; /* all bits zero */
2881             ilet = otmp->invlet;
2882             if (flags.sortpack && !classcount) {
2883                 add_menu(win, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
2884                          let_to_name(*invlet, FALSE,
2885                                      (want_reply && iflags.menu_head_objsym)),
2886                          MENU_UNSELECTED);
2887                 classcount++;
2888             }
2889             if (wizid)
2890                 any.a_obj = otmp;
2891             else
2892                 any.a_char = ilet;
2893             add_menu(win, obj_to_glyph(otmp, rn2_on_display_rng), &any, ilet,
2894                      wizid ? def_oc_syms[(int) otmp->oclass].sym : 0,
2895                      ATR_NONE, doname(otmp), MENU_UNSELECTED);
2896         }
2897     }
2898     if (flags.sortpack) {
2899         if (*++invlet)
2900             goto nextclass;
2901         if (--invlet != venom_inv) {
2902             invlet = venom_inv;
2903             goto nextclass;
2904         }
2905     }
2906     if (iflags.force_invmenu && lets && want_reply) {
2907         any = zeroany;
2908 #if 0 /*JP*/
2909         add_menu(win, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
2910                  "Special", MENU_UNSELECTED);
2911 #else
2912         add_menu(win, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
2913                  "\93Á\8eê", MENU_UNSELECTED);
2914 #endif
2915         any.a_char = '*';
2916 #if 0 /*JP*/
2917         add_menu(win, NO_GLYPH, &any, '*', 0, ATR_NONE,
2918                  "(list everything)", MENU_UNSELECTED);
2919 #else
2920         add_menu(win, NO_GLYPH, &any, '*', 0, ATR_NONE,
2921                  "(\91S\82Ä\82Ì\88ê\97\97)", MENU_UNSELECTED);
2922 #endif
2923     }
2924     unsortloot(&sortedinvent);
2925     /* for permanent inventory where we intend to show everything but
2926        nothing has been listed (because there isn't anyhing to list;
2927        recognized via any.a_char still being zero; the n==0 case above
2928        gets skipped for perm_invent), put something into the menu */
2929     if (iflags.perm_invent && !lets && !any.a_char) {
2930         any = zeroany;
2931         add_menu(win, NO_GLYPH, &any, 0, 0, 0,
2932                  not_carrying_anything, MENU_UNSELECTED);
2933         want_reply = FALSE;
2934     }
2935     end_menu(win, query && *query ? query : (char *) 0);
2936
2937     n = select_menu(win,
2938                     wizid ? PICK_ANY : want_reply ? PICK_ONE : PICK_NONE,
2939                     &selected);
2940     if (n > 0) {
2941         if (wizid) {
2942             int i;
2943
2944             ret = '\0';
2945             for (i = 0; i < n; ++i) {
2946                 otmp = selected[i].item.a_obj;
2947                 if (otmp == &wizid_fakeobj) {
2948                     identify_pack(0, FALSE);
2949                 } else {
2950                     if (not_fully_identified(otmp))
2951                         (void) identify(otmp);
2952                 }
2953             }
2954         } else {
2955             ret = selected[0].item.a_char;
2956             if (out_cnt)
2957                 *out_cnt = selected[0].count;
2958         }
2959         free((genericptr_t) selected);
2960     } else
2961         ret = !n ? '\0' : '\033'; /* cancelled */
2962
2963     return ret;
2964 }
2965
2966 /*
2967  * If lets == NULL or "", list all objects in the inventory.  Otherwise,
2968  * list all objects with object classes that match the order in lets.
2969  *
2970  * Returns the letter identifier of a selected item, or 0 if nothing
2971  * was selected.
2972  */
2973 char
2974 display_inventory(lets, want_reply)
2975 const char *lets;
2976 boolean want_reply;
2977 {
2978     return display_pickinv(lets, (char *) 0, (char *) 0,
2979                            want_reply, (long *) 0);
2980 }
2981
2982 /*
2983  * Show what is current using inventory letters.
2984  *
2985  */
2986 STATIC_OVL char
2987 display_used_invlets(avoidlet)
2988 char avoidlet;
2989 {
2990     struct obj *otmp;
2991     char ilet, ret = 0;
2992     char *invlet = flags.inv_order;
2993     int n, classcount, invdone = 0;
2994     winid win;
2995     anything any;
2996     menu_item *selected;
2997
2998     if (invent) {
2999         win = create_nhwindow(NHW_MENU);
3000         start_menu(win);
3001         while (!invdone) {
3002             any = zeroany; /* set all bits to zero */
3003             classcount = 0;
3004             for (otmp = invent; otmp; otmp = otmp->nobj) {
3005                 ilet = otmp->invlet;
3006                 if (ilet == avoidlet)
3007                     continue;
3008                 if (!flags.sortpack || otmp->oclass == *invlet) {
3009                     if (flags.sortpack && !classcount) {
3010                         any = zeroany; /* zero */
3011                         add_menu(win, NO_GLYPH, &any, 0, 0,
3012                                  iflags.menu_headings,
3013                                  let_to_name(*invlet, FALSE, FALSE),
3014                                  MENU_UNSELECTED);
3015                         classcount++;
3016                     }
3017                     any.a_char = ilet;
3018                     add_menu(win, obj_to_glyph(otmp, rn2_on_display_rng),
3019                              &any, ilet, 0, ATR_NONE,
3020                              doname(otmp), MENU_UNSELECTED);
3021                 }
3022             }
3023             if (flags.sortpack && *++invlet)
3024                 continue;
3025             invdone = 1;
3026         }
3027         end_menu(win, "Inventory letters used:");
3028
3029         n = select_menu(win, PICK_ONE, &selected);
3030         if (n > 0) {
3031             ret = selected[0].item.a_char;
3032             free((genericptr_t) selected);
3033         } else
3034             ret = !n ? '\0' : '\033'; /* cancelled */
3035         destroy_nhwindow(win);
3036     }
3037     return ret;
3038 }
3039
3040 /*
3041  * Returns the number of unpaid items within the given list.  This includes
3042  * contained objects.
3043  */
3044 int
3045 count_unpaid(list)
3046 struct obj *list;
3047 {
3048     int count = 0;
3049
3050     while (list) {
3051         if (list->unpaid)
3052             count++;
3053         if (Has_contents(list))
3054             count += count_unpaid(list->cobj);
3055         list = list->nobj;
3056     }
3057     return count;
3058 }
3059
3060 /*
3061  * Returns the number of items with b/u/c/unknown within the given list.
3062  * This does NOT include contained objects.
3063  *
3064  * Assumes that the hero sees or touches or otherwise senses the objects
3065  * at some point:  bknown is forced for priest[ess], like in xname().
3066  */
3067 int
3068 count_buc(list, type, filterfunc)
3069 struct obj *list;
3070 int type;
3071 boolean FDECL((*filterfunc), (OBJ_P));
3072 {
3073     int count = 0;
3074
3075     for (; list; list = list->nobj) {
3076         /* priests always know bless/curse state */
3077         if (Role_if(PM_PRIEST))
3078             list->bknown = (list->oclass != COIN_CLASS);
3079         /* some actions exclude some or most items */
3080         if (filterfunc && !(*filterfunc)(list))
3081             continue;
3082
3083         /* coins are either uncursed or unknown based upon option setting */
3084         if (list->oclass == COIN_CLASS) {
3085             if (type == (iflags.goldX ? BUC_UNKNOWN : BUC_UNCURSED))
3086                 ++count;
3087             continue;
3088         }
3089         /* check whether this object matches the requested type */
3090         if (!list->bknown
3091                 ? (type == BUC_UNKNOWN)
3092                 : list->blessed ? (type == BUC_BLESSED)
3093                                 : list->cursed ? (type == BUC_CURSED)
3094                                                : (type == BUC_UNCURSED))
3095             ++count;
3096     }
3097     return count;
3098 }
3099
3100 /* similar to count_buc(), but tallies all states at once
3101    rather than looking for a specific type */
3102 void
3103 tally_BUCX(list, by_nexthere, bcp, ucp, ccp, xcp, ocp)
3104 struct obj *list;
3105 boolean by_nexthere;
3106 int *bcp, *ucp, *ccp, *xcp, *ocp;
3107 {
3108     /* Future extensions:
3109      *  Skip current_container when list is invent, uchain when
3110      *  first object of list is located on the floor.  'ocp' will then
3111      *  have a function again (it was a counter for having skipped gold,
3112      *  but that's not skipped anymore).
3113      */
3114     *bcp = *ucp = *ccp = *xcp = *ocp = 0;
3115     for ( ; list; list = (by_nexthere ? list->nexthere : list->nobj)) {
3116         /* priests always know bless/curse state */
3117         if (Role_if(PM_PRIEST))
3118             list->bknown = (list->oclass != COIN_CLASS);
3119         /* coins are either uncursed or unknown based upon option setting */
3120         if (list->oclass == COIN_CLASS) {
3121             if (iflags.goldX)
3122                 ++(*xcp);
3123             else
3124                 ++(*ucp);
3125             continue;
3126         }
3127         /* ordinary items */
3128         if (!list->bknown)
3129             ++(*xcp);
3130         else if (list->blessed)
3131             ++(*bcp);
3132         else if (list->cursed)
3133             ++(*ccp);
3134         else /* neither blessed nor cursed => uncursed */
3135             ++(*ucp);
3136     }
3137 }
3138
3139 /* count everything inside a container, or just shop-owned items inside */
3140 long
3141 count_contents(container, nested, quantity, everything)
3142 struct obj *container;
3143 boolean nested, /* include contents of any nested containers */
3144     quantity,   /* count all vs count separate stacks */
3145     everything; /* all objects vs only unpaid objects */
3146 {
3147     struct obj *otmp, *topc;
3148     boolean shoppy = FALSE;
3149     long count = 0L;
3150
3151     if (!everything) {
3152         for (topc = container; topc->where == OBJ_CONTAINED;
3153              topc = topc->ocontainer)
3154             continue;
3155         if (topc->where == OBJ_FLOOR) {
3156             xchar x, y;
3157
3158             (void) get_obj_location(topc, &x, &y, CONTAINED_TOO);
3159             shoppy = costly_spot(x, y);
3160         }
3161     }
3162     for (otmp = container->cobj; otmp; otmp = otmp->nobj) {
3163         if (nested && Has_contents(otmp))
3164             count += count_contents(otmp, nested, quantity, everything);
3165         if (everything || otmp->unpaid || (shoppy && !otmp->no_charge))
3166             count += quantity ? otmp->quan : 1L;
3167     }
3168     return count;
3169 }
3170
3171 STATIC_OVL void
3172 dounpaid()
3173 {
3174     winid win;
3175     struct obj *otmp, *marker, *contnr;
3176     register char ilet;
3177     char *invlet = flags.inv_order;
3178     int classcount, count, num_so_far;
3179     long cost, totcost;
3180
3181     count = count_unpaid(invent);
3182     otmp = marker = contnr = (struct obj *) 0;
3183
3184     if (count == 1) {
3185         otmp = find_unpaid(invent, &marker);
3186         contnr = unknwn_contnr_contents(otmp);
3187     }
3188     if  (otmp && !contnr) {
3189         /* 1 item; use pline instead of popup menu */
3190         cost = unpaid_cost(otmp, FALSE);
3191         iflags.suppress_price++; /* suppress "(unpaid)" suffix */
3192         pline1(xprname(otmp, distant_name(otmp, doname),
3193                        carried(otmp) ? otmp->invlet : CONTAINED_SYM,
3194                        TRUE, cost, 0L));
3195         iflags.suppress_price--;
3196         return;
3197     }
3198
3199     win = create_nhwindow(NHW_MENU);
3200     cost = totcost = 0;
3201     num_so_far = 0; /* count of # printed so far */
3202     if (!flags.invlet_constant)
3203         reassign();
3204
3205     do {
3206         classcount = 0;
3207         for (otmp = invent; otmp; otmp = otmp->nobj) {
3208             ilet = otmp->invlet;
3209             if (otmp->unpaid) {
3210                 if (!flags.sortpack || otmp->oclass == *invlet) {
3211                     if (flags.sortpack && !classcount) {
3212                         putstr(win, 0, let_to_name(*invlet, TRUE, FALSE));
3213                         classcount++;
3214                     }
3215
3216                     totcost += cost = unpaid_cost(otmp, FALSE);
3217                     iflags.suppress_price++; /* suppress "(unpaid)" suffix */
3218                     putstr(win, 0, xprname(otmp, distant_name(otmp, doname),
3219                                            ilet, TRUE, cost, 0L));
3220                     iflags.suppress_price--;
3221                     num_so_far++;
3222                 }
3223             }
3224         }
3225     } while (flags.sortpack && (*++invlet));
3226
3227     if (count > num_so_far) {
3228         /* something unpaid is contained */
3229         if (flags.sortpack)
3230             putstr(win, 0, let_to_name(CONTAINED_SYM, TRUE, FALSE));
3231         /*
3232          * Search through the container objects in the inventory for
3233          * unpaid items.  The top level inventory items have already
3234          * been listed.
3235          */
3236         for (otmp = invent; otmp; otmp = otmp->nobj) {
3237             if (Has_contents(otmp)) {
3238                 long contcost = 0L;
3239
3240                 marker = (struct obj *) 0; /* haven't found any */
3241                 while (find_unpaid(otmp->cobj, &marker)) {
3242                     totcost += cost = unpaid_cost(marker, FALSE);
3243                     contcost += cost;
3244                     if (otmp->cknown) {
3245                         iflags.suppress_price++; /* suppress "(unpaid)" sfx */
3246                         putstr(win, 0,
3247                                xprname(marker, distant_name(marker, doname),
3248                                        CONTAINED_SYM, TRUE, cost, 0L));
3249                         iflags.suppress_price--;
3250                     }
3251                 }
3252                 if (!otmp->cknown) {
3253                     char contbuf[BUFSZ];
3254
3255                     /* Shopkeeper knows what to charge for contents */
3256                     Sprintf(contbuf, "%s contents", s_suffix(xname(otmp)));
3257                     putstr(win, 0,
3258                            xprname((struct obj *) 0, contbuf, CONTAINED_SYM,
3259                                    TRUE, contcost, 0L));
3260                 }
3261             }
3262         }
3263     }
3264
3265     putstr(win, 0, "");
3266 #if 0 /*JP*/
3267     putstr(win, 0,
3268            xprname((struct obj *) 0, "Total:", '*', FALSE, totcost, 0L));
3269 #else
3270     putstr(win, 0,
3271            xprname((struct obj *) 0, "\8d\87\8cv\81F", '*', FALSE, totcost, 0L));
3272 #endif
3273     display_nhwindow(win, FALSE);
3274     destroy_nhwindow(win);
3275 }
3276
3277 /* query objlist callback: return TRUE if obj type matches "this_type" */
3278 static int this_type;
3279
3280 STATIC_OVL boolean
3281 this_type_only(obj)
3282 struct obj *obj;
3283 {
3284     boolean res = (obj->oclass == this_type);
3285
3286     if (obj->oclass == COIN_CLASS) {
3287         /* if filtering by bless/curse state, gold is classified as
3288            either unknown or uncursed based on user option setting */
3289         if (this_type && index("BUCX", this_type))
3290             res = (this_type == (iflags.goldX ? 'X' : 'U'));
3291     } else {
3292         switch (this_type) {
3293         case 'B':
3294             res = (obj->bknown && obj->blessed);
3295             break;
3296         case 'U':
3297             res = (obj->bknown && !(obj->blessed || obj->cursed));
3298             break;
3299         case 'C':
3300             res = (obj->bknown && obj->cursed);
3301             break;
3302         case 'X':
3303             res = !obj->bknown;
3304             break;
3305         default:
3306             break; /* use 'res' as-is */
3307         }
3308     }
3309     return res;
3310 }
3311
3312 /* the 'I' command */
3313 int
3314 dotypeinv()
3315 {
3316     char c = '\0';
3317     int n, i = 0;
3318     char *extra_types, types[BUFSZ];
3319     int class_count, oclass, unpaid_count, itemcount;
3320     int bcnt, ccnt, ucnt, xcnt, ocnt;
3321     boolean billx = *u.ushops && doinvbill(0);
3322     menu_item *pick_list;
3323     boolean traditional = TRUE;
3324 /*JP
3325     const char *prompt = "What type of object do you want an inventory of?";
3326 */
3327     const char *prompt = "\82Ç\82Ì\8eí\97Þ\82Ì\8e\9d\82¿\95¨\82ð\8c©\82Ü\82·\82©\81H";
3328
3329     if (!invent && !billx) {
3330 /*JP
3331         You("aren't carrying anything.");
3332 */
3333         You("\82»\82Ì\8eí\97Þ\82Ì\95¨\82Í\89½\82à\8e\9d\82Á\82Ä\82¢\82È\82¢\81D");
3334         return 0;
3335     }
3336     unpaid_count = count_unpaid(invent);
3337     tally_BUCX(invent, FALSE, &bcnt, &ucnt, &ccnt, &xcnt, &ocnt);
3338
3339     if (flags.menu_style != MENU_TRADITIONAL) {
3340         if (flags.menu_style == MENU_FULL
3341             || flags.menu_style == MENU_PARTIAL) {
3342             traditional = FALSE;
3343             i = UNPAID_TYPES;
3344             if (billx)
3345                 i |= BILLED_TYPES;
3346             if (bcnt)
3347                 i |= BUC_BLESSED;
3348             if (ucnt)
3349                 i |= BUC_UNCURSED;
3350             if (ccnt)
3351                 i |= BUC_CURSED;
3352             if (xcnt)
3353                 i |= BUC_UNKNOWN;
3354             n = query_category(prompt, invent, i, &pick_list, PICK_ONE);
3355             if (!n)
3356                 return 0;
3357             this_type = c = pick_list[0].item.a_int;
3358             free((genericptr_t) pick_list);
3359         }
3360     }
3361     if (traditional) {
3362         /* collect a list of classes of objects carried, for use as a prompt
3363          */
3364         types[0] = 0;
3365         class_count = collect_obj_classes(types, invent, FALSE,
3366                                           (boolean FDECL((*), (OBJ_P))) 0,
3367                                           &itemcount);
3368         if (unpaid_count || billx || (bcnt + ccnt + ucnt + xcnt) != 0)
3369             types[class_count++] = ' ';
3370         if (unpaid_count)
3371             types[class_count++] = 'u';
3372         if (billx)
3373             types[class_count++] = 'x';
3374         if (bcnt)
3375             types[class_count++] = 'B';
3376         if (ucnt)
3377             types[class_count++] = 'U';
3378         if (ccnt)
3379             types[class_count++] = 'C';
3380         if (xcnt)
3381             types[class_count++] = 'X';
3382         types[class_count] = '\0';
3383         /* add everything not already included; user won't see these */
3384         extra_types = eos(types);
3385         *extra_types++ = '\033';
3386         if (!unpaid_count)
3387             *extra_types++ = 'u';
3388         if (!billx)
3389             *extra_types++ = 'x';
3390         if (!bcnt)
3391             *extra_types++ = 'B';
3392         if (!ucnt)
3393             *extra_types++ = 'U';
3394         if (!ccnt)
3395             *extra_types++ = 'C';
3396         if (!xcnt)
3397             *extra_types++ = 'X';
3398         *extra_types = '\0'; /* for index() */
3399         for (i = 0; i < MAXOCLASSES; i++)
3400             if (!index(types, def_oc_syms[i].sym)) {
3401                 *extra_types++ = def_oc_syms[i].sym;
3402                 *extra_types = '\0';
3403             }
3404
3405         if (class_count > 1) {
3406             c = yn_function(prompt, types, '\0');
3407             savech(c);
3408             if (c == '\0') {
3409                 clear_nhwindow(WIN_MESSAGE);
3410                 return 0;
3411             }
3412         } else {
3413             /* only one thing to itemize */
3414             if (unpaid_count)
3415                 c = 'u';
3416             else if (billx)
3417                 c = 'x';
3418             else
3419                 c = types[0];
3420         }
3421     }
3422     if (c == 'x' || (c == 'X' && billx && !xcnt)) {
3423         if (billx)
3424             (void) doinvbill(1);
3425         else
3426 #if 0 /*JP*/
3427             pline("No used-up objects%s.",
3428                   unpaid_count ? " on your shopping bill" : "");
3429 #else
3430           pline("\8eg\82Á\82Ä\82µ\82Ü\82Á\82½\95¨\82Í%s\82È\82¢\81D",
3431                   unpaid_count ? "\8f¤\93X\82Ì\90¿\8b\81\8f\91\82É\82Í" : "");
3432 #endif
3433         return 0;
3434     }
3435     if (c == 'u' || (c == 'U' && unpaid_count && !ucnt)) {
3436         if (unpaid_count)
3437             dounpaid();
3438         else
3439 /*JP
3440             You("are not carrying any unpaid objects.");
3441 */
3442             You("\96¢\95¥\82¢\82Ì\83A\83C\83e\83\80\82ð\8e\9d\82Á\82Ä\82¢\82È\82¢\81D");
3443         return 0;
3444     }
3445     if (traditional) {
3446         if (index("BUCX", c))
3447             oclass = c; /* not a class but understood by this_type_only() */
3448         else
3449             oclass = def_char_to_objclass(c); /* change to object class */
3450
3451         if (oclass == COIN_CLASS)
3452             return doprgold();
3453         if (index(types, c) > index(types, '\033')) {
3454             /* '> ESC' => hidden choice, something known not to be carried */
3455             const char *before = "", *after = "";
3456
3457             switch (c) {
3458             case 'B':
3459 /*JP
3460                 before = "known to be blessed ";
3461 */
3462                 before = "\8fj\95\9f\82³\82ê\82Ä\82¢\82é\82Æ\82í\82©\82Á\82Ä\82¢\82é";
3463                 break;
3464             case 'U':
3465 /*JP
3466                 before = "known to be uncursed ";
3467 */
3468                 before = "\8eô\82í\82ê\82Ä\82¢\82È\82¢\82Æ\82í\82©\82Á\82Ä\82¢\82é";
3469                 break;
3470             case 'C':
3471 /*JP
3472                 before = "known to be cursed ";
3473 */
3474                 before = "\8eô\82í\82ê\82Ä\82¢\82é\82Æ\82í\82©\82Á\82Ä\82¢\82é";
3475                 break;
3476             case 'X':
3477 /*JP
3478                 after = " whose blessed/uncursed/cursed status is unknown";
3479 */
3480                 after = "\8fj\95\9f\81^\8eô\82¢\82ª\82í\82©\82ç\82È\82¢";
3481                 break; /* better phrasing is desirable */
3482             default:
3483                 /* 'c' is an object class, because we've already handled
3484                    all the non-class letters which were put into 'types[]';
3485                    could/should move object class names[] array from below
3486                    to somewhere above so that we can access it here (via
3487                    lcase(strcpy(classnamebuf, names[(int) c]))), but the
3488                    game-play value of doing so is low... */
3489 /*JP
3490                 before = "such ";
3491 */
3492                 before = "\82»\82Ì\82æ\82¤\82È";
3493                 break;
3494             }
3495 /*JP
3496             You("have no %sobjects%s.", before, after);
3497 */
3498                 You("%s%s\82à\82Ì\82Í\89½\82à\8e\9d\82Á\82Ä\82¢\82È\82¢\81D", before, after);
3499             return 0;
3500         }
3501         this_type = oclass;
3502     }
3503     if (query_objlist((char *) 0, &invent,
3504                       ((flags.invlet_constant ? USE_INVLET : 0)
3505                        | INVORDER_SORT),
3506                       &pick_list, PICK_NONE, this_type_only) > 0)
3507         free((genericptr_t) pick_list);
3508     return 0;
3509 }
3510
3511 /* return a string describing the dungeon feature at <x,y> if there
3512    is one worth mentioning at that location; otherwise null */
3513 const char *
3514 dfeature_at(x, y, buf)
3515 int x, y;
3516 char *buf;
3517 {
3518     struct rm *lev = &levl[x][y];
3519     int ltyp = lev->typ, cmap = -1;
3520     const char *dfeature = 0;
3521     static char altbuf[BUFSZ];
3522
3523     if (IS_DOOR(ltyp)) {
3524         switch (lev->doormask) {
3525         case D_NODOOR:
3526             cmap = S_ndoor;
3527             break; /* "doorway" */
3528         case D_ISOPEN:
3529             cmap = S_vodoor;
3530             break; /* "open door" */
3531         case D_BROKEN:
3532 /*JP
3533             dfeature = "broken door";
3534 */
3535             dfeature = "\89ó\82ê\82½\94à";
3536             break;
3537         default:
3538             cmap = S_vcdoor;
3539             break; /* "closed door" */
3540         }
3541         /* override door description for open drawbridge */
3542         if (is_drawbridge_wall(x, y) >= 0)
3543 /*JP
3544             dfeature = "open drawbridge portcullis", cmap = -1;
3545 */
3546             dfeature = "\8d~\82è\82Ä\82¢\82é\92µ\82Ë\8b´", cmap = -1;
3547     } else if (IS_FOUNTAIN(ltyp))
3548         cmap = S_fountain; /* "fountain" */
3549     else if (IS_THRONE(ltyp))
3550         cmap = S_throne; /* "opulent throne" */
3551     else if (is_lava(x, y))
3552         cmap = S_lava; /* "molten lava" */
3553     else if (is_ice(x, y))
3554         cmap = S_ice; /* "ice" */
3555     else if (is_pool(x, y))
3556 /*JP
3557         dfeature = "pool of water";
3558 */
3559         dfeature = "\90\85\82½\82Ü\82è";
3560     else if (IS_SINK(ltyp))
3561         cmap = S_sink; /* "sink" */
3562     else if (IS_ALTAR(ltyp)) {
3563 #if 0 /*JP*/
3564         Sprintf(altbuf, "%saltar to %s (%s)",
3565                 ((lev->altarmask & AM_SHRINE)
3566                  && (Is_astralevel(&u.uz) || Is_sanctum(&u.uz)))
3567                     ? "high "
3568                     : "",
3569                 a_gname(),
3570                 align_str(Amask2align(lev->altarmask & ~AM_SHRINE)));
3571 #else
3572         Sprintf(altbuf, "%s%s\82Ì\8dÕ\92d(%s)",
3573                 ((lev->altarmask & AM_SHRINE)
3574                  && (Is_astralevel(&u.uz) || Is_sanctum(&u.uz)))
3575                     ? "\8d\82\88Ê\82Ì"
3576                     : "",
3577                 a_gname(),
3578                 align_str(Amask2align(lev->altarmask & ~AM_SHRINE)));
3579 #endif
3580         dfeature = altbuf;
3581     } else if ((x == xupstair && y == yupstair)
3582                || (x == sstairs.sx && y == sstairs.sy && sstairs.up))
3583         cmap = S_upstair; /* "staircase up" */
3584     else if ((x == xdnstair && y == ydnstair)
3585              || (x == sstairs.sx && y == sstairs.sy && !sstairs.up))
3586         cmap = S_dnstair; /* "staircase down" */
3587     else if (x == xupladder && y == yupladder)
3588         cmap = S_upladder; /* "ladder up" */
3589     else if (x == xdnladder && y == ydnladder)
3590         cmap = S_dnladder; /* "ladder down" */
3591     else if (ltyp == DRAWBRIDGE_DOWN)
3592         cmap = S_vodbridge; /* "lowered drawbridge" */
3593     else if (ltyp == DBWALL)
3594         cmap = S_vcdbridge; /* "raised drawbridge" */
3595     else if (IS_GRAVE(ltyp))
3596         cmap = S_grave; /* "grave" */
3597     else if (ltyp == TREE)
3598         cmap = S_tree; /* "tree" */
3599     else if (ltyp == IRONBARS)
3600 /*JP
3601         dfeature = "set of iron bars";
3602 */
3603         dfeature = "\93S\82Ì\96_";
3604
3605     if (cmap >= 0)
3606         dfeature = defsyms[cmap].explanation;
3607     if (dfeature)
3608         Strcpy(buf, dfeature);
3609     return dfeature;
3610 }
3611
3612 /* look at what is here; if there are many objects (pile_limit or more),
3613    don't show them unless obj_cnt is 0 */
3614 int
3615 look_here(obj_cnt, picked_some)
3616 int obj_cnt; /* obj_cnt > 0 implies that autopickup is in progress */
3617 boolean picked_some;
3618 {
3619     struct obj *otmp;
3620     struct trap *trap;
3621 #if 0 /*JP:C*/
3622     const char *verb = Blind ? "feel" : "see";
3623 #else
3624     const char *verb = Blind ? "\82ª\82 \82é\82æ\82¤\82È\8bC\82ª\82µ\82½" : "\82ð\82Ý\82Â\82¯\82½";
3625 #endif
3626     const char *dfeature = (char *) 0;
3627     char fbuf[BUFSZ], fbuf2[BUFSZ];
3628     winid tmpwin;
3629     boolean skip_objects, felt_cockatrice = FALSE;
3630
3631     /* default pile_limit is 5; a value of 0 means "never skip"
3632        (and 1 effectively forces "always skip") */
3633     skip_objects = (flags.pile_limit > 0 && obj_cnt >= flags.pile_limit);
3634     if (u.uswallow && u.ustuck) {
3635         struct monst *mtmp = u.ustuck;
3636
3637 #if 0 /*JP:T*/
3638         Sprintf(fbuf, "Contents of %s %s", s_suffix(mon_nam(mtmp)),
3639                 mbodypart(mtmp, STOMACH));
3640 #else
3641         Sprintf(fbuf, "%s\82Ì%s\82Ì\92\86\90g", mon_nam(mtmp),
3642                 mbodypart(mtmp, STOMACH));
3643 #endif
3644 #if 0 /*JP*//*\8cê\8f\87\82ª\88á\82¤\82Ì\82Å\91f\92¼\82É*/
3645         /* Skip "Contents of " by using fbuf index 12 */
3646         You("%s to %s what is lying in %s.", Blind ? "try" : "look around",
3647             verb, &fbuf[12]);
3648 #else
3649         You("%s\82Ì%s\82É\89½\82ª\82 \82é\82©%s\81D",
3650             mon_nam(mtmp), mbodypart(mtmp, STOMACH),
3651             Blind ? "\82³\82®\82Á\82½" : "\8c©\89ñ\82µ\82½");
3652 #endif
3653         otmp = mtmp->minvent;
3654         if (otmp) {
3655             for (; otmp; otmp = otmp->nobj) {
3656                 /* If swallower is an animal, it should have become stone
3657                  * but... */
3658                 if (otmp->otyp == CORPSE)
3659                     feel_cockatrice(otmp, FALSE);
3660             }
3661 #if 0 /*JP*/
3662             if (Blind)
3663                 Strcpy(fbuf, "You feel");
3664             Strcat(fbuf, ":");
3665 #else
3666             Sprintf(fbuf, "\82±\82±\82É\82 \82é%s\82à\82Ì\82Í\81F", Blind ? "\82ç\82µ\82¢" : "");
3667 #endif
3668             (void) display_minventory(mtmp, MINV_ALL | PICK_NONE, fbuf);
3669         } else {
3670 #if 0 /*JP*/
3671             You("%s no objects here.", verb);
3672 #else
3673             pline(Blind ? "\82 \82È\82½\82Í\89½\82à\82È\82¢\82æ\82¤\82È\8bC\82ª\82µ\82½\81D"
3674                   : "\82 \82È\82½\82Í\89½\82à\82Ý\82Â\82¯\82ç\82ê\82È\82©\82Á\82½\81D");
3675 #endif
3676         }
3677         return !!Blind;
3678     }
3679     if (!skip_objects && (trap = t_at(u.ux, u.uy)) && trap->tseen)
3680 /*JP
3681         There("is %s here.",
3682 */
3683         pline("\82±\82±\82É\82Í%s\82ª\82 \82é\81D",
3684               an(defsyms[trap_to_defsym(trap->ttyp)].explanation));
3685
3686     otmp = level.objects[u.ux][u.uy];
3687     dfeature = dfeature_at(u.ux, u.uy, fbuf2);
3688 /*JP
3689     if (dfeature && !strcmp(dfeature, "pool of water") && Underwater)
3690 */
3691     if (dfeature && !strcmp(dfeature, "\90\85\82½\82Ü\82è") && Underwater)
3692         dfeature = 0;
3693
3694     if (Blind) {
3695         boolean drift = Is_airlevel(&u.uz) || Is_waterlevel(&u.uz);
3696
3697 /*JP
3698         if (dfeature && !strncmp(dfeature, "altar ", 6)) {
3699 */
3700         if (dfeature && !strncmp(dfeature, "\8dÕ\92d", 4)) {
3701             /* don't say "altar" twice, dfeature has more info */
3702 /*JP
3703             You("try to feel what is here.");
3704 */
3705             You("\82±\82±\82É\89½\82ª\82 \82é\82Ì\82©\92²\82×\82æ\82¤\82Æ\82µ\82½\81D");
3706         } else {
3707 #if 0 /*JP*/
3708             const char *where = (Blind && !can_reach_floor(TRUE))
3709                                     ? "lying beneath you"
3710                                     : "lying here on the ",
3711                        *onwhat = (Blind && !can_reach_floor(TRUE))
3712                                      ? ""
3713                                      : surface(u.ux, u.uy);
3714
3715             You("try to feel what is %s%s.", drift ? "floating here" : where,
3716                 drift ? "" : onwhat);
3717 #else
3718             if (drift) {
3719                 You("\89½\82ª\95\82\82¢\82Ä\82¢\82é\82Ì\82©\92²\82×\82æ\82¤\82Æ\82µ\82½\81D");
3720             } else if (Blind && !can_reach_floor(TRUE)) {
3721                 You("\89½\82ª\91«\89º\82É\82 \82é\82Ì\82©\92²\82×\82æ\82¤\82Æ\82µ\82½\81D");
3722             } else {
3723                 You("\89½\82ª%s\82Ì\8fã\82É\82 \82é\82Ì\82©\92²\82×\82æ\82¤\82Æ\82µ\82½\81D", surface(u.ux, u.uy));
3724             }
3725 #endif
3726         }
3727         if (dfeature && !drift && !strcmp(dfeature, surface(u.ux, u.uy)))
3728             dfeature = 0; /* ice already identified */
3729         if (!can_reach_floor(TRUE)) {
3730 /*JP
3731             pline("But you can't reach it!");
3732 */
3733             pline("\82µ\82©\82µ\93Í\82©\82È\82¢\81I");
3734             return 0;
3735         }
3736     }
3737
3738     if (dfeature)
3739 /*JP
3740         Sprintf(fbuf, "There is %s here.", an(dfeature));
3741 */
3742         Sprintf(fbuf, "\82±\82±\82É\82Í%s\82ª\82 \82é\81D", an(dfeature));
3743
3744     if (!otmp || is_lava(u.ux, u.uy)
3745         || (is_pool(u.ux, u.uy) && !Underwater)) {
3746         if (dfeature)
3747             pline1(fbuf);
3748         read_engr_at(u.ux, u.uy); /* Eric Backus */
3749         if (!skip_objects && (Blind || !dfeature))
3750 #if 0 /*JP:C*/
3751             You("%s no objects here.", verb);
3752 #else
3753           pline(Blind ?
3754                 "\82È\82É\82à\82È\82¢\82æ\82¤\82È\8bC\82ª\82·\82é\81D" :
3755                 "\82È\82É\82à\82Ý\82Â\82¯\82ç\82ê\82È\82©\82Á\82½\81D");
3756 #endif
3757         return !!Blind;
3758     }
3759     /* we know there is something here */
3760
3761     if (skip_objects) {
3762         if (dfeature)
3763             pline1(fbuf);
3764         read_engr_at(u.ux, u.uy); /* Eric Backus */
3765         if (obj_cnt == 1 && otmp->quan == 1L)
3766 /*JP
3767             There("is %s object here.", picked_some ? "another" : "an");
3768 */
3769             There("\82±\82±\82É\82Í%s\88ê\82Â\82à\82Ì\82ª\82 \82é\81D", picked_some ? "\82à\82¤" : "");
3770         else
3771 #if 0 /*JP*/
3772             There("are %s%s objects here.",
3773                   (obj_cnt < 5)
3774                       ? "a few"
3775                       : (obj_cnt < 10)
3776                           ? "several"
3777                           : "many",
3778                   picked_some ? " more" : "");
3779 #else
3780             pline("\82±\82±\82É\82Í%s%s\82à\82Ì\82ª\82 \82é\81D",
3781                   picked_some ? "\82³\82ç\82É" : "",
3782                   (obj_cnt < 10)
3783                       ? "\82¢\82­\82Â\82©\82Ì"
3784                       : "\82½\82­\82³\82ñ\82Ì");
3785 #endif
3786         for (; otmp; otmp = otmp->nexthere)
3787             if (otmp->otyp == CORPSE && will_feel_cockatrice(otmp, FALSE)) {
3788 #if 0 /*JP*//*"It's (corpse_name), unfortunately"*/
3789                 pline("%s %s%s.",
3790                       (obj_cnt > 1)
3791                           ? "Including"
3792                           : (otmp->quan > 1L)
3793                               ? "They're"
3794                               : "It's",
3795                       corpse_xname(otmp, (const char *) 0, CXN_ARTICLE),
3796                       poly_when_stoned(youmonst.data)
3797                           ? ""
3798                           : ", unfortunately");
3799 #else
3800                 pline("%s%s%s\81D",
3801                       poly_when_stoned(youmonst.data)
3802                           ? ""
3803                           : "\8ec\94O\82È\82ª\82ç",
3804                       corpse_xname(otmp, (const char *) 0, CXN_ARTICLE),
3805                       (obj_cnt > 1)
3806                           ? "\82ð\8aÜ\82ñ\82Å\82¢\82é"
3807                           : "\82¾");
3808 #endif
3809                 feel_cockatrice(otmp, FALSE);
3810                 break;
3811             }
3812     } else if (!otmp->nexthere) {
3813         /* only one object */
3814         if (dfeature)
3815             pline1(fbuf);
3816         read_engr_at(u.ux, u.uy); /* Eric Backus */
3817 /*JP
3818         You("%s here %s.", verb, doname_with_price(otmp));
3819 */
3820         pline("%s%s\81D", doname_with_price(otmp), verb);
3821         iflags.last_msg = PLNMSG_ONE_ITEM_HERE;
3822         if (otmp->otyp == CORPSE)
3823             feel_cockatrice(otmp, FALSE);
3824     } else {
3825         char buf[BUFSZ];
3826
3827         display_nhwindow(WIN_MESSAGE, FALSE);
3828         tmpwin = create_nhwindow(NHW_MENU);
3829         if (dfeature) {
3830             putstr(tmpwin, 0, fbuf);
3831             putstr(tmpwin, 0, "");
3832         }
3833 #if 0 /*JP*/
3834         Sprintf(buf, "%s that %s here:",
3835                 picked_some ? "Other things" : "Things",
3836                 Blind ? "you feel" : "are");
3837 #else
3838         Sprintf(buf, "%s\82±\82±\82É\82 \82é%s\82à\82Ì\82Í\81F",
3839                 picked_some ? "\91¼\82É" : "",
3840                 Blind ? "\82ç\82µ\82¢" : "");
3841 #endif
3842         putstr(tmpwin, 0, buf);
3843         for (; otmp; otmp = otmp->nexthere) {
3844             if (otmp->otyp == CORPSE && will_feel_cockatrice(otmp, FALSE)) {
3845                 felt_cockatrice = TRUE;
3846 /*JP
3847                 Sprintf(buf, "%s...", doname(otmp));
3848 */
3849                 Sprintf(buf, "%s\81D\81D\81D", doname(otmp));
3850                 putstr(tmpwin, 0, buf);
3851                 break;
3852             }
3853             putstr(tmpwin, 0, doname_with_price(otmp));
3854         }
3855         display_nhwindow(tmpwin, TRUE);
3856         destroy_nhwindow(tmpwin);
3857         if (felt_cockatrice)
3858             feel_cockatrice(otmp, FALSE);
3859         read_engr_at(u.ux, u.uy); /* Eric Backus */
3860     }
3861     return !!Blind;
3862 }
3863
3864 /* the ':' command - explicitly look at what is here, including all objects */
3865 int
3866 dolook()
3867 {
3868     int res;
3869
3870     /* don't let
3871        MSGTYPE={norep,noshow} "You see here"
3872        interfere with feedback from the look-here command */
3873     hide_unhide_msgtypes(TRUE, MSGTYP_MASK_REP_SHOW);
3874     res = look_here(0, FALSE);
3875     /* restore normal msgtype handling */
3876     hide_unhide_msgtypes(FALSE, MSGTYP_MASK_REP_SHOW);
3877     return res;
3878 }
3879
3880 boolean
3881 will_feel_cockatrice(otmp, force_touch)
3882 struct obj *otmp;
3883 boolean force_touch;
3884 {
3885     if ((Blind || force_touch) && !uarmg && !Stone_resistance
3886         && (otmp->otyp == CORPSE && touch_petrifies(&mons[otmp->corpsenm])))
3887         return TRUE;
3888     return FALSE;
3889 }
3890
3891 void
3892 feel_cockatrice(otmp, force_touch)
3893 struct obj *otmp;
3894 boolean force_touch;
3895 {
3896     char kbuf[BUFSZ];
3897
3898     if (will_feel_cockatrice(otmp, force_touch)) {
3899         /* "the <cockatrice> corpse" */
3900         Strcpy(kbuf, corpse_xname(otmp, (const char *) 0, CXN_PFX_THE));
3901
3902         if (poly_when_stoned(youmonst.data))
3903 #if 0 /*JP*/
3904             You("touched %s with your bare %s.", kbuf,
3905                 makeplural(body_part(HAND)));
3906 #else
3907             You("%s\82Ì\8e\80\91Ì\82É\91f%s\82Å\90G\82Á\82½\81D", kbuf,
3908                 body_part(HAND));
3909 #endif
3910         else
3911 /*JP
3912             pline("Touching %s is a fatal mistake...", kbuf);
3913 */
3914             pline("%s\82Ì\8e\80\91Ì\82É\90G\82ê\82é\82Ì\82Í\92v\96½\93I\82È\8aÔ\88á\82¢\82¾\81D\81D\81D", kbuf);
3915         /* normalize body shape here; hand, not body_part(HAND) */
3916 /*JP
3917         Sprintf(kbuf, "touching %s bare-handed", killer_xname(otmp));
3918 */
3919         Sprintf(kbuf, "%s\82Ì\8e\80\91Ì\82É\90G\82ê\82Ä", killer_xname(otmp));
3920         /* will call polymon() for the poly_when_stoned() case */
3921         instapetrify(kbuf);
3922     }
3923 }
3924
3925 void
3926 stackobj(obj)
3927 struct obj *obj;
3928 {
3929     struct obj *otmp;
3930
3931     for (otmp = level.objects[obj->ox][obj->oy]; otmp; otmp = otmp->nexthere)
3932         if (otmp != obj && merged(&obj, &otmp))
3933             break;
3934     return;
3935 }
3936
3937 /* returns TRUE if obj & otmp can be merged; used in invent.c and mkobj.c */
3938 boolean
3939 mergable(otmp, obj)
3940 register struct obj *otmp, *obj;
3941 {
3942     int objnamelth = 0, otmpnamelth = 0;
3943
3944     /* fail if already the same object, if different types, if either is
3945        explicitly marked to prevent merge, or if not mergable in general */
3946     if (obj == otmp || obj->otyp != otmp->otyp
3947         || obj->nomerge || otmp->nomerge || !objects[obj->otyp].oc_merge)
3948         return FALSE;
3949
3950     /* coins of the same kind will always merge */
3951     if (obj->oclass == COIN_CLASS)
3952         return TRUE;
3953
3954     if (obj->unpaid != otmp->unpaid || obj->spe != otmp->spe
3955         || obj->cursed != otmp->cursed || obj->blessed != otmp->blessed
3956         || obj->no_charge != otmp->no_charge || obj->obroken != otmp->obroken
3957         || obj->otrapped != otmp->otrapped || obj->lamplit != otmp->lamplit
3958         || obj->bypass != otmp->bypass)
3959         return FALSE;
3960
3961     if (obj->globby)
3962         return TRUE;
3963     /* Checks beyond this point either aren't applicable to globs
3964      * or don't inhibit their merger.
3965      */
3966
3967     if (obj->oclass == FOOD_CLASS
3968         && (obj->oeaten != otmp->oeaten || obj->orotten != otmp->orotten))
3969         return FALSE;
3970
3971     if (obj->dknown != otmp->dknown
3972         || (obj->bknown != otmp->bknown && !Role_if(PM_PRIEST))
3973         || obj->oeroded != otmp->oeroded || obj->oeroded2 != otmp->oeroded2
3974         || obj->greased != otmp->greased)
3975         return FALSE;
3976
3977     if ((obj->oclass == WEAPON_CLASS || obj->oclass == ARMOR_CLASS)
3978         && (obj->oerodeproof != otmp->oerodeproof
3979             || obj->rknown != otmp->rknown))
3980         return FALSE;
3981
3982     if (obj->otyp == CORPSE || obj->otyp == EGG || obj->otyp == TIN) {
3983         if (obj->corpsenm != otmp->corpsenm)
3984             return FALSE;
3985     }
3986
3987     /* hatching eggs don't merge; ditto for revivable corpses */
3988     if ((obj->otyp == EGG && (obj->timed || otmp->timed))
3989         || (obj->otyp == CORPSE && otmp->corpsenm >= LOW_PM
3990             && is_reviver(&mons[otmp->corpsenm])))
3991         return FALSE;
3992
3993     /* allow candle merging only if their ages are close */
3994     /* see begin_burn() for a reference for the magic "25" */
3995     if (Is_candle(obj) && obj->age / 25 != otmp->age / 25)
3996         return FALSE;
3997
3998     /* burning potions of oil never merge */
3999     if (obj->otyp == POT_OIL && obj->lamplit)
4000         return FALSE;
4001
4002     /* don't merge surcharged item with base-cost item */
4003     if (obj->unpaid && !same_price(obj, otmp))
4004         return FALSE;
4005
4006     /* if they have names, make sure they're the same */
4007     objnamelth = strlen(safe_oname(obj));
4008     otmpnamelth = strlen(safe_oname(otmp));
4009     if ((objnamelth != otmpnamelth
4010          && ((objnamelth && otmpnamelth) || obj->otyp == CORPSE))
4011         || (objnamelth && otmpnamelth
4012             && strncmp(ONAME(obj), ONAME(otmp), objnamelth)))
4013         return FALSE;
4014
4015     /* for the moment, any additional information is incompatible */
4016     if (has_omonst(obj) || has_omid(obj) || has_olong(obj) || has_omonst(otmp)
4017         || has_omid(otmp) || has_olong(otmp))
4018         return FALSE;
4019
4020     if (obj->oartifact != otmp->oartifact)
4021         return FALSE;
4022
4023     if (obj->known == otmp->known || !objects[otmp->otyp].oc_uses_known) {
4024         return (boolean) objects[obj->otyp].oc_merge;
4025     } else
4026         return FALSE;
4027 }
4028
4029 /* the '$' command */
4030 int
4031 doprgold()
4032 {
4033     /* the messages used to refer to "carrying gold", but that didn't
4034        take containers into account */
4035     long umoney = money_cnt(invent);
4036
4037     if (!umoney)
4038 /*JP
4039         Your("wallet is empty.");
4040 */
4041         Your("\8dà\95z\82Í\8bó\82Á\82Û\82¾\81D");
4042     else
4043 /*JP
4044         Your("wallet contains %ld %s.", umoney, currency(umoney));
4045 */
4046         Your("\8dà\95z\82É\82Í%ld%s\93ü\82Á\82Ä\82¢\82é\81D", umoney, currency(umoney));
4047     shopper_financial_report();
4048     return 0;
4049 }
4050
4051 /* the ')' command */
4052 int
4053 doprwep()
4054 {
4055     if (!uwep) {
4056 /*JP
4057         You("are empty %s.", body_part(HANDED));
4058 */
4059         if(!uwep) You("%s\82É\95\90\8aí\82ð\82à\82Á\82Ä\82¢\82È\82¢\81D", body_part(HAND));
4060     } else {
4061         prinv((char *) 0, uwep, 0L);
4062         if (u.twoweap)
4063             prinv((char *) 0, uswapwep, 0L);
4064     }
4065     return 0;
4066 }
4067
4068 /* caller is responsible for checking !wearing_armor() */
4069 STATIC_OVL void
4070 noarmor(report_uskin)
4071 boolean report_uskin;
4072 {
4073     if (!uskin || !report_uskin) {
4074 /*JP
4075         You("are not wearing any armor.");
4076 */
4077         You("\8aZ\82ð\92\85\82Ä\82¢\82È\82¢\81D");
4078     } else {
4079         char *p, *uskinname, buf[BUFSZ];
4080
4081         uskinname = strcpy(buf, simpleonames(uskin));
4082 #if 0 /*JP*/
4083         /* shorten "set of <color> dragon scales" to "<color> scales"
4084            and "<color> dragon scale mail" to "<color> scale mail" */
4085         if (!strncmpi(uskinname, "set of ", 7))
4086             uskinname += 7;
4087         if ((p = strstri(uskinname, " dragon ")) != 0)
4088             while ((p[1] = p[8]) != '\0')
4089                 ++p;
4090 #else /*\81u<\90F>\83h\83\89\83S\83\93\82Ì\97Ø\81v\82ð\81u<\90F>\82Ì\97Ø\81v\82É\82·\82é*/
4091         if ((p = strstri(uskinname, "\83h\83\89\83S\83\93\82Ì\97Ø")) != 0)
4092             strcpy(p, "\97Ø");
4093 #endif
4094
4095 /*JP
4096         You("are not wearing armor but have %s embedded in your skin.",
4097 */
4098         You("\82Í\8aZ\82ð\92\85\82Ä\82¢\82È\82¢\82ª\81C%s\82ª\94§\82É\96\84\82ß\8d\9e\82Ü\82ê\82Ä\82¢\82é\81D",
4099             uskinname);
4100     }
4101 }
4102
4103 /* the '[' command */
4104 int
4105 doprarm()
4106 {
4107     char lets[8];
4108     register int ct = 0;
4109     /*
4110      * Note:  players sometimes get here by pressing a function key which
4111      * transmits ''ESC [ <something>'' rather than by pressing '[';
4112      * there's nothing we can--or should-do about that here.
4113      */
4114
4115     if (!wearing_armor()) {
4116         noarmor(TRUE);
4117     } else {
4118         if (uarmu)
4119             lets[ct++] = obj_to_let(uarmu);
4120         if (uarm)
4121             lets[ct++] = obj_to_let(uarm);
4122         if (uarmc)
4123             lets[ct++] = obj_to_let(uarmc);
4124         if (uarmh)
4125             lets[ct++] = obj_to_let(uarmh);
4126         if (uarms)
4127             lets[ct++] = obj_to_let(uarms);
4128         if (uarmg)
4129             lets[ct++] = obj_to_let(uarmg);
4130         if (uarmf)
4131             lets[ct++] = obj_to_let(uarmf);
4132         lets[ct] = 0;
4133         (void) display_inventory(lets, FALSE);
4134     }
4135     return 0;
4136 }
4137
4138 /* the '=' command */
4139 int
4140 doprring()
4141 {
4142     if (!uleft && !uright)
4143 /*JP
4144         You("are not wearing any rings.");
4145 */
4146         You("\8ew\97Ö\82ð\90g\82É\82Â\82¯\82Ä\82¢\82È\82¢\81D");
4147     else {
4148         char lets[3];
4149         register int ct = 0;
4150
4151         if (uleft)
4152             lets[ct++] = obj_to_let(uleft);
4153         if (uright)
4154             lets[ct++] = obj_to_let(uright);
4155         lets[ct] = 0;
4156         (void) display_inventory(lets, FALSE);
4157     }
4158     return 0;
4159 }
4160
4161 /* the '"' command */
4162 int
4163 dopramulet()
4164 {
4165     if (!uamul)
4166 /*JP
4167         You("are not wearing an amulet.");
4168 */
4169         You("\96\82\8f\9c\82¯\82ð\90g\82É\82Â\82¯\82Ä\82¢\82È\82¢\81D");
4170     else
4171         prinv((char *) 0, uamul, 0L);
4172     return 0;
4173 }
4174
4175 STATIC_OVL boolean
4176 tool_in_use(obj)
4177 struct obj *obj;
4178 {
4179     if ((obj->owornmask & (W_TOOL | W_SADDLE)) != 0L)
4180         return TRUE;
4181     if (obj->oclass != TOOL_CLASS)
4182         return FALSE;
4183     return (boolean) (obj == uwep || obj->lamplit
4184                       || (obj->otyp == LEASH && obj->leashmon));
4185 }
4186
4187 /* the '(' command */
4188 int
4189 doprtool()
4190 {
4191     struct obj *otmp;
4192     int ct = 0;
4193     char lets[52 + 1];
4194
4195     for (otmp = invent; otmp; otmp = otmp->nobj)
4196         if (tool_in_use(otmp))
4197             lets[ct++] = obj_to_let(otmp);
4198     lets[ct] = '\0';
4199     if (!ct)
4200 /*JP
4201         You("are not using any tools.");
4202 */
4203         You("\8eg\82¦\82é\93¹\8bï\82ð\82à\82Á\82Ä\82¢\82È\82¢\81D");
4204     else
4205         (void) display_inventory(lets, FALSE);
4206     return 0;
4207 }
4208
4209 /* '*' command; combines the ')' + '[' + '=' + '"' + '(' commands;
4210    show inventory of all currently wielded, worn, or used objects */
4211 int
4212 doprinuse()
4213 {
4214     struct obj *otmp;
4215     int ct = 0;
4216     char lets[52 + 1];
4217
4218     for (otmp = invent; otmp; otmp = otmp->nobj)
4219         if (is_worn(otmp) || tool_in_use(otmp))
4220             lets[ct++] = obj_to_let(otmp);
4221     lets[ct] = '\0';
4222     if (!ct)
4223 /*JP
4224         You("are not wearing or wielding anything.");
4225 */
4226         You("\89½\82à\92\85\82Ä\82¢\82È\82¢\82µ\81C\91\95\94õ\82µ\82Ä\82¢\82È\82¢\81D");
4227     else
4228         (void) display_inventory(lets, FALSE);
4229     return 0;
4230 }
4231
4232 /*
4233  * uses up an object that's on the floor, charging for it as necessary
4234  */
4235 void
4236 useupf(obj, numused)
4237 register struct obj *obj;
4238 long numused;
4239 {
4240     register struct obj *otmp;
4241     boolean at_u = (obj->ox == u.ux && obj->oy == u.uy);
4242
4243     /* burn_floor_objects() keeps an object pointer that it tries to
4244      * useupf() multiple times, so obj must survive if plural */
4245     if (obj->quan > numused)
4246         otmp = splitobj(obj, numused);
4247     else
4248         otmp = obj;
4249     if (costly_spot(otmp->ox, otmp->oy)) {
4250         if (index(u.urooms, *in_rooms(otmp->ox, otmp->oy, 0)))
4251             addtobill(otmp, FALSE, FALSE, FALSE);
4252         else
4253             (void) stolen_value(otmp, otmp->ox, otmp->oy, FALSE, FALSE);
4254     }
4255     delobj(otmp);
4256     if (at_u && u.uundetected && hides_under(youmonst.data))
4257         (void) hideunder(&youmonst);
4258 }
4259
4260 /*
4261  * Conversion from a class to a string for printing.
4262  * This must match the object class order.
4263  */
4264 STATIC_VAR NEARDATA const char *names[] = {
4265 #if 0 /*JP*/
4266     0, "Illegal objects", "Weapons", "Armor", "Rings", "Amulets", "Tools",
4267     "Comestibles", "Potions", "Scrolls", "Spellbooks", "Wands", "Coins",
4268     "Gems/Stones", "Boulders/Statues", "Iron balls", "Chains", "Venoms"
4269 #else
4270     0, "\96­\82È\95¨\91Ì", "\95\90\8aí", "\8aZ", "\8ew\97Ö", "\96\82\8f\9c\82¯", "\93¹\8bï",
4271     "\90H\97¿", "\96ò", "\8aª\95¨", "\96\82\96@\8f\91", "\8fñ", "\8bà\89Ý",
4272     "\95ó\90Î", "\8aâ\82Ü\82½\82Í\92¤\91\9c", "\93S\8b\85", "\8d½", "\93Å"
4273 #endif
4274 };
4275 STATIC_VAR NEARDATA const char oth_symbols[] = { CONTAINED_SYM, '\0' };
4276 /*JP
4277 STATIC_VAR NEARDATA const char *oth_names[] = { "Bagged/Boxed items" };
4278 */
4279 STATIC_VAR NEARDATA const char *oth_names[] = { "\8bl\82ß\82ç\82ê\82½\93¹\8bï" };
4280
4281 STATIC_VAR NEARDATA char *invbuf = (char *) 0;
4282 STATIC_VAR NEARDATA unsigned invbufsiz = 0;
4283
4284 char *
4285 let_to_name(let, unpaid, showsym)
4286 char let;
4287 boolean unpaid, showsym;
4288 {
4289     const char *ocsymfmt = "  ('%c')";
4290     const int invbuf_sympadding = 8; /* arbitrary */
4291     const char *class_name;
4292     const char *pos;
4293     int oclass = (let >= 1 && let < MAXOCLASSES) ? let : 0;
4294     unsigned len;
4295
4296     if (oclass)
4297         class_name = names[oclass];
4298     else if ((pos = index(oth_symbols, let)) != 0)
4299         class_name = oth_names[pos - oth_symbols];
4300     else
4301         class_name = names[0];
4302
4303 /*JP
4304     len = strlen(class_name) + (unpaid ? sizeof "unpaid_" : sizeof "")
4305 */
4306     len = strlen(class_name) + (unpaid ? sizeof "\96¢\95¥\82¢\82Ì" : sizeof "")
4307           + (oclass ? (strlen(ocsymfmt) + invbuf_sympadding) : 0);
4308     if (len > invbufsiz) {
4309         if (invbuf)
4310             free((genericptr_t) invbuf);
4311         invbufsiz = len + 10; /* add slop to reduce incremental realloc */
4312         invbuf = (char *) alloc(invbufsiz);
4313     }
4314     if (unpaid)
4315 /*JP
4316         Strcat(strcpy(invbuf, "Unpaid "), class_name);
4317 */
4318         Strcat(strcpy(invbuf, "\96¢\95¥\82¢\82Ì"), class_name);
4319     else
4320         Strcpy(invbuf, class_name);
4321     if ((oclass != 0) && showsym) {
4322         char *bp = eos(invbuf);
4323         int mlen = invbuf_sympadding - strlen(class_name);
4324         while (--mlen > 0) {
4325             *bp = ' ';
4326             bp++;
4327         }
4328         *bp = '\0';
4329         Sprintf(eos(invbuf), ocsymfmt, def_oc_syms[oclass].sym);
4330     }
4331     return invbuf;
4332 }
4333
4334 /* release the static buffer used by let_to_name() */
4335 void
4336 free_invbuf()
4337 {
4338     if (invbuf)
4339         free((genericptr_t) invbuf), invbuf = (char *) 0;
4340     invbufsiz = 0;
4341 }
4342
4343 /* give consecutive letters to every item in inventory (for !fixinv mode);
4344    gold is always forced to '$' slot at head of list */
4345 void
4346 reassign()
4347 {
4348     int i;
4349     struct obj *obj, *prevobj, *goldobj;
4350
4351     /* first, remove [first instance of] gold from invent, if present */
4352     prevobj = goldobj = 0;
4353     for (obj = invent; obj; prevobj = obj, obj = obj->nobj)
4354         if (obj->oclass == COIN_CLASS) {
4355             goldobj = obj;
4356             if (prevobj)
4357                 prevobj->nobj = goldobj->nobj;
4358             else
4359                 invent = goldobj->nobj;
4360             break;
4361         }
4362     /* second, re-letter the rest of the list */
4363     for (obj = invent, i = 0; obj; obj = obj->nobj, i++)
4364         obj->invlet =
4365             (i < 26) ? ('a' + i) : (i < 52) ? ('A' + i - 26) : NOINVSYM;
4366     /* third, assign gold the "letter" '$' and re-insert it at head */
4367     if (goldobj) {
4368         goldobj->invlet = GOLD_SYM;
4369         goldobj->nobj = invent;
4370         invent = goldobj;
4371     }
4372     if (i >= 52)
4373         i = 52 - 1;
4374     lastinvnr = i;
4375 }
4376
4377 /* #adjust command
4378  *
4379  *      User specifies a 'from' slot for inventory stack to move,
4380  *      then a 'to' slot for its destination.  Open slots and those
4381  *      filled by compatible stacks are listed as likely candidates
4382  *      but user can pick any inventory letter (including 'from').
4383  *
4384  *  to == from, 'from' has a name
4385  *      All compatible items (same name or no name) are gathered
4386  *      into the 'from' stack.  No count is allowed.
4387  *  to == from, 'from' does not have a name
4388  *      All compatible items without a name are gathered into the
4389  *      'from' stack.  No count is allowed.  Compatible stacks with
4390  *      names are left as-is.
4391  *  to != from, no count
4392  *      Move 'from' to 'to'.  If 'to' is not empty, merge 'from'
4393  *      into it if possible, otherwise swap it with the 'from' slot.
4394  *  to != from, count given
4395  *      If the user specifies a count when choosing the 'from' slot,
4396  *      and that count is less than the full size of the stack,
4397  *      then the stack will be split.  The 'count' portion is moved
4398  *      to the destination, and the only candidate for merging with
4399  *      it is the stack already at the 'to' slot, if any.  When the
4400  *      destination is non-empty but won't merge, whatever is there
4401  *      will be moved to an open slot; if there isn't any open slot
4402  *      available, the adjustment attempt fails.
4403  *
4404  *      To minimize merging for 'from == to', unnamed stacks will
4405  *      merge with named 'from' but named ones won't merge with
4406  *      unnamed 'from'.  Otherwise attempting to collect all unnamed
4407  *      stacks would lump the first compatible named stack with them
4408  *      and give them its name.
4409  *
4410  *      To maximize merging for 'from != to', compatible stacks will
4411  *      merge when either lacks a name (or they already have the same
4412  *      name).  When no count is given and one stack has a name and
4413  *      the other doesn't, the merged result will have that name.
4414  *      However, when splitting results in a merger, the name of the
4415  *      destination overrides that of the source, even if destination
4416  *      is unnamed and source is named.
4417  */
4418 int
4419 doorganize() /* inventory organizer by Del Lamb */
4420 {
4421     struct obj *obj, *otmp, *splitting, *bumped;
4422     int ix, cur, trycnt, goldstacks;
4423     char let;
4424 #define GOLD_INDX   0
4425 #define GOLD_OFFSET 1
4426 #define OVRFLW_INDX (GOLD_OFFSET + 52) /* past gold and 2*26 letters */
4427     char lets[1 + 52 + 1 + 1]; /* room for '$a-zA-Z#\0' */
4428     char qbuf[QBUFSZ];
4429     char allowall[4]; /* { ALLOW_COUNT, ALL_CLASSES, 0, 0 } */
4430     char *objname, *otmpname;
4431     const char *adj_type;
4432     boolean ever_mind = FALSE, collect;
4433
4434     if (!invent) {
4435 /*JP
4436         You("aren't carrying anything to adjust.");
4437 */
4438         You("\8f\87\8f\98\82ð\95Ï\82¦\82é\82à\82Ì\82ð\89½\82à\8e\9d\82Á\82Ä\82¢\82È\82¢\81D");
4439         return 0;
4440     }
4441
4442     if (!flags.invlet_constant)
4443         reassign();
4444     /* get object the user wants to organize (the 'from' slot) */
4445     allowall[0] = ALLOW_COUNT;
4446     allowall[1] = ALL_CLASSES;
4447     allowall[2] = '\0';
4448     for (goldstacks = 0, otmp = invent; otmp; otmp = otmp->nobj) {
4449         /* gold should never end up in a letter slot, nor should two '$'
4450            slots occur, but if they ever do, allow #adjust to handle them
4451            (in the past, things like this have happened, usually due to
4452            bknown being erroneously set on one stack, clear on another;
4453            object merger isn't fooled by that anymore) */
4454         if (otmp->oclass == COIN_CLASS
4455             && (otmp->invlet != GOLD_SYM || ++goldstacks > 1)) {
4456             allowall[1] = COIN_CLASS;
4457             allowall[2] = ALL_CLASSES;
4458             allowall[3] = '\0';
4459             break;
4460         }
4461     }
4462     if (!(obj = getobj(allowall, "adjust")))
4463         return 0;
4464
4465     /* figure out whether user gave a split count to getobj() */
4466     splitting = bumped = 0;
4467     for (otmp = invent; otmp; otmp = otmp->nobj)
4468         if (otmp->nobj == obj) { /* knowledge of splitobj() operation */
4469             if (otmp->invlet == obj->invlet)
4470                 splitting = otmp;
4471             break;
4472         }
4473
4474     /* initialize the list with all lower and upper case letters */
4475     lets[GOLD_INDX] = (obj->oclass == COIN_CLASS) ? GOLD_SYM : ' ';
4476     for (ix = GOLD_OFFSET, let = 'a'; let <= 'z';)
4477         lets[ix++] = let++;
4478     for (let = 'A'; let <= 'Z';)
4479         lets[ix++] = let++;
4480     lets[OVRFLW_INDX] = ' ';
4481     lets[sizeof lets - 1] = '\0';
4482     /* for floating inv letters, truncate list after the first open slot */
4483     if (!flags.invlet_constant && (ix = inv_cnt(FALSE)) < 52)
4484         lets[ix + (splitting ? 0 : 1)] = '\0';
4485
4486     /* blank out all the letters currently in use in the inventory
4487        except those that will be merged with the selected object */
4488     for (otmp = invent; otmp; otmp = otmp->nobj)
4489         if (otmp != obj && !mergable(otmp, obj)) {
4490             let = otmp->invlet;
4491             if (let >= 'a' && let <= 'z')
4492                 lets[GOLD_OFFSET + let - 'a'] = ' ';
4493             else if (let >= 'A' && let <= 'Z')
4494                 lets[GOLD_OFFSET + let - 'A' + 26] = ' ';
4495             /* overflow defaults to off, but it we find a stack using that
4496                slot, switch to on -- the opposite of normal invlet handling */
4497             else if (let == NOINVSYM)
4498                 lets[OVRFLW_INDX] = NOINVSYM;
4499         }
4500
4501     /* compact the list by removing all the blanks */
4502     for (ix = cur = 0; lets[ix]; ix++)
4503         if (lets[ix] != ' ' && cur++ < ix)
4504             lets[cur - 1] = lets[ix];
4505     lets[cur] = '\0';
4506     /* and by dashing runs of letters */
4507     if (cur > 5)
4508         compactify(lets);
4509
4510     /* get 'to' slot to use as destination */
4511 #if 0 /*JP:T*/
4512     Sprintf(qbuf, "Adjust letter to what [%s]%s?", lets,
4513             invent ? " (? see used letters)" : "");
4514 #else
4515     Sprintf(qbuf, "\82Ç\82Ì\95\8e\9a\82É\92²\90®\82µ\82Ü\82·\82©[%s]%s\81H", lets,
4516             invent ? " (? \82Å\8eg\82Á\82Ä\82¢\82é\95\8e\9a\82ð\95\\8e¦)" : "");
4517 #endif
4518     for (trycnt = 1; ; ++trycnt) {
4519         let = yn_function(qbuf, (char *) 0, '\0');
4520         if (let == '?' || let == '*') {
4521             let = display_used_invlets(splitting ? obj->invlet : 0);
4522             if (!let)
4523                 continue;
4524             if (let == '\033')
4525                 goto noadjust;
4526         }
4527         if (index(quitchars, let)
4528             /* adjusting to same slot is meaningful since all
4529                compatible stacks get collected along the way,
4530                but splitting to same slot is not */
4531             || (splitting && let == obj->invlet)) {
4532  noadjust:
4533             if (splitting)
4534                 (void) merged(&splitting, &obj);
4535             if (!ever_mind)
4536                 pline1(Never_mind);
4537             return 0;
4538         } else if (let == GOLD_SYM && obj->oclass != COIN_CLASS) {
4539 #if 0 /*JP*/
4540             pline("Only gold coins may be moved into the '%c' slot.",
4541                   GOLD_SYM);
4542 #else
4543             pline("'%c'\82É\82Å\82«\82é\82Ì\82Í\8bà\89Ý\82¾\82¯\81D",
4544                   GOLD_SYM);
4545 #endif
4546             ever_mind = TRUE;
4547             goto noadjust;
4548         }
4549         /* letter() classifies '@' as one; compactify() can put '-' in lets;
4550            the only thing of interest that index() might find is '$' or '#'
4551            since letter() catches everything else that we put into lets[] */
4552         if ((letter(let) && let != '@') || (index(lets, let) && let != '-'))
4553             break; /* got one */
4554         if (trycnt == 5)
4555             goto noadjust;
4556 #if 0 /*JP*/
4557         pline("Select an inventory slot letter."); /* else try again */
4558 #else
4559         pline("\8e\9d\82¿\95¨\82Ì\95\8e\9a\82ð\91I\82ñ\82Å\82­\82¾\82³\82¢\81D");
4560 #endif
4561     }
4562
4563     collect = (let == obj->invlet);
4564     /* change the inventory and print the resulting item */
4565 /*JP
4566     adj_type = collect ? "Collecting" : !splitting ? "Moving:" : "Splitting:";
4567 */
4568     adj_type = collect ? "\82ð\8fW\82ß\82½\81D" : !splitting ? "\82ð\88Ú\93®\82µ\82½\81D" : "\82ð\95ª\8a\84\82µ\82½\81D";
4569
4570     /*
4571      * don't use freeinv/addinv to avoid double-touching artifacts,
4572      * dousing lamps, losing luck, cursing loadstone, etc.
4573      */
4574     extract_nobj(obj, &invent);
4575
4576     for (otmp = invent; otmp;) {
4577         /* it's tempting to pull this outside the loop, but merged() could
4578            free ONAME(obj) [via obfree()] and replace it with ONAME(otmp) */
4579         objname = has_oname(obj) ? ONAME(obj) : (char *) 0;
4580
4581         if (collect) {
4582             /* Collecting: #adjust an inventory stack into its same slot;
4583                keep it there and merge other compatible stacks into it.
4584                Traditional inventory behavior is to merge unnamed stacks
4585                with compatible named ones; we only want that if it is
4586                the 'from' stack (obj) with a name and candidate (otmp)
4587                without one, not unnamed 'from' with named candidate. */
4588             otmpname = has_oname(otmp) ? ONAME(otmp) : (char *) 0;
4589             if ((!otmpname || (objname && !strcmp(objname, otmpname)))
4590                 && merged(&otmp, &obj)) {
4591 /*JP
4592                 adj_type = "Merging:";
4593 */
4594                 adj_type = "\82ð\8d\87\82í\82¹\82½\81D";
4595                 obj = otmp;
4596                 otmp = otmp->nobj;
4597                 extract_nobj(obj, &invent);
4598                 continue; /* otmp has already been updated */
4599             }
4600         } else if (otmp->invlet == let) {
4601             /* Moving or splitting: don't merge extra compatible stacks.
4602                Found 'otmp' in destination slot; merge if compatible,
4603                otherwise bump whatever is there to an open slot. */
4604             if (!splitting) {
4605 /*JP
4606                 adj_type = "Swapping:";
4607 */
4608                 adj_type = "\82ð\8cð\8a·\82µ\82½\81D";
4609                 otmp->invlet = obj->invlet;
4610             } else {
4611                 /* strip 'from' name if it has one */
4612                 if (objname && !obj->oartifact)
4613                     ONAME(obj) = (char *) 0;
4614                 if (!mergable(otmp, obj)) {
4615                     /* won't merge; put 'from' name back */
4616                     if (objname)
4617                         ONAME(obj) = objname;
4618                 } else {
4619                     /* will merge; discard 'from' name */
4620                     if (objname)
4621                         free((genericptr_t) objname), objname = 0;
4622                 }
4623
4624                 if (merged(&otmp, &obj)) {
4625 /*JP
4626                     adj_type = "Splitting and merging:";
4627 */
4628                     adj_type = "\82ð\95ª\8a\84\82µ\82Ä\8d\87\82í\82¹\82½\81D";
4629                     obj = otmp;
4630                     extract_nobj(obj, &invent);
4631                 } else if (inv_cnt(FALSE) >= 52) {
4632                     (void) merged(&splitting, &obj); /* undo split */
4633                     /* "knapsack cannot accommodate any more items" */
4634 /*JP
4635                     Your("pack is too full.");
4636 */
4637                     Your("\8e\9d\82¿\95¨\82Í\88ê\94t\82¾\81D");
4638                     return 0;
4639                 } else {
4640                     bumped = otmp;
4641                     extract_nobj(bumped, &invent);
4642                 }
4643             } /* moving vs splitting */
4644             break; /* not collecting and found 'to' slot */
4645         } /* collect */
4646         otmp = otmp->nobj;
4647     }
4648
4649     /* inline addinv; insert loose object at beginning of inventory */
4650     obj->invlet = let;
4651     obj->nobj = invent;
4652     obj->where = OBJ_INVENT;
4653     invent = obj;
4654     reorder_invent();
4655     if (bumped) {
4656         /* splitting the 'from' stack is causing an incompatible
4657            stack in the 'to' slot to be moved into an open one;
4658            we need to do another inline insertion to inventory */
4659         assigninvlet(bumped);
4660         bumped->nobj = invent;
4661         bumped->where = OBJ_INVENT;
4662         invent = bumped;
4663         reorder_invent();
4664     }
4665
4666     /* messages deferred until inventory has been fully reestablished */
4667     prinv(adj_type, obj, 0L);
4668     if (bumped)
4669 /*JP
4670         prinv("Moving:", bumped, 0L);
4671 */
4672         prinv("\88Ú\93®:", bumped, 0L);
4673     if (splitting)
4674         clear_splitobjs(); /* reset splitobj context */
4675     update_inventory();
4676     return 0;
4677 }
4678
4679 /* common to display_minventory and display_cinventory */
4680 STATIC_OVL void
4681 invdisp_nothing(hdr, txt)
4682 const char *hdr, *txt;
4683 {
4684     winid win;
4685     anything any;
4686     menu_item *selected;
4687
4688     any = zeroany;
4689     win = create_nhwindow(NHW_MENU);
4690     start_menu(win);
4691     add_menu(win, NO_GLYPH, &any, 0, 0, iflags.menu_headings, hdr,
4692              MENU_UNSELECTED);
4693     add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, "", MENU_UNSELECTED);
4694     add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, txt, MENU_UNSELECTED);
4695     end_menu(win, (char *) 0);
4696     if (select_menu(win, PICK_NONE, &selected) > 0)
4697         free((genericptr_t) selected);
4698     destroy_nhwindow(win);
4699     return;
4700 }
4701
4702 /* query_objlist callback: return things that are worn or wielded */
4703 STATIC_OVL boolean
4704 worn_wield_only(obj)
4705 struct obj *obj;
4706 {
4707 #if 1
4708     /* check for things that *are* worn or wielded (only used for monsters,
4709        so we don't worry about excluding W_CHAIN, W_ARTI and the like) */
4710     return (boolean) (obj->owornmask != 0L);
4711 #else
4712     /* this used to check for things that *might* be worn or wielded,
4713        but that's not particularly interesting */
4714     if (is_weptool(obj) || is_wet_towel(obj) || obj->otyp == MEAT_RING)
4715         return TRUE;
4716     return (boolean) (obj->oclass == WEAPON_CLASS
4717                       || obj->oclass == ARMOR_CLASS
4718                       || obj->oclass == AMULET_CLASS
4719                       || obj->oclass == RING_CLASS);
4720 #endif
4721 }
4722
4723 /*
4724  * Display a monster's inventory.
4725  * Returns a pointer to the object from the monster's inventory selected
4726  * or NULL if nothing was selected.
4727  *
4728  * By default, only worn and wielded items are displayed.  The caller
4729  * can pick one.  Modifier flags are:
4730  *
4731  *      PICK_NONE, PICK_ONE - standard menu control
4732  *      PICK_ANY            - allowed, but we only return a single object
4733  *      MINV_NOLET          - nothing selectable
4734  *      MINV_ALL            - display all inventory
4735  */
4736 struct obj *
4737 display_minventory(mon, dflags, title)
4738 register struct monst *mon;
4739 int dflags;
4740 char *title;
4741 {
4742     struct obj *ret;
4743     char tmp[QBUFSZ];
4744     int n;
4745     menu_item *selected = 0;
4746     int do_all = (dflags & MINV_ALL) != 0,
4747         incl_hero = (do_all && u.uswallow && mon == u.ustuck),
4748         have_inv = (mon->minvent != 0), have_any = (have_inv || incl_hero),
4749         pickings = (dflags & MINV_PICKMASK);
4750
4751 #if 0 /*JP*/
4752     Sprintf(tmp, "%s %s:", s_suffix(noit_Monnam(mon)),
4753             do_all ? "possessions" : "armament");
4754 #else
4755     Sprintf(tmp, "%s\82Ì%s\81F", Monnam(mon),
4756             do_all ? "\8e\9d\82¿\95¨" : "\91\95\94õ");
4757 #endif
4758
4759     if (do_all ? have_any : (mon->misc_worn_check || MON_WEP(mon))) {
4760         /* Fool the 'weapon in hand' routine into
4761          * displaying 'weapon in claw', etc. properly.
4762          */
4763         youmonst.data = mon->data;
4764         /* in case inside a shop, don't append "for sale" prices */
4765         iflags.suppress_price++;
4766
4767         n = query_objlist(title ? title : tmp, &(mon->minvent),
4768                           (INVORDER_SORT | (incl_hero ? INCLUDE_HERO : 0)),
4769                           &selected, pickings,
4770                           do_all ? allow_all : worn_wield_only);
4771
4772         iflags.suppress_price--;
4773         /* was 'set_uasmon();' but that potentially has side-effects */
4774         youmonst.data = &mons[u.umonnum]; /* most basic part of set_uasmon */
4775     } else {
4776 /*JP
4777         invdisp_nothing(title ? title : tmp, "(none)");
4778 */
4779         invdisp_nothing(title ? title : tmp, "(\89½\82à\82È\82¢)");
4780         n = 0;
4781     }
4782
4783     if (n > 0) {
4784         ret = selected[0].item.a_obj;
4785         free((genericptr_t) selected);
4786     } else
4787         ret = (struct obj *) 0;
4788     return ret;
4789 }
4790
4791 /*
4792  * Display the contents of a container in inventory style.
4793  * Currently, this is only used for statues, via wand of probing.
4794  */
4795 struct obj *
4796 display_cinventory(obj)
4797 register struct obj *obj;
4798 {
4799     struct obj *ret;
4800     char qbuf[QBUFSZ];
4801     int n;
4802     menu_item *selected = 0;
4803
4804 #if 0 /*JP*/
4805     (void) safe_qbuf(qbuf, "Contents of ", ":", obj, doname, ansimpleoname,
4806                      "that");
4807 #else
4808     (void) safe_qbuf(qbuf, "", "\82Ì\92\86\90g\81F", obj, doname, ansimpleoname,
4809                      "\82»");
4810 #endif
4811
4812     if (obj->cobj) {
4813         n = query_objlist(qbuf, &(obj->cobj), INVORDER_SORT,
4814                           &selected, PICK_NONE, allow_all);
4815     } else {
4816 /*JP
4817         invdisp_nothing(qbuf, "(empty)");
4818 */
4819         invdisp_nothing(qbuf, "(\8bó\82Á\82Û)");
4820         n = 0;
4821     }
4822     if (n > 0) {
4823         ret = selected[0].item.a_obj;
4824         free((genericptr_t) selected);
4825     } else
4826         ret = (struct obj *) 0;
4827     obj->cknown = 1;
4828     return ret;
4829 }
4830
4831 /* query objlist callback: return TRUE if obj is at given location */
4832 static coord only;
4833
4834 STATIC_OVL boolean
4835 only_here(obj)
4836 struct obj *obj;
4837 {
4838     return (obj->ox == only.x && obj->oy == only.y);
4839 }
4840
4841 /*
4842  * Display a list of buried items in inventory style.  Return a non-zero
4843  * value if there were items at that spot.
4844  *
4845  * Currently, this is only used with a wand of probing zapped downwards.
4846  */
4847 int
4848 display_binventory(x, y, as_if_seen)
4849 int x, y;
4850 boolean as_if_seen;
4851 {
4852     struct obj *obj;
4853     menu_item *selected = 0;
4854     int n;
4855
4856     /* count # of objects here */
4857     for (n = 0, obj = level.buriedobjlist; obj; obj = obj->nobj)
4858         if (obj->ox == x && obj->oy == y) {
4859             if (as_if_seen)
4860                 obj->dknown = 1;
4861             n++;
4862         }
4863
4864     if (n) {
4865         only.x = x;
4866         only.y = y;
4867 /*JP
4868         if (query_objlist("Things that are buried here:",
4869 */
4870         if (query_objlist("\82±\82±\82É\96\84\82ß\82ç\82ê\82Ä\82¢\82é\82à\82Ì\81F",
4871                           &level.buriedobjlist, INVORDER_SORT,
4872                           &selected, PICK_NONE, only_here) > 0)
4873             free((genericptr_t) selected);
4874         only.x = only.y = 0;
4875     }
4876     return n;
4877 }
4878
4879 /*invent.c*/