xref: /openbsd-src/games/hack/hack.invent.c (revision 6acf840eb12048fe6e815d917fa237f8a82441d8)
1*6acf840eSmestre /*	$OpenBSD: hack.invent.c,v 1.14 2016/01/09 21:54:11 mestre Exp $	*/
2d0b779f3Sniklas 
3df930be7Sderaadt /*
4d25013f2Scamield  * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
5d25013f2Scamield  * Amsterdam
6d25013f2Scamield  * All rights reserved.
7d25013f2Scamield  *
8d25013f2Scamield  * Redistribution and use in source and binary forms, with or without
9d25013f2Scamield  * modification, are permitted provided that the following conditions are
10d25013f2Scamield  * met:
11d25013f2Scamield  *
12d25013f2Scamield  * - Redistributions of source code must retain the above copyright notice,
13d25013f2Scamield  * this list of conditions and the following disclaimer.
14d25013f2Scamield  *
15d25013f2Scamield  * - Redistributions in binary form must reproduce the above copyright
16d25013f2Scamield  * notice, this list of conditions and the following disclaimer in the
17d25013f2Scamield  * documentation and/or other materials provided with the distribution.
18d25013f2Scamield  *
19d25013f2Scamield  * - Neither the name of the Stichting Centrum voor Wiskunde en
20d25013f2Scamield  * Informatica, nor the names of its contributors may be used to endorse or
21d25013f2Scamield  * promote products derived from this software without specific prior
22d25013f2Scamield  * written permission.
23d25013f2Scamield  *
24d25013f2Scamield  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
25d25013f2Scamield  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
26d25013f2Scamield  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
27d25013f2Scamield  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
28d25013f2Scamield  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29d25013f2Scamield  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
30d25013f2Scamield  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
31d25013f2Scamield  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
32d25013f2Scamield  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33d25013f2Scamield  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34d25013f2Scamield  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35d25013f2Scamield  */
36d25013f2Scamield 
37d25013f2Scamield /*
38d25013f2Scamield  * Copyright (c) 1982 Jay Fenlason <hack@gnu.org>
39d25013f2Scamield  * All rights reserved.
40d25013f2Scamield  *
41d25013f2Scamield  * Redistribution and use in source and binary forms, with or without
42d25013f2Scamield  * modification, are permitted provided that the following conditions
43d25013f2Scamield  * are met:
44d25013f2Scamield  * 1. Redistributions of source code must retain the above copyright
45d25013f2Scamield  *    notice, this list of conditions and the following disclaimer.
46d25013f2Scamield  * 2. Redistributions in binary form must reproduce the above copyright
47d25013f2Scamield  *    notice, this list of conditions and the following disclaimer in the
48d25013f2Scamield  *    documentation and/or other materials provided with the distribution.
49d25013f2Scamield  * 3. The name of the author may not be used to endorse or promote products
50d25013f2Scamield  *    derived from this software without specific prior written permission.
51d25013f2Scamield  *
52d25013f2Scamield  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
53d25013f2Scamield  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
54d25013f2Scamield  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
55d25013f2Scamield  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
56d25013f2Scamield  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
57d25013f2Scamield  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
58d25013f2Scamield  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
59d25013f2Scamield  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
60d25013f2Scamield  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
61d25013f2Scamield  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62df930be7Sderaadt  */
63df930be7Sderaadt 
644a5fbbc4Spjanzen #include <ctype.h>
65df930be7Sderaadt #include <stdio.h>
66aed906e4Smestre #include <stdlib.h>
67aed906e4Smestre 
684a5fbbc4Spjanzen #include "hack.h"
694a5fbbc4Spjanzen 
70df930be7Sderaadt extern struct obj zeroobj;
71df930be7Sderaadt extern char morc;
72df930be7Sderaadt extern char quitchars[];
73df930be7Sderaadt 
74df930be7Sderaadt #ifndef NOWORM
75df930be7Sderaadt extern struct wseg *wsegs[32];
7654da88e4Spjanzen #endif /* NOWORM */
77df930be7Sderaadt 
78df930be7Sderaadt #define	NOINVSYM	'#'
79df930be7Sderaadt 
80df930be7Sderaadt static int lastinvnr = 51;	/* 0 ... 51 */
814a5fbbc4Spjanzen 
824a5fbbc4Spjanzen static void assigninvlet(struct obj *);
834a5fbbc4Spjanzen static char obj_to_let(struct obj *);
844a5fbbc4Spjanzen static char *xprname(struct obj *, char);
854a5fbbc4Spjanzen static void doinv(char *);
864a5fbbc4Spjanzen static int  merged(struct obj *, struct obj *, int);
874a5fbbc4Spjanzen 
884a5fbbc4Spjanzen 
894a5fbbc4Spjanzen static void
assigninvlet(struct obj * otmp)904a5fbbc4Spjanzen assigninvlet(struct obj *otmp)
91df930be7Sderaadt {
92df930be7Sderaadt 	boolean inuse[52];
934a5fbbc4Spjanzen 	int i;
944a5fbbc4Spjanzen 	struct obj *obj;
95df930be7Sderaadt 
96df930be7Sderaadt 	for(i = 0; i < 52; i++) inuse[i] = FALSE;
97df930be7Sderaadt 	for(obj = invent; obj; obj = obj->nobj) if(obj != otmp) {
98df930be7Sderaadt 		i = obj->invlet;
99df930be7Sderaadt 		if('a' <= i && i <= 'z') inuse[i - 'a'] = TRUE; else
100df930be7Sderaadt 		if('A' <= i && i <= 'Z') inuse[i - 'A' + 26] = TRUE;
101df930be7Sderaadt 		if(i == otmp->invlet) otmp->invlet = 0;
102df930be7Sderaadt 	}
103df930be7Sderaadt 	if((i = otmp->invlet) &&
104df930be7Sderaadt 	    (('a' <= i && i <= 'z') || ('A' <= i && i <= 'Z')))
105df930be7Sderaadt 		return;
106df930be7Sderaadt 	for(i = lastinvnr+1; i != lastinvnr; i++) {
107df930be7Sderaadt 		if(i == 52) { i = -1; continue; }
108df930be7Sderaadt 		if(!inuse[i]) break;
109df930be7Sderaadt 	}
110df930be7Sderaadt 	otmp->invlet = (inuse[i] ? NOINVSYM :
111df930be7Sderaadt 			(i < 26) ? ('a'+i) : ('A'+i-26));
112df930be7Sderaadt 	lastinvnr = i;
113df930be7Sderaadt }
114df930be7Sderaadt 
115df930be7Sderaadt struct obj *
addinv(struct obj * obj)1164a5fbbc4Spjanzen addinv(struct obj *obj)
117df930be7Sderaadt {
1184a5fbbc4Spjanzen 	struct obj *otmp;
119df930be7Sderaadt 
120df930be7Sderaadt 	/* merge or attach to end of chain */
121df930be7Sderaadt 	if(!invent) {
122df930be7Sderaadt 		invent = obj;
123df930be7Sderaadt 		otmp = 0;
124df930be7Sderaadt 	} else
125df930be7Sderaadt 	for(otmp = invent; /* otmp */; otmp = otmp->nobj) {
126df930be7Sderaadt 		if(merged(otmp, obj, 0))
127df930be7Sderaadt 			return(otmp);
128df930be7Sderaadt 		if(!otmp->nobj) {
129df930be7Sderaadt 			otmp->nobj = obj;
130df930be7Sderaadt 			break;
131df930be7Sderaadt 		}
132df930be7Sderaadt 	}
133df930be7Sderaadt 	obj->nobj = 0;
134df930be7Sderaadt 
135df930be7Sderaadt 	if(flags.invlet_constant) {
136df930be7Sderaadt 		assigninvlet(obj);
137df930be7Sderaadt 		/*
138df930be7Sderaadt 		 * The ordering of the chain is nowhere significant
139df930be7Sderaadt 		 * so in case you prefer some other order than the
140df930be7Sderaadt 		 * historical one, change the code below.
141df930be7Sderaadt 		 */
142df930be7Sderaadt 		if(otmp) {	/* find proper place in chain */
143df930be7Sderaadt 			otmp->nobj = 0;
144df930be7Sderaadt 			if((invent->invlet ^ 040) > (obj->invlet ^ 040)) {
145df930be7Sderaadt 				obj->nobj = invent;
146df930be7Sderaadt 				invent = obj;
147df930be7Sderaadt 			} else
148df930be7Sderaadt 			for(otmp = invent; ; otmp = otmp->nobj) {
149df930be7Sderaadt 			    if(!otmp->nobj ||
150df930be7Sderaadt 				(otmp->nobj->invlet ^ 040) > (obj->invlet ^ 040)){
151df930be7Sderaadt 				obj->nobj = otmp->nobj;
152df930be7Sderaadt 				otmp->nobj = obj;
153df930be7Sderaadt 				break;
154df930be7Sderaadt 			    }
155df930be7Sderaadt 			}
156df930be7Sderaadt 		}
157df930be7Sderaadt 	}
158df930be7Sderaadt 
159df930be7Sderaadt 	return(obj);
160df930be7Sderaadt }
161df930be7Sderaadt 
1624a5fbbc4Spjanzen void
useup(struct obj * obj)1634a5fbbc4Spjanzen useup(struct obj *obj)
164df930be7Sderaadt {
165df930be7Sderaadt 	if(obj->quan > 1){
166df930be7Sderaadt 		obj->quan--;
167df930be7Sderaadt 		obj->owt = weight(obj);
168df930be7Sderaadt 	} else {
169df930be7Sderaadt 		setnotworn(obj);
170df930be7Sderaadt 		freeinv(obj);
171df930be7Sderaadt 		obfree(obj, (struct obj *) 0);
172df930be7Sderaadt 	}
173df930be7Sderaadt }
174df930be7Sderaadt 
1754a5fbbc4Spjanzen void
freeinv(struct obj * obj)1764a5fbbc4Spjanzen freeinv(struct obj *obj)
177df930be7Sderaadt {
1784a5fbbc4Spjanzen 	struct obj *otmp;
179df930be7Sderaadt 
180df930be7Sderaadt 	if(obj == invent)
181df930be7Sderaadt 		invent = invent->nobj;
182df930be7Sderaadt 	else {
183df930be7Sderaadt 		for(otmp = invent; otmp->nobj != obj; otmp = otmp->nobj)
184df930be7Sderaadt 			if(!otmp->nobj) panic("freeinv");
185df930be7Sderaadt 		otmp->nobj = obj->nobj;
186df930be7Sderaadt 	}
187df930be7Sderaadt }
188df930be7Sderaadt 
189df930be7Sderaadt /* destroy object in fobj chain (if unpaid, it remains on the bill) */
1904a5fbbc4Spjanzen void
delobj(struct obj * obj)1914a5fbbc4Spjanzen delobj(struct obj *obj)
1924a5fbbc4Spjanzen {
193df930be7Sderaadt 	freeobj(obj);
194df930be7Sderaadt 	unpobj(obj);
195df930be7Sderaadt 	obfree(obj, (struct obj *) 0);
196df930be7Sderaadt }
197df930be7Sderaadt 
198df930be7Sderaadt /* unlink obj from chain starting with fobj */
1994a5fbbc4Spjanzen void
freeobj(struct obj * obj)2004a5fbbc4Spjanzen freeobj(struct obj *obj)
2014a5fbbc4Spjanzen {
2024a5fbbc4Spjanzen 	struct obj *otmp;
203df930be7Sderaadt 
204df930be7Sderaadt 	if(obj == fobj) fobj = fobj->nobj;
205df930be7Sderaadt 	else {
206df930be7Sderaadt 		for(otmp = fobj; otmp->nobj != obj; otmp = otmp->nobj)
207df930be7Sderaadt 			if(!otmp) panic("error in freeobj");
208df930be7Sderaadt 		otmp->nobj = obj->nobj;
209df930be7Sderaadt 	}
210df930be7Sderaadt }
211df930be7Sderaadt 
212df930be7Sderaadt /* Note: freegold throws away its argument! */
2134a5fbbc4Spjanzen void
freegold(struct gold * gold)2144a5fbbc4Spjanzen freegold(struct gold *gold)
2154a5fbbc4Spjanzen {
2164a5fbbc4Spjanzen 	struct gold *gtmp;
217df930be7Sderaadt 
218df930be7Sderaadt 	if(gold == fgold) fgold = gold->ngold;
219df930be7Sderaadt 	else {
220df930be7Sderaadt 		for(gtmp = fgold; gtmp->ngold != gold; gtmp = gtmp->ngold)
221df930be7Sderaadt 			if(!gtmp) panic("error in freegold");
222df930be7Sderaadt 		gtmp->ngold = gold->ngold;
223df930be7Sderaadt 	}
224ebf3d589Sguenther 	free(gold);
225df930be7Sderaadt }
226df930be7Sderaadt 
2274a5fbbc4Spjanzen void
deltrap(struct trap * trap)2284a5fbbc4Spjanzen deltrap(struct trap *trap)
229df930be7Sderaadt {
2304a5fbbc4Spjanzen 	struct trap *ttmp;
231df930be7Sderaadt 
232df930be7Sderaadt 	if(trap == ftrap)
233df930be7Sderaadt 		ftrap = ftrap->ntrap;
234df930be7Sderaadt 	else {
235df930be7Sderaadt 		for(ttmp = ftrap; ttmp->ntrap != trap; ttmp = ttmp->ntrap) ;
236df930be7Sderaadt 		ttmp->ntrap = trap->ntrap;
237df930be7Sderaadt 	}
238ebf3d589Sguenther 	free(trap);
239df930be7Sderaadt }
240df930be7Sderaadt 
241df930be7Sderaadt struct wseg *m_atseg;
242df930be7Sderaadt 
243df930be7Sderaadt struct monst *
m_at(int x,int y)2444a5fbbc4Spjanzen m_at(int x, int y)
245df930be7Sderaadt {
2464a5fbbc4Spjanzen 	struct monst *mtmp;
247df930be7Sderaadt #ifndef NOWORM
2484a5fbbc4Spjanzen 	struct wseg *wtmp;
24954da88e4Spjanzen #endif /* NOWORM */
250df930be7Sderaadt 
251df930be7Sderaadt 	m_atseg = 0;
252df930be7Sderaadt 	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon){
253df930be7Sderaadt 		if(mtmp->mx == x && mtmp->my == y)
254df930be7Sderaadt 			return(mtmp);
255df930be7Sderaadt #ifndef NOWORM
256df930be7Sderaadt 		if(mtmp->wormno){
257df930be7Sderaadt 		    for(wtmp = wsegs[mtmp->wormno]; wtmp; wtmp = wtmp->nseg)
258df930be7Sderaadt 		    if(wtmp->wx == x && wtmp->wy == y){
259df930be7Sderaadt 			m_atseg = wtmp;
260df930be7Sderaadt 			return(mtmp);
261df930be7Sderaadt 		    }
262df930be7Sderaadt 		}
26354da88e4Spjanzen #endif /* NOWORM */
264df930be7Sderaadt 	}
265df930be7Sderaadt 	return(0);
266df930be7Sderaadt }
267df930be7Sderaadt 
268df930be7Sderaadt struct obj *
o_at(int x,int y)2694a5fbbc4Spjanzen o_at(int x, int y)
270df930be7Sderaadt {
2714a5fbbc4Spjanzen 	struct obj *otmp;
272df930be7Sderaadt 
273df930be7Sderaadt 	for(otmp = fobj; otmp; otmp = otmp->nobj)
274df930be7Sderaadt 		if(otmp->ox == x && otmp->oy == y) return(otmp);
275df930be7Sderaadt 	return(0);
276df930be7Sderaadt }
277df930be7Sderaadt 
278df930be7Sderaadt struct obj *
sobj_at(int n,int x,int y)2794a5fbbc4Spjanzen sobj_at(int n, int x, int y)
280df930be7Sderaadt {
2814a5fbbc4Spjanzen 	struct obj *otmp;
282df930be7Sderaadt 
283df930be7Sderaadt 	for(otmp = fobj; otmp; otmp = otmp->nobj)
284df930be7Sderaadt 		if(otmp->ox == x && otmp->oy == y && otmp->otyp == n)
285df930be7Sderaadt 			return(otmp);
286df930be7Sderaadt 	return(0);
287df930be7Sderaadt }
288df930be7Sderaadt 
2894a5fbbc4Spjanzen int
carried(struct obj * obj)2904a5fbbc4Spjanzen carried(struct obj *obj)
2914a5fbbc4Spjanzen {
2924a5fbbc4Spjanzen 	struct obj *otmp;
2934a5fbbc4Spjanzen 
294df930be7Sderaadt 	for(otmp = invent; otmp; otmp = otmp->nobj)
295df930be7Sderaadt 		if(otmp == obj) return(1);
296df930be7Sderaadt 	return(0);
297df930be7Sderaadt }
298df930be7Sderaadt 
2994a5fbbc4Spjanzen boolean
carrying(int type)3004a5fbbc4Spjanzen carrying(int type)
301df930be7Sderaadt {
3024a5fbbc4Spjanzen 	struct obj *otmp;
303df930be7Sderaadt 
304df930be7Sderaadt 	for(otmp = invent; otmp; otmp = otmp->nobj)
305df930be7Sderaadt 		if(otmp->otyp == type)
306df930be7Sderaadt 			return(TRUE);
307df930be7Sderaadt 	return(FALSE);
308df930be7Sderaadt }
309df930be7Sderaadt 
310df930be7Sderaadt struct obj *
o_on(unsigned int id,struct obj * objchn)3114a5fbbc4Spjanzen o_on(unsigned int id, struct obj *objchn)
3124a5fbbc4Spjanzen {
313df930be7Sderaadt 	while(objchn) {
314df930be7Sderaadt 		if(objchn->o_id == id) return(objchn);
315df930be7Sderaadt 		objchn = objchn->nobj;
316df930be7Sderaadt 	}
3174a5fbbc4Spjanzen 	return(NULL);
318df930be7Sderaadt }
319df930be7Sderaadt 
320df930be7Sderaadt struct trap *
t_at(int x,int y)3214a5fbbc4Spjanzen t_at(int x, int y)
322df930be7Sderaadt {
3234a5fbbc4Spjanzen 	struct trap *trap = ftrap;
3244a5fbbc4Spjanzen 
325df930be7Sderaadt 	while(trap) {
326df930be7Sderaadt 		if(trap->tx == x && trap->ty == y) return(trap);
327df930be7Sderaadt 		trap = trap->ntrap;
328df930be7Sderaadt 	}
3294a5fbbc4Spjanzen 	return(NULL);
330df930be7Sderaadt }
331df930be7Sderaadt 
332df930be7Sderaadt struct gold *
g_at(int x,int y)3334a5fbbc4Spjanzen g_at(int x, int y)
334df930be7Sderaadt {
3354a5fbbc4Spjanzen 	struct gold *gold = fgold;
3364a5fbbc4Spjanzen 
337df930be7Sderaadt 	while(gold) {
338df930be7Sderaadt 		if(gold->gx == x && gold->gy == y) return(gold);
339df930be7Sderaadt 		gold = gold->ngold;
340df930be7Sderaadt 	}
3414a5fbbc4Spjanzen 	return(NULL);
342df930be7Sderaadt }
343df930be7Sderaadt 
344df930be7Sderaadt /* make dummy object structure containing gold - for temporary use only */
345df930be7Sderaadt struct obj *
mkgoldobj(long q)3464a5fbbc4Spjanzen mkgoldobj(long q)
347df930be7Sderaadt {
3484a5fbbc4Spjanzen 	struct obj *otmp;
349df930be7Sderaadt 
350df930be7Sderaadt 	otmp = newobj(0);
351df930be7Sderaadt 	/* should set o_id etc. but otmp will be freed soon */
352df930be7Sderaadt 	otmp->olet = '$';
353df930be7Sderaadt 	u.ugold -= q;
354df930be7Sderaadt 	OGOLD(otmp) = q;
355df930be7Sderaadt 	flags.botl = 1;
356df930be7Sderaadt 	return(otmp);
357df930be7Sderaadt }
358df930be7Sderaadt 
359df930be7Sderaadt /*
360df930be7Sderaadt  * getobj returns:
361df930be7Sderaadt  *	struct obj *xxx:	object to do something with.
362df930be7Sderaadt  *	(struct obj *) 0	error return: no object.
363df930be7Sderaadt  *	&zeroobj		explicitly no object (as in w-).
364df930be7Sderaadt  */
365df930be7Sderaadt struct obj *
getobj(char * let,char * word)3664a5fbbc4Spjanzen getobj(char *let, char *word)
367df930be7Sderaadt {
3684a5fbbc4Spjanzen 	struct obj *otmp;
3694a5fbbc4Spjanzen 	char ilet,ilet1,ilet2;
370df930be7Sderaadt 	char buf[BUFSZ];
371df930be7Sderaadt 	char lets[BUFSZ];
3724a5fbbc4Spjanzen 	int foo = 0, foo2;
3734a5fbbc4Spjanzen 	char *bp = buf;
374df930be7Sderaadt 	xchar allowcnt = 0;	/* 0, 1 or 2 */
375df930be7Sderaadt 	boolean allowgold = FALSE;
376df930be7Sderaadt 	boolean allowall = FALSE;
377df930be7Sderaadt 	boolean allownone = FALSE;
378df930be7Sderaadt 	xchar foox = 0;
379df930be7Sderaadt 	long cnt;
380df930be7Sderaadt 
381df930be7Sderaadt 	if(*let == '0') let++, allowcnt = 1;
382df930be7Sderaadt 	if(*let == '$') let++, allowgold = TRUE;
383df930be7Sderaadt 	if(*let == '#') let++, allowall = TRUE;
384df930be7Sderaadt 	if(*let == '-') let++, allownone = TRUE;
385df930be7Sderaadt 	if(allownone) *bp++ = '-';
386df930be7Sderaadt 	if(allowgold) *bp++ = '$';
387df930be7Sderaadt 	if(bp > buf && bp[-1] == '-') *bp++ = ' ';
388df930be7Sderaadt 
389df930be7Sderaadt 	ilet = 'a';
390df930be7Sderaadt 	for(otmp = invent; otmp; otmp = otmp->nobj){
391180acc8fSmillert 	    if(!*let || strchr(let, otmp->olet)) {
392df930be7Sderaadt 		bp[foo++] = flags.invlet_constant ? otmp->invlet : ilet;
393df930be7Sderaadt 
394df930be7Sderaadt 		/* ugly check: remove inappropriate things */
395df930be7Sderaadt 		if((!strcmp(word, "take off") &&
396df930be7Sderaadt 		    !(otmp->owornmask & (W_ARMOR - W_ARM2)))
397df930be7Sderaadt 		|| (!strcmp(word, "wear") &&
398df930be7Sderaadt 		    (otmp->owornmask & (W_ARMOR | W_RING)))
399df930be7Sderaadt 		|| (!strcmp(word, "wield") &&
400df930be7Sderaadt 		    (otmp->owornmask & W_WEP))) {
401df930be7Sderaadt 			foo--;
402df930be7Sderaadt 			foox++;
403df930be7Sderaadt 		}
404df930be7Sderaadt 	    }
405df930be7Sderaadt 	    if(ilet == 'z') ilet = 'A'; else ilet++;
406df930be7Sderaadt 	}
407df930be7Sderaadt 	bp[foo] = 0;
408df930be7Sderaadt 	if(foo == 0 && bp > buf && bp[-1] == ' ') *--bp = 0;
40942ceebb3Sderaadt 	(void) strlcpy(lets, bp, sizeof lets);	/* necessary since we destroy buf */
410df930be7Sderaadt 	if(foo > 5) {			/* compactify string */
411df930be7Sderaadt 		foo = foo2 = 1;
412df930be7Sderaadt 		ilet2 = bp[0];
413df930be7Sderaadt 		ilet1 = bp[1];
4144a5fbbc4Spjanzen 		while ((ilet = bp[++foo2] = bp[++foo])) {
415df930be7Sderaadt 			if(ilet == ilet1+1){
416df930be7Sderaadt 				if(ilet1 == ilet2+1)
417df930be7Sderaadt 					bp[foo2 - 1] = ilet1 = '-';
418df930be7Sderaadt 				else if(ilet2 == '-') {
419df930be7Sderaadt 					bp[--foo2] = ++ilet1;
420df930be7Sderaadt 					continue;
421df930be7Sderaadt 				}
422df930be7Sderaadt 			}
423df930be7Sderaadt 			ilet2 = ilet1;
424df930be7Sderaadt 			ilet1 = ilet;
425df930be7Sderaadt 		}
426df930be7Sderaadt 	}
427df930be7Sderaadt 	if(!foo && !allowall && !allowgold && !allownone) {
428df930be7Sderaadt 		pline("You don't have anything %sto %s.",
429df930be7Sderaadt 			foox ? "else " : "", word);
430df930be7Sderaadt 		return(0);
431df930be7Sderaadt 	}
432df930be7Sderaadt 	for(;;) {
433df930be7Sderaadt 		if(!buf[0])
434df930be7Sderaadt 			pline("What do you want to %s [*]? ", word);
435df930be7Sderaadt 		else
436df930be7Sderaadt 			pline("What do you want to %s [%s or ?*]? ",
437df930be7Sderaadt 				word, buf);
438df930be7Sderaadt 
439df930be7Sderaadt 		cnt = 0;
440df930be7Sderaadt 		ilet = readchar();
441a0a49686Smmcc 		while(isdigit((unsigned char)ilet) && allowcnt) {
442df930be7Sderaadt 			if (cnt < 100000000)
443df930be7Sderaadt 			    cnt = 10*cnt + (ilet - '0');
444df930be7Sderaadt 			else
445df930be7Sderaadt 			    cnt = 999999999;
446df930be7Sderaadt 			allowcnt = 2;	/* signal presence of cnt */
447df930be7Sderaadt 			ilet = readchar();
448df930be7Sderaadt 		}
449a0a49686Smmcc 		if(isdigit((unsigned char)ilet)) {
450df930be7Sderaadt 			pline("No count allowed with this command.");
451df930be7Sderaadt 			continue;
452df930be7Sderaadt 		}
453180acc8fSmillert 		if(strchr(quitchars,ilet))
454df930be7Sderaadt 			return((struct obj *)0);
455df930be7Sderaadt 		if(ilet == '-') {
456df930be7Sderaadt 			return(allownone ? &zeroobj : (struct obj *) 0);
457df930be7Sderaadt 		}
458df930be7Sderaadt 		if(ilet == '$') {
459df930be7Sderaadt 			if(!allowgold){
460df930be7Sderaadt 				pline("You cannot %s gold.", word);
461df930be7Sderaadt 				continue;
462df930be7Sderaadt 			}
463df930be7Sderaadt 			if(!(allowcnt == 2 && cnt < u.ugold))
464df930be7Sderaadt 				cnt = u.ugold;
465df930be7Sderaadt 			return(mkgoldobj(cnt));
466df930be7Sderaadt 		}
467df930be7Sderaadt 		if(ilet == '?') {
468df930be7Sderaadt 			doinv(lets);
469df930be7Sderaadt 			if(!(ilet = morc)) continue;
470df930be7Sderaadt 			/* he typed a letter (not a space) to more() */
471df930be7Sderaadt 		} else if(ilet == '*') {
472*6acf840eSmestre 			doinv(NULL);
473df930be7Sderaadt 			if(!(ilet = morc)) continue;
474df930be7Sderaadt 			/* ... */
475df930be7Sderaadt 		}
476df930be7Sderaadt 		if(flags.invlet_constant) {
477df930be7Sderaadt 			for(otmp = invent; otmp; otmp = otmp->nobj)
478df930be7Sderaadt 				if(otmp->invlet == ilet) break;
479df930be7Sderaadt 		} else {
480df930be7Sderaadt 			if(ilet >= 'A' && ilet <= 'Z') ilet += 'z'-'A'+1;
481df930be7Sderaadt 			ilet -= 'a';
482df930be7Sderaadt 			for(otmp = invent; otmp && ilet;
483df930be7Sderaadt 					ilet--, otmp = otmp->nobj) ;
484df930be7Sderaadt 		}
485df930be7Sderaadt 		if(!otmp) {
486df930be7Sderaadt 			pline("You don't have that object.");
487df930be7Sderaadt 			continue;
488df930be7Sderaadt 		}
489df930be7Sderaadt 		if(cnt < 0 || otmp->quan < cnt) {
490df930be7Sderaadt 			pline("You don't have that many! [You have %u]"
491df930be7Sderaadt 			, otmp->quan);
492df930be7Sderaadt 			continue;
493df930be7Sderaadt 		}
494df930be7Sderaadt 		break;
495df930be7Sderaadt 	}
496180acc8fSmillert 	if(!allowall && let && !strchr(let,otmp->olet)) {
497df930be7Sderaadt 		pline("That is a silly thing to %s.",word);
498df930be7Sderaadt 		return(0);
499df930be7Sderaadt 	}
500df930be7Sderaadt 	if(allowcnt == 2) {	/* cnt given */
501df930be7Sderaadt 		if(cnt == 0) return(0);
502df930be7Sderaadt 		if(cnt != otmp->quan) {
5034a5fbbc4Spjanzen 			struct obj *obj;
504df930be7Sderaadt 			obj = splitobj(otmp, (int) cnt);
505df930be7Sderaadt 			if(otmp == uwep) setuwep(obj);
506df930be7Sderaadt 		}
507df930be7Sderaadt 	}
508df930be7Sderaadt 	return(otmp);
509df930be7Sderaadt }
510df930be7Sderaadt 
5114a5fbbc4Spjanzen int
ckunpaid(struct obj * otmp)5124a5fbbc4Spjanzen ckunpaid(struct obj *otmp)
5134a5fbbc4Spjanzen {
514df930be7Sderaadt 	return( otmp->unpaid );
515df930be7Sderaadt }
516df930be7Sderaadt 
517df930be7Sderaadt /* interactive version of getobj - used for Drop and Identify */
518df930be7Sderaadt /* return the number of times fn was called successfully */
5194a5fbbc4Spjanzen int
ggetobj(char * word,int (* fn)(struct obj *),int max)5204a5fbbc4Spjanzen ggetobj(char *word, int (*fn)(struct obj *), int max)
521df930be7Sderaadt {
522df930be7Sderaadt 	char buf[BUFSZ];
5234a5fbbc4Spjanzen 	char *ip;
5244a5fbbc4Spjanzen 	char sym;
5254a5fbbc4Spjanzen 	int oletct = 0, iletct = 0;
5264a5fbbc4Spjanzen 	boolean allflag = FALSE;
527df930be7Sderaadt 	char olets[20], ilets[20];
5284a5fbbc4Spjanzen 	int (*ckfn)(struct obj *) = NULL;
529df930be7Sderaadt 	xchar allowgold = (u.ugold && !strcmp(word, "drop")) ? 1 : 0;	/* BAH */
5304a5fbbc4Spjanzen 
531df930be7Sderaadt 	if(!invent && !allowgold){
532df930be7Sderaadt 		pline("You have nothing to %s.", word);
533df930be7Sderaadt 		return(0);
534df930be7Sderaadt 	} else {
5354a5fbbc4Spjanzen 		struct obj *otmp = invent;
5364a5fbbc4Spjanzen 		int uflg = 0;
537df930be7Sderaadt 
538df930be7Sderaadt 		if(allowgold) ilets[iletct++] = '$';
539df930be7Sderaadt 		ilets[iletct] = 0;
540df930be7Sderaadt 		while(otmp) {
541180acc8fSmillert 			if(!strchr(ilets, otmp->olet)){
542df930be7Sderaadt 				ilets[iletct++] = otmp->olet;
543df930be7Sderaadt 				ilets[iletct] = 0;
544df930be7Sderaadt 			}
545df930be7Sderaadt 			if(otmp->unpaid) uflg = 1;
546df930be7Sderaadt 			otmp = otmp->nobj;
547df930be7Sderaadt 		}
548df930be7Sderaadt 		ilets[iletct++] = ' ';
549df930be7Sderaadt 		if(uflg) ilets[iletct++] = 'u';
550df930be7Sderaadt 		if(invent) ilets[iletct++] = 'a';
551df930be7Sderaadt 		ilets[iletct] = 0;
552df930be7Sderaadt 	}
553df930be7Sderaadt 	pline("What kinds of thing do you want to %s? [%s] ",
554df930be7Sderaadt 		word, ilets);
555df930be7Sderaadt 	getlin(buf);
556df930be7Sderaadt 	if(buf[0] == '\033') {
557df930be7Sderaadt 		clrlin();
558df930be7Sderaadt 		return(0);
559df930be7Sderaadt 	}
560df930be7Sderaadt 	ip = buf;
561df930be7Sderaadt 	olets[0] = 0;
5624a5fbbc4Spjanzen 	while ((sym = *ip++)) {
5634a5fbbc4Spjanzen 		if (sym == ' ')
5644a5fbbc4Spjanzen 			continue;
565df930be7Sderaadt 		if (sym == '$') {
566df930be7Sderaadt 			if (allowgold == 1)
567df930be7Sderaadt 				(*fn)(mkgoldobj(u.ugold));
568df930be7Sderaadt 			else if (!u.ugold)
569df930be7Sderaadt 				pline("You have no gold.");
570df930be7Sderaadt 			allowgold = 2;
5714a5fbbc4Spjanzen 		} else if (sym == 'a' || sym == 'A')
5724a5fbbc4Spjanzen 			allflag = TRUE;
5734a5fbbc4Spjanzen 		else if (sym == 'u' || sym == 'U')
5744a5fbbc4Spjanzen 			ckfn = ckunpaid;
5754a5fbbc4Spjanzen 		else if (strchr("!%?[()=*/\"0", sym)) {
576180acc8fSmillert 			if (!strchr(olets, sym)) {
577df930be7Sderaadt 				olets[oletct++] = sym;
578df930be7Sderaadt 				olets[oletct] = 0;
579df930be7Sderaadt 			}
580df930be7Sderaadt 		}
581df930be7Sderaadt 		else pline("You don't have any %c's.", sym);
582df930be7Sderaadt 	}
583df930be7Sderaadt 	if (allowgold == 2 && !oletct)
584df930be7Sderaadt 		return(1);	/* he dropped gold (or at least tried to) */
585df930be7Sderaadt 	else
586df930be7Sderaadt 		return(askchain(invent, olets, allflag, fn, ckfn, max));
587df930be7Sderaadt }
588df930be7Sderaadt 
589df930be7Sderaadt /*
590df930be7Sderaadt  * Walk through the chain starting at objchn and ask for all objects
591df930be7Sderaadt  * with olet in olets (if nonNULL) and satisfying ckfn (if nonNULL)
592df930be7Sderaadt  * whether the action in question (i.e., fn) has to be performed.
593df930be7Sderaadt  * If allflag then no questions are asked. Max gives the max nr of
594df930be7Sderaadt  * objects to be treated. Return the number of objects treated.
595df930be7Sderaadt  */
5964a5fbbc4Spjanzen int
askchain(struct obj * objchn,char * olets,int allflag,int (* fn)(struct obj *),int (* ckfn)(struct obj *),int max)5974a5fbbc4Spjanzen askchain(struct obj *objchn, char *olets, int allflag, int (*fn)(struct obj *),
5984a5fbbc4Spjanzen     int (*ckfn)(struct obj *), int max)
599df930be7Sderaadt {
6004a5fbbc4Spjanzen 	struct obj *otmp, *otmp2;
6014a5fbbc4Spjanzen 	char sym, ilet;
6024a5fbbc4Spjanzen 	int cnt = 0;
6034a5fbbc4Spjanzen 
604df930be7Sderaadt 	ilet = 'a'-1;
605df930be7Sderaadt 	for(otmp = objchn; otmp; otmp = otmp2){
606df930be7Sderaadt 		if(ilet == 'z') ilet = 'A'; else ilet++;
607df930be7Sderaadt 		otmp2 = otmp->nobj;
608180acc8fSmillert 		if(olets && *olets && !strchr(olets, otmp->olet)) continue;
609df930be7Sderaadt 		if(ckfn && !(*ckfn)(otmp)) continue;
610df930be7Sderaadt 		if(!allflag) {
611911134d2Sguenther 			pline("%s", xprname(otmp, ilet));
612df930be7Sderaadt 			addtopl(" [nyaq]? ");
613df930be7Sderaadt 			sym = readchar();
614df930be7Sderaadt 		}
615df930be7Sderaadt 		else	sym = 'y';
616df930be7Sderaadt 
617df930be7Sderaadt 		switch(sym){
618df930be7Sderaadt 		case 'a':
619df930be7Sderaadt 			allflag = 1;
620df930be7Sderaadt 		case 'y':
621df930be7Sderaadt 			cnt += (*fn)(otmp);
622df930be7Sderaadt 			if(--max == 0) goto ret;
623df930be7Sderaadt 		case 'n':
624df930be7Sderaadt 		default:
625df930be7Sderaadt 			break;
626df930be7Sderaadt 		case 'q':
627df930be7Sderaadt 			goto ret;
628df930be7Sderaadt 		}
629df930be7Sderaadt 	}
630df930be7Sderaadt 	pline(cnt ? "That was all." : "No applicable objects.");
631df930be7Sderaadt ret:
632df930be7Sderaadt 	return(cnt);
633df930be7Sderaadt }
634df930be7Sderaadt 
6354a5fbbc4Spjanzen /* should of course only be called for things in invent */
6364a5fbbc4Spjanzen static char
obj_to_let(struct obj * obj)6374a5fbbc4Spjanzen obj_to_let(struct obj *obj)
638df930be7Sderaadt {
6394a5fbbc4Spjanzen 	struct obj *otmp;
6404a5fbbc4Spjanzen 	char ilet;
641df930be7Sderaadt 
642df930be7Sderaadt 	if(flags.invlet_constant)
643df930be7Sderaadt 		return(obj->invlet);
644df930be7Sderaadt 	ilet = 'a';
645df930be7Sderaadt 	for(otmp = invent; otmp && otmp != obj; otmp = otmp->nobj)
646df930be7Sderaadt 		if(++ilet > 'z') ilet = 'A';
647df930be7Sderaadt 	return(otmp ? ilet : NOINVSYM);
648df930be7Sderaadt }
649df930be7Sderaadt 
6504a5fbbc4Spjanzen void
prinv(struct obj * obj)6514a5fbbc4Spjanzen prinv(struct obj *obj)
652df930be7Sderaadt {
653911134d2Sguenther 	pline("%s", xprname(obj, obj_to_let(obj)));
654df930be7Sderaadt }
655df930be7Sderaadt 
656df930be7Sderaadt static char *
xprname(struct obj * obj,char let)6574a5fbbc4Spjanzen xprname(struct obj *obj, char let)
658df930be7Sderaadt {
659df930be7Sderaadt 	static char li[BUFSZ];
660df930be7Sderaadt 
66142ceebb3Sderaadt 	(void) snprintf(li, sizeof li, "%c - %s.",
662df930be7Sderaadt 		flags.invlet_constant ? obj->invlet : let,
663df930be7Sderaadt 		doname(obj));
664df930be7Sderaadt 	return(li);
665df930be7Sderaadt }
666df930be7Sderaadt 
6674a5fbbc4Spjanzen int
ddoinv(void)668aed906e4Smestre ddoinv(void)
669df930be7Sderaadt {
670*6acf840eSmestre 	doinv(NULL);
671df930be7Sderaadt 	return(0);
672df930be7Sderaadt }
673df930be7Sderaadt 
674df930be7Sderaadt /* called with 0 or "": all objects in inventory */
675df930be7Sderaadt /* otherwise: all objects with (serial) letter in lets */
6764a5fbbc4Spjanzen static void
doinv(char * lets)6774a5fbbc4Spjanzen doinv(char *lets)
678df930be7Sderaadt {
6794a5fbbc4Spjanzen 	struct obj *otmp;
6804a5fbbc4Spjanzen 	char ilet;
681df930be7Sderaadt 	int ct = 0;
682df930be7Sderaadt 	char any[BUFSZ];
683df930be7Sderaadt 
684df930be7Sderaadt 	morc = 0;		/* just to be sure */
685df930be7Sderaadt 
686df930be7Sderaadt 	if(!invent){
687df930be7Sderaadt 		pline("Not carrying anything.");
688df930be7Sderaadt 		return;
689df930be7Sderaadt 	}
690df930be7Sderaadt 
691*6acf840eSmestre 	cornline(0, NULL);
692df930be7Sderaadt 	ilet = 'a';
693df930be7Sderaadt 	for(otmp = invent; otmp; otmp = otmp->nobj) {
694df930be7Sderaadt 	    if(flags.invlet_constant) ilet = otmp->invlet;
695180acc8fSmillert 	    if(!lets || !*lets || strchr(lets, ilet)) {
696df930be7Sderaadt 		    cornline(1, xprname(otmp, ilet));
697df930be7Sderaadt 		    any[ct++] = ilet;
698df930be7Sderaadt 	    }
699df930be7Sderaadt 	    if(!flags.invlet_constant) if(++ilet > 'z') ilet = 'A';
700df930be7Sderaadt 	}
701df930be7Sderaadt 	any[ct] = 0;
702df930be7Sderaadt 	cornline(2, any);
703df930be7Sderaadt }
704df930be7Sderaadt 
7054a5fbbc4Spjanzen int
dotypeinv(void)706aed906e4Smestre dotypeinv(void)				/* free after Robert Viduya */
7071ccb6c7bStodd /* Changed to one type only, so he doesn't have to type cr */
708df930be7Sderaadt {
709df930be7Sderaadt     char c, ilet;
710df930be7Sderaadt     char stuff[BUFSZ];
7114a5fbbc4Spjanzen     int stct;
7124a5fbbc4Spjanzen     struct obj *otmp;
713df930be7Sderaadt     boolean billx = inshop() && doinvbill(0);
714df930be7Sderaadt     boolean unpd = FALSE;
715df930be7Sderaadt 
716df930be7Sderaadt 	if (!invent && !u.ugold && !billx) {
717df930be7Sderaadt 	    pline ("You aren't carrying anything.");
718df930be7Sderaadt 	    return(0);
719df930be7Sderaadt 	}
720df930be7Sderaadt 
721df930be7Sderaadt 	stct = 0;
722df930be7Sderaadt 	if(u.ugold) stuff[stct++] = '$';
723df930be7Sderaadt 	stuff[stct] = 0;
724df930be7Sderaadt 	for(otmp = invent; otmp; otmp = otmp->nobj) {
725180acc8fSmillert 	    if (!strchr (stuff, otmp->olet)) {
726df930be7Sderaadt 		stuff[stct++] = otmp->olet;
727df930be7Sderaadt 		stuff[stct] = 0;
728df930be7Sderaadt 	    }
729df930be7Sderaadt 	    if(otmp->unpaid)
730df930be7Sderaadt 		unpd = TRUE;
731df930be7Sderaadt 	}
732df930be7Sderaadt 	if(unpd) stuff[stct++] = 'u';
733df930be7Sderaadt 	if(billx) stuff[stct++] = 'x';
734df930be7Sderaadt 	stuff[stct] = 0;
735df930be7Sderaadt 
736df930be7Sderaadt 	if(stct > 1) {
737df930be7Sderaadt 	    pline ("What type of object [%s] do you want an inventory of? ",
738df930be7Sderaadt 		stuff);
739df930be7Sderaadt 	    c = readchar();
740180acc8fSmillert 	    if(strchr(quitchars,c)) return(0);
741df930be7Sderaadt 	} else
742df930be7Sderaadt 	    c = stuff[0];
743df930be7Sderaadt 
744df930be7Sderaadt 	if(c == '$')
745df930be7Sderaadt 	    return(doprgold());
746df930be7Sderaadt 
747df930be7Sderaadt 	if(c == 'x' || c == 'X') {
748df930be7Sderaadt 	    if(billx)
749df930be7Sderaadt 		(void) doinvbill(1);
750df930be7Sderaadt 	    else
751df930be7Sderaadt 		pline("No used-up objects on the shopping bill.");
752df930be7Sderaadt 	    return(0);
753df930be7Sderaadt 	}
754df930be7Sderaadt 
755df930be7Sderaadt 	if((c == 'u' || c == 'U') && !unpd) {
756df930be7Sderaadt 		pline("You are not carrying any unpaid objects.");
757df930be7Sderaadt 		return(0);
758df930be7Sderaadt 	}
759df930be7Sderaadt 
760df930be7Sderaadt 	stct = 0;
761df930be7Sderaadt 	ilet = 'a';
762df930be7Sderaadt 	for (otmp = invent; otmp; otmp = otmp -> nobj) {
763df930be7Sderaadt 	    if(flags.invlet_constant) ilet = otmp->invlet;
764df930be7Sderaadt 	    if (c == otmp -> olet || (c == 'u' && otmp -> unpaid))
765df930be7Sderaadt 		stuff[stct++] = ilet;
766df930be7Sderaadt 	    if(!flags.invlet_constant) if(++ilet > 'z') ilet = 'A';
767df930be7Sderaadt 	}
768df930be7Sderaadt 	stuff[stct] = '\0';
769df930be7Sderaadt 	if(stct == 0)
770df930be7Sderaadt 		pline("You have no such objects.");
771df930be7Sderaadt 	else
772df930be7Sderaadt 		doinv (stuff);
773df930be7Sderaadt 
774df930be7Sderaadt 	return(0);
775df930be7Sderaadt }
776df930be7Sderaadt 
777df930be7Sderaadt /* look at what is here */
7784a5fbbc4Spjanzen int
dolook(void)779aed906e4Smestre dolook(void)
7804a5fbbc4Spjanzen {
7814a5fbbc4Spjanzen     struct obj *otmp, *otmp0;
7824a5fbbc4Spjanzen     struct gold *gold;
783df930be7Sderaadt     char *verb = Blind ? "feel" : "see";
784df930be7Sderaadt     int	ct = 0;
785df930be7Sderaadt 
786df930be7Sderaadt     if(!u.uswallow) {
787df930be7Sderaadt 	if(Blind) {
788df930be7Sderaadt 	    pline("You try to feel what is lying here on the floor.");
789df930be7Sderaadt 	    if(Levitation) {				/* ab@unido */
790df930be7Sderaadt 		pline("You cannot reach the floor!");
791df930be7Sderaadt 		return(1);
792df930be7Sderaadt 	    }
793df930be7Sderaadt 	}
794df930be7Sderaadt 	otmp0 = o_at(u.ux, u.uy);
795df930be7Sderaadt 	gold = g_at(u.ux, u.uy);
796df930be7Sderaadt     }
797df930be7Sderaadt 
798df930be7Sderaadt     if(u.uswallow || (!otmp0 && !gold)) {
799df930be7Sderaadt 	pline("You %s no objects here.", verb);
800df930be7Sderaadt 	return(!!Blind);
801df930be7Sderaadt     }
802df930be7Sderaadt 
803df930be7Sderaadt     cornline(0, "Things that are here:");
804df930be7Sderaadt     for(otmp = otmp0; otmp; otmp = otmp->nobj) {
805df930be7Sderaadt 	if(otmp->ox == u.ux && otmp->oy == u.uy) {
806df930be7Sderaadt 	    ct++;
807df930be7Sderaadt 	    cornline(1, doname(otmp));
808df930be7Sderaadt 	    if(Blind && otmp->otyp == DEAD_COCKATRICE && !uarmg) {
809df930be7Sderaadt 		pline("Touching the dead cockatrice is a fatal mistake ...");
810df930be7Sderaadt 		pline("You die ...");
811df930be7Sderaadt 		killer = "dead cockatrice";
812df930be7Sderaadt 		done("died");
813df930be7Sderaadt 	    }
814df930be7Sderaadt 	}
815df930be7Sderaadt     }
816df930be7Sderaadt 
817df930be7Sderaadt     if(gold) {
818df930be7Sderaadt 	char gbuf[30];
819df930be7Sderaadt 
82042ceebb3Sderaadt 	(void) snprintf(gbuf, sizeof gbuf, "%ld gold piece%s",
821df930be7Sderaadt 		gold->amount, plur(gold->amount));
822df930be7Sderaadt 	if(!ct++)
823df930be7Sderaadt 	    pline("You %s here %s.", verb, gbuf);
824df930be7Sderaadt 	else
825df930be7Sderaadt 	    cornline(1, gbuf);
826df930be7Sderaadt     }
827df930be7Sderaadt 
828df930be7Sderaadt     if(ct == 1 && !gold) {
829df930be7Sderaadt 	pline("You %s here %s.", verb, doname(otmp0));
830*6acf840eSmestre 	cornline(3, NULL);
831df930be7Sderaadt     }
832df930be7Sderaadt     if(ct > 1)
833*6acf840eSmestre 	cornline(2, NULL);
834df930be7Sderaadt     return(!!Blind);
835df930be7Sderaadt }
836df930be7Sderaadt 
8374a5fbbc4Spjanzen void
stackobj(struct obj * obj)8384a5fbbc4Spjanzen stackobj(struct obj *obj)
8394a5fbbc4Spjanzen {
8404a5fbbc4Spjanzen 	struct obj *otmp = fobj;
8414a5fbbc4Spjanzen 
842df930be7Sderaadt 	for(otmp = fobj; otmp; otmp = otmp->nobj) if(otmp != obj)
843df930be7Sderaadt 	if(otmp->ox == obj->ox && otmp->oy == obj->oy &&
844df930be7Sderaadt 		merged(obj,otmp,1))
845df930be7Sderaadt 			return;
846df930be7Sderaadt }
847df930be7Sderaadt 
848df930be7Sderaadt /* merge obj with otmp and delete obj if types agree */
8494a5fbbc4Spjanzen static int
merged(struct obj * otmp,struct obj * obj,int lose)8504a5fbbc4Spjanzen merged(struct obj *otmp, struct obj *obj, int lose)
8514a5fbbc4Spjanzen {
852df930be7Sderaadt 	if(obj->otyp == otmp->otyp &&
853df930be7Sderaadt 	  obj->unpaid == otmp->unpaid &&
854df930be7Sderaadt 	  obj->spe == otmp->spe &&
855df930be7Sderaadt 	  obj->dknown == otmp->dknown &&
856df930be7Sderaadt 	  obj->cursed == otmp->cursed &&
857180acc8fSmillert 	  (strchr("%*?!", obj->olet) ||
858df930be7Sderaadt 	    (obj->known == otmp->known &&
859df930be7Sderaadt 		(obj->olet == WEAPON_SYM && obj->otyp < BOOMERANG)))) {
860df930be7Sderaadt 		otmp->quan += obj->quan;
861df930be7Sderaadt 		otmp->owt += obj->owt;
862df930be7Sderaadt 		if(lose) freeobj(obj);
863df930be7Sderaadt 		obfree(obj,otmp);	/* free(obj), bill->otmp */
864df930be7Sderaadt 		return(1);
865df930be7Sderaadt 	} else	return(0);
866df930be7Sderaadt }
867df930be7Sderaadt 
868df930be7Sderaadt /*
869df930be7Sderaadt  * Gold is no longer displayed; in fact, when you have a lot of money,
870df930be7Sderaadt  * it may take a while before you have counted it all.
871df930be7Sderaadt  * [Bug: d$ and pickup still tell you how much it was.]
872df930be7Sderaadt  */
8734a5fbbc4Spjanzen extern int (*occupation)(void);
874df930be7Sderaadt extern char *occtxt;
875df930be7Sderaadt static long goldcounted;
876df930be7Sderaadt 
8774a5fbbc4Spjanzen int
countgold(void)878aed906e4Smestre countgold(void)
8794a5fbbc4Spjanzen {
880df930be7Sderaadt 	if((goldcounted += 100*(u.ulevel + 1)) >= u.ugold) {
881df930be7Sderaadt 		long eps = 0;
882df930be7Sderaadt 		if(!rn2(2)) eps = rnd((int) (u.ugold/100 + 1));
883df930be7Sderaadt 		pline("You probably have about %ld gold pieces.",
884df930be7Sderaadt 			u.ugold + eps);
885df930be7Sderaadt 		return(0);	/* done */
886df930be7Sderaadt 	}
887df930be7Sderaadt 	return(1);		/* continue */
888df930be7Sderaadt }
889df930be7Sderaadt 
8904a5fbbc4Spjanzen int
doprgold(void)891aed906e4Smestre doprgold(void)
8924a5fbbc4Spjanzen {
893df930be7Sderaadt 	if(!u.ugold)
894df930be7Sderaadt 		pline("You do not carry any gold.");
895df930be7Sderaadt 	else if(u.ugold <= 500)
896df930be7Sderaadt 		pline("You are carrying %ld gold pieces.", u.ugold);
897df930be7Sderaadt 	else {
898df930be7Sderaadt 		pline("You sit down in order to count your gold pieces.");
899df930be7Sderaadt 		goldcounted = 500;
900df930be7Sderaadt 		occupation = countgold;
901df930be7Sderaadt 		occtxt = "counting your gold";
902df930be7Sderaadt 	}
903df930be7Sderaadt 	return(1);
904df930be7Sderaadt }
905df930be7Sderaadt 
906df930be7Sderaadt /* --- end of gold counting section --- */
907df930be7Sderaadt 
9084a5fbbc4Spjanzen int
doprwep(void)909aed906e4Smestre doprwep(void)
9104a5fbbc4Spjanzen {
911df930be7Sderaadt 	if(!uwep) pline("You are empty handed.");
912df930be7Sderaadt 	else prinv(uwep);
913df930be7Sderaadt 	return(0);
914df930be7Sderaadt }
915df930be7Sderaadt 
9164a5fbbc4Spjanzen int
doprarm(void)917aed906e4Smestre doprarm(void)
9184a5fbbc4Spjanzen {
919df930be7Sderaadt 	if(!uarm && !uarmg && !uarms && !uarmh)
920df930be7Sderaadt 		pline("You are not wearing any armor.");
921df930be7Sderaadt 	else {
922df930be7Sderaadt 		char lets[6];
9234a5fbbc4Spjanzen 		int ct = 0;
924df930be7Sderaadt 
925df930be7Sderaadt 		if(uarm) lets[ct++] = obj_to_let(uarm);
926df930be7Sderaadt 		if(uarm2) lets[ct++] = obj_to_let(uarm2);
927df930be7Sderaadt 		if(uarmh) lets[ct++] = obj_to_let(uarmh);
928df930be7Sderaadt 		if(uarms) lets[ct++] = obj_to_let(uarms);
929df930be7Sderaadt 		if(uarmg) lets[ct++] = obj_to_let(uarmg);
930df930be7Sderaadt 		lets[ct] = 0;
931df930be7Sderaadt 		doinv(lets);
932df930be7Sderaadt 	}
933df930be7Sderaadt 	return(0);
934df930be7Sderaadt }
935df930be7Sderaadt 
9364a5fbbc4Spjanzen int
doprring(void)937aed906e4Smestre doprring(void)
9384a5fbbc4Spjanzen {
939df930be7Sderaadt 	if(!uleft && !uright)
940df930be7Sderaadt 		pline("You are not wearing any rings.");
941df930be7Sderaadt 	else {
942df930be7Sderaadt 		char lets[3];
9434a5fbbc4Spjanzen 		int ct = 0;
944df930be7Sderaadt 
945df930be7Sderaadt 		if(uleft) lets[ct++] = obj_to_let(uleft);
946df930be7Sderaadt 		if(uright) lets[ct++] = obj_to_let(uright);
947df930be7Sderaadt 		lets[ct] = 0;
948df930be7Sderaadt 		doinv(lets);
949df930be7Sderaadt 	}
950df930be7Sderaadt 	return(0);
951df930be7Sderaadt }
952