1*d5b021c7Sdholland /* $NetBSD: hack.invent.c,v 1.18 2011/08/07 06:03:45 dholland Exp $ */
23ea4a95cSchristos
302ded532Smycroft /*
41c7f94e5Sjsm * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
51c7f94e5Sjsm * Amsterdam
61c7f94e5Sjsm * All rights reserved.
71c7f94e5Sjsm *
81c7f94e5Sjsm * Redistribution and use in source and binary forms, with or without
91c7f94e5Sjsm * modification, are permitted provided that the following conditions are
101c7f94e5Sjsm * met:
111c7f94e5Sjsm *
121c7f94e5Sjsm * - Redistributions of source code must retain the above copyright notice,
131c7f94e5Sjsm * this list of conditions and the following disclaimer.
141c7f94e5Sjsm *
151c7f94e5Sjsm * - Redistributions in binary form must reproduce the above copyright
161c7f94e5Sjsm * notice, this list of conditions and the following disclaimer in the
171c7f94e5Sjsm * documentation and/or other materials provided with the distribution.
181c7f94e5Sjsm *
191c7f94e5Sjsm * - Neither the name of the Stichting Centrum voor Wiskunde en
201c7f94e5Sjsm * Informatica, nor the names of its contributors may be used to endorse or
211c7f94e5Sjsm * promote products derived from this software without specific prior
221c7f94e5Sjsm * written permission.
231c7f94e5Sjsm *
241c7f94e5Sjsm * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
251c7f94e5Sjsm * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
261c7f94e5Sjsm * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
271c7f94e5Sjsm * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
281c7f94e5Sjsm * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
291c7f94e5Sjsm * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
301c7f94e5Sjsm * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
311c7f94e5Sjsm * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
321c7f94e5Sjsm * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
331c7f94e5Sjsm * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
341c7f94e5Sjsm * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
351c7f94e5Sjsm */
361c7f94e5Sjsm
371c7f94e5Sjsm /*
381c7f94e5Sjsm * Copyright (c) 1982 Jay Fenlason <hack@gnu.org>
391c7f94e5Sjsm * All rights reserved.
401c7f94e5Sjsm *
411c7f94e5Sjsm * Redistribution and use in source and binary forms, with or without
421c7f94e5Sjsm * modification, are permitted provided that the following conditions
431c7f94e5Sjsm * are met:
441c7f94e5Sjsm * 1. Redistributions of source code must retain the above copyright
451c7f94e5Sjsm * notice, this list of conditions and the following disclaimer.
461c7f94e5Sjsm * 2. Redistributions in binary form must reproduce the above copyright
471c7f94e5Sjsm * notice, this list of conditions and the following disclaimer in the
481c7f94e5Sjsm * documentation and/or other materials provided with the distribution.
491c7f94e5Sjsm * 3. The name of the author may not be used to endorse or promote products
501c7f94e5Sjsm * derived from this software without specific prior written permission.
511c7f94e5Sjsm *
521c7f94e5Sjsm * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
531c7f94e5Sjsm * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
541c7f94e5Sjsm * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
551c7f94e5Sjsm * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
561c7f94e5Sjsm * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
571c7f94e5Sjsm * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
581c7f94e5Sjsm * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
591c7f94e5Sjsm * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
601c7f94e5Sjsm * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
611c7f94e5Sjsm * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
6202ded532Smycroft */
6302ded532Smycroft
643ea4a95cSchristos #include <sys/cdefs.h>
6502ded532Smycroft #ifndef lint
66*d5b021c7Sdholland __RCSID("$NetBSD: hack.invent.c,v 1.18 2011/08/07 06:03:45 dholland Exp $");
6702ded532Smycroft #endif /* not lint */
6861f28255Scgd
69165c915bSdholland #include <assert.h>
703ea4a95cSchristos #include <stdlib.h>
7161f28255Scgd #include "hack.h"
723ea4a95cSchristos #include "extern.h"
7361f28255Scgd
7461f28255Scgd #ifndef NOWORM
7561f28255Scgd #include "def.wseg.h"
763ea4a95cSchristos #endif /* NOWORM */
7761f28255Scgd
7861f28255Scgd #define NOINVSYM '#'
7961f28255Scgd
8061f28255Scgd static int lastinvnr = 51; /* 0 ... 51 */
813ea4a95cSchristos
82cb5fd834Sjsm static char *xprname(struct obj *, char);
832c0ecb1aSdholland static void doinv(const char *);
849b92b189Sdholland static int merged(struct obj *, struct obj *, int);
853ea4a95cSchristos
863ea4a95cSchristos static void
assigninvlet(struct obj * otmp)871fa8a9a6Sdholland assigninvlet(struct obj *otmp)
8861f28255Scgd {
8961f28255Scgd boolean inuse[52];
903ea4a95cSchristos int i;
913ea4a95cSchristos struct obj *obj;
9261f28255Scgd
933ea4a95cSchristos for (i = 0; i < 52; i++)
943ea4a95cSchristos inuse[i] = FALSE;
953ea4a95cSchristos for (obj = invent; obj; obj = obj->nobj)
963ea4a95cSchristos if (obj != otmp) {
9761f28255Scgd i = obj->invlet;
983ea4a95cSchristos if ('a' <= i && i <= 'z')
993ea4a95cSchristos inuse[i - 'a'] = TRUE;
1003ea4a95cSchristos else if ('A' <= i && i <= 'Z')
1013ea4a95cSchristos inuse[i - 'A' + 26] = TRUE;
1023ea4a95cSchristos if (i == otmp->invlet)
1033ea4a95cSchristos otmp->invlet = 0;
10461f28255Scgd }
10561f28255Scgd if ((i = otmp->invlet) &&
10661f28255Scgd (('a' <= i && i <= 'z') || ('A' <= i && i <= 'Z')))
10761f28255Scgd return;
10861f28255Scgd for (i = lastinvnr + 1; i != lastinvnr; i++) {
1093ea4a95cSchristos if (i == 52) {
1103ea4a95cSchristos i = -1;
1113ea4a95cSchristos continue;
1123ea4a95cSchristos }
1133ea4a95cSchristos if (!inuse[i])
1143ea4a95cSchristos break;
11561f28255Scgd }
11661f28255Scgd otmp->invlet = (inuse[i] ? NOINVSYM :
11761f28255Scgd (i < 26) ? ('a' + i) : ('A' + i - 26));
11861f28255Scgd lastinvnr = i;
11961f28255Scgd }
12061f28255Scgd
12161f28255Scgd struct obj *
addinv(struct obj * obj)1221fa8a9a6Sdholland addinv(struct obj *obj)
12361f28255Scgd {
1243ea4a95cSchristos struct obj *otmp;
12561f28255Scgd
12661f28255Scgd /* merge or attach to end of chain */
12761f28255Scgd if (!invent) {
12861f28255Scgd invent = obj;
12961f28255Scgd otmp = 0;
13061f28255Scgd } else
13161f28255Scgd for (otmp = invent; /* otmp */ ; otmp = otmp->nobj) {
13261f28255Scgd if (merged(otmp, obj, 0))
13361f28255Scgd return (otmp);
13461f28255Scgd if (!otmp->nobj) {
13561f28255Scgd otmp->nobj = obj;
13661f28255Scgd break;
13761f28255Scgd }
13861f28255Scgd }
13961f28255Scgd obj->nobj = 0;
14061f28255Scgd
14161f28255Scgd if (flags.invlet_constant) {
14261f28255Scgd assigninvlet(obj);
14361f28255Scgd /*
14461f28255Scgd * The ordering of the chain is nowhere significant
14561f28255Scgd * so in case you prefer some other order than the
14661f28255Scgd * historical one, change the code below.
14761f28255Scgd */
14861f28255Scgd if (otmp) { /* find proper place in chain */
14961f28255Scgd otmp->nobj = 0;
15061f28255Scgd if ((invent->invlet ^ 040) > (obj->invlet ^ 040)) {
15161f28255Scgd obj->nobj = invent;
15261f28255Scgd invent = obj;
15361f28255Scgd } else
15461f28255Scgd for (otmp = invent;; otmp = otmp->nobj) {
15561f28255Scgd if (!otmp->nobj ||
15661f28255Scgd (otmp->nobj->invlet ^ 040) > (obj->invlet ^ 040)) {
15761f28255Scgd obj->nobj = otmp->nobj;
15861f28255Scgd otmp->nobj = obj;
15961f28255Scgd break;
16061f28255Scgd }
16161f28255Scgd }
16261f28255Scgd }
16361f28255Scgd }
16461f28255Scgd return (obj);
16561f28255Scgd }
16661f28255Scgd
1673ea4a95cSchristos void
useup(struct obj * obj)1681fa8a9a6Sdholland useup(struct obj *obj)
16961f28255Scgd {
17061f28255Scgd if (obj->quan > 1) {
17161f28255Scgd obj->quan--;
17261f28255Scgd obj->owt = weight(obj);
17361f28255Scgd } else {
17461f28255Scgd setnotworn(obj);
17561f28255Scgd freeinv(obj);
17661f28255Scgd obfree(obj, (struct obj *) 0);
17761f28255Scgd }
17861f28255Scgd }
17961f28255Scgd
1803ea4a95cSchristos void
freeinv(struct obj * obj)1811fa8a9a6Sdholland freeinv(struct obj *obj)
18261f28255Scgd {
1833ea4a95cSchristos struct obj *otmp;
18461f28255Scgd
18561f28255Scgd if (obj == invent)
18661f28255Scgd invent = invent->nobj;
18761f28255Scgd else {
18861f28255Scgd for (otmp = invent; otmp->nobj != obj; otmp = otmp->nobj)
1893ea4a95cSchristos if (!otmp->nobj)
1903ea4a95cSchristos panic("freeinv");
19161f28255Scgd otmp->nobj = obj->nobj;
19261f28255Scgd }
19361f28255Scgd }
19461f28255Scgd
19561f28255Scgd /* destroy object in fobj chain (if unpaid, it remains on the bill) */
1963ea4a95cSchristos void
delobj(struct obj * obj)1971fa8a9a6Sdholland delobj(struct obj *obj)
1983ea4a95cSchristos {
19961f28255Scgd freeobj(obj);
20061f28255Scgd unpobj(obj);
20161f28255Scgd obfree(obj, (struct obj *) 0);
20261f28255Scgd }
20361f28255Scgd
20461f28255Scgd /* unlink obj from chain starting with fobj */
2053ea4a95cSchristos void
freeobj(struct obj * obj)2061fa8a9a6Sdholland freeobj(struct obj *obj)
2073ea4a95cSchristos {
2083ea4a95cSchristos struct obj *otmp;
20961f28255Scgd
2103ea4a95cSchristos if (obj == fobj)
2113ea4a95cSchristos fobj = fobj->nobj;
21261f28255Scgd else {
21383f277c4Sjnemeth otmp = fobj;
21483f277c4Sjnemeth while (otmp->nobj != obj) {
21583f277c4Sjnemeth if (otmp->nobj == NULL)
2163ea4a95cSchristos panic("error in freeobj");
21783f277c4Sjnemeth otmp = otmp->nobj;
21883f277c4Sjnemeth }
21961f28255Scgd otmp->nobj = obj->nobj;
22061f28255Scgd }
22161f28255Scgd }
22261f28255Scgd
22361f28255Scgd /* Note: freegold throws away its argument! */
2243ea4a95cSchristos void
freegold(struct gold * gold)2251fa8a9a6Sdholland freegold(struct gold *gold)
2263ea4a95cSchristos {
2273ea4a95cSchristos struct gold *gtmp;
22861f28255Scgd
2293ea4a95cSchristos if (gold == fgold)
2303ea4a95cSchristos fgold = gold->ngold;
23161f28255Scgd else {
23283f277c4Sjnemeth gtmp = fgold;
23383f277c4Sjnemeth while (gtmp->ngold != gold) {
23483f277c4Sjnemeth if (gtmp->ngold == NULL)
2353ea4a95cSchristos panic("error in freegold");
23683f277c4Sjnemeth gtmp = gtmp->ngold;
23783f277c4Sjnemeth }
23861f28255Scgd gtmp->ngold = gold->ngold;
23961f28255Scgd }
2408e73b3adSdholland free(gold);
24161f28255Scgd }
24261f28255Scgd
2433ea4a95cSchristos void
deltrap(struct trap * trap)2441fa8a9a6Sdholland deltrap(struct trap *trap)
24561f28255Scgd {
2463ea4a95cSchristos struct trap *ttmp;
24761f28255Scgd
24861f28255Scgd if (trap == ftrap)
24961f28255Scgd ftrap = ftrap->ntrap;
25061f28255Scgd else {
25161f28255Scgd for (ttmp = ftrap; ttmp->ntrap != trap; ttmp = ttmp->ntrap);
25261f28255Scgd ttmp->ntrap = trap->ntrap;
25361f28255Scgd }
2548e73b3adSdholland free(trap);
25561f28255Scgd }
25661f28255Scgd
25761f28255Scgd struct wseg *m_atseg;
25861f28255Scgd
25961f28255Scgd struct monst *
m_at(int x,int y)2601fa8a9a6Sdholland m_at(int x, int y)
26161f28255Scgd {
2623ea4a95cSchristos struct monst *mtmp;
26361f28255Scgd #ifndef NOWORM
2643ea4a95cSchristos struct wseg *wtmp;
2653ea4a95cSchristos #endif /* NOWORM */
26661f28255Scgd
26761f28255Scgd m_atseg = 0;
26861f28255Scgd for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
26961f28255Scgd if (mtmp->mx == x && mtmp->my == y)
27061f28255Scgd return (mtmp);
27161f28255Scgd #ifndef NOWORM
27261f28255Scgd if (mtmp->wormno) {
27361f28255Scgd for (wtmp = wsegs[mtmp->wormno]; wtmp; wtmp = wtmp->nseg)
27461f28255Scgd if (wtmp->wx == x && wtmp->wy == y) {
27561f28255Scgd m_atseg = wtmp;
27661f28255Scgd return (mtmp);
27761f28255Scgd }
27861f28255Scgd }
2793ea4a95cSchristos #endif /* NOWORM */
28061f28255Scgd }
28161f28255Scgd return (0);
28261f28255Scgd }
28361f28255Scgd
28461f28255Scgd struct obj *
o_at(int x,int y)2851fa8a9a6Sdholland o_at(int x, int y)
28661f28255Scgd {
2873ea4a95cSchristos struct obj *otmp;
28861f28255Scgd
28961f28255Scgd for (otmp = fobj; otmp; otmp = otmp->nobj)
2903ea4a95cSchristos if (otmp->ox == x && otmp->oy == y)
2913ea4a95cSchristos return (otmp);
29261f28255Scgd return (0);
29361f28255Scgd }
29461f28255Scgd
29561f28255Scgd struct obj *
sobj_at(int n,int x,int y)2961fa8a9a6Sdholland sobj_at(int n, int x, int y)
29761f28255Scgd {
2983ea4a95cSchristos struct obj *otmp;
29961f28255Scgd
30061f28255Scgd for (otmp = fobj; otmp; otmp = otmp->nobj)
30161f28255Scgd if (otmp->ox == x && otmp->oy == y && otmp->otyp == n)
30261f28255Scgd return (otmp);
30361f28255Scgd return (0);
30461f28255Scgd }
30561f28255Scgd
3063ea4a95cSchristos int
carried(struct obj * obj)3071fa8a9a6Sdholland carried(struct obj *obj)
3083ea4a95cSchristos {
3093ea4a95cSchristos struct obj *otmp;
31061f28255Scgd for (otmp = invent; otmp; otmp = otmp->nobj)
3113ea4a95cSchristos if (otmp == obj)
3123ea4a95cSchristos return (1);
31361f28255Scgd return (0);
31461f28255Scgd }
31561f28255Scgd
3163ea4a95cSchristos int
carrying(int type)3171fa8a9a6Sdholland carrying(int type)
31861f28255Scgd {
3193ea4a95cSchristos struct obj *otmp;
32061f28255Scgd
32161f28255Scgd for (otmp = invent; otmp; otmp = otmp->nobj)
32261f28255Scgd if (otmp->otyp == type)
32361f28255Scgd return (TRUE);
32461f28255Scgd return (FALSE);
32561f28255Scgd }
32661f28255Scgd
32761f28255Scgd struct obj *
o_on(unsigned int id,struct obj * objchn)3281fa8a9a6Sdholland o_on(unsigned int id, struct obj *objchn)
3293ea4a95cSchristos {
33061f28255Scgd while (objchn) {
3313ea4a95cSchristos if (objchn->o_id == id)
3323ea4a95cSchristos return (objchn);
33361f28255Scgd objchn = objchn->nobj;
33461f28255Scgd }
33561f28255Scgd return ((struct obj *) 0);
33661f28255Scgd }
33761f28255Scgd
33861f28255Scgd struct trap *
t_at(int x,int y)3391fa8a9a6Sdholland t_at(int x, int y)
34061f28255Scgd {
3413ea4a95cSchristos struct trap *trap = ftrap;
34261f28255Scgd while (trap) {
3433ea4a95cSchristos if (trap->tx == x && trap->ty == y)
3443ea4a95cSchristos return (trap);
34561f28255Scgd trap = trap->ntrap;
34661f28255Scgd }
34761f28255Scgd return (0);
34861f28255Scgd }
34961f28255Scgd
35061f28255Scgd struct gold *
g_at(int x,int y)3511fa8a9a6Sdholland g_at(int x, int y)
35261f28255Scgd {
3533ea4a95cSchristos struct gold *gold = fgold;
35461f28255Scgd while (gold) {
3553ea4a95cSchristos if (gold->gx == x && gold->gy == y)
3563ea4a95cSchristos return (gold);
35761f28255Scgd gold = gold->ngold;
35861f28255Scgd }
35961f28255Scgd return (0);
36061f28255Scgd }
36161f28255Scgd
36261f28255Scgd /* make dummy object structure containing gold - for temporary use only */
3639b92b189Sdholland static struct obj *
mkgoldobj(long q)3641fa8a9a6Sdholland mkgoldobj(long q)
36561f28255Scgd {
3663ea4a95cSchristos struct obj *otmp;
36761f28255Scgd
36861f28255Scgd otmp = newobj(0);
36961f28255Scgd /* should set o_id etc. but otmp will be freed soon */
37061f28255Scgd otmp->olet = '$';
37161f28255Scgd u.ugold -= q;
37261f28255Scgd OGOLD(otmp) = q;
37361f28255Scgd flags.botl = 1;
37461f28255Scgd return (otmp);
37561f28255Scgd }
37661f28255Scgd
37761f28255Scgd /*
37861f28255Scgd * getobj returns:
37961f28255Scgd * struct obj *xxx: object to do something with.
38061f28255Scgd * (struct obj *) 0 error return: no object.
38161f28255Scgd * &zeroobj explicitly no object (as in w-).
38261f28255Scgd */
38361f28255Scgd struct obj *
getobj(const char * let,const char * word)3841fa8a9a6Sdholland getobj(const char *let, const char *word)
38561f28255Scgd {
3863ea4a95cSchristos struct obj *otmp;
3873ea4a95cSchristos char ilet, ilet1, ilet2;
38861f28255Scgd char buf[BUFSZ];
38961f28255Scgd char lets[BUFSZ];
3903ea4a95cSchristos int foo = 0, foo2;
3913ea4a95cSchristos char *bp = buf;
39261f28255Scgd xchar allowcnt = 0; /* 0, 1 or 2 */
39361f28255Scgd boolean allowgold = FALSE;
39461f28255Scgd boolean allowall = FALSE;
39561f28255Scgd boolean allownone = FALSE;
39661f28255Scgd xchar foox = 0;
39761f28255Scgd long cnt;
39861f28255Scgd
3993ea4a95cSchristos if (*let == '0')
4003ea4a95cSchristos let++, allowcnt = 1;
4013ea4a95cSchristos if (*let == '$')
4023ea4a95cSchristos let++, allowgold = TRUE;
4033ea4a95cSchristos if (*let == '#')
4043ea4a95cSchristos let++, allowall = TRUE;
4053ea4a95cSchristos if (*let == '-')
4063ea4a95cSchristos let++, allownone = TRUE;
4073ea4a95cSchristos if (allownone)
4083ea4a95cSchristos *bp++ = '-';
4093ea4a95cSchristos if (allowgold)
4103ea4a95cSchristos *bp++ = '$';
4113ea4a95cSchristos if (bp > buf && bp[-1] == '-')
4123ea4a95cSchristos *bp++ = ' ';
41361f28255Scgd
41461f28255Scgd ilet = 'a';
41561f28255Scgd for (otmp = invent; otmp; otmp = otmp->nobj) {
4163ea4a95cSchristos if (!*let || strchr(let, otmp->olet)) {
41761f28255Scgd bp[foo++] = flags.invlet_constant ? otmp->invlet : ilet;
41861f28255Scgd
41961f28255Scgd /* ugly check: remove inappropriate things */
42061f28255Scgd if ((!strcmp(word, "take off") &&
42161f28255Scgd !(otmp->owornmask & (W_ARMOR - W_ARM2)))
42261f28255Scgd || (!strcmp(word, "wear") &&
42361f28255Scgd (otmp->owornmask & (W_ARMOR | W_RING)))
42461f28255Scgd || (!strcmp(word, "wield") &&
42561f28255Scgd (otmp->owornmask & W_WEP))) {
42661f28255Scgd foo--;
42761f28255Scgd foox++;
42861f28255Scgd }
42961f28255Scgd }
4303ea4a95cSchristos if (ilet == 'z')
4313ea4a95cSchristos ilet = 'A';
4323ea4a95cSchristos else
4333ea4a95cSchristos ilet++;
43461f28255Scgd }
43561f28255Scgd bp[foo] = 0;
4363ea4a95cSchristos if (foo == 0 && bp > buf && bp[-1] == ' ')
4373ea4a95cSchristos *--bp = 0;
43861f28255Scgd (void) strcpy(lets, bp);/* necessary since we destroy buf */
43961f28255Scgd if (foo > 5) { /* compactify string */
44061f28255Scgd foo = foo2 = 1;
44161f28255Scgd ilet2 = bp[0];
44261f28255Scgd ilet1 = bp[1];
4433ea4a95cSchristos while ((ilet = bp[++foo2] = bp[++foo]) != '\0') {
44461f28255Scgd if (ilet == ilet1 + 1) {
44561f28255Scgd if (ilet1 == ilet2 + 1)
44661f28255Scgd bp[foo2 - 1] = ilet1 = '-';
44761f28255Scgd else if (ilet2 == '-') {
44861f28255Scgd bp[--foo2] = ++ilet1;
44961f28255Scgd continue;
45061f28255Scgd }
45161f28255Scgd }
45261f28255Scgd ilet2 = ilet1;
45361f28255Scgd ilet1 = ilet;
45461f28255Scgd }
45561f28255Scgd }
45661f28255Scgd if (!foo && !allowall && !allowgold && !allownone) {
45761f28255Scgd pline("You don't have anything %sto %s.",
45861f28255Scgd foox ? "else " : "", word);
45961f28255Scgd return (0);
46061f28255Scgd }
46161f28255Scgd for (;;) {
46261f28255Scgd if (!buf[0])
46361f28255Scgd pline("What do you want to %s [*]? ", word);
46461f28255Scgd else
46561f28255Scgd pline("What do you want to %s [%s or ?*]? ",
46661f28255Scgd word, buf);
46761f28255Scgd
46861f28255Scgd cnt = 0;
46961f28255Scgd ilet = readchar();
47061f28255Scgd while (digit(ilet) && allowcnt) {
47161f28255Scgd if (cnt < 100000000)
47261f28255Scgd cnt = 10 * cnt + (ilet - '0');
47361f28255Scgd else
47461f28255Scgd cnt = 999999999;
47561f28255Scgd allowcnt = 2; /* signal presence of cnt */
47661f28255Scgd ilet = readchar();
47761f28255Scgd }
47861f28255Scgd if (digit(ilet)) {
47961f28255Scgd pline("No count allowed with this command.");
48061f28255Scgd continue;
48161f28255Scgd }
4823ea4a95cSchristos if (strchr(quitchars, ilet))
48361f28255Scgd return ((struct obj *) 0);
48461f28255Scgd if (ilet == '-') {
48561f28255Scgd return (allownone ? &zeroobj : (struct obj *) 0);
48661f28255Scgd }
48761f28255Scgd if (ilet == '$') {
48861f28255Scgd if (!allowgold) {
48961f28255Scgd pline("You cannot %s gold.", word);
49061f28255Scgd continue;
49161f28255Scgd }
49261f28255Scgd if (!(allowcnt == 2 && cnt < u.ugold))
49361f28255Scgd cnt = u.ugold;
49461f28255Scgd return (mkgoldobj(cnt));
49561f28255Scgd }
49661f28255Scgd if (ilet == '?') {
49761f28255Scgd doinv(lets);
4983ea4a95cSchristos if (!(ilet = morc))
4993ea4a95cSchristos continue;
50061f28255Scgd /* he typed a letter (not a space) to more() */
50161f28255Scgd } else if (ilet == '*') {
5022c0ecb1aSdholland doinv(NULL);
5033ea4a95cSchristos if (!(ilet = morc))
5043ea4a95cSchristos continue;
50561f28255Scgd /* ... */
50661f28255Scgd }
50761f28255Scgd if (flags.invlet_constant) {
50861f28255Scgd for (otmp = invent; otmp; otmp = otmp->nobj)
5093ea4a95cSchristos if (otmp->invlet == ilet)
5103ea4a95cSchristos break;
51161f28255Scgd } else {
5123ea4a95cSchristos if (ilet >= 'A' && ilet <= 'Z')
5133ea4a95cSchristos ilet += 'z' - 'A' + 1;
51461f28255Scgd ilet -= 'a';
51561f28255Scgd for (otmp = invent; otmp && ilet;
51661f28255Scgd ilet--, otmp = otmp->nobj);
51761f28255Scgd }
51861f28255Scgd if (!otmp) {
51961f28255Scgd pline("You don't have that object.");
52061f28255Scgd continue;
52161f28255Scgd }
52261f28255Scgd if (cnt < 0 || otmp->quan < cnt) {
52361f28255Scgd pline("You don't have that many! [You have %u]"
52461f28255Scgd ,otmp->quan);
52561f28255Scgd continue;
52661f28255Scgd }
52761f28255Scgd break;
52861f28255Scgd }
5293ea4a95cSchristos if (!allowall && let && !strchr(let, otmp->olet)) {
53061f28255Scgd pline("That is a silly thing to %s.", word);
53161f28255Scgd return (0);
53261f28255Scgd }
53361f28255Scgd if (allowcnt == 2) { /* cnt given */
5343ea4a95cSchristos if (cnt == 0)
5353ea4a95cSchristos return (0);
53661f28255Scgd if (cnt != otmp->quan) {
5373ea4a95cSchristos struct obj *obj;
53861f28255Scgd obj = splitobj(otmp, (int) cnt);
5393ea4a95cSchristos if (otmp == uwep)
5403ea4a95cSchristos setuwep(obj);
54161f28255Scgd }
54261f28255Scgd }
54361f28255Scgd return (otmp);
54461f28255Scgd }
54561f28255Scgd
5469b92b189Sdholland static int
ckunpaid(struct obj * otmp)5471fa8a9a6Sdholland ckunpaid(struct obj *otmp)
5483ea4a95cSchristos {
54961f28255Scgd return (otmp->unpaid);
55061f28255Scgd }
55161f28255Scgd
55261f28255Scgd /* interactive version of getobj - used for Drop and Identify */
55361f28255Scgd /* return the number of times fn was called successfully */
5543ea4a95cSchristos int
ggetobj(const char * word,int (* fn)(struct obj *),int max)5551fa8a9a6Sdholland ggetobj(const char *word, int (*fn)(struct obj *), int max)
55661f28255Scgd {
55761f28255Scgd char buf[BUFSZ];
5583ea4a95cSchristos char *ip;
5593ea4a95cSchristos char sym;
560165c915bSdholland unsigned oletct = 0, iletct = 0;
5613ea4a95cSchristos boolean allflag = FALSE;
56261f28255Scgd char olets[20], ilets[20];
563cb5fd834Sjsm int (*ckfn)(struct obj *) =
564cb5fd834Sjsm (int (*)(struct obj *)) 0;
56561f28255Scgd xchar allowgold = (u.ugold && !strcmp(word, "drop")) ? 1 : 0; /* BAH */
56661f28255Scgd if (!invent && !allowgold) {
56761f28255Scgd pline("You have nothing to %s.", word);
56861f28255Scgd return (0);
56961f28255Scgd } else {
5703ea4a95cSchristos struct obj *otmp = invent;
5713ea4a95cSchristos int uflg = 0;
57261f28255Scgd
5733ea4a95cSchristos if (allowgold)
5743ea4a95cSchristos ilets[iletct++] = '$';
57561f28255Scgd ilets[iletct] = 0;
57661f28255Scgd while (otmp) {
5773ea4a95cSchristos if (!strchr(ilets, otmp->olet)) {
57861f28255Scgd ilets[iletct++] = otmp->olet;
57961f28255Scgd ilets[iletct] = 0;
58061f28255Scgd }
5813ea4a95cSchristos if (otmp->unpaid)
5823ea4a95cSchristos uflg = 1;
58361f28255Scgd otmp = otmp->nobj;
58461f28255Scgd }
58561f28255Scgd ilets[iletct++] = ' ';
5863ea4a95cSchristos if (uflg)
5873ea4a95cSchristos ilets[iletct++] = 'u';
5883ea4a95cSchristos if (invent)
5893ea4a95cSchristos ilets[iletct++] = 'a';
59061f28255Scgd ilets[iletct] = 0;
591165c915bSdholland assert(iletct < sizeof(ilets));
59261f28255Scgd }
59361f28255Scgd pline("What kinds of thing do you want to %s? [%s] ",
59461f28255Scgd word, ilets);
59561f28255Scgd getlin(buf);
59661f28255Scgd if (buf[0] == '\033') {
59761f28255Scgd clrlin();
59861f28255Scgd return (0);
59961f28255Scgd }
60061f28255Scgd ip = buf;
60161f28255Scgd olets[0] = 0;
6023ea4a95cSchristos while ((sym = *ip++) != '\0') {
6033ea4a95cSchristos if (sym == ' ')
6043ea4a95cSchristos continue;
60561f28255Scgd if (sym == '$') {
60661f28255Scgd if (allowgold == 1)
60761f28255Scgd (*fn) (mkgoldobj(u.ugold));
60861f28255Scgd else if (!u.ugold)
60961f28255Scgd pline("You have no gold.");
61061f28255Scgd allowgold = 2;
6113ea4a95cSchristos } else if (sym == 'a' || sym == 'A')
6123ea4a95cSchristos allflag = TRUE;
6133ea4a95cSchristos else if (sym == 'u' || sym == 'U')
6143ea4a95cSchristos ckfn = ckunpaid;
6153ea4a95cSchristos else if (strchr("!%?[()=*/\"0", sym)) {
6163ea4a95cSchristos if (!strchr(olets, sym)) {
61761f28255Scgd olets[oletct++] = sym;
61861f28255Scgd olets[oletct] = 0;
61961f28255Scgd }
620165c915bSdholland assert(oletct < sizeof(olets));
6213ea4a95cSchristos } else
6223ea4a95cSchristos pline("You don't have any %c's.", sym);
62361f28255Scgd }
62461f28255Scgd if (allowgold == 2 && !oletct)
62561f28255Scgd return (1); /* he dropped gold (or at least tried to) */
62661f28255Scgd else
62761f28255Scgd return (askchain(invent, olets, allflag, fn, ckfn, max));
62861f28255Scgd }
62961f28255Scgd
63061f28255Scgd /*
63161f28255Scgd * Walk through the chain starting at objchn and ask for all objects
63261f28255Scgd * with olet in olets (if nonNULL) and satisfying ckfn (if nonNULL)
63361f28255Scgd * whether the action in question (i.e., fn) has to be performed.
63461f28255Scgd * If allflag then no questions are asked. Max gives the max nr of
63561f28255Scgd * objects to be treated. Return the number of objects treated.
63661f28255Scgd */
6373ea4a95cSchristos int
askchain(struct obj * objchn,char * olets,int allflag,int (* fn)(struct obj *),int (* ckfn)(struct obj *),int max)6381fa8a9a6Sdholland askchain(struct obj *objchn, char *olets, int allflag,
6391fa8a9a6Sdholland int (*fn)(struct obj *),
6401fa8a9a6Sdholland int (*ckfn)(struct obj *),
6411fa8a9a6Sdholland int max)
64261f28255Scgd {
6433ea4a95cSchristos struct obj *otmp, *otmp2;
6443ea4a95cSchristos char sym, ilet;
6453ea4a95cSchristos int cnt = 0;
64661f28255Scgd ilet = 'a' - 1;
64761f28255Scgd for (otmp = objchn; otmp; otmp = otmp2) {
6483ea4a95cSchristos if (ilet == 'z')
6493ea4a95cSchristos ilet = 'A';
6503ea4a95cSchristos else
6513ea4a95cSchristos ilet++;
65261f28255Scgd otmp2 = otmp->nobj;
6533ea4a95cSchristos if (olets && *olets && !strchr(olets, otmp->olet))
6543ea4a95cSchristos continue;
6553ea4a95cSchristos if (ckfn && !(*ckfn) (otmp))
6563ea4a95cSchristos continue;
65761f28255Scgd if (!allflag) {
65857c13365Sjoerg pline("%s", xprname(otmp, ilet));
65961f28255Scgd addtopl(" [nyaq]? ");
66061f28255Scgd sym = readchar();
6613ea4a95cSchristos } else
6623ea4a95cSchristos sym = 'y';
66361f28255Scgd
66461f28255Scgd switch (sym) {
66561f28255Scgd case 'a':
66661f28255Scgd allflag = 1;
667*d5b021c7Sdholland /* FALLTHROUGH */
66861f28255Scgd case 'y':
66961f28255Scgd cnt += (*fn) (otmp);
6703ea4a95cSchristos if (--max == 0)
6713ea4a95cSchristos goto ret;
672*d5b021c7Sdholland break;
67361f28255Scgd case 'n':
67461f28255Scgd default:
67561f28255Scgd break;
67661f28255Scgd case 'q':
67761f28255Scgd goto ret;
67861f28255Scgd }
67961f28255Scgd }
68061f28255Scgd pline(cnt ? "That was all." : "No applicable objects.");
68161f28255Scgd ret:
68261f28255Scgd return (cnt);
68361f28255Scgd }
68461f28255Scgd
6851fa8a9a6Sdholland /* should of course only be called for things in invent */
6869b92b189Sdholland static char
obj_to_let(struct obj * obj)6871fa8a9a6Sdholland obj_to_let(struct obj *obj)
68861f28255Scgd {
6893ea4a95cSchristos struct obj *otmp;
6903ea4a95cSchristos char ilet;
69161f28255Scgd
69261f28255Scgd if (flags.invlet_constant)
69361f28255Scgd return (obj->invlet);
69461f28255Scgd ilet = 'a';
69561f28255Scgd for (otmp = invent; otmp && otmp != obj; otmp = otmp->nobj)
6963ea4a95cSchristos if (++ilet > 'z')
6973ea4a95cSchristos ilet = 'A';
69861f28255Scgd return (otmp ? ilet : NOINVSYM);
69961f28255Scgd }
70061f28255Scgd
7013ea4a95cSchristos void
prinv(struct obj * obj)7021fa8a9a6Sdholland prinv(struct obj *obj)
70361f28255Scgd {
70457c13365Sjoerg pline("%s", xprname(obj, obj_to_let(obj)));
70561f28255Scgd }
70661f28255Scgd
70761f28255Scgd static char *
xprname(struct obj * obj,char let)7081fa8a9a6Sdholland xprname(struct obj *obj, char let)
70961f28255Scgd {
71061f28255Scgd static char li[BUFSZ];
71161f28255Scgd
712907fca1bSdholland (void) snprintf(li, sizeof(li), "%c - %s.",
71361f28255Scgd flags.invlet_constant ? obj->invlet : let,
71461f28255Scgd doname(obj));
71561f28255Scgd return (li);
71661f28255Scgd }
71761f28255Scgd
7183ea4a95cSchristos int
ddoinv(void)7191fa8a9a6Sdholland ddoinv(void)
72061f28255Scgd {
7212c0ecb1aSdholland doinv(NULL);
72261f28255Scgd return (0);
72361f28255Scgd }
72461f28255Scgd
72561f28255Scgd /* called with 0 or "": all objects in inventory */
72661f28255Scgd /* otherwise: all objects with (serial) letter in lets */
7279b92b189Sdholland static void
doinv(const char * lets)7282c0ecb1aSdholland doinv(const char *lets)
72961f28255Scgd {
7303ea4a95cSchristos struct obj *otmp;
7313ea4a95cSchristos char ilet;
732165c915bSdholland unsigned ct = 0;
73361f28255Scgd char any[BUFSZ];
73461f28255Scgd
73561f28255Scgd morc = 0; /* just to be sure */
73661f28255Scgd
73761f28255Scgd if (!invent) {
73861f28255Scgd pline("Not carrying anything.");
73961f28255Scgd return;
74061f28255Scgd }
7412c0ecb1aSdholland cornline(0, NULL);
74261f28255Scgd ilet = 'a';
74361f28255Scgd for (otmp = invent; otmp; otmp = otmp->nobj) {
7443ea4a95cSchristos if (flags.invlet_constant)
7453ea4a95cSchristos ilet = otmp->invlet;
7463ea4a95cSchristos if (!lets || !*lets || strchr(lets, ilet)) {
74761f28255Scgd cornline(1, xprname(otmp, ilet));
74861f28255Scgd any[ct++] = ilet;
74961f28255Scgd }
7503ea4a95cSchristos if (!flags.invlet_constant)
7513ea4a95cSchristos if (++ilet > 'z')
7523ea4a95cSchristos ilet = 'A';
75361f28255Scgd }
75461f28255Scgd any[ct] = 0;
755165c915bSdholland assert(ct < sizeof(any));
75661f28255Scgd cornline(2, any);
75761f28255Scgd }
75861f28255Scgd
7593ea4a95cSchristos int
dotypeinv(void)7601fa8a9a6Sdholland dotypeinv(void)
7613ea4a95cSchristos { /* free after Robert Viduya */
76261f28255Scgd /* Changed to one type only, so he doesnt have to type cr */
76361f28255Scgd char c, ilet;
76461f28255Scgd char stuff[BUFSZ];
765165c915bSdholland unsigned stct;
7663ea4a95cSchristos struct obj *otmp;
76761f28255Scgd boolean billx = inshop() && doinvbill(0);
76861f28255Scgd boolean unpd = FALSE;
76961f28255Scgd
77061f28255Scgd if (!invent && !u.ugold && !billx) {
77161f28255Scgd pline("You aren't carrying anything.");
77261f28255Scgd return (0);
77361f28255Scgd }
77461f28255Scgd stct = 0;
7753ea4a95cSchristos if (u.ugold)
7763ea4a95cSchristos stuff[stct++] = '$';
77761f28255Scgd stuff[stct] = 0;
77861f28255Scgd for (otmp = invent; otmp; otmp = otmp->nobj) {
7793ea4a95cSchristos if (!strchr(stuff, otmp->olet)) {
78061f28255Scgd stuff[stct++] = otmp->olet;
78161f28255Scgd stuff[stct] = 0;
78261f28255Scgd }
78361f28255Scgd if (otmp->unpaid)
78461f28255Scgd unpd = TRUE;
78561f28255Scgd }
7863ea4a95cSchristos if (unpd)
7873ea4a95cSchristos stuff[stct++] = 'u';
7883ea4a95cSchristos if (billx)
7893ea4a95cSchristos stuff[stct++] = 'x';
79061f28255Scgd stuff[stct] = 0;
791165c915bSdholland assert(stct < sizeof(stuff));
79261f28255Scgd
79361f28255Scgd if (stct > 1) {
79461f28255Scgd pline("What type of object [%s] do you want an inventory of? ",
79561f28255Scgd stuff);
79661f28255Scgd c = readchar();
7973ea4a95cSchristos if (strchr(quitchars, c))
7983ea4a95cSchristos return (0);
79961f28255Scgd } else
80061f28255Scgd c = stuff[0];
80161f28255Scgd
80261f28255Scgd if (c == '$')
80361f28255Scgd return (doprgold());
80461f28255Scgd
80561f28255Scgd if (c == 'x' || c == 'X') {
80661f28255Scgd if (billx)
80761f28255Scgd (void) doinvbill(1);
80861f28255Scgd else
80961f28255Scgd pline("No used-up objects on the shopping bill.");
81061f28255Scgd return (0);
81161f28255Scgd }
81261f28255Scgd if ((c == 'u' || c == 'U') && !unpd) {
81361f28255Scgd pline("You are not carrying any unpaid objects.");
81461f28255Scgd return (0);
81561f28255Scgd }
81661f28255Scgd stct = 0;
81761f28255Scgd ilet = 'a';
81861f28255Scgd for (otmp = invent; otmp; otmp = otmp->nobj) {
8193ea4a95cSchristos if (flags.invlet_constant)
8203ea4a95cSchristos ilet = otmp->invlet;
82161f28255Scgd if (c == otmp->olet || (c == 'u' && otmp->unpaid))
82261f28255Scgd stuff[stct++] = ilet;
8233ea4a95cSchristos if (!flags.invlet_constant)
8243ea4a95cSchristos if (++ilet > 'z')
8253ea4a95cSchristos ilet = 'A';
82661f28255Scgd }
82761f28255Scgd stuff[stct] = '\0';
828165c915bSdholland assert(stct < sizeof(stuff));
829165c915bSdholland
83061f28255Scgd if (stct == 0)
83161f28255Scgd pline("You have no such objects.");
83261f28255Scgd else
83361f28255Scgd doinv(stuff);
83461f28255Scgd
83561f28255Scgd return (0);
83661f28255Scgd }
83761f28255Scgd
83861f28255Scgd /* look at what is here */
8393ea4a95cSchristos int
dolook(void)8401fa8a9a6Sdholland dolook(void)
8413ea4a95cSchristos {
8423aa9af7cSfair struct obj *otmp = NULL, *otmp0 = NULL;
8433aa9af7cSfair struct gold *gold = NULL;
844ab8b6343Sjsm const char *verb = Blind ? "feel" : "see";
84561f28255Scgd int ct = 0;
84661f28255Scgd
84761f28255Scgd if (!u.uswallow) {
84861f28255Scgd if (Blind) {
84961f28255Scgd pline("You try to feel what is lying here on the floor.");
85061f28255Scgd if (Levitation) { /* ab@unido */
85161f28255Scgd pline("You cannot reach the floor!");
85261f28255Scgd return (1);
85361f28255Scgd }
85461f28255Scgd }
85561f28255Scgd otmp0 = o_at(u.ux, u.uy);
85661f28255Scgd gold = g_at(u.ux, u.uy);
85761f28255Scgd }
85861f28255Scgd if (u.uswallow || (!otmp0 && !gold)) {
85961f28255Scgd pline("You %s no objects here.", verb);
86061f28255Scgd return (!!Blind);
86161f28255Scgd }
86261f28255Scgd cornline(0, "Things that are here:");
86361f28255Scgd for (otmp = otmp0; otmp; otmp = otmp->nobj) {
86461f28255Scgd if (otmp->ox == u.ux && otmp->oy == u.uy) {
86561f28255Scgd ct++;
86661f28255Scgd cornline(1, doname(otmp));
86761f28255Scgd if (Blind && otmp->otyp == DEAD_COCKATRICE && !uarmg) {
86861f28255Scgd pline("Touching the dead cockatrice is a fatal mistake ...");
86961f28255Scgd pline("You die ...");
87061f28255Scgd killer = "dead cockatrice";
87161f28255Scgd done("died");
87261f28255Scgd }
87361f28255Scgd }
87461f28255Scgd }
87561f28255Scgd
87661f28255Scgd if (gold) {
87761f28255Scgd char gbuf[30];
87861f28255Scgd
879907fca1bSdholland (void) snprintf(gbuf, sizeof(gbuf), "%ld gold piece%s",
88061f28255Scgd gold->amount, plur(gold->amount));
88161f28255Scgd if (!ct++)
88261f28255Scgd pline("You %s here %s.", verb, gbuf);
88361f28255Scgd else
88461f28255Scgd cornline(1, gbuf);
88561f28255Scgd }
88661f28255Scgd if (ct == 1 && !gold) {
88761f28255Scgd pline("You %s here %s.", verb, doname(otmp0));
8882c0ecb1aSdholland cornline(3, NULL);
88961f28255Scgd }
89061f28255Scgd if (ct > 1)
8912c0ecb1aSdholland cornline(2, NULL);
89261f28255Scgd return (!!Blind);
89361f28255Scgd }
89461f28255Scgd
8953ea4a95cSchristos void
stackobj(struct obj * obj)8961fa8a9a6Sdholland stackobj(struct obj *obj)
8973ea4a95cSchristos {
8983ea4a95cSchristos struct obj *otmp = fobj;
8993ea4a95cSchristos for (otmp = fobj; otmp; otmp = otmp->nobj)
9003ea4a95cSchristos if (otmp != obj)
90161f28255Scgd if (otmp->ox == obj->ox && otmp->oy == obj->oy &&
90261f28255Scgd merged(obj, otmp, 1))
90361f28255Scgd return;
90461f28255Scgd }
90561f28255Scgd
90661f28255Scgd /* merge obj with otmp and delete obj if types agree */
9079b92b189Sdholland static int
merged(struct obj * otmp,struct obj * obj,int lose)9081fa8a9a6Sdholland merged(struct obj *otmp, struct obj *obj, int lose)
9093ea4a95cSchristos {
91061f28255Scgd if (obj->otyp == otmp->otyp &&
91161f28255Scgd obj->unpaid == otmp->unpaid &&
91261f28255Scgd obj->spe == otmp->spe &&
91361f28255Scgd obj->dknown == otmp->dknown &&
91461f28255Scgd obj->cursed == otmp->cursed &&
9153ea4a95cSchristos (strchr("%*?!", obj->olet) ||
91661f28255Scgd (obj->known == otmp->known &&
91761f28255Scgd (obj->olet == WEAPON_SYM && obj->otyp < BOOMERANG)))) {
91861f28255Scgd otmp->quan += obj->quan;
91961f28255Scgd otmp->owt += obj->owt;
9203ea4a95cSchristos if (lose)
9213ea4a95cSchristos freeobj(obj);
92261f28255Scgd obfree(obj, otmp); /* free(obj), bill->otmp */
92361f28255Scgd return (1);
9243ea4a95cSchristos } else
9253ea4a95cSchristos return (0);
92661f28255Scgd }
92761f28255Scgd
9283ea4a95cSchristos static long goldcounted;
92961f28255Scgd /*
93061f28255Scgd * Gold is no longer displayed; in fact, when you have a lot of money,
93161f28255Scgd * it may take a while before you have counted it all.
93261f28255Scgd * [Bug: d$ and pickup still tell you how much it was.]
93361f28255Scgd */
9349b92b189Sdholland static int
countgold(void)9351fa8a9a6Sdholland countgold(void)
9363ea4a95cSchristos {
93761f28255Scgd if ((goldcounted += 100 * (u.ulevel + 1)) >= u.ugold) {
93861f28255Scgd long eps = 0;
9393ea4a95cSchristos if (!rn2(2))
9403ea4a95cSchristos eps = rnd((int) (u.ugold / 100 + 1));
94161f28255Scgd pline("You probably have about %ld gold pieces.",
94261f28255Scgd u.ugold + eps);
94361f28255Scgd return (0); /* done */
94461f28255Scgd }
94561f28255Scgd return (1); /* continue */
94661f28255Scgd }
94761f28255Scgd
9483ea4a95cSchristos int
doprgold(void)9491fa8a9a6Sdholland doprgold(void)
9503ea4a95cSchristos {
95161f28255Scgd if (!u.ugold)
95261f28255Scgd pline("You do not carry any gold.");
95361f28255Scgd else if (u.ugold <= 500)
95461f28255Scgd pline("You are carrying %ld gold pieces.", u.ugold);
95561f28255Scgd else {
95661f28255Scgd pline("You sit down in order to count your gold pieces.");
95761f28255Scgd goldcounted = 500;
95861f28255Scgd occupation = countgold;
95961f28255Scgd occtxt = "counting your gold";
96061f28255Scgd }
96161f28255Scgd return (1);
96261f28255Scgd }
96361f28255Scgd
96461f28255Scgd /* --- end of gold counting section --- */
9653ea4a95cSchristos int
doprwep(void)9661fa8a9a6Sdholland doprwep(void)
9673ea4a95cSchristos {
9683ea4a95cSchristos if (!uwep)
9693ea4a95cSchristos pline("You are empty handed.");
9703ea4a95cSchristos else
9713ea4a95cSchristos prinv(uwep);
97261f28255Scgd return (0);
97361f28255Scgd }
97461f28255Scgd
9753ea4a95cSchristos int
doprarm(void)9761fa8a9a6Sdholland doprarm(void)
9773ea4a95cSchristos {
97861f28255Scgd if (!uarm && !uarmg && !uarms && !uarmh)
97961f28255Scgd pline("You are not wearing any armor.");
98061f28255Scgd else {
98161f28255Scgd char lets[6];
9823ea4a95cSchristos int ct = 0;
98361f28255Scgd
9843ea4a95cSchristos if (uarm)
9853ea4a95cSchristos lets[ct++] = obj_to_let(uarm);
9863ea4a95cSchristos if (uarm2)
9873ea4a95cSchristos lets[ct++] = obj_to_let(uarm2);
9883ea4a95cSchristos if (uarmh)
9893ea4a95cSchristos lets[ct++] = obj_to_let(uarmh);
9903ea4a95cSchristos if (uarms)
9913ea4a95cSchristos lets[ct++] = obj_to_let(uarms);
9923ea4a95cSchristos if (uarmg)
9933ea4a95cSchristos lets[ct++] = obj_to_let(uarmg);
99461f28255Scgd lets[ct] = 0;
99561f28255Scgd doinv(lets);
99661f28255Scgd }
99761f28255Scgd return (0);
99861f28255Scgd }
99961f28255Scgd
10003ea4a95cSchristos int
doprring(void)10011fa8a9a6Sdholland doprring(void)
10023ea4a95cSchristos {
100361f28255Scgd if (!uleft && !uright)
100461f28255Scgd pline("You are not wearing any rings.");
100561f28255Scgd else {
100661f28255Scgd char lets[3];
10073ea4a95cSchristos int ct = 0;
100861f28255Scgd
10093ea4a95cSchristos if (uleft)
10103ea4a95cSchristos lets[ct++] = obj_to_let(uleft);
10113ea4a95cSchristos if (uright)
10123ea4a95cSchristos lets[ct++] = obj_to_let(uright);
101361f28255Scgd lets[ct] = 0;
101461f28255Scgd doinv(lets);
101561f28255Scgd }
101661f28255Scgd return (0);
101761f28255Scgd }
101861f28255Scgd
10193ea4a95cSchristos int
digit(int c)10201fa8a9a6Sdholland digit(int c)
10213ea4a95cSchristos {
102261f28255Scgd return (c >= '0' && c <= '9');
102361f28255Scgd }
1024