Source:SLASH'EM 0.0.7E7F2/pickup.c

Below is the full text to pickup.c from the source code of SLASH'EM 0.0.7E7F2. To link to a particular line, write [[SLASH'EM 0.0.7E7F2/pickup.c#line123 ]], for example.

The latest source code for vanilla NetHack is at Source code.

1.   /*	SCCS Id: @(#)pickup.c	3.4	2003/07/27	*/ 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.  STATIC_DCL void FDECL(simple_look, (struct obj *,BOOLEAN_P)); 12.  #ifndef GOLDOBJ 13.  STATIC_DCL boolean FDECL(query_classes, (char *,boolean *,boolean *, 14.  		const char *,struct obj *,BOOLEAN_P,BOOLEAN_P,int *)); 15.  #else 16.  STATIC_DCL boolean FDECL(query_classes, (char *,boolean *,boolean *, 17.  		const char *,struct obj *,BOOLEAN_P,int *)); 18.  #endif 19.  STATIC_DCL void FDECL(check_here, (BOOLEAN_P)); 20.  STATIC_DCL boolean FDECL(n_or_more, (struct obj *)); 21.  STATIC_DCL boolean FDECL(all_but_uchain, (struct obj *)); 22.  #if 0 /* not used */ 23.  STATIC_DCL boolean FDECL(allow_cat_no_uchain, (struct obj *)); 24.  #endif 25.  STATIC_DCL int FDECL(autopick, (struct obj*, int, menu_item **)); 26.  STATIC_DCL int FDECL(count_categories, (struct obj *,int)); 27.  STATIC_DCL long FDECL(carry_count,  28.   		      (struct obj *,struct obj *,long,BOOLEAN_P,int *,int *)); 29.  STATIC_DCL int FDECL(lift_object, (struct obj *,struct obj *,long *,BOOLEAN_P)); 30.  STATIC_PTR int FDECL(in_container,(struct obj *)); 31.  STATIC_PTR int FDECL(ck_bag,(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 int FDECL(menu_loot, (int, struct obj *, BOOLEAN_P)); 36.  STATIC_DCL int FDECL(in_or_out_menu, (const char *,struct obj *, BOOLEAN_P, BOOLEAN_P)); 37.  STATIC_DCL int FDECL(container_at, (int, int, BOOLEAN_P)); 38.  STATIC_DCL boolean FDECL(able_to_loot, (int, int)); 39.  STATIC_DCL boolean FDECL(mon_beside, (int, int)); 40.   41.   /* define for query_objlist and autopickup */ 42.  #define FOLLOW(curr, flags) \ 43.      (((flags) & BY_NEXTHERE) ? (curr)->nexthere : (curr)->nobj) 44.   45.   #define CEILDIV(x,y)	(((x)+(y)-1)/(y))	/* ceil(x/y) */ 46.  /*  47.    *  How much the weight of the given container will change when the given 48.   *  object is removed from it. This calculation must match the one used 49.   *  by weight in mkobj.c.  50. */ 51.   #define DELTA_CWT(cont,obj)		\ 52.      ((cont)->cursed ? (obj)->owt * ((cont)->oartifact ? 4 : 2) :	\ 53.      CEILDIV((obj)->owt, ((cont)->oartifact ? 3 : 2) * ((cont)->blessed ? 2 : 1))) 54.  #define GOLD_WT(n)		(((n) + 50L) / 100L) 55.  /* if you can figure this out, give yourself a hearty pat on the back... */ 56.   #define GOLD_CAPACITY(w,n)	(((w) * -100L) - ((n) + 50L) - 1L) 57.   58.   /* A variable set in use_container, to be used by the callback routines  */ 59.  /* in_container and out_container from askchain and use_container. */ 60.   /* Also used by memu_loot and container_gone. */ 61.   static NEARDATA struct obj *current_container; 62.  #define Icebox (current_container->otyp == ICE_BOX) 63.   64.   static const char moderateloadmsg[] = "You have a little trouble lifting"; 65.  static const char nearloadmsg[] = "You have much trouble lifting"; 66.  static const char overloadmsg[] = "You have extreme difficulty lifting"; 67.   68.   /* BUG: this lets you look at cockatrice corpses while blind without 69.     touching them */ 70.  /* much simpler version of the look-here code; used by query_classes */ 71.  STATIC_OVL void 72.  simple_look(otmp, here) 73.  struct obj *otmp;	/* list of objects */ 74.  boolean here;		/* flag for type of obj list linkage */ 75.  {  76.   	/* Neither of the first two cases is expected to happen, since 77.  	 * we're only called after multiple classes of objects have been 78.  	 * detected, hence multiple objects must be present. 79.  	 */  80.   	if (!otmp) { 81.  	    impossible("simple_look(null)"); 82.  	} else if (!(here ? otmp->nexthere : otmp->nobj)) { 83.  	    pline("%s", doname(otmp)); 84.  	} else { 85.  	    winid tmpwin = create_nhwindow(NHW_MENU); 86.  	    putstr(tmpwin, 0, ""); 87.  	    do { 88.  		putstr(tmpwin, 0, doname(otmp)); 89.  		otmp = here ? otmp->nexthere : otmp->nobj; 90.  	    } while (otmp); 91.  	    display_nhwindow(tmpwin, TRUE); 92.  	    destroy_nhwindow(tmpwin); 93.  	}  94.   }  95.    96.   #ifndef GOLDOBJ 97.  int 98.  collect_obj_classes(ilets, otmp, here, incl_gold, filter, itemcount) 99.  char ilets[]; 100. register struct obj *otmp; 101. boolean here, incl_gold; 102. boolean FDECL((*filter),(OBJ_P)); 103. int *itemcount; 104. #else 105. int 106. collect_obj_classes(ilets, otmp, here, filter, itemcount) 107. char ilets[]; 108. register struct obj *otmp; 109. boolean here; 110. boolean FDECL((*filter),(OBJ_P)); 111. int *itemcount; 112. #endif 113. {  114.  	register int iletct = 0; 115. 	register char c;  116. 117. 	*itemcount = 0; 118. #ifndef GOLDOBJ 119. 	if (incl_gold) 120. 	    ilets[iletct++] = def_oc_syms[COIN_CLASS]; 121. #endif 122. 	ilets[iletct] = '\0'; /* terminate ilets so that index will work */ 123. 	while (otmp) { 124. 	    c = def_oc_syms[(int)otmp->oclass]; 125. 	    if (!index(ilets, c) && (!filter || (*filter)(otmp))) 126. 		ilets[iletct++] = c,  ilets[iletct] = '\0'; 127. 	    *itemcount += 1; 128. 	    otmp = here ? otmp->nexthere : otmp->nobj; 129. 	}  130.   131.  	return iletct; 132. }  133.   134.  /*  135.   * Suppose some '?' and '!' objects are present, but '/' objects aren't:  136. *	"a" picks all items without further prompting; 137.  *	"A" steps through all items, asking one by one; 138.  *	"?" steps through '?' items, asking, and ignores '!' ones; 139.  *	"/" becomes 'A', since no '/' present; 140.  *	"?a" or "a?" picks all '?' without further prompting; 141.  *	"/a" or "a/" becomes 'A' since there aren't any '/' 142.  *	    (bug fix:  3.1.0 thru 3.1.3 treated it as "a"); 143.  *	"?/a" or "a?/" or "/a?",&c picks all '?' even though no '/' 144.  *	    (ie, treated as if it had just been "?a"). 145.  */  146.  #ifndef GOLDOBJ 147. STATIC_OVL boolean 148. query_classes(oclasses, one_at_a_time, everything, action, objs,  149.  	      here, incl_gold, menu_on_demand) 150. char oclasses[]; 151. boolean *one_at_a_time, *everything; 152. const char *action; 153. struct obj *objs; 154. boolean here, incl_gold; 155. int *menu_on_demand; 156. #else 157. STATIC_OVL boolean 158. query_classes(oclasses, one_at_a_time, everything, action, objs,  159.  	      here, menu_on_demand) 160. char oclasses[]; 161. boolean *one_at_a_time, *everything; 162. const char *action; 163. struct obj *objs; 164. boolean here; 165. int *menu_on_demand; 166. #endif 167. {  168.  	char ilets[20], inbuf[BUFSZ]; 169. 	int iletct, oclassct; 170. 	boolean not_everything; 171. 	char qbuf[QBUFSZ]; 172. 	boolean m_seen; 173. 	int itemcount; 174.  175.  	oclasses[oclassct = 0] = '\0'; 176. 	*one_at_a_time = *everything = m_seen = FALSE; 177. 	iletct = collect_obj_classes(ilets, objs, here,  178.  #ifndef GOLDOBJ  179.  				     incl_gold,  180.  #endif  181.  				     (boolean FDECL((*),(OBJ_P))) 0, &itemcount); 182. 	if (iletct == 0) { 183. 		return FALSE; 184. 	} else if (iletct == 1) { 185. 		oclasses[0] = def_char_to_objclass(ilets[0]); 186. 		oclasses[1] = '\0'; 187. 		if (itemcount && menu_on_demand) { 188. 			ilets[iletct++] = 'm'; 189. 			*menu_on_demand = 0; 190. 			ilets[iletct] = '\0'; 191. 		}  192.  	} else  {	/* more than one choice available */ 193. 		const char *where = 0; 194. 		register char sym, oc_of_sym, *p; 195. 		/* additional choices */ 196. 		ilets[iletct++] = ' '; 197. 		ilets[iletct++] = 'a'; 198. 		ilets[iletct++] = 'A'; 199. 		ilets[iletct++] = (objs == invent ? 'i' : ':'); 200. 		if (menu_on_demand) { 201. 			ilets[iletct++] = 'm'; 202. 			*menu_on_demand = 0; 203. 		}  204.  		ilets[iletct] = '\0'; 205. ask_again: 206. 		oclasses[oclassct = 0] = '\0'; 207. 		*one_at_a_time = *everything = FALSE; 208. 		not_everything = FALSE; 209. 		Sprintf(qbuf,"What kinds of thing do you want to %s? [%s]",  210.  			action, ilets); 211. 		getlin(qbuf,inbuf); 212. 		if (*inbuf == '\033') return FALSE; 213.  214.  		for (p = inbuf; (sym = *p++); ) { 215. 		    /* new A function (selective all) added by GAN 01/09/87 */ 216. 		    if (sym == ' ') continue; 217. 		    else if (sym == 'A') *one_at_a_time = TRUE; 218. 		    else if (sym == 'a') *everything = TRUE; 219. 		    else if (sym == ':') { 220. 			simple_look(objs, here);  /* dumb if objs==invent */ 221. 			goto ask_again; 222. 		    } else if (sym == 'i') { 223. 			(void) display_inventory((char *)0, TRUE); 224. 			goto ask_again; 225. 		    } else if (sym == 'm') { 226. 			m_seen = TRUE; 227. 		    } else { 228. 			oc_of_sym = def_char_to_objclass(sym); 229. 			if (index(ilets,sym)) { 230. 			    add_valid_menu_class(oc_of_sym); 231. 			    oclasses[oclassct++] = oc_of_sym; 232. 			    oclasses[oclassct] = '\0'; 233. 			} else { 234. 			    if (!where) 235. 				where = !strcmp(action,"pick up")  ? "here" : 236. 					!strcmp(action,"take out") ? 237. 							    "inside" : ""; 238. 			    if (*where) 239. 				There("are no %c's %s.", sym, where); 240. 			    else 241. 				You("have no %c's.", sym); 242. 			    not_everything = TRUE; 243. 			}  244.  		    }  245.  		}  246.  		if (m_seen && menu_on_demand) { 247. 			*menu_on_demand = (*everything || !oclassct) ? -2 : -3; 248.  			return FALSE; 249. 		}  250.  		if (!oclassct && (!*everything || not_everything)) { 251. 		    /* didn't pick anything, 252. 		       or tried to pick something that's not present */ 253. 		    *one_at_a_time = TRUE;	/* force 'A' */ 254. 		    *everything = FALSE;	/* inhibit 'a' */ 255. 		}  256.  	}  257.  	return TRUE; 258. }  259.   260.  /* look at the objects at our location, unless there are too many of them */ 261. STATIC_OVL void 262. check_here(picked_some) 263. boolean picked_some; 264. {  265.  	register struct obj *obj; 266. 	register int ct = 0; 267.  268.  	/* count the objects here */ 269. 	for (obj = level.objects[u.ux][u.uy]; obj; obj = obj->nexthere) { 270. 	    if (obj != uchain) 271. 		ct++; 272. 	}  273.   274.  	/* If there are objects here, take a look. */ 275.  	if (ct) { 276. 	    if (flags.run) nomul(0); 277. 	    flush_screen(1); 278. 	    (void) look_here(ct, picked_some); 279. 	} else { 280. 	    sense_engr_at(u.ux, u.uy, FALSE); 281. 	}  282.  }  283.   284.  /* Value set by query_objlist for n_or_more. */ 285.  static long val_for_n_or_more; 286.  287.  /* query_objlist callback: return TRUE if obj's count is >= reference value */ 288. STATIC_OVL boolean 289. n_or_more(obj) 290. struct obj *obj; 291. {  292.      if (obj == uchain) return FALSE; 293.     return (obj->quan >= val_for_n_or_more); 294. }  295.   296.  /* List of valid menu classes for query_objlist and allow_category callback */ 297. static char valid_menu_classes[MAXOCLASSES + 2]; 298.  299.  void 300. add_valid_menu_class(c) 301. int c;  302. { 303.  	static int vmc_count = 0; 304.  305.  	if (c == 0)  /* reset */ 306. 	  vmc_count = 0; 307. 	else 308. 	  valid_menu_classes[vmc_count++] = (char)c; 309. 	valid_menu_classes[vmc_count] = '\0'; 310. }  311.   312.  /* query_objlist callback: return TRUE if not uchain */ 313. STATIC_OVL boolean 314. all_but_uchain(obj) 315. struct obj *obj; 316. {  317.      return (obj != uchain); 318. }  319.   320.  /* query_objlist callback: return TRUE */ 321. /*ARGSUSED*/ 322. boolean 323. allow_all(obj) 324. struct obj *obj; 325. {  326.      return TRUE; 327. }  328.   329.  boolean 330. allow_category(obj) 331. struct obj *obj; 332. {  333.      if (Role_if(PM_PRIEST)) obj->bknown = TRUE; 334.     if (((index(valid_menu_classes,'u') != (char *)0) && obj->unpaid) ||  335.  	(index(valid_menu_classes, obj->oclass) != (char *)0)) 336. 	return TRUE; 337.     else if (((index(valid_menu_classes,'U') != (char *)0) && 338. 	(obj->oclass != COIN_CLASS && obj->bknown && !obj->blessed && !obj->cursed))) 339. 	return TRUE; 340.     else if (((index(valid_menu_classes,'B') != (char *)0) && 341. 	(obj->oclass != COIN_CLASS && obj->bknown && obj->blessed))) 342. 	return TRUE; 343.     else if (((index(valid_menu_classes,'C') != (char *)0) && 344. 	(obj->oclass != COIN_CLASS && obj->bknown && obj->cursed))) 345. 	return TRUE; 346.     else if (((index(valid_menu_classes,'X') != (char *)0) && 347. 	(obj->oclass != COIN_CLASS && !obj->bknown))) 348. 	return TRUE; 349.     else 350. 	return FALSE; 351. }  352.   353.  #if 0 /* not used */ 354. /* query_objlist callback: return TRUE if valid category (class), no uchain */ 355. STATIC_OVL boolean 356. allow_cat_no_uchain(obj) 357. struct obj *obj; 358. {  359.      if ((obj != uchain) &&  360.  	(((index(valid_menu_classes,'u') != (char *)0) && obj->unpaid) || 361. 	(index(valid_menu_classes, obj->oclass) != (char *)0))) 362. 	return TRUE; 363.     else 364. 	return FALSE; 365. }  366.  #endif 367.  368.  /* query_objlist callback: return TRUE if valid class and worn */ 369. boolean 370. is_worn_by_type(otmp) 371. register struct obj *otmp; 372. {  373.  	return((boolean)(!!(otmp->owornmask &  374.  			(W_ARMOR | W_RING | W_AMUL | W_TOOL | W_WEP | W_SWAPWEP | W_QUIVER)))  375.  	        && (index(valid_menu_classes, otmp->oclass) != (char *)0)); 376. }  377.   378.  /*  379.   * Have the hero pick things from the ground 380.  * or a monster's inventory if swallowed. 381.  *  382.   * Arg what: 383.  *	>0  autopickup 384.  *	=0  interactive 385.  *	<0  pickup count of something 386.  *  387.   * Returns 1 if tried to pick something up, whether 388.  * or not it succeeded. 389.  */  390.  int 391. pickup(what) 392. int what;		/* should be a long */ 393. {  394.  	int i, n, res, count, n_tried = 0, n_picked = 0; 395. 	menu_item *pick_list = (menu_item *) 0; 396. 	boolean autopickup = what > 0; 397. 	struct obj *objchain; 398. 	int traverse_how; 399.  400.  	if (what < 0)		/* pick N of something */ 401. 	    count = -what; 402. 	else			/* pick anything */ 403. 	    count = 0; 404.  405.  	if (!u.uswallow) { 406. 		struct trap *ttmp = t_at(u.ux, u.uy); 407. 		/* no auto-pick if no-pick move, nothing there, or in a pool */ 408. 		if (autopickup && (flags.nopick || !OBJ_AT(u.ux, u.uy) || 409. 			(is_pool(u.ux, u.uy) && !Underwater) || is_lava(u.ux, u.uy))) { 410. 			sense_engr_at(u.ux, u.uy, FALSE); 411. 			return (0); 412. 		}  413.   414.  		/* no pickup if levitating & not on air or water level */ 415. 		if (!can_reach_floor) { 416. 		    if ((multi && !flags.run) || (autopickup && !flags.pickup)) 417. 			sense_engr_at(u.ux, u.uy, FALSE); 418. 		    return (0); 419. 		}  420.  		if (ttmp && ttmp->tseen) { 421. 		    /* Allow pickup from holes and trap doors that you escaped 422. 		     * from because that stuff is teetering on the edge just 423. 		     * like you, but not pits, because there is an elevation 424. 		     * discrepancy with stuff in pits. 425. 		     */  426.  		    if ((ttmp->ttyp == PIT || ttmp->ttyp == SPIKED_PIT) &&  427.  			(!u.utrap || (u.utrap && u.utraptype != TT_PIT))) { 428. 			sense_engr_at(u.ux, u.uy, FALSE); 429. 			return(0); 430. 		    }  431.  		}  432.  		/* multi && !flags.run means they are in the middle of some other 433. 		 * action, or possibly paralyzed, sleeping, etc.... and they just 434. 		 * teleported onto the object. They shouldn't pick it up. 435. 		 */  436.  		if ((multi && !flags.run) || (autopickup && !flags.pickup)) { 437. 		    check_here(FALSE); 438. 		    return (0); 439. 		}  440.  		if (notake(youmonst.data)) { 441. 		    if (!autopickup) 442. 			You("are physically incapable of picking anything up."); 443. 		    else 444. 			check_here(FALSE); 445. 		    return (0); 446. 		}  447.   448.  		/* if there's anything here, stop running */ 449. 		if (OBJ_AT(u.ux,u.uy) && flags.run && flags.run != 8 && !flags.nopick) nomul(0); 450. 	}  451.   452.  	add_valid_menu_class(0);	/* reset */ 453. 	if (!u.uswallow) { 454. 		objchain = level.objects[u.ux][u.uy]; 455. 		traverse_how = BY_NEXTHERE; 456. 	} else { 457. 		objchain = u.ustuck->minvent; 458. 		traverse_how = 0;	/* nobj */ 459. 	}  460.  	/*  461.  	 * Start the actual pickup process. This is split into two main 462. 	 * sections, the newer menu and the older "traditional" methods. 463. 	 * Automatic pickup has been split into its own menu-style routine 464. 	 * to make things less confusing. 465. 	 */  466.  	if (autopickup) { 467. 	    n = autopick(objchain, traverse_how, &pick_list); 468. 	    goto menu_pickup; 469. 	}  470.   471.  	if (flags.menu_style != MENU_TRADITIONAL || iflags.menu_requested) { 472.  473.  	    /* use menus exclusively */ 474. 	    if (count) {	/* looking for N of something */ 475. 		char buf[QBUFSZ]; 476. 		Sprintf(buf, "Pick %d of what?", count); 477. 		val_for_n_or_more = count;	/* set up callback selector */ 478. 		n = query_objlist(buf, objchain,  479.  			    traverse_how|AUTOSELECT_SINGLE|INVORDER_SORT,  480.  			    &pick_list, PICK_ONE, n_or_more); 481. 		/* correct counts, if any given */ 482. 		for (i = 0; i < n; i++) 483. 		    pick_list[i].count = count; 484. 	    } else { 485. 		n = query_objlist("Pick up what?", objchain,  486.  			traverse_how|AUTOSELECT_SINGLE|INVORDER_SORT|FEEL_COCKATRICE,  487.  			&pick_list, PICK_ANY, all_but_uchain); 488. 	    }  489.  menu_pickup: 490. 	    n_tried = n;  491. for (n_picked = i = 0 ; i < n; i++) { 492. 		res = pickup_object(pick_list[i].item.a_obj,pick_list[i].count,  493.  					FALSE); 494. 		if (res < 0) break;	/* can't continue */ 495. 		n_picked += res; 496. 	    }  497.  	    if (pick_list) free((genericptr_t)pick_list); 498.  499.  	} else { 500. 	    /* old style interface */ 501. 	    int ct = 0; 502. 	    long lcount; 503. 	    boolean all_of_a_type, selective; 504. 	    char oclasses[MAXOCLASSES]; 505. 	    struct obj *obj, *obj2; 506.  507.  	    oclasses[0] = '\0';		/* types to consider (empty for all) */ 508. 	    all_of_a_type = TRUE;	/* take all of considered types */ 509. 	    selective = FALSE;		/* ask for each item */ 510.  511.  	    /* check for more than one object */ 512. 	    for (obj = objchain;  513.  		  obj; obj = (traverse_how == BY_NEXTHERE) ? obj->nexthere : obj->nobj) 514. 		ct++; 515.  516.  	    if (ct == 1 && count) { 517. 		/* if only one thing, then pick it */ 518. 		obj = objchain; 519. 		lcount = min(obj->quan, (long)count); 520. 		n_tried++; 521. 		if (pickup_object(obj, lcount, FALSE) > 0) 522. 		    n_picked++;	/* picked something */ 523. 		goto end_query; 524.  525.  	    } else if (ct >= 2) { 526. 		int via_menu = 0; 527.  528.  		There("are %s objects here.",  529.  		      (ct <= 10) ? "several" : "many"); 530. 		if (!query_classes(oclasses, &selective, &all_of_a_type, 531. 				   "pick up", objchain, 532. 				   traverse_how == BY_NEXTHERE, 533. #ifndef GOLDOBJ 534. 				   FALSE, 535. #endif 536. 				   &via_menu)) { 537. 		    if (!via_menu) return (0); 538. 		    n = query_objlist("Pick up what?",  539.  				  objchain,  540.  				  traverse_how|(selective ? 0 : INVORDER_SORT), 541.  				  &pick_list, PICK_ANY,  542.  				  via_menu == -2 ? allow_all : allow_category); 543. 		    goto menu_pickup; 544. 		}  545.  	    }  546.   547.  	    for (obj = objchain; obj; obj = obj2) { 548. 		if (traverse_how == BY_NEXTHERE) 549. 			obj2 = obj->nexthere;	/* perhaps obj will be picked up */ 550. 		else 551. 			obj2 = obj->nobj; 552. 		lcount = -1L; 553.  554.  		if (!selective && oclasses[0] && !index(oclasses,obj->oclass)) 555. 		    continue; 556.  557.  		if (!all_of_a_type) { 558. 		    char qbuf[BUFSZ]; 559. 		    Sprintf(qbuf, "Pick up %s?",  560.  			safe_qbuf("", sizeof("Pick up ?"), doname(obj), 561. 					an(simple_typename(obj->otyp)), "something")); 562. 		    switch ((obj->quan < 2L) ? ynaq(qbuf) : ynNaq(qbuf)) { 563. 		    case 'q': goto end_query;	/* out 2 levels */ 564. 		    case 'n': continue; 565. 		    case 'a': 566. 			all_of_a_type = TRUE; 567. 			if (selective) { 568. 			    selective = FALSE; 569. 			    oclasses[0] = obj->oclass; 570. 			    oclasses[1] = '\0'; 571. 			}  572.  			break; 573. 		    case '#':	/* count was entered */ 574. 			if (!yn_number) continue; /* 0 count => No */ 575. 			lcount = (long) yn_number; 576. 			if (lcount > obj->quan) lcount = obj->quan; 577. 			/* fall thru */ 578. 		    default:	/* 'y' */ 579. 			break; 580. 		    }  581.  		}  582.  		if (lcount == -1L) lcount = obj->quan; 583.  584.  		n_tried++; 585. 		if ((res = pickup_object(obj, lcount, FALSE)) < 0) break; 586. 		n_picked += res; 587. 	    }  588.  end_query: 589. 	    ;	/* semicolon needed by brain-damaged compilers */ 590. 	}  591.   592.  	if (!u.uswallow) { 593. 		if (!OBJ_AT(u.ux,u.uy)) u.uundetected = 0; 594.  595.  		/* position may need updating (invisible hero) */ 596. 		if (n_picked) newsym(u.ux,u.uy); 597.  598.  		/* see whether there's anything else here, after auto-pickup is done */ 599. 		if (autopickup) check_here(n_picked > 0); 600. 	}  601.  	return (n_tried > 0); 602. }  603.   604.  #ifdef AUTOPICKUP_EXCEPTIONS 605. boolean 606. is_autopickup_exception(obj, grab) 607. struct obj *obj; 608. boolean grab;	 /* forced pickup, rather than forced leave behind? */ 609.  {  610.  	/*  611.  	 *  Does the text description of this match an exception? 612. 	 */  613.  	char *objdesc = makesingular(doname(obj)); 614. 	struct autopickup_exception *ape = (grab) ? 615. 					iflags.autopickup_exceptions[AP_GRAB] : 616. 					iflags.autopickup_exceptions[AP_LEAVE]; 617. 	while (ape) { 618. 		if (pmatch(ape->pattern, objdesc)) return TRUE; 619. 		ape = ape->next; 620. 	}  621.  	return FALSE; 622. }  623.  #endif /* AUTOPICKUP_EXCEPTIONS */ 624.  625.  /*  626.   * Pick from the given list using flags.pickup_types. Return the number 627.  * of items picked (not counts). Create an array that returns pointers 628.  * and counts of the items to be picked up. If the number of items 629.  * picked is zero, the pickup list is left alone. The caller of this 630.  * function must free the pickup list. 631.  */  632.  STATIC_OVL int 633. autopick(olist, follow, pick_list) 634. struct obj *olist;	/* the object list */ 635. int follow;		/* how to follow the object list */ 636. menu_item **pick_list;	/* list of objects and counts to pick up */ 637. {  638.  	menu_item *pi;	/* pick item */ 639. 	struct obj *curr; 640. 	int n;  641. const char *otypes = flags.pickup_types; 642.  643.  	/* first count the number of eligible items */ 644. 	for (n = 0, curr = olist; curr; curr = FOLLOW(curr, follow)) 645.  646.   647.  #ifndef AUTOPICKUP_EXCEPTIONS 648. 	    if (!*otypes || index(otypes, curr->oclass) ||  649.  		flags.pickup_thrown && curr->was_thrown) 650. #else 651. 	    if ((!*otypes || index(otypes, curr->oclass) || 652. 		flags.pickup_thrown && curr->was_thrown || 653. 		is_autopickup_exception(curr, TRUE)) &&  654.  		!is_autopickup_exception(curr, FALSE)) 655. #endif 656. 		n++; 657.  658.  	if (n) { 659. 	    *pick_list = pi = (menu_item *) alloc(sizeof(menu_item) * n); 660. 	    for (n = 0, curr = olist; curr; curr = FOLLOW(curr, follow)) 661. #ifndef AUTOPICKUP_EXCEPTIONS 662. 		if (!*otypes || index(otypes, curr->oclass) ||  663.  			flags.pickup_thrown && curr->was_thrown) { 664. #else 665. 		if ((!*otypes || index(otypes, curr->oclass) || 666. 			flags.pickup_thrown && curr->was_thrown || 667. 			is_autopickup_exception(curr, TRUE)) &&  668.  			!is_autopickup_exception(curr, FALSE)) { 669. #endif 670. 		    pi[n].item.a_obj = curr; 671. 		    pi[n].count = curr->quan; 672. 		    n++; 673. 		}  674.  	}  675.  	return n;  676. } 677.   678.   679.  /*  680.   * Put up a menu using the given object list. Only those objects on the 681.  * list that meet the approval of the allow function are displayed. Return 682.  * a count of the number of items selected, as well as an allocated array of  683. * menu_items, containing pointers to the objects selected and counts. The 684.  * returned counts are guaranteed to be in bounds and non-zero. 685.  *  686.   * Query flags: 687.  *	BY_NEXTHERE	  - Follow object list via nexthere instead of nobj. 688.  *	AUTOSELECT_SINGLE - Don't ask if only 1 object qualifies - just 689.  *			    use it. 690.  *	USE_INVLET	  - Use object's invlet. 691.  *	INVORDER_SORT	  - Use hero's pack order. 692.  *	SIGNAL_NOMENU	  - Return -1 rather than 0 if nothing passes "allow". 693.  *	SIGNAL_CANCEL	  - Return -2 rather than 0 if player cancels. 694.  */  695.  int 696. query_objlist(qstr, olist, qflags, pick_list, how, allow) 697. const char *qstr;		/* query string */ 698. struct obj *olist;		/* the list to pick from */ 699. int qflags;			/* options to control the query */ 700. menu_item **pick_list;		/* return list of items picked */ 701. int how;			/* type of query */ 702. boolean FDECL((*allow), (OBJ_P));/* allow function */ 703. {  704.  	int n;  705. winid win; 706. 	struct obj *curr, *last; 707. 	char *pack; 708. 	anything any; 709. 	boolean printed_type_name; 710.  711.  	*pick_list = (menu_item *) 0; 712. 	if (!olist) return 0; 713.  714.  	/* count the number of items allowed */ 715. 	for (n = 0, last = 0, curr = olist; curr; curr = FOLLOW(curr, qflags)) 716. 	    if ((*allow)(curr)) { 717. 		last = curr; 718. 		n++; 719. 	    }  720.   721.  	if (n == 0)	/* nothing to pick here */ 722. 	    return (qflags & SIGNAL_NOMENU) ? -1 : 0; 723.   724.  	if (n == 1 && (qflags & AUTOSELECT_SINGLE)) { 725. 	    *pick_list = (menu_item *) alloc(sizeof(menu_item)); 726. 	    (*pick_list)->item.a_obj = last; 727. 	    (*pick_list)->count = last->quan; 728. 	    return 1; 729. 	}  730.   731.  	win = create_nhwindow(NHW_MENU); 732. 	start_menu(win); 733. 	any.a_obj = (struct obj *) 0; 734.  735.  	/*  736.  	 * Run through the list and add the objects to the menu. If 737. * INVORDER_SORT is set, we'll run through the list once for 738. 	 * each type so we can group them. The allow function will only 739. 	 * be called once per object in the list. 740. 	 */  741.  	pack = flags.inv_order; 742. 	do { 743. 	    printed_type_name = FALSE; 744. 	    for (curr = olist; curr; curr = FOLLOW(curr, qflags)) { 745. 		if ((qflags & FEEL_COCKATRICE) && curr->otyp == CORPSE &&  746.  		     will_feel_cockatrice(curr, FALSE)) { 747. 			destroy_nhwindow(win);	/* stop the menu and revert */ 748. 			(void) look_here(0, FALSE); 749. 			return 0; 750. 		}  751.  		if ((!(qflags & INVORDER_SORT) || curr->oclass == *pack)  752.  							&& (*allow)(curr)) { 753.  754.  		    /* if sorting, print type name (once only) */ 755. 		    if (qflags & INVORDER_SORT && !printed_type_name) { 756. 			any.a_obj = (struct obj *) 0; 757. 			add_menu(win, NO_GLYPH, &any, 0, 0, iflags.menu_headings,  758.  					let_to_name(*pack, FALSE), MENU_UNSELECTED); 759. 			printed_type_name = TRUE; 760. 		    }  761.   762.  		    any.a_obj = curr; 763. 		    add_menu(win, obj_to_glyph(curr), &any,  764.  			    qflags & USE_INVLET ? curr->invlet : 0,  765.  			    def_oc_syms[(int)objects[curr->otyp].oc_class],  766.  			    ATR_NONE, doname(curr), MENU_UNSELECTED); 767. 		}  768.  	    }  769.  	    pack++; 770. 	} while (qflags & INVORDER_SORT && *pack); 771.  772.  	end_menu(win, qstr); 773. 	n = select_menu(win, how, pick_list); 774. 	destroy_nhwindow(win); 775.  776.  	if (n > 0) { 777. 	    menu_item *mi; 778. 	    int i;  779. 780. 	    /* fix up counts:  -1 means no count used => pick all */ 781. 	    for (i = 0, mi = *pick_list; i < n; i++, mi++) 782. 		if (mi->count == -1L || mi->count > mi->item.a_obj->quan) 783. 		    mi->count = mi->item.a_obj->quan; 784. 	} else if (n < 0) { 785. 	    /* caller's don't expect -1 */ 786. 	    n = (qflags & SIGNAL_CANCEL) ? -2 : 0; 787.  	}  788.  	return n;  789. } 790.   791.  /*  792.   * allow menu-based category (class) selection (for Drop,take off etc.) 793.  *  794.   */  795.  int 796. query_category(qstr, olist, qflags, pick_list, how) 797. const char *qstr;		/* query string */ 798. struct obj *olist;		/* the list to pick from */ 799. int qflags;			/* behaviour modification flags */ 800. menu_item **pick_list;		/* return list of items picked */ 801. int how;			/* type of query */ 802. {  803.  	int n;  804. winid win; 805. 	struct obj *curr; 806. 	char *pack; 807. 	anything any; 808. 	boolean collected_type_name; 809. 	char invlet; 810. 	int ccount; 811. 	boolean do_unpaid = FALSE; 812. 	boolean do_blessed = FALSE, do_cursed = FALSE, do_uncursed = FALSE, 813. 	    do_buc_unknown = FALSE; 814. 	int num_buc_types = 0; 815.  816.  	*pick_list = (menu_item *) 0; 817. 	if (!olist) return 0; 818. 	if ((qflags & UNPAID_TYPES) && count_unpaid(olist)) do_unpaid = TRUE; 819. 	if ((qflags & BUC_BLESSED) && count_buc(olist, BUC_BLESSED)) { 820. 	    do_blessed = TRUE; 821. 	    num_buc_types++; 822. 	}  823.  	if ((qflags & BUC_CURSED) && count_buc(olist, BUC_CURSED)) { 824. 	    do_cursed = TRUE; 825. 	    num_buc_types++; 826. 	}  827.  	if ((qflags & BUC_UNCURSED) && count_buc(olist, BUC_UNCURSED)) { 828. 	    do_uncursed = TRUE; 829. 	    num_buc_types++; 830. 	}  831.  	if ((qflags & BUC_UNKNOWN) && count_buc(olist, BUC_UNKNOWN)) { 832. 	    do_buc_unknown = TRUE; 833. 	    num_buc_types++; 834. 	}  835.   836.  	ccount = count_categories(olist, qflags); 837. 	/* no point in actually showing a menu for a single category */ 838. 	if (ccount == 1 && !do_unpaid && num_buc_types <= 1 && !(qflags & BILLED_TYPES)) { 839. 	    for (curr = olist; curr; curr = FOLLOW(curr, qflags)) { 840. 		if ((qflags & WORN_TYPES) &&  841.  		    !(curr->owornmask & (W_ARMOR|W_RING|W_AMUL|W_TOOL|W_WEP|W_SWAPWEP|W_QUIVER))) 842. 		    continue; 843. 		break; 844. 	    }  845.  	    if (curr) { 846. 		*pick_list = (menu_item *) alloc(sizeof(menu_item)); 847. 		(*pick_list)->item.a_int = curr->oclass; 848. 		return 1; 849. 	    } else { 850. #ifdef DEBUG 851. 		impossible("query_category: no single object match"); 852. #endif 853. 	    }  854.  	    return 0; 855. 	}  856.   857.  	win = create_nhwindow(NHW_MENU); 858. 	start_menu(win); 859. 	pack = flags.inv_order; 860. 	if ((qflags & ALL_TYPES) && (ccount > 1)) { 861. 		invlet = 'a'; 862. 		any.a_void = 0; 863. 		any.a_int = ALL_TYPES_SELECTED; 864. 		add_menu(win, NO_GLYPH, &any, invlet, 0, ATR_NONE,  865.  		       (qflags & WORN_TYPES) ? "All worn types" : "All types",  866.  			MENU_UNSELECTED); 867. 		invlet = 'b'; 868. 	} else 869. 		invlet = 'a'; 870. 	do { 871. 	    collected_type_name = FALSE; 872. 	    for (curr = olist; curr; curr = FOLLOW(curr, qflags)) { 873. 		if (curr->oclass == *pack) { 874. 		   if ((qflags & WORN_TYPES) &&  875.  		   		!(curr->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL |  876.  		    	W_WEP | W_SWAPWEP | W_QUIVER))) 877. 			 continue; 878. 		   if (!collected_type_name) { 879. 			any.a_void = 0; 880. 			any.a_int = curr->oclass; 881. 			add_menu(win, NO_GLYPH, &any, invlet++,  882.  				def_oc_syms[(int)objects[curr->otyp].oc_class],  883.  				ATR_NONE, let_to_name(*pack, FALSE),  884.  				MENU_UNSELECTED); 885. 			collected_type_name = TRUE; 886. 		   }  887.  		}  888.  	    }  889.  	    pack++; 890. 	    if (invlet >= 'u') { 891. 		impossible("query_category: too many categories"); 892. 		return 0; 893. 	    }  894.  	} while (*pack); 895. 	/* unpaid items if there are any */ 896. 	if (do_unpaid) { 897. 		invlet = 'u'; 898. 		any.a_void = 0; 899. 		any.a_int = 'u'; 900. 		add_menu(win, NO_GLYPH, &any, invlet, 0, ATR_NONE,  901.  			"Unpaid items", MENU_UNSELECTED); 902. 	}  903.  	/* billed items: checked by caller, so always include if BILLED_TYPES */ 904. 	if (qflags & BILLED_TYPES) { 905. 		invlet = 'x'; 906. 		any.a_void = 0; 907. 		any.a_int = 'x'; 908. 		add_menu(win, NO_GLYPH, &any, invlet, 0, ATR_NONE,  909.  			 "Unpaid items already used up", MENU_UNSELECTED); 910. 	}  911.  	if (qflags & CHOOSE_ALL) { 912. 		invlet = 'A'; 913. 		any.a_void = 0; 914. 		any.a_int = 'A'; 915. 		add_menu(win, NO_GLYPH, &any, invlet, 0, ATR_NONE,  916.  			(qflags & WORN_TYPES) ?  917.  			"Auto-select every item being worn" :  918.  			"Auto-select every item", MENU_UNSELECTED); 919. 	}  920.  	/* items with b/u/c/unknown if there are any */ 921. 	if (do_blessed) { 922. 		invlet = 'B'; 923. 		any.a_void = 0; 924. 		any.a_int = 'B'; 925. 		add_menu(win, NO_GLYPH, &any, invlet, 0, ATR_NONE,  926.  			"Items known to be Blessed", MENU_UNSELECTED); 927. 	}  928.  	if (do_cursed) { 929. 		invlet = 'C'; 930. 		any.a_void = 0; 931. 		any.a_int = 'C'; 932. 		add_menu(win, NO_GLYPH, &any, invlet, 0, ATR_NONE,  933.  			"Items known to be Cursed", MENU_UNSELECTED); 934. 	}  935.  	if (do_uncursed) { 936. 		invlet = 'U'; 937. 		any.a_void = 0; 938. 		any.a_int = 'U'; 939. 		add_menu(win, NO_GLYPH, &any, invlet, 0, ATR_NONE,  940.  			"Items known to be Uncursed", MENU_UNSELECTED); 941. 	}  942.  	if (do_buc_unknown) { 943. 		invlet = 'X'; 944. 		any.a_void = 0; 945. 		any.a_int = 'X'; 946. 		add_menu(win, NO_GLYPH, &any, invlet, 0, ATR_NONE,  947.  			"Items of unknown B/C/U status",  948.  			MENU_UNSELECTED); 949. 	}  950.  	end_menu(win, qstr); 951. 	n = select_menu(win, how, pick_list); 952. 	destroy_nhwindow(win); 953. 	if (n < 0) 954. 	    n = 0;	/* caller's don't expect -1 */ 955. 	return n;  956. } 957.   958.  STATIC_OVL int 959. count_categories(olist, qflags) 960. struct obj *olist; 961. int qflags; 962. {  963.  	char *pack; 964. 	boolean counted_category; 965. 	int ccount = 0; 966. 	struct obj *curr; 967.  968.  	pack = flags.inv_order; 969. 	do { 970. 	    counted_category = FALSE; 971. 	    for (curr = olist; curr; curr = FOLLOW(curr, qflags)) { 972. 		if (curr->oclass == *pack) { 973. 		   if ((qflags & WORN_TYPES) &&  974.  		    	!(curr->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL |  975.  		    	W_WEP | W_SWAPWEP | W_QUIVER))) 976. 			 continue; 977. 		   if (!counted_category) { 978. 			ccount++; 979. 			counted_category = TRUE; 980. 		   }  981.  		}  982.  	    }  983.  	    pack++; 984. 	} while (*pack); 985. 	return ccount; 986. }  987.   988.  /* could we carry `obj'? if not, could we carry some of it/them? */ 989.  STATIC_OVL long 990. carry_count(obj, container, count, telekinesis, wt_before, wt_after) 991. struct obj *obj, *container;	/* object to pick up, bag it's coming out of */ 992. long count; 993. boolean telekinesis; 994. int *wt_before, *wt_after; 995. {  996.      boolean adjust_wt = container && carried(container), 997. 	    is_gold = obj->oclass == COIN_CLASS; 998.     int wt, iw, ow, oow; 999.     long qq, savequan; 1000. #ifdef GOLDOBJ 1001.    long umoney = money_cnt(invent); 1002. #endif 1003.    unsigned saveowt; 1004.    const char *verb, *prefx1, *prefx2, *suffx; 1005.    char obj_nambuf[BUFSZ], where[BUFSZ]; 1006. 1007.     savequan = obj->quan; 1008.    saveowt = obj->owt; 1009. 1010.     iw = max_capacity; 1011. 1012.     if (count != savequan) { 1013. 	obj->quan = count; 1014. 	obj->owt = (unsigned)weight(obj); 1015.    }  1016.     wt = iw + (int)obj->owt; 1017.    if (adjust_wt) 1018. 	wt -= (container->otyp == BAG_OF_HOLDING) ? 1019. 		(int)DELTA_CWT(container, obj) : (int)obj->owt; 1020. #ifndef GOLDOBJ 1021.    if (is_gold)	/* merged gold might affect cumulative weight */ 1022. 	wt -= (GOLD_WT(u.ugold) + GOLD_WT(count) - GOLD_WT(u.ugold + count)); 1023. #else 1024.    /* This will go with silver+copper & new gold weight */ 1025.    if (is_gold)	/* merged gold might affect cumulative weight */ 1026. 	wt -= (GOLD_WT(umoney) + GOLD_WT(count) - GOLD_WT(umoney + count)); 1027. #endif 1028.    if (count != savequan) { 1029. 	obj->quan = savequan; 1030. 	obj->owt = saveowt; 1031.    }  1032.     *wt_before = iw; 1033.    *wt_after  = wt; 1034. 1035.     if (wt < 0) 1036. 	return count; 1037. 1038.     /* see how many we can lift */ 1039.    if (is_gold) { 1040. #ifndef GOLDOBJ 1041. 	iw -= (int)GOLD_WT(u.ugold); 1042. 	if (!adjust_wt) { 1043. 	   qq = GOLD_CAPACITY((long)iw, u.ugold); 1044. 	} else { 1045. 	   oow = 0; 1046. 	   qq = 50L - (u.ugold % 100L) - 1L; 1047. #else 1048. 	iw -= (int)GOLD_WT(umoney); 1049. 	if (!adjust_wt) { 1050. 	   qq = GOLD_CAPACITY((long)iw, umoney); 1051. 	} else { 1052. 	   oow = 0; 1053. 	   qq = 50L - (umoney % 100L) - 1L; 1054. #endif 1055. 	   if (qq < 0L) qq += 100L; 1056. 	   for (qq <= count; qq += 100L) { 1057. 		obj->quan = qq; 1058. 		obj->owt = (unsigned)GOLD_WT(qq); 1059. #ifndef GOLDOBJ 1060. 		ow = (int)GOLD_WT(u.ugold + qq); 1061. #else 1062. 		ow = (int)GOLD_WT(umoney + qq); 1063. #endif 1064. 		ow -= (container->otyp == BAG_OF_HOLDING) ? 1065. 			(int)DELTA_CWT(container, obj) : (int)obj->owt; 1066. 		if (iw + ow >= 0) break; 1067. 		oow = ow; 1068. 	   }  1069. 	    iw -= oow; 1070. 	   qq -= 100L; 1071. 	} 1072. 	if (qq < 0L) qq = 0L; 1073. 	else if (qq > count) qq = count; 1074. #ifndef GOLDOBJ 1075. 	wt = iw + (int)GOLD_WT(u.ugold + qq); 1076. #else 1077. 	wt = iw + (int)GOLD_WT(umoney + qq); 1078. #endif 1079.    } else if (count > 1 || count < obj->quan) { 1080. 	/* 1081. 	 * Ugh. Calc num to lift by changing the quan of of the 1082. 	 * object and calling weight. 1083. 	 * 1084. 	 * This works for containers only because containers 1085. 	 * don't merge. -dean 1086. 	 */ 1087. 	for (qq = 1L; qq <= count; qq++) { 1088. 	   obj->quan = qq; 1089. 	   obj->owt = (unsigned)(ow = weight(obj)); 1090. 	   if (adjust_wt) 1091. 		ow -= (container->otyp == BAG_OF_HOLDING) ? 1092. 			(int)DELTA_CWT(container, obj) : (int)obj->owt; 1093. 	   if (iw + ow >= 0) 1094. 		break; 1095. 	   wt = iw + ow; 1096. 	} 1097. 	--qq; 1098.    } else { 1099. 	/* there's only one, and we can't lift it */ 1100. 	qq = 0L; 1101.    }  1102.     obj->quan = savequan; 1103.    obj->owt = saveowt; 1104. 1105.     if (qq < count) { 1106. 	/* some message will be given */ 1107. 	Strcpy(obj_nambuf, doname(obj)); 1108. 	if (container) { 1109. 	   Sprintf(where, "in %s", the(xname(container))); 1110. 	   verb = "carry"; 1111. 	} else { 1112. 	   Strcpy(where, "lying here"); 1113. 	   verb = telekinesis ? "acquire" : "lift"; 1114. 	} 1115.     } else { 1116. 	/* lint supppression */ 1117. 	*obj_nambuf = *where = '\0'; 1118. 	verb = ""; 1119.    }  1120.     /* we can carry qq of them */ 1121.    if (qq > 0) { 1122. 	if (qq < count) 1123. 	   You("can only %s %s of the %s %s.",  1124. 		verb, (qq == 1L) ? "one" : "some", obj_nambuf, where); 1125. 	*wt_after = wt; 1126. 	return qq; 1127.    }  1128.  1129.     if (!container) Strcpy(where, "here");  /* slightly shorter form */ 1130. #ifndef GOLDOBJ 1131.    if (invent || u.ugold) { 1132. #else 1133.    if (invent || umoney) { 1134. #endif 1135. 	prefx1 = "you cannot "; 1136. 	prefx2 = ""; 1137. 	suffx = " any more"; 1138.    } else { 1139. 	prefx1 = (obj->quan == 1L) ? "it " : "even one "; 1140. 	prefx2 = "is too heavy for you to "; 1141. 	suffx = ""; 1142.    }  1143.     There("%s %s %s, but %s%s%s%s.",  1144. 	  otense(obj, "are"), obj_nambuf, where,  1145. 	  prefx1, prefx2, verb, suffx); 1146. 1147.  /* *wt_after = iw; */ 1148.    return 0L; 1149. } 1150.  1151. /* determine whether character is able and player is willing to carry `obj' */ 1152. STATIC_OVL 1153. int 1154. lift_object(obj, container, cnt_p, telekinesis) 1155. struct obj *obj, *container;	/* object to pick up, bag it's coming out of */ 1156. long *cnt_p; 1157. boolean telekinesis; 1158. { 1159.     int result, old_wt, new_wt, prev_encumbr, next_encumbr; 1160. 1161.     if (obj->otyp == BOULDER && In_sokoban(&u.uz)) { 1162. 	You("cannot get your %s around this %s.", 1163. 			body_part(HAND), xname(obj)); 1164. 	return -1; 1165.    }  1166.     if (obj->otyp == LOADSTONE ||  1167. 	    (obj->otyp == BOULDER && throws_rocks(youmonst.data))) 1168. 	return 1;		/* lift regardless of current situation */ 1169. 1170.     *cnt_p = carry_count(obj, container, *cnt_p, telekinesis, &old_wt, &new_wt); 1171.    if (*cnt_p < 1L) { 1172. 	result = -1;	/* nothing lifted */ 1173. #ifndef GOLDOBJ 1174.    } else if (obj->oclass != COIN_CLASS && inv_cnt >= 52 &&  1175. 		!merge_choice(invent, obj)) { 1176. #else 1177.    } else if (inv_cnt >= 52 && !merge_choice(invent, obj)) { 1178. #endif 1179. 	Your("knapsack cannot accommodate any more items."); 1180. 	result = -1;	/* nothing lifted */ 1181.    } else { 1182. 	result = 1; 1183. 	prev_encumbr = near_capacity; 1184. 	if (prev_encumbr < flags.pickup_burden) 1185. 		prev_encumbr = flags.pickup_burden; 1186. 	next_encumbr = calc_capacity(new_wt - old_wt); 1187. 	if (next_encumbr > prev_encumbr) { 1188. 	   if (telekinesis) { 1189. 		result = 0;	/* don't lift */ 1190. 	   } else { 1191. 		char qbuf[BUFSZ]; 1192. 		long savequan = obj->quan; 1193. 1194. 		obj->quan = *cnt_p; 1195. 		Strcpy(qbuf, 1196. 			(next_encumbr > HVY_ENCUMBER) ? overloadmsg :  1197. 			(next_encumbr > MOD_ENCUMBER) ? nearloadmsg :  1198. 			moderateloadmsg); 1199. 		Sprintf(eos(qbuf), " %s. Continue?", 1200. 			safe_qbuf(qbuf, sizeof(" . Continue?"), 1201. 				doname(obj), an(simple_typename(obj->otyp)), "something")); 1202. 		obj->quan = savequan; 1203. 		switch (ynq(qbuf)) { 1204. 		case 'q': result = -1; break; 1205. 		case 'n': result =  0; break; 1206. 		default:  break;	/* 'y' => result == 1 */ 1207. 		} 1208. 		clear_nhwindow(WIN_MESSAGE); 1209. 	   }  1210. 	}  1211.     }  1212.  1213.     if (obj->otyp == SCR_SCARE_MONSTER && result <= 0 && !container) 1214. 	obj->spe = 0; 1215.    return result; 1216. } 1217.  1218. /* To prevent qbuf overflow in prompts use planA only 1219. * if it fits, or planB if PlanA doesn't fit, 1220. * finally using the fallback as a last resort. 1221. * last_restort is expected to be very short. 1222. */  1223. const char * 1224. safe_qbuf(qbuf, padlength, planA, planB, last_resort) 1225. const char *qbuf, *planA, *planB, *last_resort; 1226. unsigned padlength; 1227. { 1228. 	/* convert size_t (or int for ancient systems) to ordinary unsigned */ 1229. 	unsigned len_qbuf = (unsigned)strlen(qbuf), 1230. 	        len_planA = (unsigned)strlen(planA), 1231. 	        len_planB = (unsigned)strlen(planB), 1232. 	        len_lastR = (unsigned)strlen(last_resort); 1233. 	unsigned textleft = QBUFSZ - (len_qbuf + padlength); 1234. 1235. 	if (len_lastR >= textleft) { 1236. 	   impossible("safe_qbuf: last_resort too large at %u characters.",  1237. 		       len_lastR); 1238. 	   return ""; 1239. 	} 1240. 	return (len_planA < textleft) ? planA : 1241. 		   (len_planB < textleft) ? planB : last_resort; 1242. } 1243.  1244. /*  1245.  * Pick up of obj from the ground and add it to the hero's inventory. 1246. * Returns -1 if caller should break out of its loop, 0 if nothing picked 1247. * up, 1 if otherwise. 1248. */  1249. int 1250. pickup_object(obj, count, telekinesis) 1251. struct obj *obj; 1252. long count; 1253. boolean telekinesis;	/* not picking it up directly by hand */ 1254. { 1255. 	int res, nearload; 1256. #ifndef GOLDOBJ 1257. 	const char *where = (obj->ox == u.ux && obj->oy == u.uy) ? 1258. 			   "here" : "there"; 1259. #endif 1260. 1261. 	if (obj->quan < count) { 1262. 	   impossible("pickup_object: count %ld > quan %ld?",  1263. 		count, obj->quan); 1264. 	   return 0; 1265. 	} 1266.  1267. 	/* In case of auto-pickup, where we haven't had a chance 1268. 	  to look at it yet; affects docall(SCR_SCARE_MONSTER). */ 1269. 	if (!Blind) 1270. #ifdef INVISIBLE_OBJECTS 1271. 		if (!obj->oinvis || See_invisible) 1272. #endif 1273. 		obj->dknown = 1; 1274. 1275. 	if (obj == uchain) {    /* do not pick up attached chain */ 1276. 	   return 0; 1277. 	} else if (obj->oartifact && !touch_artifact(obj,&youmonst)) { 1278. 	   return 0; 1279. #ifndef GOLDOBJ 1280. 	} else if (obj->oclass == COIN_CLASS) { 1281. 	   /* Special consideration for gold pieces... */ 1282. 	    long iw = (long)max_capacity - GOLD_WT(u.ugold); 1283. 	   long gold_capacity = GOLD_CAPACITY(iw, u.ugold); 1284. 1285. 	    if (gold_capacity <= 0L) { 1286. 		pline( 1287. 	       "There %s %ld gold piece%s %s, but you cannot carry any more.",  1288. 		      otense(obj, "are"),  1289. 		      obj->quan, plur(obj->quan), where); 1290. 		return 0; 1291. 	   } else if (gold_capacity < count) { 1292. 		You("can only %s %s of the %ld gold pieces lying %s.", 1293. 		    telekinesis ? "acquire" : "carry",  1294. 		    gold_capacity == 1L ? "one" : "some", obj->quan, where); 1295. 		pline("%s %ld gold piece%s.", 1296. 		    nearloadmsg, gold_capacity, plur(gold_capacity)); 1297. 		u.ugold += gold_capacity; 1298. 		obj->quan -= gold_capacity; 1299. 		costly_gold(obj->ox, obj->oy, gold_capacity); 1300. 	   } else { 1301. 		u.ugold += count; 1302. 		if ((nearload = near_capacity) != 0) 1303. 		   pline("%s %ld gold piece%s.",  1304. 			  nearload < MOD_ENCUMBER ?  1305. 			  moderateloadmsg : nearloadmsg,  1306. 			  count, plur(count)); 1307. 		else 1308. 		   prinv((char *) 0, obj, count); 1309. 		costly_gold(obj->ox, obj->oy, count); 1310. 		if (count == obj->quan) 1311. 		   delobj(obj); 1312. 		else 1313. 		   obj->quan -= count; 1314. 	   }  1315. 	    flags.botl = 1; 1316. 	   if (flags.run) nomul(0); 1317. 	   return 1; 1318. #endif 1319. 	} else if (obj->otyp == CORPSE) { 1320. 	   if ( (touch_petrifies(&mons[obj->corpsenm])) && !uarmg  1321. 				&& !Stone_resistance && !telekinesis) { 1322. 		if (poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM)) 1323. 		   display_nhwindow(WIN_MESSAGE, FALSE); 1324. 		else { 1325. 			char kbuf[BUFSZ]; 1326. 1327. 			Strcpy(kbuf, an(corpse_xname(obj, TRUE))); 1328. 			pline("Touching %s is a fatal mistake.", kbuf); 1329. 			Strcpy(kbuf, an(killer_cxname(obj, TRUE))); 1330. 			instapetrify(kbuf); 1331. 		   return -1; 1332. 		} 1333. 	    } else if (is_rider(&mons[obj->corpsenm])) { 1334. 		pline("At your %s, the corpse suddenly moves...", 1335. 			telekinesis ? "attempted acquisition" : "touch"); 1336. 		(void) revive_corpse(obj, FALSE); 1337. 		exercise(A_WIS, FALSE); 1338. 		return -1; 1339. 	   }  1340. 	} else  if (obj->otyp == SCR_SCARE_MONSTER) { 1341. 	   if (obj->blessed) obj->blessed = 0; 1342. 	   else if (!obj->spe && !obj->cursed) obj->spe = 1; 1343. 	   else { 1344. 		pline_The("scroll%s %s to dust as you %s %s up.", 1345. 			plur(obj->quan), otense(obj, "turn"),  1346. 			telekinesis ? "raise" : "pick",  1347. 			(obj->quan == 1L) ? "it" : "them"); 1348. 		if (!(objects[SCR_SCARE_MONSTER].oc_name_known) && 1349. 				    !(objects[SCR_SCARE_MONSTER].oc_uname)) 1350. 		   docall(obj); 1351. 		useupf(obj, obj->quan); 1352. 		return 1;	/* tried to pick something up and failed, but 1353. 				  don't want to terminate pickup loop yet   */ 1354. 	   }  1355. 	}  1356.  1357. 	if ((res = lift_object(obj, (struct obj *)0, &count, telekinesis)) <= 0) 1358. 	   return res; 1359. 1360. #ifdef GOLDOBJ 1361.        /* Whats left of the special case for gold :-) */  1362. 	if (obj->oclass == COIN_CLASS) flags.botl = 1;  1363. #endif  1364. 	if (obj->quan != count && obj->otyp != LOADSTONE)  1365. 	    obj = splitobj(obj, count);  1366.  1367. 	obj = pick_obj(obj);  1368.  1369. 	if (uwep && uwep == obj) mrg_to_wielded = TRUE;  1370. 	nearload = near_capacity;  1371. 	prinv(nearload == SLT_ENCUMBER ? moderateloadmsg : (char *) 0, 1372. 	     obj, count);  1373. 	mrg_to_wielded = FALSE;  1374. 	return 1;  1375. }  1376.  1377. /*  1378.  * Do the actual work of picking otmp from the floor or monster's interior  1379.  * and putting it in the hero's inventory.  Take care of billing.  Return a  1380.  * pointer to the object where otmp ends up.  This may be different  1381.  * from otmp because of merging.  1382.  *  1383.  * Gold never reaches this routine unless GOLDOBJ is defined.  1384.  */  1385. struct obj *  1386. pick_obj(otmp)  1387. struct obj *otmp;  1388. {  1389. 	obj_extract_self(otmp);  1390. 	if (!u.uswallow && otmp != uball && costly_spot(otmp->ox, otmp->oy)) {  1391. 	    char saveushops[5], fakeshop[2];  1392.  1393. 	    /* addtobill cares about your location rather than the object's;  1394. 	       usually they'll be the same, but not when using telekinesis  1395. 	       (if ever implemented) or a grappling hook */ 1396. 	   Strcpy(saveushops, u.ushops); 1397. 	   fakeshop[0] = *in_rooms(otmp->ox, otmp->oy, SHOPBASE); 1398. 	   fakeshop[1] = '\0'; 1399. 	   Strcpy(u.ushops, fakeshop); 1400. 	   /* sets obj->unpaid if necessary */ 1401. 	   addtobill(otmp, TRUE, FALSE, FALSE); 1402. 	   Strcpy(u.ushops, saveushops); 1403. 	   /* if you're outside the shop, make shk notice */ 1404. 	   if (!index(u.ushops, *fakeshop)) 1405. 		remote_burglary(otmp->ox, otmp->oy); 1406. 	} 1407. 	if (otmp->no_charge)	/* only applies to objects outside invent */ 1408. 	   otmp->no_charge = 0; 1409. 	if (otmp->was_thrown)	/* likewise */ 1410. 	   otmp->was_thrown = 0; 1411. 	newsym(otmp->ox, otmp->oy); 1412. 	return addinv(otmp);	/* might merge it with other objects */ 1413. } 1414.  1415. /*  1416.  * prints a message if encumbrance changed since the last check and 1417. * returns the new encumbrance value (from near_capacity). 1418. */  1419. int 1420. encumber_msg 1421. { 1422.     static int oldcap = UNENCUMBERED; 1423.    int newcap = near_capacity; 1424. 1425.     if(oldcap < newcap) { 1426. 	switch(newcap) { 1427. 	case 1: Your("movements are slowed slightly because of your load."); 1428. 		break; 1429. 	case 2: You("rebalance your load. Movement is difficult."); 1430. 		break; 1431. 	case 3: You("%s under your heavy load. Movement is very hard.",  1432. 		    stagger(youmonst.data, "stagger")); 1433. 		break; 1434. 	default: You("%s move a handspan with this load!", 1435. 		     newcap == 4 ? "can barely" : "can't even"); 1436. 		break; 1437. 	} 1438. 	flags.botl = 1; 1439.    } else if(oldcap > newcap) { 1440. 	switch(newcap) { 1441. 	case 0: Your("movements are now unencumbered."); 1442. 		break; 1443. 	case 1: Your("movements are only slowed slightly by your load."); 1444. 		break; 1445. 	case 2: You("rebalance your load. Movement is still difficult."); 1446. 		break; 1447. 	case 3: You("%s under your load. Movement is still very hard.",  1448. 		    stagger(youmonst.data, "stagger")); 1449. 		break; 1450. 	} 1451. 	flags.botl = 1; 1452.    }  1453.  1454.     oldcap = newcap; 1455.    return (newcap); 1456. } 1457.  1458. /* Is there a container at x,y. Optional: return count of containers at x,y */ 1459. STATIC_OVL int 1460. container_at(x, y, countem) 1461. int x,y; 1462. boolean countem; 1463. { 1464. 	struct obj *cobj, *nobj; 1465. 	int container_count = 0; 1466. 	 1467. 	for(cobj = level.objects[x][y]; cobj; cobj = nobj) { 1468. 		nobj = cobj->nexthere; 1469. 		if(Is_container(cobj)) { 1470. 			container_count++; 1471. 			if (!countem) break; 1472. 		} 1473. 	}  1474. 	return container_count; 1475. } 1476.  1477. STATIC_OVL boolean 1478. able_to_loot(x, y) 1479. int x, y; 1480. { 1481. 	if (!can_reach_floor) { 1482. #ifdef STEED 1483. 		if (u.usteed && P_SKILL(P_RIDING) < P_BASIC) 1484. 			rider_cant_reach; /* not skilled enough to reach */ 1485. 		else 1486. #endif 1487. 			You("cannot reach the %s.", surface(x, y)); 1488. 		return FALSE; 1489. 	} else if (is_pool(x, y) || is_lava(x, y)) { 1490. 		/* at present, can't loot in water even when Underwater */ 1491. 		You("cannot loot things that are deep in the %s.", 1492. 		    is_lava(x, y) ? "lava" : "water"); 1493. 		return FALSE; 1494. 	} else if (nolimbs(youmonst.data)) { 1495. 		pline("Without limbs, you cannot loot anything."); 1496. 		return FALSE; 1497. 	} else if (!freehand) { 1498. 		pline("Without a free %s, you cannot loot anything.", 1499. 			body_part(HAND)); 1500. 		return FALSE; 1501. 	} 1502. 	return TRUE; 1503. } 1504.  1505. STATIC_OVL boolean 1506. mon_beside(x,y) 1507. int x, y; 1508. { 1509. 	int i,j,nx,ny; 1510. 	for(i = -1; i <= 1; i++) 1511. 	   for(j = -1; j <= 1; j++) { 1512. 	   	nx = x + i;  1513. ny = y + j; 1514. if(isok(nx, ny) && MON_AT(nx, ny)) 1515. 			return TRUE; 1516. 	   }  1517. 	return FALSE; 1518. } 1519.  1520. int 1521. doloot	/* loot a container on the floor or loot saddle from mon. */ 1522. {  1523.     struct obj *cobj, *nobj; 1524.    register int c = -1; 1525.    int timepassed = 0; 1526.    coord cc; 1527.    boolean underfoot = TRUE; 1528.    const char *dont_find_anything = "don't find anything"; 1529.    struct monst *mtmp; 1530.    char qbuf[BUFSZ]; 1531.    int prev_inquiry = 0; 1532.    boolean prev_loot = FALSE; 1533. 1534.     if (check_capacity((char *)0)) { 1535. 	/* "Can't do that while carrying so much stuff." */ 1536. 	return 0; 1537.    }  1538.     if (nohands(youmonst.data)) { 1539. 	You("have no hands!");	/* not `body_part(HAND)' */ 1540. 	return 0; 1541.    }  1542.     cc.x = u.ux; cc.y = u.uy; 1543. 1544. lootcont: 1545. 1546.     if (container_at(cc.x, cc.y, FALSE)) { 1547. 	boolean any = FALSE; 1548. 1549. 	if (!able_to_loot(cc.x, cc.y)) return 0; 1550. 	for (cobj = level.objects[cc.x][cc.y]; cobj; cobj = nobj) { 1551. 	   nobj = cobj->nexthere; 1552. 1553. 	    if (Is_container(cobj)) { 1554. 		Sprintf(qbuf, "There is %s here, loot it?", 1555. 			safe_qbuf("", sizeof("There is  here, loot it?"), 1556. 			    doname(cobj), an(simple_typename(cobj->otyp)), 1557. 			    "a container")); 1558. 		c = ynq(qbuf); 1559. 		if (c == 'q') return (timepassed); 1560. 		if (c == 'n') continue; 1561. 		any = TRUE; 1562. 1563. 		if (cobj->olocked) { 1564. 		   pline("Hmmm, it seems to be locked."); 1565. 		   continue; 1566. 		} 1567. 		if (cobj->otyp == BAG_OF_TRICKS) { 1568. 		   int tmp; 1569. 		   You("carefully open the bag..."); 1570. 		   pline("It develops a huge set of teeth and bites you!"); 1571. 		   tmp = rnd(10); 1572. 		   if (Half_physical_damage) tmp = (tmp+1) / 2; 1573. 		   losehp(tmp, "carnivorous bag", KILLED_BY_AN); 1574. 		   makeknown(BAG_OF_TRICKS); 1575. 		   timepassed = 1; 1576. 		   continue; 1577. 		} 1578.  1579. 		You("carefully open %s...", the(xname(cobj))); 1580. 		timepassed |= use_container(&cobj, 0); 1581. 		/* might have triggered chest trap or magic bag explosion */ 1582. 		if (multi < 0 || !cobj) return 1; 1583. 	   }  1584. 	}  1585. 	if (any) c = 'y'; 1586.    } else if (Confusion) { 1587. #ifndef GOLDOBJ 1588. 	if (u.ugold){ 1589. 	   long contribution = rnd((int)min(LARGEST_INT,u.ugold)); 1590. 	   struct obj *goldob = mkgoldobj(contribution); 1591. #else 1592. 	struct obj *goldob; 1593. 	/* Find a money object to mess with */ 1594. 	for (goldob = invent; goldob; goldob = goldob->nobj) { 1595. 	   if (goldob->oclass == COIN_CLASS) break; 1596. 	} 1597. 	if (goldob){ 1598. 	   long contribution = rnd((int)min(LARGEST_INT, goldob->quan)); 1599. 	   if (contribution < goldob->quan) 1600. 		goldob = splitobj(goldob, contribution); 1601. 	   freeinv(goldob); 1602. #endif 1603. 	   if (IS_THRONE(levl[u.ux][u.uy].typ)){ 1604. 		struct obj *coffers; 1605. 		int pass; 1606. 		/* find the original coffers chest, or any chest */ 1607. 		for (pass = 2; pass > -1; pass -= 2) 1608. 		   for (coffers = fobj; coffers; coffers = coffers->nobj) 1609. 			if (coffers->otyp == CHEST && coffers->spe == pass) 1610. 			   goto gotit;	/* two level break */ 1611. gotit: 1612. 		if (coffers) { 1613. 	   verbalize("Thank you for your contribution to reduce the debt."); 1614. 		   (void) add_to_container(coffers, goldob); 1615. 		   coffers->owt = weight(coffers); 1616. 		} else { 1617. 		   struct monst *mon = makemon(courtmon,  1618. 					    u.ux, u.uy, NO_MM_FLAGS); 1619. 		   if (mon) { 1620. #ifndef GOLDOBJ 1621. 			mon->mgold += goldob->quan; 1622. 			delobj(goldob); 1623. 			pline("The exchequer accepts your contribution."); 1624. 		   } else { 1625. 			dropx(goldob); 1626. 		   }  1627. 		}  1628. 	    } else { 1629. 		dropx(goldob); 1630. #else 1631. 			add_to_minv(mon, goldob); 1632. 			pline("The exchequer accepts your contribution."); 1633. 		   } else { 1634. 			dropy(goldob); 1635. 		   }  1636. 		}  1637. 	    } else { 1638. 		dropy(goldob); 1639. #endif 1640. 		pline("Ok, now there is loot here."); 1641. 	   }  1642. 	}  1643.     } else if (IS_GRAVE(levl[cc.x][cc.y].typ)) { 1644. 	You("need to dig up the grave to effectively loot it..."); 1645.    }  1646.     /*  1647.      * 3.3.1 introduced directional looting for some things. 1648.     */  1649.     if (c != 'y' && mon_beside(u.ux, u.uy)) { 1650. 	if (!get_adjacent_loc("Loot in what direction?", "Invalid loot location", 1651. 			u.ux, u.uy, &cc)) return 0; 1652. 	if (cc.x == u.ux && cc.y == u.uy) { 1653. 	   underfoot = TRUE; 1654. 	   if (container_at(cc.x, cc.y, FALSE)) 1655. 		goto lootcont; 1656. 	} else 1657. 	   underfoot = FALSE; 1658. 	if (u.dz < 0) { 1659. 	   You("%s to loot on the %s.", dont_find_anything,  1660. 		ceiling(cc.x, cc.y)); 1661. 	   timepassed = 1; 1662. 	   return timepassed; 1663. 	} 1664. 	mtmp = m_at(cc.x, cc.y); 1665. 	if (mtmp) timepassed = loot_mon(mtmp, &prev_inquiry, &prev_loot); 1666. 1667. 	/* Preserve pre-3.3.1 behaviour for containers. 1668. 	 * Adjust this if-block to allow container looting 1669. 	 * from one square away to change that in the future. 1670. 	 */ 1671. 	if (!underfoot) { 1672. 	   if (container_at(cc.x, cc.y, FALSE)) { 1673. 		if (mtmp) { 1674. 		   You_cant("loot anything %sthere with %s in the way.",  1675. 			    prev_inquiry ? "else " : "", mon_nam(mtmp)); 1676. 		   return timepassed; 1677. 		} else { 1678. 		   You("have to be at a container to loot it."); 1679. 		} 1680. 	    } else { 1681. 		You("%s %sthere to loot.", dont_find_anything, 1682. 			(prev_inquiry || prev_loot) ? "else " : ""); 1683. 		return timepassed; 1684. 	   }  1685. 	}  1686.     } else if (c != 'y' && c != 'n') { 1687. 	You("%s %s to loot.", dont_find_anything, 1688. 		    underfoot ? "here" : "there"); 1689.    }  1690.     return (timepassed); 1691. } 1692.  1693. /* loot_mon returns amount of time passed. 1694. */  1695. int 1696. loot_mon(mtmp, passed_info, prev_loot) 1697. struct monst *mtmp; 1698. int *passed_info; 1699. boolean *prev_loot; 1700. { 1701.     int c = -1; 1702.    int timepassed = 0; 1703. #ifdef STEED 1704.    struct obj *otmp; 1705.    char qbuf[QBUFSZ]; 1706. 1707.     /* 3.3.1 introduced the ability to remove saddle from a steed             */ 1708.    /* 	*passed_info is set to TRUE if a loot query was given. */ 1709.     /*	*prev_loot is set to TRUE if something was actually acquired in here. */ 1710.     if (mtmp && mtmp != u.usteed && (otmp = which_armor(mtmp, W_SADDLE))) { 1711. 	long unwornmask; 1712. 	if (passed_info) *passed_info = 1; 1713. 	Sprintf(qbuf, "Do you want to remove the saddle from %s?", 1714. 		x_monnam(mtmp, ARTICLE_THE, (char *)0, SUPPRESS_SADDLE, FALSE)); 1715. 	if ((c = yn_function(qbuf, ynqchars, 'n')) == 'y') { 1716. 		if (nolimbs(youmonst.data)) { 1717. 		   You_cant("do that without limbs."); /* not body_part(HAND) */ 1718. 		   return (0); 1719. 		} 1720. 		if (otmp->cursed) { 1721. 		   You("can't. The saddle seems to be stuck to %s.",  1722. 			x_monnam(mtmp, ARTICLE_THE, (char *)0, 1723. 				SUPPRESS_SADDLE, FALSE)); 1724. 			    1725. 		    /* the attempt costs you time */ 1726. 			return (1); 1727. 		} 1728. 		obj_extract_self(otmp); 1729. 		if ((unwornmask = otmp->owornmask) != 0L) { 1730. 		   mtmp->misc_worn_check &= ~unwornmask; 1731. 		   otmp->owornmask = 0L; 1732. 		   update_mon_intrinsics(mtmp, otmp, FALSE, FALSE); 1733. 		} 1734. 		otmp = hold_another_object(otmp, "You drop %s!", doname(otmp),  1735. 					(const char *)0); 1736. 		timepassed = rnd(3); 1737. 		if (prev_loot) *prev_loot = TRUE; 1738. 	} else if (c == 'q') { 1739. 		return (0); 1740. 	} 1741.     }  1742. #endif	/* STEED */ 1743.    /* 3.4.0 introduced the ability to pick things up from within swallower's stomach */ 1744.    if (u.uswallow) { 1745. 	int count = passed_info ? *passed_info : 0; 1746. 	timepassed = pickup(count); 1747.    }  1748.     return timepassed; 1749. } 1750.  1751. /*  1752.  * Decide whether an object being placed into a magic bag will cause 1753. * it to explode. If the object is a bag itself, check recursively. 1754. */  1755. boolean 1756. mbag_explodes(obj, depthin) 1757.    struct obj *obj; 1758.    int depthin; 1759. { 1760.     /* these won't cause an explosion when they're empty */ 1761.    if ((obj->otyp == WAN_CANCELLATION || obj->otyp == BAG_OF_TRICKS) &&  1762. 	    obj->spe <= 0) 1763. 	return FALSE; 1764. 1765.     /* odds: 1/1, 2/2, 3/4, 4/8, 5/16, 6/32, 7/64, 8/128, 9/128, 10/128,... */ 1766.     if ((Is_mbag(obj) || obj->otyp == WAN_CANCELLATION) &&  1767. 	(rn2(1 << (depthin > 7 ? 7 : depthin)) <= depthin)) 1768. 	return TRUE; 1769.    else if (Has_contents(obj)) { 1770. 	struct obj *otmp; 1771. 1772. 	for (otmp = obj->cobj; otmp; otmp = otmp->nobj) 1773. 	   if (mbag_explodes(otmp, depthin+1)) return TRUE; 1774.    }  1775.     return FALSE; 1776. } 1777.  1778. void 1779. destroy_mbag(bomb, silent) 1780. struct obj *bomb; 1781. boolean silent; 1782. { 1783.     xchar x,y; 1784.    boolean underwater; 1785.    struct monst *mtmp = (struct monst *)0; 1786. 1787.     if (get_obj_location(bomb, &x, &y, BURIED_TOO | CONTAINED_TOO)) { 1788. 	switch(bomb->where) { 1789. 	   case OBJ_MINVENT: 1790. 		mtmp = bomb->ocarry; 1791. 		if (bomb == MON_WEP(mtmp)) { 1792. 		   bomb->owornmask &= ~W_WEP; 1793. 		   MON_NOWEP(mtmp); 1794. 		} 1795. 		if (!silent && canseemon(mtmp)) 1796. 		   You("see %s engulfed in an explosion!", mon_nam(mtmp)); 1797. 		mtmp->mhp -= d(6,6); 1798. 		if (mtmp->mhp < 1) { 1799. 		   if (!bomb->yours) 1800. 			monkilled(mtmp, silent ? "" : "explosion", AD_PHYS); 1801. 		   else xkilled(mtmp, !silent); 1802. 		} 1803. 		break; 1804. 	   case OBJ_INVENT: 1805. 		/* This shouldn't be silent! */ 1806. 		pline("Something explodes inside your knapsack!"); 1807. 		if (bomb == uwep) { 1808. 		   uwepgone; 1809. 		   stop_occupation; 1810. 		} else if (bomb == uswapwep) { 1811. 		   uswapwepgone; 1812. 		   stop_occupation; 1813. 		} else if (bomb == uquiver) { 1814. 		   uqwepgone; 1815. 		   stop_occupation; 1816. 		} 1817. 		losehp(d(6,6), "carrying live explosives", KILLED_BY); 1818. 		break; 1819. 	   case OBJ_FLOOR: 1820. 		underwater = is_pool(x, y); 1821. 		if (!silent) { 1822. 		   if (x == u.ux && y == u.uy) { 1823. 			if (underwater && (Flying || Levitation)) 1824. 			   pline_The("water boils beneath you."); 1825. 			else if (underwater && Wwalking) 1826. 			   pline_The("water erupts around you."); 1827. 			else pline("A bag explodes under your %s!", 1828. 			  makeplural(body_part(FOOT))); 1829. 		   } else if (cansee(x, y)) 1830. 			You(underwater ? 1831. 			    "see a plume of water shoot up." :  1832. 			    "see a bag explode."); 1833. 		} 1834. 		if (underwater && (Flying || Levitation || Wwalking)) { 1835. 		   if (Wwalking && x == u.ux && y == u.uy) { 1836. 			struct trap trap; 1837. 			trap.ntrap = NULL; 1838. 			trap.tx = x; 1839. trap.ty = y; 1840. trap.launch.x = -1; 1841. 			trap.launch.y = -1; 1842. 			trap.ttyp = RUST_TRAP; 1843. 			trap.tseen = 0; 1844. 			trap.once = 0; 1845. 			trap.madeby_u = 0; 1846. 			trap.dst.dnum = -1; 1847. 			trap.dst.dlevel = -1; 1848. 			dotrap(&trap, 0); 1849. 		   }  1850. 		    goto free_bomb; 1851. 		} 1852. 		break; 1853. 	   default:	/* Buried, contained, etc. */ 1854. 		if (!silent) 1855. 		   You_hear("a muffled explosion."); 1856. 		goto free_bomb; 1857. 		break; 1858. 	} 1859.     }  1860.  1861. free_bomb: 1862.    if (Has_contents(bomb)) 1863. 	delete_contents(bomb); 1864. 1865.     obj_extract_self(bomb); 1866.    obfree(bomb, (struct obj *)0); 1867.    newsym(x,y); 1868. } 1869.  1870. /* Returns: -1 to stop, 1 item was inserted, 0 item was not inserted. */ 1871. STATIC_PTR int 1872. in_container(obj) 1873. register struct obj *obj; 1874. { 1875. 	boolean floor_container = !carried(current_container); 1876. 	boolean was_unpaid = FALSE; 1877. 	char buf[BUFSZ]; 1878. 1879. 	if (!current_container) { 1880. 		impossible(" no current_container?"); 1881. 		return 0; 1882. 	} else if (obj == uball || obj == uchain) { 1883. 		You("must be kidding."); 1884. 		return 0; 1885. 	} else if (obj == current_container) { 1886. 		pline("That would be an interesting topological exercise."); 1887. 		return 0; 1888. 	} else if (obj->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL)) { 1889. 		Norep("You cannot %s %s you are wearing.", 1890. 			Icebox ? "refrigerate" : "stash", something); 1891. 		return 0; 1892. 	} else if ((obj->otyp == LOADSTONE) && obj->cursed) { 1893. 		obj->bknown = 1; 1894. 	     pline_The("stone%s won't leave your person.", plur(obj->quan)); 1895. 		return 0; 1896. 	} else if (obj->otyp == AMULET_OF_YENDOR || 1897. 		   obj->otyp == CANDELABRUM_OF_INVOCATION ||  1898. 		   obj->otyp == BELL_OF_OPENING ||  1899. 		   obj->otyp == SPE_BOOK_OF_THE_DEAD) { 1900. 	/* Prohibit Amulets in containers; if you allow it, monsters can't 1901. * steal them. It also becomes a pain to check to see if someone 1902. 	 * has the Amulet. Ditto for the Candelabrum, the Bell and the Book. 1903. 	 */ 1904. 	    pline("%s cannot be confined in such trappings.", The(xname(obj))); 1905. 	   return 0; 1906. 	} else if (obj->otyp == LEASH && obj->leashmon != 0) { 1907. 		pline("%s attached to your pet.", Tobjnam(obj, "are")); 1908. 		return 0; 1909. 	} else if (obj == uwep) { 1910. 		if (welded(obj)) { 1911. 			weldmsg(obj); 1912. 			return 0; 1913. 		} 1914. 		setuwep((struct obj *) 0, FALSE); 1915. 		if (uwep) return 0;	/* unwielded, died, rewielded */ 1916. 	} else if (obj == uswapwep) { 1917. 		setuswapwep((struct obj *) 0, FALSE); 1918. 		if (uswapwep) return 0;    /* unwielded, died, rewielded */ 1919. 	} else if (obj == uquiver) { 1920. 		setuqwep((struct obj *) 0); 1921. 		if (uquiver) return 0;    /* unwielded, died, rewielded */ 1922. 	} 1923.  1924. 	if (obj->otyp == CORPSE) { 1925. 	   if ( (touch_petrifies(&mons[obj->corpsenm])) && !uarmg  1926. 		 && !Stone_resistance) { 1927. 		if (poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM)) 1928. 		   display_nhwindow(WIN_MESSAGE, FALSE); 1929. 		else { 1930. 		   char kbuf[BUFSZ]; 1931. 1932. 		    Strcpy(kbuf, an(corpse_xname(obj, TRUE))); 1933. 		   pline("Touching %s is a fatal mistake.", kbuf); 1934. 		   Strcpy(kbuf, an(killer_cxname(obj, TRUE))); 1935. 		   instapetrify(kbuf); 1936. 		   return -1; 1937. 		} 1938. 	    }  1939. 	}  1940.  1941. 	/* boxes, boulders, and big statues can't fit into any container */ 1942. 	if (obj->otyp == ICE_BOX || Is_box(obj) || obj->otyp == BOULDER || 1943. 		(obj->otyp == STATUE && bigmonst(&mons[obj->corpsenm]))) { 1944. 		/* 1945. 		 *  xname uses a static result array. Save obj's name 1946. 		 * before current_container's name is computed. Don't 1947. * use the result of strcpy within You --- the order 1948. 		 * of evaluation of the parameters is undefined. 1949. 		 */ 1950. 		Strcpy(buf, the(xname(obj))); 1951. 		You("cannot fit %s into %s.", buf, 1952. 		    the(xname(current_container))); 1953. 		return 0; 1954. 	} 1955.  1956. 	freeinv(obj); 1957. 1958. 	if (obj_is_burning(obj))	/* this used to be part of freeinv */ 1959. 		(void) snuff_lit(obj); 1960. 1961. 	if (floor_container && costly_spot(u.ux, u.uy)) { 1962. 	   if (current_container->no_charge && !obj->unpaid) { 1963. 		/* don't sell when putting the item into your own container */ 1964. 		obj->no_charge = 1; 1965. 	   } else if (obj->oclass != COIN_CLASS) { 1966. 		/* sellobj will take an unpaid item off the shop bill 1967. 		 * note: coins are handled later */ 1968. 		was_unpaid = obj->unpaid ? TRUE : FALSE; 1969. 		sellobj_state(SELL_DELIBERATE); 1970. 		sellobj(obj, u.ux, u.uy); 1971. 		sellobj_state(SELL_NORMAL); 1972. 	   }  1973. 	}  1974. 	if (Icebox && !age_is_relative(obj)) { 1975. 		obj->age = monstermoves - obj->age; /* actual age */ 1976. 		/* stop any corpse timeouts when frozen */ 1977. 		if (obj->otyp == CORPSE && obj->timed) { 1978. 			long rot_alarm = stop_timer(ROT_CORPSE, (genericptr_t)obj); 1979. 			(void) stop_timer(MOLDY_CORPSE, (genericptr_t)obj); 1980. 			(void) stop_timer(REVIVE_MON, (genericptr_t)obj); 1981. 			/* mark a non-reviving corpse as such */ 1982. 			if (rot_alarm) obj->norevive = 1; 1983. 		} 1984. 	} else if (Is_mbag(current_container) && mbag_explodes(obj, 0)) { 1985. 		/* explicitly mention what item is triggering the explosion */ 1986. 		pline( 1987. 	      "As you put %s inside, you are blasted by a magical explosion!",  1988. 		      doname(obj)); 1989. 		if (Has_contents(obj)) { 1990. 		   struct obj *otmp; 1991. 		   while((otmp = container_extract_indestructable(obj))) 1992. 			if (!flooreffects(otmp, u.ux, u.uy, "fall")) 1993. 			   place_object(otmp, u.ux, u.uy); 1994. 		} 1995. 		/* did not actually insert obj yet */ 1996. 		if (was_unpaid) addtobill(obj, FALSE, FALSE, TRUE); 1997. 		if (Has_contents(obj)) 1998. 		   delete_contents(obj); 1999. 		obfree(obj, (struct obj *)0); 2000. 		delete_contents(current_container); 2001. 		if (!floor_container) 2002. 			useup(current_container); 2003. 		else if (obj_here(current_container, u.ux, u.uy)) 2004. 			useupf(current_container, current_container->quan); 2005. 		else 2006. 			panic("in_container: bag not found."); 2007. 2008. 		losehp(d(6,6),"magical explosion", KILLED_BY_AN); 2009. 		current_container = 0;	/* baggone = TRUE; */ 2010. 	} 2011.  2012. 	if (current_container) { 2013. 	   Strcpy(buf, the(xname(current_container))); 2014. 	   You("put %s into %s.", doname(obj), buf); 2015. 2016. 	    /* gold in container always needs to be added to credit */ 2017. 	   if (floor_container && obj->oclass == COIN_CLASS) 2018. 		sellobj(obj, current_container->ox, current_container->oy); 2019. 	   (void) add_to_container(current_container, obj); 2020. 	   current_container->owt = weight(current_container); 2021. 	} 2022. 	/* gold needs this, and freeinv many lines above may cause 2023. 	 * the encumbrance to disappear from the status, so just always 2024. 	 * update status immediately. 2025. 	 */ 2026. 	bot; 2027. 2028. 	return(current_container ? 1 : -1); 2029. } 2030.  2031. STATIC_PTR int 2032. ck_bag(obj) 2033. struct obj *obj; 2034. { 2035. 	return current_container && obj != current_container; 2036. } 2037.  2038. /* Returns: -1 to stop, 1 item was removed, 0 item was not removed. */ 2039. STATIC_PTR int 2040. out_container(obj) 2041. register struct obj *obj; 2042. { 2043. 	register struct obj *otmp; 2044. 	boolean is_gold = (obj->oclass == COIN_CLASS); 2045. 	int res, loadlev; 2046. 	long count; 2047. 2048. 	if (!current_container) { 2049. 		impossible(" no current_container?"); 2050. 		return -1; 2051. 	} else if (is_gold) { 2052. 		obj->owt = weight(obj); 2053. 	} 2054.  2055. 	if(obj->oartifact && !touch_artifact(obj,&youmonst)) return 0; 2056. 2057. 	if (obj->otyp == CORPSE) { 2058. 	   if ( (touch_petrifies(&mons[obj->corpsenm])) && !uarmg  2059. 		 && !Stone_resistance) { 2060. 		if (poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM)) 2061. 		   display_nhwindow(WIN_MESSAGE, FALSE); 2062. 		else { 2063. 		   char kbuf[BUFSZ]; 2064. 2065. 		    Strcpy(kbuf, an(corpse_xname(obj, TRUE))); 2066. 		   pline("Touching %s is a fatal mistake.", kbuf); 2067. 		   Strcpy(kbuf, an(killer_cxname(obj, TRUE))); 2068. 		   instapetrify(kbuf); 2069. 		   return -1; 2070. 		} 2071. 	    }  2072. 	}  2073.  2074. 	count = obj->quan; 2075. 	if ((res = lift_object(obj, current_container, &count, FALSE)) <= 0) 2076. 	   return res; 2077. 2078. 	if (obj->quan != count && obj->otyp != LOADSTONE) 2079. 	   obj = splitobj(obj, count); 2080. 2081. 	/* Remove the object from the list. */ 2082. 	obj_extract_self(obj); 2083. 	current_container->owt = weight(current_container); 2084. 2085. 	if (Icebox && !age_is_relative(obj)) { 2086. 		obj->age = monstermoves - obj->age; /* actual age */ 2087. 		if (obj->otyp == CORPSE) 2088. 			start_corpse_timeout(obj); 2089. 	} 2090. 	/* simulated point of time */ 2091. 2092. 	if(!obj->unpaid && !carried(current_container) &&  2093. 	     costly_spot(current_container->ox, current_container->oy)) { 2094. 		obj->ox = current_container->ox; 2095. 		obj->oy = current_container->oy; 2096. 		addtobill(obj, FALSE, FALSE, FALSE); 2097. 	} 2098. 	if (is_pick(obj) && !obj->unpaid && *u.ushops && shop_keeper(*u.ushops)) 2099. 		verbalize("You sneaky cad! Get out of here with that pick!"); 2100. 2101. 	otmp = addinv(obj); 2102. 	loadlev = near_capacity; 2103. 	prinv(loadlev ? 2104. 	      (loadlev < MOD_ENCUMBER ? 2105. 	      "You have a little trouble removing" : 2106. 	      "You have much trouble removing") : (char *)0,  2107. 	      otmp, count); 2108. 2109. 	if (is_gold) { 2110. #ifndef GOLDOBJ 2111. 		dealloc_obj(obj); 2112. #endif 2113. 		bot;	/* update character's gold piece count immediately */ 2114. 	} 2115. 	return 1; 2116. } 2117.  2118. /* an object inside a cursed bag of holding is being destroyed */ 2119. STATIC_OVL long 2120. mbag_item_gone(held, item) 2121. int held; 2122. struct obj *item; 2123. { 2124.     struct monst *shkp; 2125.    long loss = 0L; 2126. 2127.     if (item->dknown) 2128. 	pline("%s %s vanished!", Doname2(item), otense(item, "have")); 2129.    else 2130. 	You("%s %s disappear!", Blind ? "notice" : "see", doname(item)); 2131. 2132.     if (*u.ushops && (shkp = shop_keeper(*u.ushops)) != 0) { 2133. 	if (held ? (boolean) item->unpaid : costly_spot(u.ux, u.uy)) 2134. 	   loss = stolen_value(item, u.ux, u.uy,  2135. 				(boolean)shkp->mpeaceful, TRUE, TRUE); 2136.    }  2137.     /* [ALI] In Slash'EM we must delete the contents of containers before 2138.     * we call obj_extract_self so that any indestructable items can 2139.     * migrate into the bag of holding. We are also constrained by the 2140.     * need to wait until after we have calculated any loss. 2141.     */  2142.     if (Has_contents(item)) delete_contents(item); 2143.    obj_extract_self(item); 2144.    obfree(item, (struct obj *) 0); 2145.    return loss; 2146. } 2147.  2148. STATIC_OVL void 2149. observe_quantum_cat(box) 2150. struct obj *box; 2151. { 2152.     static NEARDATA const char sc[] = "Schroedinger's Cat"; 2153.    struct obj *deadcat; 2154.    struct monst *livecat; 2155.    xchar ox, oy; 2156. 2157.     box->spe = 0;		/* box->owt will be updated below */ 2158.    if (get_obj_location(box, &ox, &oy, 0)) 2159. 	box->ox = ox, box->oy = oy;	/* in case it's being carried */ 2160. 2161.     /* this isn't really right, since any form of observation 2162.       (telepathic or monster/object/food detection) ought to  2163. force the determination of alive vs dead state; but basing 2164.       it just on opening the box is much simpler to cope with */ 2165.    livecat = rn2(2) ? makemon(&mons[PM_HOUSECAT], 2166. 			       box->ox, box->oy, NO_MINVENT) : 0; 2167.    if (livecat) { 2168. 	livecat->mpeaceful = 1; 2169. 	set_malign(livecat); 2170. 	if (!canspotmon(livecat)) 2171. 	   You("think %s brushed your %s.", something, body_part(FOOT)); 2172. 	else 2173. 	   pline("%s inside the box is still alive!", Monnam(livecat)); 2174. 	(void) christen_monst(livecat, sc); 2175.    } else { 2176. 	deadcat = mk_named_object(CORPSE, &mons[PM_HOUSECAT], 2177. 				  box->ox, box->oy, sc); 2178. 	if (deadcat) { 2179. 	   obj_extract_self(deadcat); 2180. 	   (void) add_to_container(box, deadcat); 2181. 	} 2182. 	pline_The("%s inside the box is dead!",  2183. 	    Hallucination ? rndmonnam : "housecat"); 2184.    }  2185.     box->owt = weight(box); 2186.    return; 2187. } 2188.  2189. #undef Icebox 2190. 2191. /* used by askchain to check for magic bag explosion */ 2192. boolean 2193. container_gone(fn) 2194. int FDECL((*fn), (OBJ_P)); 2195. { 2196.     /* result is only meaningful while use_container is executing */ 2197.    return ((fn == in_container || fn == out_container) && !current_container); 2198. } 2199.  2200. int 2201. use_container(objp, held) 2202. struct obj **objp; 2203. int held; 2204. { 2205. 	struct obj *curr, *otmp, *obj = *objp; 2206. #ifndef GOLDOBJ 2207. 	struct obj *u_gold = (struct obj *)0; 2208. #endif 2209. 	struct monst *shkp; 2210. 	boolean one_by_one, allflag, quantum_cat = FALSE, 2211. 		loot_out = FALSE, loot_in = FALSE; 2212. 	char select[MAXOCLASSES+1]; 2213. 	char qbuf[BUFSZ], emptymsg[BUFSZ], pbuf[QBUFSZ]; 2214. 	long loss = 0L; 2215. 	int cnt = 0, used = 0, lcnt = 0, 2216. 	   menu_on_request; 2217. 2218. 	emptymsg[0] = '\0'; 2219. 	if (nohands(youmonst.data)) { 2220. 		You("have no hands!");	/* not `body_part(HAND)' */ 2221. 		return 0; 2222. 	} else if (!freehand) { 2223. 		You("have no free %s.", body_part(HAND)); 2224. 		return 0; 2225. 	} 2226. 	if (obj->olocked) { 2227. 	   pline("%s to be locked.", Tobjnam(obj, "seem")); 2228. 	   if (held) You("must put it down to unlock."); 2229. 	   return 0; 2230. 	} else if (obj->otrapped) { 2231. 	   if (held) You("open %s...", the(xname(obj))); 2232. 	   (void) chest_trap(obj, HAND, FALSE); 2233. 	   /* even if the trap fails, you've used up this turn */ 2234. 	   if (multi >= 0) {	/* in case we didn't become paralyzed */ 2235. 		nomul(-1); 2236. 		nomovemsg = ""; 2237. 	   }  2238. 	    return 1; 2239. 	} 2240.  2241. 	current_container = obj;	/* for use by in/out_container */ 2242. 	/* from here on out, all early returns go through containerdone */ 2243. 2244. 	if (obj->spe == 1) { 2245. 	   observe_quantum_cat(obj); 2246. 	   used = 1; 2247. 	   quantum_cat = TRUE;	/* for adjusting "it's empty" message */ 2248. 	} 2249. 	/* [ALI] If a container vanishes which contains indestructible 2250. 	 * objects then these will be added to the magic bag. This makes 2251. 	 * it very hard to combine the count and vanish loops so we do 2252. * them seperately. 2253. 	 */ 2254. 	/* Sometimes toss objects if a cursed magic bag. */ 2255. 	if (Is_mbag(obj) && obj->cursed) { 2256. 	   for (curr = obj->cobj; curr; curr = otmp) { 2257. 		otmp = curr->nobj; 2258. 		if (!rn2(13) && !evades_destruction(curr)) { 2259. 		   loss += mbag_item_gone(held, curr); 2260. 		   used = 1; 2261. 		} 2262. 	    }  2263. 	}  2264. 	/* Count the number of contained objects. */ 2265. 	for (curr = obj->cobj; curr; curr = curr->nobj) 2266. 	   cnt++; 2267. 2268. 	if (loss)	/* magic bag lost some shop goods */ 2269. 	   You("owe %ld %s for lost merchandise.", loss, currency(loss)); 2270. 	obj->owt = weight(obj);	/* in case any items were lost */ 2271.   2272. 	if (!cnt) 2273. 	   Sprintf(emptymsg, "%s is %sempty.", Yname2(obj),  2274. 		    quantum_cat ? "now " : ""); 2275. 	if (current_container->otyp == MEDICAL_KIT) { 2276. 	   if (!cnt) 2277. 		pline("%s", emptymsg); 2278. 	   else 2279. 		(void) display_cinventory(current_container); 2280. 	   return 0; 2281. 	} 2282. 	if (cnt || flags.menu_style == MENU_FULL) { 2283. 	   Strcpy(qbuf, "Do you want to take something out of "); 2284. 	   Sprintf(eos(qbuf), "%s?",  2285. 		    safe_qbuf(qbuf, 1, yname(obj), ysimple_name(obj), "it")); 2286. 	   if (flags.menu_style != MENU_TRADITIONAL) { 2287. 		if (flags.menu_style == MENU_FULL) { 2288. 		   int t;  2289. char menuprompt[BUFSZ]; 2290. 		   boolean outokay = (cnt != 0), 2291. 			   inokay = (invent != 0); 2292. 2293. #ifndef GOLDOBJ 2294. 		   if (u.ugold) inokay = TRUE; 2295. #endif 2296. 		   if (!outokay && !inokay) { 2297. 			pline("%s", emptymsg); 2298. 			You("don't have anything to put in."); 2299. 			goto containerdone; 2300. 		   }  2301. 		    menuprompt[0] = '\0'; 2302. 		   if (!cnt) Sprintf(menuprompt, "%s ", emptymsg); 2303. 		   Strcat(menuprompt, "Do what?"); 2304. 		   t = in_or_out_menu(menuprompt, current_container,  2305. 				       outokay, inokay); 2306. 		   if (t <= 0) { 2307. 			used = 0; 2308. 			goto containerdone; 2309. 		   }  2310. 		    loot_out = (t & 0x01) != 0; 2311. 		   loot_in  = (t & 0x02) != 0; 2312. 		} else {	/* MENU_COMBINATION or MENU_PARTIAL */ 2313. 		   loot_out = (yn_function(qbuf, "ynq", 'n') == 'y'); 2314. 		} 2315. 		if (loot_out) { 2316. 		   add_valid_menu_class(0);	/* reset */ 2317. 		   used |= menu_loot(0, current_container, FALSE) > 0; 2318. 		} 2319. 	    } else { 2320. 		/* traditional code */ 2321. ask_again2: 2322. 		menu_on_request = 0; 2323. 		add_valid_menu_class(0);	/* reset */ 2324. 		Strcpy(pbuf, ":ynq"); 2325. 		if (cnt) Strcat(pbuf, "m"); 2326. 		switch (yn_function(qbuf, pbuf, 'n')) { 2327. 		case ':': 2328. 		   container_contents(current_container, FALSE, FALSE); 2329. 		   goto ask_again2; 2330. 		case 'y': 2331. 		   if (query_classes(select, &one_by_one, &allflag, 2332. 				     "take out", current_container->cobj, 2333. 				     FALSE, 2334. #ifndef GOLDOBJ 2335. 				     FALSE, 2336. #endif 2337. 				     &menu_on_request)) { 2338. 			if (askchain((struct obj **)&current_container->cobj, 2339. 				    (one_by_one ? (char *)0 : select), 2340. 				    allflag, out_container, 2341. 				    (int FDECL((*),(OBJ_P)))0, 2342. 				    0, "nodot")) 2343. 			   used = 1; 2344. 		   } else if (menu_on_request < 0) { 2345. 			used |= menu_loot(menu_on_request, 2346. 					  current_container, FALSE) > 0; 2347. 		   }  2348. 		    /*FALLTHRU*/ 2349. 		case 'n': 2350. 		   break; 2351. 		case 'm': 2352. 		   menu_on_request = -2; /* triggers ALL_CLASSES */ 2353. 		   used |= menu_loot(menu_on_request, current_container, FALSE) > 0; 2354. 		   break; 2355. 		case 'q': 2356. 		default: 2357. 		   goto containerdone; 2358. 		} 2359. 	    }  2360. 	} else { 2361. 	   pline("%s", emptymsg);		/* is empty. */ 2362. 	}  2363.  2364. #ifndef GOLDOBJ 2365. 	if (!invent && u.ugold == 0) { 2366. #else 2367. 	if (!invent) { 2368. #endif 2369. 	   /* nothing to put in, but some feedback is necessary */ 2370. 	   You("don't have anything to put in."); 2371. 	   goto containerdone; 2372. 	} 2373. 	if (flags.menu_style != MENU_FULL) { 2374. 	   Sprintf(qbuf, "Do you wish to put %s in?", something); 2375. 	   Strcpy(pbuf, ynqchars); 2376. 	   if (flags.menu_style == MENU_TRADITIONAL && invent && inv_cnt > 0) 2377. 		Strcat(pbuf, "m"); 2378. 	   switch (yn_function(qbuf, pbuf, 'n')) { 2379. 		case 'y': 2380. 		   loot_in = TRUE; 2381. 		   break; 2382. 		case 'n': 2383. 		   break; 2384. 		case 'm': 2385. 		   add_valid_menu_class(0);	  /* reset */ 2386. 		   menu_on_request = -2; /* triggers ALL_CLASSES */ 2387. 		   used |= menu_loot(menu_on_request, current_container, TRUE) > 0; 2388. 		   break; 2389. 		case 'q': 2390. 		default: 2391. 		   goto containerdone; 2392. 	   }  2393. 	}  2394. 	/*  2395. 	 * Gone: being nice about only selecting food if we know we are 2396. 	 * putting things in an ice chest. 2397. 	 */ 2398. 	if (loot_in) { 2399. #ifndef GOLDOBJ 2400. 	   if (u.ugold) { 2401. 		/* 2402. 		 * Hack: gold is not in the inventory, so make a gold object 2403. 		 * and put it at the head of the inventory list. 2404. 		 */ 2405. 		u_gold = mkgoldobj(u.ugold);	/* removes from u.ugold */ 2406. 		u_gold->in_use = TRUE; 2407. 		u.ugold = u_gold->quan;		/* put the gold back */ 2408. 		assigninvlet(u_gold);		/* might end up as NOINVSYM */ 2409. 		u_gold->nobj = invent; 2410. 		invent = u_gold; 2411. 	   }  2412. #endif 2413. 	   add_valid_menu_class(0);	  /* reset */ 2414. 	   if (flags.menu_style != MENU_TRADITIONAL) { 2415. 		used |= menu_loot(0, current_container, TRUE) > 0; 2416. 	   } else { 2417. 		/* traditional code */ 2418. 		menu_on_request = 0; 2419. 		if (query_classes(select, &one_by_one, &allflag, "put in", 2420. 				  invent, FALSE, 2421. #ifndef GOLDOBJ 2422. 				  (u.ugold != 0L), 2423. #endif 2424. 				  &menu_on_request)) { 2425. 		   (void) askchain((struct obj **)&invent,  2426. 				    (one_by_one ? (char *)0 : select), allflag, 2427. 				    in_container, ck_bag, 0, "nodot"); 2428. 		   used = 1; 2429. 		} else if (menu_on_request < 0) { 2430. 		   used |= menu_loot(menu_on_request,  2431. 				      current_container, TRUE) > 0; 2432. 		} 2433. 	    }  2434. 	}  2435.  2436. #ifndef GOLDOBJ 2437. 	if (u_gold && invent && invent->oclass == COIN_CLASS) { 2438. 	   /* didn't stash [all of] it */ 2439. 	   u_gold = invent; 2440. 	   invent = u_gold->nobj; 2441. 	   u_gold->in_use = FALSE; 2442. 	   dealloc_obj(u_gold); 2443. 	} 2444. #endif 2445. 2446.  containerdone: 2447. 	*objp = current_container;	/* might have become null */ 2448. 	current_container = 0;		/* avoid hanging on to stale pointer */ 2449. 	return used; 2450. } 2451.  2452. /* Loot a container (take things out, put things in), using a menu. */ 2453. STATIC_OVL int 2454. menu_loot(retry, container, put_in) 2455. int retry; 2456. struct obj *container; 2457. boolean put_in; 2458. { 2459.     int n, i, n_looted = 0; 2460.    boolean all_categories = TRUE, loot_everything = FALSE; 2461.    char buf[BUFSZ]; 2462.    const char *takeout = "Take out", *putin = "Put in"; 2463.    struct obj *otmp, *otmp2; 2464.    menu_item *pick_list; 2465.    int mflags, res; 2466.    long count; 2467. 2468.     if (retry) { 2469. 	all_categories = (retry == -2); 2470.    } else if (flags.menu_style == MENU_FULL) { 2471. 	all_categories = FALSE; 2472. 	Sprintf(buf,"%s what type of objects?", put_in ? putin : takeout); 2473. 	mflags = put_in ? ALL_TYPES | BUC_ALLBKNOWN | BUC_UNKNOWN : 2474. 		         ALL_TYPES | CHOOSE_ALL | BUC_ALLBKNOWN | BUC_UNKNOWN; 2475. 	n = query_category(buf, put_in ? invent : container->cobj, 2476. 			   mflags, &pick_list, PICK_ANY); 2477. 	if (!n) return 0; 2478. 	for (i = 0; i < n; i++) { 2479. 	   if (pick_list[i].item.a_int == 'A') 2480. 		loot_everything = TRUE; 2481. 	   else if (pick_list[i].item.a_int == ALL_TYPES_SELECTED) 2482. 		all_categories = TRUE; 2483. 	   else 2484. 		add_valid_menu_class(pick_list[i].item.a_int); 2485. 	} 2486. 	free((genericptr_t) pick_list); 2487.    }  2488.  2489.     if (loot_everything) { 2490. 	for (otmp = container->cobj; otmp; otmp = otmp2) { 2491. 	   otmp2 = otmp->nobj; 2492. 	   res = out_container(otmp); 2493. 	   if (res < 0) break; 2494. 	} 2495.     } else { 2496. 	mflags = INVORDER_SORT; 2497. 	if (put_in && flags.invlet_constant) mflags |= USE_INVLET; 2498. 	Sprintf(buf,"%s what?", put_in ? putin : takeout); 2499. 	n = query_objlist(buf, put_in ? invent : container->cobj, 2500. 			  mflags, &pick_list, PICK_ANY,  2501. 			  all_categories ? allow_all : allow_category); 2502. 	if (n) { 2503. 		n_looted = n; 2504. for (i = 0; i < n; i++) { 2505. 		   otmp = pick_list[i].item.a_obj; 2506. 		   count = pick_list[i].count; 2507. 		   if (count > 0 && count < otmp->quan) { 2508. 			otmp = splitobj(otmp, count); 2509. 			/* special split case also handled by askchain */ 2510. 		   }  2511. 		    res = put_in ? in_container(otmp) : out_container(otmp); 2512. 		   if (res < 0) { 2513. 			if (!current_container) { 2514. 			   /* otmp caused current_container to explode; 2515. 			      both are now gone */ 2516. 			   otmp = 0;		/* and break loop */ 2517. 			} else if (otmp && otmp != pick_list[i].item.a_obj) { 2518. 			   /* split occurred, merge again */ 2519. 			   (void) merged(&pick_list[i].item.a_obj, &otmp); 2520. 			} 2521. 			break; 2522. 		   }  2523. 		}  2524. 		free((genericptr_t)pick_list); 2525. 	} 2526.     }  2527.     return n_looted; 2528. } 2529.  2530. STATIC_OVL int 2531. in_or_out_menu(prompt, obj, outokay, inokay) 2532. const char *prompt; 2533. struct obj *obj; 2534. boolean outokay, inokay; 2535. { 2536.     winid win; 2537.    anything any; 2538.    menu_item *pick_list; 2539.    char buf[BUFSZ]; 2540.    int n;  2541. const char *menuselector = iflags.lootabc ? "abc" : "oib"; 2542. 2543.     any.a_void = 0; 2544.    win = create_nhwindow(NHW_MENU); 2545.    start_menu(win); 2546.    if (outokay) { 2547. 	any.a_int = 1; 2548. 	Sprintf(buf,"Take %s out of %s", something, the(xname(obj))); 2549. 	add_menu(win, NO_GLYPH, &any, *menuselector, 0, ATR_NONE, 2550. 			buf, MENU_UNSELECTED); 2551.    }  2552.     menuselector++; 2553.    if (inokay) { 2554. 	any.a_int = 2; 2555. 	Sprintf(buf,"Put %s into %s", something, the(xname(obj))); 2556. 	add_menu(win, NO_GLYPH, &any, *menuselector, 0, ATR_NONE, buf, MENU_UNSELECTED); 2557.    }  2558.     menuselector++; 2559.    if (outokay && inokay) { 2560. 	any.a_int = 3; 2561. 	add_menu(win, NO_GLYPH, &any, *menuselector, 0, ATR_NONE, 2562. 			"Both of the above", MENU_UNSELECTED); 2563.    }  2564.     end_menu(win, prompt); 2565.    n = select_menu(win, PICK_ONE, &pick_list); 2566.    destroy_nhwindow(win); 2567.    if (n > 0) { 2568. 	n = pick_list[0].item.a_int; 2569. 	free((genericptr_t) pick_list); 2570.    }  2571.     return n;  2572. } 2573.  2574. /*pickup.c*/