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. */
5 /* JNetHack Copyright */
6 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000 */
7 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2016 */
8 /* JNetHack may be freely redistributed. See license for details. */
11 * Contains code for picking objects up, and container use.
16 #define CONTAINED_SYM '>' /* from invent.c */
18 STATIC_DCL void FDECL(simple_look, (struct obj *, BOOLEAN_P));
20 FDECL(query_classes, (char *, boolean *, boolean *, const char *,
21 struct obj *, BOOLEAN_P, int *));
22 STATIC_DCL boolean FDECL(fatal_corpse_mistake, (struct obj *, BOOLEAN_P));
23 STATIC_DCL void FDECL(check_here, (BOOLEAN_P));
24 STATIC_DCL boolean FDECL(n_or_more, (struct obj *));
25 STATIC_DCL boolean FDECL(all_but_uchain, (struct obj *));
27 STATIC_DCL boolean FDECL(allow_cat_no_uchain, (struct obj *));
29 STATIC_DCL int FDECL(autopick, (struct obj *, int, menu_item **));
30 STATIC_DCL int FDECL(count_categories, (struct obj *, int));
31 STATIC_DCL long FDECL(carry_count, (struct obj *, struct obj *, long,
32 BOOLEAN_P, int *, int *));
33 STATIC_DCL int FDECL(lift_object,
34 (struct obj *, struct obj *, long *, BOOLEAN_P));
35 STATIC_DCL boolean FDECL(mbag_explodes, (struct obj *, int));
36 STATIC_PTR int FDECL(in_container, (struct obj *));
37 STATIC_PTR int FDECL(out_container, (struct obj *));
38 STATIC_DCL long FDECL(mbag_item_gone, (int, struct obj *));
39 STATIC_DCL void FDECL(observe_quantum_cat, (struct obj *));
40 STATIC_DCL void NDECL(explain_container_prompt);
41 STATIC_DCL int FDECL(traditional_loot, (BOOLEAN_P));
42 STATIC_DCL int FDECL(menu_loot, (int, BOOLEAN_P));
43 STATIC_DCL char FDECL(in_or_out_menu, (const char *, struct obj *, BOOLEAN_P,
44 BOOLEAN_P, BOOLEAN_P));
45 STATIC_DCL int FDECL(container_at, (int, int, BOOLEAN_P));
46 STATIC_DCL boolean FDECL(able_to_loot, (int, int, BOOLEAN_P));
47 STATIC_DCL boolean NDECL(reverse_loot);
48 STATIC_DCL boolean FDECL(mon_beside, (int, int));
49 STATIC_DCL int FDECL(do_loot_cont, (struct obj **));
50 STATIC_DCL void FDECL(tipcontainer, (struct obj *));
52 /* define for query_objlist() and autopickup() */
53 #define FOLLOW(curr, flags) \
54 (((flags) &BY_NEXTHERE) ? (curr)->nexthere : (curr)->nobj)
57 * How much the weight of the given container will change when the given
58 * object is removed from it. This calculation must match the one used
59 * by weight() in mkobj.c.
61 #define DELTA_CWT(cont, obj) \
62 ((cont)->cursed ? (obj)->owt * 2 : (cont)->blessed \
63 ? ((obj)->owt + 3) / 4 \
64 : ((obj)->owt + 1) / 2)
65 #define GOLD_WT(n) (((n) + 50L) / 100L)
66 /* if you can figure this out, give yourself a hearty pat on the back... */
67 #define GOLD_CAPACITY(w, n) (((w) * -100L) - ((n) + 50L) - 1L)
69 /* A variable set in use_container(), to be used by the callback routines */
70 /* in_container() and out_container() from askchain() and use_container(). */
71 /* Also used by menu_loot() and container_gone(). */
72 static NEARDATA struct obj *current_container;
73 #define Icebox (current_container->otyp == ICE_BOX)
76 static const char moderateloadmsg[] = "You have a little trouble lifting";
78 static const char moderateloadmsg[] = "
\82ð
\8e\9d\82Á
\82½
\82ç
\8f
\82µ
\82Ó
\82ç
\82Â
\82¢
\82½
\81D";
80 static const char nearloadmsg[] = "You have much trouble lifting";
82 static const char nearloadmsg[] = "
\82Í
\82¸
\82Á
\82µ
\82è
\82Æ
\8c¨
\82É
\82Ì
\82µ
\82©
\82©
\82Á
\82½
\81D";
84 static const char overloadmsg[] = "You have extreme difficulty lifting";
86 static const char overloadmsg[] = "
\82ð
\8e\9d\82¿
\82 \82°
\82é
\82Ì
\82Í
\82Æ
\82Ä
\82à
\82Â
\82ç
\82¢
\81D";
88 /* BUG: this lets you look at cockatrice corpses while blind without
90 /* much simpler version of the look-here code; used by query_classes() */
92 simple_look(otmp, here)
93 struct obj *otmp; /* list of objects */
94 boolean here; /* flag for type of obj list linkage */
96 /* Neither of the first two cases is expected to happen, since
97 * we're only called after multiple classes of objects have been
98 * detected, hence multiple objects must be present.
101 impossible("simple_look(null)");
102 } else if (!(here ? otmp->nexthere : otmp->nobj)) {
103 pline1(doname(otmp));
105 winid tmpwin = create_nhwindow(NHW_MENU);
106 putstr(tmpwin, 0, "");
108 putstr(tmpwin, 0, doname(otmp));
109 otmp = here ? otmp->nexthere : otmp->nobj;
111 display_nhwindow(tmpwin, TRUE);
112 destroy_nhwindow(tmpwin);
117 collect_obj_classes(ilets, otmp, here, filter, itemcount)
119 register struct obj *otmp;
121 boolean FDECL((*filter), (OBJ_P));
124 register int iletct = 0;
128 ilets[iletct] = '\0'; /* terminate ilets so that index() will work */
130 c = def_oc_syms[(int) otmp->oclass].sym;
131 if (!index(ilets, c) && (!filter || (*filter)(otmp)))
132 ilets[iletct++] = c, ilets[iletct] = '\0';
134 otmp = here ? otmp->nexthere : otmp->nobj;
141 * Suppose some '?' and '!' objects are present, but '/' objects aren't:
142 * "a" picks all items without further prompting;
143 * "A" steps through all items, asking one by one;
144 * "?" steps through '?' items, asking, and ignores '!' ones;
145 * "/" becomes 'A', since no '/' present;
146 * "?a" or "a?" picks all '?' without further prompting;
147 * "/a" or "a/" becomes 'A' since there aren't any '/'
148 * (bug fix: 3.1.0 thru 3.1.3 treated it as "a");
149 * "?/a" or "a?/" or "/a?",&c picks all '?' even though no '/'
150 * (ie, treated as if it had just been "?a").
152 /*JP CHECK: 3.4.3
\82Å
\82Ì
\8cÄ
\82Ñ
\8fo
\82µ
\8c³
153 pickup.c:572:("
\8fE
\82¤") if (!query_classes(oclasses, &selective, &all_of_a_type,
154 pickup.c:2604:("
\8eæ
\82è
\8fo
\82·") if (query_classes(select, &one_by_one, &allflag,
155 pickup.c:2704:("
\93ü
\82ê
\82é") if (query_classes(select, &one_by_one, &allflag, "
\93ü
\82ê
\82é",
158 query_classes(oclasses, one_at_a_time, everything, action, objs, here,
161 boolean *one_at_a_time, *everything;
167 char ilets[30], inbuf[BUFSZ]; /* FIXME: hardcoded ilets[] length */
168 int iletct, oclassct;
169 boolean not_everything;
174 oclasses[oclassct = 0] = '\0';
175 *one_at_a_time = *everything = m_seen = FALSE;
176 iletct = collect_obj_classes(ilets, objs, here,
177 (boolean FDECL((*), (OBJ_P))) 0, &itemcount);
180 } else if (iletct == 1) {
181 oclasses[0] = def_char_to_objclass(ilets[0]);
183 if (itemcount && menu_on_demand) {
184 ilets[iletct++] = 'm';
186 ilets[iletct] = '\0';
188 } else { /* more than one choice available */
189 const char *where = 0;
190 register char sym, oc_of_sym, *p;
191 /* additional choices */
192 ilets[iletct++] = ' ';
193 ilets[iletct++] = 'a';
194 ilets[iletct++] = 'A';
195 ilets[iletct++] = (objs == invent ? 'i' : ':');
196 if (menu_on_demand) {
197 ilets[iletct++] = 'm';
200 ilets[iletct] = '\0';
202 oclasses[oclassct = 0] = '\0';
203 *one_at_a_time = *everything = FALSE;
204 not_everything = FALSE;
206 Sprintf(qbuf, "What kinds of thing do you want to %s? [%s]", action,
209 Sprintf(qbuf,"
\82Ç
\82Ì
\8eí
\97Þ
\82Ì
\82à
\82Ì
\82ð%s
\82©
\81H[%s]", jpolite(action),
213 if (*inbuf == '\033')
216 for (p = inbuf; (sym = *p++);) {
217 /* new A function (selective all) added by GAN 01/09/87 */
221 *one_at_a_time = TRUE;
224 else if (sym == ':') {
225 simple_look(objs, here); /* dumb if objs==invent */
226 /* if we just scanned the contents of a container
227 then mark it as having known contents */
228 if (objs->where == OBJ_CONTAINED)
229 objs->ocontainer->cknown = 1;
231 } else if (sym == 'i') {
232 (void) display_inventory((char *) 0, TRUE);
234 } else if (sym == 'm') {
237 oc_of_sym = def_char_to_objclass(sym);
238 if (index(ilets, sym)) {
239 add_valid_menu_class(oc_of_sym);
240 oclasses[oclassct++] = oc_of_sym;
241 oclasses[oclassct] = '\0';
246 !strcmp(action, "pick up")
248 !strcmp(action, "
\8fE
\82¤")
254 : !strcmp(action, "take out") ? "inside" : "";
256 : !strcmp(action, "
\8eæ
\82è
\8fo
\82·") ? "
\82Ì
\92\86" : "";
259 There("are no %c's %s.", sym, where);
261 pline("%c
\82Í%s
\82É
\82È
\82¢
\81D", sym, where);
264 You("have no %c's.", sym);
266 You("%c
\82Í
\8e\9d\82Á
\82Ä
\82¢
\82È
\82¢
\81D", sym);
267 not_everything = TRUE;
271 if (m_seen && menu_on_demand) {
272 *menu_on_demand = (*everything || !oclassct) ? -2 : -3;
275 if (!oclassct && (!*everything || not_everything)) {
276 /* didn't pick anything,
277 or tried to pick something that's not present */
278 *one_at_a_time = TRUE; /* force 'A' */
279 *everything = FALSE; /* inhibit 'a' */
285 /* check whether hero is bare-handedly touching a cockatrice corpse */
287 fatal_corpse_mistake(obj, remotely)
291 if (uarmg || remotely || obj->otyp != CORPSE
292 || !touch_petrifies(&mons[obj->corpsenm]) || Stone_resistance)
295 if (poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM)) {
296 display_nhwindow(WIN_MESSAGE, FALSE); /* --More-- */
301 pline("Touching %s is a fatal mistake.",
303 pline("%s
\82É
\90G
\82ê
\82é
\82Ì
\82Í
\92v
\96½
\93I
\82È
\8aÔ
\88á
\82¢
\82¾
\81D",
304 corpse_xname(obj, (const char *) 0, CXN_SINGULAR | CXN_ARTICLE));
305 instapetrify(killer_xname(obj));
309 /* attempting to manipulate a Rider's corpse triggers its revival */
311 rider_corpse_revival(obj, remotely)
315 if (!obj || obj->otyp != CORPSE || !is_rider(&mons[obj->corpsenm]))
319 pline("At your %s, the corpse suddenly moves...",
321 pline("
\82 \82È
\82½
\82ª%s
\82é
\82Æ
\93Ë
\91R
\8e\80\91Ì
\82ª
\93®
\82«
\8fo
\82µ
\82½
\81D
\81D
\81D",
323 remotely ? "attempted acquisition" : "touch");
325 remotely ? "
\8al
\93¾
\82µ
\82æ
\82¤
\82Æ
\82·" : "
\90G");
326 (void) revive_corpse(obj);
327 exercise(A_WIS, FALSE);
331 /* look at the objects at our location, unless there are too many of them */
333 check_here(picked_some)
336 register struct obj *obj;
339 /* count the objects here */
340 for (obj = level.objects[u.ux][u.uy]; obj; obj = obj->nexthere) {
345 /* If there are objects here, take a look. */
350 (void) look_here(ct, picked_some);
352 read_engr_at(u.ux, u.uy);
356 /* Value set by query_objlist() for n_or_more(). */
357 static long val_for_n_or_more;
359 /* query_objlist callback: return TRUE if obj's count is >= reference value */
366 return (boolean) (obj->quan >= val_for_n_or_more);
369 /* list of valid menu classes for query_objlist() and allow_category callback
370 (with room for all object classes, 'u'npaid, BUCX, and terminator) */
371 static char valid_menu_classes[MAXOCLASSES + 1 + 4 + 1];
372 static boolean class_filter, bucx_filter, shop_filter;
375 add_valid_menu_class(c)
378 static int vmc_count = 0;
380 if (c == 0) { /* reset */
382 class_filter = bucx_filter = shop_filter = FALSE;
384 valid_menu_classes[vmc_count++] = (char) c;
385 /* categorize the new class */
389 case 'C': /*FALLTHRU*/
401 valid_menu_classes[vmc_count] = '\0';
404 /* query_objlist callback: return TRUE if not uchain */
409 return (boolean) (obj != uchain);
412 /* query_objlist callback: return TRUE */
416 struct obj *obj UNUSED;
425 /* unpaid and BUC checks don't apply to coins */
426 if (obj->oclass == COIN_CLASS)
427 return index(valid_menu_classes, COIN_CLASS) ? TRUE : FALSE;
429 if (Role_if(PM_PRIEST))
432 * There are three types of filters possible and the first and
433 * third can have more than one entry:
434 * 1) object class (armor, potion, &c);
435 * 2) unpaid shop item;
436 * 3) bless/curse state (blessed, uncursed, cursed, BUC-unknown).
437 * When only one type is present, the situation is simple:
438 * to be accepted, obj's status must match one of the entries.
439 * When more than one type is present, the obj will now only
440 * be accepted when it matches one entry of each type.
441 * So ?!B will accept blessed scrolls or potions, and [u will
442 * accept unpaid armor. (In 3.4.3, an object was accepted by
443 * this filter if it met any entry of any type, so ?!B resulted
444 * in accepting all scrolls and potions regardless of bless/curse
445 * state plus all blessed non-scroll, non-potion objects.)
447 /* if class is expected but obj's class is not in the list, reject */
448 if (class_filter && !index(valid_menu_classes, obj->oclass))
450 /* if unpaid is expected and obj isn't unpaid, reject (treat a container
451 holding any unpaid object as unpaid even if isn't unpaid itself) */
452 if (shop_filter && !obj->unpaid
453 && !(Has_contents(obj) && count_unpaid(obj->cobj) > 0))
455 /* check for particular bless/curse state */
457 /* first categorize this object's bless/curse state */
459 !obj->bknown ? 'X' : obj->blessed ? 'B' : obj->cursed ? 'C' : 'U';
461 /* if its category is not in the list, reject */
462 if (!index(valid_menu_classes, bucx))
465 /* obj didn't fail any of the filter checks, so accept */
470 /* query_objlist callback: return TRUE if valid category (class), no uchain */
472 allow_cat_no_uchain(obj)
476 && ((index(valid_menu_classes,'u') && obj->unpaid)
477 || index(valid_menu_classes, obj->oclass)))
484 /* query_objlist callback: return TRUE if valid class and worn */
486 is_worn_by_type(otmp)
487 register struct obj *otmp;
489 return (boolean) (!!(otmp->owornmask & (W_ARMOR | W_ACCESSORY | W_WEAPON))
490 && index(valid_menu_classes, otmp->oclass) != 0);
494 * Have the hero pick things from the ground
495 * or a monster's inventory if swallowed.
500 * <0 pickup count of something
502 * Returns 1 if tried to pick something up, whether
503 * or not it succeeded.
507 int what; /* should be a long */
509 int i, n, res, count, n_tried = 0, n_picked = 0;
510 menu_item *pick_list = (menu_item *) 0;
511 boolean autopickup = what > 0;
512 struct obj *objchain;
515 /* we might have arrived here while fainted or sleeping, via
516 random teleport or levitation timeout; if so, skip check_here
517 and read_engr_at in addition to bypassing autopickup itself
518 [probably ought to check whether hero is using a cockatrice
519 corpse for a pillow here... (also at initial faint/sleep)] */
520 if (autopickup && multi < 0 && unconscious())
523 if (what < 0) /* pick N of something */
525 else /* pick anything */
529 struct trap *ttmp = t_at(u.ux, u.uy);
530 /* no auto-pick if no-pick move, nothing there, or in a pool */
531 if (autopickup && (context.nopick || !OBJ_AT(u.ux, u.uy)
532 || (is_pool(u.ux, u.uy) && !Underwater)
533 || is_lava(u.ux, u.uy))) {
534 read_engr_at(u.ux, u.uy);
538 /* no pickup if levitating & not on air or water level */
539 if (!can_reach_floor(TRUE)) {
540 if ((multi && !context.run) || (autopickup && !flags.pickup)
541 || (ttmp && uteetering_at_seen_pit(ttmp)))
542 read_engr_at(u.ux, u.uy);
545 /* multi && !context.run means they are in the middle of some other
546 * action, or possibly paralyzed, sleeping, etc.... and they just
547 * teleported onto the object. They shouldn't pick it up.
549 if ((multi && !context.run) || (autopickup && !flags.pickup)) {
553 if (notake(youmonst.data)) {
556 You("are physically incapable of picking anything up.");
558 You("
\95¨
\97\9d\93I
\82É
\8fE
\82¢
\82 \82°
\82é
\82±
\82Æ
\82ª
\82Å
\82«
\82È
\82¢
\81D");
564 /* if there's anything here, stop running */
565 if (OBJ_AT(u.ux, u.uy) && context.run && context.run != 8
570 add_valid_menu_class(0); /* reset */
572 objchain = level.objects[u.ux][u.uy];
573 traverse_how = BY_NEXTHERE;
575 objchain = u.ustuck->minvent;
576 traverse_how = 0; /* nobj */
579 * Start the actual pickup process. This is split into two main
580 * sections, the newer menu and the older "traditional" methods.
581 * Automatic pickup has been split into its own menu-style routine
582 * to make things less confusing.
585 n = autopick(objchain, traverse_how, &pick_list);
589 if (flags.menu_style != MENU_TRADITIONAL || iflags.menu_requested) {
590 /* use menus exclusively */
591 if (count) { /* looking for N of something */
594 Sprintf(buf, "Pick %d of what?", count);
596 Sprintf(buf, "
\89½
\82ð%d
\8cÂ
\8fE
\82¢
\82Ü
\82·
\82©
\81H", count);
597 val_for_n_or_more = count; /* set up callback selector */
598 n = query_objlist(buf, objchain, traverse_how | AUTOSELECT_SINGLE
600 &pick_list, PICK_ONE, n_or_more);
601 /* correct counts, if any given */
602 for (i = 0; i < n; i++)
603 pick_list[i].count = count;
606 n = query_objlist("Pick up what?", objchain,
608 n = query_objlist("
\89½
\82ð
\8fE
\82¢
\82Ü
\82·
\82©
\81H", objchain,
609 traverse_how | AUTOSELECT_SINGLE | INVORDER_SORT
611 &pick_list, PICK_ANY, all_but_uchain);
615 for (n_picked = i = 0; i < n; i++) {
616 res = pickup_object(pick_list[i].item.a_obj, pick_list[i].count,
619 break; /* can't continue */
623 free((genericptr_t) pick_list);
626 /* old style interface */
629 boolean all_of_a_type, selective;
630 char oclasses[MAXOCLASSES];
631 struct obj *obj, *obj2;
633 oclasses[0] = '\0'; /* types to consider (empty for all) */
634 all_of_a_type = TRUE; /* take all of considered types */
635 selective = FALSE; /* ask for each item */
637 /* check for more than one object */
638 for (obj = objchain; obj;
639 obj = (traverse_how == BY_NEXTHERE) ? obj->nexthere : obj->nobj)
642 if (ct == 1 && count) {
643 /* if only one thing, then pick it */
645 lcount = min(obj->quan, (long) count);
647 if (pickup_object(obj, lcount, FALSE) > 0)
648 n_picked++; /* picked something */
651 } else if (ct >= 2) {
655 There("are %s objects here.", (ct <= 10) ? "several" : "many");
657 pline("
\82±
\82±
\82É
\82Í%s
\82à
\82Ì
\82ª
\82 \82é
\81D", (ct <= 10) ? "
\82¢
\82
\82Â
\82©" : "
\91ò
\8eR
\82Ì");
658 if (!query_classes(oclasses, &selective, &all_of_a_type,
662 "
\8fE
\82¤", objchain,
663 traverse_how == BY_NEXTHERE, &via_menu)) {
668 "Pick up what?", objchain,
670 "
\89½
\82ð
\8fE
\82¢
\82Ü
\82·
\82©
\81H", objchain,
671 traverse_how | (selective ? 0 : INVORDER_SORT),
672 &pick_list, PICK_ANY,
673 via_menu == -2 ? allow_all : allow_category);
678 for (obj = objchain; obj; obj = obj2) {
679 if (traverse_how == BY_NEXTHERE)
680 obj2 = obj->nexthere; /* perhaps obj will be picked up */
685 if (!selective && oclasses[0] && !index(oclasses, obj->oclass))
688 if (!all_of_a_type) {
692 (void) safe_qbuf(qbuf, "Pick up ", "?", obj, doname,
693 ansimpleoname, something);
695 (void) safe_qbuf(qbuf, "", "
\82ð
\8fE
\82¢
\82Ü
\82·
\82©
\81H", obj, doname,
696 ansimpleoname, "
\82±
\82ê");
698 switch ((obj->quan < 2L) ? ynaq(qbuf) : ynNaq(qbuf)) {
700 goto end_query; /* out 2 levels */
704 all_of_a_type = TRUE;
707 oclasses[0] = obj->oclass;
711 case '#': /* count was entered */
713 continue; /* 0 count => No */
714 lcount = (long) yn_number;
715 if (lcount > obj->quan)
726 if ((res = pickup_object(obj, lcount, FALSE)) < 0)
731 ; /* semicolon needed by brain-damaged compilers */
735 if (hides_under(youmonst.data))
736 (void) hideunder(&youmonst);
738 /* position may need updating (invisible hero) */
742 /* check if there's anything else here after auto-pickup is done */
744 check_here(n_picked > 0);
746 return (n_tried > 0);
750 is_autopickup_exception(obj, grab)
752 boolean grab; /* forced pickup, rather than forced leave behind? */
755 * Does the text description of this match an exception?
757 char *objdesc = makesingular(doname(obj));
758 struct autopickup_exception *ape =
759 (grab) ? iflags.autopickup_exceptions[AP_GRAB]
760 : iflags.autopickup_exceptions[AP_LEAVE];
762 if (regex_match(objdesc, ape->regex))
770 * Pick from the given list using flags.pickup_types. Return the number
771 * of items picked (not counts). Create an array that returns pointers
772 * and counts of the items to be picked up. If the number of items
773 * picked is zero, the pickup list is left alone. The caller of this
774 * function must free the pickup list.
777 autopick(olist, follow, pick_list)
778 struct obj *olist; /* the object list */
779 int follow; /* how to follow the object list */
780 menu_item **pick_list; /* list of objects and counts to pick up */
782 menu_item *pi; /* pick item */
786 const char *otypes = flags.pickup_types;
788 /* first count the number of eligible items */
789 for (n = 0, curr = olist; curr; curr = FOLLOW(curr, follow)) {
790 pickit = (!*otypes || index(otypes, curr->oclass));
791 /* check for "always pick up */
793 pickit = is_autopickup_exception(curr, TRUE);
794 /* then for "never pick up */
796 pickit = !is_autopickup_exception(curr, FALSE);
797 /* pickup_thrown overrides pickup_types and exceptions */
799 pickit = (flags.pickup_thrown && curr->was_thrown);
800 /* finally, do we count this object? */
806 *pick_list = pi = (menu_item *) alloc(sizeof(menu_item) * n);
807 for (n = 0, curr = olist; curr; curr = FOLLOW(curr, follow)) {
808 pickit = (!*otypes || index(otypes, curr->oclass));
810 pickit = is_autopickup_exception(curr, TRUE);
812 pickit = !is_autopickup_exception(curr, FALSE);
814 pickit = (flags.pickup_thrown && curr->was_thrown);
816 pi[n].item.a_obj = curr;
817 pi[n].count = curr->quan;
826 * Put up a menu using the given object list. Only those objects on the
827 * list that meet the approval of the allow function are displayed. Return
828 * a count of the number of items selected, as well as an allocated array of
829 * menu_items, containing pointers to the objects selected and counts. The
830 * returned counts are guaranteed to be in bounds and non-zero.
833 * BY_NEXTHERE - Follow object list via nexthere instead of nobj.
834 * AUTOSELECT_SINGLE - Don't ask if only 1 object qualifies - just
836 * USE_INVLET - Use object's invlet.
837 * INVORDER_SORT - Use hero's pack order.
838 * INCLUDE_HERO - Showing engulfer's invent; show hero too.
839 * SIGNAL_NOMENU - Return -1 rather than 0 if nothing passes "allow".
840 * SIGNAL_ESCAPE - Return -1 rather than 0 if player uses ESC to
844 query_objlist(qstr, olist, qflags, pick_list, how, allow)
845 const char *qstr; /* query string */
846 struct obj *olist; /* the list to pick from */
847 int qflags; /* options to control the query */
848 menu_item **pick_list; /* return list of items picked */
849 int how; /* type of query */
850 boolean FDECL((*allow), (OBJ_P)); /* allow function */
854 struct obj *curr, *last, fake_hero_object;
858 boolean printed_type_name, sorted = (qflags & INVORDER_SORT) != 0,
859 engulfer = (qflags & INCLUDE_HERO) != 0;
861 *pick_list = (menu_item *) 0;
862 if (!olist && !engulfer)
865 /* count the number of items allowed */
866 for (n = 0, last = 0, curr = olist; curr; curr = FOLLOW(curr, qflags))
867 if ((*allow)(curr)) {
874 /* don't autoselect swallowed hero if it's the only choice */
875 qflags &= ~AUTOSELECT_SINGLE;
878 if (n == 0) /* nothing to pick here */
879 return (qflags & SIGNAL_NOMENU) ? -1 : 0;
881 if (n == 1 && (qflags & AUTOSELECT_SINGLE)) {
882 *pick_list = (menu_item *) alloc(sizeof(menu_item));
883 (*pick_list)->item.a_obj = last;
884 (*pick_list)->count = last->quan;
888 oarray = objarr_init(actualn);
889 /* Add objects to the array */
891 for (curr = olist; curr; curr = FOLLOW(curr, qflags)) {
892 if ((*allow)(curr)) {
893 objarr_set(curr, i++, oarray, (flags.sortloot == 'f'
894 || (flags.sortloot == 'l'
895 && !(qflags & USE_INVLET))));
899 win = create_nhwindow(NHW_MENU);
904 * Run through the list and add the objects to the menu. If
905 * INVORDER_SORT is set, we'll run through the list once for
906 * each type so we can group them. The allow function will only
907 * be called once per object in the list.
909 pack = flags.inv_order;
911 printed_type_name = FALSE;
912 for (i = 0; i < actualn; i++) {
914 if ((qflags & FEEL_COCKATRICE) && curr->otyp == CORPSE
915 && will_feel_cockatrice(curr, FALSE)) {
916 destroy_nhwindow(win); /* stop the menu and revert */
917 (void) look_here(0, FALSE);
920 if ((!sorted || curr->oclass == *pack) && (*allow)(curr)) {
921 /* if sorting, print type name (once only) */
922 if (sorted && !printed_type_name) {
924 add_menu(win, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
925 let_to_name(*pack, FALSE,
927 && iflags.menu_head_objsym),
929 printed_type_name = TRUE;
933 add_menu(win, obj_to_glyph(curr), &any,
934 (qflags & USE_INVLET) ? curr->invlet : 0,
935 def_oc_syms[(int) objects[curr->otyp].oc_class].sym,
936 ATR_NONE, doname_with_price(curr), MENU_UNSELECTED);
940 } while (sorted && *pack);
947 if (sorted && n > 1) {
948 Sprintf(buf, "%s Creatures",
949 is_animal(u.ustuck->data) ? "Swallowed" : "Engulfed");
950 add_menu(win, NO_GLYPH, &any, 0, 0, iflags.menu_headings, buf,
953 fake_hero_object = zeroobj;
954 fake_hero_object.quan = 1L; /* not strictly necessary... */
955 any.a_obj = &fake_hero_object;
956 add_menu(win, mon_to_glyph(&youmonst), &any,
957 /* fake inventory letter, no group accelerator */
958 CONTAINED_SYM, 0, ATR_NONE, an(self_lookat(buf)),
963 n = select_menu(win, how, pick_list);
964 destroy_nhwindow(win);
970 /* fix up counts: -1 means no count used => pick all;
971 if fake_hero_object was picked, discard that choice */
972 for (i = k = 0, mi = *pick_list; i < n; i++, mi++) {
973 if (mi->item.a_obj == &fake_hero_object)
975 if (mi->count == -1L || mi->count > mi->item.a_obj->quan)
976 mi->count = mi->item.a_obj->quan;
978 (*pick_list)[k] = *mi;
982 /* fake_hero was only choice so discard whole list */
983 free((genericptr_t) *pick_list);
987 /* other stuff plus fake_hero; last slot is now unused */
988 (*pick_list)[k].item = zeroany;
989 (*pick_list)[k].count = 0L;
993 /* -1 is used for SIGNAL_NOMENU, so callers don't expect it
994 to indicate that the player declined to make a choice */
995 n = (qflags & SIGNAL_ESCAPE) ? -2 : 0;
1001 * allow menu-based category (class) selection (for Drop,take off etc.)
1005 query_category(qstr, olist, qflags, pick_list, how)
1006 const char *qstr; /* query string */
1007 struct obj *olist; /* the list to pick from */
1008 int qflags; /* behaviour modification flags */
1009 menu_item **pick_list; /* return list of items picked */
1010 int how; /* type of query */
1017 boolean collected_type_name;
1020 boolean do_unpaid = FALSE;
1021 boolean do_blessed = FALSE, do_cursed = FALSE, do_uncursed = FALSE,
1022 do_buc_unknown = FALSE;
1023 int num_buc_types = 0;
1025 *pick_list = (menu_item *) 0;
1028 if ((qflags & UNPAID_TYPES) && count_unpaid(olist))
1030 if ((qflags & BUC_BLESSED) && count_buc(olist, BUC_BLESSED)) {
1034 if ((qflags & BUC_CURSED) && count_buc(olist, BUC_CURSED)) {
1038 if ((qflags & BUC_UNCURSED) && count_buc(olist, BUC_UNCURSED)) {
1042 if ((qflags & BUC_UNKNOWN) && count_buc(olist, BUC_UNKNOWN)) {
1043 do_buc_unknown = TRUE;
1047 ccount = count_categories(olist, qflags);
1048 /* no point in actually showing a menu for a single category */
1049 if (ccount == 1 && !do_unpaid && num_buc_types <= 1
1050 && !(qflags & BILLED_TYPES)) {
1051 for (curr = olist; curr; curr = FOLLOW(curr, qflags)) {
1052 if ((qflags & WORN_TYPES)
1053 && !(curr->owornmask & (W_ARMOR | W_ACCESSORY | W_WEAPON)))
1058 *pick_list = (menu_item *) alloc(sizeof(menu_item));
1059 (*pick_list)->item.a_int = curr->oclass;
1062 debugpline0("query_category: no single object match");
1067 win = create_nhwindow(NHW_MENU);
1069 pack = flags.inv_order;
1070 if ((qflags & ALL_TYPES) && (ccount > 1)) {
1073 any.a_int = ALL_TYPES_SELECTED;
1074 add_menu(win, NO_GLYPH, &any, invlet, 0, ATR_NONE,
1076 (qflags & WORN_TYPES) ? "All worn types" : "All types",
1078 (qflags & WORN_TYPES) ? "
\90g
\82É
\82Â
\82¯
\82é
\82à
\82Ì
\91S
\82Ä" : "
\91S
\82Ä",
1084 collected_type_name = FALSE;
1085 for (curr = olist; curr; curr = FOLLOW(curr, qflags)) {
1086 if (curr->oclass == *pack) {
1087 if ((qflags & WORN_TYPES)
1088 && !(curr->owornmask & (W_ARMOR | W_ACCESSORY | W_WEAPON)))
1090 if (!collected_type_name) {
1092 any.a_int = curr->oclass;
1094 win, NO_GLYPH, &any, invlet++,
1095 def_oc_syms[(int) objects[curr->otyp].oc_class].sym,
1096 ATR_NONE, let_to_name(*pack, FALSE,
1098 && iflags.menu_head_objsym),
1100 collected_type_name = TRUE;
1105 if (invlet >= 'u') {
1106 impossible("query_category: too many categories");
1110 /* unpaid items if there are any */
1116 add_menu(win, NO_GLYPH, &any, invlet, 0, ATR_NONE, "Unpaid items",
1118 add_menu(win, NO_GLYPH, &any, invlet, 0, ATR_NONE, "
\96¢
\95¥
\82Ì
\82à
\82Ì",
1121 /* billed items: checked by caller, so always include if BILLED_TYPES */
1122 if (qflags & BILLED_TYPES) {
1126 add_menu(win, NO_GLYPH, &any, invlet, 0, ATR_NONE,
1128 "Unpaid items already used up", MENU_UNSELECTED);
1130 "
\96¢
\95¥
\82Å
\8eg
\82Á
\82Ä
\82µ
\82Ü
\82Á
\82½
\82à
\82Ì", MENU_UNSELECTED);
1132 if (qflags & CHOOSE_ALL) {
1136 add_menu(win, NO_GLYPH, &any, invlet, 0, ATR_NONE,
1138 (qflags & WORN_TYPES) ? "Auto-select every item being worn"
1140 (qflags & WORN_TYPES) ? "
\90g
\82É
\82Â
\82¯
\82ç
\82ê
\82é
\95¨
\91S
\82Ä"
1142 : "Auto-select every item",
1147 /* items with b/u/c/unknown if there are any */
1152 add_menu(win, NO_GLYPH, &any, invlet, 0, ATR_NONE,
1154 "Items known to be Blessed", MENU_UNSELECTED);
1156 "
\8fj
\95\9f\82³
\82ê
\82Ä
\82¢
\82é
\82Æ
\82í
\82©
\82Á
\82Ä
\82¢
\82é
\82à
\82Ì", MENU_UNSELECTED);
1162 add_menu(win, NO_GLYPH, &any, invlet, 0, ATR_NONE,
1164 "Items known to be Cursed", MENU_UNSELECTED);
1166 "
\8eô
\82í
\82ê
\82Ä
\82¢
\82é
\82Æ
\82í
\82©
\82Á
\82Ä
\82¢
\82é
\82à
\82Ì", MENU_UNSELECTED);
1172 add_menu(win, NO_GLYPH, &any, invlet, 0, ATR_NONE,
1174 "Items known to be Uncursed", MENU_UNSELECTED);
1176 "
\8eô
\82í
\82ê
\82Ä
\82¢
\82È
\82¢
\82Æ
\82í
\82©
\82Á
\82Ä
\82¢
\82é
\82à
\82Ì", MENU_UNSELECTED);
1178 if (do_buc_unknown) {
1182 add_menu(win, NO_GLYPH, &any, invlet, 0, ATR_NONE,
1184 "Items of unknown B/C/U status", MENU_UNSELECTED);
1186 "
\8fj
\95\9f\81^
\8eô
\82¢
\82ª
\82í
\82©
\82ç
\82È
\82¢
\82à
\82Ì", MENU_UNSELECTED);
1188 end_menu(win, qstr);
1189 n = select_menu(win, how, pick_list);
1190 destroy_nhwindow(win);
1192 n = 0; /* caller's don't expect -1 */
1197 count_categories(olist, qflags)
1202 boolean counted_category;
1206 pack = flags.inv_order;
1208 counted_category = FALSE;
1209 for (curr = olist; curr; curr = FOLLOW(curr, qflags)) {
1210 if (curr->oclass == *pack) {
1211 if ((qflags & WORN_TYPES)
1212 && !(curr->owornmask & (W_ARMOR | W_ACCESSORY | W_WEAPON)))
1214 if (!counted_category) {
1216 counted_category = TRUE;
1225 /* could we carry `obj'? if not, could we carry some of it/them? */
1227 carry_count(obj, container, count, telekinesis, wt_before, wt_after)
1228 struct obj *obj, *container; /* object to pick up, bag it's coming out of */
1230 boolean telekinesis;
1231 int *wt_before, *wt_after;
1233 boolean adjust_wt = container && carried(container),
1234 is_gold = obj->oclass == COIN_CLASS;
1235 int wt, iw, ow, oow;
1236 long qq, savequan, umoney;
1239 const char *verb, *prefx1, *prefx2, *suffx;
1241 const char *verb, *prefx1;
1243 char obj_nambuf[BUFSZ], where[BUFSZ];
1245 savequan = obj->quan;
1247 umoney = money_cnt(invent);
1248 iw = max_capacity();
1250 if (count != savequan) {
1252 obj->owt = (unsigned) weight(obj);
1254 wt = iw + (int) obj->owt;
1256 wt -= (container->otyp == BAG_OF_HOLDING)
1257 ? (int) DELTA_CWT(container, obj)
1259 /* This will go with silver+copper & new gold weight */
1260 if (is_gold) /* merged gold might affect cumulative weight */
1261 wt -= (GOLD_WT(umoney) + GOLD_WT(count) - GOLD_WT(umoney + count));
1262 if (count != savequan) {
1263 obj->quan = savequan;
1272 /* see how many we can lift */
1274 iw -= (int) GOLD_WT(umoney);
1276 qq = GOLD_CAPACITY((long) iw, umoney);
1279 qq = 50L - (umoney % 100L) - 1L;
1282 for (; qq <= count; qq += 100L) {
1284 obj->owt = (unsigned) GOLD_WT(qq);
1285 ow = (int) GOLD_WT(umoney + qq);
1286 ow -= (container->otyp == BAG_OF_HOLDING)
1287 ? (int) DELTA_CWT(container, obj)
1298 else if (qq > count)
1300 wt = iw + (int) GOLD_WT(umoney + qq);
1301 } else if (count > 1 || count < obj->quan) {
1303 * Ugh. Calc num to lift by changing the quan of of the
1304 * object and calling weight.
1306 * This works for containers only because containers
1307 * don't merge. -dean
1309 for (qq = 1L; qq <= count; qq++) {
1311 obj->owt = (unsigned) (ow = weight(obj));
1313 ow -= (container->otyp == BAG_OF_HOLDING)
1314 ? (int) DELTA_CWT(container, obj)
1322 /* there's only one, and we can't lift it */
1325 obj->quan = savequan;
1329 /* some message will be given */
1330 Strcpy(obj_nambuf, doname(obj));
1333 Sprintf(where, "in %s", the(xname(container)));
1335 Sprintf(where, "%s
\82Ì
\92\86\82É
\93ü
\82Á
\82Ä
\82¢
\82é", the(xname(container)));
1339 verb = "
\89^
\82×
\82È
\82¢";
1342 Strcpy(where, "lying here");
1344 Strcpy(where, "
\82±
\82±
\82É
\92u
\82¢
\82Ä
\82 \82é");
1346 verb = telekinesis ? "acquire" : "lift";
1348 verb = telekinesis ? "
\8al
\93¾
\82Å
\82«
\82È
\82¢" : "
\8e\9d\82¿
\82 \82°
\82ç
\82ê
\82È
\82¢";
1351 /* lint suppression */
1352 *obj_nambuf = *where = '\0';
1355 /* we can carry qq of them */
1359 You("can only %s %s of the %s %s.", verb,
1360 (qq == 1L) ? "one" : "some", obj_nambuf, where);
1362 You("%s%s
\82Ì
\82¤
\82¿
\82Ì%s
\82µ
\82©%s
\81D",
1363 where, obj_nambuf, (qq == 1L) ? "
\82P
\82Â" : "
\82¢
\82
\82Â
\82©", verb);
1371 Strcpy(where, "here"); /* slightly shorter form */
1373 Strcpy(where, "
\82±
\82±
\82É
\82Í"); /* slightly shorter form */
1375 if (invent || umoney) {
1377 prefx1 = "you cannot ";
1379 suffx = " any more";
1381 prefx1 = "
\82±
\82ê
\88È
\8fã";
1385 prefx1 = (obj->quan == 1L) ? "it " : "even one ";
1386 prefx2 = "is too heavy for you to ";
1389 prefx1 = "
\8fd
\82·
\82¬
\82Ä";
1393 There("%s %s %s, but %s%s%s%s.", otense(obj, "are"), obj_nambuf, where,
1394 prefx1, prefx2, verb, suffx);
1396 pline("%s%s
\82ª
\82 \82é
\81C
\82µ
\82©
\82µ%s%s
\81D",
1397 where, obj_nambuf, prefx1, verb);
1400 /* *wt_after = iw; */
1404 /* determine whether character is able and player is willing to carry `obj' */
1407 lift_object(obj, container, cnt_p, telekinesis)
1408 struct obj *obj, *container; /* object to pick up, bag it's coming out of */
1410 boolean telekinesis;
1412 int result, old_wt, new_wt, prev_encumbr, next_encumbr;
1414 if (obj->otyp == BOULDER && Sokoban) {
1416 You("cannot get your %s around this %s.", body_part(HAND),
1419 You("%s
\82ð%s
\82Å
\8e\9d\82¿
\82 \82°
\82é
\82±
\82Æ
\82ª
\82Å
\82«
\82È
\82¢
\81D",
1420 xname(obj), body_part(HAND));
1424 /* override weight consideration for loadstone picked up by anybody
1425 and for boulder picked up by hero poly'd into a giant; override
1426 availability of open inventory slot iff not already carrying one */
1427 if (obj->otyp == LOADSTONE
1428 || (obj->otyp == BOULDER && throws_rocks(youmonst.data))) {
1429 if (inv_cnt(FALSE) < 52 || !carrying(obj->otyp)
1430 || merge_choice(invent, obj))
1431 return 1; /* lift regardless of current situation */
1432 /* if we reach here, we're out of slots and already have at least
1433 one of these, so treat this one more like a normal item */
1435 You("are carrying too much stuff to pick up %s %s.",
1436 (obj->quan == 1L) ? "another" : "more", simpleonames(obj));
1438 You("%s
\82ð%s
\8fE
\82¤
\82É
\82Í
\95¨
\82ð
\8e\9d\82¿
\82·
\82¬
\82Ä
\82¢
\82é
\81D",
1439 simpleonames(obj), (obj->quan == 1L) ? "
\82à
\82¤
\88ê
\82Â" : "
\82à
\82Á
\82Æ");
1445 carry_count(obj, container, *cnt_p, telekinesis, &old_wt, &new_wt);
1447 result = -1; /* nothing lifted */
1448 } else if (obj->oclass != COIN_CLASS
1449 /* [exception for gold coins will have to change
1450 if silver/copper ones ever get implemented] */
1451 && inv_cnt(FALSE) >= 52 && !merge_choice(invent, obj)) {
1453 Your("knapsack cannot accommodate any more items.");
1455 Your("
\83i
\83b
\83v
\83U
\83b
\83N
\82Í
\82±
\82ê
\88È
\8fã
\83A
\83C
\83e
\83\80\82ð
\8bl
\82ß
\8d\9e\82ß
\82È
\82¢
\81D");
1456 result = -1; /* nothing lifted */
1459 prev_encumbr = near_capacity();
1460 if (prev_encumbr < flags.pickup_burden)
1461 prev_encumbr = flags.pickup_burden;
1462 next_encumbr = calc_capacity(new_wt - old_wt);
1463 if (next_encumbr > prev_encumbr) {
1465 result = 0; /* don't lift */
1468 long savequan = obj->quan;
1471 Strcpy(qbuf, (next_encumbr > HVY_ENCUMBER)
1473 : (next_encumbr > MOD_ENCUMBER)
1477 (void) strsubst(qbuf, "lifting", "removing");
1479 (void) safe_qbuf(qbuf, qbuf, ". Continue?", obj, doname,
1480 ansimpleoname, something);
1481 obj->quan = savequan;
1482 switch (ynq(qbuf)) {
1490 break; /* 'y' => result == 1 */
1492 clear_nhwindow(WIN_MESSAGE);
1497 if (obj->otyp == SCR_SCARE_MONSTER && result <= 0 && !container)
1503 * Pick up <count> of obj from the ground and add it to the hero's inventory.
1504 * Returns -1 if caller should break out of its loop, 0 if nothing picked
1505 * up, 1 if otherwise.
1508 pickup_object(obj, count, telekinesis)
1511 boolean telekinesis; /* not picking it up directly by hand */
1515 if (obj->quan < count) {
1516 impossible("pickup_object: count %ld > quan %ld?", count, obj->quan);
1520 /* In case of auto-pickup, where we haven't had a chance
1521 to look at it yet; affects docall(SCR_SCARE_MONSTER). */
1525 if (obj == uchain) { /* do not pick up attached chain */
1527 } else if (obj->oartifact && !touch_artifact(obj, &youmonst)) {
1529 } else if (obj->otyp == CORPSE) {
1530 if (fatal_corpse_mistake(obj, telekinesis)
1531 || rider_corpse_revival(obj, telekinesis))
1533 } else if (obj->otyp == SCR_SCARE_MONSTER) {
1536 else if (!obj->spe && !obj->cursed)
1540 pline_The("scroll%s %s to dust as you %s %s up.", plur(obj->quan),
1541 otense(obj, "turn"), telekinesis ? "raise" : "pick",
1542 (obj->quan == 1L) ? "it" : "them");
1544 pline("
\8aª
\95¨
\82Í
\82 \82È
\82½
\82ª%s
\8fã
\82°
\82é
\82Æ
\90o
\82Æ
\82È
\82Á
\82Ä
\82µ
\82Ü
\82Á
\82½
\81D",
1545 telekinesis ? "
\8e\9d\82¿" : "
\8fE
\82¢");
1547 if (!(objects[SCR_SCARE_MONSTER].oc_name_known)
1548 && !(objects[SCR_SCARE_MONSTER].oc_uname))
1550 useupf(obj, obj->quan);
1551 return 1; /* tried to pick something up and failed, but
1552 don't want to terminate pickup loop yet */
1556 if ((res = lift_object(obj, (struct obj *) 0, &count, telekinesis)) <= 0)
1559 /* Whats left of the special case for gold :-) */
1560 if (obj->oclass == COIN_CLASS)
1562 if (obj->quan != count && obj->otyp != LOADSTONE)
1563 obj = splitobj(obj, count);
1565 obj = pick_obj(obj);
1567 if (uwep && uwep == obj)
1568 mrg_to_wielded = TRUE;
1569 nearload = near_capacity();
1570 prinv(nearload == SLT_ENCUMBER ? moderateloadmsg : (char *) 0, obj,
1572 mrg_to_wielded = FALSE;
1577 * Do the actual work of picking otmp from the floor or monster's interior
1578 * and putting it in the hero's inventory. Take care of billing. Return a
1579 * pointer to the object where otmp ends up. This may be different
1580 * from otmp because of merging.
1586 obj_extract_self(otmp);
1587 if (!u.uswallow && otmp != uball && costly_spot(otmp->ox, otmp->oy)) {
1588 char saveushops[5], fakeshop[2];
1590 /* addtobill cares about your location rather than the object's;
1591 usually they'll be the same, but not when using telekinesis
1592 (if ever implemented) or a grappling hook */
1593 Strcpy(saveushops, u.ushops);
1594 fakeshop[0] = *in_rooms(otmp->ox, otmp->oy, SHOPBASE);
1596 Strcpy(u.ushops, fakeshop);
1597 /* sets obj->unpaid if necessary */
1598 addtobill(otmp, TRUE, FALSE, FALSE);
1599 Strcpy(u.ushops, saveushops);
1600 /* if you're outside the shop, make shk notice */
1601 if (!index(u.ushops, *fakeshop))
1602 remote_burglary(otmp->ox, otmp->oy);
1604 newsym(otmp->ox, otmp->oy);
1605 return addinv(otmp); /* might merge it with other objects */
1609 * prints a message if encumbrance changed since the last check and
1610 * returns the new encumbrance value (from near_capacity()).
1615 static int oldcap = UNENCUMBERED;
1616 int newcap = near_capacity();
1618 if (oldcap < newcap) {
1622 Your("movements are slowed slightly because of your load.");
1624 Your("
\93®
\82«
\82Í
\89×
\95¨
\82Ì
\82½
\82ß
\82É
\8f
\82µ
\92x
\82
\82È
\82Á
\82½
\81D");
1628 You("rebalance your load. Movement is difficult.");
1630 You("
\89×
\95¨
\82Ì
\92Þ
\8d\87\82ð
\82Æ
\82è
\92¼
\82µ
\82½
\82ª
\81C
\93®
\82«
\82É
\82
\82¢
\81D");
1634 You("%s under your heavy load. Movement is very hard.",
1635 stagger(youmonst.data, "stagger"));
1637 You("
\89×
\95¨
\82Ì
\8fd
\82Ý
\82Å
\82Ì
\82½
\82¤
\82¿
\82Ü
\82í
\82Á
\82½
\81D
\93®
\82
\82Ì
\82ª
\94ñ
\8fí
\82É
\82«
\82Â
\82¢
\81D");
1642 You("%s move a handspan with this load!",
1643 newcap == 4 ? "can barely" : "can't even");
1645 You("
\82±
\82Ì
\8fd
\82³
\82Å
\82Í
\8f
\82µ
\82à
\93®
\82¯
\82È
\82¢
\81I");
1650 } else if (oldcap > newcap) {
1654 Your("movements are now unencumbered.");
1656 Your("
\93®
\82«
\82Í
\8ay
\82É
\82È
\82Á
\82½
\81D");
1660 Your("movements are only slowed slightly by your load.");
1662 You("
\82¿
\82å
\82Á
\82Æ
\93®
\82«
\82â
\82·
\82
\82È
\82Á
\82½
\81D");
1666 You("rebalance your load. Movement is still difficult.");
1668 You("
\89×
\95¨
\82Ì
\92Þ
\8d\87\82ð
\82Æ
\82è
\92¼
\82µ
\82½
\81D
\82¾
\82ª
\82Ü
\82¾
\93®
\82
\82Ì
\82Í
\82«
\82Â
\82¢
\81D");
1672 You("%s under your load. Movement is still very hard.",
1673 stagger(youmonst.data, "stagger"));
1675 You("
\89×
\95¨
\82Ì
\8fd
\82Ý
\82ª
\82¸
\82Á
\82µ
\82è
\82Æ
\8c¨
\82É
\82
\82é
\81D
\82Ü
\82¾
\93®
\82
\82Ì
\82ª
\94ñ
\8fí
\82É
\82«
\82Â
\82¢
\81D");
1686 /* Is there a container at x,y. Optional: return count of containers at x,y */
1688 container_at(x, y, countem)
1692 struct obj *cobj, *nobj;
1693 int container_count = 0;
1695 for (cobj = level.objects[x][y]; cobj; cobj = nobj) {
1696 nobj = cobj->nexthere;
1697 if (Is_container(cobj)) {
1703 return container_count;
1707 able_to_loot(x, y, looting)
1709 boolean looting; /* loot vs tip */
1712 const char *verb = looting ? "loot" : "tip";
1714 const char *verb = looting ? "
\8aJ
\82¯
\82é" : "
\82Ð
\82Á
\82
\82è
\95Ô
\82·";
1716 if (!can_reach_floor(TRUE)) {
1717 if (u.usteed && P_SKILL(P_RIDING) < P_BASIC)
1718 rider_cant_reach(); /* not skilled enough to reach */
1720 cant_reach_floor(x, y, FALSE, TRUE);
1722 } else if ((is_pool(x, y) && (looting || !Underwater)) || is_lava(x, y)) {
1723 /* at present, can't loot in water even when Underwater;
1724 can tip underwater, but not when over--or stuck in--lava */
1726 You("cannot %s things that are deep in the %s.", verb,
1727 is_lava(x, y) ? "lava" : "water");
1729 You("%s
\82É
\90[
\82
\82É
\92¾
\82ñ
\82¾
\82à
\82Ì
\82ð%s
\82±
\82Æ
\82Í
\82Å
\82«
\82È
\82¢
\81D",
1730 is_lava(u.ux, u.uy) ? "
\97n
\8aâ" : "
\90\85", verb);
1733 } else if (nolimbs(youmonst.data)) {
1735 pline("Without limbs, you cannot %s anything.", verb);
1737 pline("
\8eè
\91«
\82ª
\82È
\82¢
\82Ì
\82Å
\81C%s
\82±
\82Æ
\82Í
\82Å
\82«
\82È
\82¢
\81D", verb);
1739 } else if (looting && !freehand()) {
1741 pline("Without a free %s, you cannot loot anything.",
1743 pline("
\8e©
\97R
\82É
\82È
\82é%s
\82ª
\82È
\82¢
\82Ì
\82Å
\81C
\8aJ
\82¯
\82é
\82±
\82Æ
\82Í
\82Å
\82«
\82È
\82¢
\81D",
1755 for (i = -1; i <= 1; i++)
1756 for (j = -1; j <= 1; j++) {
1759 if (isok(nx, ny) && MON_AT(nx, ny))
1769 struct obj *cobj = *cobjp;
1772 if (cobj->olocked) {
1775 cobj->lknown ? "It is" : "Hmmm, it turns out to be");
1777 pline("%s
\8c®
\82ª
\82©
\82©
\82Á
\82Ä
\82¢
\82é
\81D", cobj->lknown ? "" : "
\82Þ
\81[
\82ñ
\81C");
1784 if (cobj->otyp == BAG_OF_TRICKS) {
1787 You("carefully open the bag...");
1789 You("
\90T
\8fd
\82É
\8a\93\82ð
\8aJ
\82¯
\82½
\81D
\81D
\81D");
1791 pline("It develops a huge set of teeth and bites you!");
1793 pline("
\8a\93\82©
\82ç
\91å
\82«
\82È
\8e\95\82ª
\90¶
\82¦
\82Ä
\82«
\82Ä
\81C
\82 \82È
\82½
\82ð
\8a\9a\82ñ
\82¾
\81I");
1796 losehp(Maybe_Half_Phys(tmp), "carnivorous bag", KILLED_BY_AN);
1798 losehp(Maybe_Half_Phys(tmp), "
\90H
\93÷
\8a\93\82É
\8a\9a\82Ü
\82ê
\82Ä", KILLED_BY_AN);
1799 makeknown(BAG_OF_TRICKS);
1804 You("%sopen %s...", (!cobj->cknown || !cobj->lknown) ? "carefully " : "",
1806 You("%s%s
\82ð
\8aJ
\82¯
\82½
\81D
\81D
\81D", (!cobj->cknown || !cobj->lknown) ? "
\90T
\8fd
\82É" : "",
1808 return use_container(cobjp, 0);
1811 /* loot a container on the floor or loot saddle from mon. */
1815 struct obj *cobj, *nobj;
1816 register int c = -1;
1819 boolean underfoot = TRUE;
1821 const char *dont_find_anything = "don't find anything";
1825 int prev_inquiry = 0;
1826 boolean prev_loot = FALSE;
1829 if (check_capacity((char *) 0)) {
1830 /* "Can't do that while carrying so much stuff." */
1833 if (nohands(youmonst.data)) {
1835 You("have no hands!"); /* not `body_part(HAND)' */
1837 pline("
\82 \82È
\82½
\82É
\82Í
\8eè
\82ª
\82È
\82¢
\81I");
1842 if (rn2(6) && reverse_loot())
1845 pline("Being confused, you find nothing to loot.");
1846 return 1; /* costs a turn */
1847 } /* else fallthrough to normal looting */
1854 if ((num_conts = container_at(cc.x, cc.y, TRUE)) > 0) {
1855 boolean anyfound = FALSE;
1857 if (!able_to_loot(cc.x, cc.y, TRUE))
1860 if (num_conts > 1) {
1861 /* use a menu to loot many containers */
1865 menu_item *pick_list = NULL;
1868 win = create_nhwindow(NHW_MENU);
1871 for (cobj = level.objects[cc.x][cc.y]; cobj;
1872 cobj = cobj->nexthere)
1873 if (Is_container(cobj)) {
1875 add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE,
1876 doname(cobj), MENU_UNSELECTED);
1879 end_menu(win, "Loot which containers?");
1881 end_menu(win, "
\82Ç
\82ê
\82ð
\8aJ
\82¯
\82Ü
\82·
\82©
\81H");
1882 n = select_menu(win, PICK_ANY, &pick_list);
1883 destroy_nhwindow(win);
1886 for (i = 0; i < n; i++) {
1887 timepassed |= do_loot_cont(&pick_list[i].item.a_obj);
1888 if (multi < 0 || !pick_list[i].item.a_obj) {
1889 free((genericptr_t) pick_list);
1895 free((genericptr_t) pick_list);
1899 for (cobj = level.objects[cc.x][cc.y]; cobj; cobj = nobj) {
1900 nobj = cobj->nexthere;
1902 if (Is_container(cobj)) {
1904 c = ynq(safe_qbuf(qbuf, "There is ", " here, loot it?",
1905 cobj, doname, ansimpleoname,
1908 c = ynq(safe_qbuf(qbuf, "
\82±
\82±
\82É
\82Í", "
\82ª
\82 \82é
\81C
\8aJ
\82¯
\82Ü
\82·
\82©
\81H",
1909 cobj, doname, ansimpleoname,
1918 timepassed |= do_loot_cont(&cobj);
1919 /* might have triggered chest trap or magic bag explosion
1921 if (multi < 0 || !cobj)
1928 } else if (IS_GRAVE(levl[cc.x][cc.y].typ)) {
1930 You("need to dig up the grave to effectively loot it...");
1932 You("
\95æ
\8dr
\82ç
\82µ
\82ð
\82·
\82é
\82É
\82Í
\8c@
\82ç
\82È
\82
\82Ä
\82Í
\81D
\81D
\81D");
1935 * 3.3.1 introduced directional looting for some things.
1937 if (c != 'y' && mon_beside(u.ux, u.uy)) {
1939 if (!get_adjacent_loc("Loot in what direction?",
1941 if (!get_adjacent_loc("
\82Ç
\82Ì
\95û
\8cü
\82ð
\92²
\82×
\82é
\81H",
1943 "Invalid loot location", u.ux, u.uy, &cc))
1945 "
\96³
\8cø
\82È
\95û
\8cü", u.ux, u.uy, &cc))
1947 if (cc.x == u.ux && cc.y == u.uy) {
1949 if (container_at(cc.x, cc.y, FALSE))
1955 You("%s to loot on the %s.", dont_find_anything,
1956 ceiling(cc.x, cc.y));
1958 You("%s
\82ð
\92²
\82×
\82½
\82ª
\89½
\82à
\82Ý
\82Â
\82©
\82ç
\82È
\82©
\82Á
\82½
\81D",
1959 ceiling(cc.x, cc.y));
1964 mtmp = m_at(cc.x, cc.y);
1966 timepassed = loot_mon(mtmp, &prev_inquiry, &prev_loot);
1967 /* always use a turn when choosing a direction is impaired,
1968 even if you've successfully targetted a saddled creature
1969 and then answered "no" to the "remove its saddle?" prompt */
1970 if (Confusion || Stunned)
1973 /* Preserve pre-3.3.1 behaviour for containers.
1974 * Adjust this if-block to allow container looting
1975 * from one square away to change that in the future.
1978 if (container_at(cc.x, cc.y, FALSE)) {
1981 You_cant("loot anything %sthere with %s in the way.",
1982 prev_inquiry ? "else " : "", mon_nam(mtmp));
1984 pline("%s
\82ª
\82¢
\82é
\82Ì
\82Å%s
\94 \82ð
\8aJ
\82¯
\82ç
\82ê
\82È
\82¢
\81D",
1985 mon_nam(mtmp), prev_inquiry ? "
\82Ù
\82©
\82Ì" : "");
1990 You("have to be at a container to loot it.");
1992 You("
\82Í
\94 \82ð
\8aJ
\82¯
\82é
\82½
\82ß
\82É
\82Í
\93¯
\82¶
\88Ê
\92u
\82É
\82¢
\82È
\82¯
\82ê
\82Î
\82È
\82ç
\82È
\82¢
\81D");
1997 You("%s %sthere to loot.", dont_find_anything,
1998 (prev_inquiry || prev_loot) ? "else " : "");
2000 pline("
\82±
\82±
\82É
\82Í%s
\8aJ
\82¯
\82ç
\82ê
\82é
\82à
\82Ì
\82Í
\82È
\82¢
\81D",
2001 (prev_inquiry || prev_loot) ? "
\82Ù
\82©
\82É" : "");
2006 } else if (c != 'y' && c != 'n') {
2008 You("%s %s to loot.", dont_find_anything,
2009 underfoot ? "here" : "there");
2011 pline("%s
\82É
\82Í
\8aJ
\82¯
\82ç
\82ê
\82é
\82à
\82Ì
\82Í
\82È
\82¢
\81D",
2012 underfoot ? "
\82±
\82±" : "
\82»
\82±");
2018 /* called when attempting to #loot while confused */
2022 struct obj *goldob = 0, *coffers, *otmp, boxdummy;
2025 int n, x = u.ux, y = u.uy;
2028 /* n objects: 1/(n+1) chance per object plus 1/(n+1) to fall off end
2030 for (n = inv_cnt(TRUE), otmp = invent; otmp; --n, otmp = otmp->nobj)
2032 prinv("You find old loot:", otmp, 0L);
2038 /* find a money object to mess with */
2039 for (goldob = invent; goldob; goldob = goldob->nobj)
2040 if (goldob->oclass == COIN_CLASS) {
2041 contribution = ((long) rnd(5) * goldob->quan + 4L) / 5L;
2042 if (contribution < goldob->quan)
2043 goldob = splitobj(goldob, contribution);
2049 if (!IS_THRONE(levl[x][y].typ)) {
2051 /* the dropped gold might have fallen to lower level */
2054 pline("Ok, now there is loot here.");
2056 pline("
\83I
\81[
\83P
\81[
\81C
\82±
\82±
\82É
\98d
\98G
\82ð
\92u
\82¢
\82Ä
\82¨
\82±
\82¤
\81D");
2058 /* find original coffers chest if present, otherwise use nearest one
2061 for (coffers = fobj; coffers; coffers = coffers->nobj)
2062 if (coffers->otyp == CHEST) {
2063 if (coffers->spe == 2)
2064 break; /* a throne room chest */
2066 || distu(coffers->ox, coffers->oy)
2067 < distu(otmp->ox, otmp->oy))
2068 otmp = coffers; /* remember closest ordinary chest */
2075 verbalize("Thank you for your contribution to reduce the debt.");
2077 verbalize("
\90Ô
\8e\9a\8d\91\8dÂ
\95Ô
\8dÏ
\82Ì
\82½
\82ß
\82Ì
\8añ
\95t
\82É
\8a´
\8eÓ
\82µ
\82Ü
\82·
\81D");
2079 (void) add_to_container(coffers, goldob);
2080 coffers->owt = weight(coffers);
2081 coffers->cknown = 0;
2082 if (!coffers->olocked) {
2083 boxdummy = zeroobj, boxdummy.otyp = SPE_WIZARD_LOCK;
2084 (void) boxlock(coffers, &boxdummy);
2086 } else if (levl[x][y].looted != T_LOOTED &&
2087 (mon = makemon(courtmon(), x, y, NO_MM_FLAGS)) != 0) {
2089 add_to_minv(mon, goldob);
2091 pline("The exchequer accepts your contribution.");
2093 pline("
\8dà
\96±
\8fÈ
\82Í
\82 \82È
\82½
\82Ì
\8añ
\95t
\82ð
\8eó
\82¯
\82Æ
\82Á
\82½
\81D");
2095 levl[x][y].looted = T_LOOTED;
2097 You("drop %s.", doname(goldob));
2104 /* loot_mon() returns amount of time passed.
2107 loot_mon(mtmp, passed_info, prev_loot)
2117 /* 3.3.1 introduced the ability to remove saddle from a steed */
2118 /* *passed_info is set to TRUE if a loot query was given. */
2119 /* *prev_loot is set to TRUE if something was actually acquired in here.
2121 if (mtmp && mtmp != u.usteed && (otmp = which_armor(mtmp, W_SADDLE))) {
2127 qbuf, "Do you want to remove the saddle from %s?",
2129 qbuf, "%s
\82©
\82ç
\88Æ
\82ð
\82Í
\82¸
\82µ
\82Ü
\82·
\82©
\81H",
2130 x_monnam(mtmp, ARTICLE_THE, (char *) 0, SUPPRESS_SADDLE, FALSE));
2131 if ((c = yn_function(qbuf, ynqchars, 'n')) == 'y') {
2132 if (nolimbs(youmonst.data)) {
2134 You_cant("do that without limbs."); /* not body_part(HAND) */
2136 You_cant("
\8eè
\82ª
\82È
\82¢
\82Æ
\82Å
\82«
\82È
\82¢
\81D");
2142 You("can't. The saddle seems to be stuck to %s.",
2144 pline("
\88Æ
\82Í%s
\82É
\82
\82Á
\82Â
\82¢
\82Ä
\82¢
\82é
\82æ
\82¤
\82¾
\81D",
2145 x_monnam(mtmp, ARTICLE_THE, (char *) 0, SUPPRESS_SADDLE,
2147 /* the attempt costs you time */
2150 obj_extract_self(otmp);
2151 if ((unwornmask = otmp->owornmask) != 0L) {
2152 mtmp->misc_worn_check &= ~unwornmask;
2153 otmp->owornmask = 0L;
2154 update_mon_intrinsics(mtmp, otmp, FALSE, FALSE);
2157 otmp = hold_another_object(otmp, "You drop %s!", doname(otmp),
2159 otmp = hold_another_object(otmp, "%s
\82ð
\97\8e\82Æ
\82µ
\82½
\81I", doname(otmp),
2161 timepassed = rnd(3);
2164 } else if (c == 'q') {
2168 /* 3.4.0 introduced the ability to pick things up from within swallower's
2171 int count = passed_info ? *passed_info : 0;
2172 timepassed = pickup(count);
2178 * Decide whether an object being placed into a magic bag will cause
2179 * it to explode. If the object is a bag itself, check recursively.
2182 mbag_explodes(obj, depthin)
2186 /* these won't cause an explosion when they're empty */
2187 if ((obj->otyp == WAN_CANCELLATION || obj->otyp == BAG_OF_TRICKS)
2191 /* odds: 1/1, 2/2, 3/4, 4/8, 5/16, 6/32, 7/64, 8/128, 9/128, 10/128,... */
2192 if ((Is_mbag(obj) || obj->otyp == WAN_CANCELLATION)
2193 && (rn2(1 << (depthin > 7 ? 7 : depthin)) <= depthin))
2195 else if (Has_contents(obj)) {
2198 for (otmp = obj->cobj; otmp; otmp = otmp->nobj)
2199 if (mbag_explodes(otmp, depthin + 1))
2205 /* Returns: -1 to stop, 1 item was inserted, 0 item was not inserted. */
2208 register struct obj *obj;
2210 boolean floor_container = !carried(current_container);
2211 boolean was_unpaid = FALSE;
2214 if (!current_container) {
2215 impossible("<in> no current_container?");
2217 } else if (obj == uball || obj == uchain) {
2219 You("must be kidding.");
2221 pline("
\82²
\8fç
\92k
\82ð
\81D");
2223 } else if (obj == current_container) {
2225 pline("That would be an interesting topological exercise.");
2227 pline("
\82»
\82ê
\82Í
\8b»
\96¡
\82ð
\82»
\82»
\82ç
\82ê
\82é
\83g
\83|
\83\8d\83W
\81[
\82Ì
\96â
\91è
\82¾
\81D");
2229 } else if (obj->owornmask & (W_ARMOR | W_ACCESSORY)) {
2231 Norep("You cannot %s %s you are wearing.",
2232 Icebox ? "refrigerate" : "stash", something);
2234 Norep("
\90g
\82É
\82Â
\82¯
\82Ä
\82¢
\82é
\82à
\82Ì
\82ð%s
\82±
\82Æ
\82Í
\82Å
\82«
\82È
\82¢
\81D",
2235 Icebox ? "
\97â
\93\80\82·
\82é" : "
\82µ
\82Ü
\82¤");
2238 } else if ((obj->otyp == LOADSTONE) && obj->cursed) {
2241 pline_The("stone%s won't leave your person.", plur(obj->quan));
2243 pline("
\82Ç
\82¤
\82¢
\82¤
\82í
\82¯
\82©
\82»
\82Ì
\90Î
\82ð
\82µ
\82Ü
\82¤
\82±
\82Æ
\82Í
\82Å
\82«
\82È
\82¢
\81D");
2245 } else if (obj->otyp == AMULET_OF_YENDOR
2246 || obj->otyp == CANDELABRUM_OF_INVOCATION
2247 || obj->otyp == BELL_OF_OPENING
2248 || obj->otyp == SPE_BOOK_OF_THE_DEAD) {
2249 /* Prohibit Amulets in containers; if you allow it, monsters can't
2250 * steal them. It also becomes a pain to check to see if someone
2251 * has the Amulet. Ditto for the Candelabrum, the Bell and the Book.
2254 pline("%s cannot be confined in such trappings.", The(xname(obj)));
2256 pline("%s
\82Í
\8bl
\82ß
\82é
\82±
\82Æ
\82Í
\82Å
\82«
\82È
\82¢
\81D", The(xname(obj)));
2258 } else if (obj->otyp == LEASH && obj->leashmon != 0) {
2260 pline("%s attached to your pet.", Tobjnam(obj, "are"));
2262 pline("%s
\82Í
\83y
\83b
\83g
\82É
\95t
\82¯
\82ç
\82ê
\82Ä
\82¢
\82é
\81D", xname(obj));
2264 } else if (obj == uwep) {
2269 setuwep((struct obj *) 0);
2271 return 0; /* unwielded, died, rewielded */
2272 } else if (obj == uswapwep) {
2273 setuswapwep((struct obj *) 0);
2275 return 0; /* unwielded, died, rewielded */
2276 } else if (obj == uquiver) {
2277 setuqwep((struct obj *) 0);
2279 return 0; /* unwielded, died, rewielded */
2282 if (fatal_corpse_mistake(obj, FALSE))
2285 /* boxes, boulders, and big statues can't fit into any container */
2286 if (obj->otyp == ICE_BOX || Is_box(obj) || obj->otyp == BOULDER
2287 || (obj->otyp == STATUE && bigmonst(&mons[obj->corpsenm]))) {
2289 * xname() uses a static result array. Save obj's name
2290 * before current_container's name is computed. Don't
2291 * use the result of strcpy() within You() --- the order
2292 * of evaluation of the parameters is undefined.
2294 Strcpy(buf, the(xname(obj)));
2296 You("cannot fit %s into %s.", buf, the(xname(current_container)));
2298 pline("%s
\82ð%s
\82É
\8bl
\82ß
\8d\9e\82Þ
\82±
\82Æ
\82Í
\82Å
\82«
\82È
\82¢
\81D", buf, the(xname(current_container)));
2304 if (obj_is_burning(obj)) /* this used to be part of freeinv() */
2305 (void) snuff_lit(obj);
2307 if (floor_container && costly_spot(u.ux, u.uy)) {
2308 if (current_container->no_charge && !obj->unpaid) {
2309 /* don't sell when putting the item into your own container */
2311 } else if (obj->oclass != COIN_CLASS) {
2312 /* sellobj() will take an unpaid item off the shop bill
2313 * note: coins are handled later */
2314 was_unpaid = obj->unpaid ? TRUE : FALSE;
2315 sellobj_state(SELL_DELIBERATE);
2316 sellobj(obj, u.ux, u.uy);
2317 sellobj_state(SELL_NORMAL);
2320 if (Icebox && !age_is_relative(obj)) {
2321 obj->age = monstermoves - obj->age; /* actual age */
2322 /* stop any corpse timeouts when frozen */
2323 if (obj->otyp == CORPSE && obj->timed) {
2324 long rot_alarm = stop_timer(ROT_CORPSE, obj_to_any(obj));
2325 (void) stop_timer(REVIVE_MON, obj_to_any(obj));
2326 /* mark a non-reviving corpse as such */
2330 } else if (Is_mbag(current_container) && mbag_explodes(obj, 0)) {
2331 /* explicitly mention what item is triggering the explosion */
2333 pline("As you put %s inside, you are blasted by a magical explosion!",
2335 pline("%s
\82ð
\92\86\82É
\93ü
\82ê
\82é
\82Æ
\81C
\82 \82È
\82½
\82Í
\96\82\96@
\82Ì
\94\9a\94
\82ð
\97\81\82Ñ
\82½
\81I",
2337 /* did not actually insert obj yet */
2339 addtobill(obj, FALSE, FALSE, TRUE);
2340 obfree(obj, (struct obj *) 0);
2341 delete_contents(current_container);
2342 if (!floor_container)
2343 useup(current_container);
2344 else if (obj_here(current_container, u.ux, u.uy))
2345 useupf(current_container, current_container->quan);
2347 panic("in_container: bag not found.");
2350 losehp(d(6, 6), "magical explosion", KILLED_BY_AN);
2352 losehp(d(6, 6), "
\96\82\96@
\82Ì
\94\9a\94
\82Å", KILLED_BY_AN);
2353 current_container = 0; /* baggone = TRUE; */
2356 if (current_container) {
2357 Strcpy(buf, the(xname(current_container)));
2359 You("put %s into %s.", doname(obj), buf);
2361 You("%s
\82ð%s
\82Ì
\92\86\82É
\82µ
\82Ü
\82Á
\82½
\81D", doname(obj), buf);
2363 /* gold in container always needs to be added to credit */
2364 if (floor_container && obj->oclass == COIN_CLASS)
2365 sellobj(obj, current_container->ox, current_container->oy);
2366 (void) add_to_container(current_container, obj);
2367 current_container->owt = weight(current_container);
2369 /* gold needs this, and freeinv() many lines above may cause
2370 * the encumbrance to disappear from the status, so just always
2371 * update status immediately.
2375 return (current_container ? 1 : -1);
2382 return current_container && obj != current_container;
2385 /* Returns: -1 to stop, 1 item was removed, 0 item was not removed. */
2388 register struct obj *obj;
2390 register struct obj *otmp;
2391 boolean is_gold = (obj->oclass == COIN_CLASS);
2395 if (!current_container) {
2396 impossible("<out> no current_container?");
2398 } else if (is_gold) {
2399 obj->owt = weight(obj);
2402 if (obj->oartifact && !touch_artifact(obj, &youmonst))
2405 if (fatal_corpse_mistake(obj, FALSE))
2409 if ((res = lift_object(obj, current_container, &count, FALSE)) <= 0)
2412 if (obj->quan != count && obj->otyp != LOADSTONE)
2413 obj = splitobj(obj, count);
2415 /* Remove the object from the list. */
2416 obj_extract_self(obj);
2417 current_container->owt = weight(current_container);
2419 if (Icebox && !age_is_relative(obj)) {
2420 obj->age = monstermoves - obj->age; /* actual age */
2421 if (obj->otyp == CORPSE)
2422 start_corpse_timeout(obj);
2424 /* simulated point of time */
2426 if (!obj->unpaid && !carried(current_container)
2427 && costly_spot(current_container->ox, current_container->oy)) {
2428 obj->ox = current_container->ox;
2429 obj->oy = current_container->oy;
2430 addtobill(obj, FALSE, FALSE, FALSE);
2433 pick_pick(obj); /* shopkeeper feedback */
2436 loadlev = near_capacity();
2439 ? (loadlev < MOD_ENCUMBER ? "You have a little trouble removing"
2441 ? (loadlev < MOD_ENCUMBER ? "
\82ð
\89^
\82Ô
\82Ì
\82Í
\8f
\81X
\8d¢
\93ï
\82¾
\81D"
2443 : "You have much trouble removing")
2445 : "
\82ð
\89^
\82Ô
\82Ì
\82Í
\82©
\82È
\82è
\8d¢
\93ï
\82¾
\81D")
2450 bot(); /* update character's gold piece count immediately */
2455 /* an object inside a cursed bag of holding is being destroyed */
2457 mbag_item_gone(held, item)
2466 pline("%s %s vanished!", Doname2(item), otense(item, "have"));
2468 pline("%s
\82Í
\8fÁ
\82¦
\8b\8e\82Á
\82½
\81I", Doname2(item));
2471 You("%s %s disappear!", Blind ? "notice" : "see", doname(item));
2473 You("%s
\82ª
\8c©
\82¦
\82È
\82
\82È
\82é
\82Ì%s
\81D", doname(item), Blind ? "
\82É
\8bC
\82Ã
\82¢
\82½" : "
\82ð
\8c©
\82½");
2476 if (*u.ushops && (shkp = shop_keeper(*u.ushops)) != 0) {
2477 if (held ? (boolean) item->unpaid : costly_spot(u.ux, u.uy))
2478 loss = stolen_value(item, u.ux, u.uy, (boolean) shkp->mpeaceful,
2481 obfree(item, (struct obj *) 0);
2486 observe_quantum_cat(box)
2490 static NEARDATA const char sc[] = "Schroedinger's Cat";
2492 static NEARDATA const char sc[] = "
\83V
\83\85\83\8c\83f
\83B
\83\93\83K
\81[
\82Ì
\94L";
2493 struct obj *deadcat;
2494 struct monst *livecat;
2497 box->spe = 0; /* box->owt will be updated below */
2498 if (get_obj_location(box, &ox, &oy, 0))
2499 box->ox = ox, box->oy = oy; /* in case it's being carried */
2501 /* this isn't really right, since any form of observation
2502 (telepathic or monster/object/food detection) ought to
2503 force the determination of alive vs dead state; but basing
2504 it just on opening the box is much simpler to cope with */
2506 ? makemon(&mons[PM_HOUSECAT], box->ox, box->oy, NO_MINVENT)
2509 livecat->mpeaceful = 1;
2510 set_malign(livecat);
2511 if (!canspotmon(livecat))
2513 You("think %s brushed your %s.", something, body_part(FOOT));
2515 You("%s
\82ª
\82 \82È
\82½
\82Ì%s
\82ð
\82
\82·
\82®
\82Á
\82½
\81D", something, body_part(FOOT));
2518 pline("%s inside the box is still alive!", Monnam(livecat));
2520 pline("
\94 \82Ì
\82È
\82©
\82Ì%s
\82Í
\82Ü
\82¾
\90¶
\82«
\82Ä
\82¢
\82é
\81I", Monnam(livecat));
2521 (void) christen_monst(livecat, sc);
2524 mk_named_object(CORPSE, &mons[PM_HOUSECAT], box->ox, box->oy, sc);
2526 obj_extract_self(deadcat);
2527 (void) add_to_container(box, deadcat);
2530 pline_The("%s inside the box is dead!",
2531 Hallucination ? rndmonnam(NULL) : "housecat");
2533 pline_The("
\94 \82Ì
\92\86\82Ì%s
\82Í
\8e\80\82ñ
\82Å
\82¢
\82é
\81I",
2534 Hallucination ? rndmonnam(NULL) : "
\94L");
2537 box->owt = weight(box);
2543 /* used by askchain() to check for magic bag explosion */
2546 int FDECL((*fn), (OBJ_P));
2548 /* result is only meaningful while use_container() is executing */
2549 return ((fn == in_container || fn == out_container)
2550 && !current_container);
2554 explain_container_prompt()
2556 static const char *const explaintext[] = {
2558 "Container actions:", "", " : -- Look: examine contents",
2559 " o -- Out: take things out", " i -- In: put things in",
2560 " b -- Both: first take things out, then put things in",
2561 " r -- Reversed: put things in, then take things out",
2562 " s -- Stash: put one item in", " q -- Quit: do nothing",
2563 " ? -- Help: display this text.", "", 0
2565 "
\93ü
\82ê
\95¨
\82Ö
\82Ì
\8ds
\93®
\81F", "", " : -- Look:
\92\86\90g
\82ð
\92²
\82×
\82é",
2566 " o -- Out:
\95¨
\82ð
\8fo
\82·", " i -- In:
\95¨
\82ð
\93ü
\82ê
\82é",
2567 " b -- Both:
\82Ü
\82¸
\95¨
\82ð
\8fo
\82µ
\81A
\82»
\82ê
\82©
\82ç
\95¨
\82ð
\93ü
\82ê
\82é",
2568 " r -- Reversed:
\95¨
\82ð
\93ü
\82ê
\81A
\82»
\82ê
\82©
\82ç
\95¨
\82ð
\8fo
\82·",
2569 " s -- Stash:
\95¨
\82ð
\88ê
\82Â
\93ü
\82ê
\82é", " q -- Quit:
\89½
\82à
\82µ
\82È
\82¢",
2570 " ? -- Help:
\82±
\82ê
\82ð
\95\
\8e¦
\82·
\82é", "", 0
2573 const char *const *txtpp;
2576 /* "Do what with <container>? [:oibrsq or ?] (q)" */
2577 if ((win = create_nhwindow(NHW_TEXT)) != WIN_ERR) {
2578 for (txtpp = explaintext; *txtpp; ++txtpp)
2579 putstr(win, 0, *txtpp);
2580 display_nhwindow(win, FALSE);
2581 destroy_nhwindow(win);
2588 if (nohands(youmonst.data)) {
2590 You("have no hands!"); /* not `body_part(HAND)' */
2592 pline("
\82 \82È
\82½
\82É
\82Í
\8eè
\82ª
\82È
\82¢
\81I"); /* not `body_part(HAND)' */
2595 } else if (!freehand()) {
2597 You("have no free %s.", body_part(HAND));
2599 You("%s
\82Ì
\8e©
\97R
\82ª
\8cø
\82©
\82È
\82¢
\81D", body_part(HAND));
2605 static const char stashable[] = { ALLOW_COUNT, COIN_CLASS, ALL_CLASSES, 0 };
2608 use_container(objp, held)
2612 struct obj *curr, *otmp, *obj = *objp;
2613 boolean quantum_cat, cursed_mbag, loot_out, loot_in, loot_in_first,
2614 stash_one, inokay, outokay, outmaybe;
2615 char c, emptymsg[BUFSZ], qbuf[QBUFSZ], pbuf[QBUFSZ], xbuf[QBUFSZ];
2625 pline("%s locked.", Tobjnam(obj, "are"));
2627 pline("%s
\82Í
\8c®
\82ª
\82©
\82©
\82Á
\82Ä
\82¢
\82é
\81D", xname(obj));
2630 You("must put it down to unlock.");
2632 if (held) pline("
\89º
\82É
\92u
\82©
\82È
\82¢
\82±
\82Æ
\82É
\82Í
\8c®
\82ð
\82Í
\82¸
\82¹
\82È
\82¢
\81D");
2635 } else if (obj->otrapped) {
2638 You("open %s...", the(xname(obj)));
2640 You("%s
\82ð
\8aJ
\82¯
\82½
\81D
\81D
\81D", the(xname(obj)));
2642 (void) chest_trap(obj, HAND, FALSE);
2643 /* even if the trap fails, you've used up this turn */
2644 if (multi >= 0) { /* in case we didn't become paralyzed */
2646 multi_reason = "opening a container";
2653 current_container = obj; /* for use by in/out_container */
2654 /* from here on out, all early returns go through containerdone */
2656 /* check for Schroedinger's Cat */
2657 quantum_cat = SchroedingersBox(current_container);
2659 observe_quantum_cat(current_container);
2662 /* sometimes toss objects if a cursed magic bag */
2663 cursed_mbag = (Is_mbag(current_container) && current_container->cursed
2664 && Has_contents(current_container));
2668 for (curr = current_container->cobj; curr; curr = otmp) {
2671 obj_extract_self(curr);
2672 loss += mbag_item_gone(held, curr);
2678 You("owe %ld %s for lost merchandise.", loss, currency(loss));
2680 You("
\8e¸
\82Á
\82½
\8f¤
\95i
\82Ì
\82½
\82ß
\82É%ld%s
\82Ì
\95\89\8dÂ
\82ð
\95\89\82Á
\82½
\81D", loss, currency(loss));
2681 current_container->owt = weight(current_container);
2683 inokay = (invent != 0
2684 && !(invent == current_container && !current_container->nobj));
2685 outokay = Has_contents(current_container);
2686 if (!outokay) /* preformat the empty-container message */
2688 Sprintf(emptymsg, "%s is %sempty.", Ysimple_name2(current_container),
2689 (quantum_cat || cursed_mbag) ? "now " : "");
2691 Sprintf(emptymsg, "%s
\82Í%s
\8bó
\82Á
\82Û
\82¾
\81D", Ysimple_name2(current_container),
2692 (quantum_cat || cursed_mbag) ? "
\8d¡
\82Í" : "");
2696 * What-to-do prompt's list of possible actions:
2697 * always include the look-inside choice (':');
2698 * include the take-out choice ('o') if container
2699 * has anything in it or if player doesn't yet know
2700 * that it's empty (latter can change on subsequent
2701 * iterations if player picks ':' response);
2702 * include the put-in choices ('i','s') if hero
2703 * carries any inventory (including gold);
2704 * include do-both when 'o' is available, even if
2705 * inventory is empty--taking out could alter that;
2706 * include do-both-reversed when 'i' is available,
2707 * even if container is empty--for similar reason;
2708 * always include the quit choice ('q').
2709 * include the help choice (" or ?") if `cmdassist'
2710 * run-time option is set;
2711 * (Player can pick any of (o,i,b,r,s,?) even when
2712 * they're not listed among the available actions.)
2714 * Do what with <the/your/Shk's container>? [:oibrsq or ?] (q)
2716 * <The/Your/Shk's container> is empty. Do what with it? [:irsq or ?]
2718 for (;;) { /* repeats if '?' or ":' gets chosen */
2719 outmaybe = (outokay || !current_container->cknown);
2721 (void) safe_qbuf(qbuf, (char *) 0, " is empty. Do what with it?",
2722 current_container, Yname2, Ysimple_name2,
2725 (void) safe_qbuf(qbuf, "Do what with ", "?", current_container,
2726 yname, ysimple_name, "it");
2727 /* ask player about what to do with this container */
2728 if (flags.menu_style == MENU_FULL) {
2729 if (!inokay && !outmaybe) {
2730 /* nothing to take out, nothing to put in;
2731 trying to do both will yield proper feedback */
2734 c = in_or_out_menu(qbuf, current_container, outmaybe, inokay,
2737 } else { /* TRADITIONAL, COMBINATION, or PARTIAL */
2738 xbuf[0] = '\0'; /* list of extra acceptable responses */
2739 Strcpy(pbuf, ":"); /* look inside */
2740 Strcat(outmaybe ? pbuf : xbuf, "o"); /* take out */
2741 Strcat(inokay ? pbuf : xbuf, "i"); /* put in */
2742 Strcat(outmaybe ? pbuf : xbuf, "b"); /* both */
2743 Strcat(inokay ? pbuf : xbuf, "rs"); /* reversed, stash */
2744 Strcat(pbuf, "q"); /* quit */
2745 if (iflags.cmdassist)
2746 Strcat(pbuf, " or ?"); /* help */
2750 Strcat(strcat(pbuf, "\033"), xbuf);
2751 c = yn_function(qbuf, pbuf, 'q');
2752 } /* FULL vs other modes */
2755 explain_container_prompt();
2756 } else if (c == ':') { /* note: will set obj->cknown */
2757 if (!current_container->cknown)
2758 used = 1; /* gaining info */
2759 container_contents(current_container, FALSE, FALSE, TRUE);
2762 } /* loop until something other than '?' or ':' is picked */
2764 if (c == 'q') /* [not strictly needed; falling through works] */
2766 loot_out = (c == 'o' || c == 'b' || c == 'r');
2767 loot_in = (c == 'i' || c == 'b' || c == 'r');
2768 loot_in_first = (c == 'r'); /* both, reversed */
2769 stash_one = (c == 's');
2771 /* out-only or out before in */
2772 if (loot_out && !loot_in_first) {
2773 if (!Has_contents(current_container)) {
2774 pline1(emptymsg); /* <whatever> is empty. */
2775 if (!current_container->cknown)
2777 current_container->cknown = 1;
2779 add_valid_menu_class(0); /* reset */
2780 if (flags.menu_style == MENU_TRADITIONAL)
2781 used |= traditional_loot(FALSE);
2783 used |= (menu_loot(0, FALSE) > 0);
2787 if ((loot_in || stash_one)
2788 && (!invent || (invent == current_container && !invent->nobj))) {
2789 You("don't have anything%s to %s.", invent ? " else" : "",
2790 stash_one ? "stash" : "put in");
2791 loot_in = stash_one = FALSE;
2795 * Gone: being nice about only selecting food if we know we are
2796 * putting things in an ice chest.
2799 add_valid_menu_class(0); /* reset */
2800 if (flags.menu_style == MENU_TRADITIONAL)
2801 used |= traditional_loot(TRUE);
2803 used |= (menu_loot(0, TRUE) > 0);
2804 } else if (stash_one) {
2805 /* put one item into container */
2806 if ((otmp = getobj(stashable, "stash")) != 0) {
2807 if (in_container(otmp)) {
2810 /* couldn't put selected item into container for some
2811 reason; might need to undo splitobj() */
2812 for (curr = invent; curr; curr = curr->nobj)
2813 if (curr->nobj == otmp)
2815 if (curr && curr->invlet == otmp->invlet)
2816 (void) merged(&curr, &otmp);
2820 /* putting something in might have triggered magic bag explosion */
2821 if (!current_container)
2825 if (loot_out && loot_in_first) {
2826 if (!Has_contents(current_container)) {
2827 pline1(emptymsg); /* <whatever> is empty. */
2828 if (!current_container->cknown)
2830 current_container->cknown = 1;
2832 add_valid_menu_class(0); /* reset */
2833 if (flags.menu_style == MENU_TRADITIONAL)
2834 used |= traditional_loot(FALSE);
2836 used |= (menu_loot(0, FALSE) > 0);
2842 /* Not completely correct; if we put something in without knowing
2843 whatever was already inside, now we suddenly do. That can't
2844 be helped unless we want to track things item by item and then
2845 deal with containers whose contents are "partly known". */
2846 if (current_container)
2847 current_container->cknown = 1;
2851 *objp = current_container; /* might have become null */
2852 current_container = 0; /* avoid hanging on to stale pointer */
2856 /* loot current_container (take things out or put things in), by prompting */
2858 traditional_loot(put_in)
2861 int FDECL((*actionfunc), (OBJ_P)), FDECL((*checkfunc), (OBJ_P));
2862 struct obj **objlist;
2863 char selection[MAXOCLASSES + 1];
2865 boolean one_by_one, allflag;
2866 int used = 0, menu_on_request = 0;
2871 actionfunc = in_container;
2874 action = "take out";
2875 objlist = &(current_container->cobj);
2876 actionfunc = out_container;
2877 checkfunc = (int FDECL((*), (OBJ_P))) 0;
2880 if (query_classes(selection, &one_by_one, &allflag, action, *objlist,
2881 FALSE, &menu_on_request)) {
2882 if (askchain(objlist, (one_by_one ? (char *) 0 : selection), allflag,
2883 actionfunc, checkfunc, 0, action))
2885 } else if (menu_on_request < 0) {
2886 used = (menu_loot(menu_on_request, put_in) > 0);
2891 /* loot current_container (take things out or put things in), using a menu */
2893 menu_loot(retry, put_in)
2897 int n, i, n_looted = 0;
2898 boolean all_categories = TRUE, loot_everything = FALSE;
2900 const char *action = put_in ? "Put in" : "Take out";
2901 struct obj *otmp, *otmp2;
2902 menu_item *pick_list;
2907 all_categories = (retry == -2);
2908 } else if (flags.menu_style == MENU_FULL) {
2909 all_categories = FALSE;
2910 Sprintf(buf, "%s what type of objects?", action);
2912 ? ALL_TYPES | BUC_ALLBKNOWN | BUC_UNKNOWN
2913 : ALL_TYPES | CHOOSE_ALL | BUC_ALLBKNOWN | BUC_UNKNOWN;
2914 n = query_category(buf, put_in ? invent : current_container->cobj,
2915 mflags, &pick_list, PICK_ANY);
2918 for (i = 0; i < n; i++) {
2919 if (pick_list[i].item.a_int == 'A')
2920 loot_everything = TRUE;
2921 else if (pick_list[i].item.a_int == ALL_TYPES_SELECTED)
2922 all_categories = TRUE;
2924 add_valid_menu_class(pick_list[i].item.a_int);
2926 free((genericptr_t) pick_list);
2929 if (loot_everything) {
2930 current_container->cknown = 1;
2931 for (otmp = current_container->cobj; otmp; otmp = otmp2) {
2933 res = out_container(otmp);
2938 mflags = INVORDER_SORT;
2939 if (put_in && flags.invlet_constant)
2940 mflags |= USE_INVLET;
2942 current_container->cknown = 1;
2943 Sprintf(buf, "%s what?", action);
2944 n = query_objlist(buf, put_in ? invent : current_container->cobj,
2945 mflags, &pick_list, PICK_ANY,
2946 all_categories ? allow_all : allow_category);
2949 for (i = 0; i < n; i++) {
2950 otmp = pick_list[i].item.a_obj;
2951 count = pick_list[i].count;
2952 if (count > 0 && count < otmp->quan) {
2953 otmp = splitobj(otmp, count);
2954 /* special split case also handled by askchain() */
2956 res = put_in ? in_container(otmp) : out_container(otmp);
2958 if (!current_container) {
2959 /* otmp caused current_container to explode;
2960 both are now gone */
2961 otmp = 0; /* and break loop */
2962 } else if (otmp && otmp != pick_list[i].item.a_obj) {
2963 /* split occurred, merge again */
2964 (void) merged(&pick_list[i].item.a_obj, &otmp);
2969 free((genericptr_t) pick_list);
2976 in_or_out_menu(prompt, obj, outokay, inokay, alreadyused)
2979 boolean outokay, inokay, alreadyused;
2981 /* underscore is not a choice; it's used to skip element [0] */
2982 static const char lootchars[] = "_:oibrsq", abc_chars[] = "_:abcdeq";
2985 menu_item *pick_list;
2988 const char *menuselector = flags.lootabc ? abc_chars : lootchars;
2991 win = create_nhwindow(NHW_MENU);
2994 any.a_int = 1; /* ':' */
2995 Sprintf(buf, "Look inside %s", thesimpleoname(obj));
2996 add_menu(win, NO_GLYPH, &any, menuselector[any.a_int], 0, ATR_NONE, buf,
2999 any.a_int = 2; /* 'o' */
3000 Sprintf(buf, "take %s out", something);
3001 add_menu(win, NO_GLYPH, &any, menuselector[any.a_int], 0, ATR_NONE,
3002 buf, MENU_UNSELECTED);
3005 any.a_int = 3; /* 'i' */
3006 Sprintf(buf, "put %s in", something);
3007 add_menu(win, NO_GLYPH, &any, menuselector[any.a_int], 0, ATR_NONE,
3008 buf, MENU_UNSELECTED);
3011 any.a_int = 4; /* 'b' */
3012 Sprintf(buf, "%stake out, then put in", inokay ? "both; " : "");
3013 add_menu(win, NO_GLYPH, &any, menuselector[any.a_int], 0, ATR_NONE,
3014 buf, MENU_UNSELECTED);
3017 any.a_int = 5; /* 'r' */
3018 Sprintf(buf, "%sput in, then take out",
3019 outokay ? "both reversed; " : "");
3020 add_menu(win, NO_GLYPH, &any, menuselector[any.a_int], 0, ATR_NONE,
3021 buf, MENU_UNSELECTED);
3022 any.a_int = 6; /* 's' */
3023 Sprintf(buf, "stash one item into %s", thesimpleoname(obj));
3024 add_menu(win, NO_GLYPH, &any, menuselector[any.a_int], 0, ATR_NONE,
3025 buf, MENU_UNSELECTED);
3027 any.a_int = 7; /* 'q' */
3028 Strcpy(buf, alreadyused ? "done" : "do nothing");
3029 add_menu(win, NO_GLYPH, &any, menuselector[any.a_int], 0, ATR_NONE, buf,
3032 end_menu(win, prompt);
3033 n = select_menu(win, PICK_ONE, &pick_list);
3034 destroy_nhwindow(win);
3036 n = pick_list[0].item.a_int;
3037 free((genericptr_t) pick_list);
3038 return lootchars[n]; /* :,o,i,b,r,s,q */
3040 return 'q'; /* quit */
3043 static const char tippables[] = { ALL_CLASSES, TOOL_CLASS, 0 };
3045 /* #tip command -- empty container contents onto floor */
3049 struct obj *cobj, *nobj;
3052 char c, buf[BUFSZ], qbuf[BUFSZ];
3053 const char *spillage = 0;
3056 * doesn't require free hands;
3057 * limbs are needed to tip floor containers
3060 /* at present, can only tip things at current spot, not adjacent ones */
3061 cc.x = u.ux, cc.y = u.uy;
3063 /* check floor container(s) first; at most one will be accessed */
3064 if ((boxes = container_at(cc.x, cc.y, TRUE)) > 0) {
3065 Sprintf(buf, "You can't tip %s while carrying so much.",
3066 !flags.verbose ? "a container" : (boxes > 1) ? "one" : "it");
3067 if (!check_capacity(buf) && able_to_loot(cc.x, cc.y, FALSE)) {
3068 if (boxes > 1 && (flags.menu_style != MENU_TRADITIONAL
3069 || iflags.menu_requested)) {
3070 /* use menu to pick a container to tip */
3074 menu_item *pick_list = NULL;
3075 struct obj dummyobj, *otmp;
3078 win = create_nhwindow(NHW_MENU);
3081 for (cobj = level.objects[cc.x][cc.y], i = 0; cobj;
3082 cobj = cobj->nexthere)
3083 if (Is_container(cobj)) {
3086 add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE,
3087 doname(cobj), MENU_UNSELECTED);
3091 add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE,
3092 "", MENU_UNSELECTED);
3093 any.a_obj = &dummyobj;
3094 /* use 'i' for inventory unless there are so many
3095 containers that it's already being used */
3096 i = (i <= 'i' - 'a' && !flags.lootabc) ? 'i' : 0;
3097 add_menu(win, NO_GLYPH, &any, i, 0, ATR_NONE,
3098 "tip something being carried", MENU_SELECTED);
3100 end_menu(win, "Tip which container?");
3101 n = select_menu(win, PICK_ONE, &pick_list);
3102 destroy_nhwindow(win);
3104 * Deal with quirk of preselected item in pick-one menu:
3105 * n == 0 => picked preselected entry, toggling it off;
3106 * n == 1 => accepted preselected choice via SPACE or RETURN;
3107 * n == 2 => picked something other than preselected entry;
3108 * n == -1 => cancelled via ESC;
3110 otmp = (n <= 0) ? (struct obj *) 0 : pick_list[0].item.a_obj;
3111 if (n > 1 && otmp == &dummyobj)
3112 otmp = pick_list[1].item.a_obj;
3114 free((genericptr_t) pick_list);
3115 if (otmp && otmp != &dummyobj) {
3121 /* else pick-from-invent below */
3123 for (cobj = level.objects[cc.x][cc.y]; cobj; cobj = nobj) {
3124 nobj = cobj->nexthere;
3125 if (!Is_container(cobj))
3127 c = ynq(safe_qbuf(qbuf, "There is ", " here, tip it?",
3129 doname, ansimpleoname, "container"));
3135 /* can only tip one container at a time */
3142 /* either no floor container(s) or couldn't tip one or didn't tip any */
3143 cobj = getobj(tippables, "tip");
3148 if (Is_container(cobj) || cobj->otyp == HORN_OF_PLENTY) {
3152 /* assorted other cases */
3153 if (Is_candle(cobj) && cobj->lamplit) {
3154 /* note "wax" even for tallow candles to avoid giving away info */
3156 } else if ((cobj->otyp == POT_OIL && cobj->lamplit)
3157 || (cobj->otyp == OIL_LAMP && cobj->age != 0L)
3158 || (cobj->otyp == MAGIC_LAMP && cobj->spe != 0)) {
3160 /* todo: reduce potion's remaining burn timer or oil lamp's fuel */
3161 } else if (cobj->otyp == CAN_OF_GREASE && cobj->spe > 0) {
3162 /* charged consumed below */
3163 spillage = "grease";
3164 } else if (cobj->otyp == FOOD_RATION || cobj->otyp == CRAM_RATION
3165 || cobj->otyp == LEMBAS_WAFER) {
3166 spillage = "crumbs";
3167 } else if (cobj->oclass == VENOM_CLASS) {
3172 if (is_pool(u.ux, u.uy))
3173 Sprintf(buf, " and gradually %s", vtense(spillage, "dissipate"));
3174 else if (is_lava(u.ux, u.uy))
3175 Sprintf(buf, " and immediately %s away",
3176 vtense(spillage, "burn"));
3177 pline("Some %s %s onto the %s%s.", spillage,
3178 vtense(spillage, "spill"), surface(u.ux, u.uy), buf);
3179 /* shop usage message comes after the spill message */
3180 if (cobj->otyp == CAN_OF_GREASE && cobj->spe > 0) {
3181 consume_obj_charge(cobj, TRUE);
3183 /* something [useless] happened */
3186 /* anything not covered yet */
3187 if (cobj->oclass == POTION_CLASS) /* can't pour potions... */
3188 pline_The("%s %s securely sealed.", xname(cobj), otense(cobj, "are"));
3189 else if (cobj->otyp == STATUE)
3191 pline("Nothing interesting happens.");
3193 pline("
\96Ê
\94\92\82¢
\82±
\82Æ
\82Í
\89½
\82à
\8bN
\82«
\82È
\82©
\82Á
\82½
\81D");
3195 pline1(nothing_happens);
3201 struct obj *box; /* or bag */
3203 xchar ox = u.ux, oy = u.uy; /* #tip only works at hero's location */
3204 boolean empty_it = FALSE,
3205 /* Shop handling: can't rely on the container's own unpaid
3206 or no_charge status because contents might differ with it.
3207 A carried container's contents will be flagged as unpaid
3208 or not, as appropriate, and need no special handling here.
3209 Items owned by the hero get sold to the shop without
3210 confirmation as with other uncontrolled drops. A floor
3211 container's contents will be marked no_charge if owned by
3212 hero, otherwise they're owned by the shop. By passing
3213 the contents through shop billing, they end up getting
3214 treated the same as in the carried case. We do so one
3215 item at a time instead of doing whole container at once
3216 to reduce the chance of exhausting shk's billing capacity. */
3217 maybeshopgoods = !carried(box) && costly_spot(ox, oy);
3219 /* caveat: this assumes that cknown, lknown, olocked, and otrapped
3220 fields haven't been overloaded to mean something special for the
3221 non-standard "container" horn of plenty */
3224 pline("It's locked.");
3225 } else if (box->otrapped) {
3226 /* we're not reaching inside but we're still handling it... */
3227 (void) chest_trap(box, HAND, FALSE);
3228 /* even if the trap fails, you've used up this turn */
3229 if (multi >= 0) { /* in case we didn't become paralyzed */
3231 multi_reason = "tipping a container";
3234 } else if (box->otyp == BAG_OF_TRICKS || box->otyp == HORN_OF_PLENTY) {
3235 boolean bag = box->otyp == BAG_OF_TRICKS;
3236 int old_spe = box->spe, seen = 0;
3238 if (maybeshopgoods && !box->no_charge)
3239 addtobill(box, FALSE, FALSE, TRUE);
3240 /* apply this bag/horn until empty or monster/object creation fails
3241 (if the latter occurs, force the former...) */
3243 if (!(bag ? bagotricks(box, TRUE, &seen)
3244 : hornoplenty(box, TRUE)))
3246 } while (box->spe > 0);
3248 if (box->spe < old_spe) {
3250 pline((seen == 0) ? "Nothing seems to happen."
3251 : (seen == 1) ? "A monster appears."
3252 : "Monsters appear!");
3253 /* check_unpaid wants to see a non-zero charge count */
3255 check_unpaid_usage(box, TRUE);
3256 box->spe = 0; /* empty */
3259 if (maybeshopgoods && !box->no_charge)
3260 subfrombill(box, shop_keeper(*in_rooms(ox, oy, SHOPBASE)));
3261 } else if (SchroedingersBox(box)) {
3262 char yourbuf[BUFSZ];
3264 observe_quantum_cat(box);
3265 if (!Has_contents(box)) /* evidently a live cat came out */
3266 /* container type of "large box" is inferred */
3267 pline("%sbox is now empty.", Shk_Your(yourbuf, box));
3268 else /* holds cat corpse or other random stuff */
3271 } else if (!Has_contents(box)) {
3273 pline("It's empty.");
3279 struct obj *otmp, *nobj;
3280 boolean verbose = FALSE, highdrop = !can_reach_floor(TRUE),
3281 altarizing = IS_ALTAR(levl[ox][oy].typ),
3282 cursed_mbag = (Is_mbag(box) && box->cursed);
3283 int held = carried(box);
3287 highdrop = altarizing = FALSE;
3290 box->cobj->nobj ? "Objects spill" : "An object spills",
3291 !(highdrop || altarizing) ? ':' : '.');
3292 for (otmp = box->cobj; otmp; otmp = nobj) {
3294 obj_extract_self(otmp);
3295 if (cursed_mbag && !rn2(13)) {
3296 loss += mbag_item_gone(held, otmp);
3297 /* abbreviated drop format is no longer appropriate */
3302 if (maybeshopgoods) {
3303 addtobill(otmp, FALSE, FALSE, TRUE);
3304 iflags.suppress_price++; /* doname formatting */
3308 /* might break or fall down stairs; handles altars itself */
3314 pline("%s %s to the %s.", Doname2(otmp),
3315 otense(otmp, "drop"), surface(ox, oy));
3317 pline("%s%c", doname(otmp), nobj ? ',' : '.');
3321 iflags.suppress_price--; /* reset */
3323 if (loss) /* magic bag lost some shop goods */
3324 You("owe %ld %s for lost merchandise.", loss, currency(loss));
3325 box->owt = weight(box); /* mbag_item_gone() doesn't update this */
3327 (void) encumber_msg();