Source:NetHack 3.2.0/invent.c

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

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

1.   /*	SCCS Id: @(#)invent.c	3.2	96/03/03	*/ 2.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3.    /* NetHack may be freely redistributed. See license for details. */ 4.     5.    #include "hack.h"  6.    #include "artifact.h"  7. 8.   #define NOINVSYM	'#' 9.   #define CONTAINED_SYM	'>'	/* designator for inside a container */ 10.   11.   #ifdef OVL1 12.  static void NDECL(reorder_invent); 13.  static boolean FDECL(mergable,(struct obj *,struct obj *)); 14.  static void FDECL(invdisp_nothing, (const char *,const char *)); 15.  static boolean FDECL(worn_wield_only, (struct obj *)); 16.  static boolean FDECL(only_here, (struct obj *)); 17.  #endif /* OVL1 */ 18.  STATIC_DCL void FDECL(compactify,(char *)); 19.  STATIC_PTR int FDECL(ckunpaid,(struct obj *)); 20.  #ifdef OVLB 21.  static boolean FDECL(this_type_only, (struct obj *)); 22.  static void NDECL(dounpaid); 23.  static struct obj *FDECL(find_unpaid,(struct obj *,struct obj **)); 24.  static void FDECL(fully_identify_obj, (struct obj *)); 25.  static void FDECL(menu_identify, (int)); 26.  static void FDECL(feel_cockatrice, (struct obj *)); 27.  #endif /* OVLB */ 28.  STATIC_DCL char FDECL(obj_to_let,(struct obj *)); 29.   30.    31.   #ifdef OVLB 32.   33.   static int lastinvnr = 51;	/* 0 ... 51 (never saved&restored) */ 34.   35.   #ifdef WIZARD 36.  /* wizards can wish for venom, which will become an invisible inventory 37.   * item without this. putting it in inv_order would mean venom would 38.   * suddenly become a choice for all the inventory-class commands, which 39.   * would probably cause mass confusion. the test for inventory venom 40.   * is only WIZARD and not wizard because the wizard can leave venom lying 41.   * around on a bones level for normal players to find. 42.   */  43.   static char venom_inv[] = { VENOM_CLASS, 0 };	/* (constant) */ 44.  #endif 45.   46.   void 47.  assigninvlet(otmp) 48.  register struct obj *otmp; 49.  {  50.   	boolean inuse[52]; 51.  	register int i;  52. register struct obj *obj; 53.   54.   	for(i = 0; i < 52; i++) inuse[i] = FALSE; 55.  	for(obj = invent; obj; obj = obj->nobj) if(obj != otmp) { 56.  		i = obj->invlet; 57.  		if('a' <= i && i <= 'z') inuse[i - 'a'] = TRUE; else 58.  		if('A' <= i && i <= 'Z') inuse[i - 'A' + 26] = TRUE; 59.  		if(i == otmp->invlet) otmp->invlet = 0; 60.  	}  61.   	if((i = otmp->invlet) &&  62.   	    (('a' <= i && i <= 'z') || ('A' <= i && i <= 'Z'))) 63.  		return; 64.  	for(i = lastinvnr+1; i != lastinvnr; i++) { 65.  		if(i == 52) { i = -1; continue; } 66.  		if(!inuse[i]) break; 67.  	}  68.   	otmp->invlet = (inuse[i] ? NOINVSYM :  69.   			(i < 26) ? ('a'+i) : ('A'+i-26)); 70.  	lastinvnr = i;  71. } 72.    73.   #endif /* OVLB */ 74.  #ifdef OVL1 75.   76.   /* note: assumes ASCII; toggling a bit puts lowercase in front of uppercase */ 77.  #define inv_rank(o) ((o)->invlet ^ 040) 78.   79.   /* sort the inventory; used by addinv and doorganize */ 80.  static void 81.  reorder_invent 82.  {  83.   	struct obj *otmp, *prev, *next; 84.  	boolean need_more_sorting; 85.   86.   	do { 87.  	    /*  88.   	     * We expect at most one item to be out of order, so this 89.  	     * isn't nearly as inefficient as it may first appear. 90.  	     */  91.   	    need_more_sorting = FALSE; 92.  	    for (otmp = invent, prev = 0; otmp; ) { 93.  		next = otmp->nobj; 94.  		if (next && inv_rank(next) < inv_rank(otmp)) { 95.  		    need_more_sorting = TRUE; 96.  		    if (prev) prev->nobj = next; 97.  		    else      invent = next; 98.  		    otmp->nobj = next->nobj; 99.  		    next->nobj = otmp; 100. 		    prev = next; 101. 		} else { 102. 		    prev = otmp; 103. 		    otmp = next; 104. 		}  105.  	    }  106.  	} while (need_more_sorting); 107. }  108.   109.  #undef inv_rank 110.  111.  /* scan a list of objects to see whether another object will merge with 112.    one of them; used in pickup.c */ 113. struct obj * 114. merge_choice(objlist, obj) 115. struct obj *objlist, *obj; 116. {  117.  	if (obj->otyp == SCR_SCARE_MONSTER)	/* punt on these */ 118. 	    return (struct obj *)0; 119. 	while (objlist) { 120. 	    if (mergable(objlist, obj)) return objlist; 121. 	    objlist = objlist->nobj; 122. 	}  123.  	return (struct obj *)0; 124. }  125.   126.  /* merge obj with otmp and delete obj if types agree */ 127. int 128. merged(potmp, pobj) 129. struct obj **potmp, **pobj; 130. {  131.  	register struct obj *otmp = *potmp, *obj = *pobj; 132.  133.  	if(mergable(otmp, obj)) { 134. 		/* Approximate age: we do it this way because if we were to  135. * do it "accurately" (merge only when ages are identical) 136. 		 * we'd wind up never merging any corpses. 137. 		 * otmp->age = otmp->age*(1-proportion) + obj->age*proportion; 138. 		 *  139.  		 * Don't do the age manipulation if lit.  We would need 140. 		 * to stop the burn on both items, then merge the age, 141. 		 * then restart the burn. 142. 		 */  143.  		if (!obj->lamplit) 144. 		    otmp->age = ((otmp->age*otmp->quan) + (obj->age*obj->quan)) 145. 			    / (otmp->quan + obj->quan); 146.  147.  		otmp->quan += obj->quan; 148. 		otmp->owt += obj->owt; 149. 		if(!otmp->onamelth && obj->onamelth) 150. 			otmp = *potmp = oname(otmp, ONAME(obj)); 151. 		obj_extract_self(obj); 152.  153.  		/* really should merge the timeouts */ 154. 		if (obj->lamplit) end_burn(obj, TRUE); 155. 		if (obj->timed) obj_stop_timers(obj);	/* follows end_burn */ 156.  157.  		/* fixup for `#adjust' merging wielded darts, daggers, &c */ 158. 		if (obj->owornmask) { 159. 			otmp->owornmask |= obj->owornmask; 160. 			/* (it isn't necessary to "unwear" `obj' first) */ 161. 			if (otmp->where == OBJ_INVENT) 162. 			    setworn(otmp, otmp->owornmask); 163. #if 0 164. 			/* (this should never be necessary, since items  165.  			    already in a monster's inventory don't ever get  166.  			    merged into other objects [only vice versa]) */ 167. 			else if (otmp->where == OBJ_MINVENT) { 168. 			    if (obj == MON_WEP(otmp->ocarry)) 169. 				MON_WEP(otmp->ocarry) = otmp; 170. 			}  171.  #endif 172. 		}  173.  		obfree(obj,otmp);	/* free(obj), bill->otmp */ 174. 		return(1); 175. 	}  176.  	return 0; 177. }  178.   179.  struct obj * 180. addinv(obj) 181. struct obj *obj; 182. {  183.  	struct obj *otmp, *prev; 184.  185.  	if (obj->where != OBJ_FREE) 186. 		panic("addinv: obj not free"); 187.  188.  	if (obj->oclass == GOLD_CLASS) { 189. 		u.ugold += obj->quan; 190. 		flags.botl = 1; 191. 		return obj; 192. 	} else if (obj->otyp == AMULET_OF_YENDOR) { 193. 		if (u.uhave.amulet) impossible ("already have amulet?"); 194. 		u.uhave.amulet = 1; 195. 	} else if (obj->otyp == CANDELABRUM_OF_INVOCATION) { 196. 		if (u.uhave.menorah) impossible ("already have candelabrum?"); 197. 		u.uhave.menorah = 1; 198. 	} else if (obj->otyp == BELL_OF_OPENING) { 199. 		if (u.uhave.bell) impossible ("already have silver bell?"); 200. 		u.uhave.bell = 1; 201. 	} else if (obj->otyp == SPE_BOOK_OF_THE_DEAD) { 202. 		if (u.uhave.book) impossible ("already have the book?"); 203. 		u.uhave.book = 1; 204. 	} else if (is_quest_artifact(obj)) { 205. 		if (u.uhave.questart) impossible ("already have the artifact?"); 206. 		u.uhave.questart = 1; 207. 		artitouch; 208. 		set_artifact_intrinsic(obj, 1, W_ART); 209. 	} else if(obj->oartifact) { 210. 		set_artifact_intrinsic(obj, 1, W_ART); 211. 	}  212.  	/* merge if possible; find end of chain in the process */ 213. 	for (prev = 0, otmp = invent; otmp; prev = otmp, otmp = otmp->nobj) 214. 	    if (merged(&otmp, &obj)) { 215. 		obj = otmp; 216. 		goto added; 217. 	    }  218.  	/* didn't merge, so insert into chain */ 219. 	if (flags.invlet_constant || !prev) { 220. 	    if (flags.invlet_constant) assigninvlet(obj); 221. 	    obj->nobj = invent;		/* insert at beginning */ 222. 	    invent = obj; 223. 	    if (flags.invlet_constant) reorder_invent; 224. 	} else { 225. 	    prev->nobj = obj;		/* insert at end */ 226. 	    obj->nobj = 0; 227. 	}  228.  	obj->where = OBJ_INVENT; 229.  230.  added: 231. 	if (obj->otyp == LUCKSTONE  232.  	    || (obj->oartifact && spec_ability(obj, SPFX_LUCK))) { 233. 		/* new luckstone must be in inventory by this point 234. 		 * for correct calculation */ 235. 		set_moreluck; 236. 	}  237.  	update_inventory; 238. 	return(obj); 239. }  240.   241.  #endif /* OVL1 */ 242. #ifdef OVLB 243.  244.  /* Add an item to the inventory unless we're fumbling, and give a message. 245.  * If there aren't any free inventory slots, we'll drop it instead. 246.  * If both success and failure messages are NULL, then we're just doing the 247.  * fumbling/slot-limit checking for a silent grab. 248.  */  249.  struct obj * 250. hold_another_object(obj, drop_fmt, drop_arg, hold_msg) 251. struct obj *obj; 252. const char *drop_fmt, *drop_arg, *hold_msg; 253. {  254.  	if (!Blind) obj->dknown = 1;	/* maximize mergibility */ 255. 	if (Fumbling) { 256. 		if (drop_fmt) pline(drop_fmt, drop_arg); 257. 		dropy(obj); 258. 	} else { 259. 		long oquan = obj->quan; 260. 		int prev_encumbr = near_capacity;	/* before addinv */ 261. 		/* encumbrance only matters if it would now become worse 262. 		   than max( current_value, stressed ) */ 263. 		if (prev_encumbr < MOD_ENCUMBER) prev_encumbr = MOD_ENCUMBER; 264. 		obj = addinv(obj); 265. 		if (inv_cnt > 52  266.  		    || ((obj->otyp != LOADSTONE || !obj->cursed) 267. 			&& near_capacity > prev_encumbr)) { 268. 			if (drop_fmt) pline(drop_fmt, drop_arg); 269. 			/* undo any merge which took place */ 270. 			if (obj->quan > oquan) { 271. 			    struct obj *otmp = splitobj(obj, oquan); 272. 			    /* might have merged with weapon */ 273. 			    if (obj->owornmask) 274. 				setworn(otmp, obj->owornmask); 275. 			}  276.  			dropx(obj); 277. 		} else { 278. 			if (hold_msg || drop_fmt) prinv(hold_msg, obj, oquan); 279. 		}  280.  	}  281.  	return obj; 282. }  283.   284.  void 285. useup(obj) 286. register struct obj *obj; 287. {  288.  	/*  Note:  This works correctly for containers because they */ 289. 	/*	   (containers) don't merge. */ 290.  	if(obj->quan > 1L){ 291. #ifndef NO_SIGNAL 292. 		obj->in_use = FALSE;	/* no longer in use */ 293. #endif 294. 		obj->quan--; 295. 		obj->owt = weight(obj); 296. 		update_inventory; 297. 	} else { 298. 		setnotworn(obj); 299. 		freeinv(obj); 300. 		obfree(obj, (struct obj *) 0);	/* deletes contents also */ 301. 	}  302.  }  303.   304.  #endif /* OVLB */ 305. #ifdef OVL3 306.  307.  void 308. freeinv(obj) 309. register struct obj *obj; 310. {  311.  	extract_nobj(obj, &invent); 312.  313.  	if (obj->oclass == GOLD_CLASS) { 314. 		u.ugold -= obj->quan; 315. 		flags.botl = 1; 316. 		return; 317. 	} else if (obj->otyp == AMULET_OF_YENDOR) { 318. 		if (!u.uhave.amulet) impossible ("don't have amulet?"); 319. 		u.uhave.amulet = 0; 320. 	} else if (obj->otyp == CANDELABRUM_OF_INVOCATION) { 321. 		if (!u.uhave.menorah) impossible ("don't have candelabrum?"); 322. 		u.uhave.menorah = 0; 323. 	} else if (obj->otyp == BELL_OF_OPENING) { 324. 		if (!u.uhave.bell) impossible ("don't have silver bell?"); 325. 		u.uhave.bell = 0; 326. 	} else if (obj->otyp == SPE_BOOK_OF_THE_DEAD) { 327. 		if (!u.uhave.book) impossible ("don't have the book?"); 328. 		u.uhave.book = 0; 329. 	} else if (is_quest_artifact(obj)) { 330. 		if(!u.uhave.questart) impossible ("don't have the artifact?"); 331. 		u.uhave.questart = 0; 332. 		set_artifact_intrinsic(obj, 0, W_ART); 333. 	} else if (obj->oartifact) { 334. 		set_artifact_intrinsic(obj, 0, W_ART); 335. 	} else if (obj->otyp == LOADSTONE) { 336. 		curse(obj); 337. 	} else if (obj->otyp == LUCKSTONE  338.  		   || (obj->oartifact && spec_ability(obj, SPFX_LUCK))) { 339. 		set_moreluck; 340. 		flags.botl = 1; 341. 	}  342.  	update_inventory; 343. }  344.   345.  void 346. delallobj(x, y)  347. int x, y; 348. { 349.  	struct obj *otmp, *otmp2; 350.  351.  	for (otmp = level.objects[x][y]; otmp; otmp = otmp2) { 352. 		if (otmp == uball) 353. 			unpunish; 354. 		/* after unpunish, or might get deallocated chain */ 355. 		otmp2 = otmp->nexthere; 356. 		if (otmp == uchain) 357. 			continue; 358. 		delobj(otmp); 359. 	}  360.  }  361.   362.  #endif /* OVL3 */ 363. #ifdef OVL2 364.  365.  /* destroy object in fobj chain (if unpaid, it remains on the bill) */ 366. void 367. delobj(obj) 368. register struct obj *obj; 369. {  370.  	if(obj->otyp == LEASH && obj->leashmon != 0) o_unleash(obj); 371. 	if (obj->otyp == AMULET_OF_YENDOR ||  372.  			obj->otyp == CANDELABRUM_OF_INVOCATION ||  373.  			obj->otyp == BELL_OF_OPENING ||  374.  			obj->otyp == SPE_BOOK_OF_THE_DEAD) { 375. 		/* player might be doing something stupid, but we  376. * can't guarantee that. assume special artifacts 377. 		 * are indestructible via drawbridges, and exploding 378. 		 * chests, and golem creation, and ...  379. */ 380.  		return; 381. 	}  382.  	obj_extract_self(obj); 383. 	newsym(obj->ox,obj->oy); 384. 	obfree(obj, (struct obj *) 0);	/* frees contents also */ 385. }  386.   387.  #endif /* OVL2 */ 388. #ifdef OVL0 389.  390.  struct obj * 391. sobj_at(n,x,y) 392. register int n, x, y;  393. { 394.  	register struct obj *otmp; 395.  396.  	for(otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere) 397. 		if(otmp->otyp == n)  398. return(otmp); 399. 	return((struct obj *)0); 400. }  401.   402.  #endif /* OVL0 */ 403. #ifdef OVLB 404.  405.  struct obj * 406. carrying(type) 407. register int type; 408. {  409.  	register struct obj *otmp; 410.  411.  	for(otmp = invent; otmp; otmp = otmp->nobj) 412. 		if(otmp->otyp == type) 413. 			return(otmp); 414. 	return((struct obj *) 0); 415. }  416.   417.  boolean 418. have_lizard 419. {  420.  	register struct obj *otmp; 421.  422.  	for(otmp = invent; otmp; otmp = otmp->nobj) 423. 		if(otmp->otyp == CORPSE && otmp->corpsenm == PM_LIZARD) 424. 			return(TRUE); 425. 	return(FALSE); 426. }  427.   428.  struct obj * 429. o_on(id, objchn) 430. unsigned int id; 431. register struct obj *objchn; 432. {  433.  	struct obj *temp; 434.  435.  	while(objchn) { 436. 		if(objchn->o_id == id) return(objchn); 437. 		if (Has_contents(objchn) && (temp = o_on(id,objchn->cobj))) 438. 			return temp; 439. 		objchn = objchn->nobj; 440. 	}  441.  	return((struct obj *) 0); 442. }  443.   444.  boolean 445. obj_here(obj, x, y)  446. register struct obj *obj; 447. int x, y;  448. { 449.  	register struct obj *otmp; 450.  451.  	for(otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere) 452. 		if(obj == otmp) return(TRUE); 453. 	return(FALSE); 454. }  455.   456.  #endif /* OVLB */ 457. #ifdef OVL2 458.  459.  struct obj * 460. g_at(x,y) 461. register int x, y;  462. { 463.  	register struct obj *obj = level.objects[x][y]; 464. 	while(obj) { 465. 	    if (obj->oclass == GOLD_CLASS) return obj; 466. 	    obj = obj->nexthere; 467. 	}  468.  	return((struct obj *)0); 469. }  470.   471.  #endif /* OVL2 */ 472. #ifdef OVLB 473.  474.  /* Make a gold object from the hero's gold. */ 475.  struct obj * 476. mkgoldobj(q) 477. register long q;  478. { 479.  	register struct obj *otmp; 480.  481.  	otmp = mksobj(GOLD_PIECE, FALSE, FALSE); 482. 	u.ugold -= q;  483. otmp->quan = q; 484. otmp->owt = weight(otmp); 485. 	flags.botl = 1; 486. 	return(otmp); 487. }  488.   489.  #endif /* OVLB */ 490. #ifdef OVL1 491.  492.  STATIC_OVL void 493. compactify(buf) 494. register char *buf; 495. /* compact a string of inventory letters by dashing runs of letters */ 496. {  497.  	register int i1 = 1, i2 = 1; 498. 	register char ilet, ilet1, ilet2; 499.  500.  	ilet2 = buf[0]; 501. 	ilet1 = buf[1]; 502. 	buf[++i2] = buf[++i1]; 503. 	ilet = buf[i1]; 504. 	while(ilet) { 505. 		if(ilet == ilet1+1) { 506. 			if(ilet1 == ilet2+1) 507. 				buf[i2 - 1] = ilet1 = '-'; 508. 			else if(ilet2 == '-') { 509. 				buf[i2 - 1] = ++ilet1; 510. 				buf[i2] = buf[++i1]; 511. 				ilet = buf[i1]; 512. 				continue; 513. 			}  514.  		}  515.  		ilet2 = ilet1; 516. 		ilet1 = ilet; 517. 		buf[++i2] = buf[++i1]; 518. 		ilet = buf[i1]; 519. 	}  520.  }  521.   522.  /*  523.   * getobj returns: 524.  *	struct obj *xxx:	object to do something with. 525.  *	(struct obj *) 0	error return: no object. 526.  *	&zeroobj		explicitly no object (as in w-). 527.  */  528.  struct obj * 529. getobj(let,word) 530. register const char *let,*word; 531. {  532.  	register struct obj *otmp; 533. 	register char ilet; 534. 	char buf[BUFSZ], qbuf[QBUFSZ]; 535. 	char lets[BUFSZ]; 536. 	register int foo = 0; 537. 	register char *bp = buf; 538. 	xchar allowcnt = 0;	/* 0, 1 or 2 */ 539. 	boolean allowgold = FALSE, usegold = FALSE; 540. 		/* Two possibilities: they can't use gold because it's illegal, 541. 		 * or they can't use gold because they don't have any. 542. 		 */  543.  	boolean allowall = FALSE; 544. 	boolean allownone = FALSE; 545. 	xchar foox = 0; 546. 	long cnt; 547. 	boolean prezero = FALSE; 548.  549.  	if(*let == ALLOW_COUNT) let++, allowcnt = 1; 550. 	if(*let == GOLD_CLASS) let++, 551. 		usegold = TRUE, allowgold = (u.ugold ? TRUE : FALSE); 552.  553.  	/* Equivalent of an "ugly check" for gold */ 554. 	if (usegold && !strcmp(word, "eat") && !metallivorous(uasmon)) 555. 		usegold = allowgold = FALSE; 556.  557.  	if(*let == ALL_CLASSES) let++, allowall = TRUE; 558. 	if(*let == ALLOW_NONE) let++, allownone = TRUE; 559. 	/* "ugly check" for reading fortune cookies, part 1 */ 560. 	/* The normal 'ugly check' keeps the object on the inventory list. 561. 	 * We don't want to do that for shirts/cookies, so the check for 562. 	 * them is handled a bit differently (and also requires that we set  563.  	 * allowall in the caller) 564. 	 */  565.  	if(allowall && !strcmp(word, "read")) allowall = FALSE; 566.  567.  	if(allownone) *bp++ = '-'; 568. 	if(allowgold) *bp++ = def_oc_syms[GOLD_CLASS]; 569. 	if(bp > buf && bp[-1] == '-') *bp++ = ' '; 570.  571.  	ilet = 'a'; 572. 	for (otmp = invent; otmp; otmp = otmp->nobj) { 573. 	    if (!flags.invlet_constant) otmp->invlet = ilet;	/* reassign */ 574. 	    if (!*let || index(let, otmp->oclass)) { 575. 		register int otyp = otmp->otyp; 576. 		bp[foo++] = otmp->invlet; 577.  578.  		/* ugly check: remove inappropriate things */ 579. 		if((!strcmp(word, "take off") && 580. 		    (!(otmp->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL))  581.  		     || (otmp==uarm && uarmc)  582.  #ifdef TOURIST  583.  		     || (otmp==uarmu && (uarm || uarmc))  584.  #endif  585.  		    ))  586.  		|| (!strcmp(word, "wear") && 587. 		     (otmp->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL)))  588.  							/* already worn */  589.  		|| (!strcmp(word, "wield") && 590. 		    (otmp->owornmask & W_WEP))  591.  		    ) { 592. 			foo--; 593. 			foox++; 594. 		}  595.   596.  		/* Second ugly check; unlike the first it won't trigger an  597. * "else" in "you don't have anything else to ___". 598. 		 */  599.  		else if ((!strcmp(word, "wear") && 600. 		    (otmp->oclass == TOOL_CLASS &&  601.  		     otyp != BLINDFOLD && otyp != TOWEL))  602.  		|| (!strcmp(word, "wield") && 603. 		    (otmp->oclass == TOOL_CLASS && !is_weptool(otmp)))  604.  		|| (!strcmp(word, "eat") && !is_edible(otmp))  605.  		|| (!strcmp(word, "sacrifice") && 606. 		    (otyp != CORPSE &&  607.  		     otyp != AMULET_OF_YENDOR && otyp != FAKE_AMULET_OF_YENDOR))  608.  		|| (!strcmp(word, "write with") && 609. 		    (otmp->oclass == TOOL_CLASS &&  610.  		     otyp != MAGIC_MARKER && otyp != TOWEL))  611.  		|| (!strcmp(word, "tin") && 612. 		    (otyp != CORPSE || !tinnable(otmp)))  613.  		|| (!strcmp(word, "rub") && 614. 		    (otmp->oclass == TOOL_CLASS &&  615.  		     otyp != OIL_LAMP && otyp != MAGIC_LAMP &&  616.  		     otyp != BRASS_LANTERN))  617.  		|| ((!strcmp(word, "use or apply") ||  618.  			!strcmp(word, "untrap with")) && 619. 		     /* only applicable weapon is BULLWHIP */ 620. 		    ((otmp->oclass == WEAPON_CLASS && otyp != BULLWHIP)  621.  		|| (otmp->oclass == POTION_CLASS && 622. 		     /* only applicable potion is oil, and it will only 623. 			be offered as a choice when already discovered */ 624. 		     (otyp != POT_OIL || !otmp->dknown ||  625.  		      !objects[POT_OIL].oc_name_known))))  626.  		|| (!strcmp(word, "invoke") && 627. 		    (!otmp->oartifact && !objects[otyp].oc_unique &&  628.  		     (otyp != FAKE_AMULET_OF_YENDOR || otmp->known) &&  629.  		     otyp != CRYSTAL_BALL &&	/* #invoke synonym for apply */  630.  		   /* note: presenting the possibility of invoking non-artifact  631.  		      mirrors and/or lamps is a simply a cruel deception... */  632.  		     otyp != MIRROR && otyp != MAGIC_LAMP &&  633.  		     (otyp != OIL_LAMP ||	/* don't list known oil lamp */ 634. 		      (otmp->dknown && objects[OIL_LAMP].oc_name_known))))  635.  		|| (!strcmp(word, "untrap with") && 636. 		    (otmp->oclass == TOOL_CLASS && otyp != CAN_OF_GREASE))  637.  		|| (!strcmp(word, "charge") && !is_chargeable(otmp))  638.  		    ) 639. 			foo--; 640. 	    } else { 641.  642.  		/* "ugly check" for reading fortune cookies, part 2 */ 643. 		if ((!strcmp(word, "read") && 644. 		    (otmp->otyp == FORTUNE_COOKIE  645.  #ifdef TOURIST  646.  			|| otmp->otyp == T_SHIRT  647.  #endif  648.  		    ))) 649. 			allowall = TRUE; 650. 	    }  651.   652.  	    if(ilet == 'z') ilet = 'A'; else ilet++; 653. 	}  654.  	bp[foo] = 0; 655. 	if(foo == 0 && bp > buf && bp[-1] == ' ') *--bp = 0; 656. 	Strcpy(lets, bp);	/* necessary since we destroy buf */ 657. 	if(foo > 5)			/* compactify string */ 658. 		compactify(bp); 659.  660.  	if(!foo && !allowall && !allowgold && !allownone) { 661. 		You("don't have anything %sto %s.",  662.  			foox ? "else " : "", word); 663. 		return((struct obj *)0); 664. 	}  665.  	for { 666. 		cnt = 0; 667. 		if (allowcnt == 2) allowcnt = 1;  /* abort previous count */ 668. 		if(!buf[0]) { 669. 			Sprintf(qbuf, "What do you want to %s? [*]", word); 670. 		} else { 671. 			Sprintf(qbuf, "What do you want to %s? [%s or ?*]",  672.  				word, buf); 673. 		}  674.  #ifdef REDO 675. 		if (in_doagain) 676. 		    ilet = readchar; 677. 		else 678. #endif 679. 		    ilet = yn_function(qbuf, (char *)0, '\0'); 680. 		if(ilet == '0') prezero = TRUE; 681. 		while(digit(ilet) && allowcnt) { 682. #ifdef REDO 683. 			if (ilet != '?' && ilet != '*')	savech(ilet); 684. #endif 685. 			cnt = 10*cnt + (ilet - '0'); 686. 			allowcnt = 2;	/* signal presence of cnt */ 687. 			ilet = readchar; 688. 		}  689.  		if(digit(ilet)) { 690. 			pline("No count allowed with this command."); 691. 			continue; 692. 		}  693.  		if(index(quitchars,ilet)) { 694. 		    if(flags.verbose) 695. 			pline("Never mind."); 696. 		    return((struct obj *)0); 697. 		}  698.  		if(ilet == '-') { 699. 			return(allownone ? &zeroobj : (struct obj *) 0); 700. 		}  701.  		if(ilet == def_oc_syms[GOLD_CLASS]) { 702. 			if(!usegold){ 703. 				You("cannot %s gold.", word); 704. 				return(struct obj *)0; 705. 			} else if (!allowgold) { 706. 				You("are not carrying any gold."); 707. 				return(struct obj *)0; 708. 			}  709.  			if(cnt == 0 && prezero) return((struct obj *)0); 710. 			/* Historic note: early Nethack had a bug which was 711. 			 * first reported for Larn, where trying to drop 2^32-n 712. 			 * gold pieces was allowed, and did interesting things 713. 			 * to your money supply. The LRS is the tax bureau 714. 			 * from Larn. 715. 			 */  716.  			if(cnt < 0) { 717. 	pline_The("LRS would be very interested to know you have that much."); 718. 				return(struct obj *)0; 719. 			}  720.   721.  			if(!(allowcnt == 2 && cnt < u.ugold)) 722. 				cnt = u.ugold; 723. 			return(mkgoldobj(cnt)); 724. 		}  725.  		if(allowcnt == 2 && !strcmp(word,"throw")) { 726. 			/* permit counts for throwing gold, but don't accept 727. 			 * counts for other things since the throw code will 728. 			 * split off a single item anyway */ 729. 			allowcnt = 1; 730. 			if(cnt == 0 && prezero) return((struct obj *)0); 731. 			if(cnt > 1) { 732. 			    You("can only throw one item at a time."); 733. 			    continue; 734. 			}  735.  		}  736.  		if(ilet == '?' || ilet == '*') { 737. 		    ilet = display_inventory(ilet=='?' ? lets:(char *)0, TRUE); 738. 		    if(!ilet) continue; 739. 		    if(ilet == '\033') { 740. 			if(flags.verbose) 741. 			    pline("Never mind."); 742. 			return((struct obj *)0); 743. 		    }  744.  		    /* they typed a letter (not a space) at the prompt */ 745. 		}  746.  #ifdef REDO 747. 		savech(ilet); 748. #endif 749. 		for (otmp = invent; otmp; otmp = otmp->nobj) 750. 			if (otmp->invlet == ilet) break; 751. 		if(!otmp) { 752. 			You("don't have that object."); 753. #ifdef REDO 754. 			if (in_doagain) return((struct obj *) 0); 755. #endif 756. 			continue; 757. 		} else if (cnt < 0 || otmp->quan < cnt) { 758. 			You("don't have that many!  You have only %ld.",  759.  			    otmp->quan); 760. #ifdef REDO 761. 			if (in_doagain) return((struct obj *) 0); 762. #endif 763. 			continue; 764. 		}  765.  		break; 766. 	}  767.  	if(!allowall && let && !index(let,otmp->oclass)) { 768. 		pline(silly_thing_to, word); 769. 		return((struct obj *)0); 770. 	}  771.  	if(allowcnt == 2) {	/* cnt given */ 772. 		if(cnt == 0) return (struct obj *)0; 773. 		if(cnt != otmp->quan) { 774. 			register struct obj *obj = splitobj(otmp, cnt); 775. 		/* Very ugly kludge necessary to prevent someone from trying 776. 		 * to drop one of several loadstones and having the loadstone 777. 		 * now be separate. 778. 		 */  779.  			if (!strcmp(word, "drop") &&  780.  			    obj->otyp == LOADSTONE && obj->cursed) 781. 				otmp->corpsenm = obj->invlet; 782. 			if(otmp == uwep) setuwep(obj); 783. 		}  784.  	}  785.  	return(otmp); 786. }  787.   788.  #endif /* OVL1 */ 789. #ifdef OVLB 790.  791.  STATIC_PTR int 792. ckunpaid(otmp) 793. register struct obj *otmp; 794. {  795.  	return((int)(otmp->unpaid)); 796. }  797.   798.  boolean 799. wearing_armor 800. {  801.  	return((boolean)(uarm || uarmc || uarmf || uarmg || uarmh || uarms 802. #ifdef TOURIST 803. 		|| uarmu 804. #endif 805. 		));  806.  }  807.   808.  boolean 809. is_worn(otmp) 810. register struct obj *otmp; 811. {  812.      return((boolean)(!!(otmp->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL | W_WEP)))); 813. }  814.   815.  static NEARDATA const char removeables[] = 816. 	{ ARMOR_CLASS, WEAPON_CLASS, RING_CLASS, AMULET_CLASS, TOOL_CLASS, 0 }; 817.  818.  /* interactive version of getobj - used for Drop, Identify and */ 819. /* Takeoff (A). Return the number of times fn was called successfully */ 820. /* If combo is TRUE, we just use this to get a category list */ 821. int 822. ggetobj(word, fn, mx, combo) 823. const char *word; 824. int FDECL((*fn),(OBJ_P)), mx; 825. boolean combo;		/* combination menu flag */ 826. {  827.  	int FDECL((*ckfn),(OBJ_P)) = (int FDECL((*),(OBJ_P))) 0; 828. 	boolean FDECL((*filter),(OBJ_P)) = (boolean FDECL((*),(OBJ_P))) 0; 829. 	boolean takeoff, ident, allflag, m_seen; 830. 	int oletct, iletct, allowgold, unpaid, oc_of_sym; 831. 	char sym, *ip, olets[MAXOCLASSES+5], ilets[MAXOCLASSES+5]; 832. 	char buf[BUFSZ], qbuf[QBUFSZ]; 833.  834.  	allowgold = (u.ugold && !strcmp(word, "drop")) ? 1 : 0; 835.  	takeoff = ident = allflag = m_seen = FALSE; 836. 	if(!invent && !allowgold){ 837. 		You("have nothing to %s.", word); 838. 		return(0); 839. 	}  840.  	if (combo) add_valid_menu_class(0);	/* reset */ 841. 	if (!strcmp(word, "take off")) { 842. 	    takeoff = TRUE; 843. 	    filter = is_worn; 844. 	} else if (!strcmp(word, "identify")) { 845. 	    ident = TRUE; 846. 	    filter = not_fully_identified; 847. 	}  848.   849.  	iletct = collect_obj_classes(ilets, invent,  850.  				     FALSE, (allowgold != 0), filter); 851. 	unpaid = count_unpaid(invent); 852.  853.  	if (ident && !iletct) { 854. 	    return -1;		/* no further identifications */ 855. 	} else if (!takeoff && (unpaid || invent)) { 856. 	    ilets[iletct++] = ' '; 857. 	    if (unpaid) ilets[iletct++] = 'u'; 858. 	    if (invent) ilets[iletct++] = 'a'; 859. 	} else if (takeoff && invent) { 860. 	    ilets[iletct++] = ' '; 861. 	}  862.  	ilets[iletct++] = 'i'; 863. 	if (!combo) 864. 	    ilets[iletct++] = 'm';	/* allow menu presentation on request */ 865. 	ilets[iletct] = '\0'; 866.  867.  	for  { 868. 	    Sprintf(qbuf,"What kinds of thing do you want to %s? [%s]",  869.  		    word, ilets); 870. 	    getlin(qbuf, buf); 871. 	    if (buf[0] == '\033') return(0); 872. 	    if (index(buf, 'i')) 873. 		(void) display_inventory((char *)0, FALSE); 874. 	    else 875. 		break; 876. 	}  877.   878.  	ip = buf; 879. 	olets[oletct = 0] = '\0'; 880. 	while ((sym = *ip++) != '\0') { 881. 	    if (sym == ' ') continue; 882. 	    oc_of_sym = def_char_to_objclass(sym); 883. 	    if (takeoff && !(uwep && oc_of_sym == uwep->oclass) &&  884.  		    (oc_of_sym != MAXOCLASSES)) { 885. 		if (!index(removeables, oc_of_sym)) { 886. 		    pline("Not applicable."); 887. 		    return 0; 888. 		} else if (oc_of_sym == ARMOR_CLASS && !wearing_armor) { 889. 		    You("are not wearing any armor."); 890. 		    return 0; 891. 		} else if (oc_of_sym == WEAPON_CLASS && !uwep) { 892. 		    You("are not wielding anything."); 893. 		    return 0; 894. 		} else if (oc_of_sym == RING_CLASS && !uright && !uleft) { 895. 		    You("are not wearing rings."); 896. 		    return 0; 897. 		} else if (oc_of_sym == AMULET_CLASS && !uamul) { 898. 		    You("are not wearing an amulet."); 899. 		    return 0; 900. 		} else if (oc_of_sym == TOOL_CLASS && !ublindf) { 901. 		    You("are not wearing a blindfold."); 902. 		    return 0; 903. 		}  904.  	    }  905.   906.  	    if (oc_of_sym == GOLD_CLASS && !combo) { 907. 		if (allowgold == 1) 908. 		    (*fn)(mkgoldobj(u.ugold)); 909. 		else if (!u.ugold) 910. 		    You("have no gold."); 911. 		allowgold = 2; 912. 	    } else if (sym == 'a' || sym == 'A') { 913. 		allflag = TRUE; 914. 	    } else if (sym == 'u' || sym == 'U') { 915. 		add_valid_menu_class('u'); 916. 		ckfn = ckunpaid; 917. 	    } else if (sym == 'm') { 918. 		m_seen = TRUE; 919. 	    } else if (oc_of_sym == MAXOCLASSES) { 920. 		You("don't have any %c's.", sym); 921. 	    } else if (oc_of_sym != VENOM_CLASS) {	/* suppress venom */ 922. 		if (!index(olets, oc_of_sym)) { 923. 		    add_valid_menu_class(oc_of_sym); 924. 		    olets[oletct++] = oc_of_sym; 925. 		    olets[oletct] = 0; 926. 		}  927.  	    }  928.  	}  929.   930.  	if (m_seen) 931. 	    return (allflag || (!oletct && ckfn != ckunpaid)) ? -2 : -3; 932.  	else if (flags.menu_style != MENU_TRADITIONAL && combo && !allflag) 933. 	    return 0; 934. 	else if (allowgold == 2 && !oletct) 935. 	    return 1;	/* you dropped gold (or at least tried to) */ 936. 	else 937. 	    return askchain(&invent, olets, allflag, fn, ckfn, mx, word); 938. }  939.   940.  /*  941.   * Walk through the chain starting at objchn and ask for all objects 942.  * with olet in olets (if nonNULL) and satisfying ckfn (if nonnull) 943.  * whether the action in question (i.e., fn) has to be performed. 944.  * If allflag then no questions are asked. Max gives the max nr of 945. * objects to be treated. Return the number of objects treated. 946.  */  947.  int 948. askchain(objchn, olets, allflag, fn, ckfn, mx, word) 949. struct obj **objchn; 950. register int allflag, mx; 951. register const char *olets, *word;	/* olets is an Obj Class char array */ 952. register int FDECL((*fn),(OBJ_P)), FDECL((*ckfn),(OBJ_P)); 953. {  954.  	register struct obj *otmp, *otmp2; 955. 	register char sym, ilet; 956. 	register int cnt = 0, dud = 0, tmp; 957. 	boolean takeoff, nodot, ident, ininv; 958. 	char qbuf[QBUFSZ]; 959.  960.  	takeoff = !strcmp(word, "take off"); 961. 	ident = !strcmp(word, "identify"); 962. 	nodot = (!strcmp(word, "nodot") || !strcmp(word, "drop") ||  963.  		 ident || takeoff); 964. 	ininv = (*objchn == invent); 965. 	/* Changed so the askchain is interrogated in the order specified. 966. 	 * For example, if a person specifies =/ then first all rings will be  967. * asked about followed by all wands -dgk 968. 	 */  969.  nextclass: 970. 	ilet = 'a'-1; 971. 	if (*objchn && (*objchn)->oclass == GOLD_CLASS) 972. 		ilet--;		/* extra iteration */ 973. 	for (otmp = *objchn; otmp; otmp = otmp2) { 974. 		if(ilet == 'z') ilet = 'A'; else ilet++; 975. 		otmp2 = otmp->nobj; 976. 		if (olets && *olets && otmp->oclass != *olets) continue; 977. 		if (takeoff && !is_worn(otmp)) continue; 978. 		if (ident && !not_fully_identified(otmp)) continue; 979. 		if (ckfn && !(*ckfn)(otmp)) continue; 980. 		if (!allflag) { 981. 			Strcpy(qbuf, !ininv ? doname(otmp) :  982.  				xprname(otmp, (char *)0, ilet, !nodot, 0L)); 983. 			Strcat(qbuf, "?"); 984. 			sym = (takeoff || ident || otmp->quan < 2L) ? 985. 				nyaq(qbuf) : nyNaq(qbuf); 986. 		}  987.  		else	sym = 'y'; 988.  989.  		if (sym == '#') { 990. 		 /* Number was entered; split the object unless it corresponds 991. 		    to 'none' or 'all'. 2 special cases: cursed loadstones and 992. 		    welded weapons (eg, multiple daggers) will remain as merged 993. 		    unit; done to avoid splitting an object that won't be  994. droppable (even if we're picking up rather than dropping). 995. 		  */  996.  		    if (!yn_number) 997. 			sym = 'n'; 998. 		    else { 999. 			sym = 'y'; 1000. 			if (yn_number < otmp->quan && !welded(otmp) && 1001. 			    (!otmp->cursed || otmp->otyp != LOADSTONE)) { 1002. 			   struct obj *otmpx = splitobj(otmp, yn_number); 1003. 			   if (!otmpx || otmpx->nobj != otmp2) 1004. 				impossible("bad object split in askchain"); 1005. 			   /* assume other worn items aren't mergable */ 1006. 			   if (otmp == uwep) setuwep(otmpx); 1007. 			} 1008. 		    }  1009. 		}  1010. 		switch(sym){ 1011. 		case 'a': 1012. 			allflag = 1; 1013. 		case 'y': 1014. 			tmp = (*fn)(otmp); 1015. 			if(tmp < 0) goto ret; 1016. 			cnt += tmp; 1017. 			if(--mx == 0) goto ret; 1018. 		case 'n': 1019. 			if(nodot) dud++; 1020. 		default: 1021. 			break; 1022. 		case 'q': 1023. 			/* special case for seffects */ 1024. 			if (ident) cnt = -1; 1025. 			goto ret; 1026. 		} 1027. 	}  1028. 	if (olets && *olets && *++olets) 1029. 		goto nextclass; 1030. 	if(!takeoff && (dud || cnt)) pline("That was all."); 1031. 	else if(!dud && !cnt) pline("No applicable objects."); 1032. ret: 1033. 	return(cnt); 1034. } 1035.  1036.  1037. /*  1038.  *	Object identification routines: 1039. */  1040.  1041. /* make an object actually be identified; no display updating */ 1042. static void 1043. fully_identify_obj(otmp) 1044. struct obj *otmp; 1045. { 1046.     makeknown(otmp->otyp); 1047.    otmp->known = otmp->dknown = otmp->bknown = otmp->rknown = 1; 1048.    if (otmp->otyp == EGG && otmp->corpsenm != NON_PM) 1049. 	learn_egg_type(otmp->corpsenm); 1050. } 1051.  1052. /* ggetobj callback routine; identify an object and give immediate feedback */ 1053. int 1054. identify(otmp) 1055. struct obj *otmp; 1056. { 1057.     fully_identify_obj(otmp); 1058.    prinv((char *)0, otmp, 0L); 1059.    return 1; 1060. } 1061.  1062. /* menu of unidentified objects; select and identify up to id_limit of them */ 1063. static void 1064. menu_identify(id_limit) 1065. int id_limit; 1066. { 1067.     menu_item *pick_list; 1068.    int n, i, first = 1; 1069.    char buf[BUFSZ]; 1070.    /* assumptions:  id_limit > 0 and at least one unID'd item is present */ 1071. 1072.     while (id_limit) { 1073. 	Sprintf(buf, "What would you like to identify %s?", 1074. 		first ? "first" : "next"); 1075. 	n = query_objlist(buf, invent, SIGNAL_NOMENU|USE_INVLET|INVORDER_SORT, 1076. 		&pick_list, PICK_ANY, not_fully_identified); 1077. 1078. 	if (n > 0) { 1079. 	   if (n > id_limit) n = id_limit; 1080. 	   for (i = 0; i < n; i++, id_limit--) 1081. 		(void) identify(pick_list[i].item.a_obj); 1082. 	   free((genericptr_t) pick_list); 1083. 	   mark_synch; /* Before we loop to pop open another menu */ 1084. 	} else { 1085. 	   if (n < 0) pline("That was all."); 1086. 	   id_limit = 0; /* Stop now */ 1087. 	} 1088. 	first = 0; 1089.    }  1090. }  1091.  1092. /* dialog with user to identify a given number of items; 0 means all */ 1093. void 1094. identify_pack(id_limit) 1095. int id_limit; 1096. { 1097.     struct obj *obj, *the_obj; 1098.    int n, unid_cnt; 1099. 1100.     unid_cnt = 0; 1101.    the_obj = 0;		/* if unid_cnt ends up 1, this will be it */ 1102.    for (obj = invent; obj; obj = obj->nobj) 1103. 	if (not_fully_identified(obj)) ++unid_cnt, the_obj = obj; 1104. 1105.     if (!unid_cnt) { 1106. 	You("have already identified all of your possessions."); 1107.    } else if (!id_limit) { 1108. 	/* identify everything */ 1109. 	if (unid_cnt == 1) { 1110. 	   (void) identify(the_obj); 1111. 	} else { 1112. 1113. 	    /* TODO:  use fully_identify_obj and cornline/menu/whatever here */ 1114. 	   for (obj = invent; obj; obj = obj->nobj) 1115. 		if (not_fully_identified(obj)) (void) identify(obj); 1116. 1117. 	}  1118.     } else { 1119. 	/* identify up to `id_limit' items */ 1120. 	n = 0; 1121. 	if (flags.menu_style == MENU_TRADITIONAL) 1122. 	   do { 1123. 		n = ggetobj("identify", identify, id_limit, FALSE); 1124. 		if (n < 0) break; /* quit or no eligible items */ 1125. 	   } while ((id_limit -= n) > 0); 1126. 	if (n == 0 || n < -1) 1127. 	   menu_identify(id_limit); 1128.    }  1129.     update_inventory; 1130. } 1131.  1132. #endif /* OVLB */ 1133. #ifdef OVL2 1134. 1135. STATIC_OVL char 1136. obj_to_let(obj)	/* should of course only be called for things in invent */ 1137. register struct obj *obj; 1138. { 1139. 	if (obj->oclass == GOLD_CLASS) 1140. 		return GOLD_SYM; 1141. 	if (!flags.invlet_constant) { 1142. 		obj->invlet = NOINVSYM; 1143. 		reassign; 1144. 	} 1145. 	return obj->invlet; 1146. } 1147.  1148. /*  1149.  * Print the indicated quantity of the given object. If quan == 0L then use 1150. * the current quantity. 1151. */  1152. void 1153. prinv(prefix, obj, quan) 1154. const char *prefix; 1155. register struct obj *obj; 1156. long quan; 1157. { 1158. 	long savequan = obj->quan; 1159. 	if (quan) obj->quan = quan; 1160. 	if (!prefix) prefix = ""; 1161. 	pline("%s%s%s", 1162. 	      prefix, *prefix ? " " : "",  1163. 	      xprname(obj, (char *)0, obj_to_let(obj), TRUE, 0L)); 1164. 	if (quan) obj->quan = savequan; 1165. } 1166.  1167. #endif /* OVL2 */ 1168. #ifdef OVL1 1169. 1170. char * 1171. xprname(obj, txt, let, dot, cost) 1172. struct obj *obj; 1173. const char *txt;	/* text to print instead of obj */ 1174. char let;		/* inventory letter */ 1175. boolean dot;		/* append period; (dot && cost => Iu) */ 1176. long cost;		/* cost (for inventory of unpaid or expended items) */ 1177. { 1178. #ifdef LINT	/* handle static char li[BUFSZ]; */ 1179. 	char li[BUFSZ]; 1180. #else 1181. 	static char li[BUFSZ]; 1182. #endif 1183. 	boolean use_invlet = flags.invlet_constant && let != CONTAINED_SYM; 1184.    /*  1185.      * If let is: 1186.     *	*  Then obj == null and we are printing a total amount. 1187.     *	>  Then the object is contained and doesn't have an inventory letter. 1188.     */  1189.     if (cost != 0 || let == '*') { 1190. 	/* if dot is true, we're doing Iu, otherwise Ix */ 1191. 	Sprintf(li, "%c - %-45s %6ld zorkmid%s", 1192. 		(dot && use_invlet ? obj->invlet : let), 1193. 		(txt ? txt : doname(obj)), cost, plur(cost)); 1194.    } else if (obj->oclass == GOLD_CLASS) { 1195. 	Sprintf(li, "%ld gold piece%s%s", obj->quan, plur(obj->quan), 1196. 		(dot ? "." : "")); 1197.     } else { 1198. 	/* ordinary inventory display or pickup message */ 1199. 	Sprintf(li, "%c - %s%s", 1200. 		(use_invlet ? obj->invlet : let), 1201. 		(txt ? txt : doname(obj)), (dot ? "." : "")); 1202.     }  1203.     return li; 1204. } 1205.  1206. #endif /* OVL1 */ 1207. #ifdef OVLB 1208. 1209. /* the 'i' command */ 1210. int 1211. ddoinv 1212. { 1213. 	(void) display_inventory((char *)0, FALSE); 1214. 	return 0; 1215. } 1216.  1217. /*  1218.  * find_unpaid 1219. *  1220.  * Scan the given list of objects. If last_found is NULL, return the first 1221. * unpaid object found. If last_found is not NULL, then skip over unpaid 1222. * objects until last_found is reached, then set last_found to NULL so the 1223. * next unpaid object is returned. This routine recursively follows 1224. * containers. 1225. */  1226. static struct obj * 1227. find_unpaid(list, last_found) 1228.    struct obj *list, **last_found; 1229. { 1230.     struct obj *obj; 1231. 1232.     while (list) { 1233. 	if (list->unpaid) { 1234. 	   if (*last_found) { 1235. 		/* still looking for previous unpaid object */ 1236. 		if (list == *last_found) 1237. 		   *last_found = (struct obj *) 0; 1238. 	   } else 1239. 		return (*last_found = list); 1240. 	} 1241. 	if (Has_contents(list)) { 1242. 	   if ((obj = find_unpaid(list->cobj, last_found)) != 0) 1243. 		return obj; 1244. 	} 1245. 	list = list->nobj; 1246.    }  1247.     return (struct obj *) 0; 1248. } 1249.  1250. /*  1251.  * If lets == NULL or "", list all objects in the inventory. Otherwise, 1252. * list all objects with object classes that match the order in lets. 1253. *  1254.  * Returns the letter identifier of a selected item, or 0 if nothing 1255. * was selected. 1256. */  1257. char 1258. display_inventory(lets, want_reply) 1259. register const char *lets; 1260. boolean want_reply; 1261. { 1262. 	struct obj *otmp; 1263. 	char ilet, ret; 1264. 	char *invlet = flags.inv_order; 1265. 	int n, classcount; 1266. 	winid win;				/* windows being used */ 1267. 	static winid local_win = WIN_ERR;	/* window for partial menus */ 1268. 	anything any; 1269. 	menu_item *selected; 1270. 1271. 	/* overriden by global flag */ 1272. 	if (flags.perm_invent) { 1273. 	   win = (lets && *lets) ? local_win : WIN_INVEN; 1274. 	   /* create the first time used */ 1275. 	   if (win == WIN_ERR) 1276. 		win = local_win = create_nhwindow(NHW_MENU); 1277. 	} else 1278. 	   win = WIN_INVEN; 1279. 1280. 	if (!invent) { 1281. 	   pline("Not carrying anything%s.", u.ugold ? " except gold" : ""); 1282. 	   return 0; 1283. 	} 1284.  1285. 	/* oxymoron? temporarily assign permanent inventory letters */ 1286. 	if (!flags.invlet_constant) reassign; 1287. 1288. 	if (lets && strlen(lets) == 1) { 1289. 	   /* when only one item of interest, use pline instead of menus; 1290. 	      we actually use a fake message-line menu in order to allow 1291. 	      the user to perform selection at the --More-- prompt for tty */ 1292. 	   ret = '\0'; 1293. 	   for (otmp = invent; otmp; otmp = otmp->nobj) { 1294. 		if (otmp->invlet == lets[0]) { 1295. 		   ret = message_menu(lets[0],  1296. 				  want_reply ? PICK_ONE : PICK_NONE,  1297. 				  xprname(otmp, (char *)0, lets[0], TRUE, 0L)); 1298. 		   break; 1299. 		} 1300. 	    }  1301. 	    return ret; 1302. 	} 1303.  1304. 	start_menu(win); 1305. nextclass: 1306. 	classcount = 0; 1307. 	any.a_void = 0;		/* set all bits to zero */ 1308. 	for(otmp = invent; otmp; otmp = otmp->nobj) { 1309. 		ilet = otmp->invlet; 1310. 		if(!lets || !*lets || index(lets, ilet)) { 1311. 			if (!flags.sortpack || otmp->oclass == *invlet) { 1312. 			   if (flags.sortpack && !classcount) { 1313. 				any.a_void = 0;		/* zero */ 1314. 				add_menu(win, NO_GLYPH, &any, 0, ATR_INVERSE, 1315. 				    let_to_name(*invlet, FALSE), MENU_UNSELECTED); 1316. 				classcount++; 1317. 			   }  1318. 			    any.a_char = ilet; 1319. 			   add_menu(win, obj_to_glyph(otmp),  1320. 					&any, ilet, ATR_NONE, doname(otmp),  1321. 					MENU_UNSELECTED); 1322. 			} 1323. 		}  1324. 	}  1325. 	if (flags.sortpack) { 1326. 		if (*++invlet) goto nextclass; 1327. #ifdef WIZARD 1328. 		if (--invlet != venom_inv) { 1329. 			invlet = venom_inv; 1330. 			goto nextclass; 1331. 		} 1332. #endif 1333. 	} 1334. 	end_menu(win, (char *) 0); 1335. 1336. 	n = select_menu(win, want_reply ? PICK_ONE : PICK_NONE, &selected); 1337. 	if (n > 0) { 1338. 	   ret = selected[0].item.a_char; 1339. 	   free((genericptr_t)selected); 1340. 	} else 1341. 	   ret = !n ? '\0' : '\033';	/* cancelled */ 1342. 1343. 	return ret; 1344. } 1345.  1346. /*  1347.  * Returns the number of unpaid items within the given list. This includes 1348. * contained objects. 1349. */  1350. int 1351. count_unpaid(list) 1352.    struct obj *list; 1353. { 1354.     int count = 0; 1355. 1356.     while (list) { 1357. 	if (list->unpaid) count++; 1358. 	if (Has_contents(list)) 1359. 	   count += count_unpaid(list->cobj); 1360. 	list = list->nobj; 1361.    }  1362.     return count; 1363. } 1364.  1365. static void 1366. dounpaid 1367. { 1368.     winid win; 1369.    struct obj *otmp, *marker; 1370.    register char ilet; 1371.    char *invlet = flags.inv_order; 1372.    int classcount, count, num_so_far; 1373.    int save_unpaid = 0;	/* lint init */ 1374.    long cost, totcost; 1375. 1376.     count = count_unpaid(invent); 1377. 1378.     if (count == 1) { 1379. 	marker = (struct obj *) 0; 1380. 	otmp = find_unpaid(invent, &marker); 1381. 1382. 	/* see if the unpaid item is in the top level inventory */ 1383. 	for (marker = invent; marker; marker = marker->nobj) 1384. 	   if (marker == otmp) break; 1385. 1386. 	pline("%s", xprname(otmp, distant_name(otmp, doname), 1387. 			   marker ? otmp->invlet : CONTAINED_SYM, 1388. 			   TRUE, unpaid_cost(otmp))); 1389. 	return; 1390.    }  1391.  1392.     win = create_nhwindow(NHW_MENU); 1393.    cost = totcost = 0; 1394.    num_so_far = 0;	/* count of # printed so far */ 1395.    if (!flags.invlet_constant) reassign; 1396. 1397.     do { 1398. 	classcount = 0; 1399. 	for (otmp = invent; otmp; otmp = otmp->nobj) { 1400. 	   ilet = otmp->invlet; 1401. 	   if (otmp->unpaid) { 1402. 		if (!flags.sortpack || otmp->oclass == *invlet) { 1403. 		   if (flags.sortpack && !classcount) { 1404. 			putstr(win, 0, let_to_name(*invlet, TRUE)); 1405. 			classcount++; 1406. 		   }  1407.  1408. 		    totcost += cost = unpaid_cost(otmp); 1409. 		   /* suppress "(unpaid)" suffix */ 1410. 		   save_unpaid = otmp->unpaid; 1411. 		   otmp->unpaid = 0; 1412. 		   putstr(win, 0, xprname(otmp, distant_name(otmp, doname), 1413. 					  ilet, TRUE, cost)); 1414. 		   otmp->unpaid = save_unpaid; 1415. 		   num_so_far++; 1416. 		} 1417. 	    }  1418. 	}  1419.     } while (flags.sortpack && (*++invlet)); 1420. 1421.     if (count > num_so_far) { 1422. 	/* something unpaid is contained */ 1423. 	if (flags.sortpack) 1424. 	   putstr(win, 0, let_to_name(CONTAINED_SYM, TRUE)); 1425. 	/* 1426. 	 * Search through the container objects in the inventory for 1427. 	 * unpaid items. The top level inventory items have already 1428. 	 * been listed. 1429. 	 */ 1430. 	for (otmp = invent; otmp; otmp = otmp->nobj) { 1431. 	   if (Has_contents(otmp)) { 1432. 		marker = (struct obj *) 0;	/* haven't found any */ 1433. 		while (find_unpaid(otmp->cobj, &marker)) { 1434. 		   totcost += cost = unpaid_cost(marker); 1435. 		   save_unpaid = marker->unpaid; 1436. 		   marker->unpaid = 0;    /* suppress "(unpaid)" suffix */ 1437. 		   putstr(win, 0,  1438. 			   xprname(marker, distant_name(marker, doname), 1439. 				  CONTAINED_SYM, TRUE, cost)); 1440. 		   marker->unpaid = save_unpaid; 1441. 		} 1442. 	    }  1443. 	}  1444.     }  1445.  1446.     putstr(win, 0, ""); 1447.    putstr(win, 0, xprname((struct obj *)0, "Total:", '*', FALSE, totcost)); 1448.    display_nhwindow(win, FALSE); 1449.    destroy_nhwindow(win); 1450. } 1451.  1452.  1453. /* query objlist callback: return TRUE if obj type matches "this_type" */ 1454. static int this_type; 1455. 1456. static boolean 1457. this_type_only(obj) 1458.    struct obj *obj; 1459. { 1460.     return (obj->oclass == this_type); 1461. } 1462.  1463. /* the 'I' command */ 1464. int 1465. dotypeinv 1466. { 1467. 	char c = '\0'; 1468. 	int n, i = 0; 1469. 	char *extra_types, types[BUFSZ]; 1470. 	int class_count, oclass, unpaid_count; 1471. 	boolean billx = *u.ushops && doinvbill(0); 1472. 	menu_item *pick_list; 1473. 	boolean traditional = TRUE; 1474. 	const char *prompt = "What type of object do you want an inventory of?"; 1475. 1476. 	if (!invent && !u.ugold && !billx) { 1477. 	   You("aren't carrying anything."); 1478. 	   return 0; 1479. 	} 1480. 	unpaid_count = count_unpaid(invent); 1481. 	if (flags.menu_style != MENU_TRADITIONAL) { 1482. 	   if (flags.menu_style == MENU_FULL ||  1483. 				flags.menu_style == MENU_PARTIAL) { 1484. 		traditional = FALSE; 1485. 		i = UNPAID_TYPES; 1486. 		if (billx) i |= BILLED_TYPES; 1487. 		n = query_category(prompt, invent, i, &pick_list, PICK_ONE); 1488. 		if (!n) return 0; 1489. 		this_type = c = pick_list[0].item.a_int; 1490. 		free((genericptr_t) pick_list); 1491. 	   }  1492. 	}  1493. 	if (traditional) { 1494. 	   /* collect a list of classes of objects carried, for use as a prompt */ 1495. 	   types[0] = 0; 1496. 	   class_count = collect_obj_classes(types, invent,  1497. 					      FALSE, (u.ugold != 0),  1498. 					      (boolean FDECL((*),(OBJ_P))) 0); 1499. 	   if (unpaid_count) { 1500. 		Strcat(types, "u"); 1501. 		class_count++; 1502. 	   }  1503. 	    if (billx) { 1504. 		Strcat(types, "x"); 1505. 		class_count++; 1506. 	   }  1507. 	    /* add everything not already included; user won't see these */ 1508. 	   extra_types = eos(types); 1509. 	   *extra_types++ = '\033'; 1510. 	   if (!unpaid_count) *extra_types++ = 'u'; 1511. 	   if (!billx) *extra_types++ = 'x'; 1512. 	   *extra_types = '\0';	/* for index */ 1513. 	   for (i = 0; i < MAXOCLASSES; i++) 1514. 		if (!index(types, def_oc_syms[i])) { 1515. 		   *extra_types++ = def_oc_syms[i]; 1516. 		   *extra_types = '\0'; 1517. 		} 1518.  1519. 	    if(class_count > 1) { 1520. 		c = yn_function(prompt, types, '\0'); 1521. #ifdef REDO 1522. 		savech(c); 1523. #endif 1524. 		if(c == '\0') { 1525. 			clear_nhwindow(WIN_MESSAGE); 1526. 			return 0; 1527. 		} 1528. 	    } else { 1529. 		/* only one thing to itemize */ 1530. 		if (unpaid_count) 1531. 		   c = 'u'; 1532. 		else if (billx) 1533. 		   c = 'x'; 1534. 		else 1535. 		   c = types[0]; 1536. 	   }  1537. 	}  1538. 	if (c == 'x') { 1539. 	   if (billx) 1540. 		(void) doinvbill(1); 1541. 	   else 1542. 		pline("No used-up objects on your shopping bill."); 1543. 	   return 0; 1544. 	} 1545. 	if (c == 'u') { 1546. 	   if (unpaid_count) 1547. 		dounpaid; 1548. 	   else 1549. 		You("are not carrying any unpaid objects."); 1550. 	   return 0; 1551. 	} 1552. 	if (traditional) { 1553. 	   oclass = def_char_to_objclass(c); /* change to object class */ 1554. 	   if (oclass == GOLD_CLASS) { 1555. 		return doprgold; 1556. 	   } else if (index(types, c) > index(types, '\033')) { 1557. 		You("have no such objects."); 1558. 		return 0; 1559. 	   }  1560. 	    this_type = oclass; 1561. 	} 1562. 	if (query_objlist((char *) 0, invent, 1563. 		   (flags.invlet_constant ? USE_INVLET : 0)|INVORDER_SORT, 1564. 		   &pick_list, PICK_NONE, this_type_only) > 0) 1565. 	   free((genericptr_t)pick_list); 1566. 	return 0; 1567. } 1568.  1569. /* look at what is here */ 1570. int 1571. dolook 1572. { 1573. 	register struct obj *otmp, *otmp0; 1574. 	struct trap *trap; 1575. 	const char *verb = Blind ? "feel" : "see"; 1576. 	const char *dfeature = (char*) 0; 1577. 	char fbuf[BUFSZ], fbuf2[BUFSZ]; 1578. 	boolean no_article = FALSE; 1579. 	winid tmpwin; 1580. 1581. 	if(u.uswallow) { 1582. 		You("%s no objects here.", verb); 1583. 		return(!!Blind); 1584. 	} 1585. 	read_engr_at(u.ux, u.uy); /* Eric Backus */ 1586. 	if ((trap = t_at(u.ux,u.uy)) && trap->tseen) 1587. 		pline("There is %s here.", 1588. 			an(defsyms[trap_to_defsym(trap->ttyp)].explanation)); 1589. 1590. 	otmp0 = level.objects[u.ux][u.uy]; 1591. 1592. 	if(IS_DOOR(levl[u.ux][u.uy].typ))  { 1593. 		switch(levl[u.ux][u.uy].doormask) { 1594. 		   case D_NODOOR: 1595. 			dfeature = "doorway"; break; 1596. 		   case D_ISOPEN: 1597. 			dfeature = "open door"; break; 1598. 		   case D_BROKEN: 1599. 			dfeature = "broken door"; break; 1600. 		   default: 1601. 			dfeature = "closed door"; 1602. 		} 1603. 		/* override door description for open drawbridge */ 1604. 		if (is_drawbridge_wall(u.ux, u.uy) >= 0) 1605. 			dfeature = "open drawbridge portcullis"; 1606. 	} else if(IS_FOUNTAIN(levl[u.ux][u.uy].typ)) 1607. 		/* added by GAN 10/30/86 */ 1608. 		dfeature = "fountain"; 1609. 	else if(IS_THRONE(levl[u.ux][u.uy].typ)) 1610. 		dfeature = "opulent throne"; 1611. 	else if(is_lava(u.ux,u.uy)) 1612. 		dfeature = "molten lava", no_article = TRUE; 1613. 	else if(is_ice(u.ux,u.uy)) 1614. 		dfeature = "ice", no_article = TRUE; 1615. 	else if(is_pool(u.ux,u.uy) && !Underwater) 1616. 		dfeature = "pool of water"; 1617. #ifdef SINKS 1618. 	else if(IS_SINK(levl[u.ux][u.uy].typ)) 1619. 		dfeature = "kitchen sink"; 1620. #endif 1621. 	else if(IS_ALTAR(levl[u.ux][u.uy].typ)) { 1622. 		Sprintf(fbuf2, "altar to %s (%s)", 1623. 			a_gname,  1624. 			align_str(Amask2align(levl[u.ux][u.uy].altarmask  1625. 							    & ~AM_SHRINE))); 1626. 		dfeature = fbuf2; 1627. 	} else if(u.ux == xupstair && u.uy == yupstair) 1628. 		dfeature = "stairway up"; 1629. 	else if(u.ux == xdnstair && u.uy == ydnstair) 1630. 		dfeature = "stairway down"; 1631. 	else if(u.ux == sstairs.sx && u.uy == sstairs.sy) { 1632. 		if (sstairs.up) 1633. 			dfeature = "stairway up"; 1634. 		else 1635. 			dfeature = "stairway down"; 1636. 	} else if(u.ux == xupladder && u.uy == yupladder) 1637. 		dfeature = "ladder up"; 1638. 	else if(u.ux == xdnladder && u.uy == ydnladder) 1639. 		dfeature = "ladder down"; 1640. 	else if (levl[u.ux][u.uy].typ == DRAWBRIDGE_DOWN) 1641. 		dfeature = "lowered drawbridge"; 1642. 	else if (levl[u.ux][u.uy].typ == DBWALL) 1643. 		dfeature = "raised drawbridge"; 1644. 1645. 	if (Blind) { 1646. 		boolean drift = Is_airlevel(&u.uz) || Is_waterlevel(&u.uz); 1647. 		You("try to feel what is %s%s.", 1648. 		    drift ? "floating here" : "lying here on the ",  1649. 		    drift ?	""	    : surface(u.ux, u.uy)); 1650. 		if (dfeature && !drift && !strcmp(dfeature, surface(u.ux,u.uy))) 1651. 			dfeature = 0;		/* ice already identifed */ 1652. 		if (!can_reach_floor) { 1653. 			pline("But you can't reach it!"); 1654. 			return(0); 1655. 		} 1656. 	}  1657.  1658. 	if (dfeature) 1659. 		Sprintf(fbuf, "There is %s%s here.", 1660. 			no_article ? "" :  1661. 				index(vowels,dfeature[0]) ? "an " : "a ",  1662. 			dfeature); 1663. 1664. 	if(!otmp0 || (is_pool(u.ux,u.uy) && !Underwater)) { 1665. 		if (dfeature) pline(fbuf); 1666. 		if (Blind || !dfeature) You("%s no objects here.", verb); 1667. 		return(!!Blind); 1668. 	} 1669. 	/* we know there is something here */ 1670. 1671. 	if (!otmp0->nexthere) { 1672. 	   /* only one object */ 1673. 	   if (dfeature) pline(fbuf); 1674. 	   You("%s here %s.", verb, doname(otmp0)); 1675. 	   feel_cockatrice(otmp0); 1676. 	} else { 1677. 	   display_nhwindow(WIN_MESSAGE, FALSE); 1678. 	   tmpwin = create_nhwindow(NHW_MENU); 1679. 	   if(dfeature) { 1680. 		putstr(tmpwin, 0, fbuf); 1681. 		putstr(tmpwin, 0, ""); 1682. 	   }  1683. 	    putstr(tmpwin, 0, "Things that are here:"); 1684. 	   for(otmp = otmp0; otmp; otmp = otmp->nexthere) { 1685. 		putstr(tmpwin, 0, doname(otmp)); 1686. 		feel_cockatrice(otmp); 1687. 	   }  1688. 	    display_nhwindow(tmpwin, TRUE); 1689. 	   destroy_nhwindow(tmpwin); 1690. 	} 1691. 	return(!!Blind); 1692. } 1693.  1694. static void 1695. feel_cockatrice(otmp) 1696. struct obj *otmp; 1697. { 1698. 	if(Blind  && !uarmg && !resists_ston(&youmonst) &&  1699. 	    (otmp->otyp == CORPSE && otmp->corpsenm == PM_COCKATRICE)) { 1700. 	   if(poly_when_stoned(uasmon)) 1701. 		You("touched the cockatrice corpse with your bare %s.", 1702. 			makeplural(body_part(HAND))); 1703. 	   else 1704. 		pline("Touching the cockatrice corpse is a fatal mistake..."); 1705. 	   instapetrify("cockatrice corpse"); 1706. 	} 1707. }  1708.  1709. #endif /* OVLB */ 1710. #ifdef OVL1 1711. 1712. void 1713. stackobj(obj) 1714. struct obj *obj; 1715. { 1716. 	struct obj *otmp; 1717. 1718. 	for(otmp = level.objects[obj->ox][obj->oy]; otmp; otmp = otmp->nexthere) 1719. 		if(otmp != obj && merged(&obj,&otmp)) 1720. 			break; 1721. 	return; 1722. } 1723.  1724. static boolean 1725. mergable(otmp, obj)	/* returns TRUE if obj & otmp can be merged */ 1726. 	register struct obj *otmp, *obj; 1727. { 1728. 	if (obj->otyp != otmp->otyp || obj->unpaid != otmp->unpaid ||  1729. 	    obj->spe != otmp->spe || obj->dknown != otmp->dknown ||  1730. 	    (obj->bknown != otmp->bknown && !Role_is('P')) ||  1731. 	    obj->cursed != otmp->cursed || obj->blessed != otmp->blessed ||  1732. 	    obj->no_charge != otmp->no_charge ||  1733. 	    obj->obroken != otmp->obroken ||  1734. 	    obj->otrapped != otmp->otrapped ||  1735. 	    obj->lamplit != otmp->lamplit ||  1736. 	    obj->oeroded != otmp->oeroded) 1737. 	   return(FALSE); 1738. 1739. 	if ((obj->oclass==WEAPON_CLASS || obj->oclass==ARMOR_CLASS) &&  1740. 	    (obj->oerodeproof!=otmp->oerodeproof || obj->rknown!=otmp->rknown)) 1741. 	   return FALSE; 1742. 1743. 	if (obj->oclass == FOOD_CLASS && (obj->oeaten != otmp->oeaten || 1744. 					 obj->orotten != otmp->orotten)) 1745. 	   return(FALSE); 1746. 1747. 	if (obj->otyp == CORPSE || obj->otyp == EGG || obj->otyp == TIN) { 1748. 		if((obj->corpsenm != otmp->corpsenm) || 1749. 			(ONAME(obj) && strcmp(ONAME(obj), ONAME(otmp)))) 1750. 				return FALSE; 1751. 	} 1752.  1753. 	/* hatching eggs don't merge; ditto for revivable corpses */ 1754. 	if ((obj->otyp == EGG && (obj->timed || otmp->timed)) || 1755. 	    (obj->otyp == CORPSE && otmp->corpsenm >= LOW_PM && 1756. 		mons[otmp->corpsenm].mlet == S_TROLL)) 1757. 	   return FALSE; 1758. 1759. 	/* allow candle merging only if their ages are close */ 1760. 	/* see begin_burn for a reference for the magic "25" */ 1761. 	if (Is_candle(obj) && obj->age/25 != otmp->age/25) 1762. 	   return(FALSE); 1763. 1764. 	/* burning potions of oil never merge */ 1765. 	if (obj->otyp == POT_OIL && obj->lamplit) 1766. 	   return FALSE; 1767. 1768. 	/* don't merge surcharged item with base-cost item */ 1769. 	if (obj->unpaid && !same_price(obj, otmp)) 1770. 	   return FALSE; 1771. 1772. /* if they have names, make sure they're the same */ 1773. 	if ( (obj->onamelth != otmp->onamelth && 1774. 		((obj->onamelth && otmp->onamelth) || obj->otyp == CORPSE) 1775. 	    ) ||  1776. 	    (obj->onamelth && otmp->onamelth && 1777. 		   strncmp(ONAME(obj), ONAME(otmp), (int)obj->onamelth))) 1778. 		return FALSE; 1779. 1780. 	if(obj->oartifact != otmp->oartifact) return FALSE; 1781. 1782. 	if(obj->known == otmp->known ||  1783. 		!objects[otmp->otyp].oc_uses_known) { 1784. 		return((boolean)(objects[obj->otyp].oc_merge)); 1785. 	} else return(FALSE); 1786. } 1787.  1788. int 1789. doprgold 1790. { 1791. 	/* the messages used to refer to "carrying gold", but that didn't  1792. take containers into account */ 1793. 	if(!u.ugold) 1794. 	   Your("wallet is empty."); 1795. 	else 1796. 	   Your("wallet contains %ld gold piece%s.", u.ugold, plur(u.ugold)); 1797. 	shopper_financial_report; 1798. 	return 0; 1799. } 1800.  1801. #endif /* OVL1 */ 1802. #ifdef OVLB 1803. 1804. int 1805. doprwep 1806. { 1807. 	if(!uwep) You("are empty %s.", body_part(HANDED)); 1808. 	else prinv((char *)0, uwep, 0L); 1809. 	return 0; 1810. } 1811.  1812. int 1813. doprarm 1814. { 1815. 	if(!wearing_armor) 1816. 		You("are not wearing any armor."); 1817. 	else { 1818. #ifdef TOURIST 1819. 		char lets[8]; 1820. #else 1821. 		char lets[7]; 1822. #endif 1823. 		register int ct = 0; 1824. 1825. #ifdef TOURIST 1826. 		if(uarmu) lets[ct++] = obj_to_let(uarmu); 1827. #endif 1828. 		if(uarm) lets[ct++] = obj_to_let(uarm); 1829. 		if(uarmc) lets[ct++] = obj_to_let(uarmc); 1830. 		if(uarmh) lets[ct++] = obj_to_let(uarmh); 1831. 		if(uarms) lets[ct++] = obj_to_let(uarms); 1832. 		if(uarmg) lets[ct++] = obj_to_let(uarmg); 1833. 		if(uarmf) lets[ct++] = obj_to_let(uarmf); 1834. 		lets[ct] = 0; 1835. 		(void) display_inventory(lets, FALSE); 1836. 	} 1837. 	return 0; 1838. } 1839.  1840. int 1841. doprring 1842. { 1843. 	if(!uleft && !uright) 1844. 		You("are not wearing any rings."); 1845. 	else { 1846. 		char lets[3]; 1847. 		register int ct = 0; 1848. 1849. 		if(uleft) lets[ct++] = obj_to_let(uleft); 1850. 		if(uright) lets[ct++] = obj_to_let(uright); 1851. 		lets[ct] = 0; 1852. 		(void) display_inventory(lets, FALSE); 1853. 	} 1854. 	return 0; 1855. } 1856.  1857. int 1858. dopramulet 1859. { 1860. 	if (!uamul) 1861. 		You("are not wearing an amulet."); 1862. 	else 1863. 		prinv((char *)0, uamul, 0L); 1864. 	return 0; 1865. } 1866.  1867. int 1868. doprtool 1869. { 1870. 	register struct obj *otmp; 1871. 	register int ct=0; 1872. 	char lets[52+1]; 1873. 1874. 	for(otmp = invent; otmp; otmp = otmp->nobj) { 1875. 		if ((otmp->owornmask & W_TOOL) || 1876. 		    (otmp->oclass == TOOL_CLASS && 1877. 			(otmp == uwep || otmp->lamplit)) || 1878. 		    (otmp->otyp == LEASH && otmp->leashmon)) 1879. 			lets[ct++] = obj_to_let(otmp); 1880. 	} 1881. 	lets[ct] = 0; 1882. 	if (!ct) You("are not using any tools."); 1883. 	else (void) display_inventory(lets, FALSE); 1884. 	return 0; 1885. } 1886.  1887. /*  1888.  * uses up an object that's on the floor, charging for it as necessary 1889. */  1890. void 1891. useupf(obj) 1892. register struct obj *obj; 1893. { 1894. 	register struct obj *otmp; 1895. 1896. 	/* burn_floor_paper keeps an object pointer that it tries to  1897. * useupf multiple times, so obj must survive if plural */ 1898. 	if(obj->quan > 1L) 1899. 		otmp = splitobj(obj, obj->quan - 1L); 1900. 	else 1901. 		otmp = obj; 1902. 	if(costly_spot(otmp->ox, otmp->oy)) { 1903. 	   if(index(u.urooms, *in_rooms(otmp->ox, otmp->oy, 0))) 1904. 	       addtobill(otmp, FALSE, FALSE, FALSE); 1905. 	   else (void)stolen_value(otmp, otmp->ox, otmp->oy, FALSE, FALSE); 1906. 	} 1907. 	delobj(otmp); 1908. } 1909.  1910. #endif /* OVLB */ 1911. 1912.  1913. #ifdef OVL1 1914. 1915. /*  1916.  * Conversion from a class to a string for printing. 1917. * This must match the object class order. 1918. */  1919. STATIC_VAR NEARDATA const char *names[] = { 0, 1920. 	"Illegal objects", "Weapons", "Armor", "Rings", "Amulets", 1921. 	"Tools", "Comestibles", "Potions", "Scrolls", "Spellbooks", 1922. 	"Wands", "Coins", "Gems", "Boulders/Statues", "Iron balls", 1923. 	"Chains", "Venoms" 1924. }; 1925.  1926. static NEARDATA const char oth_symbols[] = { 1927. 	CONTAINED_SYM, 1928. 	'\0' 1929. };  1930.  1931. static NEARDATA const char *oth_names[] = { 1932. 	"Bagged/Boxed items" 1933. }; 1934.  1935. char * 1936. let_to_name(let,unpaid) 1937. char let; 1938. boolean unpaid; 1939. { 1940. 	const char *class_name; 1941. 	const char *pos; 1942. 	int oclass = (let >= 1 && let < MAXOCLASSES) ? let : 0; 1943. 	unsigned len; 1944. 	static NEARDATA char *buf = (char *)0; 1945. 	static NEARDATA unsigned bufsiz = 0; 1946. 1947. 	if (oclass) 1948. 	   class_name = names[oclass]; 1949. 	else if ((pos = index(oth_symbols, let)) != 0) 1950. 	   class_name = oth_names[pos - oth_symbols]; 1951. 	else 1952. 	   class_name = names[0]; 1953. 1954. 	len = strlen(class_name) + (unpaid ? sizeof "unpaid_" : sizeof ""); 1955. 	if (len > bufsiz) { 1956. 	   if (buf)  free((genericptr_t)buf),  buf = (char *)0; 1957. 	   bufsiz = len + 10; /* add slop to reduce incremental realloc */ 1958. 	   buf = (char *) alloc(bufsiz); 1959. 	} 1960. 	if (unpaid) 1961. 	   Strcat(strcpy(buf, "Unpaid "), class_name); 1962. 	else 1963. 	   Strcpy(buf, class_name); 1964. 	return (buf); 1965. } 1966.  1967. #endif /* OVL1 */ 1968. #ifdef OVLB 1969. 1970. void 1971. reassign 1972. { 1973. 	register int i;  1974. register struct obj *obj; 1975. 1976. 	for(obj = invent, i = 0; obj; obj = obj->nobj, i++) 1977. 		obj->invlet = (i < 26) ? ('a'+i) : ('A'+i-26); 1978. 	lastinvnr = i; 1979. } 1980.  1981. #endif /* OVLB */ 1982. #ifdef OVL1 1983. 1984. int 1985. doorganize	/* inventory organizer by Del Lamb */ 1986. { 1987. 	struct obj *obj, *otmp; 1988. 	register int ix, cur; 1989. 	register char let; 1990. 	char alphabet[52+1], buf[52+1]; 1991. 	char qbuf[QBUFSZ]; 1992. 	char allowall[2]; 1993. 	const char *adj_type; 1994. 1995. 	if (!flags.invlet_constant) reassign; 1996. 	/* get a pointer to the object the user wants to organize */ 1997. 	allowall[0] = ALL_CLASSES; allowall[1] = '\0'; 1998. 	if (!(obj = getobj(allowall,"adjust"))) return(0); 1999. 2000. 	/* initialize the list with all upper and lower case letters */ 2001. 	for (let = 'a', ix = 0; let <= 'z';) alphabet[ix++] = let++; 2002. 	for (let = 'A', ix = 26; let <= 'Z';) alphabet[ix++] = let++; 2003. 	alphabet[52] = 0; 2004. 2005. 	/* blank out all the letters currently in use in the inventory */ 2006. 	/* except those that will be merged with the selected object  */ 2007. 	for (otmp = invent; otmp; otmp = otmp->nobj) 2008. 		if (otmp != obj && !mergable(otmp,obj)) 2009. 			if (otmp->invlet <= 'Z') 2010. 				alphabet[(otmp->invlet) - 'A' + 26] = ' '; 2011. 			else	alphabet[(otmp->invlet) - 'a']	   = ' '; 2012. 2013. 	/* compact the list by removing all the blanks */ 2014. 	for (ix = cur = 0; ix <= 52; ix++) 2015. 		if (alphabet[ix] != ' ') buf[cur++] = alphabet[ix]; 2016. 2017. 	/* and by dashing runs of letters */ 2018. 	if(cur > 5) compactify(buf); 2019. 2020. 	/* get new letter to use as inventory letter */ 2021. 	for { 2022. 		Sprintf(qbuf, "Adjust letter to what [%s]?",buf); 2023. 		let = yn_function(qbuf, (char *)0, '\0'); 2024. 		if(index(quitchars,let)) { 2025. 			pline("Never mind."); 2026. 			return(0); 2027. 		} 2028. 		if (let == '@' || !letter(let)) 2029. 			pline("Select an inventory slot letter."); 2030. 		else 2031. 			break; 2032. 	} 2033.  2034. 	/* change the inventory and print the resulting item */ 2035. 	adj_type = "Moving:"; 2036. 2037. 	/*  2038. 	 * don't use freeinv/addinv to avoid double-touching artifacts, 2039. 	 * dousing lamps, losing luck, cursing loadstone, etc. 2040. 	 */ 2041. 	extract_nobj(obj, &invent); 2042. 2043. 	for (otmp = invent; otmp;) 2044. 		if (merged(&otmp,&obj)) { 2045. 			adj_type = "Merging:"; 2046. 			obj = otmp; 2047. 			otmp = otmp->nobj; 2048. 			extract_nobj(obj, &invent); 2049. 		} else { 2050. 			if (otmp->invlet == let) { 2051. 				adj_type = "Swapping:"; 2052. 				otmp->invlet = obj->invlet; 2053. 			} 2054. 			otmp = otmp->nobj; 2055. 		} 2056.  2057. 	/* inline addinv (assuming flags.invlet_constant and !merged) */ 2058. 	obj->invlet = let; 2059. 	obj->nobj = invent; /* insert at beginning */ 2060. 	obj->where = OBJ_INVENT; 2061. 	invent = obj; 2062. 	reorder_invent; 2063. 2064. 	prinv(adj_type, obj, 0L); 2065. 	update_inventory; 2066. 	return(0); 2067. } 2068.  2069. /* common to display_minventory and display_cinventory */ 2070. static void 2071. invdisp_nothing(hdr, txt) 2072. const char *hdr, *txt; 2073. { 2074. 	winid win; 2075. 	anything any; 2076. 	menu_item *selected; 2077. 2078. 	any.a_void = 0; 2079. 	win = create_nhwindow(NHW_MENU); 2080. 	start_menu(win); 2081. 	add_menu(win, NO_GLYPH, &any, 0, ATR_INVERSE, hdr, MENU_UNSELECTED); 2082. 	add_menu(win, NO_GLYPH, &any, 0, ATR_NONE, "", MENU_UNSELECTED); 2083. 	add_menu(win, NO_GLYPH, &any, 0, ATR_NONE, txt, MENU_UNSELECTED); 2084. 	end_menu(win, (char *)0); 2085. 	if (select_menu(win, PICK_NONE, &selected) > 0) 2086. 	   free((genericptr_t)selected); 2087. 	destroy_nhwindow(win); 2088. 	return; 2089. } 2090.  2091. /* query_objlist callback: return things that could possibly be worn/wielded */ 2092. static boolean 2093. worn_wield_only(obj) 2094. struct obj *obj; 2095. { 2096.     return (obj->oclass == WEAPON_CLASS  2097. 		|| obj->oclass == ARMOR_CLASS  2098. 		|| obj->oclass == AMULET_CLASS  2099. 		|| obj->oclass == RING_CLASS  2100. 		|| obj->oclass == TOOL_CLASS); 2101. } 2102.  2103. /*  2104.  * Display a monster's inventory. 2105. * Returns a pointer to the object from the monster's inventory selected 2106. * or NULL if nothing was selected. 2107. *  2108.  * By default, only worn and wielded items are displayed. The caller 2109. * can pick one. Modifier flags are: 2110. *  2111.  *	MINV_NOLET	- nothing selectable 2112. *	MINV_ALL	- display all inventory 2113. */  2114. struct obj * 2115. display_minventory(mon, dflags) 2116. register struct monst *mon; 2117. int dflags; 2118. { 2119. 	struct obj *ret, m_gold; 2120. 	char tmp[QBUFSZ]; 2121. 	int n; 2122. menu_item *selected = 0; 2123. 	int do_all = (dflags & MINV_ALL) != 0, 2124. 	   do_gold = (do_all && mon->mgold); 2125. 2126. 	Sprintf(tmp,"%s %s:", s_suffix(Monnam(mon)),  2127. 		do_all ? "possessions" : "armament"); 2128. 2129. 	if (do_all ? (mon->minvent || mon->mgold)  2130. 		   : (mon->misc_worn_check || MON_WEP(mon))) { 2131. 	   /* Fool the 'weapon in hand' routine into 2132. 	    * displaying 'weapon in claw', etc. properly. 2133. 	    */  2134. 	    char save_usym = u.usym; 2135. 2136. 	    u.usym = mon->data->mlet; 2137. 	   uasmon = mon->data; 2138. 2139. 	    if (do_gold) { 2140. 		/* make temporary gold object & insert at head of inventory */ 2141. 		m_gold = zeroobj; 2142. 		m_gold.otyp = GOLD_PIECE; m_gold.oclass = GOLD_CLASS; 2143. 		m_gold.quan = mon->mgold; m_gold.dknown = 1; 2144. 		m_gold.where = OBJ_FREE; 2145. 		add_to_minv(mon, &m_gold); 2146. 	   }  2147.  2148. 	    n = query_objlist(tmp, mon->minvent, INVORDER_SORT, &selected,  2149. 			(dflags & MINV_NOLET) ? PICK_NONE : PICK_ONE,  2150. 			do_all ? allow_all : worn_wield_only); 2151. 2152. 	    if (do_gold) obj_extract_self(&m_gold); 2153. 2154. 	    u.usym = save_usym; 2155. 	   set_uasmon; 2156. 	} else { 2157. 	   invdisp_nothing(tmp, "(none)"); 2158. 	   n = 0; 2159. 	} 2160.  2161. 	if (n > 0) { 2162. 	   ret = selected[0].item.a_obj; 2163. 	   free((genericptr_t)selected); 2164. 	   /*  2165. 	     * Unfortunately, we can't return a pointer to our temporary 2166. 	    * gold object. We'll have to work out a scheme where this 2167. 	    * can happen. Maybe even put gold in the inventory list... 2168. */ 2169. 	    if (ret == &m_gold) ret = (struct obj *) 0; 2170. 	} else 2171. 	   ret = (struct obj *) 0; 2172. 	return ret; 2173. } 2174.  2175. /*  2176.  * Display the contents of a container in inventory style. 2177. * Currently, this is only used for statues, via wand of probing. 2178. */  2179. struct obj * 2180. display_cinventory(obj) 2181. register struct obj *obj; 2182. { 2183. 	struct obj *ret; 2184. 	char tmp[QBUFSZ]; 2185. 	int n; 2186. menu_item *selected = 0; 2187. 2188. 	Sprintf(tmp,"Contents of %s:", doname(obj)); 2189. 2190. 	if (obj->cobj) { 2191. 	   n = query_objlist(tmp, obj->cobj, INVORDER_SORT, &selected,  2192. 			    PICK_NONE, allow_all); 2193. 	} else { 2194. 	   invdisp_nothing(tmp, "(empty)"); 2195. 	   n = 0; 2196. 	} 2197. 	if (n > 0) { 2198. 	   ret = selected[0].item.a_obj; 2199. 	   free((genericptr_t)selected); 2200. 	} else 2201. 	   ret = (struct obj *) 0; 2202. 	return ret; 2203. } 2204.  2205. /* query objlist callback: return TRUE if obj is at given location */ 2206. static coord only; 2207. 2208. static boolean 2209. only_here(obj) 2210.    struct obj *obj; 2211. { 2212.     return (obj->ox == only.x && obj->oy == only.y); 2213. } 2214.  2215. /*  2216.  * Display a list of buried items in inventory style. Return a non-zero 2217. * value if there were items at that spot. 2218. *  2219.  * Currently, this is only used with a wand of probing zapped downwards. 2220. */  2221. int 2222. display_binventory(x, y, as_if_seen) 2223. int x, y; 2224. boolean as_if_seen; 2225. { 2226. 	struct obj *obj; 2227. 	menu_item *selected = 0; 2228. 	int n; 2229. 2230. 	/* count # of objects here */ 2231. 	for (n = 0, obj = level.buriedobjlist; obj; obj = obj->nobj) 2232. 	   if (obj->ox == x && obj->oy == y) { 2233. 		if (as_if_seen) obj->dknown = 1; 2234. 		n++; 2235. 	   }  2236.  2237. 	if (n) { 2238. 	   only.x = x;  2239. only.y = y; 2240. if (query_objlist("Things that are buried here:", 2241. 			     level.buriedobjlist, INVORDER_SORT, 2242. 			     &selected, PICK_NONE, only_here) > 0) 2243. 		free((genericptr_t)selected); 2244. 	   only.x = only.y = 0; 2245. 	} 2246. 	return n;  2247. } 2248.  2249. #endif /* OVL1 */ 2250. 2251. /*invent.c*/