Source:NetHack 3.1.0/invent.c

Below is the full text to invent.c from the source code of NetHack 3.1.0. To link to a particular line, write [[NetHack 3.1.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.1	92/12/11	*/ 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 int FDECL(merged,(struct obj *,struct obj *,int)); 15.  #endif /* OVL1 */ 16.  STATIC_DCL void FDECL(assigninvlet,(struct obj *)); 17.  STATIC_DCL void FDECL(unlinkinv,(struct obj*)); 18.  STATIC_DCL void FDECL(compactify,(char *)); 19.  STATIC_PTR int FDECL(ckunpaid,(struct obj *)); 20.  #ifdef OVLB 21.  static struct obj *FDECL(find_unpaid,(struct obj *,struct obj **)); 22.  static boolean NDECL(wearing_armor); 23.  static boolean FDECL(is_worn,(struct obj *)); 24.  #endif /* OVLB */ 25.  STATIC_DCL char FDECL(obj_to_let,(struct obj *)); 26.   27.   #ifdef OVLB 28.   29.   static int lastinvnr = 51;	/* 0 ... 51 (never saved&restored) */ 30.   31.   char inv_order[] = {	/* manipulated in options.c, used below */ 32.  	AMULET_CLASS, WEAPON_CLASS, ARMOR_CLASS, FOOD_CLASS, SCROLL_CLASS, 33.  	SPBOOK_CLASS, POTION_CLASS, RING_CLASS, WAND_CLASS, TOOL_CLASS, 34.  	GEM_CLASS, ROCK_CLASS, BALL_CLASS, CHAIN_CLASS, 0 }; 35.   36.   #ifdef WIZARD 37.  /* wizards can wish for venom, which will become an invisible inventory 38.   * item without this. putting it in inv_order would mean venom would 39.   * suddenly become a choice for all the inventory-class commands, which 40.   * would probably cause mass confusion. the test for inventory venom 41.   * is only WIZARD and not wizard because the wizard can leave venom lying 42.   * around on a bones level for normal players to find. 43.   */  44.   static char venom_inv[] = { VENOM_CLASS, 0 };	/* (constant) */ 45.  #endif 46.   47.   STATIC_OVL void 48.  assigninvlet(otmp) 49.  register struct obj *otmp; 50.  {  51.   	boolean inuse[52]; 52.  	register int i;  53. register struct obj *obj; 54.   55.   	for(i = 0; i < 52; i++) inuse[i] = FALSE; 56.  	for(obj = invent; obj; obj = obj->nobj) if(obj != otmp) { 57.  		i = obj->invlet; 58.  		if('a' <= i && i <= 'z') inuse[i - 'a'] = TRUE; else 59.  		if('A' <= i && i <= 'Z') inuse[i - 'A' + 26] = TRUE; 60.  		if(i == otmp->invlet) otmp->invlet = 0; 61.  	}  62.   	if((i = otmp->invlet) &&  63.   	    (('a' <= i && i <= 'z') || ('A' <= i && i <= 'Z'))) 64.  		return; 65.  	for(i = lastinvnr+1; i != lastinvnr; i++) { 66.  		if(i == 52) { i = -1; continue; } 67.  		if(!inuse[i]) break; 68.  	}  69.   	otmp->invlet = (inuse[i] ? NOINVSYM :  70.   			(i < 26) ? ('a'+i) : ('A'+i-26)); 71.  	lastinvnr = i;  72. } 73.    74.   #endif /* OVLB */ 75.  #ifdef OVL1 76.   77.   /* note: assumes ASCII; toggling a bit puts lowercase in front of uppercase */ 78.  #define inv_rank(o) ((o)->invlet ^ 040) 79.   80.   /* sort the inventory; used by addinv and doorganize */ 81.  static void 82.  reorder_invent 83.  {  84.   	struct obj *otmp, *prev, *next; 85.  	boolean need_more_sorting; 86.   87.   	do { 88.  	    /*  89.   	     * We expect at most one item to be out of order, so this 90.  	     * isn't nearly as inefficient as it may first appear. 91.  	     */  92.   	    need_more_sorting = FALSE; 93.  	    for (otmp = invent, prev = 0; otmp; ) { 94.  		next = otmp->nobj; 95.  		if (next && inv_rank(next) < inv_rank(otmp)) { 96.  		    need_more_sorting = TRUE; 97.  		    if (prev) prev->nobj = next; 98.  		    else      invent = next; 99.  		    otmp->nobj = next->nobj; 100. 		    next->nobj = otmp; 101. 		    prev = next; 102. 		} else { 103. 		    prev = otmp; 104. 		    otmp = next; 105. 		}  106.  	    }  107.  	} while (need_more_sorting); 108. }  109.   110.  #undef inv_rank 111.  112.  /* merge obj with otmp and delete obj if types agree */ 113. STATIC_OVL int 114. merged(otmp, obj, lose) 115. register struct obj *otmp, *obj; 116. register int lose; 117. {  118.  	if(mergable(otmp, obj)) { 119. 		/* Approximate age: we do it this way because if we were to  120. * do it "accurately" (merge only when ages are identical) 121. 		 * we'd wind up never merging any corpses. 122. 		 * otmp->age = otmp->age*(1-proportion) + obj->age*proportion; 123. 		 */  124.  		otmp->age = ((otmp->age*otmp->quan) + (obj->age*obj->quan)) 125. 			/ (otmp->quan + obj->quan); 126. 		otmp->quan += obj->quan; 127. 		otmp->owt += obj->owt; 128. 		if(!otmp->onamelth && obj->onamelth) 129. 			otmp = oname(otmp, ONAME(obj), 1); 130. 		if(lose) freeobj(obj); 131. 		obfree(obj,otmp);	/* free(obj), bill->otmp */ 132. 		return(1); 133. 	} else	return(0); 134. }  135.   136.  struct obj * 137. addinv(obj) 138. register struct obj *obj; 139. {  140.  	register struct obj *otmp, *prev; 141.  142.  	if (obj->otyp == GOLD_PIECE) { 143. 		u.ugold += obj->quan; 144. 		flags.botl = 1; 145. 		return obj; 146. 	} else if (obj->otyp == AMULET_OF_YENDOR) { 147. 		if (u.uhave.amulet) impossible ("already have amulet?"); 148. 		u.uhave.amulet = 1; 149. 	} else if (obj->otyp == CANDELABRUM_OF_INVOCATION) { 150. 		if (u.uhave.menorah) impossible ("already have candelabrum?"); 151. 		u.uhave.menorah = 1; 152. 	} else if (obj->otyp == BELL_OF_OPENING) { 153. 		if (u.uhave.bell) impossible ("already have silver bell?"); 154. 		u.uhave.bell = 1; 155. 	} else if (obj->otyp == SPE_BOOK_OF_THE_DEAD) { 156. 		if (u.uhave.book) impossible ("already have the book?"); 157. 		u.uhave.book = 1; 158. #ifdef MULDGN 159. 	} else if (is_quest_artifact(obj)) { 160. 		if (u.uhave.questart) impossible ("already have the artifact?"); 161. 		u.uhave.questart = 1; 162. 		artitouch; 163. 		set_artifact_intrinsic(obj, 1, W_ART); 164. #endif 165. 	} else if(obj->oartifact) { 166. 		set_artifact_intrinsic(obj, 1, W_ART); 167. 	}  168.  	/* merge if possible; find end of chain in the process */ 169. 	for (prev = 0, otmp = invent; otmp; prev = otmp, otmp = otmp->nobj) 170. 	    if (merged(otmp, obj, 0)) { 171. 		obj = otmp; 172. 		goto added; 173. 	    }  174.  	/* didn't merge, so insert into chain */ 175. 	if (flags.invlet_constant || !prev) { 176. 	    if (flags.invlet_constant) assigninvlet(obj); 177. 	    obj->nobj = invent;		/* insert at beginning */ 178. 	    invent = obj; 179. 	    if (flags.invlet_constant) reorder_invent; 180. 	} else { 181. 	    prev->nobj = obj;		/* insert at end */ 182. 	    obj->nobj = 0; 183. 	}  184.   185.  added: 186. 	if (obj->otyp == LUCKSTONE  187.  	    || (obj->oartifact && spec_ability(obj, SPFX_LUCK))) { 188. 		/* new luckstone must be in inventory by this point 189. 		 * for correct calculation */ 190. 		if (stone_luck(TRUE) >= 0) u.moreluck = LUCKADD; 191. 		else u.moreluck = -LUCKADD; 192. 	} else if (obj->otyp == OIL_LAMP || obj->otyp == MAGIC_LAMP) 193. 		check_lamps; 194. 	update_inventory; 195. 	return(obj); 196. }  197.   198.  #endif /* OVL1 */ 199. #ifdef OVLB 200.  201.  /* Add an item to the inventory unless we're fumbling, and give a message. 202.  * If there aren't any free inventory slots, we'll drop it instead. 203.  * If both success and failure messages are NULL, then we're just doing the 204.  * fumbling/slot-limit checking for a silent grab. 205.  * Note: will drop the whole bunch if the object merges first. 206.  */  207.  struct obj * 208. hold_another_object(obj, drop_fmt, drop_arg, hold_msg) 209. struct obj *obj; 210. const char *drop_fmt, *drop_arg, *hold_msg; 211. {  212.  	long oquan = obj->quan; 213. 	if (!Blind) obj->dknown = 1;	/* maximize mergibility */ 214. 	if (Fumbling) { 215. 		if (drop_fmt) pline(drop_fmt, drop_arg); 216. 		dropy(obj); 217. 	} else { 218. 		obj = addinv(obj); 219. 		if (inv_cnt > 52  220.  		    || ((obj->otyp != LOADSTONE || !obj->cursed) 221. 			&& near_capacity >= OVERLOADED)) { 222. 			if (drop_fmt) pline(drop_fmt, drop_arg); 223. 			dropx(obj); 224. 		} else { 225. 			if (hold_msg || drop_fmt) prinv(hold_msg, obj, oquan); 226. 		}  227.  	}  228.  	return obj; 229. }  230.   231.  void 232. useup(obj) 233. register struct obj *obj; 234. {  235.  	/*  Note:  This works correctly for containers because they */ 236. 	/*	   (containers) don't merge. */ 237.  	if(obj->quan > 1L){ 238. #ifndef NO_SIGNAL 239. 		obj->in_use = FALSE;	/* no longer in use */ 240. #endif 241. 		obj->quan--; 242. 		obj->owt = weight(obj); 243. 	} else { 244. 		setnotworn(obj); 245. 		freeinv(obj); 246. 		obfree(obj, (struct obj *) 0);	/* deletes contents also */ 247. 	}  248.  }  249.   250.  #endif /* OVLB */ 251. #ifdef OVL3 252.  253.  /* used by freeinv and doorganize to do list manipulation */ 254. STATIC_OVL 255. void 256. unlinkinv(obj) 257. register struct obj *obj; 258. {  259.  	register struct obj *otmp; 260.  261.  	if(obj == invent) 262. 		invent = invent->nobj; 263. 	else { 264. 		for(otmp = invent; otmp->nobj != obj; otmp = otmp->nobj) 265. 			if(!otmp->nobj) panic("unlinkinv"); 266. 		otmp->nobj = obj->nobj; 267. 	}  268.  	obj->nobj = 0; 269. }  270.   271.  void 272. freeinv(obj) 273. register struct obj *obj; 274. {  275.  	unlinkinv(obj); 276.  277.  	if (obj->otyp == GOLD_PIECE) { 278. 		u.ugold -= obj->quan; 279. 		flags.botl = 1; 280. 		return; 281. 	} else if (obj->otyp == AMULET_OF_YENDOR) { 282. 		if (!u.uhave.amulet) impossible ("don't have amulet?"); 283. 		u.uhave.amulet = 0; 284. 	} else if (obj->otyp == CANDELABRUM_OF_INVOCATION) { 285. 		if (!u.uhave.menorah) impossible ("don't have candelabrum?"); 286. 		u.uhave.menorah = 0; 287. 	} else if (obj->otyp == BELL_OF_OPENING) { 288. 		if (!u.uhave.bell) impossible ("don't have silver bell?"); 289. 		u.uhave.bell = 0; 290. 	} else if (obj->otyp == SPE_BOOK_OF_THE_DEAD) { 291. 		if (!u.uhave.book) impossible ("don't have the book?"); 292. 		u.uhave.book = 0; 293. #ifdef MULDGN 294. 	} else if (is_quest_artifact(obj)) { 295. 		if(!u.uhave.questart) impossible ("don't have the artifact?"); 296. 		u.uhave.questart = 0; 297. 		set_artifact_intrinsic(obj, 0, W_ART); 298. #endif 299. 	} else if (obj->oartifact) { 300. 		set_artifact_intrinsic(obj, 0, W_ART); 301. 	} else if (obj->otyp == OIL_LAMP || obj->otyp == MAGIC_LAMP  302.  		   || obj->otyp == BRASS_LANTERN) { 303. 		if (obj->lamplit) { 304. 			obj->lamplit = 0; 305. 			if (!Blind) pline("%s goes out!", The(xname(obj))); 306. 		}  307.  		check_lamps; 308. 	} else if (obj->otyp == LOADSTONE) { 309. 		curse(obj); 310. 	} else if (obj->otyp == LUCKSTONE  311.  		   || (obj->oartifact && spec_ability(obj, SPFX_LUCK))) { 312. 		int luckbon = stone_luck(TRUE); 313. 		if (!luckbon && !carrying(LUCKSTONE)) u.moreluck = 0; 314. 		else if (luckbon >= 0) u.moreluck = LUCKADD; 315. 		else u.moreluck = -LUCKADD; 316. 		flags.botl = 1; 317. 	}  318.  	update_inventory; 319. }  320.   321.  void 322. delallobj(x, y)  323. int x, y; 324. { 325.  	struct obj *otmp, *otmp2; 326.  327.  	for (otmp = level.objects[x][y]; otmp; otmp = otmp2) { 328. 		otmp2 = otmp->nexthere; 329. 		if (otmp == uball) 330. 			unpunish; 331. 		if (otmp == uchain) 332. 			continue; 333. 		delobj(otmp); 334. 	}  335.  }  336.   337.  #endif /* OVL3 */ 338. #ifdef OVL2 339.  340.  /* destroy object in fobj chain (if unpaid, it remains on the bill) */ 341. void 342. delobj(obj) 343. register struct obj *obj; 344. {  345.  #ifdef WALKIES 346. 	if(obj->otyp == LEASH && obj->leashmon != 0) o_unleash(obj); 347. #endif 348. 	freeobj(obj); 349. 	newsym(obj->ox,obj->oy); 350. 	obfree(obj, (struct obj *) 0);	/* frees contents also */ 351. }  352.   353.  /* unlink obj from chain starting with fobj */ 354. void 355. freeobj(obj) 356. register struct obj *obj; 357. {  358.  	register struct obj *otmp; 359.  360.  	if (obj == fobj) 361. 	    fobj = fobj->nobj; 362. 	else { 363. 	    for(otmp = fobj; otmp; otmp = otmp->nobj) 364. 		if (otmp->nobj == obj) { 365. 		    otmp->nobj = obj->nobj; 366. 		    break; 367. 		}  368.  	    if (!otmp) panic("error in freeobj"); 369. 	}  370.  	remove_object(obj); 371. }  372.   373.  #endif /* OVL2 */ 374. #ifdef OVL0 375.  376.  struct obj * 377. sobj_at(n,x,y) 378. register int n, x, y;  379. { 380.  	register struct obj *otmp; 381.  382.  	for(otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere) 383. 		if(otmp->otyp == n)  384. return(otmp); 385. 	return((struct obj *)0); 386. }  387.   388.  #endif /* OVL0 */ 389. #ifdef OVLB 390.  391.  int 392. carried(obj) 393. register struct obj *obj; 394. {  395.  	register struct obj *otmp; 396.  397.  	for(otmp = invent; otmp; otmp = otmp->nobj) 398. 		if(otmp == obj) return(1); 399. 	return(0); 400. }  401.   402.  struct obj * 403. carrying(type) 404. register int type; 405. {  406.  	register struct obj *otmp; 407.  408.  	for(otmp = invent; otmp; otmp = otmp->nobj) 409. 		if(otmp->otyp == type) 410. 			return(otmp); 411. 	return((struct obj *) 0); 412. }  413.   414.  boolean 415. have_lizard 416. {  417.  	register struct obj *otmp; 418.  419.  	for(otmp = invent; otmp; otmp = otmp->nobj) 420. 		if(otmp->otyp == CORPSE && otmp->corpsenm == PM_LIZARD) 421. 			return(TRUE); 422. 	return(FALSE); 423. }  424.   425.  struct obj * 426. o_on(id, objchn) 427. unsigned int id; 428. register struct obj *objchn; 429. {  430.  	struct obj *temp; 431.  432.  	while(objchn) { 433. 		if(objchn->o_id == id) return(objchn); 434. 		if (Is_container(objchn) && (temp = o_on(id,objchn->cobj))) 435. 			return temp; 436. 		objchn = objchn->nobj; 437. 	}  438.  	return((struct obj *) 0); 439. }  440.   441.  boolean 442. obj_here(obj, x, y)  443. register struct obj *obj; 444. int x, y;  445. { 446.  	register struct obj *otmp; 447.  448.  	for(otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere) 449. 		if(obj == otmp) return(TRUE); 450. 	return(FALSE); 451. }  452.   453.  #endif /* OVLB */ 454. #ifdef OVL2 455.  456.  struct obj * 457. g_at(x,y) 458. register int x, y;  459. { 460.  	register struct obj *obj = level.objects[x][y]; 461. 	while(obj) { 462. 	    if (obj->otyp == GOLD_PIECE) return obj; 463. 	    obj = obj->nexthere; 464. 	}  465.  	return((struct obj *)0); 466. }  467.   468.  #endif /* OVL2 */ 469. #ifdef OVLB 470.  471.  /* Make a gold object from the hero's gold. */ 472.  struct obj * 473. mkgoldobj(q) 474. register long q;  475. { 476.  	register struct obj *otmp; 477.  478.  	otmp = mksobj(GOLD_PIECE, FALSE, FALSE); 479. 	u.ugold -= q;  480. otmp->quan = q; 481. otmp->owt = weight(otmp); 482. 	flags.botl = 1; 483. 	return(otmp); 484. }  485.   486.  #endif /* OVLB */ 487. #ifdef OVL1 488.  489.  STATIC_OVL void 490. compactify(buf) 491. register char *buf; 492. /* compact a string of inventory letters by dashing runs of letters */ 493. {  494.  	register int i1 = 1, i2 = 1; 495. 	register char ilet, ilet1, ilet2; 496.  497.  	ilet2 = buf[0]; 498. 	ilet1 = buf[1]; 499. 	buf[++i2] = buf[++i1]; 500. 	ilet = buf[i1]; 501. 	while(ilet) { 502. 		if(ilet == ilet1+1) { 503. 			if(ilet1 == ilet2+1) 504. 				buf[i2 - 1] = ilet1 = '-'; 505. 			else if(ilet2 == '-') { 506. 				buf[i2 - 1] = ++ilet1; 507. 				buf[i2] = buf[++i1]; 508. 				ilet = buf[i1]; 509. 				continue; 510. 			}  511.  		}  512.  		ilet2 = ilet1; 513. 		ilet1 = ilet; 514. 		buf[++i2] = buf[++i1]; 515. 		ilet = buf[i1]; 516. 	}  517.  }  518.   519.  /*  520.   * getobj returns: 521.  *	struct obj *xxx:	object to do something with. 522.  *	(struct obj *) 0	error return: no object. 523.  *	&zeroobj		explicitly no object (as in w-). 524.  */  525.  struct obj * 526. getobj(let,word) 527. register const char *let,*word; 528. {  529.  	register struct obj *otmp; 530. 	register char ilet; 531. 	char buf[BUFSZ], qbuf[QBUFSZ]; 532. 	char lets[BUFSZ]; 533. 	register int foo = 0; 534. 	register char *bp = buf; 535. 	xchar allowcnt = 0;	/* 0, 1 or 2 */ 536. 	boolean allowgold = FALSE, usegold = FALSE; 537. 		/* Two possibilities: they can't use gold because it's illegal, 538. 		 * or they can't use gold because they don't have any. 539. 		 */  540.  	boolean allowall = FALSE; 541. 	boolean allownone = FALSE; 542. 	xchar foox = 0; 543. 	long cnt; 544. 	boolean prezero = FALSE; 545.  546.  	if(*let == ALLOW_COUNT) let++, allowcnt = 1; 547. 	if(*let == GOLD_CLASS) let++, 548. 		usegold = TRUE, allowgold = (u.ugold ? TRUE : FALSE); 549. #ifdef POLYSELF 550. 	/* Equivalent of an "ugly check" for gold */ 551. 	if (usegold && !strcmp(word, "eat") && !metallivorous(uasmon)) 552. 		usegold = allowgold = FALSE; 553. #endif 554. 	if(*let == ALL_CLASSES) let++, allowall = TRUE; 555. 	if(*let == ALLOW_NONE) let++, allownone = TRUE; 556. 	/* "ugly check" for reading fortune cookies, part 1 */ 557. 	if(allowall && !strcmp(word, "read")) allowall = FALSE; 558.  559.  	if(allownone) *bp++ = '-'; 560. 	if(allowgold) *bp++ = def_oc_syms[GOLD_CLASS]; 561. 	if(bp > buf && bp[-1] == '-') *bp++ = ' '; 562.  563.  	ilet = 'a'; 564. 	for(otmp = invent; otmp; otmp = otmp->nobj){ 565. 	    if(!*let || index(let, otmp->oclass)) { 566. 		bp[foo++] = flags.invlet_constant ? otmp->invlet : ilet; 567.  568.  		/* ugly check: remove inappropriate things */ 569. 		if((!strcmp(word, "take off") && 570. 		    (!(otmp->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL))  571.  		     || (otmp==uarm && uarmc)  572.  #ifdef TOURIST  573.  		     || (otmp==uarmu && (uarm || uarmc))  574.  #endif  575.  		    ))  576.  		|| (!strcmp(word, "wear") && 577. 		     (otmp->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL)))  578.  							/* already worn */  579.  		|| (!strcmp(word, "wield") && 580. 		    (otmp->owornmask & W_WEP))  581.  		    ) { 582. 			foo--; 583. 			foox++; 584. 		}  585.   586.  		/* Second ugly check; unlike the first it won't trigger an  587. * "else" in "you don't have anything else to ___". 588. 		 */  589.  		else if ((!strcmp(word, "wear") && 590. 		    (otmp->oclass == TOOL_CLASS &&  591.  		     otmp->otyp != BLINDFOLD && otmp->otyp != TOWEL))  592.  #ifdef POLYSELF  593.  		|| (!strcmp(word, "eat") && !is_edible(otmp))  594.  #endif  595.  		|| (!strcmp(word, "can") && 596. 		    (otmp->otyp != CORPSE))  597.  		|| (!strcmp(word, "write with") && 598. 		    (otmp->oclass == TOOL_CLASS &&  599.  		     otmp->otyp != MAGIC_MARKER && otmp->otyp != TOWEL))  600.  		|| (!strcmp(word, "rub") && 601. 		    (otmp->oclass == TOOL_CLASS &&  602.  		     otmp->otyp != OIL_LAMP && otmp->otyp != MAGIC_LAMP &&  603.  		     otmp->otyp != BRASS_LANTERN))  604.  		|| (!strcmp(word, "wield") && 605. 		    (otmp->oclass == TOOL_CLASS &&  606.  		     otmp->otyp != PICK_AXE && otmp->otyp != UNICORN_HORN))  607.  		    ) 608. 			foo--; 609. 	    } else { 610.  611.  		/* "ugly check" for reading fortune cookies, part 2 */ 612. 		if ((!strcmp(word, "read") && otmp->otyp == FORTUNE_COOKIE)) 613. 			allowall = TRUE; 614. 	    }  615.   616.  	    if(ilet == 'z') ilet = 'A'; else ilet++; 617. 	}  618.  	bp[foo] = 0; 619. 	if(foo == 0 && bp > buf && bp[-1] == ' ') *--bp = 0; 620. 	Strcpy(lets, bp);	/* necessary since we destroy buf */ 621. 	if(foo > 5)			/* compactify string */ 622. 		compactify(bp); 623.  624.  	if(!foo && !allowall && !allowgold && !allownone) { 625. 		You("don't have anything %sto %s.",  626.  			foox ? "else " : "", word); 627. 		return((struct obj *)0); 628. 	}  629.  	for { 630. 		cnt = 0; 631. 		if (allowcnt == 2) allowcnt = 1;  /* abort previous count */ 632. 		if(!buf[0]) { 633. 			Sprintf(qbuf, "What do you want to %s? [*]", word); 634. 		} else { 635. 			Sprintf(qbuf, "What do you want to %s? [%s or ?*]",  636.  				word, buf); 637. 		}  638.  #ifdef REDO 639. 		if(!in_doagain) 640. 		    ilet = yn_function(qbuf, NULL, '\0'); 641. 		else 642. #endif 643. 		    ilet = readchar; 644. 		if(ilet == '0') prezero = TRUE; 645. 		while(digit(ilet) && allowcnt) { 646. #ifdef REDO 647. 			if (ilet != '?' && ilet != '*')	savech(ilet); 648. #endif 649. 			cnt = 10*cnt + (ilet - '0'); 650. 			allowcnt = 2;	/* signal presence of cnt */ 651. 			ilet = readchar; 652. 		}  653.  		if(digit(ilet)) { 654. 			pline("No count allowed with this command."); 655. 			continue; 656. 		}  657.  		if(index(quitchars,ilet)) { 658. 		    if(flags.verbose) 659. 			pline("Never mind."); 660. 		    return((struct obj *)0); 661. 		}  662.  		if(ilet == '-') { 663. 			return(allownone ? &zeroobj : (struct obj *) 0); 664. 		}  665.  		if(ilet == def_oc_syms[GOLD_CLASS]) { 666. 			if(!usegold){ 667. 				You("cannot %s gold.", word); 668. 				return(struct obj *)0; 669. 			} else if (!allowgold) { 670. 				You("are not carrying any gold."); 671. 				return(struct obj *)0; 672. 			}  673.  			if(cnt == 0 && prezero) return((struct obj *)0); 674. 			/* Historic note: early Nethack had a bug which was 675. 			 * first reported for Larn, where trying to drop 2^32-n 676. 			 * gold pieces was allowed, and did interesting things 677. 			 * to your money supply. The LRS is the tax bureau 678. 			 * from Larn. 679. 			 */  680.  			if(cnt < 0) { 681. 	pline("The LRS would be very interested to know you have that much."); 682. 				return(struct obj *)0; 683. 			}  684.   685.  			if(!(allowcnt == 2 && cnt < u.ugold)) 686. 				cnt = u.ugold; 687. 			return(mkgoldobj(cnt)); 688. 		}  689.  		if(allowcnt == 2 && !strcmp(word,"throw")) { 690. 			/* permit counts for throwing gold, but don't accept 691. 			 * counts for other things since the throw code will 692. 			 * split off a single item anyway */ 693. 			allowcnt = 1; 694. 			if(cnt == 0 && prezero) return((struct obj *)0); 695. 			if(cnt > 1) { 696. 			    You("can only throw one item at a time."); 697. 			    continue; 698. 			}  699.  		}  700.  		if(ilet == '?' || ilet == '*') { 701. 		    ilet = display_inventory(ilet == '?' ? lets : NULL, FALSE); 702. 		    if(!ilet) continue; 703. 		    if(ilet == '\033') { 704. 			if(flags.verbose) 705. 			    pline("Never mind."); 706. 			return((struct obj *)0); 707. 		    }  708.  		    /* they typed a letter (not a space) at the prompt */ 709. 		}  710.  #ifdef REDO 711. 		savech(ilet); 712. #endif 713. 		if(flags.invlet_constant) { 714. 			for(otmp = invent; otmp; otmp = otmp->nobj) 715. 				if(otmp->invlet == ilet) break; 716. 		} else { 717. 			if(ilet >= 'A' && ilet <= 'Z') ilet += 'z' - 'A' + 1; 718. 			ilet -= 'a'; 719. 			for(otmp = invent; otmp && ilet;  720.  					ilet--, otmp = otmp->nobj) ; 721. 		}  722.  		if(!otmp) { 723. 			You("don't have that object."); 724. 			continue; 725. 		} else if (cnt < 0 || otmp->quan < cnt) { 726. 			You("don't have that many!  You have only %ld.",  727.  			    otmp->quan); 728. 			continue; 729. 		}  730.  		break; 731. 	}  732.  	if(!allowall && let && !index(let,otmp->oclass)) { 733. 		pline(silly_thing_to, word); 734. 		return((struct obj *)0); 735. 	}  736.  	if(allowcnt == 2) {	/* cnt given */ 737. 		if(cnt == 0) return (struct obj *)0; 738. 		if(cnt != otmp->quan) { 739. 			register struct obj *obj = splitobj(otmp, cnt); 740. 		/* Very ugly kludge necessary to prevent someone from trying 741. 		 * to drop one of several loadstones and having the loadstone 742. 		 * now be separate. 743. 		 */  744.  			if (!strcmp(word, "drop") &&  745.  			    obj->otyp == LOADSTONE && obj->cursed) 746. 				otmp->corpsenm = obj->invlet; 747. 			if(otmp == uwep) setuwep(obj); 748. 		}  749.  	}  750.  	return(otmp); 751. }  752.   753.  #endif /* OVL1 */ 754. #ifdef OVLB 755.  756.  STATIC_PTR int 757. ckunpaid(otmp) 758. register struct obj *otmp; 759. {  760.  	return((int)(otmp->unpaid)); 761. }  762.   763.  static boolean 764. wearing_armor { 765. 	return(uarm || uarmc || uarmf || uarmg || uarmh || uarms  766.  #ifdef TOURIST  767.  		|| uarmu  768.  #endif  769.  		); 770. }  771.   772.  static boolean 773. is_worn(otmp) 774. register struct obj *otmp; 775. {  776.      return(!!(otmp->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL | W_WEP))); 777. }  778.   779.  static const char NEARDATA removeables[] = 780. 	{ ARMOR_CLASS, WEAPON_CLASS, RING_CLASS, AMULET_CLASS, TOOL_CLASS, 0 }; 781.  782.  /* interactive version of getobj - used for Drop, Identify and */ 783. /* Takeoff (A). Return the number of times fn was called successfully */ 784. int 785. ggetobj(word, fn, mx) 786. register const char *word; 787. register int FDECL((*fn),(OBJ_P)), mx; 788. {  789.  	char buf[BUFSZ], qbuf[QBUFSZ]; 790. 	register char *ip; 791. 	register char sym; 792. 	register int oletct = 0, iletct = 0; 793. 	register boolean allflag = FALSE; 794. 	char olets[20], ilets[20]; 795. 	int FDECL((*ckfn),(OBJ_P)) = (int (*)) 0; 796. 	xchar allowgold = (u.ugold && !strcmp(word, "drop")) ? 1 : 0; /* BAH */ 797. 	register boolean takeoff = !strcmp(word, "take off"); 798. 	struct obj *obj; 799. 	int unpaid, oc_of_sym; 800.  801.  	if(takeoff && !wearing_armor && !uwep && !uamul &&  802.  			!uleft && !uright && !ublindf) { 803. 		You("are not wearing anything."); 804. 		return(0); 805. 	}  806.  	if(!invent && !allowgold){ 807. 		You("have nothing to %s.", word); 808. 		return(0); 809. 	}  810.   811.  	if (allowgold) ilets[iletct++] = def_oc_syms[GOLD_CLASS]; 812. 	ilets[iletct] = '\0';	/* terminate for index */ 813. 	unpaid = 0; 814. 	for (obj = invent; obj; obj = obj->nobj) { 815. 		sym = (char) def_oc_syms[(int) obj->oclass]; 816. 		if (!index(ilets, sym) && (!takeoff || is_worn(obj))) { 817. 			ilets[iletct++] = sym; 818. 			/* necessary because of index being used above */ 819. 			ilets[iletct] = '\0'; 820. 		}  821.   822.  		if (obj->unpaid) unpaid = 1; 823. 	}  824.   825.  	if (!takeoff && (unpaid || invent)) { 826. 	    ilets[iletct++] = ' '; 827. 	    if (unpaid) ilets[iletct++] = 'u'; 828. 	    if (invent) ilets[iletct++] = 'a'; 829. 	}  830.  	ilets[iletct] = '\0';	/* outside the if to catch iletct==0 case */ 831.  832.  	Sprintf(qbuf,"What kinds of thing do you want to %s? [%s]",  833.  		word, ilets); 834. 	getlin(qbuf, buf); 835. 	if(buf[0] == '\033') { 836. 		clear_nhwindow(WIN_MESSAGE); 837. 		return(0); 838. 	}  839.  	ip = buf; 840. 	olets[0] = 0; 841. 	while ((sym = *ip++) != 0) { 842. 		if(sym == ' ') continue; 843. 		oc_of_sym = def_char_to_objclass(sym); 844. 		if(takeoff && !(uwep && oc_of_sym == uwep->oclass)  845.  		   && (oc_of_sym != MAXOCLASSES)) { 846. 		    if(!index(removeables,oc_of_sym)) { 847. 			pline("Not applicable."); 848. 			return(0); 849. 		    } else if(oc_of_sym == ARMOR_CLASS && !wearing_armor) { 850. 			You("are not wearing any armor."); 851. 			return(0); 852. 		    } else if(oc_of_sym == WEAPON_CLASS && !uwep) { 853. 			You("are not wielding anything."); 854. 			return(0); 855. 		    } else if(oc_of_sym == RING_CLASS && !uright && !uleft) { 856. 			You("are not wearing rings."); 857. 			return(0); 858. 		    } else if(oc_of_sym == AMULET_CLASS && !uamul) { 859. 			You("are not wearing an amulet."); 860. 			return(0); 861. 		    } else if(oc_of_sym == TOOL_CLASS && !ublindf) { 862. 			You("are not wearing a blindfold."); 863. 			return(0); 864. 		    }  865.  		}  866.  		if(oc_of_sym == GOLD_CLASS) { 867. 			if(allowgold == 1) 868. 				(*fn)(mkgoldobj(u.ugold)); 869. 			else if(!u.ugold) 870. 				You("have no gold."); 871. 			allowgold = 2; 872. 		} else if(sym == 'a' || sym == 'A') 873. 		    allflag = TRUE; 874. 		else if(sym == 'u' || sym == 'U') 875. 		    ckfn = ckunpaid; 876. 		else if (oc_of_sym == MAXOCLASSES) 877. 			You("don't have any %c's.", sym); 878. 		else if (oc_of_sym != VENOM_CLASS) {/* venom doesn't show up */ 879. 			if (!index(olets, oc_of_sym)) { 880. 				olets[oletct++] = oc_of_sym; 881. 				olets[oletct] = 0; 882. 			}  883.  		}  884.  	}  885.  	if(allowgold == 2 && !oletct) 886. 		return 1;	/* you dropped gold (or at least tried to) */ 887. 	else 888. 		return askchain((struct obj **)&invent, olets, allflag,  889.  				fn, ckfn, mx, word); 890. }  891.   892.  /*  893.   * Walk through the chain starting at objchn and ask for all objects 894.  * with olet in olets (if nonNULL) and satisfying ckfn (if nonNULL) 895.  * whether the action in question (i.e., fn) has to be performed. 896.  * If allflag then no questions are asked. Max gives the max nr of 897. * objects to be treated. Return the number of objects treated. 898.  */  899.  int 900. askchain(objchn, olets, allflag, fn, ckfn, mx, word) 901. struct obj **objchn; 902. register int allflag, mx; 903. register const char *olets, *word;	/* olets is an Obj Class char array */ 904. register int FDECL((*fn),(OBJ_P)), FDECL((*ckfn),(OBJ_P)); 905. {  906.  	register struct obj *otmp, *otmp2; 907. 	register char sym, ilet; 908. 	register int cnt = 0, dud = 0, tmp; 909. 	boolean takeoff, nodot, ident, ininv; 910. 	char qbuf[QBUFSZ]; 911.  912.  	takeoff = !strcmp(word, "take off"); 913. 	ident = !strcmp(word, "identify"); 914. 	nodot = (!strcmp(word, "nodot") || !strcmp(word, "drop") ||  915.  		 ident || takeoff); 916. 	ininv = (*objchn == invent); 917. 	/* Changed so the askchain is interrogated in the order specified. 918. 	 * For example, if a person specifies =/ then first all rings will be  919. * asked about followed by all wands -dgk 920. 	 */  921.  nextclass: 922. 	ilet = 'a'-1; 923. 	if ((*objchn)->otyp == GOLD_PIECE) ilet--;	/* extra iteration */ 924. 	for (otmp = *objchn; otmp; otmp = otmp2) { 925. 		if(ilet == 'z') ilet = 'A'; else ilet++; 926. 		otmp2 = otmp->nobj; 927. 		if (olets && *olets && otmp->oclass != *olets) continue; 928. 		if(takeoff && !is_worn(otmp)) continue; 929. 		if(ckfn && !(*ckfn)(otmp)) continue; 930. 		if(!allflag) { 931. 			Strcpy(qbuf, ininv ?  932.  				xprname(otmp, ilet, !nodot, 0L) : doname(otmp)); 933. 			Strcat(qbuf, "?"); 934. 			sym = (takeoff || ident || otmp->quan < 2L) ? 935. 				nyaq(qbuf) : nyNaq(qbuf); 936. 		}  937.  		else	sym = 'y'; 938.  939.  		if (sym == '#') { 940. 		 /* Number was entered; split the object unless it corresponds 941. 		    to 'none' or 'all'. 2 special cases: cursed loadstones and 942. 		    welded weapons (eg, multiple daggers) will remain as merged 943. 		    unit; done to avoid splitting an object that won't be  944. droppable (even if we're picking up rather than dropping). 945. 		  */  946.  		    if (!yn_number) 947. 			sym = 'n'; 948. 		    else { 949. 			sym = 'y'; 950. 			if (yn_number < otmp->quan && !welded(otmp) &&  951.  			    (!otmp->cursed || otmp->otyp != LOADSTONE)) { 952. 			    struct obj *otmpx = splitobj(otmp, yn_number); 953. 			    if (!otmpx || otmpx->nobj != otmp2) 954. 				impossible("bad object split in askchain"); 955. 			}  956.  		    }  957.  		}  958.  		switch(sym){ 959. 		case 'a': 960. 			allflag = 1; 961. 		case 'y': 962. 			tmp = (*fn)(otmp); 963. 			if(tmp < 0) goto ret; 964. 			cnt += tmp; 965. 			if(--mx == 0) goto ret; 966. 		case 'n': 967. 			if(nodot) dud++; 968. 		default: 969. 			break; 970. 		case 'q': 971. 			goto ret; 972. 		}  973.  	}  974.  	if (olets && *olets && *++olets) 975. 		goto nextclass; 976. 	if(!takeoff && (dud || cnt)) pline("That was all."); 977. 	else if(!dud && !cnt) pline("No applicable objects."); 978. ret: 979. 	return(cnt); 980. }  981.   982.  #endif /* OVLB */ 983. #ifdef OVL2 984.  985.  STATIC_OVL char 986. obj_to_let(obj)	/* should of course only be called for things in invent */ 987. register struct obj *obj; 988. {  989.  	register struct obj *otmp; 990. 	register char ilet; 991.  992.  	if (obj->otyp == GOLD_PIECE) 993. 		return GOLD_SYM; 994. 	else if (flags.invlet_constant) 995. 		return obj->invlet; 996. 	ilet = 'a'; 997. 	for(otmp = invent; otmp && otmp != obj; otmp = otmp->nobj) 998. 		if(++ilet > 'z') ilet = 'A'; 999. 	return(otmp ? ilet : NOINVSYM); 1000. } 1001.  1002. /*  1003.  * Print the indicated quantity of the given object. If quan == 0L then use 1004. * the current quantity. 1005. */  1006. void 1007. prinv(prefix, obj, quan) 1008. const char *prefix; 1009. register struct obj *obj; 1010. long quan; 1011. { 1012. #ifdef GCC_WARN 1013. 	long savequan = 0; 1014. #else 1015. 	long savequan; 1016. #endif 1017. 	if ( !prefix ) prefix = ""; 1018. 	if (quan) { 1019. 		savequan = obj->quan; 1020. 		obj->quan = quan; 1021. 	} 1022. 	pline("%s%s%s",  1023. 	      prefix, *prefix ? " " : "",  1024. 	      xprname(obj, obj_to_let(obj), TRUE, 0L)); 1025. 	if (quan) obj->quan = savequan; 1026. } 1027.  1028. #endif /* OVL2 */ 1029. #ifdef OVL1 1030. 1031. char * 1032. xprname(obj,let,dot,cost) 1033. register struct obj *obj; 1034. register char let; 1035. register boolean dot;  /* append period; (dot && cost => Iu) */ 1036. register long cost;    /* cost (for inventory of unpaid or expended items) */ 1037. { 1038. #ifdef LINT	/* handle static char li[BUFSZ]; */ 1039. 	char li[BUFSZ]; 1040. #else 1041. 	static char li[BUFSZ]; 1042. #endif 1043. 	boolean use_invlet = flags.invlet_constant && let != CONTAINED_SYM; 1044.    /*  1045.      * If let is: 1046.     *	*  Then obj == NULL and we are printing a total amount. 1047.     *	>  Then the object is contained and doesn't have an inventory letter. 1048.     */  1049.     if (cost != 0 || let == '*') { 1050. 	/* if dot is true, we're doing Iu, otherwise Ix */ 1051. 	Sprintf(li, "%c - %-45s %6ld zorkmid%s", 1052. 		(dot && use_invlet ? obj->invlet : let), 1053. 		(let != '*' ? doname(obj) : "Total:"), cost, plur(cost)); 1054.    } else if (obj->otyp == GOLD_PIECE) { 1055. 	Sprintf(li, "%ld gold piece%s%s", obj->quan, plur(obj->quan), 1056. 		(dot ? "." : "")); 1057.     } else { 1058. 	/* ordinary inventory display or pickup message */ 1059. 	Sprintf(li, "%c - %s", 1060. 		(use_invlet ? obj->invlet : let), 1061. 		doname(obj)); 1062. 	if(dot) Strcat(li,"."); 1063.    }  1064.     return li; 1065. } 1066.  1067. #endif /* OVL1 */ 1068. #ifdef OVLB 1069. 1070. int 1071. ddoinv 1072. { 1073. 	(void) display_inventory(NULL, FALSE); 1074. 	return 0; 1075. } 1076.  1077. /*  1078.  *  find_unpaid 1079. *  1080.  *  Scan the given list of objects. If last_found is NULL, return the first 1081. *  unpaid object found. If last_found is not NULL, then skip over unpaid 1082. *  objects until last_found is reached, then set last_found to NULL so the 1083. *  next unpaid object is returned. This routine recursively follows 1084. *  containers. 1085. */  1086. static struct obj * 1087. find_unpaid(list, last_found) 1088.    struct obj *list, **last_found; 1089. { 1090.     struct obj *obj; 1091. 1092.     while (list) { 1093. 	if (list->unpaid) { 1094. 	   if (*last_found) { 1095. 		/* still looking for previous unpaid object */ 1096. 		if (list == *last_found) 1097. 		   *last_found = (struct obj *) 0; 1098. 	   } else 1099. 		return (*last_found = list); 1100. 	} 1101. 	if (Is_container(list) && list->cobj) { 1102. 	   if ((obj = find_unpaid(list->cobj, last_found)) != 0) 1103. 		return obj; 1104. 	} 1105. 	list = list->nobj; 1106.    }  1107.     return (struct obj *) 0; 1108. } 1109.  1110. /*  1111.  *  If lets == NULL or "", list all objects in the inventory. Otherwise, 1112. *  list all objects with object classes that match the order in lets. 1113. *  The last letter could possibly be a '>' which means list unpaid contained 1114. *  objects. 1115. *  Returns the letter identifier of a selected item, or 0 (nothing was  1116.  *  selected), or '\033' (the menu was cancelled). 1117. */  1118. char 1119. display_inventory(lets,show_cost) 1120. register const char *lets; 1121. boolean show_cost; 1122. { 1123. 	register struct obj *otmp; 1124. 	struct obj *z_obj; 1125. 	register char ilet; 1126. 	char *invlet = inv_order; 1127. 	int classcount; 1128. #if defined(LINT) || defined(GCC_WARN) 1129. 	int save_unpaid = 0; 1130. #else 1131. 	int save_unpaid; 1132. #endif 1133. 	long cost, totcost; 1134. 	boolean do_containers = FALSE; 1135. 1136. 	if(!invent){ 1137. 		pline("Not carrying anything."); 1138. 		return 0; 1139. 	} 1140. 	if (lets != NULL) { 1141. 	   int ct = strlen(lets); /* count number of inventory slots to show */ 1142. 	   /* If we've got unpaid items in containers, count all unpaid 1143. 	      objects. At least one won't be in any inventory slot. */ 1144. 	    do_containers = (ct && lets[ct-1] == CONTAINED_SYM); 1145. 	   if (do_containers && ct == 1) ct = count_unpaid(invent); 1146. 	   /* if only one item of interest, use pline instead of menus */ 1147. 	   if (ct == 1) { 1148. 		if (do_containers) {	/* single non-inventory object */ 1149. 		   z_obj = (struct obj *) 0; 1150. 		   if ((otmp = find_unpaid(invent, &z_obj)) != 0) 1151. 			pline(xprname(otmp, CONTAINED_SYM, TRUE, 1152. 				    (show_cost ? unpaid_cost(otmp) : 0L))); 1153. 		   else 1154. 			impossible( 1155. 		    "display_inventory: no singular unpaid contained objects"); 1156. 		} else { 1157. 		   for(otmp = invent; otmp; otmp = otmp->nobj) { 1158. 			if (otmp->invlet == lets[0]) { 1159. 			   pline(xprname(otmp, lets[0], TRUE, 1160. 					 (show_cost ? unpaid_cost(otmp) : 0L))); 1161. 			   break; 1162. 			} 1163. 		    }  1164. 		}  1165. 		return 0; 1166. 	   }  1167. 	}  1168.  1169. 	start_menu(WIN_INVEN); 1170. 	cost = totcost = 0; 1171. nextclass: 1172. 	classcount = 0; 1173. 	ilet = 'a'; 1174. 	for(otmp = invent; otmp; otmp = otmp->nobj) { 1175. 		if(flags.invlet_constant) ilet = otmp->invlet; 1176. 		if(!lets || !*lets || index(lets, ilet)) { 1177. 			if (!flags.sortpack || otmp->oclass == *invlet) { 1178. 			   if (flags.sortpack && !classcount) { 1179. 				add_menu(WIN_INVEN, 0, ATR_INVERSE, 1180. 					 let_to_name(*invlet, show_cost)); 1181. 				classcount++; 1182. 			   }  1183. 			    if (show_cost) { 1184. 				totcost += cost = unpaid_cost(otmp); 1185. 				/* suppress "(unpaid)" suffix */ 1186. 				save_unpaid = otmp->unpaid; 1187. 				otmp->unpaid = 0; 1188. 			   }  1189. 			    add_menu(WIN_INVEN, ilet, 0,  1190. 				     xprname(otmp, ilet, TRUE, cost)); 1191. 			   if (show_cost)  otmp->unpaid = save_unpaid; 1192. 			} 1193. 		}  1194. 		if(!flags.invlet_constant) if(++ilet > 'z') ilet = 'A'; 1195. 	} 1196. 	if (flags.sortpack) { 1197. 		if (*++invlet) goto nextclass; 1198. #ifdef WIZARD 1199. 		if (--invlet != venom_inv) { 1200. 			invlet = venom_inv; 1201. 			goto nextclass; 1202. 		} 1203. #endif 1204. 	} 1205.  1206. 	/* right now, we only do this for unpaid items, so always do cost */ 1207. 	if (do_containers) { 1208. 	   if (flags.sortpack) add_menu(WIN_INVEN, 0, ATR_INVERSE,  1209. 					 let_to_name(CONTAINED_SYM, 1)); 1210. 	   /*  1211. 	     *  Search through the container objects in the inventory for 1212. 	    *  unpaid items. Note that we check each container, not 1213. 	    *  the invent list. This is because the invent list could 1214. 	    *  have unpaid items that have been already listed. 1215. 	    */  1216. 	    for (otmp = invent; otmp; otmp = otmp->nobj) { 1217. 		if (Is_container(otmp) && otmp->cobj) { 1218. 		   z_obj = (struct obj *) 0;	/* haven't found any */ 1219. 		   while (find_unpaid(otmp->cobj, (struct obj **)&z_obj)) { 1220. 			totcost += cost = unpaid_cost(z_obj); 1221. 			save_unpaid = z_obj->unpaid; 1222. 			z_obj->unpaid = 0;   /* suppress "(unpaid)" suffix */ 1223. 			add_menu(WIN_INVEN, 0, 0, 1224. 				 xprname(z_obj, CONTAINED_SYM, TRUE, cost)); 1225. 			z_obj->unpaid = save_unpaid; 1226. 		   }  1227. 		}  1228. 	    }  1229. 	}  1230.  1231. 	if (show_cost) { 1232. 	   /* give 'Totals' line */ 1233. 	   add_menu(WIN_INVEN, 0, 0, ""); 1234. 	   add_menu(WIN_INVEN, 0, 0,  1235. 		     xprname((struct obj *)0, '*', FALSE, totcost)); 1236. 	} 1237. 	end_menu(WIN_INVEN, '\033', "\033 ", NULL); 1238. 	return select_menu(WIN_INVEN); 1239. } 1240.  1241. /*  1242.  *  Returns the number of unpaid items within the given list. This includes 1243. *  contained objects. 1244. */  1245. int 1246. count_unpaid(list) 1247.    struct obj *list; 1248. { 1249.     int count = 0; 1250. 1251.     while (list) { 1252. 	if (list->unpaid) count++; 1253. 	if (Is_container(list) && list->cobj) 1254. 	   count += count_unpaid(list->cobj); 1255. 	list = list->nobj; 1256.    }  1257.     return count; 1258. } 1259.  1260. int 1261. dotypeinv				/* free after Robert Viduya */ 1262. /* Changed to one type only, so you don't have to type return */ 1263. { 1264. 	char c, ilet; 1265. 	char stuff[BUFSZ]; 1266. 	register int stct; 1267. 	register struct obj *otmp; 1268. 	boolean billx = *u.ushops && doinvbill(0); 1269. 	boolean do_unpd = FALSE; 1270. 	int unpd, class; 1271. 1272. 	if (!invent && !u.ugold && !billx) { 1273. 	   You("aren't carrying anything."); 1274. 	   return 0; 1275. 	} 1276.  1277. 	Strcpy(stuff, "What type of object do you want an inventory of? ["); 1278. 	/* collect a list of classes of objects carried, for use as a prompt */ 1279. 	stct = collect_obj_classes(eos(stuff), invent, FALSE, (u.ugold != 0)); 1280. 	unpd = count_unpaid(invent); 1281. 	if(unpd) Strcat(stuff, "u"); 1282. 	if(billx) Strcat(stuff, "x"); 1283. 	Strcat(stuff, "]"); 1284. 1285. 	if(stct > 1) { 1286. 	 c = yn_function(stuff, NULL, '\0'); 1287. #ifdef REDO 1288. 	   savech(c); 1289. #endif 1290. 	   if(c == '\0') { 1291. 		clear_nhwindow(WIN_MESSAGE); 1292. 		return 0; 1293. 	   }  1294. 	} else 1295. 	   c = stuff[0]; 1296. 1297. 	if(c == 'x' || c == 'X') { 1298. 	   if(billx) 1299. 		(void) doinvbill(1); 1300. 	   else 1301. 		pline("No used-up objects on the shopping bill."); 1302. 	   return(0); 1303. 	} 1304.  1305. 	if (c == 'u' || c == 'U') { 1306. 	   if (!unpd) { 1307. 		You("are not carrying any unpaid objects."); 1308. 		return(0); 1309. 	   }  1310. 	    do_unpd = TRUE; 1311. 	} 1312.  1313. 	class = def_char_to_objclass(c);	/* change to object class */ 1314. 1315. 	if(class == GOLD_CLASS) 1316. 	   return(doprgold); 1317. 1318. 	/* collect all items which match the selected objclass */ 1319. 	stct = 0; 1320. 	ilet = 'a'; 1321. 	for (otmp = invent; otmp; otmp = otmp->nobj) { 1322. 	   if(flags.invlet_constant) ilet = otmp->invlet; 1323. 	   if (class == otmp->oclass || (do_unpd && otmp->unpaid)) { 1324. 		stuff[stct++] = ilet; 1325. 		--unpd;	/* decrement unpaid count */ 1326. 	   }  1327. 	    if(!flags.invlet_constant) if(++ilet > 'z') ilet = 'A'; 1328. 	} 1329. 	/* unpd is now the number of unpaid contained objects */ 1330. 	if (do_unpd && unpd) 1331. 	   stuff[stct++] = CONTAINED_SYM;	/* list contained unpaid items */ 1332. 1333. 	stuff[stct] = '\0'; 1334. 	if(stct == 0) 1335. 		You("have no such objects."); 1336. 	else 1337. 		(void) display_inventory(stuff, do_unpd); 1338. 1339. 	return(0); 1340. } 1341.  1342. /* look at what is here */ 1343. int 1344. dolook 1345. { 1346. 	register struct obj *otmp, *otmp0; 1347. 	struct trap *trap; 1348. 	const char *verb = Blind ? "feel" : "see"; 1349. 	const char *dfeature = (char*) 0; 1350. 	char fbuf[BUFSZ], fbuf2[BUFSZ]; 1351. 	int ct; 1352. 	boolean no_article = FALSE; 1353. 	winid tmpwin; 1354. 1355. 	if(u.uswallow) { 1356. 		You("%s no objects here.", verb); 1357. 		return(!!Blind); 1358. 	} 1359. 	read_engr_at(u.ux, u.uy); /* Eric Backus */ 1360. 	if ((trap = t_at(u.ux,u.uy)) && trap->tseen) 1361. 		pline("There is a%s here.", traps[trap->ttyp]); 1362. 1363. 	otmp0 = level.objects[u.ux][u.uy]; 1364. 1365. 	if(IS_DOOR(levl[u.ux][u.uy].typ))  { 1366. 		switch(levl[u.ux][u.uy].doormask) { 1367. 		   case D_NODOOR: 1368. 			dfeature = "doorway"; break; 1369. 		   case D_ISOPEN: 1370. 			dfeature = "open door"; break; 1371. 		   case D_BROKEN: 1372. 			dfeature = "broken door"; break; 1373. 		   default: 1374. 			dfeature = "closed door"; 1375. 		} 1376. 	} else if(IS_FOUNTAIN(levl[u.ux][u.uy].typ)) 1377. 		/* added by GAN 10/30/86 */ 1378. 		dfeature = "fountain"; 1379. 	else if(IS_THRONE(levl[u.ux][u.uy].typ)) 1380. 		dfeature = "opulent throne"; 1381. 	else if(is_lava(u.ux,u.uy)) 1382. 		dfeature = "molten lava", no_article = TRUE; 1383. 	else if(is_ice(u.ux,u.uy)) 1384. 		dfeature = "ice", no_article = TRUE; 1385. 	else if(is_pool(u.ux,u.uy) && !Underwater) 1386. 		dfeature = "pool of water"; 1387. #ifdef SINKS 1388. 	else if(IS_SINK(levl[u.ux][u.uy].typ)) 1389. 		dfeature = "kitchen sink"; 1390. #endif 1391. 	else if(IS_ALTAR(levl[u.ux][u.uy].typ)) { 1392. 		Sprintf(fbuf2, "altar to %s (%s)", 1393. 			a_gname,  1394. 			align_str(Amask2align(levl[u.ux][u.uy].altarmask  1395. 							    & ~AM_SHRINE))); 1396. 		dfeature = fbuf2; 1397. 	} else if(u.ux == xupstair && u.uy == yupstair) 1398. 		dfeature = "stairway up"; 1399. 	else if(u.ux == xdnstair && u.uy == ydnstair) 1400. 		dfeature = "stairway down"; 1401. 	else if(u.ux == sstairs.sx && u.uy == sstairs.sy) { 1402. 		if (sstairs.up) 1403. 			dfeature = "stairway up"; 1404. 		else 1405. 			dfeature = "stairway down"; 1406. 	} else if(u.ux == xupladder && u.uy == yupladder) 1407. 		dfeature = "ladder up"; 1408. 	else if(u.ux == xdnladder && u.uy == ydnladder) 1409. 		dfeature = "ladder down"; 1410. 	else if (levl[u.ux][u.uy].typ == DRAWBRIDGE_DOWN) 1411. 		dfeature = "lowered drawbridge"; 1412. 1413. 	if (Blind) { 1414. 		You("try to feel what is %s.", 1415. 		    Is_airlevel(&u.uz) || Is_waterlevel(&u.uz) ?  1416. 			"floating here" :  1417. 			"lying here on the floor"); 1418. 	 	if (Levitation && 1419. 		    !Is_airlevel(&u.uz) && !Is_waterlevel(&u.uz)) { 1420. 			pline("But you can't reach it!"); 1421. 			return(0); 1422. 	 	} 1423. 	}  1424.  1425. 	if (dfeature) 1426. 		Sprintf(fbuf, "There is %s%s here.", 1427. 			no_article ? "" :  1428. 				index(vowels,dfeature[0]) ? "an " : "a ",  1429. 			dfeature); 1430. 1431. 	if(!otmp0 || (is_pool(u.ux,u.uy) && !Underwater)) { 1432. 	   	if(dfeature) pline(fbuf); 1433. 		if(Blind || !dfeature) 1434. 			You("%s no objects here.", verb); 1435. 		return(!!Blind); 1436. 	} 1437. 	/* we know there is something here */ 1438. 1439. 	/* find out if there is more than one object there */ 1440. 	for (ct = 0, otmp = otmp0; otmp; otmp = otmp->nexthere) 1441. 	   if (++ct > 1) break; 1442. 1443. 	if (ct == 1) { 1444. 	   if (dfeature) pline(fbuf); 1445. 	   You("%s here %s.", verb, doname(otmp0)); 1446. 	} else { 1447. 	   display_nhwindow(NHW_MESSAGE, FALSE); 1448. 	   tmpwin = create_nhwindow(NHW_MENU); 1449. 	   if(dfeature) { 1450. 		putstr(tmpwin, 0, fbuf); 1451. 		putstr(tmpwin, 0, ""); 1452. 	   }  1453. 	    putstr(tmpwin, 0, "Things that are here:"); 1454. 	   for(otmp = otmp0; otmp; otmp = otmp->nexthere) { 1455. 		putstr(tmpwin, 0, doname(otmp)); 1456. 1457. 		if(Blind  && !uarmg &&  1458. #ifdef POLYSELF  1459. 			    !resists_ston(uasmon) &&  1460. #endif  1461. 			    (otmp->otyp == CORPSE && 1462. 					otmp->corpsenm == PM_COCKATRICE)) { 1463. #if defined(POLYSELF) 1464. 		   if(poly_when_stoned(uasmon)) { 1465. 			You("touched the cockatrice corpse with your bare hands."); 1466. 			(void) polymon(PM_STONE_GOLEM); 1467. 		   } else 1468. #endif 1469. 		   {  1470. 			pline("Touching the cockatrice corpse is a fatal mistake..."); 1471. 			You("turn to stone..."); 1472. 			killer_format = KILLED_BY_AN; 1473. 			killer = "cockatrice corpse"; 1474. 			done(STONING); 1475. 		   }  1476. 		}  1477. 	    }  1478. 	    display_nhwindow(tmpwin, TRUE); 1479. 	   destroy_nhwindow(tmpwin); 1480. 	} 1481. 	return(!!Blind); 1482. } 1483.  1484. #endif /* OVLB */ 1485. #ifdef OVL1 1486. 1487. void 1488. stackobj(obj) 1489. register struct obj *obj; 1490. { 1491. 	register struct obj *otmp; 1492. 1493. 	for(otmp = level.objects[obj->ox][obj->oy]; otmp; otmp = otmp->nexthere) 1494. 		if(otmp != obj && merged(obj,otmp,1)) 1495. 			break; 1496. 	return; 1497. } 1498.  1499. static boolean 1500. mergable(otmp, obj)	/* returns TRUE if obj & otmp can be merged */ 1501. 	register struct obj *otmp, *obj; 1502. { 1503. 	if(obj->otyp != otmp->otyp || obj->unpaid != otmp->unpaid ||  1504. 	   obj->spe != otmp->spe || obj->dknown != otmp->dknown ||  1505. 	   (obj->bknown != otmp->bknown && pl_character[0] != 'P') ||  1506. 	   obj->cursed != otmp->cursed || obj->blessed != otmp->blessed ||  1507. 	   obj->no_charge != otmp->no_charge ||  1508. 	   obj->obroken != otmp->obroken ||  1509. 	   obj->otrapped != otmp->otrapped ||  1510. 	   obj->oeroded != otmp->oeroded) 1511. 	   return(FALSE); 1512. 1513. 	if((obj->oclass==WEAPON_CLASS || obj->oclass==ARMOR_CLASS) &&  1514. 	   (obj->oerodeproof!=otmp->oerodeproof || obj->rknown!=otmp->rknown)) 1515. 		return FALSE; 1516. 1517. 	if(obj->oclass == FOOD_CLASS && (obj->oeaten != otmp->oeaten || 1518. 		obj->orotten != otmp->orotten)) 1519. 		return(FALSE); 1520. 1521. 	if(obj->otyp == CORPSE || obj->otyp == EGG || obj->otyp == TIN) { 1522. 		if((obj->corpsenm != otmp->corpsenm) || 1523. 			(ONAME(obj) && strcmp(ONAME(obj), ONAME(otmp)))) 1524. 				return FALSE; 1525. 	} 1526.  1527. /* if they have names, make sure they're the same */ 1528. 	if ( (obj->onamelth != otmp->onamelth && 1529. 		((obj->onamelth && otmp->onamelth) || obj->otyp == CORPSE) 1530. 	    ) ||  1531. 	    (obj->onamelth && 1532. 		   strncmp(ONAME(obj), ONAME(otmp), (int)obj->onamelth))) 1533. 		return FALSE; 1534. 1535. 	if(obj->oartifact != otmp->oartifact) return FALSE; 1536. 1537. 	if(obj->known == otmp->known ||  1538. 		!objects[otmp->otyp].oc_uses_known) { 1539. 		return(objects[obj->otyp].oc_merge); 1540. 	} else return(FALSE); 1541. } 1542.  1543. #endif /* OVL1 */ 1544. #ifdef OVLB 1545. 1546. int 1547. doprgold{ 1548. 	if(!u.ugold) 1549. 		You("do not carry any gold."); 1550. 	else 1551. 		You("are carrying %ld gold piece%s.", u.ugold, plur(u.ugold)); 1552. 	return 0; 1553. } 1554.  1555. int 1556. doprwep 1557. { 1558. 	if(!uwep) You("are empty %s.", body_part(HANDED)); 1559. 	else prinv(NULL, uwep, 0L); 1560. 	return 0; 1561. } 1562.  1563. int 1564. doprarm{ 1565. 	if(!wearing_armor) 1566. 		You("are not wearing any armor."); 1567. 	else { 1568. #ifdef TOURIST 1569. 		char lets[8]; 1570. #else 1571. 		char lets[7]; 1572. #endif 1573. 		register int ct = 0; 1574. 1575. #ifdef TOURIST 1576. 		if(uarmu) lets[ct++] = obj_to_let(uarmu); 1577. #endif 1578. 		if(uarm) lets[ct++] = obj_to_let(uarm); 1579. 		if(uarmc) lets[ct++] = obj_to_let(uarmc); 1580. 		if(uarmh) lets[ct++] = obj_to_let(uarmh); 1581. 		if(uarms) lets[ct++] = obj_to_let(uarms); 1582. 		if(uarmg) lets[ct++] = obj_to_let(uarmg); 1583. 		if(uarmf) lets[ct++] = obj_to_let(uarmf); 1584. 		lets[ct] = 0; 1585. 		(void) display_inventory(lets, FALSE); 1586. 	} 1587. 	return 0; 1588. } 1589.  1590. int 1591. doprring{ 1592. 	if(!uleft && !uright) 1593. 		You("are not wearing any rings."); 1594. 	else { 1595. 		char lets[3]; 1596. 		register int ct = 0; 1597. 1598. 		if(uleft) lets[ct++] = obj_to_let(uleft); 1599. 		if(uright) lets[ct++] = obj_to_let(uright); 1600. 		lets[ct] = 0; 1601. 		(void) display_inventory(lets, FALSE); 1602. 	} 1603. 	return 0; 1604. } 1605.  1606. int 1607. dopramulet{ 1608. 	if (!uamul) 1609. 		You("are not wearing an amulet."); 1610. 	else 1611. 		prinv(NULL, uamul, 0L); 1612. 	return 0; 1613. } 1614.  1615. int 1616. doprtool{ 1617. 	register struct obj *otmp; 1618. 	register int ct=0; 1619. 	char lets[3]; /* Maximum: pick-axe, blindfold */ 1620. 1621. 	for(otmp = invent; otmp; otmp = otmp->nobj) { 1622. 		if (((otmp->owornmask & W_TOOL) && otmp->oclass==TOOL_CLASS) 1623. 		   || (otmp==uwep && 1624. 		  (otmp->otyp==PICK_AXE || otmp->otyp==TIN_OPENER))) 1625. 			lets[ct++] = obj_to_let(otmp); 1626. 	} 1627. 	lets[ct] = 0; 1628. 	if (!ct) You("are not using any tools."); 1629. 	else (void) display_inventory(lets, FALSE); 1630. 	return 0; 1631. } 1632.  1633. /*  1634.  * uses up an object that's on the floor, charging for it as necessary 1635. */  1636. void 1637. useupf(obj) 1638. register struct obj *obj; 1639. { 1640. 	register struct obj *otmp; 1641. 1642. 	/* burn_floor_paper keeps an object pointer that it tries to  1643. * useupf multiple times, so obj must survive if plural */ 1644. 	if(obj->quan > 1L) 1645. 		otmp = splitobj(obj, obj->quan - 1L); 1646. 	else 1647. 		otmp = obj; 1648. 	if(costly_spot(otmp->ox, otmp->oy)) { 1649. 	   if(index(u.urooms, *in_rooms(otmp->ox, otmp->oy, 0))) 1650. 	       addtobill(otmp, FALSE, FALSE, FALSE); 1651. 	   else (void)stolen_value(otmp, otmp->ox, otmp->oy, FALSE, FALSE); 1652. 	} 1653. 	delobj(otmp); 1654. } 1655.  1656. #endif /* OVLB */ 1657. #ifdef OVL1 1658. 1659. extern const char obj_symbols[];	/* o_init.c */ 1660. /* 1661.  * Conversion from a symbol to a string for printing object classes. 1662. * This must match the array obj_symbols[]. 1663. */  1664. static const char NEARDATA *names[] = { 1665. 	"Illegal objects", "Amulets", "Coins", "Comestibles", "Weapons", 1666. 	"Tools", "Iron balls", "Chains", "Boulders/Statues", "Armor", 1667. 	"Potions", "Scrolls", "Wands", "Spellbooks", "Rings", "Gems" 1668. }; 1669.  1670. static const char NEARDATA oth_symbols[] = { 1671. #ifdef WIZARD 1672. 	VENOM_CLASS, 1673. #endif 1674. 	CONTAINED_SYM, 1675. 	'\0' 1676. };  1677.  1678. static const char NEARDATA *oth_names[] = { 1679. #ifdef WIZARD 1680. 	"Venoms", 1681. #endif 1682. 	"Bagged/Boxed items" 1683. }; 1684.  1685. char * 1686. let_to_name(let,unpaid) 1687. char let; 1688. boolean unpaid; 1689. { 1690. 	const char *class_name; 1691. 	const char *pos = index(obj_symbols, let); 1692. 	int len; 1693. 	static char NEARDATA *buf = NULL; 1694. 	static unsigned NEARDATA bufsiz = 0; 1695. 1696. 	if (pos) 1697. 	   class_name = names[pos - obj_symbols]; 1698. 	else if ((pos = index(oth_symbols, let)) != 0) 1699. 	   class_name = oth_names[pos - oth_symbols]; 1700. 	else 1701. 	   class_name = names[0]; 1702. 1703. 	len = strlen(class_name) 1704. 	    + (unpaid ? sizeof("unpaid_") : 1);    /* count terminating NUL */ 1705. 	if (len > bufsiz) { 1706. 	   if (buf)  free((genericptr_t)buf),  buf = NULL; 1707. 	   bufsiz = len + 10; /* add slop to avoid incremental reallocations */ 1708. 	   buf = (char *) alloc(bufsiz); 1709. 	} 1710. 	if (unpaid) 1711. 	   Strcat(strcpy(buf, "Unpaid "), class_name); 1712. 	else 1713. 	   Strcpy(buf, class_name); 1714. 	return (buf); 1715. } 1716.  1717. #endif /* OVL1 */ 1718. #ifdef OVLB 1719. 1720. void 1721. reassign 1722. { 1723. 	register int i;  1724. register struct obj *obj; 1725. 1726. 	for(obj = invent, i = 0; obj; obj = obj->nobj, i++) 1727. 		obj->invlet = (i < 26) ? ('a'+i) : ('A'+i-26); 1728. 	lastinvnr = i; 1729. } 1730.  1731. #endif /* OVLB */ 1732. #ifdef OVL1 1733. int 1734. doorganize	/* inventory organizer by Del Lamb */ 1735. { 1736. 	register struct obj *obj, *otmp; 1737. 	register int ix, cur; 1738. 	register char let; 1739. 	char alphabet[52+1], buf[52+1]; 1740. 	char qbuf[QBUFSZ]; 1741. 	char allow_all[2]; 1742. 	const char *adj_type; 1743. 1744. 	/* check to see if the inventory is of the fixed kind */ 1745. 	if (!flags.invlet_constant ) { 1746. 		pline("Sorry, only fixed inventories can be adjusted."); 1747. 		return(0); 1748. 	} 1749. #if 0 1750. 	/* check to see if the inventory has any gaps left in it */ 1751. 	if (inv_cnt >= 52) { 1752. 		pline("Sorry, no available letters for adjustment."); 1753. 		return(0); 1754. 	} 1755. #endif 1756. 	/* get a pointer to the object the user wants to organize */ 1757. 	allow_all[0] = ALL_CLASSES; allow_all[1] = '\0'; 1758. 	if (!(obj = getobj(allow_all,"adjust"))) return(0); 1759. 1760. 	/* initialize the list with all upper and lower case letters */ 1761. 	for (let = 'a', ix = 0; let <= 'z';) alphabet[ix++] = let++; 1762. 	for (let = 'A', ix = 26; let <= 'Z';) alphabet[ix++] = let++; 1763. 	alphabet[52] = 0; 1764. 1765. 	/* blank out all the letters currently in use in the inventory */ 1766. 	/* except those that will be merged with the selected object  */ 1767. 	for (otmp = invent; otmp; otmp = otmp->nobj) 1768. 		if (otmp != obj && !mergable(otmp,obj)) 1769. 			if (otmp->invlet <= 'Z') 1770. 				alphabet[(otmp->invlet) - 'A' + 26] = ' '; 1771. 			else	alphabet[(otmp->invlet) - 'a']	   = ' '; 1772. 1773. 	/* compact the list by removing all the blanks */ 1774. 	for (ix = cur = 0; ix <= 52; ix++) 1775. 		if (alphabet[ix] != ' ') buf[cur++] = alphabet[ix]; 1776. 1777. 	/* and by dashing runs of letters */ 1778. 	if(cur > 5) compactify(buf); 1779. 1780. 	/* get new letter to use as inventory letter */ 1781. 	for { 1782. 		Sprintf(qbuf, "Adjust letter to what [%s]?",buf); 1783. 		let = yn_function(qbuf, NULL, '\0'); 1784. 		if(index(quitchars,let)) { 1785. 			pline("Never mind."); 1786. 			return(0); 1787. 		} 1788. 		if (let == '@' || !letter(let)) 1789. 			pline("Select an inventory slot letter."); 1790. 		else 1791. 			break; 1792. 	} 1793.  1794. 	/* change the inventory and print the resulting item */ 1795. 	adj_type = "Moving:"; 1796. 1797. 	/*  1798. 	 * don't use freeinv/addinv to avoid double-touching artifacts, 1799. 	 * dousing lamps, losing luck, cursing loadstone, etc. 1800. 	 */ 1801. 	unlinkinv(obj); 1802. 1803. 	for (otmp = invent; otmp;) 1804. 		if (merged(otmp,obj,0)) { 1805. 			adj_type = "Merging:"; 1806. 			obj = otmp; 1807. 			otmp = otmp->nobj; 1808. 			unlinkinv(obj); 1809. 		} else { 1810. 			if (otmp->invlet == let) { 1811. 				adj_type = "Swapping:"; 1812. 				otmp->invlet = obj->invlet; 1813. 			} 1814. 			otmp = otmp->nobj; 1815. 		} 1816.  1817. 	/* inline addinv (assuming flags.invlet_constant and !merged) */ 1818. 	obj->invlet = let; 1819. 	obj->nobj = invent; /* insert at beginning */ 1820. 	invent = obj; 1821. 	reorder_invent; 1822. 1823. 	prinv(adj_type, obj, 0L); 1824. 	update_inventory; 1825. 	return(0); 1826. } 1827.  1828. #endif /* OVL1 */ 1829. 1830. /*invent.c*/