Wikia

Wikihack

Source:NetHack 3.1.0/invent.c

2,032pages on
this wiki
Talk0

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

The NetHack General Public License applies to screenshots, source code and other content from NetHack.
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*/

Around Wikia's network

Random Wiki