Source:NetHack 3.1.0/pickup.c

Below is the full text to pickup.c from the source code of NetHack 3.1.0. To link to a particular line, write [[NetHack 3.1.0/pickup.c#line123 ]], for example.

Warning! This is the source code from an old release. For the latest release, see Source code

1.   /*	SCCS Id: @(#)pickup.c	3.1	93/01/04	*/ 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 void FDECL(unsplitobj, (struct obj *,struct obj *,long)); 12.  static void FDECL(simple_look, (struct obj *,BOOLEAN_P)); 13.  static boolean FDECL(query_classes, (char *,boolean *,boolean *, 14.  			     const char *,struct obj *,BOOLEAN_P,BOOLEAN_P)); 15.  static boolean FDECL(pickup_object, (struct obj *,struct obj *)); 16.  static boolean FDECL(mbag_explodes, (struct obj *,int)); 17.  STATIC_PTR int FDECL(in_container,(struct obj *)); 18.  STATIC_PTR int FDECL(ck_bag,(struct obj *)); 19.  STATIC_PTR int FDECL(out_container,(struct obj *)); 20.   21.   /*  22.    *  How much the weight of the given container will change when the given 23.   *  object is removed from it. This calculation must match the one used 24.   *  by weight in mkobj.c.  25. */ 26.   #define DELTA_CWT(cont,obj)		\ 27.      ((cont)->cursed ? (obj)->owt * 2 :	\  28.   		      1 + ((obj)->owt / ((cont)->blessed ? 4 : 2))) 29.   30.   static const char moderateloadmsg[] = "You have a little trouble lifting"; 31.  static const char nearloadmsg[] = "You have much trouble lifting"; 32.   33.   static void 34.  unsplitobj(obj_block, obj_chip, resplit) 35.  register struct obj *obj_block, *obj_chip; 36.  long resplit;	/* non-zero => shift the quantities */ 37.  {  38.   	if (obj_block->nobj != obj_chip) { 39.  		impossible("can't unsplit objects"); 40.  	} else if (resplit) { /* 1st object should be reduced to 'resplit' */ 41.  		obj_chip->quan += (obj_block->quan - resplit); 42.  		obj_block->quan = resplit; 43.  		obj_block->owt = weight(obj_block); 44.  		obj_chip->owt = weight(obj_chip); 45.  	} else {  /* 2nd obj should be merged back into 1st, then destroyed */ 46.  		obj_block->nobj = obj_chip->nobj; 47.  		obj_block->nexthere = obj_chip->nexthere; 48.  		obj_block->quan += obj_chip->quan; 49.  		obj_block->owt = weight(obj_block); 50.  		/* no need to worry about 'unsplitbill'; unsplit only occurs 51.  		   when unable to pick something up, hence we're not dealing 52.  		   with billable objects here (I hope!) 53.  		 */  54.   		dealloc_obj(obj_chip); 55.  	}  56.   }  57.    58.   /* much simpler version of the look-here code; used by query_classes */ 59.  static void 60.  simple_look(otmp, here) 61.  struct obj *otmp;	/* list of objects */ 62.  boolean here;		/* flag for type of obj list linkage */ 63.  {  64.   	/* Neither of the first two cases is expected to happen, since 65.  	 * we're only called after multiple classes of objects have been 66.  	 * detected, hence multiple objects must be present. 67.  	 */  68.   	if (!otmp) { 69.  	    impossible("simple_look(NULL)"); 70.  	} else if (!(here ? otmp->nexthere : otmp->nobj)) { 71.  	    pline("%s", doname(otmp)); 72.  	} else { 73.  	    winid tmpwin = create_nhwindow(NHW_MENU); 74.  	    putstr(tmpwin, 0, ""); 75.  	    do { 76.  		putstr(tmpwin, 0, doname(otmp)); 77.  		otmp = here ? otmp->nexthere : otmp->nobj; 78.  	    } while (otmp); 79.  	    display_nhwindow(tmpwin, TRUE); 80.  	    destroy_nhwindow(tmpwin); 81.  	}  82.   }  83.    84.   int 85.  collect_obj_classes(ilets, otmp, here, incl_gold) 86.  char ilets[]; 87.  register struct obj *otmp; 88.  boolean here, incl_gold; 89.  {  90.   	register int iletct = 0; 91.  	register char c, last_c = '\0'; 92.   93.   	if (incl_gold) 94.  		ilets[iletct++] = def_oc_syms[GOLD_CLASS]; 95.  	ilets[iletct] = '\0'; /* terminate ilets so that index will work */ 96.  	while (otmp) { 97.  		c = def_oc_syms[(int)otmp->oclass]; 98.  		if (c != last_c && !index(ilets, (last_c = c))) 99.  			ilets[iletct++] = c,  ilets[iletct] = '\0'; 100. 		otmp = here ? otmp->nexthere : otmp->nobj; 101. 	}  102.   103.  	return iletct; 104. }  105.   106.  static boolean 107. query_classes(olets, one_at_a_time, everything, action, objs, here, incl_gold) 108. char olets[]; 109. boolean *one_at_a_time, *everything; 110. const char *action; 111. struct obj *objs; 112. boolean here, incl_gold; 113. {  114.  	char ilets[20], inbuf[BUFSZ]; 115. 	int iletct, oletct; 116. 	char qbuf[QBUFSZ]; 117.  118.  	olets[oletct = 0] = '\0'; 119. 	*one_at_a_time = *everything = FALSE; 120. 	iletct = collect_obj_classes(ilets, objs, here, incl_gold); 121. 	if (iletct == 0) { 122. 		return FALSE; 123. 	} else if (iletct == 1) { 124. 		olets[0] = def_char_to_objclass(ilets[0]); 125. 		olets[1] = '\0'; 126. 	} else  {	/* more than one choice available */ 127. 		const char *where = 0; 128. 		register char sym, oc_of_sym, *p; 129. 		/* additional choices */ 130. 		ilets[iletct++] = ' '; 131. 		ilets[iletct++] = 'a'; 132. 		ilets[iletct++] = 'A'; 133. 		ilets[iletct++] = (objs == invent ? 'i' : ':'); 134. 		ilets[iletct] = '\0'; 135. ask_again: 136. 		olets[oletct = 0] = '\0'; 137. 		*one_at_a_time = *everything = FALSE; 138. 		Sprintf(qbuf,"What kinds of thing do you want to %s? [%s]",  139.  			action, ilets); 140. 		getlin(qbuf,inbuf); 141. 		if (*inbuf == '\033') { 142. 			clear_nhwindow(WIN_MESSAGE); 143. 			return FALSE; 144. 		}  145.  		for (p = inbuf; (sym = *p++); ) { 146. 		    /* new A function (selective all) added by GAN 01/09/87 */ 147. 		    if (sym == ' ') continue; 148. 		    else if (sym == 'A') *one_at_a_time = TRUE; 149. 		    else if (sym == 'a') *everything = TRUE; 150. 		    else if (sym == ':') { 151. 			simple_look(objs, here);  /* dumb if objs==invent */ 152. 			goto ask_again; 153. 		    } else if (sym == 'i') { 154. 			(void) display_inventory(NULL, FALSE); 155. 			goto ask_again; 156. 		    } else { 157. 			oc_of_sym = def_char_to_objclass(sym); 158. 			if (index(ilets,sym)) { 159. 			    olets[oletct++] = oc_of_sym; 160. 			    olets[oletct] = '\0'; 161. 			} else { 162. 			    if (!where) 163. 				where = !strcmp(action,"pick up")  ? "here" : 164. 					!strcmp(action,"take out") ? 165. 							    "inside" : ""; 166. 			    if (*where) 167. 				pline("There are no %c's %s.", sym, where); 168. 			    else 169. 				You("have no %c's.", sym); 170. 			}  171.  		    }  172.  		}  173.  		if (!oletct && !*everything) *one_at_a_time = TRUE; 174. 	}  175.  	return TRUE; 176. }  177.   178.  void 179. pickup(all) 180. int all;	/* all >= 0 => yes/no; -count */ 181. {  182.  	register struct obj *obj; 183. 	struct obj *obj2, *objx; 184. 	boolean all_of_a_type = FALSE, selective = FALSE; 185. 	char olets[20]; 186. 	long count; 187.  188.  	count = (all < 0) ? (-1L * all) : 0L; 189. 	if (count) all = 0; 190.  191.  	if(Levitation && !Is_airlevel(&u.uz) && !Is_waterlevel(&u.uz)) { 192. 		if ((multi && !flags.run) || (all && !flags.pickup)) 193. 			read_engr_at(u.ux,u.uy); 194. 		return; 195. 	}  196.   197.  	/* multi && !flags.run means they are in the middle of some other 198. 	 * action, or possibly paralyzed, sleeping, etc.... and they just 199. 	 * teleported onto the object. They shouldn't pick it up. 200. 	 */  201.  	if ((multi && !flags.run) || (all && !flags.pickup)) { 202. 		int ct = 0; 203.  204.  		for (obj = level.objects[u.ux][u.uy]; obj;  205.  						 obj = obj->nexthere) 206. 			if(obj != uchain) 207. 				ct++; 208.  209.  		/* If there are objects here, take a look. 210. 		 */  211.  		if (ct) { 212. 			if (flags.run) 213. 				nomul(0); 214. 			flush_screen(1); 215. 			if (ct < 5) 216. 				(void) dolook; 217. 			else { 218. 				read_engr_at(u.ux,u.uy); 219. 				pline("There are several objects here."); 220. 			}  221.  		} else read_engr_at(u.ux,u.uy); 222. 		return; 223. 	}  224.   225.  	/* check for more than one object */ 226. 	if(!all) { 227. 		register int ct = 0; 228.  229.  		for(obj = level.objects[u.ux][u.uy]; obj; obj = obj->nexthere) 230. 			ct++; 231. 		if(ct < 2) 232. 			all++; 233. 		else { 234. 			pline("There are several objects here."); 235. 			count = 0; 236. 		}  237.  	}  238.   239.  #ifdef POLYSELF 240. 	if (nolimbs(uasmon)) { 241. 		You("cannot pick things up without limbs."); 242. 		return; 243. 	}  244.  #endif 245.  246.  	/* added by GAN 10/24/86 to allow selective picking up */ 247. 	if (!all) { 248. 		if (!query_classes(olets, &selective, &all_of_a_type, 249. 			  "pick up", level.objects[u.ux][u.uy], TRUE, FALSE)) 250. 			return; 251. 	}  252.  	if(all_of_a_type && !olets[0]) all = TRUE; 253.  254.  	for(obj = level.objects[u.ux][u.uy]; obj; obj = obj2) { 255. 		obj2 = obj->nexthere;	/* perhaps obj will be picked up */ 256. 		objx = 0; 257. 		if(flags.run) nomul(0); 258.  259.  		if(!all)  { 260. 		    if(!selective && !index(olets,obj->oclass)) continue; 261.  262.  		    if (!all_of_a_type) { 263. 			char qbuf[QBUFSZ]; 264. 			Sprintf(qbuf,"Pick up %s?", doname(obj)); 265. 			switch ((obj->quan < 2L) ? ynaq(qbuf) : ynNaq(qbuf)) { 266. 			case 'q': return; 267. 			case 'n': continue; 268. 			case 'a': 269. 			    all_of_a_type = TRUE; 270. 			    if (selective) { 271. 				selective = FALSE; 272. 				olets[0] = obj->oclass; 273. 				olets[1] = '\0'; 274. 			    }  275.  			    break; 276. 			case '#':	/* count was entered */ 277. 			    if (!yn_number) continue; /* 0 count => No */ 278. 			    else count = yn_number; 279. 			    /* fall thru :-} */ 280. 			default:	/* 'y' */ 281. 			    break; 282. 			}  283.  		    }  284.  		}  285.   286.  		if (count) { 287. 		    /* Pickup a specific number of items; split the object 288. 		       unless count corresponds to full quantity. 1 special 289. 		       case:  cursed loadstones will remain as merged unit. 290. 		     */  291.  		    if (count < obj->quan &&  292.  			    (!obj->cursed || obj->otyp != LOADSTONE)) { 293. 			objx = splitobj(obj, count); 294. 			if (!objx || objx->nexthere != obj2) 295. 			    impossible("bad object split in pickup"); 296. 		    }  297.  		    count = 0;	/* reset */ 298. 		}  299.  		if (pickup_object(obj, objx)) break; 300. 	}  301.   302.  	/*  303.  	 *  Re-map what is at the hero's location after the pickup so the 304. 	 *  map is correct. 305. 	 */  306.  	newsym(u.ux,u.uy); 307. }  308.   309.  /*  310.   * Pick up an object from the ground or out of a container and add it to  311. * the inventory. Returns true if pickup should break out of its loop. 312.  */  313.  static boolean 314. pickup_object(obj, objx) 315. struct obj *obj, *objx; 316. {  317.  	int wt, nearload; 318. 	long pickquan; 319.  320.  	if (obj == uchain) {    /* do not pick up attached chain */ 321. 	    return FALSE; 322. 	} else if (obj->oartifact && !touch_artifact(obj,&youmonst)) { 323. 	    return FALSE; 324. 	} else if (obj->otyp == GOLD_PIECE) { 325. 	    /*  326.  	     *  Special consideration for gold pieces...  327. */ 328.  	    long iw = (long)max_capacity - ((u.ugold + 50L) / 100L); 329. 	    long gold_capacity = ((-iw) * 100L) - 50L + 99L - u.ugold; 330.  331.  	    if (gold_capacity <= 0L) { 332. 		if (objx) unsplitobj(obj, objx, 0L); 333.        pline("There %s %ld gold piece%s here, but you cannot carry any more.",  334.  			(obj->quan == 1L) ? "is" : "are",  335.  			obj->quan, plur(obj->quan)); 336. 		return FALSE; 337. 	    } else if (gold_capacity < obj->quan) { 338. 		if (objx) unsplitobj(obj, objx, 0L); 339. 		You("can only carry %s of the %ld gold pieces lying here.",  340.  		    gold_capacity == 1L ? "one" : "some", obj->quan); 341. 		pline("%s %ld gold piece%s.",  342.  		    nearloadmsg, gold_capacity, plur(gold_capacity)); 343. 		u.ugold += gold_capacity; 344. 		obj->quan -= gold_capacity; 345. 		costly_gold(obj->ox, obj->oy, gold_capacity); 346. 	    } else { 347. 		u.ugold += obj->quan; 348. 		if ((nearload = near_capacity) != 0) 349. 		    pline("%s %ld gold piece%s.",  350.  			  nearload < MOD_ENCUMBER ?  351.  			  moderateloadmsg : nearloadmsg,  352.  			  obj->quan, plur(obj->quan)); 353. 		else 354. 		    prinv(NULL, obj, 0L); 355. 		costly_gold(obj->ox, obj->oy, obj->quan); 356. 		delobj(obj); 357. 	    }  358.  	    flags.botl = 1; 359. 	    if (flags.run) nomul(0); 360. 	    return FALSE; 361. 	} else if (obj->otyp == CORPSE) { 362.  363.  	    if (obj->corpsenm == PM_COCKATRICE && !uarmg  364.  #ifdef POLYSELF  365.  		&& !resists_ston(uasmon)  366.  #endif  367.  	    ) { 368. #ifdef POLYSELF 369. 		if (poly_when_stoned(uasmon) && polymon(PM_STONE_GOLEM)) 370. 		    display_nhwindow(WIN_MESSAGE, FALSE); 371. 		else 372. #endif 373. 		{  374.  		  pline("Touching the cockatrice corpse is a fatal mistake."); 375. 		    You("turn to stone."); 376. 		    You("die..."); 377. 		    killer_format = KILLED_BY_AN; 378. 		    killer = "cockatrice corpse"; 379. 		    done(STONING); 380. 		}  381.  	    } else if (is_rider(&mons[obj->corpsenm])) { 382. 		pline("At your touch, the corpse suddenly moves..."); 383. 		revive_corpse(obj, 1, FALSE); 384. 		exercise(A_WIS, FALSE); 385. 		return FALSE; 386. 	    }  387.   388.  	} else  if (obj->otyp == SCR_SCARE_MONSTER) { 389. 	    if (obj->blessed) obj->blessed = 0; 390. 	    else if (!obj->spe && !obj->cursed) obj->spe = 1; 391. 	    else { 392. 		pline("The scroll%s turn%s to dust as you pick %s up.",  393.  			plur(obj->quan), (obj->quan == 1L) ? "s" : "",  394.  			(obj->quan == 1L) ? "it" : "them"); 395. 		if (!(objects[SCR_SCARE_MONSTER].oc_name_known) &&  396.  				    !(objects[SCR_SCARE_MONSTER].oc_uname)) 397. 		    docall(obj); 398. 		useupf(obj); 399. 		return FALSE; 400. 	    }  401.  	}  402.   403.  	wt = max_capacity + (int)obj->owt; 404. 	if (obj->otyp == LOADSTONE) 405. 	    goto lift_some;     /* pick it up even if too heavy */ 406. #ifdef POLYSELF 407. 	if (obj->otyp == BOULDER && throws_rocks(uasmon)) { 408. 	    goto lift_some; 409. 	}  410.  #endif 411. 	if (wt > 0) { 412. 	    if (obj->quan > 1L) { 413. 		/* see how many we can lift */ 414. 		long qq, savequan = obj->quan; 415. 		int iw = max_capacity; 416. 		/*  This is correct only because containers */ 417. 		/*  don't merge. -dean		   */ 418. 		for (qq = 1; qq < savequan; qq++) { 419. 			obj->quan = qq; 420. 			if (iw + weight(obj) > 0) 421. 				break; 422. 		}  423.  		obj->quan = savequan; 424. 		qq--; 425. 		/* we can carry qq of them */ 426. 		if (qq) { 427. 		    if (objx) {		/* temporarily unsplit */ 428. 			savequan = obj->quan; 429. 			obj->quan += objx->quan; 430. 		    }  431.  		    You("can only carry %s of the %s lying here.",  432.  			(qq == 1L) ? "one" : "some", doname(obj)); 433. 		    if (objx) {		/* re-do the prior split */ 434. 			obj->quan = savequan; 435. 			unsplitobj(obj, objx, qq); 436. 		    } else {		/* split into two groups */ 437. 			objx = splitobj(obj, qq); 438. 			if (objx->otyp == SCR_SCARE_MONSTER) objx->spe = 0; 439. 		    }  440.  		    goto lift_some; 441. 		}  442.  	    }  443.  	    if (objx) unsplitobj(obj, objx, 0L); 444. 	    pline("There %s %s here, but %s.",  445.  		    (obj->quan == 1L) ? "is" : "are", doname(obj),  446.  		    !invent ? (obj->quan == 1L ? 447. 				"it is too heavy for you to lift" : 448. 				"they are too heavy for you to lift") :  449.  			"you cannot carry any more"); 450. 	    if (obj->otyp == SCR_SCARE_MONSTER) obj->spe = 0; 451. 	    return TRUE; 452. 	}  453.   454.  lift_some: 455. 	if (inv_cnt >= 52) { 456. 	    if (objx) unsplitobj(obj, objx, 0L); 457. 	    Your("knapsack cannot accommodate any more items."); 458. 	    if (obj->otyp == SCR_SCARE_MONSTER) obj->spe = 0; 459. 	    return TRUE; 460. 	}  461.   462.  	pickquan = obj->quan;	/* save number picked up */ 463. 	obj = pick_obj(obj); 464.  465.  	if (!Blind) obj->dknown = 1; 466. 	if (uwep && uwep == obj) mrg_to_wielded = TRUE; 467. 	nearload = near_capacity; 468. 	prinv(nearload > SLT_ENCUMBER ? nearloadmsg :  469.  	      nearload > UNENCUMBERED ? moderateloadmsg : NULL,  470.  	      obj, pickquan); 471. 	mrg_to_wielded = FALSE; 472. 	return FALSE; 473. }  474.   475.  /* Gold never reaches this routine. */ 476.  struct obj * 477. pick_obj(otmp) 478. register struct obj *otmp; 479. {  480.  	freeobj(otmp); 481. 	if (*u.ushops && costly_spot(u.ux, u.uy) &&  482.  	    otmp != uball)     /* don't charge for this - kd, 1/17/90 */ 483. 	   /* sets obj->unpaid if necessary */ 484. 	    addtobill(otmp, TRUE, FALSE, FALSE); 485. 	if(Invisible) newsym(u.ux,u.uy); 486. 	return(addinv(otmp));    /* might merge it with other objects */ 487. }  488.   489.  /*  490.   * prints a message if encumbrance changed since the last check and 491.  * returns the new encumbrance value (from near_capacity). 492.  */  493.  int 494. encumber_msg 495. {  496.      static int oldcap = UNENCUMBERED; 497.     int newcap = near_capacity; 498.  499.      if(oldcap < newcap) { 500. 	switch(newcap) { 501. 	case 1: Your("movements are slowed slightly because of your load."); 502. 		break; 503. 	case 2: You("rebalance your load.  Movement is difficult."); 504. 		break; 505. 	case 3: You("stagger under your heavy load.  Movement is very hard."); 506. 		break; 507. 	default: You("can barely move a handspan with this load!"); 508. 		break; 509. 	}  510.  	flags.botl = 1; 511.     } else if(oldcap > newcap) { 512. 	switch(newcap) { 513. 	case 0: Your("movements are now unencumbered."); 514. 		break; 515. 	case 1: Your("movements are only slowed slightly by your load."); 516. 		break; 517. 	case 2: You("rebalance your load.  Movement is still difficult."); 518. 		break; 519. 	case 3: You("stagger under your load.  Movement is still very hard."); 520. 		break; 521. 	}  522.  	flags.botl = 1; 523.     }  524.   525.      oldcap = newcap; 526.     return (newcap); 527. }  528.   529.  int 530. doloot	/* loot a container on the floor. */ 531.  {  532.  	register struct obj *cobj, *nobj; 533. 	register int c;  534. int timepassed = 0; 535.  536.  	if (Levitation && !Is_airlevel(&u.uz) && !Is_waterlevel(&u.uz)) { 537. 		You("cannot reach the floor."); 538. 		return(0); 539. 	}  540.  	if(is_pool(u.ux, u.uy)) { 541. 		You("cannot loot things that are deep in the water."); 542. 		return(0); 543. 	}  544.   545.  #ifdef POLYSELF 546. 	if(nolimbs(uasmon)) { 547. 		You("cannot loot things without limbs."); 548. 		return(0); 549. 	}  550.  #endif 551.  552.  	for(cobj = level.objects[u.ux][u.uy]; cobj; cobj = nobj) { 553. 		nobj = cobj->nexthere; 554.  555.  		if(Is_container(cobj)) { 556. 		    char qbuf[QBUFSZ]; 557.  558.  		    Sprintf(qbuf, "There is %s here, loot it?", doname(cobj)); 559. 		    c = ynq(qbuf); 560. 		    if(c == 'q') return (timepassed); 561. 		    if(c == 'n') continue; 562.  563.  		    if(cobj->olocked) { 564. 			pline("Hmmm, it seems to be locked."); 565. 			continue; 566. 		    }  567.  		    if(cobj->otyp == BAG_OF_TRICKS) { 568. 			You("carefully open the bag..."); 569. 			pline("It develops a huge set of teeth and bites you!"); 570. 			c = rnd(10); 571. 			if(Half_physical_damage) c = (c+1) / 2; 572. 			losehp(c, "carnivorous bag", KILLED_BY_AN); 573. 			makeknown(BAG_OF_TRICKS); 574. 			timepassed = 1; 575. 			continue; 576. 		    }  577.   578.  		    You("carefully open %s...", the(xname(cobj))); 579. 		    if (cobj->otrapped && chest_trap(cobj, FINGER, FALSE)) { 580. 			timepassed = 1; 581. 			continue;	/* explosion destroyed cobj */ 582. 		    }  583.  		    if(multi < 0) return (1); /* a paralysis trap */ 584.  585.  		    timepassed |= use_container(cobj, 0); 586. 		}  587.  	}  588.  	return (timepassed); 589. }  590.   591.  /*  592.   * Decide whether an object being placed into a magic bag will cause 593.  * it to explode. If the object is a bag itself, check recursively. 594.  */  595.  static boolean 596. mbag_explodes(obj, depthin) 597.     struct obj *obj; 598.     int depthin; 599. {  600.      /* odds: 1/1, 2/2, 3/4, 4/8, 5/16, 6/32, 7/64, 8/128, 9/128, 10/128,... */ 601.      if ((Is_mbag(obj) || (obj->otyp == WAN_CANCELLATION && obj->spe > 0)) &&  602.  	(rn2(1 << (depthin > 7 ? 7 : depthin)) <= depthin)) 603. 	return TRUE; 604.     else if (Is_container(obj)) { 605. 	struct obj *otmp; 606.  607.  	for (otmp = obj->cobj; otmp; otmp = otmp->nobj) 608. 	    if (mbag_explodes(otmp, depthin+1)) return TRUE; 609.     }  610.      return FALSE; 611. }  612.   613.  /* A variable set in use_container, to be used by the callback routines */ 614. /* chk_bg, in_container, and out_container from askchain. */ 615.  static struct obj NEARDATA *current_container; 616. #define Icebox (current_container->otyp == ICE_BOX) 617.  618.  STATIC_PTR int 619. in_container(obj) 620. register struct obj *obj; 621. {  622.  	register struct obj *gold; 623. 	boolean is_gold = (obj->otyp == GOLD_PIECE); 624. 	boolean floor_container = !carried(current_container); 625. 	char buf[BUFSZ]; 626.  627.  	if (!current_container) { 628. 		impossible(" no current_container?"); 629. 		return 0; 630. 	} else if (obj == uball || obj == uchain) { 631. 		You("must be kidding."); 632. 		return 0; 633. 	} else if (obj == current_container) { 634. 		pline("That would be an interesting topological exercise."); 635. 		return 0; 636. 	} else if (obj->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL)) { 637. 		Norep("You cannot %s something you are wearing.",  638.  			Icebox ? "refrigerate" : "stash"); 639. 		return 0; 640. 	} else if ((obj->otyp == LOADSTONE) && obj->cursed) { 641. 		obj->bknown = 1; 642. 	      pline("The stone%s won't leave your person.", plur(obj->quan)); 643. 		return 0; 644. 	} else if (obj->otyp == AMULET_OF_YENDOR ||  645.  		   obj->otyp == CANDELABRUM_OF_INVOCATION ||  646.  		   obj->otyp == BELL_OF_OPENING ||  647.  		   obj->otyp == SPE_BOOK_OF_THE_DEAD) { 648. 	/* Prohibit Amulets in containers; if you allow it, monsters can't  649. * steal them. It also becomes a pain to check to see if someone 650. 	 * has the Amulet. Ditto for the Candelabrum, the Bell and the Book. 651. 	 */  652.  	    pline("%s cannot be confined in such trappings.", The(xname(obj))); 653. 	    return 0; 654. 	}  655.  #ifdef WALKIES 656. 	else if (obj->otyp == LEASH && obj->leashmon != 0) { 657. 		pline("%s is attached to your pet.", The(xname(obj))); 658. 		return 0; 659. 	}  660.  #endif 661. 	else if (obj == uwep) { 662. 		if (welded(obj)) { 663. 			weldmsg(obj, FALSE); 664. 			return 0; 665. 		}  666.  		setuwep((struct obj *) 0); 667. 		if (uwep) return 0;	/* unwielded, died, rewielded */ 668. 	}  669.   670.  	/* boxes can't fit into any container */ 671. 	if (obj->otyp == ICE_BOX || Is_box(obj)) { 672. 		/*  673.  		 *  xname uses a static result array. Save obj's name 674. 		 *  before current_container's name is computed. Don't 675. * use the result of strcpy within You --- the order 676. 		 *  of evaluation of the parameters is undefined. 677. 		 */  678.  		Strcpy(buf, the(xname(obj))); 679. 		You("cannot fit %s into %s.", buf,  680.  		    the(xname(current_container))); 681. 		return 0; 682. 	}  683.   684.  	freeinv(obj); 685.  686.  	if (is_gold) {	/* look for other gold within the container */ 687. 		for (gold = current_container->cobj; gold; gold = gold->nobj) 688. 			if (gold->otyp == GOLD_PIECE) break; 689. 	} else 690. 		gold = 0; 691.  692.  	if (gold) { 693. 		gold->quan += obj->quan; 694. 	} else { 695. 		obj->nobj = current_container->cobj; 696. 		current_container->cobj = obj; 697. 	}  698.   699.  	current_container->owt = weight(current_container); 700.  701.  	Strcpy(buf, the(xname(current_container))); 702. 	You("put %s into %s.", doname(obj), buf); 703.  704.  	if (floor_container && costly_spot(u.ux, u.uy)) { 705. 		sellobj_state(TRUE); 706. 		sellobj(obj, u.ux, u.uy); 707. 		sellobj_state(FALSE); 708. 	}  709.  	(void) snuff_candle(obj); /* must follow the "put" msg */ 710. 	if (Icebox && obj->otyp != OIL_LAMP && obj->otyp != BRASS_LANTERN  711.  			&& !Is_candle(obj)) 712. 		obj->age = monstermoves - obj->age; /* actual age */ 713.  714.  	else if (Is_mbag(current_container) && mbag_explodes(obj, 0)) { 715. 		You("are blasted by a magical explosion!"); 716.  717.  		/* the !floor_container case is taken care of */ 718. 		if(*u.ushops && costly_spot(u.ux, u.uy) && floor_container) { 719. 		    register struct monst *shkp; 720.  721.  		    if ((shkp = shop_keeper(*u.ushops)) != 0) 722. 			(void)stolen_value(current_container, u.ux, u.uy,  723.  					   (boolean)shkp->mpeaceful, FALSE); 724. 		}  725.  		delete_contents(current_container); 726. 		if (!floor_container) 727. 			useup(current_container); 728. 		else if (obj_here(current_container, u.ux, u.uy)) 729. 			useupf(current_container); 730. 		else 731. 			panic("in_container:  bag not found."); 732.  733.  		losehp(d(6,6),"magical explosion", KILLED_BY_AN); 734. 		current_container = 0;	/* baggone = TRUE; */ 735. 	}  736.   737.  	if (is_gold) { 738. 		if (gold) dealloc_obj(obj); 739. 		bot;	/* update character's gold piece count immediately */ 740. 	}  741.   742.  	return(current_container ? 1 : -1); 743. }  744.   745.  STATIC_PTR int 746. ck_bag(obj) 747. struct obj *obj; 748. {  749.  	return current_container && obj != current_container; 750. }  751.   752.  STATIC_PTR int 753. out_container(obj) 754. register struct obj *obj; 755. {  756.  	register struct obj *otmp, *ootmp; 757. 	boolean is_gold = (obj->otyp == GOLD_PIECE); 758. 	int loadlev; 759. 	long quan; 760.  761.  	if (!current_container) { 762. 		impossible(" no current_container?"); 763. 		return -1; 764. 	} else if (is_gold) { 765. 		obj->owt = weight(obj); 766. 	} else if (inv_cnt >= 52) { 767. 		You("have no room to hold anything else."); 768. 		return -1;	/* skips gold too; oh well */ 769. 	}  770.   771.  	if(obj->oartifact && !touch_artifact(obj,&youmonst)) return 0; 772.  773.  	if(obj->otyp != LOADSTONE && max_capacity + (int)obj->owt -  774.  	   (carried(current_container) ? 775. 	    (current_container->otyp == BAG_OF_HOLDING ?  776.  	     (int)DELTA_CWT(current_container,obj) : (int)obj->owt) : 0) > 0) { 777. 		char buf[BUFSZ]; 778.  779.  		Strcpy(buf, doname(obj)); 780. 		pline("There %s %s in %s, but %s.",  781.  			obj->quan==1 ? "is" : "are",  782.  			buf, the(xname(current_container)),  783.  			invent ? "you cannot carry any more"  784.  			: "it is too heavy for you to carry"); 785. 		/* "too heavy for you to lift" is not right if you're carrying 786. 		   the container... */ 787.  		return(0); 788. 	}  789.  	/* Remove the object from the list. */ 790.  	if (obj == current_container->cobj) 791. 		current_container->cobj = obj->nobj; 792. 	else { 793. 		for(otmp = current_container->cobj; otmp->nobj != obj;  794.  							    otmp = otmp->nobj) 795. 			if(!otmp->nobj) panic("out_container"); 796. 		otmp->nobj = obj->nobj; 797. 	}  798.   799.  	current_container->owt = weight(current_container); 800.  801.  	if (Icebox && obj->otyp != OIL_LAMP && obj->otyp != BRASS_LANTERN  802.  			&& !Is_candle(obj)) 803. 		obj->age = monstermoves - obj->age; 804. 	/* simulated point of time */ 805.  806.  	if(!obj->unpaid && !carried(current_container) &&  807.  	     costly_spot(current_container->ox, current_container->oy)) { 808.  809.  		addtobill(obj, FALSE, FALSE, FALSE); 810. 	}  811.   812.  	quan = obj->quan; 813. 	ootmp = addinv(obj); 814. 	loadlev = near_capacity; 815. 	prinv(loadlev ?  816.  	      (loadlev < MOD_ENCUMBER ? 817. 	       "You have a little trouble removing" : 818. 	       "You have much trouble removing") : NULL,  819.  	      ootmp, quan); 820.  821.  	if (is_gold) { 822. 		dealloc_obj(obj); 823. 		bot;	/* update character's gold piece count immediately */ 824. 	}  825.  	return 1; 826. }  827.   828.  /* for getobj: allow counts, allow all types, expect food */ 829. static const char NEARDATA frozen_food[] = 830. 	{ ALLOW_COUNT, ALL_CLASSES, FOOD_CLASS, 0 }; 831.  832.  int 833. use_container(obj, held) 834. register struct obj *obj; 835. register int held; 836. {  837.  	register int cnt = 0; 838. 	register struct obj *curr, *prev, *otmp; 839. 	boolean one_by_one, allflag; 840. 	char select[MAXOCLASSES+1]; 841. 	char qbuf[QBUFSZ]; 842. 	int used = 0, lcnt = 0; 843. 	long loss = 0L; 844. 	register struct monst *shkp; 845.  846.  	current_container = obj;	/* for use by in/out_container */ 847. 	if (current_container->olocked) { 848. 		pline("%s seems to be locked.", The(xname(current_container))); 849. 		if (held) You("must put it down to unlock."); 850. 		return 0; 851. 	}  852.  	/* Count the number of contained objects. Sometimes toss objects if */ 853. 	/* a cursed magic bag. */ 854.  	for(curr = obj->cobj, prev = (struct obj *) 0; curr;  855.  					    prev = curr, curr = otmp) { 856. 	    otmp = curr->nobj; 857. 	    if (Is_mbag(obj) && obj->cursed && !rn2(13)) { 858. 		if (curr->known) 859. 		    pline("%s to have vanished!", The(aobjnam(curr,"seem"))); 860. 		else 861. 		    You("%s %s disappear.", Blind ? "notice" : "see",  862.  							doname(curr)); 863. 		if (prev) 864. 		    prev->nobj = otmp; 865. 		else 866. 		    obj->cobj = otmp; 867.  868.  		if(*u.ushops && (shkp = shop_keeper(*u.ushops))) { 869. 		    if(held) { 870. 			if(curr->unpaid) 871. 			    loss += stolen_value(curr, u.ux, u.uy,  872.  					     (boolean)shkp->mpeaceful, TRUE); 873. 			lcnt++; 874. 		    } else if(costly_spot(u.ux, u.uy)) { 875. 			loss += stolen_value(curr, u.ux, u.uy,  876.  					     (boolean)shkp->mpeaceful, TRUE); 877. 			lcnt++; 878. 		    }  879.  		}  880.  		/* obfree will free all contained objects */ 881. 		obfree(curr, (struct obj *) 0); 882. 	    } else 883. 		cnt++; 884. 	}  885.   886.  	if (cnt && loss) 887. 	    You("owe %ld zorkmids for lost item%s.",  888.  		loss, lcnt > 1 ? "s" : ""); 889.  890.  	current_container->owt = weight(current_container); 891.  892.  	if(!cnt) 893. 	    pline("%s %s is empty.", (held) ? "Your" : "The", xname(obj)); 894. 	else { 895. 	    Sprintf(qbuf, "Do you want to take something out of %s?",  896.  			the(xname(obj))); 897. ask_again: 898. 	    switch (yn_function(qbuf, ":ynq", 'n')) { 899. 	    case ':': 900. 		container_contents(current_container, FALSE, FALSE); 901. 		goto ask_again; 902. 	    case 'y': 903. 		if (query_classes(select, &one_by_one, &allflag, "take out", 904. 				   current_container->cobj, FALSE, FALSE)) { 905. 		    if (askchain((struct obj **)&current_container->cobj, 906. 				 (one_by_one ? (char *)0 : select), allflag, 907. 				 out_container, (int (*))0, 0, "nodot")) 908. 			used = 1; 909. 		}  910.  		/*FALLTHRU*/ 911. 	    case 'n': 912. 		break; 913. 	    case 'q': 914. 	    default: 915. 		return 0; 916. 	    }  917.  	}  918.   919.  	if (!invent && (u.ugold == 0 || Icebox)) return used; 920. 	if (yn_function("Do you wish to put something in?", ynqchars, 'n')  921.  	    != 'y') return used; 922. 	if (Icebox && current_container->dknown) { 923. 		otmp = getobj(frozen_food, "put in"); 924. 		if(!otmp || !in_container(otmp)) 925. 			flags.move = multi = 0; 926. 	} else { 927. 		if (query_classes(select, &one_by_one, &allflag, "put in", 928. 					   invent, FALSE, (u.ugold != 0L))) { 929. 		    struct obj *u_gold = (struct obj *)0; 930. 		    if (u.ugold && (one_by_one || (allflag && !*select) 931. 				    || index(select, GOLD_CLASS))) { 932. 			/* make gold object & insert at head of inventory */ 933. 			u_gold = mkgoldobj(u.ugold);	/*(removes gold too)*/ 934. 			u.ugold = u_gold->quan;		/* put the gold back */ 935. 			u_gold->nobj = invent; 936. 			invent = u_gold; 937. 		    }  938.  		    used = (askchain((struct obj **)&invent, 939. 				(one_by_one ? (char *)0 : select), allflag, 940. 				in_container, ck_bag, 0, "nodot") > 0); 941. 		    if (u_gold && invent && invent->otyp == GOLD_PIECE) { 942. 			/* didn't stash [all of] it */ 943. 			u_gold = invent; 944. 			invent = u_gold->nobj; 945. 			dealloc_obj(u_gold); 946. 		    }  947.  		}  948.  	}  949.   950.  	return used; 951. }  952.   953.  /*pickup.c*/