OSDN Git Service

import nethack-3.6.0
[jnethack/source.git] / src / pickup.c
1 /* NetHack 3.6  pickup.c        $NHDT-Date: 1445556881 2015/10/22 23:34:41 $  $NHDT-Branch: master $:$NHDT-Revision: 1.162 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed.  See license for details. */
4
5 /*
6  *      Contains code for picking objects up, and container use.
7  */
8
9 #include "hack.h"
10
11 #define CONTAINED_SYM '>' /* from invent.c */
12
13 STATIC_DCL void FDECL(simple_look, (struct obj *, BOOLEAN_P));
14 STATIC_DCL boolean
15 FDECL(query_classes, (char *, boolean *, boolean *, const char *,
16                       struct obj *, BOOLEAN_P, int *));
17 STATIC_DCL boolean FDECL(fatal_corpse_mistake, (struct obj *, BOOLEAN_P));
18 STATIC_DCL void FDECL(check_here, (BOOLEAN_P));
19 STATIC_DCL boolean FDECL(n_or_more, (struct obj *));
20 STATIC_DCL boolean FDECL(all_but_uchain, (struct obj *));
21 #if 0 /* not used */
22 STATIC_DCL boolean FDECL(allow_cat_no_uchain, (struct obj *));
23 #endif
24 STATIC_DCL int FDECL(autopick, (struct obj *, int, menu_item **));
25 STATIC_DCL int FDECL(count_categories, (struct obj *, int));
26 STATIC_DCL long FDECL(carry_count, (struct obj *, struct obj *, long,
27                                     BOOLEAN_P, int *, int *));
28 STATIC_DCL int FDECL(lift_object,
29                      (struct obj *, struct obj *, long *, BOOLEAN_P));
30 STATIC_DCL boolean FDECL(mbag_explodes, (struct obj *, int));
31 STATIC_PTR int FDECL(in_container, (struct obj *));
32 STATIC_PTR int FDECL(out_container, (struct obj *));
33 STATIC_DCL long FDECL(mbag_item_gone, (int, struct obj *));
34 STATIC_DCL void FDECL(observe_quantum_cat, (struct obj *));
35 STATIC_DCL void NDECL(explain_container_prompt);
36 STATIC_DCL int FDECL(traditional_loot, (BOOLEAN_P));
37 STATIC_DCL int FDECL(menu_loot, (int, BOOLEAN_P));
38 STATIC_DCL char FDECL(in_or_out_menu, (const char *, struct obj *, BOOLEAN_P,
39                                        BOOLEAN_P, BOOLEAN_P));
40 STATIC_DCL int FDECL(container_at, (int, int, BOOLEAN_P));
41 STATIC_DCL boolean FDECL(able_to_loot, (int, int, BOOLEAN_P));
42 STATIC_DCL boolean NDECL(reverse_loot);
43 STATIC_DCL boolean FDECL(mon_beside, (int, int));
44 STATIC_DCL int FDECL(do_loot_cont, (struct obj **));
45 STATIC_DCL void FDECL(tipcontainer, (struct obj *));
46
47 /* define for query_objlist() and autopickup() */
48 #define FOLLOW(curr, flags) \
49     (((flags) &BY_NEXTHERE) ? (curr)->nexthere : (curr)->nobj)
50
51 /*
52  *  How much the weight of the given container will change when the given
53  *  object is removed from it.  This calculation must match the one used
54  *  by weight() in mkobj.c.
55  */
56 #define DELTA_CWT(cont, obj)                                      \
57     ((cont)->cursed ? (obj)->owt * 2 : (cont)->blessed            \
58                                            ? ((obj)->owt + 3) / 4 \
59                                            : ((obj)->owt + 1) / 2)
60 #define GOLD_WT(n) (((n) + 50L) / 100L)
61 /* if you can figure this out, give yourself a hearty pat on the back... */
62 #define GOLD_CAPACITY(w, n) (((w) * -100L) - ((n) + 50L) - 1L)
63
64 /* A variable set in use_container(), to be used by the callback routines  */
65 /* in_container() and out_container() from askchain() and use_container(). */
66 /* Also used by menu_loot() and container_gone().                          */
67 static NEARDATA struct obj *current_container;
68 #define Icebox (current_container->otyp == ICE_BOX)
69
70 static const char moderateloadmsg[] = "You have a little trouble lifting";
71 static const char nearloadmsg[] = "You have much trouble lifting";
72 static const char overloadmsg[] = "You have extreme difficulty lifting";
73
74 /* BUG: this lets you look at cockatrice corpses while blind without
75    touching them */
76 /* much simpler version of the look-here code; used by query_classes() */
77 STATIC_OVL void
78 simple_look(otmp, here)
79 struct obj *otmp; /* list of objects */
80 boolean here;     /* flag for type of obj list linkage */
81 {
82     /* Neither of the first two cases is expected to happen, since
83      * we're only called after multiple classes of objects have been
84      * detected, hence multiple objects must be present.
85      */
86     if (!otmp) {
87         impossible("simple_look(null)");
88     } else if (!(here ? otmp->nexthere : otmp->nobj)) {
89         pline1(doname(otmp));
90     } else {
91         winid tmpwin = create_nhwindow(NHW_MENU);
92         putstr(tmpwin, 0, "");
93         do {
94             putstr(tmpwin, 0, doname(otmp));
95             otmp = here ? otmp->nexthere : otmp->nobj;
96         } while (otmp);
97         display_nhwindow(tmpwin, TRUE);
98         destroy_nhwindow(tmpwin);
99     }
100 }
101
102 int
103 collect_obj_classes(ilets, otmp, here, filter, itemcount)
104 char ilets[];
105 register struct obj *otmp;
106 boolean here;
107 boolean FDECL((*filter), (OBJ_P));
108 int *itemcount;
109 {
110     register int iletct = 0;
111     register char c;
112
113     *itemcount = 0;
114     ilets[iletct] = '\0'; /* terminate ilets so that index() will work */
115     while (otmp) {
116         c = def_oc_syms[(int) otmp->oclass].sym;
117         if (!index(ilets, c) && (!filter || (*filter)(otmp)))
118             ilets[iletct++] = c, ilets[iletct] = '\0';
119         *itemcount += 1;
120         otmp = here ? otmp->nexthere : otmp->nobj;
121     }
122
123     return iletct;
124 }
125
126 /*
127  * Suppose some '?' and '!' objects are present, but '/' objects aren't:
128  *      "a" picks all items without further prompting;
129  *      "A" steps through all items, asking one by one;
130  *      "?" steps through '?' items, asking, and ignores '!' ones;
131  *      "/" becomes 'A', since no '/' present;
132  *      "?a" or "a?" picks all '?' without further prompting;
133  *      "/a" or "a/" becomes 'A' since there aren't any '/'
134  *          (bug fix:  3.1.0 thru 3.1.3 treated it as "a");
135  *      "?/a" or "a?/" or "/a?",&c picks all '?' even though no '/'
136  *          (ie, treated as if it had just been "?a").
137  */
138 STATIC_OVL boolean
139 query_classes(oclasses, one_at_a_time, everything, action, objs, here,
140               menu_on_demand)
141 char oclasses[];
142 boolean *one_at_a_time, *everything;
143 const char *action;
144 struct obj *objs;
145 boolean here;
146 int *menu_on_demand;
147 {
148     char ilets[30], inbuf[BUFSZ]; /* FIXME: hardcoded ilets[] length */
149     int iletct, oclassct;
150     boolean not_everything;
151     char qbuf[QBUFSZ];
152     boolean m_seen;
153     int itemcount;
154
155     oclasses[oclassct = 0] = '\0';
156     *one_at_a_time = *everything = m_seen = FALSE;
157     iletct = collect_obj_classes(ilets, objs, here,
158                                  (boolean FDECL((*), (OBJ_P))) 0, &itemcount);
159     if (iletct == 0) {
160         return FALSE;
161     } else if (iletct == 1) {
162         oclasses[0] = def_char_to_objclass(ilets[0]);
163         oclasses[1] = '\0';
164         if (itemcount && menu_on_demand) {
165             ilets[iletct++] = 'm';
166             *menu_on_demand = 0;
167             ilets[iletct] = '\0';
168         }
169     } else { /* more than one choice available */
170         const char *where = 0;
171         register char sym, oc_of_sym, *p;
172         /* additional choices */
173         ilets[iletct++] = ' ';
174         ilets[iletct++] = 'a';
175         ilets[iletct++] = 'A';
176         ilets[iletct++] = (objs == invent ? 'i' : ':');
177         if (menu_on_demand) {
178             ilets[iletct++] = 'm';
179             *menu_on_demand = 0;
180         }
181         ilets[iletct] = '\0';
182     ask_again:
183         oclasses[oclassct = 0] = '\0';
184         *one_at_a_time = *everything = FALSE;
185         not_everything = FALSE;
186         Sprintf(qbuf, "What kinds of thing do you want to %s? [%s]", action,
187                 ilets);
188         getlin(qbuf, inbuf);
189         if (*inbuf == '\033')
190             return FALSE;
191
192         for (p = inbuf; (sym = *p++);) {
193             /* new A function (selective all) added by GAN 01/09/87 */
194             if (sym == ' ')
195                 continue;
196             else if (sym == 'A')
197                 *one_at_a_time = TRUE;
198             else if (sym == 'a')
199                 *everything = TRUE;
200             else if (sym == ':') {
201                 simple_look(objs, here); /* dumb if objs==invent */
202                 /* if we just scanned the contents of a container
203                    then mark it as having known contents */
204                 if (objs->where == OBJ_CONTAINED)
205                     objs->ocontainer->cknown = 1;
206                 goto ask_again;
207             } else if (sym == 'i') {
208                 (void) display_inventory((char *) 0, TRUE);
209                 goto ask_again;
210             } else if (sym == 'm') {
211                 m_seen = TRUE;
212             } else {
213                 oc_of_sym = def_char_to_objclass(sym);
214                 if (index(ilets, sym)) {
215                     add_valid_menu_class(oc_of_sym);
216                     oclasses[oclassct++] = oc_of_sym;
217                     oclasses[oclassct] = '\0';
218                 } else {
219                     if (!where)
220                         where =
221                             !strcmp(action, "pick up")
222                                 ? "here"
223                                 : !strcmp(action, "take out") ? "inside" : "";
224                     if (*where)
225                         There("are no %c's %s.", sym, where);
226                     else
227                         You("have no %c's.", sym);
228                     not_everything = TRUE;
229                 }
230             }
231         }
232         if (m_seen && menu_on_demand) {
233             *menu_on_demand = (*everything || !oclassct) ? -2 : -3;
234             return FALSE;
235         }
236         if (!oclassct && (!*everything || not_everything)) {
237             /* didn't pick anything,
238                or tried to pick something that's not present */
239             *one_at_a_time = TRUE; /* force 'A' */
240             *everything = FALSE;   /* inhibit 'a' */
241         }
242     }
243     return TRUE;
244 }
245
246 /* check whether hero is bare-handedly touching a cockatrice corpse */
247 STATIC_OVL boolean
248 fatal_corpse_mistake(obj, remotely)
249 struct obj *obj;
250 boolean remotely;
251 {
252     if (uarmg || remotely || obj->otyp != CORPSE
253         || !touch_petrifies(&mons[obj->corpsenm]) || Stone_resistance)
254         return FALSE;
255
256     if (poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM)) {
257         display_nhwindow(WIN_MESSAGE, FALSE); /* --More-- */
258         return FALSE;
259     }
260
261     pline("Touching %s is a fatal mistake.",
262           corpse_xname(obj, (const char *) 0, CXN_SINGULAR | CXN_ARTICLE));
263     instapetrify(killer_xname(obj));
264     return TRUE;
265 }
266
267 /* attempting to manipulate a Rider's corpse triggers its revival */
268 boolean
269 rider_corpse_revival(obj, remotely)
270 struct obj *obj;
271 boolean remotely;
272 {
273     if (!obj || obj->otyp != CORPSE || !is_rider(&mons[obj->corpsenm]))
274         return FALSE;
275
276     pline("At your %s, the corpse suddenly moves...",
277           remotely ? "attempted acquisition" : "touch");
278     (void) revive_corpse(obj);
279     exercise(A_WIS, FALSE);
280     return TRUE;
281 }
282
283 /* look at the objects at our location, unless there are too many of them */
284 STATIC_OVL void
285 check_here(picked_some)
286 boolean picked_some;
287 {
288     register struct obj *obj;
289     register int ct = 0;
290
291     /* count the objects here */
292     for (obj = level.objects[u.ux][u.uy]; obj; obj = obj->nexthere) {
293         if (obj != uchain)
294             ct++;
295     }
296
297     /* If there are objects here, take a look. */
298     if (ct) {
299         if (context.run)
300             nomul(0);
301         flush_screen(1);
302         (void) look_here(ct, picked_some);
303     } else {
304         read_engr_at(u.ux, u.uy);
305     }
306 }
307
308 /* Value set by query_objlist() for n_or_more(). */
309 static long val_for_n_or_more;
310
311 /* query_objlist callback: return TRUE if obj's count is >= reference value */
312 STATIC_OVL boolean
313 n_or_more(obj)
314 struct obj *obj;
315 {
316     if (obj == uchain)
317         return FALSE;
318     return (boolean) (obj->quan >= val_for_n_or_more);
319 }
320
321 /* list of valid menu classes for query_objlist() and allow_category callback
322    (with room for all object classes, 'u'npaid, BUCX, and terminator) */
323 static char valid_menu_classes[MAXOCLASSES + 1 + 4 + 1];
324 static boolean class_filter, bucx_filter, shop_filter;
325
326 void
327 add_valid_menu_class(c)
328 int c;
329 {
330     static int vmc_count = 0;
331
332     if (c == 0) { /* reset */
333         vmc_count = 0;
334         class_filter = bucx_filter = shop_filter = FALSE;
335     } else {
336         valid_menu_classes[vmc_count++] = (char) c;
337         /* categorize the new class */
338         switch (c) {
339         case 'B':
340         case 'U':
341         case 'C': /*FALLTHRU*/
342         case 'X':
343             bucx_filter = TRUE;
344             break;
345         case 'u':
346             shop_filter = TRUE;
347             break;
348         default:
349             class_filter = TRUE;
350             break;
351         }
352     }
353     valid_menu_classes[vmc_count] = '\0';
354 }
355
356 /* query_objlist callback: return TRUE if not uchain */
357 STATIC_OVL boolean
358 all_but_uchain(obj)
359 struct obj *obj;
360 {
361     return (boolean) (obj != uchain);
362 }
363
364 /* query_objlist callback: return TRUE */
365 /*ARGUSED*/
366 boolean
367 allow_all(obj)
368 struct obj *obj UNUSED;
369 {
370     return TRUE;
371 }
372
373 boolean
374 allow_category(obj)
375 struct obj *obj;
376 {
377     /* unpaid and BUC checks don't apply to coins */
378     if (obj->oclass == COIN_CLASS)
379         return index(valid_menu_classes, COIN_CLASS) ? TRUE : FALSE;
380
381     if (Role_if(PM_PRIEST))
382         obj->bknown = TRUE;
383     /*
384      * There are three types of filters possible and the first and
385      * third can have more than one entry:
386      *  1) object class (armor, potion, &c);
387      *  2) unpaid shop item;
388      *  3) bless/curse state (blessed, uncursed, cursed, BUC-unknown).
389      * When only one type is present, the situation is simple:
390      * to be accepted, obj's status must match one of the entries.
391      * When more than one type is present, the obj will now only
392      * be accepted when it matches one entry of each type.
393      * So ?!B will accept blessed scrolls or potions, and [u will
394      * accept unpaid armor.  (In 3.4.3, an object was accepted by
395      * this filter if it met any entry of any type, so ?!B resulted
396      * in accepting all scrolls and potions regardless of bless/curse
397      * state plus all blessed non-scroll, non-potion objects.)
398      */
399     /* if class is expected but obj's class is not in the list, reject */
400     if (class_filter && !index(valid_menu_classes, obj->oclass))
401         return FALSE;
402     /* if unpaid is expected and obj isn't unpaid, reject (treat a container
403        holding any unpaid object as unpaid even if isn't unpaid itself) */
404     if (shop_filter && !obj->unpaid
405         && !(Has_contents(obj) && count_unpaid(obj->cobj) > 0))
406         return FALSE;
407     /* check for particular bless/curse state */
408     if (bucx_filter) {
409         /* first categorize this object's bless/curse state */
410         char bucx =
411             !obj->bknown ? 'X' : obj->blessed ? 'B' : obj->cursed ? 'C' : 'U';
412
413         /* if its category is not in the list, reject */
414         if (!index(valid_menu_classes, bucx))
415             return FALSE;
416     }
417     /* obj didn't fail any of the filter checks, so accept */
418     return TRUE;
419 }
420
421 #if 0 /* not used */
422 /* query_objlist callback: return TRUE if valid category (class), no uchain */
423 STATIC_OVL boolean
424 allow_cat_no_uchain(obj)
425 struct obj *obj;
426 {
427     if (obj != uchain
428         && ((index(valid_menu_classes,'u') && obj->unpaid)
429             || index(valid_menu_classes, obj->oclass)))
430         return TRUE;
431     else
432         return FALSE;
433 }
434 #endif
435
436 /* query_objlist callback: return TRUE if valid class and worn */
437 boolean
438 is_worn_by_type(otmp)
439 register struct obj *otmp;
440 {
441     return (boolean) (!!(otmp->owornmask & (W_ARMOR | W_ACCESSORY | W_WEAPON))
442                       && index(valid_menu_classes, otmp->oclass) != 0);
443 }
444
445 /*
446  * Have the hero pick things from the ground
447  * or a monster's inventory if swallowed.
448  *
449  * Arg what:
450  *      >0  autopickup
451  *      =0  interactive
452  *      <0  pickup count of something
453  *
454  * Returns 1 if tried to pick something up, whether
455  * or not it succeeded.
456  */
457 int
458 pickup(what)
459 int what; /* should be a long */
460 {
461     int i, n, res, count, n_tried = 0, n_picked = 0;
462     menu_item *pick_list = (menu_item *) 0;
463     boolean autopickup = what > 0;
464     struct obj *objchain;
465     int traverse_how;
466
467     /* we might have arrived here while fainted or sleeping, via
468        random teleport or levitation timeout; if so, skip check_here
469        and read_engr_at in addition to bypassing autopickup itself
470        [probably ought to check whether hero is using a cockatrice
471        corpse for a pillow here... (also at initial faint/sleep)] */
472     if (autopickup && multi < 0 && unconscious())
473         return 0;
474
475     if (what < 0) /* pick N of something */
476         count = -what;
477     else /* pick anything */
478         count = 0;
479
480     if (!u.uswallow) {
481         struct trap *ttmp = t_at(u.ux, u.uy);
482         /* no auto-pick if no-pick move, nothing there, or in a pool */
483         if (autopickup && (context.nopick || !OBJ_AT(u.ux, u.uy)
484                            || (is_pool(u.ux, u.uy) && !Underwater)
485                            || is_lava(u.ux, u.uy))) {
486             read_engr_at(u.ux, u.uy);
487             return 0;
488         }
489
490         /* no pickup if levitating & not on air or water level */
491         if (!can_reach_floor(TRUE)) {
492             if ((multi && !context.run) || (autopickup && !flags.pickup)
493                 || (ttmp && uteetering_at_seen_pit(ttmp)))
494                 read_engr_at(u.ux, u.uy);
495             return 0;
496         }
497         /* multi && !context.run means they are in the middle of some other
498          * action, or possibly paralyzed, sleeping, etc.... and they just
499          * teleported onto the object.  They shouldn't pick it up.
500          */
501         if ((multi && !context.run) || (autopickup && !flags.pickup)) {
502             check_here(FALSE);
503             return 0;
504         }
505         if (notake(youmonst.data)) {
506             if (!autopickup)
507                 You("are physically incapable of picking anything up.");
508             else
509                 check_here(FALSE);
510             return 0;
511         }
512
513         /* if there's anything here, stop running */
514         if (OBJ_AT(u.ux, u.uy) && context.run && context.run != 8
515             && !context.nopick)
516             nomul(0);
517     }
518
519     add_valid_menu_class(0); /* reset */
520     if (!u.uswallow) {
521         objchain = level.objects[u.ux][u.uy];
522         traverse_how = BY_NEXTHERE;
523     } else {
524         objchain = u.ustuck->minvent;
525         traverse_how = 0; /* nobj */
526     }
527     /*
528      * Start the actual pickup process.  This is split into two main
529      * sections, the newer menu and the older "traditional" methods.
530      * Automatic pickup has been split into its own menu-style routine
531      * to make things less confusing.
532      */
533     if (autopickup) {
534         n = autopick(objchain, traverse_how, &pick_list);
535         goto menu_pickup;
536     }
537
538     if (flags.menu_style != MENU_TRADITIONAL || iflags.menu_requested) {
539         /* use menus exclusively */
540         if (count) { /* looking for N of something */
541             char buf[QBUFSZ];
542             Sprintf(buf, "Pick %d of what?", count);
543             val_for_n_or_more = count; /* set up callback selector */
544             n = query_objlist(buf, objchain, traverse_how | AUTOSELECT_SINGLE
545                                                  | INVORDER_SORT,
546                               &pick_list, PICK_ONE, n_or_more);
547             /* correct counts, if any given */
548             for (i = 0; i < n; i++)
549                 pick_list[i].count = count;
550         } else {
551             n = query_objlist("Pick up what?", objchain,
552                               traverse_how | AUTOSELECT_SINGLE | INVORDER_SORT
553                                   | FEEL_COCKATRICE,
554                               &pick_list, PICK_ANY, all_but_uchain);
555         }
556     menu_pickup:
557         n_tried = n;
558         for (n_picked = i = 0; i < n; i++) {
559             res = pickup_object(pick_list[i].item.a_obj, pick_list[i].count,
560                                 FALSE);
561             if (res < 0)
562                 break; /* can't continue */
563             n_picked += res;
564         }
565         if (pick_list)
566             free((genericptr_t) pick_list);
567
568     } else {
569         /* old style interface */
570         int ct = 0;
571         long lcount;
572         boolean all_of_a_type, selective;
573         char oclasses[MAXOCLASSES];
574         struct obj *obj, *obj2;
575
576         oclasses[0] = '\0';   /* types to consider (empty for all) */
577         all_of_a_type = TRUE; /* take all of considered types */
578         selective = FALSE;    /* ask for each item */
579
580         /* check for more than one object */
581         for (obj = objchain; obj;
582              obj = (traverse_how == BY_NEXTHERE) ? obj->nexthere : obj->nobj)
583             ct++;
584
585         if (ct == 1 && count) {
586             /* if only one thing, then pick it */
587             obj = objchain;
588             lcount = min(obj->quan, (long) count);
589             n_tried++;
590             if (pickup_object(obj, lcount, FALSE) > 0)
591                 n_picked++; /* picked something */
592             goto end_query;
593
594         } else if (ct >= 2) {
595             int via_menu = 0;
596
597             There("are %s objects here.", (ct <= 10) ? "several" : "many");
598             if (!query_classes(oclasses, &selective, &all_of_a_type,
599                                "pick up", objchain,
600                                traverse_how == BY_NEXTHERE, &via_menu)) {
601                 if (!via_menu)
602                     return 0;
603                 n = query_objlist(
604                     "Pick up what?", objchain,
605                     traverse_how | (selective ? 0 : INVORDER_SORT),
606                     &pick_list, PICK_ANY,
607                     via_menu == -2 ? allow_all : allow_category);
608                 goto menu_pickup;
609             }
610         }
611
612         for (obj = objchain; obj; obj = obj2) {
613             if (traverse_how == BY_NEXTHERE)
614                 obj2 = obj->nexthere; /* perhaps obj will be picked up */
615             else
616                 obj2 = obj->nobj;
617             lcount = -1L;
618
619             if (!selective && oclasses[0] && !index(oclasses, obj->oclass))
620                 continue;
621
622             if (!all_of_a_type) {
623                 char qbuf[BUFSZ];
624
625                 (void) safe_qbuf(qbuf, "Pick up ", "?", obj, doname,
626                                  ansimpleoname, something);
627                 switch ((obj->quan < 2L) ? ynaq(qbuf) : ynNaq(qbuf)) {
628                 case 'q':
629                     goto end_query; /* out 2 levels */
630                 case 'n':
631                     continue;
632                 case 'a':
633                     all_of_a_type = TRUE;
634                     if (selective) {
635                         selective = FALSE;
636                         oclasses[0] = obj->oclass;
637                         oclasses[1] = '\0';
638                     }
639                     break;
640                 case '#': /* count was entered */
641                     if (!yn_number)
642                         continue; /* 0 count => No */
643                     lcount = (long) yn_number;
644                     if (lcount > obj->quan)
645                         lcount = obj->quan;
646                 /* fall thru */
647                 default: /* 'y' */
648                     break;
649                 }
650             }
651             if (lcount == -1L)
652                 lcount = obj->quan;
653
654             n_tried++;
655             if ((res = pickup_object(obj, lcount, FALSE)) < 0)
656                 break;
657             n_picked += res;
658         }
659     end_query:
660         ; /* semicolon needed by brain-damaged compilers */
661     }
662
663     if (!u.uswallow) {
664         if (hides_under(youmonst.data))
665             (void) hideunder(&youmonst);
666
667         /* position may need updating (invisible hero) */
668         if (n_picked)
669             newsym(u.ux, u.uy);
670
671         /* check if there's anything else here after auto-pickup is done */
672         if (autopickup)
673             check_here(n_picked > 0);
674     }
675     return (n_tried > 0);
676 }
677
678 boolean
679 is_autopickup_exception(obj, grab)
680 struct obj *obj;
681 boolean grab; /* forced pickup, rather than forced leave behind? */
682 {
683     /*
684      *  Does the text description of this match an exception?
685      */
686     char *objdesc = makesingular(doname(obj));
687     struct autopickup_exception *ape =
688         (grab) ? iflags.autopickup_exceptions[AP_GRAB]
689                : iflags.autopickup_exceptions[AP_LEAVE];
690     while (ape) {
691         if (regex_match(objdesc, ape->regex))
692             return TRUE;
693         ape = ape->next;
694     }
695     return FALSE;
696 }
697
698 /*
699  * Pick from the given list using flags.pickup_types.  Return the number
700  * of items picked (not counts).  Create an array that returns pointers
701  * and counts of the items to be picked up.  If the number of items
702  * picked is zero, the pickup list is left alone.  The caller of this
703  * function must free the pickup list.
704  */
705 STATIC_OVL int
706 autopick(olist, follow, pick_list)
707 struct obj *olist;     /* the object list */
708 int follow;            /* how to follow the object list */
709 menu_item **pick_list; /* list of objects and counts to pick up */
710 {
711     menu_item *pi; /* pick item */
712     struct obj *curr;
713     int n;
714     boolean pickit;
715     const char *otypes = flags.pickup_types;
716
717     /* first count the number of eligible items */
718     for (n = 0, curr = olist; curr; curr = FOLLOW(curr, follow)) {
719         pickit = (!*otypes || index(otypes, curr->oclass));
720         /* check for "always pick up */
721         if (!pickit)
722             pickit = is_autopickup_exception(curr, TRUE);
723         /* then for "never pick up */
724         if (pickit)
725             pickit = !is_autopickup_exception(curr, FALSE);
726         /* pickup_thrown overrides pickup_types and exceptions */
727         if (!pickit)
728             pickit = (flags.pickup_thrown && curr->was_thrown);
729         /* finally, do we count this object? */
730         if (pickit)
731             ++n;
732     }
733
734     if (n) {
735         *pick_list = pi = (menu_item *) alloc(sizeof(menu_item) * n);
736         for (n = 0, curr = olist; curr; curr = FOLLOW(curr, follow)) {
737             pickit = (!*otypes || index(otypes, curr->oclass));
738             if (!pickit)
739                 pickit = is_autopickup_exception(curr, TRUE);
740             if (pickit)
741                 pickit = !is_autopickup_exception(curr, FALSE);
742             if (!pickit)
743                 pickit = (flags.pickup_thrown && curr->was_thrown);
744             if (pickit) {
745                 pi[n].item.a_obj = curr;
746                 pi[n].count = curr->quan;
747                 n++;
748             }
749         }
750     }
751     return n;
752 }
753
754 /*
755  * Put up a menu using the given object list.  Only those objects on the
756  * list that meet the approval of the allow function are displayed.  Return
757  * a count of the number of items selected, as well as an allocated array of
758  * menu_items, containing pointers to the objects selected and counts.  The
759  * returned counts are guaranteed to be in bounds and non-zero.
760  *
761  * Query flags:
762  *      BY_NEXTHERE       - Follow object list via nexthere instead of nobj.
763  *      AUTOSELECT_SINGLE - Don't ask if only 1 object qualifies - just
764  *                          use it.
765  *      USE_INVLET        - Use object's invlet.
766  *      INVORDER_SORT     - Use hero's pack order.
767  *      INCLUDE_HERO      - Showing engulfer's invent; show hero too.
768  *      SIGNAL_NOMENU     - Return -1 rather than 0 if nothing passes "allow".
769  *      SIGNAL_ESCAPE     - Return -1 rather than 0 if player uses ESC to
770  *                          pick nothing.
771  */
772 int
773 query_objlist(qstr, olist, qflags, pick_list, how, allow)
774 const char *qstr;                 /* query string */
775 struct obj *olist;                /* the list to pick from */
776 int qflags;                       /* options to control the query */
777 menu_item **pick_list;            /* return list of items picked */
778 int how;                          /* type of query */
779 boolean FDECL((*allow), (OBJ_P)); /* allow function */
780 {
781     int i, n, actualn;
782     winid win;
783     struct obj *curr, *last, fake_hero_object;
784     struct obj **oarray;
785     char *pack;
786     anything any;
787     boolean printed_type_name, sorted = (qflags & INVORDER_SORT) != 0,
788                                engulfer = (qflags & INCLUDE_HERO) != 0;
789
790     *pick_list = (menu_item *) 0;
791     if (!olist && !engulfer)
792         return 0;
793
794     /* count the number of items allowed */
795     for (n = 0, last = 0, curr = olist; curr; curr = FOLLOW(curr, qflags))
796         if ((*allow)(curr)) {
797             last = curr;
798             n++;
799         }
800     actualn = n;
801     if (engulfer) {
802         ++n;
803         /* don't autoselect swallowed hero if it's the only choice */
804         qflags &= ~AUTOSELECT_SINGLE;
805     }
806
807     if (n == 0) /* nothing to pick here */
808         return (qflags & SIGNAL_NOMENU) ? -1 : 0;
809
810     if (n == 1 && (qflags & AUTOSELECT_SINGLE)) {
811         *pick_list = (menu_item *) alloc(sizeof(menu_item));
812         (*pick_list)->item.a_obj = last;
813         (*pick_list)->count = last->quan;
814         return 1;
815     }
816
817     oarray = objarr_init(actualn);
818     /* Add objects to the array */
819     i = 0;
820     for (curr = olist; curr; curr = FOLLOW(curr, qflags)) {
821         if ((*allow)(curr)) {
822             objarr_set(curr, i++, oarray, (flags.sortloot == 'f'
823                                            || (flags.sortloot == 'l'
824                                                && !(qflags & USE_INVLET))));
825         }
826     }
827
828     win = create_nhwindow(NHW_MENU);
829     start_menu(win);
830     any = zeroany;
831
832     /*
833      * Run through the list and add the objects to the menu.  If
834      * INVORDER_SORT is set, we'll run through the list once for
835      * each type so we can group them.  The allow function will only
836      * be called once per object in the list.
837      */
838     pack = flags.inv_order;
839     do {
840         printed_type_name = FALSE;
841         for (i = 0; i < actualn; i++) {
842             curr = oarray[i];
843             if ((qflags & FEEL_COCKATRICE) && curr->otyp == CORPSE
844                 && will_feel_cockatrice(curr, FALSE)) {
845                 destroy_nhwindow(win); /* stop the menu and revert */
846                 (void) look_here(0, FALSE);
847                 return 0;
848             }
849             if ((!sorted || curr->oclass == *pack) && (*allow)(curr)) {
850                 /* if sorting, print type name (once only) */
851                 if (sorted && !printed_type_name) {
852                     any = zeroany;
853                     add_menu(win, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
854                              let_to_name(*pack, FALSE,
855                                          (how != PICK_NONE)
856                                              && iflags.menu_head_objsym),
857                              MENU_UNSELECTED);
858                     printed_type_name = TRUE;
859                 }
860
861                 any.a_obj = curr;
862                 add_menu(win, obj_to_glyph(curr), &any,
863                          (qflags & USE_INVLET) ? curr->invlet : 0,
864                          def_oc_syms[(int) objects[curr->otyp].oc_class].sym,
865                          ATR_NONE, doname_with_price(curr), MENU_UNSELECTED);
866             }
867         }
868         pack++;
869     } while (sorted && *pack);
870     free(oarray);
871
872     if (engulfer) {
873         char buf[BUFSZ];
874
875         any = zeroany;
876         if (sorted && n > 1) {
877             Sprintf(buf, "%s Creatures",
878                     is_animal(u.ustuck->data) ? "Swallowed" : "Engulfed");
879             add_menu(win, NO_GLYPH, &any, 0, 0, iflags.menu_headings, buf,
880                      MENU_UNSELECTED);
881         }
882         fake_hero_object = zeroobj;
883         fake_hero_object.quan = 1L; /* not strictly necessary... */
884         any.a_obj = &fake_hero_object;
885         add_menu(win, mon_to_glyph(&youmonst), &any,
886                  /* fake inventory letter, no group accelerator */
887                  CONTAINED_SYM, 0, ATR_NONE, an(self_lookat(buf)),
888                  MENU_UNSELECTED);
889     }
890
891     end_menu(win, qstr);
892     n = select_menu(win, how, pick_list);
893     destroy_nhwindow(win);
894
895     if (n > 0) {
896         menu_item *mi;
897         int k;
898
899         /* fix up counts:  -1 means no count used => pick all;
900            if fake_hero_object was picked, discard that choice */
901         for (i = k = 0, mi = *pick_list; i < n; i++, mi++) {
902             if (mi->item.a_obj == &fake_hero_object)
903                 continue;
904             if (mi->count == -1L || mi->count > mi->item.a_obj->quan)
905                 mi->count = mi->item.a_obj->quan;
906             if (k < i)
907                 (*pick_list)[k] = *mi;
908             ++k;
909         }
910         if (!k) {
911             /* fake_hero was only choice so discard whole list */
912             free((genericptr_t) *pick_list);
913             *pick_list = 0;
914             n = 0;
915         } else if (k < n) {
916             /* other stuff plus fake_hero; last slot is now unused */
917             (*pick_list)[k].item = zeroany;
918             (*pick_list)[k].count = 0L;
919             n = k;
920         }
921     } else if (n < 0) {
922         /* -1 is used for SIGNAL_NOMENU, so callers don't expect it
923            to indicate that the player declined to make a choice */
924         n = (qflags & SIGNAL_ESCAPE) ? -2 : 0;
925     }
926     return n;
927 }
928
929 /*
930  * allow menu-based category (class) selection (for Drop,take off etc.)
931  *
932  */
933 int
934 query_category(qstr, olist, qflags, pick_list, how)
935 const char *qstr;      /* query string */
936 struct obj *olist;     /* the list to pick from */
937 int qflags;            /* behaviour modification flags */
938 menu_item **pick_list; /* return list of items picked */
939 int how;               /* type of query */
940 {
941     int n;
942     winid win;
943     struct obj *curr;
944     char *pack;
945     anything any;
946     boolean collected_type_name;
947     char invlet;
948     int ccount;
949     boolean do_unpaid = FALSE;
950     boolean do_blessed = FALSE, do_cursed = FALSE, do_uncursed = FALSE,
951             do_buc_unknown = FALSE;
952     int num_buc_types = 0;
953
954     *pick_list = (menu_item *) 0;
955     if (!olist)
956         return 0;
957     if ((qflags & UNPAID_TYPES) && count_unpaid(olist))
958         do_unpaid = TRUE;
959     if ((qflags & BUC_BLESSED) && count_buc(olist, BUC_BLESSED)) {
960         do_blessed = TRUE;
961         num_buc_types++;
962     }
963     if ((qflags & BUC_CURSED) && count_buc(olist, BUC_CURSED)) {
964         do_cursed = TRUE;
965         num_buc_types++;
966     }
967     if ((qflags & BUC_UNCURSED) && count_buc(olist, BUC_UNCURSED)) {
968         do_uncursed = TRUE;
969         num_buc_types++;
970     }
971     if ((qflags & BUC_UNKNOWN) && count_buc(olist, BUC_UNKNOWN)) {
972         do_buc_unknown = TRUE;
973         num_buc_types++;
974     }
975
976     ccount = count_categories(olist, qflags);
977     /* no point in actually showing a menu for a single category */
978     if (ccount == 1 && !do_unpaid && num_buc_types <= 1
979         && !(qflags & BILLED_TYPES)) {
980         for (curr = olist; curr; curr = FOLLOW(curr, qflags)) {
981             if ((qflags & WORN_TYPES)
982                 && !(curr->owornmask & (W_ARMOR | W_ACCESSORY | W_WEAPON)))
983                 continue;
984             break;
985         }
986         if (curr) {
987             *pick_list = (menu_item *) alloc(sizeof(menu_item));
988             (*pick_list)->item.a_int = curr->oclass;
989             return 1;
990         } else {
991             debugpline0("query_category: no single object match");
992         }
993         return 0;
994     }
995
996     win = create_nhwindow(NHW_MENU);
997     start_menu(win);
998     pack = flags.inv_order;
999     if ((qflags & ALL_TYPES) && (ccount > 1)) {
1000         invlet = 'a';
1001         any = zeroany;
1002         any.a_int = ALL_TYPES_SELECTED;
1003         add_menu(win, NO_GLYPH, &any, invlet, 0, ATR_NONE,
1004                  (qflags & WORN_TYPES) ? "All worn types" : "All types",
1005                  MENU_UNSELECTED);
1006         invlet = 'b';
1007     } else
1008         invlet = 'a';
1009     do {
1010         collected_type_name = FALSE;
1011         for (curr = olist; curr; curr = FOLLOW(curr, qflags)) {
1012             if (curr->oclass == *pack) {
1013                 if ((qflags & WORN_TYPES)
1014                     && !(curr->owornmask & (W_ARMOR | W_ACCESSORY | W_WEAPON)))
1015                     continue;
1016                 if (!collected_type_name) {
1017                     any = zeroany;
1018                     any.a_int = curr->oclass;
1019                     add_menu(
1020                         win, NO_GLYPH, &any, invlet++,
1021                         def_oc_syms[(int) objects[curr->otyp].oc_class].sym,
1022                         ATR_NONE, let_to_name(*pack, FALSE,
1023                                               (how != PICK_NONE)
1024                                                   && iflags.menu_head_objsym),
1025                         MENU_UNSELECTED);
1026                     collected_type_name = TRUE;
1027                 }
1028             }
1029         }
1030         pack++;
1031         if (invlet >= 'u') {
1032             impossible("query_category: too many categories");
1033             return 0;
1034         }
1035     } while (*pack);
1036     /* unpaid items if there are any */
1037     if (do_unpaid) {
1038         invlet = 'u';
1039         any = zeroany;
1040         any.a_int = 'u';
1041         add_menu(win, NO_GLYPH, &any, invlet, 0, ATR_NONE, "Unpaid items",
1042                  MENU_UNSELECTED);
1043     }
1044     /* billed items: checked by caller, so always include if BILLED_TYPES */
1045     if (qflags & BILLED_TYPES) {
1046         invlet = 'x';
1047         any = zeroany;
1048         any.a_int = 'x';
1049         add_menu(win, NO_GLYPH, &any, invlet, 0, ATR_NONE,
1050                  "Unpaid items already used up", MENU_UNSELECTED);
1051     }
1052     if (qflags & CHOOSE_ALL) {
1053         invlet = 'A';
1054         any = zeroany;
1055         any.a_int = 'A';
1056         add_menu(win, NO_GLYPH, &any, invlet, 0, ATR_NONE,
1057                  (qflags & WORN_TYPES) ? "Auto-select every item being worn"
1058                                        : "Auto-select every item",
1059                  MENU_UNSELECTED);
1060     }
1061     /* items with b/u/c/unknown if there are any */
1062     if (do_blessed) {
1063         invlet = 'B';
1064         any = zeroany;
1065         any.a_int = 'B';
1066         add_menu(win, NO_GLYPH, &any, invlet, 0, ATR_NONE,
1067                  "Items known to be Blessed", MENU_UNSELECTED);
1068     }
1069     if (do_cursed) {
1070         invlet = 'C';
1071         any = zeroany;
1072         any.a_int = 'C';
1073         add_menu(win, NO_GLYPH, &any, invlet, 0, ATR_NONE,
1074                  "Items known to be Cursed", MENU_UNSELECTED);
1075     }
1076     if (do_uncursed) {
1077         invlet = 'U';
1078         any = zeroany;
1079         any.a_int = 'U';
1080         add_menu(win, NO_GLYPH, &any, invlet, 0, ATR_NONE,
1081                  "Items known to be Uncursed", MENU_UNSELECTED);
1082     }
1083     if (do_buc_unknown) {
1084         invlet = 'X';
1085         any = zeroany;
1086         any.a_int = 'X';
1087         add_menu(win, NO_GLYPH, &any, invlet, 0, ATR_NONE,
1088                  "Items of unknown B/C/U status", MENU_UNSELECTED);
1089     }
1090     end_menu(win, qstr);
1091     n = select_menu(win, how, pick_list);
1092     destroy_nhwindow(win);
1093     if (n < 0)
1094         n = 0; /* caller's don't expect -1 */
1095     return n;
1096 }
1097
1098 STATIC_OVL int
1099 count_categories(olist, qflags)
1100 struct obj *olist;
1101 int qflags;
1102 {
1103     char *pack;
1104     boolean counted_category;
1105     int ccount = 0;
1106     struct obj *curr;
1107
1108     pack = flags.inv_order;
1109     do {
1110         counted_category = FALSE;
1111         for (curr = olist; curr; curr = FOLLOW(curr, qflags)) {
1112             if (curr->oclass == *pack) {
1113                 if ((qflags & WORN_TYPES)
1114                     && !(curr->owornmask & (W_ARMOR | W_ACCESSORY | W_WEAPON)))
1115                     continue;
1116                 if (!counted_category) {
1117                     ccount++;
1118                     counted_category = TRUE;
1119                 }
1120             }
1121         }
1122         pack++;
1123     } while (*pack);
1124     return ccount;
1125 }
1126
1127 /* could we carry `obj'? if not, could we carry some of it/them? */
1128 STATIC_OVL long
1129 carry_count(obj, container, count, telekinesis, wt_before, wt_after)
1130 struct obj *obj, *container; /* object to pick up, bag it's coming out of */
1131 long count;
1132 boolean telekinesis;
1133 int *wt_before, *wt_after;
1134 {
1135     boolean adjust_wt = container && carried(container),
1136             is_gold = obj->oclass == COIN_CLASS;
1137     int wt, iw, ow, oow;
1138     long qq, savequan, umoney;
1139     unsigned saveowt;
1140     const char *verb, *prefx1, *prefx2, *suffx;
1141     char obj_nambuf[BUFSZ], where[BUFSZ];
1142
1143     savequan = obj->quan;
1144     saveowt = obj->owt;
1145     umoney = money_cnt(invent);
1146     iw = max_capacity();
1147
1148     if (count != savequan) {
1149         obj->quan = count;
1150         obj->owt = (unsigned) weight(obj);
1151     }
1152     wt = iw + (int) obj->owt;
1153     if (adjust_wt)
1154         wt -= (container->otyp == BAG_OF_HOLDING)
1155                   ? (int) DELTA_CWT(container, obj)
1156                   : (int) obj->owt;
1157     /* This will go with silver+copper & new gold weight */
1158     if (is_gold) /* merged gold might affect cumulative weight */
1159         wt -= (GOLD_WT(umoney) + GOLD_WT(count) - GOLD_WT(umoney + count));
1160     if (count != savequan) {
1161         obj->quan = savequan;
1162         obj->owt = saveowt;
1163     }
1164     *wt_before = iw;
1165     *wt_after = wt;
1166
1167     if (wt < 0)
1168         return count;
1169
1170     /* see how many we can lift */
1171     if (is_gold) {
1172         iw -= (int) GOLD_WT(umoney);
1173         if (!adjust_wt) {
1174             qq = GOLD_CAPACITY((long) iw, umoney);
1175         } else {
1176             oow = 0;
1177             qq = 50L - (umoney % 100L) - 1L;
1178             if (qq < 0L)
1179                 qq += 100L;
1180             for (; qq <= count; qq += 100L) {
1181                 obj->quan = qq;
1182                 obj->owt = (unsigned) GOLD_WT(qq);
1183                 ow = (int) GOLD_WT(umoney + qq);
1184                 ow -= (container->otyp == BAG_OF_HOLDING)
1185                           ? (int) DELTA_CWT(container, obj)
1186                           : (int) obj->owt;
1187                 if (iw + ow >= 0)
1188                     break;
1189                 oow = ow;
1190             }
1191             iw -= oow;
1192             qq -= 100L;
1193         }
1194         if (qq < 0L)
1195             qq = 0L;
1196         else if (qq > count)
1197             qq = count;
1198         wt = iw + (int) GOLD_WT(umoney + qq);
1199     } else if (count > 1 || count < obj->quan) {
1200         /*
1201          * Ugh. Calc num to lift by changing the quan of of the
1202          * object and calling weight.
1203          *
1204          * This works for containers only because containers
1205          * don't merge.         -dean
1206          */
1207         for (qq = 1L; qq <= count; qq++) {
1208             obj->quan = qq;
1209             obj->owt = (unsigned) (ow = weight(obj));
1210             if (adjust_wt)
1211                 ow -= (container->otyp == BAG_OF_HOLDING)
1212                           ? (int) DELTA_CWT(container, obj)
1213                           : (int) obj->owt;
1214             if (iw + ow >= 0)
1215                 break;
1216             wt = iw + ow;
1217         }
1218         --qq;
1219     } else {
1220         /* there's only one, and we can't lift it */
1221         qq = 0L;
1222     }
1223     obj->quan = savequan;
1224     obj->owt = saveowt;
1225
1226     if (qq < count) {
1227         /* some message will be given */
1228         Strcpy(obj_nambuf, doname(obj));
1229         if (container) {
1230             Sprintf(where, "in %s", the(xname(container)));
1231             verb = "carry";
1232         } else {
1233             Strcpy(where, "lying here");
1234             verb = telekinesis ? "acquire" : "lift";
1235         }
1236     } else {
1237         /* lint suppression */
1238         *obj_nambuf = *where = '\0';
1239         verb = "";
1240     }
1241     /* we can carry qq of them */
1242     if (qq > 0) {
1243         if (qq < count)
1244             You("can only %s %s of the %s %s.", verb,
1245                 (qq == 1L) ? "one" : "some", obj_nambuf, where);
1246         *wt_after = wt;
1247         return qq;
1248     }
1249
1250     if (!container)
1251         Strcpy(where, "here"); /* slightly shorter form */
1252     if (invent || umoney) {
1253         prefx1 = "you cannot ";
1254         prefx2 = "";
1255         suffx = " any more";
1256     } else {
1257         prefx1 = (obj->quan == 1L) ? "it " : "even one ";
1258         prefx2 = "is too heavy for you to ";
1259         suffx = "";
1260     }
1261     There("%s %s %s, but %s%s%s%s.", otense(obj, "are"), obj_nambuf, where,
1262           prefx1, prefx2, verb, suffx);
1263
1264     /* *wt_after = iw; */
1265     return 0L;
1266 }
1267
1268 /* determine whether character is able and player is willing to carry `obj' */
1269 STATIC_OVL
1270 int
1271 lift_object(obj, container, cnt_p, telekinesis)
1272 struct obj *obj, *container; /* object to pick up, bag it's coming out of */
1273 long *cnt_p;
1274 boolean telekinesis;
1275 {
1276     int result, old_wt, new_wt, prev_encumbr, next_encumbr;
1277
1278     if (obj->otyp == BOULDER && Sokoban) {
1279         You("cannot get your %s around this %s.", body_part(HAND),
1280             xname(obj));
1281         return -1;
1282     }
1283     /* override weight consideration for loadstone picked up by anybody
1284        and for boulder picked up by hero poly'd into a giant; override
1285        availability of open inventory slot iff not already carrying one */
1286     if (obj->otyp == LOADSTONE
1287         || (obj->otyp == BOULDER && throws_rocks(youmonst.data))) {
1288         if (inv_cnt(FALSE) < 52 || !carrying(obj->otyp)
1289             || merge_choice(invent, obj))
1290             return 1; /* lift regardless of current situation */
1291         /* if we reach here, we're out of slots and already have at least
1292            one of these, so treat this one more like a normal item */
1293         You("are carrying too much stuff to pick up %s %s.",
1294             (obj->quan == 1L) ? "another" : "more", simpleonames(obj));
1295         return -1;
1296     }
1297
1298     *cnt_p =
1299         carry_count(obj, container, *cnt_p, telekinesis, &old_wt, &new_wt);
1300     if (*cnt_p < 1L) {
1301         result = -1; /* nothing lifted */
1302     } else if (obj->oclass != COIN_CLASS
1303                /* [exception for gold coins will have to change
1304                    if silver/copper ones ever get implemented] */
1305                && inv_cnt(FALSE) >= 52 && !merge_choice(invent, obj)) {
1306         Your("knapsack cannot accommodate any more items.");
1307         result = -1; /* nothing lifted */
1308     } else {
1309         result = 1;
1310         prev_encumbr = near_capacity();
1311         if (prev_encumbr < flags.pickup_burden)
1312             prev_encumbr = flags.pickup_burden;
1313         next_encumbr = calc_capacity(new_wt - old_wt);
1314         if (next_encumbr > prev_encumbr) {
1315             if (telekinesis) {
1316                 result = 0; /* don't lift */
1317             } else {
1318                 char qbuf[BUFSZ];
1319                 long savequan = obj->quan;
1320
1321                 obj->quan = *cnt_p;
1322                 Strcpy(qbuf, (next_encumbr > HVY_ENCUMBER)
1323                                  ? overloadmsg
1324                                  : (next_encumbr > MOD_ENCUMBER)
1325                                        ? nearloadmsg
1326                                        : moderateloadmsg);
1327                 if (container)
1328                     (void) strsubst(qbuf, "lifting", "removing");
1329                 Strcat(qbuf, " ");
1330                 (void) safe_qbuf(qbuf, qbuf, ".  Continue?", obj, doname,
1331                                  ansimpleoname, something);
1332                 obj->quan = savequan;
1333                 switch (ynq(qbuf)) {
1334                 case 'q':
1335                     result = -1;
1336                     break;
1337                 case 'n':
1338                     result = 0;
1339                     break;
1340                 default:
1341                     break; /* 'y' => result == 1 */
1342                 }
1343                 clear_nhwindow(WIN_MESSAGE);
1344             }
1345         }
1346     }
1347
1348     if (obj->otyp == SCR_SCARE_MONSTER && result <= 0 && !container)
1349         obj->spe = 0;
1350     return result;
1351 }
1352
1353 /*
1354  * Pick up <count> of obj from the ground and add it to the hero's inventory.
1355  * Returns -1 if caller should break out of its loop, 0 if nothing picked
1356  * up, 1 if otherwise.
1357  */
1358 int
1359 pickup_object(obj, count, telekinesis)
1360 struct obj *obj;
1361 long count;
1362 boolean telekinesis; /* not picking it up directly by hand */
1363 {
1364     int res, nearload;
1365
1366     if (obj->quan < count) {
1367         impossible("pickup_object: count %ld > quan %ld?", count, obj->quan);
1368         return 0;
1369     }
1370
1371     /* In case of auto-pickup, where we haven't had a chance
1372        to look at it yet; affects docall(SCR_SCARE_MONSTER). */
1373     if (!Blind)
1374         obj->dknown = 1;
1375
1376     if (obj == uchain) { /* do not pick up attached chain */
1377         return 0;
1378     } else if (obj->oartifact && !touch_artifact(obj, &youmonst)) {
1379         return 0;
1380     } else if (obj->otyp == CORPSE) {
1381         if (fatal_corpse_mistake(obj, telekinesis)
1382             || rider_corpse_revival(obj, telekinesis))
1383             return -1;
1384     } else if (obj->otyp == SCR_SCARE_MONSTER) {
1385         if (obj->blessed)
1386             obj->blessed = 0;
1387         else if (!obj->spe && !obj->cursed)
1388             obj->spe = 1;
1389         else {
1390             pline_The("scroll%s %s to dust as you %s %s up.", plur(obj->quan),
1391                       otense(obj, "turn"), telekinesis ? "raise" : "pick",
1392                       (obj->quan == 1L) ? "it" : "them");
1393             if (!(objects[SCR_SCARE_MONSTER].oc_name_known)
1394                 && !(objects[SCR_SCARE_MONSTER].oc_uname))
1395                 docall(obj);
1396             useupf(obj, obj->quan);
1397             return 1; /* tried to pick something up and failed, but
1398                          don't want to terminate pickup loop yet   */
1399         }
1400     }
1401
1402     if ((res = lift_object(obj, (struct obj *) 0, &count, telekinesis)) <= 0)
1403         return res;
1404
1405     /* Whats left of the special case for gold :-) */
1406     if (obj->oclass == COIN_CLASS)
1407         context.botl = 1;
1408     if (obj->quan != count && obj->otyp != LOADSTONE)
1409         obj = splitobj(obj, count);
1410
1411     obj = pick_obj(obj);
1412
1413     if (uwep && uwep == obj)
1414         mrg_to_wielded = TRUE;
1415     nearload = near_capacity();
1416     prinv(nearload == SLT_ENCUMBER ? moderateloadmsg : (char *) 0, obj,
1417           count);
1418     mrg_to_wielded = FALSE;
1419     return 1;
1420 }
1421
1422 /*
1423  * Do the actual work of picking otmp from the floor or monster's interior
1424  * and putting it in the hero's inventory.  Take care of billing.  Return a
1425  * pointer to the object where otmp ends up.  This may be different
1426  * from otmp because of merging.
1427  */
1428 struct obj *
1429 pick_obj(otmp)
1430 struct obj *otmp;
1431 {
1432     obj_extract_self(otmp);
1433     if (!u.uswallow && otmp != uball && costly_spot(otmp->ox, otmp->oy)) {
1434         char saveushops[5], fakeshop[2];
1435
1436         /* addtobill cares about your location rather than the object's;
1437            usually they'll be the same, but not when using telekinesis
1438            (if ever implemented) or a grappling hook */
1439         Strcpy(saveushops, u.ushops);
1440         fakeshop[0] = *in_rooms(otmp->ox, otmp->oy, SHOPBASE);
1441         fakeshop[1] = '\0';
1442         Strcpy(u.ushops, fakeshop);
1443         /* sets obj->unpaid if necessary */
1444         addtobill(otmp, TRUE, FALSE, FALSE);
1445         Strcpy(u.ushops, saveushops);
1446         /* if you're outside the shop, make shk notice */
1447         if (!index(u.ushops, *fakeshop))
1448             remote_burglary(otmp->ox, otmp->oy);
1449     }
1450     newsym(otmp->ox, otmp->oy);
1451     return addinv(otmp); /* might merge it with other objects */
1452 }
1453
1454 /*
1455  * prints a message if encumbrance changed since the last check and
1456  * returns the new encumbrance value (from near_capacity()).
1457  */
1458 int
1459 encumber_msg()
1460 {
1461     static int oldcap = UNENCUMBERED;
1462     int newcap = near_capacity();
1463
1464     if (oldcap < newcap) {
1465         switch (newcap) {
1466         case 1:
1467             Your("movements are slowed slightly because of your load.");
1468             break;
1469         case 2:
1470             You("rebalance your load.  Movement is difficult.");
1471             break;
1472         case 3:
1473             You("%s under your heavy load.  Movement is very hard.",
1474                 stagger(youmonst.data, "stagger"));
1475             break;
1476         default:
1477             You("%s move a handspan with this load!",
1478                 newcap == 4 ? "can barely" : "can't even");
1479             break;
1480         }
1481         context.botl = 1;
1482     } else if (oldcap > newcap) {
1483         switch (newcap) {
1484         case 0:
1485             Your("movements are now unencumbered.");
1486             break;
1487         case 1:
1488             Your("movements are only slowed slightly by your load.");
1489             break;
1490         case 2:
1491             You("rebalance your load.  Movement is still difficult.");
1492             break;
1493         case 3:
1494             You("%s under your load.  Movement is still very hard.",
1495                 stagger(youmonst.data, "stagger"));
1496             break;
1497         }
1498         context.botl = 1;
1499     }
1500
1501     oldcap = newcap;
1502     return newcap;
1503 }
1504
1505 /* Is there a container at x,y. Optional: return count of containers at x,y */
1506 STATIC_OVL int
1507 container_at(x, y, countem)
1508 int x, y;
1509 boolean countem;
1510 {
1511     struct obj *cobj, *nobj;
1512     int container_count = 0;
1513
1514     for (cobj = level.objects[x][y]; cobj; cobj = nobj) {
1515         nobj = cobj->nexthere;
1516         if (Is_container(cobj)) {
1517             container_count++;
1518             if (!countem)
1519                 break;
1520         }
1521     }
1522     return container_count;
1523 }
1524
1525 STATIC_OVL boolean
1526 able_to_loot(x, y, looting)
1527 int x, y;
1528 boolean looting; /* loot vs tip */
1529 {
1530     const char *verb = looting ? "loot" : "tip";
1531
1532     if (!can_reach_floor(TRUE)) {
1533         if (u.usteed && P_SKILL(P_RIDING) < P_BASIC)
1534             rider_cant_reach(); /* not skilled enough to reach */
1535         else
1536             cant_reach_floor(x, y, FALSE, TRUE);
1537         return FALSE;
1538     } else if ((is_pool(x, y) && (looting || !Underwater)) || is_lava(x, y)) {
1539         /* at present, can't loot in water even when Underwater;
1540            can tip underwater, but not when over--or stuck in--lava */
1541         You("cannot %s things that are deep in the %s.", verb,
1542             is_lava(x, y) ? "lava" : "water");
1543         return FALSE;
1544     } else if (nolimbs(youmonst.data)) {
1545         pline("Without limbs, you cannot %s anything.", verb);
1546         return FALSE;
1547     } else if (looting && !freehand()) {
1548         pline("Without a free %s, you cannot loot anything.",
1549               body_part(HAND));
1550         return FALSE;
1551     }
1552     return TRUE;
1553 }
1554
1555 STATIC_OVL boolean
1556 mon_beside(x, y)
1557 int x, y;
1558 {
1559     int i, j, nx, ny;
1560     for (i = -1; i <= 1; i++)
1561         for (j = -1; j <= 1; j++) {
1562             nx = x + i;
1563             ny = y + j;
1564             if (isok(nx, ny) && MON_AT(nx, ny))
1565                 return TRUE;
1566         }
1567     return FALSE;
1568 }
1569
1570 int
1571 do_loot_cont(cobjp)
1572 struct obj **cobjp;
1573 {
1574     struct obj *cobj = *cobjp;
1575     if (!cobj)
1576         return 0;
1577     if (cobj->olocked) {
1578         pline("%s locked.",
1579               cobj->lknown ? "It is" : "Hmmm, it turns out to be");
1580         cobj->lknown = 1;
1581         return 0;
1582     }
1583     cobj->lknown = 1;
1584
1585     if (cobj->otyp == BAG_OF_TRICKS) {
1586         int tmp;
1587         You("carefully open the bag...");
1588         pline("It develops a huge set of teeth and bites you!");
1589         tmp = rnd(10);
1590         losehp(Maybe_Half_Phys(tmp), "carnivorous bag", KILLED_BY_AN);
1591         makeknown(BAG_OF_TRICKS);
1592         return 1;
1593     }
1594
1595     You("%sopen %s...", (!cobj->cknown || !cobj->lknown) ? "carefully " : "",
1596         the(xname(cobj)));
1597     return use_container(cobjp, 0);
1598 }
1599
1600 /* loot a container on the floor or loot saddle from mon. */
1601 int
1602 doloot()
1603 {
1604     struct obj *cobj, *nobj;
1605     register int c = -1;
1606     int timepassed = 0;
1607     coord cc;
1608     boolean underfoot = TRUE;
1609     const char *dont_find_anything = "don't find anything";
1610     struct monst *mtmp;
1611     char qbuf[BUFSZ];
1612     int prev_inquiry = 0;
1613     boolean prev_loot = FALSE;
1614     int num_conts;
1615
1616     if (check_capacity((char *) 0)) {
1617         /* "Can't do that while carrying so much stuff." */
1618         return 0;
1619     }
1620     if (nohands(youmonst.data)) {
1621         You("have no hands!"); /* not `body_part(HAND)' */
1622         return 0;
1623     }
1624     if (Confusion) {
1625         if (rn2(6) && reverse_loot())
1626             return 1;
1627         if (rn2(2)) {
1628             pline("Being confused, you find nothing to loot.");
1629             return 1; /* costs a turn */
1630         }             /* else fallthrough to normal looting */
1631     }
1632     cc.x = u.ux;
1633     cc.y = u.uy;
1634
1635 lootcont:
1636
1637     if ((num_conts = container_at(cc.x, cc.y, TRUE)) > 0) {
1638         boolean anyfound = FALSE;
1639
1640         if (!able_to_loot(cc.x, cc.y, TRUE))
1641             return 0;
1642
1643         if (num_conts > 1) {
1644             /* use a menu to loot many containers */
1645             int n, i;
1646             winid win;
1647             anything any;
1648             menu_item *pick_list = NULL;
1649
1650             any.a_void = 0;
1651             win = create_nhwindow(NHW_MENU);
1652             start_menu(win);
1653
1654             for (cobj = level.objects[cc.x][cc.y]; cobj;
1655                  cobj = cobj->nexthere)
1656                 if (Is_container(cobj)) {
1657                     any.a_obj = cobj;
1658                     add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE,
1659                              doname(cobj), MENU_UNSELECTED);
1660                 }
1661             end_menu(win, "Loot which containers?");
1662             n = select_menu(win, PICK_ANY, &pick_list);
1663             destroy_nhwindow(win);
1664
1665             if (n > 0) {
1666                 for (i = 0; i < n; i++) {
1667                     timepassed |= do_loot_cont(&pick_list[i].item.a_obj);
1668                     if (multi < 0 || !pick_list[i].item.a_obj) {
1669                         free((genericptr_t) pick_list);
1670                         return 1;
1671                     }
1672                 }
1673             }
1674             if (pick_list)
1675                 free((genericptr_t) pick_list);
1676             if (n != 0)
1677                 c = 'y';
1678         } else {
1679             for (cobj = level.objects[cc.x][cc.y]; cobj; cobj = nobj) {
1680                 nobj = cobj->nexthere;
1681
1682                 if (Is_container(cobj)) {
1683                     c = ynq(safe_qbuf(qbuf, "There is ", " here, loot it?",
1684                                       cobj, doname, ansimpleoname,
1685                                       "a container"));
1686                     if (c == 'q')
1687                         return timepassed;
1688                     if (c == 'n')
1689                         continue;
1690                     anyfound = TRUE;
1691
1692                     timepassed |= do_loot_cont(&cobj);
1693                     /* might have triggered chest trap or magic bag explosion
1694                      */
1695                     if (multi < 0 || !cobj)
1696                         return 1;
1697                 }
1698             }
1699             if (anyfound)
1700                 c = 'y';
1701         }
1702     } else if (IS_GRAVE(levl[cc.x][cc.y].typ)) {
1703         You("need to dig up the grave to effectively loot it...");
1704     }
1705     /*
1706      * 3.3.1 introduced directional looting for some things.
1707      */
1708     if (c != 'y' && mon_beside(u.ux, u.uy)) {
1709         if (!get_adjacent_loc("Loot in what direction?",
1710                               "Invalid loot location", u.ux, u.uy, &cc))
1711             return 0;
1712         if (cc.x == u.ux && cc.y == u.uy) {
1713             underfoot = TRUE;
1714             if (container_at(cc.x, cc.y, FALSE))
1715                 goto lootcont;
1716         } else
1717             underfoot = FALSE;
1718         if (u.dz < 0) {
1719             You("%s to loot on the %s.", dont_find_anything,
1720                 ceiling(cc.x, cc.y));
1721             timepassed = 1;
1722             return timepassed;
1723         }
1724         mtmp = m_at(cc.x, cc.y);
1725         if (mtmp)
1726             timepassed = loot_mon(mtmp, &prev_inquiry, &prev_loot);
1727         /* always use a turn when choosing a direction is impaired,
1728            even if you've successfully targetted a saddled creature
1729            and then answered "no" to the "remove its saddle?" prompt */
1730         if (Confusion || Stunned)
1731             timepassed = 1;
1732
1733         /* Preserve pre-3.3.1 behaviour for containers.
1734          * Adjust this if-block to allow container looting
1735          * from one square away to change that in the future.
1736          */
1737         if (!underfoot) {
1738             if (container_at(cc.x, cc.y, FALSE)) {
1739                 if (mtmp) {
1740                     You_cant("loot anything %sthere with %s in the way.",
1741                              prev_inquiry ? "else " : "", mon_nam(mtmp));
1742                     return timepassed;
1743                 } else {
1744                     You("have to be at a container to loot it.");
1745                 }
1746             } else {
1747                 You("%s %sthere to loot.", dont_find_anything,
1748                     (prev_inquiry || prev_loot) ? "else " : "");
1749                 return timepassed;
1750             }
1751         }
1752     } else if (c != 'y' && c != 'n') {
1753         You("%s %s to loot.", dont_find_anything,
1754             underfoot ? "here" : "there");
1755     }
1756     return timepassed;
1757 }
1758
1759 /* called when attempting to #loot while confused */
1760 STATIC_OVL boolean
1761 reverse_loot()
1762 {
1763     struct obj *goldob = 0, *coffers, *otmp, boxdummy;
1764     struct monst *mon;
1765     long contribution;
1766     int n, x = u.ux, y = u.uy;
1767
1768     if (!rn2(3)) {
1769         /* n objects: 1/(n+1) chance per object plus 1/(n+1) to fall off end
1770          */
1771         for (n = inv_cnt(TRUE), otmp = invent; otmp; --n, otmp = otmp->nobj)
1772             if (!rn2(n + 1)) {
1773                 prinv("You find old loot:", otmp, 0L);
1774                 return TRUE;
1775             }
1776         return FALSE;
1777     }
1778
1779     /* find a money object to mess with */
1780     for (goldob = invent; goldob; goldob = goldob->nobj)
1781         if (goldob->oclass == COIN_CLASS) {
1782             contribution = ((long) rnd(5) * goldob->quan + 4L) / 5L;
1783             if (contribution < goldob->quan)
1784                 goldob = splitobj(goldob, contribution);
1785             break;
1786         }
1787     if (!goldob)
1788         return FALSE;
1789
1790     if (!IS_THRONE(levl[x][y].typ)) {
1791         dropx(goldob);
1792         /* the dropped gold might have fallen to lower level */
1793         if (g_at(x, y))
1794             pline("Ok, now there is loot here.");
1795     } else {
1796         /* find original coffers chest if present, otherwise use nearest one
1797          */
1798         otmp = 0;
1799         for (coffers = fobj; coffers; coffers = coffers->nobj)
1800             if (coffers->otyp == CHEST) {
1801                 if (coffers->spe == 2)
1802                     break; /* a throne room chest */
1803                 if (!otmp
1804                     || distu(coffers->ox, coffers->oy)
1805                            < distu(otmp->ox, otmp->oy))
1806                     otmp = coffers; /* remember closest ordinary chest */
1807             }
1808         if (!coffers)
1809             coffers = otmp;
1810
1811         if (coffers) {
1812             verbalize("Thank you for your contribution to reduce the debt.");
1813             freeinv(goldob);
1814             (void) add_to_container(coffers, goldob);
1815             coffers->owt = weight(coffers);
1816             coffers->cknown = 0;
1817             if (!coffers->olocked) {
1818                 boxdummy = zeroobj, boxdummy.otyp = SPE_WIZARD_LOCK;
1819                 (void) boxlock(coffers, &boxdummy);
1820             }
1821         } else if (levl[x][y].looted != T_LOOTED &&
1822                    (mon = makemon(courtmon(), x, y, NO_MM_FLAGS)) != 0) {
1823             freeinv(goldob);
1824             add_to_minv(mon, goldob);
1825             pline("The exchequer accepts your contribution.");
1826             if (!rn2(10))
1827                 levl[x][y].looted = T_LOOTED;
1828         } else {
1829             You("drop %s.", doname(goldob));
1830             dropx(goldob);
1831         }
1832     }
1833     return TRUE;
1834 }
1835
1836 /* loot_mon() returns amount of time passed.
1837  */
1838 int
1839 loot_mon(mtmp, passed_info, prev_loot)
1840 struct monst *mtmp;
1841 int *passed_info;
1842 boolean *prev_loot;
1843 {
1844     int c = -1;
1845     int timepassed = 0;
1846     struct obj *otmp;
1847     char qbuf[QBUFSZ];
1848
1849     /* 3.3.1 introduced the ability to remove saddle from a steed */
1850     /*  *passed_info is set to TRUE if a loot query was given. */
1851     /*  *prev_loot is set to TRUE if something was actually acquired in here.
1852      */
1853     if (mtmp && mtmp != u.usteed && (otmp = which_armor(mtmp, W_SADDLE))) {
1854         long unwornmask;
1855         if (passed_info)
1856             *passed_info = 1;
1857         Sprintf(
1858             qbuf, "Do you want to remove the saddle from %s?",
1859             x_monnam(mtmp, ARTICLE_THE, (char *) 0, SUPPRESS_SADDLE, FALSE));
1860         if ((c = yn_function(qbuf, ynqchars, 'n')) == 'y') {
1861             if (nolimbs(youmonst.data)) {
1862                 You_cant("do that without limbs."); /* not body_part(HAND) */
1863                 return 0;
1864             }
1865             if (otmp->cursed) {
1866                 You("can't.  The saddle seems to be stuck to %s.",
1867                     x_monnam(mtmp, ARTICLE_THE, (char *) 0, SUPPRESS_SADDLE,
1868                              FALSE));
1869                 /* the attempt costs you time */
1870                 return 1;
1871             }
1872             obj_extract_self(otmp);
1873             if ((unwornmask = otmp->owornmask) != 0L) {
1874                 mtmp->misc_worn_check &= ~unwornmask;
1875                 otmp->owornmask = 0L;
1876                 update_mon_intrinsics(mtmp, otmp, FALSE, FALSE);
1877             }
1878             otmp = hold_another_object(otmp, "You drop %s!", doname(otmp),
1879                                        (const char *) 0);
1880             timepassed = rnd(3);
1881             if (prev_loot)
1882                 *prev_loot = TRUE;
1883         } else if (c == 'q') {
1884             return 0;
1885         }
1886     }
1887     /* 3.4.0 introduced the ability to pick things up from within swallower's
1888      * stomach */
1889     if (u.uswallow) {
1890         int count = passed_info ? *passed_info : 0;
1891         timepassed = pickup(count);
1892     }
1893     return timepassed;
1894 }
1895
1896 /*
1897  * Decide whether an object being placed into a magic bag will cause
1898  * it to explode.  If the object is a bag itself, check recursively.
1899  */
1900 STATIC_OVL boolean
1901 mbag_explodes(obj, depthin)
1902 struct obj *obj;
1903 int depthin;
1904 {
1905     /* these won't cause an explosion when they're empty */
1906     if ((obj->otyp == WAN_CANCELLATION || obj->otyp == BAG_OF_TRICKS)
1907         && obj->spe <= 0)
1908         return FALSE;
1909
1910     /* odds: 1/1, 2/2, 3/4, 4/8, 5/16, 6/32, 7/64, 8/128, 9/128, 10/128,... */
1911     if ((Is_mbag(obj) || obj->otyp == WAN_CANCELLATION)
1912         && (rn2(1 << (depthin > 7 ? 7 : depthin)) <= depthin))
1913         return TRUE;
1914     else if (Has_contents(obj)) {
1915         struct obj *otmp;
1916
1917         for (otmp = obj->cobj; otmp; otmp = otmp->nobj)
1918             if (mbag_explodes(otmp, depthin + 1))
1919                 return TRUE;
1920     }
1921     return FALSE;
1922 }
1923
1924 /* Returns: -1 to stop, 1 item was inserted, 0 item was not inserted. */
1925 STATIC_PTR int
1926 in_container(obj)
1927 register struct obj *obj;
1928 {
1929     boolean floor_container = !carried(current_container);
1930     boolean was_unpaid = FALSE;
1931     char buf[BUFSZ];
1932
1933     if (!current_container) {
1934         impossible("<in> no current_container?");
1935         return 0;
1936     } else if (obj == uball || obj == uchain) {
1937         You("must be kidding.");
1938         return 0;
1939     } else if (obj == current_container) {
1940         pline("That would be an interesting topological exercise.");
1941         return 0;
1942     } else if (obj->owornmask & (W_ARMOR | W_ACCESSORY)) {
1943         Norep("You cannot %s %s you are wearing.",
1944               Icebox ? "refrigerate" : "stash", something);
1945         return 0;
1946     } else if ((obj->otyp == LOADSTONE) && obj->cursed) {
1947         obj->bknown = 1;
1948         pline_The("stone%s won't leave your person.", plur(obj->quan));
1949         return 0;
1950     } else if (obj->otyp == AMULET_OF_YENDOR
1951                || obj->otyp == CANDELABRUM_OF_INVOCATION
1952                || obj->otyp == BELL_OF_OPENING
1953                || obj->otyp == SPE_BOOK_OF_THE_DEAD) {
1954         /* Prohibit Amulets in containers; if you allow it, monsters can't
1955          * steal them.  It also becomes a pain to check to see if someone
1956          * has the Amulet.  Ditto for the Candelabrum, the Bell and the Book.
1957          */
1958         pline("%s cannot be confined in such trappings.", The(xname(obj)));
1959         return 0;
1960     } else if (obj->otyp == LEASH && obj->leashmon != 0) {
1961         pline("%s attached to your pet.", Tobjnam(obj, "are"));
1962         return 0;
1963     } else if (obj == uwep) {
1964         if (welded(obj)) {
1965             weldmsg(obj);
1966             return 0;
1967         }
1968         setuwep((struct obj *) 0);
1969         if (uwep)
1970             return 0; /* unwielded, died, rewielded */
1971     } else if (obj == uswapwep) {
1972         setuswapwep((struct obj *) 0);
1973         if (uswapwep)
1974             return 0; /* unwielded, died, rewielded */
1975     } else if (obj == uquiver) {
1976         setuqwep((struct obj *) 0);
1977         if (uquiver)
1978             return 0; /* unwielded, died, rewielded */
1979     }
1980
1981     if (fatal_corpse_mistake(obj, FALSE))
1982         return -1;
1983
1984     /* boxes, boulders, and big statues can't fit into any container */
1985     if (obj->otyp == ICE_BOX || Is_box(obj) || obj->otyp == BOULDER
1986         || (obj->otyp == STATUE && bigmonst(&mons[obj->corpsenm]))) {
1987         /*
1988          *  xname() uses a static result array.  Save obj's name
1989          *  before current_container's name is computed.  Don't
1990          *  use the result of strcpy() within You() --- the order
1991          *  of evaluation of the parameters is undefined.
1992          */
1993         Strcpy(buf, the(xname(obj)));
1994         You("cannot fit %s into %s.", buf, the(xname(current_container)));
1995         return 0;
1996     }
1997
1998     freeinv(obj);
1999
2000     if (obj_is_burning(obj)) /* this used to be part of freeinv() */
2001         (void) snuff_lit(obj);
2002
2003     if (floor_container && costly_spot(u.ux, u.uy)) {
2004         if (current_container->no_charge && !obj->unpaid) {
2005             /* don't sell when putting the item into your own container */
2006             obj->no_charge = 1;
2007         } else if (obj->oclass != COIN_CLASS) {
2008             /* sellobj() will take an unpaid item off the shop bill
2009              * note: coins are handled later */
2010             was_unpaid = obj->unpaid ? TRUE : FALSE;
2011             sellobj_state(SELL_DELIBERATE);
2012             sellobj(obj, u.ux, u.uy);
2013             sellobj_state(SELL_NORMAL);
2014         }
2015     }
2016     if (Icebox && !age_is_relative(obj)) {
2017         obj->age = monstermoves - obj->age; /* actual age */
2018         /* stop any corpse timeouts when frozen */
2019         if (obj->otyp == CORPSE && obj->timed) {
2020             long rot_alarm = stop_timer(ROT_CORPSE, obj_to_any(obj));
2021             (void) stop_timer(REVIVE_MON, obj_to_any(obj));
2022             /* mark a non-reviving corpse as such */
2023             if (rot_alarm)
2024                 obj->norevive = 1;
2025         }
2026     } else if (Is_mbag(current_container) && mbag_explodes(obj, 0)) {
2027         /* explicitly mention what item is triggering the explosion */
2028         pline("As you put %s inside, you are blasted by a magical explosion!",
2029               doname(obj));
2030         /* did not actually insert obj yet */
2031         if (was_unpaid)
2032             addtobill(obj, FALSE, FALSE, TRUE);
2033         obfree(obj, (struct obj *) 0);
2034         delete_contents(current_container);
2035         if (!floor_container)
2036             useup(current_container);
2037         else if (obj_here(current_container, u.ux, u.uy))
2038             useupf(current_container, current_container->quan);
2039         else
2040             panic("in_container:  bag not found.");
2041
2042         losehp(d(6, 6), "magical explosion", KILLED_BY_AN);
2043         current_container = 0; /* baggone = TRUE; */
2044     }
2045
2046     if (current_container) {
2047         Strcpy(buf, the(xname(current_container)));
2048         You("put %s into %s.", doname(obj), buf);
2049
2050         /* gold in container always needs to be added to credit */
2051         if (floor_container && obj->oclass == COIN_CLASS)
2052             sellobj(obj, current_container->ox, current_container->oy);
2053         (void) add_to_container(current_container, obj);
2054         current_container->owt = weight(current_container);
2055     }
2056     /* gold needs this, and freeinv() many lines above may cause
2057      * the encumbrance to disappear from the status, so just always
2058      * update status immediately.
2059      */
2060     bot();
2061
2062     return (current_container ? 1 : -1);
2063 }
2064
2065 int
2066 ck_bag(obj)
2067 struct obj *obj;
2068 {
2069     return current_container && obj != current_container;
2070 }
2071
2072 /* Returns: -1 to stop, 1 item was removed, 0 item was not removed. */
2073 STATIC_PTR int
2074 out_container(obj)
2075 register struct obj *obj;
2076 {
2077     register struct obj *otmp;
2078     boolean is_gold = (obj->oclass == COIN_CLASS);
2079     int res, loadlev;
2080     long count;
2081
2082     if (!current_container) {
2083         impossible("<out> no current_container?");
2084         return -1;
2085     } else if (is_gold) {
2086         obj->owt = weight(obj);
2087     }
2088
2089     if (obj->oartifact && !touch_artifact(obj, &youmonst))
2090         return 0;
2091
2092     if (fatal_corpse_mistake(obj, FALSE))
2093         return -1;
2094
2095     count = obj->quan;
2096     if ((res = lift_object(obj, current_container, &count, FALSE)) <= 0)
2097         return res;
2098
2099     if (obj->quan != count && obj->otyp != LOADSTONE)
2100         obj = splitobj(obj, count);
2101
2102     /* Remove the object from the list. */
2103     obj_extract_self(obj);
2104     current_container->owt = weight(current_container);
2105
2106     if (Icebox && !age_is_relative(obj)) {
2107         obj->age = monstermoves - obj->age; /* actual age */
2108         if (obj->otyp == CORPSE)
2109             start_corpse_timeout(obj);
2110     }
2111     /* simulated point of time */
2112
2113     if (!obj->unpaid && !carried(current_container)
2114         && costly_spot(current_container->ox, current_container->oy)) {
2115         obj->ox = current_container->ox;
2116         obj->oy = current_container->oy;
2117         addtobill(obj, FALSE, FALSE, FALSE);
2118     }
2119     if (is_pick(obj))
2120         pick_pick(obj); /* shopkeeper feedback */
2121
2122     otmp = addinv(obj);
2123     loadlev = near_capacity();
2124     prinv(loadlev
2125               ? (loadlev < MOD_ENCUMBER ? "You have a little trouble removing"
2126                                         : "You have much trouble removing")
2127               : (char *) 0,
2128           otmp, count);
2129
2130     if (is_gold) {
2131         bot(); /* update character's gold piece count immediately */
2132     }
2133     return 1;
2134 }
2135
2136 /* an object inside a cursed bag of holding is being destroyed */
2137 STATIC_OVL long
2138 mbag_item_gone(held, item)
2139 int held;
2140 struct obj *item;
2141 {
2142     struct monst *shkp;
2143     long loss = 0L;
2144
2145     if (item->dknown)
2146         pline("%s %s vanished!", Doname2(item), otense(item, "have"));
2147     else
2148         You("%s %s disappear!", Blind ? "notice" : "see", doname(item));
2149
2150     if (*u.ushops && (shkp = shop_keeper(*u.ushops)) != 0) {
2151         if (held ? (boolean) item->unpaid : costly_spot(u.ux, u.uy))
2152             loss = stolen_value(item, u.ux, u.uy, (boolean) shkp->mpeaceful,
2153                                 TRUE);
2154     }
2155     obfree(item, (struct obj *) 0);
2156     return loss;
2157 }
2158
2159 STATIC_OVL void
2160 observe_quantum_cat(box)
2161 struct obj *box;
2162 {
2163     static NEARDATA const char sc[] = "Schroedinger's Cat";
2164     struct obj *deadcat;
2165     struct monst *livecat;
2166     xchar ox, oy;
2167
2168     box->spe = 0; /* box->owt will be updated below */
2169     if (get_obj_location(box, &ox, &oy, 0))
2170         box->ox = ox, box->oy = oy; /* in case it's being carried */
2171
2172     /* this isn't really right, since any form of observation
2173        (telepathic or monster/object/food detection) ought to
2174        force the determination of alive vs dead state; but basing
2175        it just on opening the box is much simpler to cope with */
2176     livecat = rn2(2)
2177                   ? makemon(&mons[PM_HOUSECAT], box->ox, box->oy, NO_MINVENT)
2178                   : 0;
2179     if (livecat) {
2180         livecat->mpeaceful = 1;
2181         set_malign(livecat);
2182         if (!canspotmon(livecat))
2183             You("think %s brushed your %s.", something, body_part(FOOT));
2184         else
2185             pline("%s inside the box is still alive!", Monnam(livecat));
2186         (void) christen_monst(livecat, sc);
2187     } else {
2188         deadcat =
2189             mk_named_object(CORPSE, &mons[PM_HOUSECAT], box->ox, box->oy, sc);
2190         if (deadcat) {
2191             obj_extract_self(deadcat);
2192             (void) add_to_container(box, deadcat);
2193         }
2194         pline_The("%s inside the box is dead!",
2195                   Hallucination ? rndmonnam(NULL) : "housecat");
2196     }
2197     box->owt = weight(box);
2198     return;
2199 }
2200
2201 #undef Icebox
2202
2203 /* used by askchain() to check for magic bag explosion */
2204 boolean
2205 container_gone(fn)
2206 int FDECL((*fn), (OBJ_P));
2207 {
2208     /* result is only meaningful while use_container() is executing */
2209     return ((fn == in_container || fn == out_container)
2210             && !current_container);
2211 }
2212
2213 STATIC_OVL void
2214 explain_container_prompt()
2215 {
2216     static const char *const explaintext[] = {
2217         "Container actions:", "", " : -- Look: examine contents",
2218         " o -- Out: take things out", " i -- In: put things in",
2219         " b -- Both: first take things out, then put things in",
2220         " r -- Reversed: put things in, then take things out",
2221         " s -- Stash: put one item in", " q -- Quit: do nothing",
2222         " ? -- Help: display this text.", "", 0
2223     };
2224     const char *const *txtpp;
2225     winid win;
2226
2227     /* "Do what with <container>? [:oibrsq or ?] (q)" */
2228     if ((win = create_nhwindow(NHW_TEXT)) != WIN_ERR) {
2229         for (txtpp = explaintext; *txtpp; ++txtpp)
2230             putstr(win, 0, *txtpp);
2231         display_nhwindow(win, FALSE);
2232         destroy_nhwindow(win);
2233     }
2234 }
2235
2236 boolean
2237 u_handsy()
2238 {
2239     if (nohands(youmonst.data)) {
2240         You("have no hands!"); /* not `body_part(HAND)' */
2241         return FALSE;
2242     } else if (!freehand()) {
2243         You("have no free %s.", body_part(HAND));
2244         return FALSE;
2245     }
2246     return TRUE;
2247 }
2248
2249 static const char stashable[] = { ALLOW_COUNT, COIN_CLASS, ALL_CLASSES, 0 };
2250
2251 int
2252 use_container(objp, held)
2253 struct obj **objp;
2254 int held;
2255 {
2256     struct obj *curr, *otmp, *obj = *objp;
2257     boolean quantum_cat, cursed_mbag, loot_out, loot_in, loot_in_first,
2258         stash_one, inokay, outokay, outmaybe;
2259     char c, emptymsg[BUFSZ], qbuf[QBUFSZ], pbuf[QBUFSZ], xbuf[QBUFSZ];
2260     int used = 0;
2261
2262     emptymsg[0] = '\0';
2263
2264     if (!u_handsy())
2265         return 0;
2266
2267     if (obj->olocked) {
2268         pline("%s locked.", Tobjnam(obj, "are"));
2269         if (held)
2270             You("must put it down to unlock.");
2271         obj->lknown = 1;
2272         return 0;
2273     } else if (obj->otrapped) {
2274         if (held)
2275             You("open %s...", the(xname(obj)));
2276         obj->lknown = 1;
2277         (void) chest_trap(obj, HAND, FALSE);
2278         /* even if the trap fails, you've used up this turn */
2279         if (multi >= 0) { /* in case we didn't become paralyzed */
2280             nomul(-1);
2281             multi_reason = "opening a container";
2282             nomovemsg = "";
2283         }
2284         return 1;
2285     }
2286     obj->lknown = 1;
2287
2288     current_container = obj; /* for use by in/out_container */
2289     /* from here on out, all early returns go through containerdone */
2290
2291     /* check for Schroedinger's Cat */
2292     quantum_cat = SchroedingersBox(current_container);
2293     if (quantum_cat) {
2294         observe_quantum_cat(current_container);
2295         used = 1;
2296     }
2297     /* sometimes toss objects if a cursed magic bag */
2298     cursed_mbag = (Is_mbag(current_container) && current_container->cursed
2299                    && Has_contents(current_container));
2300     if (cursed_mbag) {
2301         long loss = 0L;
2302
2303         for (curr = current_container->cobj; curr; curr = otmp) {
2304             otmp = curr->nobj;
2305             if (!rn2(13)) {
2306                 obj_extract_self(curr);
2307                 loss += mbag_item_gone(held, curr);
2308                 used = 1;
2309             }
2310         }
2311         if (loss)
2312             You("owe %ld %s for lost merchandise.", loss, currency(loss));
2313         current_container->owt = weight(current_container);
2314     }
2315     inokay = (invent != 0
2316               && !(invent == current_container && !current_container->nobj));
2317     outokay = Has_contents(current_container);
2318     if (!outokay) /* preformat the empty-container message */
2319         Sprintf(emptymsg, "%s is %sempty.", Ysimple_name2(current_container),
2320                 (quantum_cat || cursed_mbag) ? "now " : "");
2321
2322     /*
2323      * What-to-do prompt's list of possible actions:
2324      * always include the look-inside choice (':');
2325      * include the take-out choice ('o') if container
2326      * has anything in it or if player doesn't yet know
2327      * that it's empty (latter can change on subsequent
2328      * iterations if player picks ':' response);
2329      * include the put-in choices ('i','s') if hero
2330      * carries any inventory (including gold);
2331      * include do-both when 'o' is available, even if
2332      * inventory is empty--taking out could alter that;
2333      * include do-both-reversed when 'i' is available,
2334      * even if container is empty--for similar reason;
2335      * always include the quit choice ('q').
2336      * include the help choice (" or ?") if `cmdassist'
2337      * run-time option is set;
2338      * (Player can pick any of (o,i,b,r,s,?) even when
2339      * they're not listed among the available actions.)
2340      *
2341      * Do what with <the/your/Shk's container>? [:oibrsq or ?] (q)
2342      * or
2343      * <The/Your/Shk's container> is empty.  Do what with it? [:irsq or ?]
2344      */
2345     for (;;) { /* repeats if '?' or ":' gets chosen */
2346         outmaybe = (outokay || !current_container->cknown);
2347         if (!outmaybe)
2348             (void) safe_qbuf(qbuf, (char *) 0, " is empty.  Do what with it?",
2349                              current_container, Yname2, Ysimple_name2,
2350                              "This");
2351         else
2352             (void) safe_qbuf(qbuf, "Do what with ", "?", current_container,
2353                              yname, ysimple_name, "it");
2354         /* ask player about what to do with this container */
2355         if (flags.menu_style == MENU_FULL) {
2356             if (!inokay && !outmaybe) {
2357                 /* nothing to take out, nothing to put in;
2358                    trying to do both will yield proper feedback */
2359                 c = 'b';
2360             } else {
2361                 c = in_or_out_menu(qbuf, current_container, outmaybe, inokay,
2362                                    (used != 0));
2363             }
2364         } else {               /* TRADITIONAL, COMBINATION, or PARTIAL */
2365             xbuf[0] = '\0';    /* list of extra acceptable responses */
2366             Strcpy(pbuf, ":"); /* look inside */
2367             Strcat(outmaybe ? pbuf : xbuf, "o"); /* take out */
2368             Strcat(inokay ? pbuf : xbuf, "i");   /* put in */
2369             Strcat(outmaybe ? pbuf : xbuf, "b"); /* both */
2370             Strcat(inokay ? pbuf : xbuf, "rs");  /* reversed, stash */
2371             Strcat(pbuf, "q");                   /* quit */
2372             if (iflags.cmdassist)
2373                 Strcat(pbuf, " or ?"); /* help */
2374             else
2375                 Strcat(xbuf, "?");
2376             if (*xbuf)
2377                 Strcat(strcat(pbuf, "\033"), xbuf);
2378             c = yn_function(qbuf, pbuf, 'q');
2379         } /* FULL vs other modes */
2380
2381         if (c == '?') {
2382             explain_container_prompt();
2383         } else if (c == ':') { /* note: will set obj->cknown */
2384             if (!current_container->cknown)
2385                 used = 1; /* gaining info */
2386             container_contents(current_container, FALSE, FALSE, TRUE);
2387         } else
2388             break;
2389     } /* loop until something other than '?' or ':' is picked */
2390
2391     if (c == 'q') /* [not strictly needed; falling through works] */
2392         goto containerdone;
2393     loot_out = (c == 'o' || c == 'b' || c == 'r');
2394     loot_in = (c == 'i' || c == 'b' || c == 'r');
2395     loot_in_first = (c == 'r'); /* both, reversed */
2396     stash_one = (c == 's');
2397
2398     /* out-only or out before in */
2399     if (loot_out && !loot_in_first) {
2400         if (!Has_contents(current_container)) {
2401             pline1(emptymsg); /* <whatever> is empty. */
2402             if (!current_container->cknown)
2403                 used = 1;
2404             current_container->cknown = 1;
2405         } else {
2406             add_valid_menu_class(0); /* reset */
2407             if (flags.menu_style == MENU_TRADITIONAL)
2408                 used |= traditional_loot(FALSE);
2409             else
2410                 used |= (menu_loot(0, FALSE) > 0);
2411         }
2412     }
2413
2414     if ((loot_in || stash_one)
2415         && (!invent || (invent == current_container && !invent->nobj))) {
2416         You("don't have anything%s to %s.", invent ? " else" : "",
2417             stash_one ? "stash" : "put in");
2418         loot_in = stash_one = FALSE;
2419     }
2420
2421     /*
2422      * Gone: being nice about only selecting food if we know we are
2423      * putting things in an ice chest.
2424      */
2425     if (loot_in) {
2426         add_valid_menu_class(0); /* reset */
2427         if (flags.menu_style == MENU_TRADITIONAL)
2428             used |= traditional_loot(TRUE);
2429         else
2430             used |= (menu_loot(0, TRUE) > 0);
2431     } else if (stash_one) {
2432         /* put one item into container */
2433         if ((otmp = getobj(stashable, "stash")) != 0) {
2434             if (in_container(otmp)) {
2435                 used = 1;
2436             } else {
2437                 /* couldn't put selected item into container for some
2438                    reason; might need to undo splitobj() */
2439                 for (curr = invent; curr; curr = curr->nobj)
2440                     if (curr->nobj == otmp)
2441                         break;
2442                 if (curr && curr->invlet == otmp->invlet)
2443                     (void) merged(&curr, &otmp);
2444             }
2445         }
2446     }
2447     /* putting something in might have triggered magic bag explosion */
2448     if (!current_container)
2449         loot_out = FALSE;
2450
2451     /* out after in */
2452     if (loot_out && loot_in_first) {
2453         if (!Has_contents(current_container)) {
2454             pline1(emptymsg); /* <whatever> is empty. */
2455             if (!current_container->cknown)
2456                 used = 1;
2457             current_container->cknown = 1;
2458         } else {
2459             add_valid_menu_class(0); /* reset */
2460             if (flags.menu_style == MENU_TRADITIONAL)
2461                 used |= traditional_loot(FALSE);
2462             else
2463                 used |= (menu_loot(0, FALSE) > 0);
2464         }
2465     }
2466
2467 containerdone:
2468     if (used) {
2469         /* Not completely correct; if we put something in without knowing
2470            whatever was already inside, now we suddenly do.  That can't
2471            be helped unless we want to track things item by item and then
2472            deal with containers whose contents are "partly known". */
2473         if (current_container)
2474             current_container->cknown = 1;
2475         update_inventory();
2476     }
2477
2478     *objp = current_container; /* might have become null */
2479     current_container = 0;     /* avoid hanging on to stale pointer */
2480     return used;
2481 }
2482
2483 /* loot current_container (take things out or put things in), by prompting */
2484 STATIC_OVL int
2485 traditional_loot(put_in)
2486 boolean put_in;
2487 {
2488     int FDECL((*actionfunc), (OBJ_P)), FDECL((*checkfunc), (OBJ_P));
2489     struct obj **objlist;
2490     char selection[MAXOCLASSES + 1];
2491     const char *action;
2492     boolean one_by_one, allflag;
2493     int used = 0, menu_on_request = 0;
2494
2495     if (put_in) {
2496         action = "put in";
2497         objlist = &invent;
2498         actionfunc = in_container;
2499         checkfunc = ck_bag;
2500     } else {
2501         action = "take out";
2502         objlist = &(current_container->cobj);
2503         actionfunc = out_container;
2504         checkfunc = (int FDECL((*), (OBJ_P))) 0;
2505     }
2506
2507     if (query_classes(selection, &one_by_one, &allflag, action, *objlist,
2508                       FALSE, &menu_on_request)) {
2509         if (askchain(objlist, (one_by_one ? (char *) 0 : selection), allflag,
2510                      actionfunc, checkfunc, 0, action))
2511             used = 1;
2512     } else if (menu_on_request < 0) {
2513         used = (menu_loot(menu_on_request, put_in) > 0);
2514     }
2515     return used;
2516 }
2517
2518 /* loot current_container (take things out or put things in), using a menu */
2519 STATIC_OVL int
2520 menu_loot(retry, put_in)
2521 int retry;
2522 boolean put_in;
2523 {
2524     int n, i, n_looted = 0;
2525     boolean all_categories = TRUE, loot_everything = FALSE;
2526     char buf[BUFSZ];
2527     const char *action = put_in ? "Put in" : "Take out";
2528     struct obj *otmp, *otmp2;
2529     menu_item *pick_list;
2530     int mflags, res;
2531     long count;
2532
2533     if (retry) {
2534         all_categories = (retry == -2);
2535     } else if (flags.menu_style == MENU_FULL) {
2536         all_categories = FALSE;
2537         Sprintf(buf, "%s what type of objects?", action);
2538         mflags = put_in
2539                      ? ALL_TYPES | BUC_ALLBKNOWN | BUC_UNKNOWN
2540                      : ALL_TYPES | CHOOSE_ALL | BUC_ALLBKNOWN | BUC_UNKNOWN;
2541         n = query_category(buf, put_in ? invent : current_container->cobj,
2542                            mflags, &pick_list, PICK_ANY);
2543         if (!n)
2544             return 0;
2545         for (i = 0; i < n; i++) {
2546             if (pick_list[i].item.a_int == 'A')
2547                 loot_everything = TRUE;
2548             else if (pick_list[i].item.a_int == ALL_TYPES_SELECTED)
2549                 all_categories = TRUE;
2550             else
2551                 add_valid_menu_class(pick_list[i].item.a_int);
2552         }
2553         free((genericptr_t) pick_list);
2554     }
2555
2556     if (loot_everything) {
2557         current_container->cknown = 1;
2558         for (otmp = current_container->cobj; otmp; otmp = otmp2) {
2559             otmp2 = otmp->nobj;
2560             res = out_container(otmp);
2561             if (res < 0)
2562                 break;
2563         }
2564     } else {
2565         mflags = INVORDER_SORT;
2566         if (put_in && flags.invlet_constant)
2567             mflags |= USE_INVLET;
2568         if (!put_in)
2569             current_container->cknown = 1;
2570         Sprintf(buf, "%s what?", action);
2571         n = query_objlist(buf, put_in ? invent : current_container->cobj,
2572                           mflags, &pick_list, PICK_ANY,
2573                           all_categories ? allow_all : allow_category);
2574         if (n) {
2575             n_looted = n;
2576             for (i = 0; i < n; i++) {
2577                 otmp = pick_list[i].item.a_obj;
2578                 count = pick_list[i].count;
2579                 if (count > 0 && count < otmp->quan) {
2580                     otmp = splitobj(otmp, count);
2581                     /* special split case also handled by askchain() */
2582                 }
2583                 res = put_in ? in_container(otmp) : out_container(otmp);
2584                 if (res < 0) {
2585                     if (!current_container) {
2586                         /* otmp caused current_container to explode;
2587                            both are now gone */
2588                         otmp = 0; /* and break loop */
2589                     } else if (otmp && otmp != pick_list[i].item.a_obj) {
2590                         /* split occurred, merge again */
2591                         (void) merged(&pick_list[i].item.a_obj, &otmp);
2592                     }
2593                     break;
2594                 }
2595             }
2596             free((genericptr_t) pick_list);
2597         }
2598     }
2599     return n_looted;
2600 }
2601
2602 STATIC_OVL char
2603 in_or_out_menu(prompt, obj, outokay, inokay, alreadyused)
2604 const char *prompt;
2605 struct obj *obj;
2606 boolean outokay, inokay, alreadyused;
2607 {
2608     /* underscore is not a choice; it's used to skip element [0] */
2609     static const char lootchars[] = "_:oibrsq", abc_chars[] = "_:abcdeq";
2610     winid win;
2611     anything any;
2612     menu_item *pick_list;
2613     char buf[BUFSZ];
2614     int n;
2615     const char *menuselector = flags.lootabc ? abc_chars : lootchars;
2616
2617     any = zeroany;
2618     win = create_nhwindow(NHW_MENU);
2619     start_menu(win);
2620
2621     any.a_int = 1; /* ':' */
2622     Sprintf(buf, "Look inside %s", thesimpleoname(obj));
2623     add_menu(win, NO_GLYPH, &any, menuselector[any.a_int], 0, ATR_NONE, buf,
2624              MENU_UNSELECTED);
2625     if (outokay) {
2626         any.a_int = 2; /* 'o' */
2627         Sprintf(buf, "take %s out", something);
2628         add_menu(win, NO_GLYPH, &any, menuselector[any.a_int], 0, ATR_NONE,
2629                  buf, MENU_UNSELECTED);
2630     }
2631     if (inokay) {
2632         any.a_int = 3; /* 'i' */
2633         Sprintf(buf, "put %s in", something);
2634         add_menu(win, NO_GLYPH, &any, menuselector[any.a_int], 0, ATR_NONE,
2635                  buf, MENU_UNSELECTED);
2636     }
2637     if (outokay) {
2638         any.a_int = 4; /* 'b' */
2639         Sprintf(buf, "%stake out, then put in", inokay ? "both; " : "");
2640         add_menu(win, NO_GLYPH, &any, menuselector[any.a_int], 0, ATR_NONE,
2641                  buf, MENU_UNSELECTED);
2642     }
2643     if (inokay) {
2644         any.a_int = 5; /* 'r' */
2645         Sprintf(buf, "%sput in, then take out",
2646                 outokay ? "both reversed; " : "");
2647         add_menu(win, NO_GLYPH, &any, menuselector[any.a_int], 0, ATR_NONE,
2648                  buf, MENU_UNSELECTED);
2649         any.a_int = 6; /* 's' */
2650         Sprintf(buf, "stash one item into %s", thesimpleoname(obj));
2651         add_menu(win, NO_GLYPH, &any, menuselector[any.a_int], 0, ATR_NONE,
2652                  buf, MENU_UNSELECTED);
2653     }
2654     any.a_int = 7; /* 'q' */
2655     Strcpy(buf, alreadyused ? "done" : "do nothing");
2656     add_menu(win, NO_GLYPH, &any, menuselector[any.a_int], 0, ATR_NONE, buf,
2657              MENU_SELECTED);
2658
2659     end_menu(win, prompt);
2660     n = select_menu(win, PICK_ONE, &pick_list);
2661     destroy_nhwindow(win);
2662     if (n > 0) {
2663         n = pick_list[0].item.a_int;
2664         free((genericptr_t) pick_list);
2665         return lootchars[n]; /* :,o,i,b,r,s,q */
2666     }
2667     return 'q'; /* quit */
2668 }
2669
2670 static const char tippables[] = { ALL_CLASSES, TOOL_CLASS, 0 };
2671
2672 /* #tip command -- empty container contents onto floor */
2673 int
2674 dotip()
2675 {
2676     struct obj *cobj, *nobj;
2677     coord cc;
2678     int boxes;
2679     char c, buf[BUFSZ], qbuf[BUFSZ];
2680     const char *spillage = 0;
2681
2682     /*
2683      * doesn't require free hands;
2684      * limbs are needed to tip floor containers
2685      */
2686
2687     /* at present, can only tip things at current spot, not adjacent ones */
2688     cc.x = u.ux, cc.y = u.uy;
2689
2690     /* check floor container(s) first; at most one will be accessed */
2691     if ((boxes = container_at(cc.x, cc.y, TRUE)) > 0) {
2692         Sprintf(buf, "You can't tip %s while carrying so much.",
2693                 !flags.verbose ? "a container" : (boxes > 1) ? "one" : "it");
2694         if (!check_capacity(buf) && able_to_loot(cc.x, cc.y, FALSE)) {
2695             if (boxes > 1 && (flags.menu_style != MENU_TRADITIONAL
2696                               || iflags.menu_requested)) {
2697                 /* use menu to pick a container to tip */
2698                 int n, i;
2699                 winid win;
2700                 anything any;
2701                 menu_item *pick_list = NULL;
2702                 struct obj dummyobj, *otmp;
2703
2704                 any = zeroany;
2705                 win = create_nhwindow(NHW_MENU);
2706                 start_menu(win);
2707
2708                 for (cobj = level.objects[cc.x][cc.y], i = 0; cobj;
2709                      cobj = cobj->nexthere)
2710                     if (Is_container(cobj)) {
2711                         ++i;
2712                         any.a_obj = cobj;
2713                         add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE,
2714                                  doname(cobj), MENU_UNSELECTED);
2715                     }
2716                 if (invent) {
2717                     any = zeroany;
2718                     add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE,
2719                              "", MENU_UNSELECTED);
2720                     any.a_obj = &dummyobj;
2721                     /* use 'i' for inventory unless there are so many
2722                        containers that it's already being used */
2723                     i = (i <= 'i' - 'a' && !flags.lootabc) ? 'i' : 0;
2724                     add_menu(win, NO_GLYPH, &any, i, 0, ATR_NONE,
2725                              "tip something being carried", MENU_SELECTED);
2726                 }
2727                 end_menu(win, "Tip which container?");
2728                 n = select_menu(win, PICK_ONE, &pick_list);
2729                 destroy_nhwindow(win);
2730                 /*
2731                  * Deal with quirk of preselected item in pick-one menu:
2732                  * n ==  0 => picked preselected entry, toggling it off;
2733                  * n ==  1 => accepted preselected choice via SPACE or RETURN;
2734                  * n ==  2 => picked something other than preselected entry;
2735                  * n == -1 => cancelled via ESC;
2736                  */
2737                 otmp = (n <= 0) ? (struct obj *) 0 : pick_list[0].item.a_obj;
2738                 if (n > 1 && otmp == &dummyobj)
2739                     otmp = pick_list[1].item.a_obj;
2740                 if (pick_list)
2741                     free((genericptr_t) pick_list);
2742                 if (otmp && otmp != &dummyobj) {
2743                     tipcontainer(otmp);
2744                     return 1;
2745                 }
2746                 if (n == -1)
2747                     return 0;
2748                 /* else pick-from-invent below */
2749             } else {
2750                 for (cobj = level.objects[cc.x][cc.y]; cobj; cobj = nobj) {
2751                     nobj = cobj->nexthere;
2752                     if (!Is_container(cobj))
2753                         continue;
2754                     c = ynq(safe_qbuf(qbuf, "There is ", " here, tip it?",
2755                                       cobj,
2756                                       doname, ansimpleoname, "container"));
2757                     if (c == 'q')
2758                         return 0;
2759                     if (c == 'n')
2760                         continue;
2761                     tipcontainer(cobj);
2762                     /* can only tip one container at a time */
2763                     return 1;
2764                 }
2765             }
2766         }
2767     }
2768
2769     /* either no floor container(s) or couldn't tip one or didn't tip any */
2770     cobj = getobj(tippables, "tip");
2771     if (!cobj)
2772         return 0;
2773
2774     /* normal case */
2775     if (Is_container(cobj) || cobj->otyp == HORN_OF_PLENTY) {
2776         tipcontainer(cobj);
2777         return 1;
2778     }
2779     /* assorted other cases */
2780     if (Is_candle(cobj) && cobj->lamplit) {
2781         /* note "wax" even for tallow candles to avoid giving away info */
2782         spillage = "wax";
2783     } else if ((cobj->otyp == POT_OIL && cobj->lamplit)
2784                || (cobj->otyp == OIL_LAMP && cobj->age != 0L)
2785                || (cobj->otyp == MAGIC_LAMP && cobj->spe != 0)) {
2786         spillage = "oil";
2787         /* todo: reduce potion's remaining burn timer or oil lamp's fuel */
2788     } else if (cobj->otyp == CAN_OF_GREASE && cobj->spe > 0) {
2789         /* charged consumed below */
2790         spillage = "grease";
2791     } else if (cobj->otyp == FOOD_RATION || cobj->otyp == CRAM_RATION
2792                || cobj->otyp == LEMBAS_WAFER) {
2793         spillage = "crumbs";
2794     } else if (cobj->oclass == VENOM_CLASS) {
2795         spillage = "venom";
2796     }
2797     if (spillage) {
2798         buf[0] = '\0';
2799         if (is_pool(u.ux, u.uy))
2800             Sprintf(buf, " and gradually %s", vtense(spillage, "dissipate"));
2801         else if (is_lava(u.ux, u.uy))
2802             Sprintf(buf, " and immediately %s away",
2803                     vtense(spillage, "burn"));
2804         pline("Some %s %s onto the %s%s.", spillage,
2805               vtense(spillage, "spill"), surface(u.ux, u.uy), buf);
2806         /* shop usage message comes after the spill message */
2807         if (cobj->otyp == CAN_OF_GREASE && cobj->spe > 0) {
2808             consume_obj_charge(cobj, TRUE);
2809         }
2810         /* something [useless] happened */
2811         return 1;
2812     }
2813     /* anything not covered yet */
2814     if (cobj->oclass == POTION_CLASS) /* can't pour potions... */
2815         pline_The("%s %s securely sealed.", xname(cobj), otense(cobj, "are"));
2816     else if (cobj->otyp == STATUE)
2817         pline("Nothing interesting happens.");
2818     else
2819         pline1(nothing_happens);
2820     return 0;
2821 }
2822
2823 STATIC_OVL void
2824 tipcontainer(box)
2825 struct obj *box; /* or bag */
2826 {
2827     xchar ox = u.ux, oy = u.uy; /* #tip only works at hero's location */
2828     boolean empty_it = FALSE,
2829             /* Shop handling:  can't rely on the container's own unpaid
2830                or no_charge status because contents might differ with it.
2831                A carried container's contents will be flagged as unpaid
2832                or not, as appropriate, and need no special handling here.
2833                Items owned by the hero get sold to the shop without
2834                confirmation as with other uncontrolled drops.  A floor
2835                container's contents will be marked no_charge if owned by
2836                hero, otherwise they're owned by the shop.  By passing
2837                the contents through shop billing, they end up getting
2838                treated the same as in the carried case.   We do so one
2839                item at a time instead of doing whole container at once
2840                to reduce the chance of exhausting shk's billing capacity. */
2841         maybeshopgoods = !carried(box) && costly_spot(ox, oy);
2842
2843     /* caveat: this assumes that cknown, lknown, olocked, and otrapped
2844        fields haven't been overloaded to mean something special for the
2845        non-standard "container" horn of plenty */
2846     box->lknown = 1;
2847     if (box->olocked) {
2848         pline("It's locked.");
2849     } else if (box->otrapped) {
2850         /* we're not reaching inside but we're still handling it... */
2851         (void) chest_trap(box, HAND, FALSE);
2852         /* even if the trap fails, you've used up this turn */
2853         if (multi >= 0) { /* in case we didn't become paralyzed */
2854             nomul(-1);
2855             multi_reason = "tipping a container";
2856             nomovemsg = "";
2857         }
2858     } else if (box->otyp == BAG_OF_TRICKS || box->otyp == HORN_OF_PLENTY) {
2859         boolean bag = box->otyp == BAG_OF_TRICKS;
2860         int old_spe = box->spe, seen = 0;
2861
2862         if (maybeshopgoods && !box->no_charge)
2863             addtobill(box, FALSE, FALSE, TRUE);
2864         /* apply this bag/horn until empty or monster/object creation fails
2865            (if the latter occurs, force the former...) */
2866         do {
2867             if (!(bag ? bagotricks(box, TRUE, &seen)
2868                       : hornoplenty(box, TRUE)))
2869                 break;
2870         } while (box->spe > 0);
2871
2872         if (box->spe < old_spe) {
2873             if (bag)
2874                 pline((seen == 0) ? "Nothing seems to happen."
2875                                   : (seen == 1) ? "A monster appears."
2876                                                 : "Monsters appear!");
2877             /* check_unpaid wants to see a non-zero charge count */
2878             box->spe = old_spe;
2879             check_unpaid_usage(box, TRUE);
2880             box->spe = 0; /* empty */
2881             box->cknown = 1;
2882         }
2883         if (maybeshopgoods && !box->no_charge)
2884             subfrombill(box, shop_keeper(*in_rooms(ox, oy, SHOPBASE)));
2885     } else if (SchroedingersBox(box)) {
2886         char yourbuf[BUFSZ];
2887
2888         observe_quantum_cat(box);
2889         if (!Has_contents(box)) /* evidently a live cat came out */
2890             /* container type of "large box" is inferred */
2891             pline("%sbox is now empty.", Shk_Your(yourbuf, box));
2892         else /* holds cat corpse or other random stuff */
2893             empty_it = TRUE;
2894         box->cknown = 1;
2895     } else if (!Has_contents(box)) {
2896         box->cknown = 1;
2897         pline("It's empty.");
2898     } else {
2899         empty_it = TRUE;
2900     }
2901
2902     if (empty_it) {
2903         struct obj *otmp, *nobj;
2904         boolean verbose = FALSE, highdrop = !can_reach_floor(TRUE),
2905                 altarizing = IS_ALTAR(levl[ox][oy].typ),
2906                 cursed_mbag = (Is_mbag(box) && box->cursed);
2907         int held = carried(box);
2908         long loss = 0L;
2909
2910         if (u.uswallow)
2911             highdrop = altarizing = FALSE;
2912         box->cknown = 1;
2913         pline("%s out%c",
2914               box->cobj->nobj ? "Objects spill" : "An object spills",
2915               !(highdrop || altarizing) ? ':' : '.');
2916         for (otmp = box->cobj; otmp; otmp = nobj) {
2917             nobj = otmp->nobj;
2918             obj_extract_self(otmp);
2919             if (cursed_mbag && !rn2(13)) {
2920                 loss += mbag_item_gone(held, otmp);
2921                 /* abbreviated drop format is no longer appropriate */
2922                 verbose = TRUE;
2923                 continue;
2924             }
2925
2926             if (maybeshopgoods) {
2927                 addtobill(otmp, FALSE, FALSE, TRUE);
2928                 iflags.suppress_price++; /* doname formatting */
2929             }
2930
2931             if (highdrop) {
2932                 /* might break or fall down stairs; handles altars itself */
2933                 hitfloor(otmp);
2934             } else {
2935                 if (altarizing)
2936                     doaltarobj(otmp);
2937                 else if (verbose)
2938                     pline("%s %s to the %s.", Doname2(otmp),
2939                           otense(otmp, "drop"), surface(ox, oy));
2940                 else
2941                     pline("%s%c", doname(otmp), nobj ? ',' : '.');
2942                 dropy(otmp);
2943             }
2944             if (maybeshopgoods)
2945                 iflags.suppress_price--; /* reset */
2946         }
2947         if (loss) /* magic bag lost some shop goods */
2948             You("owe %ld %s for lost merchandise.", loss, currency(loss));
2949         box->owt = weight(box); /* mbag_item_gone() doesn't update this */
2950         if (held)
2951             (void) encumber_msg();
2952     }
2953 }
2954
2955 /*pickup.c*/