141238Sbostic /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
241238Sbostic /* hack.invent.c - version 1.0.3 */
341238Sbostic
441238Sbostic #include "hack.h"
541238Sbostic #include <stdio.h>
641238Sbostic extern struct obj *splitobj();
741238Sbostic extern struct obj zeroobj;
841238Sbostic extern char morc;
941238Sbostic extern char quitchars[];
10*57827Storek static char *xprname();
1141238Sbostic
1241238Sbostic #ifndef NOWORM
1341238Sbostic #include "def.wseg.h"
1441238Sbostic extern struct wseg *wsegs[32];
1541238Sbostic #endif NOWORM
1641238Sbostic
1741238Sbostic #define NOINVSYM '#'
1841238Sbostic
1941238Sbostic static int lastinvnr = 51; /* 0 ... 51 */
2041238Sbostic static
assigninvlet(otmp)2141238Sbostic assigninvlet(otmp)
2241238Sbostic register struct obj *otmp;
2341238Sbostic {
2441238Sbostic boolean inuse[52];
2541238Sbostic register int i;
2641238Sbostic register struct obj *obj;
2741238Sbostic
2841238Sbostic for(i = 0; i < 52; i++) inuse[i] = FALSE;
2941238Sbostic for(obj = invent; obj; obj = obj->nobj) if(obj != otmp) {
3041238Sbostic i = obj->invlet;
3141238Sbostic if('a' <= i && i <= 'z') inuse[i - 'a'] = TRUE; else
3241238Sbostic if('A' <= i && i <= 'Z') inuse[i - 'A' + 26] = TRUE;
3341238Sbostic if(i == otmp->invlet) otmp->invlet = 0;
3441238Sbostic }
3541238Sbostic if((i = otmp->invlet) &&
3641238Sbostic (('a' <= i && i <= 'z') || ('A' <= i && i <= 'Z')))
3741238Sbostic return;
3841238Sbostic for(i = lastinvnr+1; i != lastinvnr; i++) {
3941238Sbostic if(i == 52) { i = -1; continue; }
4041238Sbostic if(!inuse[i]) break;
4141238Sbostic }
4241238Sbostic otmp->invlet = (inuse[i] ? NOINVSYM :
4341238Sbostic (i < 26) ? ('a'+i) : ('A'+i-26));
4441238Sbostic lastinvnr = i;
4541238Sbostic }
4641238Sbostic
4741238Sbostic struct obj *
addinv(obj)4841238Sbostic addinv(obj)
4941238Sbostic register struct obj *obj;
5041238Sbostic {
5141238Sbostic register struct obj *otmp;
5241238Sbostic
5341238Sbostic /* merge or attach to end of chain */
5441238Sbostic if(!invent) {
5541238Sbostic invent = obj;
5641238Sbostic otmp = 0;
5741238Sbostic } else
5841238Sbostic for(otmp = invent; /* otmp */; otmp = otmp->nobj) {
5941238Sbostic if(merged(otmp, obj, 0))
6041238Sbostic return(otmp);
6141238Sbostic if(!otmp->nobj) {
6241238Sbostic otmp->nobj = obj;
6341238Sbostic break;
6441238Sbostic }
6541238Sbostic }
6641238Sbostic obj->nobj = 0;
6741238Sbostic
6841238Sbostic if(flags.invlet_constant) {
6941238Sbostic assigninvlet(obj);
7041238Sbostic /*
7141238Sbostic * The ordering of the chain is nowhere significant
7241238Sbostic * so in case you prefer some other order than the
7341238Sbostic * historical one, change the code below.
7441238Sbostic */
7541238Sbostic if(otmp) { /* find proper place in chain */
7641238Sbostic otmp->nobj = 0;
7741238Sbostic if((invent->invlet ^ 040) > (obj->invlet ^ 040)) {
7841238Sbostic obj->nobj = invent;
7941238Sbostic invent = obj;
8041238Sbostic } else
8141238Sbostic for(otmp = invent; ; otmp = otmp->nobj) {
8241238Sbostic if(!otmp->nobj ||
8341238Sbostic (otmp->nobj->invlet ^ 040) > (obj->invlet ^ 040)){
8441238Sbostic obj->nobj = otmp->nobj;
8541238Sbostic otmp->nobj = obj;
8641238Sbostic break;
8741238Sbostic }
8841238Sbostic }
8941238Sbostic }
9041238Sbostic }
9141238Sbostic
9241238Sbostic return(obj);
9341238Sbostic }
9441238Sbostic
useup(obj)9541238Sbostic useup(obj)
9641238Sbostic register struct obj *obj;
9741238Sbostic {
9841238Sbostic if(obj->quan > 1){
9941238Sbostic obj->quan--;
10041238Sbostic obj->owt = weight(obj);
10141238Sbostic } else {
10241238Sbostic setnotworn(obj);
10341238Sbostic freeinv(obj);
10441238Sbostic obfree(obj, (struct obj *) 0);
10541238Sbostic }
10641238Sbostic }
10741238Sbostic
freeinv(obj)10841238Sbostic freeinv(obj)
10941238Sbostic register struct obj *obj;
11041238Sbostic {
11141238Sbostic register struct obj *otmp;
11241238Sbostic
11341238Sbostic if(obj == invent)
11441238Sbostic invent = invent->nobj;
11541238Sbostic else {
11641238Sbostic for(otmp = invent; otmp->nobj != obj; otmp = otmp->nobj)
11741238Sbostic if(!otmp->nobj) panic("freeinv");
11841238Sbostic otmp->nobj = obj->nobj;
11941238Sbostic }
12041238Sbostic }
12141238Sbostic
12241238Sbostic /* destroy object in fobj chain (if unpaid, it remains on the bill) */
delobj(obj)12341238Sbostic delobj(obj) register struct obj *obj; {
12441238Sbostic freeobj(obj);
12541238Sbostic unpobj(obj);
12641238Sbostic obfree(obj, (struct obj *) 0);
12741238Sbostic }
12841238Sbostic
12941238Sbostic /* unlink obj from chain starting with fobj */
freeobj(obj)13041238Sbostic freeobj(obj) register struct obj *obj; {
13141238Sbostic register struct obj *otmp;
13241238Sbostic
13341238Sbostic if(obj == fobj) fobj = fobj->nobj;
13441238Sbostic else {
13541238Sbostic for(otmp = fobj; otmp->nobj != obj; otmp = otmp->nobj)
13641238Sbostic if(!otmp) panic("error in freeobj");
13741238Sbostic otmp->nobj = obj->nobj;
13841238Sbostic }
13941238Sbostic }
14041238Sbostic
14141238Sbostic /* Note: freegold throws away its argument! */
freegold(gold)14241238Sbostic freegold(gold) register struct gold *gold; {
14341238Sbostic register struct gold *gtmp;
14441238Sbostic
14541238Sbostic if(gold == fgold) fgold = gold->ngold;
14641238Sbostic else {
14741238Sbostic for(gtmp = fgold; gtmp->ngold != gold; gtmp = gtmp->ngold)
14841238Sbostic if(!gtmp) panic("error in freegold");
14941238Sbostic gtmp->ngold = gold->ngold;
15041238Sbostic }
15141238Sbostic free((char *) gold);
15241238Sbostic }
15341238Sbostic
deltrap(trap)15441238Sbostic deltrap(trap)
15541238Sbostic register struct trap *trap;
15641238Sbostic {
15741238Sbostic register struct trap *ttmp;
15841238Sbostic
15941238Sbostic if(trap == ftrap)
16041238Sbostic ftrap = ftrap->ntrap;
16141238Sbostic else {
16241238Sbostic for(ttmp = ftrap; ttmp->ntrap != trap; ttmp = ttmp->ntrap) ;
16341238Sbostic ttmp->ntrap = trap->ntrap;
16441238Sbostic }
16541238Sbostic free((char *) trap);
16641238Sbostic }
16741238Sbostic
16841238Sbostic struct wseg *m_atseg;
16941238Sbostic
17041238Sbostic struct monst *
m_at(x,y)17141238Sbostic m_at(x,y)
17241238Sbostic register x,y;
17341238Sbostic {
17441238Sbostic register struct monst *mtmp;
17541238Sbostic #ifndef NOWORM
17641238Sbostic register struct wseg *wtmp;
17741238Sbostic #endif NOWORM
17841238Sbostic
17941238Sbostic m_atseg = 0;
18041238Sbostic for(mtmp = fmon; mtmp; mtmp = mtmp->nmon){
18141238Sbostic if(mtmp->mx == x && mtmp->my == y)
18241238Sbostic return(mtmp);
18341238Sbostic #ifndef NOWORM
18441238Sbostic if(mtmp->wormno){
18541238Sbostic for(wtmp = wsegs[mtmp->wormno]; wtmp; wtmp = wtmp->nseg)
18641238Sbostic if(wtmp->wx == x && wtmp->wy == y){
18741238Sbostic m_atseg = wtmp;
18841238Sbostic return(mtmp);
18941238Sbostic }
19041238Sbostic }
19141238Sbostic #endif NOWORM
19241238Sbostic }
19341238Sbostic return(0);
19441238Sbostic }
19541238Sbostic
19641238Sbostic struct obj *
o_at(x,y)19741238Sbostic o_at(x,y)
19841238Sbostic register x,y;
19941238Sbostic {
20041238Sbostic register struct obj *otmp;
20141238Sbostic
20241238Sbostic for(otmp = fobj; otmp; otmp = otmp->nobj)
20341238Sbostic if(otmp->ox == x && otmp->oy == y) return(otmp);
20441238Sbostic return(0);
20541238Sbostic }
20641238Sbostic
20741238Sbostic struct obj *
sobj_at(n,x,y)20841238Sbostic sobj_at(n,x,y)
20941238Sbostic register n,x,y;
21041238Sbostic {
21141238Sbostic register struct obj *otmp;
21241238Sbostic
21341238Sbostic for(otmp = fobj; otmp; otmp = otmp->nobj)
21441238Sbostic if(otmp->ox == x && otmp->oy == y && otmp->otyp == n)
21541238Sbostic return(otmp);
21641238Sbostic return(0);
21741238Sbostic }
21841238Sbostic
carried(obj)21941238Sbostic carried(obj) register struct obj *obj; {
22041238Sbostic register struct obj *otmp;
22141238Sbostic for(otmp = invent; otmp; otmp = otmp->nobj)
22241238Sbostic if(otmp == obj) return(1);
22341238Sbostic return(0);
22441238Sbostic }
22541238Sbostic
carrying(type)22641238Sbostic carrying(type)
22741238Sbostic register int type;
22841238Sbostic {
22941238Sbostic register struct obj *otmp;
23041238Sbostic
23141238Sbostic for(otmp = invent; otmp; otmp = otmp->nobj)
23241238Sbostic if(otmp->otyp == type)
23341238Sbostic return(TRUE);
23441238Sbostic return(FALSE);
23541238Sbostic }
23641238Sbostic
23741238Sbostic struct obj *
o_on(id,objchn)23841238Sbostic o_on(id, objchn) unsigned int id; register struct obj *objchn; {
23941238Sbostic while(objchn) {
24041238Sbostic if(objchn->o_id == id) return(objchn);
24141238Sbostic objchn = objchn->nobj;
24241238Sbostic }
24341238Sbostic return((struct obj *) 0);
24441238Sbostic }
24541238Sbostic
24641238Sbostic struct trap *
t_at(x,y)24741238Sbostic t_at(x,y)
24841238Sbostic register x,y;
24941238Sbostic {
25041238Sbostic register struct trap *trap = ftrap;
25141238Sbostic while(trap) {
25241238Sbostic if(trap->tx == x && trap->ty == y) return(trap);
25341238Sbostic trap = trap->ntrap;
25441238Sbostic }
25541238Sbostic return(0);
25641238Sbostic }
25741238Sbostic
25841238Sbostic struct gold *
g_at(x,y)25941238Sbostic g_at(x,y)
26041238Sbostic register x,y;
26141238Sbostic {
26241238Sbostic register struct gold *gold = fgold;
26341238Sbostic while(gold) {
26441238Sbostic if(gold->gx == x && gold->gy == y) return(gold);
26541238Sbostic gold = gold->ngold;
26641238Sbostic }
26741238Sbostic return(0);
26841238Sbostic }
26941238Sbostic
27041238Sbostic /* make dummy object structure containing gold - for temporary use only */
27141238Sbostic struct obj *
mkgoldobj(q)27241238Sbostic mkgoldobj(q)
27341238Sbostic register long q;
27441238Sbostic {
27541238Sbostic register struct obj *otmp;
27641238Sbostic
27741238Sbostic otmp = newobj(0);
27841238Sbostic /* should set o_id etc. but otmp will be freed soon */
27941238Sbostic otmp->olet = '$';
28041238Sbostic u.ugold -= q;
28141238Sbostic OGOLD(otmp) = q;
28241238Sbostic flags.botl = 1;
28341238Sbostic return(otmp);
28441238Sbostic }
28541238Sbostic
28641238Sbostic /*
28741238Sbostic * getobj returns:
28841238Sbostic * struct obj *xxx: object to do something with.
28941238Sbostic * (struct obj *) 0 error return: no object.
29041238Sbostic * &zeroobj explicitly no object (as in w-).
29141238Sbostic */
29241238Sbostic struct obj *
getobj(let,word)29341238Sbostic getobj(let,word)
29441238Sbostic register char *let,*word;
29541238Sbostic {
29641238Sbostic register struct obj *otmp;
29741238Sbostic register char ilet,ilet1,ilet2;
29841238Sbostic char buf[BUFSZ];
29941238Sbostic char lets[BUFSZ];
30041238Sbostic register int foo = 0, foo2;
30141238Sbostic register char *bp = buf;
30241238Sbostic xchar allowcnt = 0; /* 0, 1 or 2 */
30341238Sbostic boolean allowgold = FALSE;
30441238Sbostic boolean allowall = FALSE;
30541238Sbostic boolean allownone = FALSE;
30641238Sbostic xchar foox = 0;
30741238Sbostic long cnt;
30841238Sbostic
30941238Sbostic if(*let == '0') let++, allowcnt = 1;
31041238Sbostic if(*let == '$') let++, allowgold = TRUE;
31141238Sbostic if(*let == '#') let++, allowall = TRUE;
31241238Sbostic if(*let == '-') let++, allownone = TRUE;
31341238Sbostic if(allownone) *bp++ = '-';
31441238Sbostic if(allowgold) *bp++ = '$';
31541238Sbostic if(bp > buf && bp[-1] == '-') *bp++ = ' ';
31641238Sbostic
31741238Sbostic ilet = 'a';
31841238Sbostic for(otmp = invent; otmp; otmp = otmp->nobj){
31941238Sbostic if(!*let || index(let, otmp->olet)) {
32041238Sbostic bp[foo++] = flags.invlet_constant ? otmp->invlet : ilet;
32141238Sbostic
32241238Sbostic /* ugly check: remove inappropriate things */
32341238Sbostic if((!strcmp(word, "take off") &&
32441238Sbostic !(otmp->owornmask & (W_ARMOR - W_ARM2)))
32541238Sbostic || (!strcmp(word, "wear") &&
32641238Sbostic (otmp->owornmask & (W_ARMOR | W_RING)))
32741238Sbostic || (!strcmp(word, "wield") &&
32841238Sbostic (otmp->owornmask & W_WEP))) {
32941238Sbostic foo--;
33041238Sbostic foox++;
33141238Sbostic }
33241238Sbostic }
33341238Sbostic if(ilet == 'z') ilet = 'A'; else ilet++;
33441238Sbostic }
33541238Sbostic bp[foo] = 0;
33641238Sbostic if(foo == 0 && bp > buf && bp[-1] == ' ') *--bp = 0;
33741238Sbostic (void) strcpy(lets, bp); /* necessary since we destroy buf */
33841238Sbostic if(foo > 5) { /* compactify string */
33941238Sbostic foo = foo2 = 1;
34041238Sbostic ilet2 = bp[0];
34141238Sbostic ilet1 = bp[1];
34241238Sbostic while(ilet = bp[++foo2] = bp[++foo]){
34341238Sbostic if(ilet == ilet1+1){
34441238Sbostic if(ilet1 == ilet2+1)
34541238Sbostic bp[foo2 - 1] = ilet1 = '-';
34641238Sbostic else if(ilet2 == '-') {
34741238Sbostic bp[--foo2] = ++ilet1;
34841238Sbostic continue;
34941238Sbostic }
35041238Sbostic }
35141238Sbostic ilet2 = ilet1;
35241238Sbostic ilet1 = ilet;
35341238Sbostic }
35441238Sbostic }
35541238Sbostic if(!foo && !allowall && !allowgold && !allownone) {
35641238Sbostic pline("You don't have anything %sto %s.",
35741238Sbostic foox ? "else " : "", word);
35841238Sbostic return(0);
35941238Sbostic }
36041238Sbostic for(;;) {
36141238Sbostic if(!buf[0])
36241238Sbostic pline("What do you want to %s [*]? ", word);
36341238Sbostic else
36441238Sbostic pline("What do you want to %s [%s or ?*]? ",
36541238Sbostic word, buf);
36641238Sbostic
36741238Sbostic cnt = 0;
36841238Sbostic ilet = readchar();
36941238Sbostic while(digit(ilet) && allowcnt) {
37041238Sbostic if (cnt < 100000000)
37141238Sbostic cnt = 10*cnt + (ilet - '0');
37241238Sbostic else
37341238Sbostic cnt = 999999999;
37441238Sbostic allowcnt = 2; /* signal presence of cnt */
37541238Sbostic ilet = readchar();
37641238Sbostic }
37741238Sbostic if(digit(ilet)) {
37841238Sbostic pline("No count allowed with this command.");
37941238Sbostic continue;
38041238Sbostic }
38141238Sbostic if(index(quitchars,ilet))
38241238Sbostic return((struct obj *)0);
38341238Sbostic if(ilet == '-') {
38441238Sbostic return(allownone ? &zeroobj : (struct obj *) 0);
38541238Sbostic }
38641238Sbostic if(ilet == '$') {
38741238Sbostic if(!allowgold){
38841238Sbostic pline("You cannot %s gold.", word);
38941238Sbostic continue;
39041238Sbostic }
39141238Sbostic if(!(allowcnt == 2 && cnt < u.ugold))
39241238Sbostic cnt = u.ugold;
39341238Sbostic return(mkgoldobj(cnt));
39441238Sbostic }
39541238Sbostic if(ilet == '?') {
39641238Sbostic doinv(lets);
39741238Sbostic if(!(ilet = morc)) continue;
39841238Sbostic /* he typed a letter (not a space) to more() */
39941238Sbostic } else if(ilet == '*') {
40041238Sbostic doinv((char *) 0);
40141238Sbostic if(!(ilet = morc)) continue;
40241238Sbostic /* ... */
40341238Sbostic }
40441238Sbostic if(flags.invlet_constant) {
40541238Sbostic for(otmp = invent; otmp; otmp = otmp->nobj)
40641238Sbostic if(otmp->invlet == ilet) break;
40741238Sbostic } else {
40841238Sbostic if(ilet >= 'A' && ilet <= 'Z') ilet += 'z'-'A'+1;
40941238Sbostic ilet -= 'a';
41041238Sbostic for(otmp = invent; otmp && ilet;
41141238Sbostic ilet--, otmp = otmp->nobj) ;
41241238Sbostic }
41341238Sbostic if(!otmp) {
41441238Sbostic pline("You don't have that object.");
41541238Sbostic continue;
41641238Sbostic }
41741238Sbostic if(cnt < 0 || otmp->quan < cnt) {
41841238Sbostic pline("You don't have that many! [You have %u]"
41941238Sbostic , otmp->quan);
42041238Sbostic continue;
42141238Sbostic }
42241238Sbostic break;
42341238Sbostic }
42441238Sbostic if(!allowall && let && !index(let,otmp->olet)) {
42541238Sbostic pline("That is a silly thing to %s.",word);
42641238Sbostic return(0);
42741238Sbostic }
42841238Sbostic if(allowcnt == 2) { /* cnt given */
42941238Sbostic if(cnt == 0) return(0);
43041238Sbostic if(cnt != otmp->quan) {
43141238Sbostic register struct obj *obj;
43241238Sbostic obj = splitobj(otmp, (int) cnt);
43341238Sbostic if(otmp == uwep) setuwep(obj);
43441238Sbostic }
43541238Sbostic }
43641238Sbostic return(otmp);
43741238Sbostic }
43841238Sbostic
ckunpaid(otmp)43941238Sbostic ckunpaid(otmp) register struct obj *otmp; {
44041238Sbostic return( otmp->unpaid );
44141238Sbostic }
44241238Sbostic
44341238Sbostic /* interactive version of getobj - used for Drop and Identify */
44441238Sbostic /* return the number of times fn was called successfully */
ggetobj(word,fn,max)44541238Sbostic ggetobj(word, fn, max)
44641238Sbostic char *word;
44741238Sbostic int (*fn)(), max;
44841238Sbostic {
44941238Sbostic char buf[BUFSZ];
45041238Sbostic register char *ip;
45141238Sbostic register char sym;
45241238Sbostic register int oletct = 0, iletct = 0;
45341238Sbostic register boolean allflag = FALSE;
45441238Sbostic char olets[20], ilets[20];
45541238Sbostic int (*ckfn)() = (int (*)()) 0;
45641238Sbostic xchar allowgold = (u.ugold && !strcmp(word, "drop")) ? 1 : 0; /* BAH */
45741238Sbostic if(!invent && !allowgold){
45841238Sbostic pline("You have nothing to %s.", word);
45941238Sbostic return(0);
46041238Sbostic } else {
46141238Sbostic register struct obj *otmp = invent;
46241238Sbostic register int uflg = 0;
46341238Sbostic
46441238Sbostic if(allowgold) ilets[iletct++] = '$';
46541238Sbostic ilets[iletct] = 0;
46641238Sbostic while(otmp) {
46741238Sbostic if(!index(ilets, otmp->olet)){
46841238Sbostic ilets[iletct++] = otmp->olet;
46941238Sbostic ilets[iletct] = 0;
47041238Sbostic }
47141238Sbostic if(otmp->unpaid) uflg = 1;
47241238Sbostic otmp = otmp->nobj;
47341238Sbostic }
47441238Sbostic ilets[iletct++] = ' ';
47541238Sbostic if(uflg) ilets[iletct++] = 'u';
47641238Sbostic if(invent) ilets[iletct++] = 'a';
47741238Sbostic ilets[iletct] = 0;
47841238Sbostic }
47941238Sbostic pline("What kinds of thing do you want to %s? [%s] ",
48041238Sbostic word, ilets);
48141238Sbostic getlin(buf);
48241238Sbostic if(buf[0] == '\033') {
48341238Sbostic clrlin();
48441238Sbostic return(0);
48541238Sbostic }
48641238Sbostic ip = buf;
48741238Sbostic olets[0] = 0;
48841238Sbostic while(sym = *ip++){
48941238Sbostic if(sym == ' ') continue;
49041238Sbostic if(sym == '$') {
49141238Sbostic if(allowgold == 1)
49241238Sbostic (*fn)(mkgoldobj(u.ugold));
49341238Sbostic else if(!u.ugold)
49441238Sbostic pline("You have no gold.");
49541238Sbostic allowgold = 2;
49641238Sbostic } else
49741238Sbostic if(sym == 'a' || sym == 'A') allflag = TRUE; else
49841238Sbostic if(sym == 'u' || sym == 'U') ckfn = ckunpaid; else
49941238Sbostic if(index("!%?[()=*/\"0", sym)){
50041238Sbostic if(!index(olets, sym)){
50141238Sbostic olets[oletct++] = sym;
50241238Sbostic olets[oletct] = 0;
50341238Sbostic }
50441238Sbostic }
50541238Sbostic else pline("You don't have any %c's.", sym);
50641238Sbostic }
50741238Sbostic if(allowgold == 2 && !oletct)
50841238Sbostic return(1); /* he dropped gold (or at least tried to) */
50941238Sbostic else
51041238Sbostic return(askchain(invent, olets, allflag, fn, ckfn, max));
51141238Sbostic }
51241238Sbostic
51341238Sbostic /*
51441238Sbostic * Walk through the chain starting at objchn and ask for all objects
51541238Sbostic * with olet in olets (if nonNULL) and satisfying ckfn (if nonNULL)
51641238Sbostic * whether the action in question (i.e., fn) has to be performed.
51741238Sbostic * If allflag then no questions are asked. Max gives the max nr of
51841238Sbostic * objects to be treated. Return the number of objects treated.
51941238Sbostic */
52041238Sbostic askchain(objchn, olets, allflag, fn, ckfn, max)
52141238Sbostic struct obj *objchn;
52241238Sbostic register char *olets;
52341238Sbostic int allflag;
52441238Sbostic int (*fn)(), (*ckfn)();
52541238Sbostic int max;
52641238Sbostic {
52741238Sbostic register struct obj *otmp, *otmp2;
52841238Sbostic register char sym, ilet;
52941238Sbostic register int cnt = 0;
53041238Sbostic ilet = 'a'-1;
53141238Sbostic for(otmp = objchn; otmp; otmp = otmp2){
53241238Sbostic if(ilet == 'z') ilet = 'A'; else ilet++;
53341238Sbostic otmp2 = otmp->nobj;
53441238Sbostic if(olets && *olets && !index(olets, otmp->olet)) continue;
53541238Sbostic if(ckfn && !(*ckfn)(otmp)) continue;
53641238Sbostic if(!allflag) {
53741238Sbostic pline(xprname(otmp, ilet));
53841238Sbostic addtopl(" [nyaq]? ");
53941238Sbostic sym = readchar();
54041238Sbostic }
54141238Sbostic else sym = 'y';
54241238Sbostic
54341238Sbostic switch(sym){
54441238Sbostic case 'a':
54541238Sbostic allflag = 1;
54641238Sbostic case 'y':
54741238Sbostic cnt += (*fn)(otmp);
54841238Sbostic if(--max == 0) goto ret;
54941238Sbostic case 'n':
55041238Sbostic default:
55141238Sbostic break;
55241238Sbostic case 'q':
55341238Sbostic goto ret;
55441238Sbostic }
55541238Sbostic }
55641238Sbostic pline(cnt ? "That was all." : "No applicable objects.");
55741238Sbostic ret:
55841238Sbostic return(cnt);
55941238Sbostic }
56041238Sbostic
obj_to_let(obj)56141238Sbostic obj_to_let(obj) /* should of course only be called for things in invent */
56241238Sbostic register struct obj *obj;
56341238Sbostic {
56441238Sbostic register struct obj *otmp;
56541238Sbostic register char ilet;
56641238Sbostic
56741238Sbostic if(flags.invlet_constant)
56841238Sbostic return(obj->invlet);
56941238Sbostic ilet = 'a';
57041238Sbostic for(otmp = invent; otmp && otmp != obj; otmp = otmp->nobj)
57141238Sbostic if(++ilet > 'z') ilet = 'A';
57241238Sbostic return(otmp ? ilet : NOINVSYM);
57341238Sbostic }
57441238Sbostic
prinv(obj)57541238Sbostic prinv(obj)
57641238Sbostic register struct obj *obj;
57741238Sbostic {
57841238Sbostic pline(xprname(obj, obj_to_let(obj)));
57941238Sbostic }
58041238Sbostic
58141238Sbostic static char *
xprname(obj,let)58241238Sbostic xprname(obj,let)
58341238Sbostic register struct obj *obj;
58441238Sbostic register char let;
58541238Sbostic {
58641238Sbostic static char li[BUFSZ];
58741238Sbostic
58841238Sbostic (void) sprintf(li, "%c - %s.",
58941238Sbostic flags.invlet_constant ? obj->invlet : let,
59041238Sbostic doname(obj));
59141238Sbostic return(li);
59241238Sbostic }
59341238Sbostic
ddoinv()59441238Sbostic ddoinv()
59541238Sbostic {
59641238Sbostic doinv((char *) 0);
59741238Sbostic return(0);
59841238Sbostic }
59941238Sbostic
60041238Sbostic /* called with 0 or "": all objects in inventory */
60141238Sbostic /* otherwise: all objects with (serial) letter in lets */
doinv(lets)60241238Sbostic doinv(lets)
60341238Sbostic register char *lets;
60441238Sbostic {
60541238Sbostic register struct obj *otmp;
60641238Sbostic register char ilet;
60741238Sbostic int ct = 0;
60841238Sbostic char any[BUFSZ];
60941238Sbostic
61041238Sbostic morc = 0; /* just to be sure */
61141238Sbostic
61241238Sbostic if(!invent){
61341238Sbostic pline("Not carrying anything.");
61441238Sbostic return;
61541238Sbostic }
61641238Sbostic
61741238Sbostic cornline(0, (char *) 0);
61841238Sbostic ilet = 'a';
61941238Sbostic for(otmp = invent; otmp; otmp = otmp->nobj) {
62041238Sbostic if(flags.invlet_constant) ilet = otmp->invlet;
62141238Sbostic if(!lets || !*lets || index(lets, ilet)) {
62241238Sbostic cornline(1, xprname(otmp, ilet));
62341238Sbostic any[ct++] = ilet;
62441238Sbostic }
62541238Sbostic if(!flags.invlet_constant) if(++ilet > 'z') ilet = 'A';
62641238Sbostic }
62741238Sbostic any[ct] = 0;
62841238Sbostic cornline(2, any);
62941238Sbostic }
63041238Sbostic
dotypeinv()63141238Sbostic dotypeinv () /* free after Robert Viduya */
63241238Sbostic /* Changed to one type only, so he doesnt have to type cr */
63341238Sbostic {
63441238Sbostic char c, ilet;
63541238Sbostic char stuff[BUFSZ];
63641238Sbostic register int stct;
63741238Sbostic register struct obj *otmp;
63841238Sbostic boolean billx = inshop() && doinvbill(0);
63941238Sbostic boolean unpd = FALSE;
64041238Sbostic
64141238Sbostic if (!invent && !u.ugold && !billx) {
64241238Sbostic pline ("You aren't carrying anything.");
64341238Sbostic return(0);
64441238Sbostic }
64541238Sbostic
64641238Sbostic stct = 0;
64741238Sbostic if(u.ugold) stuff[stct++] = '$';
64841238Sbostic stuff[stct] = 0;
64941238Sbostic for(otmp = invent; otmp; otmp = otmp->nobj) {
65041238Sbostic if (!index (stuff, otmp->olet)) {
65141238Sbostic stuff[stct++] = otmp->olet;
65241238Sbostic stuff[stct] = 0;
65341238Sbostic }
65441238Sbostic if(otmp->unpaid)
65541238Sbostic unpd = TRUE;
65641238Sbostic }
65741238Sbostic if(unpd) stuff[stct++] = 'u';
65841238Sbostic if(billx) stuff[stct++] = 'x';
65941238Sbostic stuff[stct] = 0;
66041238Sbostic
66141238Sbostic if(stct > 1) {
66241238Sbostic pline ("What type of object [%s] do you want an inventory of? ",
66341238Sbostic stuff);
66441238Sbostic c = readchar();
66541238Sbostic if(index(quitchars,c)) return(0);
66641238Sbostic } else
66741238Sbostic c = stuff[0];
66841238Sbostic
66941238Sbostic if(c == '$')
67041238Sbostic return(doprgold());
67141238Sbostic
67241238Sbostic if(c == 'x' || c == 'X') {
67341238Sbostic if(billx)
67441238Sbostic (void) doinvbill(1);
67541238Sbostic else
67641238Sbostic pline("No used-up objects on the shopping bill.");
67741238Sbostic return(0);
67841238Sbostic }
67941238Sbostic
68041238Sbostic if((c == 'u' || c == 'U') && !unpd) {
68141238Sbostic pline("You are not carrying any unpaid objects.");
68241238Sbostic return(0);
68341238Sbostic }
68441238Sbostic
68541238Sbostic stct = 0;
68641238Sbostic ilet = 'a';
68741238Sbostic for (otmp = invent; otmp; otmp = otmp -> nobj) {
68841238Sbostic if(flags.invlet_constant) ilet = otmp->invlet;
68941238Sbostic if (c == otmp -> olet || (c == 'u' && otmp -> unpaid))
69041238Sbostic stuff[stct++] = ilet;
69141238Sbostic if(!flags.invlet_constant) if(++ilet > 'z') ilet = 'A';
69241238Sbostic }
69341238Sbostic stuff[stct] = '\0';
69441238Sbostic if(stct == 0)
69541238Sbostic pline("You have no such objects.");
69641238Sbostic else
69741238Sbostic doinv (stuff);
69841238Sbostic
69941238Sbostic return(0);
70041238Sbostic }
70141238Sbostic
70241238Sbostic /* look at what is here */
dolook()70341238Sbostic dolook() {
70441238Sbostic register struct obj *otmp, *otmp0;
70541238Sbostic register struct gold *gold;
70641238Sbostic char *verb = Blind ? "feel" : "see";
70741238Sbostic int ct = 0;
70841238Sbostic
70941238Sbostic if(!u.uswallow) {
71041238Sbostic if(Blind) {
71141238Sbostic pline("You try to feel what is lying here on the floor.");
71241238Sbostic if(Levitation) { /* ab@unido */
71341238Sbostic pline("You cannot reach the floor!");
71441238Sbostic return(1);
71541238Sbostic }
71641238Sbostic }
71741238Sbostic otmp0 = o_at(u.ux, u.uy);
71841238Sbostic gold = g_at(u.ux, u.uy);
71941238Sbostic }
72041238Sbostic
72141238Sbostic if(u.uswallow || (!otmp0 && !gold)) {
72241238Sbostic pline("You %s no objects here.", verb);
72341238Sbostic return(!!Blind);
72441238Sbostic }
72541238Sbostic
72641238Sbostic cornline(0, "Things that are here:");
72741238Sbostic for(otmp = otmp0; otmp; otmp = otmp->nobj) {
72841238Sbostic if(otmp->ox == u.ux && otmp->oy == u.uy) {
72941238Sbostic ct++;
73041238Sbostic cornline(1, doname(otmp));
73141238Sbostic if(Blind && otmp->otyp == DEAD_COCKATRICE && !uarmg) {
73241238Sbostic pline("Touching the dead cockatrice is a fatal mistake ...");
73341238Sbostic pline("You die ...");
73441238Sbostic killer = "dead cockatrice";
73541238Sbostic done("died");
73641238Sbostic }
73741238Sbostic }
73841238Sbostic }
73941238Sbostic
74041238Sbostic if(gold) {
74141238Sbostic char gbuf[30];
74241238Sbostic
74341238Sbostic (void) sprintf(gbuf, "%ld gold piece%s",
74441238Sbostic gold->amount, plur(gold->amount));
74541238Sbostic if(!ct++)
74641238Sbostic pline("You %s here %s.", verb, gbuf);
74741238Sbostic else
74841238Sbostic cornline(1, gbuf);
74941238Sbostic }
75041238Sbostic
75141238Sbostic if(ct == 1 && !gold) {
75241238Sbostic pline("You %s here %s.", verb, doname(otmp0));
75341238Sbostic cornline(3, (char *) 0);
75441238Sbostic }
75541238Sbostic if(ct > 1)
75641238Sbostic cornline(2, (char *) 0);
75741238Sbostic return(!!Blind);
75841238Sbostic }
75941238Sbostic
stackobj(obj)76041238Sbostic stackobj(obj) register struct obj *obj; {
76141238Sbostic register struct obj *otmp = fobj;
76241238Sbostic for(otmp = fobj; otmp; otmp = otmp->nobj) if(otmp != obj)
76341238Sbostic if(otmp->ox == obj->ox && otmp->oy == obj->oy &&
76441238Sbostic merged(obj,otmp,1))
76541238Sbostic return;
76641238Sbostic }
76741238Sbostic
76841238Sbostic /* merge obj with otmp and delete obj if types agree */
merged(otmp,obj,lose)76941238Sbostic merged(otmp,obj,lose) register struct obj *otmp, *obj; {
77041238Sbostic if(obj->otyp == otmp->otyp &&
77141238Sbostic obj->unpaid == otmp->unpaid &&
77241238Sbostic obj->spe == otmp->spe &&
77341238Sbostic obj->dknown == otmp->dknown &&
77441238Sbostic obj->cursed == otmp->cursed &&
77541238Sbostic (index("%*?!", obj->olet) ||
77641238Sbostic (obj->known == otmp->known &&
77741238Sbostic (obj->olet == WEAPON_SYM && obj->otyp < BOOMERANG)))) {
77841238Sbostic otmp->quan += obj->quan;
77941238Sbostic otmp->owt += obj->owt;
78041238Sbostic if(lose) freeobj(obj);
78141238Sbostic obfree(obj,otmp); /* free(obj), bill->otmp */
78241238Sbostic return(1);
78341238Sbostic } else return(0);
78441238Sbostic }
78541238Sbostic
78641238Sbostic /*
78741238Sbostic * Gold is no longer displayed; in fact, when you have a lot of money,
78841238Sbostic * it may take a while before you have counted it all.
78941238Sbostic * [Bug: d$ and pickup still tell you how much it was.]
79041238Sbostic */
79141238Sbostic extern int (*occupation)();
79241238Sbostic extern char *occtxt;
79341238Sbostic static long goldcounted;
79441238Sbostic
countgold()79541238Sbostic countgold(){
79641238Sbostic if((goldcounted += 100*(u.ulevel + 1)) >= u.ugold) {
79741238Sbostic long eps = 0;
79841238Sbostic if(!rn2(2)) eps = rnd((int) (u.ugold/100 + 1));
79941238Sbostic pline("You probably have about %ld gold pieces.",
80041238Sbostic u.ugold + eps);
80141238Sbostic return(0); /* done */
80241238Sbostic }
80341238Sbostic return(1); /* continue */
80441238Sbostic }
80541238Sbostic
doprgold()80641238Sbostic doprgold(){
80741238Sbostic if(!u.ugold)
80841238Sbostic pline("You do not carry any gold.");
80941238Sbostic else if(u.ugold <= 500)
81041238Sbostic pline("You are carrying %ld gold pieces.", u.ugold);
81141238Sbostic else {
81241238Sbostic pline("You sit down in order to count your gold pieces.");
81341238Sbostic goldcounted = 500;
81441238Sbostic occupation = countgold;
81541238Sbostic occtxt = "counting your gold";
81641238Sbostic }
81741238Sbostic return(1);
81841238Sbostic }
81941238Sbostic
82041238Sbostic /* --- end of gold counting section --- */
82141238Sbostic
doprwep()82241238Sbostic doprwep(){
82341238Sbostic if(!uwep) pline("You are empty handed.");
82441238Sbostic else prinv(uwep);
82541238Sbostic return(0);
82641238Sbostic }
82741238Sbostic
doprarm()82841238Sbostic doprarm(){
82941238Sbostic if(!uarm && !uarmg && !uarms && !uarmh)
83041238Sbostic pline("You are not wearing any armor.");
83141238Sbostic else {
83241238Sbostic char lets[6];
83341238Sbostic register int ct = 0;
83441238Sbostic
83541238Sbostic if(uarm) lets[ct++] = obj_to_let(uarm);
83641238Sbostic if(uarm2) lets[ct++] = obj_to_let(uarm2);
83741238Sbostic if(uarmh) lets[ct++] = obj_to_let(uarmh);
83841238Sbostic if(uarms) lets[ct++] = obj_to_let(uarms);
83941238Sbostic if(uarmg) lets[ct++] = obj_to_let(uarmg);
84041238Sbostic lets[ct] = 0;
84141238Sbostic doinv(lets);
84241238Sbostic }
84341238Sbostic return(0);
84441238Sbostic }
84541238Sbostic
doprring()84641238Sbostic doprring(){
84741238Sbostic if(!uleft && !uright)
84841238Sbostic pline("You are not wearing any rings.");
84941238Sbostic else {
85041238Sbostic char lets[3];
85141238Sbostic register int ct = 0;
85241238Sbostic
85341238Sbostic if(uleft) lets[ct++] = obj_to_let(uleft);
85441238Sbostic if(uright) lets[ct++] = obj_to_let(uright);
85541238Sbostic lets[ct] = 0;
85641238Sbostic doinv(lets);
85741238Sbostic }
85841238Sbostic return(0);
85941238Sbostic }
86041238Sbostic
digit(c)86141238Sbostic digit(c) char c; {
86241238Sbostic return(c >= '0' && c <= '9');
86341238Sbostic }
864