# 2.11BSD#431 - /usr/src/games/hack/hack.invent.c

##### Functions

    addinv            X
    askchain          X
    carried           X
    carrying          X
    ckunpaid          X
    countgold         X
    ddoinv            X
    delobj            X
    deltrap           X
    digit             X
    doinv             X
    dolook            X
    doprarm           X
    doprgold          X
    doprring          X
    doprwep           X
    dotypeinv         X
    freegold          X
    freeinv           X
    freeobj           X
    g_at              X
    getobj            X
    ggetobj           X
    m_at              X
    merged            X
    mkgoldobj         X
    o_at              X
    o_on              X
    obj_to_let        X
    prinv             X
    sobj_at           X
    stackobj          X
    t_at              X
    useup             X

##### Variables

    m_atseg           X

##### Macros

    NOINVSYM          X

       1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
       2: /* hack.invent.c - version 1.0.3 */
       3:
       4: #include    "hack.h"
       5: #include    <stdio.h>
       6: extern struct obj *splitobj();
       7: extern struct obj zeroobj;
       8: extern char morc;
       9: extern char quitchars[];
      10: char *xprname();
      11:
      12: #ifndef NOWORM
      13: #include    "def.wseg.h"
      14: extern struct wseg *wsegs[32];
      15: #endif NOWORM
      16:
      17: #define NOINVSYM    '#'
      18:
      19: static int lastinvnr = 51;  /* 0 ... 51 */
      20: static
      21: assigninvlet(otmp)
      22: register struct obj *otmp;
      23: {
      24:     boolean inuse[52];
      25:     register int i;
      26:     register struct obj *obj;
      27:
      28:     for(i = 0; i < 52; i++) inuse[i] = FALSE;
      29:     for(obj = invent; obj; obj = obj->nobj) if(obj != otmp) {
      30:         i = obj->invlet;
      31:         if('a' <= i && i <= 'z') inuse[i - 'a'] = TRUE; else
      32:         if('A' <= i && i <= 'Z') inuse[i - 'A' + 26] = TRUE;
      33:         if(i == otmp->invlet) otmp->invlet = 0;
      34:     }
      35:     if((i = otmp->invlet) &&
      36:         (('a' <= i && i <= 'z') || ('A' <= i && i <= 'Z')))
      37:         return;
      38:     for(i = lastinvnr+1; i != lastinvnr; i++) {
      39:         if(i == 52) { i = -1; continue; }
      40:         if(!inuse[i]) break;
      41:     }
      42:     otmp->invlet = (inuse[i] ? NOINVSYM :
      43:             (i < 26) ? ('a'+i) : ('A'+i-26));
      44:     lastinvnr = i;
      45: }
      46:
      47: struct obj *
      48: addinv(obj)
      49: register struct obj *obj;
      50: {
      51:     register struct obj *otmp;
      52:
      53:     /* merge or attach to end of chain */
      54:     if(!invent) {
      55:         invent = obj;
      56:         otmp = 0;
      57:     } else
      58:     for(otmp = invent; /* otmp */; otmp = otmp->nobj) {
      59:         if(merged(otmp, obj, 0))
      60:             return(otmp);
      61:         if(!otmp->nobj) {
      62:             otmp->nobj = obj;
      63:             break;
      64:         }
      65:     }
      66:     obj->nobj = 0;
      67:
      68:     if(flags.invlet_constant) {
      69:         assigninvlet(obj);
      70:         /*
      71: 		 * The ordering of the chain is nowhere significant
      72: 		 * so in case you prefer some other order than the
      73: 		 * historical one, change the code below.
      74: 		 */
      75:         if(otmp) {  /* find proper place in chain */
      76:             otmp->nobj = 0;
      77:             if((invent->invlet ^ 040) > (obj->invlet ^ 040)) {
      78:                 obj->nobj = invent;
      79:                 invent = obj;
      80:             } else
      81:             for(otmp = invent; ; otmp = otmp->nobj) {
      82:                 if(!otmp->nobj ||
      83:                 (otmp->nobj->invlet ^ 040) > (obj->invlet ^ 040)){
      84:                 obj->nobj = otmp->nobj;
      85:                 otmp->nobj = obj;
      86:                 break;
      87:                 }
      88:             }
      89:         }
      90:     }
      91:
      92:     return(obj);
      93: }
      94:
      95: useup(obj)
      96: register struct obj *obj;
      97: {
      98:     if(obj->quan > 1){
      99:         obj->quan--;
     100:         obj->owt = weight(obj);
     101:     } else {
     102:         setnotworn(obj);
     103:         freeinv(obj);
     104:         obfree(obj, (struct obj *) 0);
     105:     }
     106: }
     107:
     108: freeinv(obj)
     109: register struct obj *obj;
     110: {
     111:     register struct obj *otmp;
     112:
     113:     if(obj == invent)
     114:         invent = invent->nobj;
     115:     else {
     116:         for(otmp = invent; otmp->nobj != obj; otmp = otmp->nobj)
     117:             if(!otmp->nobj) panic("freeinv");
     118:         otmp->nobj = obj->nobj;
     119:     }
     120: }
     121:
     122: /* destroy object in fobj chain (if unpaid, it remains on the bill) */
     123: delobj(obj) register struct obj *obj; {
     124:     freeobj(obj);
     125:     unpobj(obj);
     126:     obfree(obj, (struct obj *) 0);
     127: }
     128:
     129: /* unlink obj from chain starting with fobj */
     130: freeobj(obj) register struct obj *obj; {
     131:     register struct obj *otmp;
     132:
     133:     if(obj == fobj) fobj = fobj->nobj;
     134:     else {
     135:         for(otmp = fobj; otmp->nobj != obj; otmp = otmp->nobj)
     136:             if(!otmp) panic("error in freeobj");
     137:         otmp->nobj = obj->nobj;
     138:     }
     139: }
     140:
     141: /* Note: freegold throws away its argument! */
     142: freegold(gold) register struct gold *gold; {
     143:     register struct gold *gtmp;
     144:
     145:     if(gold == fgold) fgold = gold->ngold;
     146:     else {
     147:         for(gtmp = fgold; gtmp->ngold != gold; gtmp = gtmp->ngold)
     148:             if(!gtmp) panic("error in freegold");
     149:         gtmp->ngold = gold->ngold;
     150:     }
     151:     free((char *) gold);
     152: }
     153:
     154: deltrap(trap)
     155: register struct trap *trap;
     156: {
     157:     register struct trap *ttmp;
     158:
     159:     if(trap == ftrap)
     160:         ftrap = ftrap->ntrap;
     161:     else {
     162:         for(ttmp = ftrap; ttmp->ntrap != trap; ttmp = ttmp->ntrap) ;
     163:         ttmp->ntrap = trap->ntrap;
     164:     }
     165:     free((char *) trap);
     166: }
     167:
     168: struct wseg *m_atseg;
     169:
     170: struct monst *
     171: m_at(x,y)
     172: register x,y;
     173: {
     174:     register struct monst *mtmp;
     175: #ifndef NOWORM
     176:     register struct wseg *wtmp;
     177: #endif NOWORM
     178:
     179:     m_atseg = 0;
     180:     for(mtmp = fmon; mtmp; mtmp = mtmp->nmon){
     181:         if(mtmp->mx == x && mtmp->my == y)
     182:             return(mtmp);
     183: #ifndef NOWORM
     184:         if(mtmp->wormno){
     185:             for(wtmp = wsegs[mtmp->wormno]; wtmp; wtmp = wtmp->nseg)
     186:             if(wtmp->wx == x && wtmp->wy == y){
     187:             m_atseg = wtmp;
     188:             return(mtmp);
     189:             }
     190:         }
     191: #endif NOWORM
     192:     }
     193:     return(0);
     194: }
     195:
     196: struct obj *
     197: o_at(x,y)
     198: register x,y;
     199: {
     200:     register struct obj *otmp;
     201:
     202:     for(otmp = fobj; otmp; otmp = otmp->nobj)
     203:         if(otmp->ox == x && otmp->oy == y) return(otmp);
     204:     return(0);
     205: }
     206:
     207: struct obj *
     208: sobj_at(n,x,y)
     209: register n,x,y;
     210: {
     211:     register struct obj *otmp;
     212:
     213:     for(otmp = fobj; otmp; otmp = otmp->nobj)
     214:         if(otmp->ox == x && otmp->oy == y && otmp->otyp == n)
     215:             return(otmp);
     216:     return(0);
     217: }
     218:
     219: carried(obj) register struct obj *obj; {
     220: register struct obj *otmp;
     221:     for(otmp = invent; otmp; otmp = otmp->nobj)
     222:         if(otmp == obj) return(1);
     223:     return(0);
     224: }
     225:
     226: carrying(type)
     227: register int type;
     228: {
     229:     register struct obj *otmp;
     230:
     231:     for(otmp = invent; otmp; otmp = otmp->nobj)
     232:         if(otmp->otyp == type)
     233:             return(TRUE);
     234:     return(FALSE);
     235: }
     236:
     237: struct obj *
     238: o_on(id, objchn) unsigned int id; register struct obj *objchn; {
     239:     while(objchn) {
     240:         if(objchn->o_id == id) return(objchn);
     241:         objchn = objchn->nobj;
     242:     }
     243:     return((struct obj *) 0);
     244: }
     245:
     246: struct trap *
     247: t_at(x,y)
     248: register x,y;
     249: {
     250:     register struct trap *trap = ftrap;
     251:     while(trap) {
     252:         if(trap->tx == x && trap->ty == y) return(trap);
     253:         trap = trap->ntrap;
     254:     }
     255:     return(0);
     256: }
     257:
     258: struct gold *
     259: g_at(x,y)
     260: register x,y;
     261: {
     262:     register struct gold *gold = fgold;
     263:     while(gold) {
     264:         if(gold->gx == x && gold->gy == y) return(gold);
     265:         gold = gold->ngold;
     266:     }
     267:     return(0);
     268: }
     269:
     270: /* make dummy object structure containing gold - for temporary use only */
     271: struct obj *
     272: mkgoldobj(q)
     273: register long q;
     274: {
     275:     register struct obj *otmp;
     276:
     277:     otmp = newobj(0);
     278:     /* should set o_id etc. but otmp will be freed soon */
     279:     otmp->olet = '$';
     280:     u.ugold -= q;
     281:     OGOLD(otmp) = q;
     282:     flags.botl = 1;
     283:     return(otmp);
     284: }
     285:
     286: /*
     287:  * getobj returns:
     288:  *	struct obj *xxx:	object to do something with.
     289:  *	(struct obj *) 0	error return: no object.
     290:  *	&zeroobj		explicitly no object (as in w-).
     291:  */
     292: struct obj *
     293: getobj(let,word)
     294: register char *let,*word;
     295: {
     296:     register struct obj *otmp;
     297:     register char ilet,ilet1,ilet2;
     298:     char buf[BUFSZ];
     299:     char lets[BUFSZ];
     300:     register int foo = 0, foo2;
     301:     register char *bp = buf;
     302:     xchar allowcnt = 0; /* 0, 1 or 2 */
     303:     boolean allowgold = FALSE;
     304:     boolean allowall = FALSE;
     305:     boolean allownone = FALSE;
     306:     xchar foox = 0;
     307:     long cnt;
     308:
     309:     if(*let == '0') let++, allowcnt = 1;
     310:     if(*let == '$') let++, allowgold = TRUE;
     311:     if(*let == '#') let++, allowall = TRUE;
     312:     if(*let == '-') let++, allownone = TRUE;
     313:     if(allownone) *bp++ = '-';
     314:     if(allowgold) *bp++ = '$';
     315:     if(bp > buf && bp[-1] == '-') *bp++ = ' ';
     316:
     317:     ilet = 'a';
     318:     for(otmp = invent; otmp; otmp = otmp->nobj){
     319:         if(!*let || index(let, otmp->olet)) {
     320:         bp[foo++] = flags.invlet_constant ? otmp->invlet : ilet;
     321:
     322:         /* ugly check: remove inappropriate things */
     323:         if((!strcmp(word, "take off") &&
     324:             !(otmp->owornmask & (W_ARMOR - W_ARM2)))
     325:         || (!strcmp(word, "wear") &&
     326:             (otmp->owornmask & (W_ARMOR | W_RING)))
     327:         || (!strcmp(word, "wield") &&
     328:             (otmp->owornmask & W_WEP))) {
     329:             foo--;
     330:             foox++;
     331:         }
     332:         }
     333:         if(ilet == 'z') ilet = 'A'; else ilet++;
     334:     }
     335:     bp[foo] = 0;
     336:     if(foo == 0 && bp > buf && bp[-1] == ' ') *--bp = 0;
     337:     (void) strcpy(lets, bp);    /* necessary since we destroy buf */
     338:     if(foo > 5) {           /* compactify string */
     339:         foo = foo2 = 1;
     340:         ilet2 = bp[0];
     341:         ilet1 = bp[1];
     342:         while(ilet = bp[++foo2] = bp[++foo]){
     343:             if(ilet == ilet1+1){
     344:                 if(ilet1 == ilet2+1)
     345:                     bp[foo2 - 1] = ilet1 = '-';
     346:                 else if(ilet2 == '-') {
     347:                     bp[--foo2] = ++ilet1;
     348:                     continue;
     349:                 }
     350:             }
     351:             ilet2 = ilet1;
     352:             ilet1 = ilet;
     353:         }
     354:     }
     355:     if(!foo && !allowall && !allowgold && !allownone) {
     356:         pline("You don't have anything %sto %s.",
     357:             foox ? "else " : "", word);
     358:         return(0);
     359:     }
     360:     for(;;) {
     361:         if(!buf[0])
     362:             pline("What do you want to %s [*]? ", word);
     363:         else
     364:             pline("What do you want to %s [%s or ?*]? ",
     365:                 word, buf);
     366:
     367:         cnt = 0;
     368:         ilet = readchar();
     369:         while(digit(ilet) && allowcnt) {
     370:             cnt = 10*cnt + (ilet - '0');
     371:             allowcnt = 2;   /* signal presence of cnt */
     372:             ilet = readchar();
     373:         }
     374:         if(digit(ilet)) {
     375:             pline("No count allowed with this command.");
     376:             continue;
     377:         }
     378:         if(index(quitchars,ilet))
     379:             return((struct obj *)0);
     380:         if(ilet == '-') {
     381:             return(allownone ? &zeroobj : (struct obj *) 0);
     382:         }
     383:         if(ilet == '$') {
     384:             if(!allowgold){
     385:                 pline("You cannot %s gold.", word);
     386:                 continue;
     387:             }
     388:             if(!(allowcnt == 2 && cnt < u.ugold))
     389:                 cnt = u.ugold;
     390:             return(mkgoldobj(cnt));
     391:         }
     392:         if(ilet == '?') {
     393:             doinv(lets);
     394:             if(!(ilet = morc)) continue;
     395:             /* he typed a letter (not a space) to more() */
     396:         } else if(ilet == '*') {
     397:             doinv((char *) 0);
     398:             if(!(ilet = morc)) continue;
     399:             /* ... */
     400:         }
     401:         if(flags.invlet_constant) {
     402:             for(otmp = invent; otmp; otmp = otmp->nobj)
     403:                 if(otmp->invlet == ilet) break;
     404:         } else {
     405:             if(ilet >= 'A' && ilet <= 'Z') ilet += 'z'-'A'+1;
     406:             ilet -= 'a';
     407:             for(otmp = invent; otmp && ilet;
     408:                     ilet--, otmp = otmp->nobj) ;
     409:         }
     410:         if(!otmp) {
     411:             pline("You don't have that object.");
     412:             continue;
     413:         }
     414:         if(cnt < 0 || otmp->quan < cnt) {
     415:             pline("You don't have that many! [You have %u]"
     416:             , otmp->quan);
     417:             continue;
     418:         }
     419:         break;
     420:     }
     421:     if(!allowall && let && !index(let,otmp->olet)) {
     422:         pline("That is a silly thing to %s.",word);
     423:         return(0);
     424:     }
     425:     if(allowcnt == 2) { /* cnt given */
     426:         if(cnt == 0) return(0);
     427:         if(cnt != otmp->quan) {
     428:             register struct obj *obj;
     429:             obj = splitobj(otmp, (int) cnt);
     430:             if(otmp == uwep) setuwep(obj);
     431:         }
     432:     }
     433:     return(otmp);
     434: }
     435:
     436: ckunpaid(otmp) register struct obj *otmp; {
     437:     return( otmp->unpaid );
     438: }
     439:
     440: /* interactive version of getobj - used for Drop and Identify */
     441: /* return the number of times fn was called successfully */
     442: ggetobj(word, fn, max)
     443: char *word;
     444: int (*fn)(),  max;
     445: {
     446: char buf[BUFSZ];
     447: register char *ip;
     448: register char sym;
     449: register int oletct = 0, iletct = 0;
     450: register boolean allflag = FALSE;
     451: char olets[20], ilets[20];
     452: int (*ckfn)() = (int (*)()) 0;
     453: xchar allowgold = (u.ugold && !strcmp(word, "drop")) ? 1 : 0;   /* BAH */
     454:     if(!invent && !allowgold){
     455:         pline("You have nothing to %s.", word);
     456:         return(0);
     457:     } else {
     458:         register struct obj *otmp = invent;
     459:         register int uflg = 0;
     460:
     461:         if(allowgold) ilets[iletct++] = '$';
     462:         ilets[iletct] = 0;
     463:         while(otmp) {
     464:             if(!index(ilets, otmp->olet)){
     465:                 ilets[iletct++] = otmp->olet;
     466:                 ilets[iletct] = 0;
     467:             }
     468:             if(otmp->unpaid) uflg = 1;
     469:             otmp = otmp->nobj;
     470:         }
     471:         ilets[iletct++] = ' ';
     472:         if(uflg) ilets[iletct++] = 'u';
     473:         if(invent) ilets[iletct++] = 'a';
     474:         ilets[iletct] = 0;
     475:     }
     476:     pline("What kinds of thing do you want to %s? [%s] ",
     477:         word, ilets);
     478:     getlin(buf);
     479:     if(buf[0] == '\033') {
     480:         clrlin();
     481:         return(0);
     482:     }
     483:     ip = buf;
     484:     olets[0] = 0;
     485:     while(sym = *ip++){
     486:         if(sym == ' ') continue;
     487:         if(sym == '$') {
     488:             if(allowgold == 1)
     489:                 (*fn)(mkgoldobj(u.ugold));
     490:             else if(!u.ugold)
     491:                 pline("You have no gold.");
     492:             allowgold = 2;
     493:         } else
     494:         if(sym == 'a' || sym == 'A') allflag = TRUE; else
     495:         if(sym == 'u' || sym == 'U') ckfn = ckunpaid; else
     496:         if(index("!%?[()=*/\"0", sym)){
     497:             if(!index(olets, sym)){
     498:                 olets[oletct++] = sym;
     499:                 olets[oletct] = 0;
     500:             }
     501:         }
     502:         else pline("You don't have any %c's.", sym);
     503:     }
     504:     if(allowgold == 2 && !oletct)
     505:         return(1);  /* he dropped gold (or at least tried to) */
     506:     else
     507:         return(askchain(invent, olets, allflag, fn, ckfn, max));
     508: }
     509:
     510: /*
     511:  * Walk through the chain starting at objchn and ask for all objects
     512:  * with olet in olets (if nonNULL) and satisfying ckfn (if nonNULL)
     513:  * whether the action in question (i.e., fn) has to be performed.
     514:  * If allflag then no questions are asked. Max gives the max nr of
     515:  * objects to be treated. Return the number of objects treated.
     516:  */
     517: askchain(objchn, olets, allflag, fn, ckfn, max)
     518: struct obj *objchn;
     519: register char *olets;
     520: int allflag;
     521: int (*fn)(), (*ckfn)();
     522: int max;
     523: {
     524: register struct obj *otmp, *otmp2;
     525: register char sym, ilet;
     526: register int cnt = 0;
     527:     ilet = 'a'-1;
     528:     for(otmp = objchn; otmp; otmp = otmp2){
     529:         if(ilet == 'z') ilet = 'A'; else ilet++;
     530:         otmp2 = otmp->nobj;
     531:         if(olets && *olets && !index(olets, otmp->olet)) continue;
     532:         if(ckfn && !(*ckfn)(otmp)) continue;
     533:         if(!allflag) {
     534:             pline(xprname(otmp, ilet));
     535:             addtopl(" [nyaq]? ");
     536:             sym = readchar();
     537:         }
     538:         else    sym = 'y';
     539:
     540:         switch(sym){
     541:         case 'a':
     542:             allflag = 1;
     543:         case 'y':
     544:             cnt += (*fn)(otmp);
     545:             if(--max == 0) goto ret;
     546:         case 'n':
     547:         default:
     548:             break;
     549:         case 'q':
     550:             goto ret;
     551:         }
     552:     }
     553:     pline(cnt ? "That was all." : "No applicable objects.");
     554: ret:
     555:     return(cnt);
     556: }
     557:
     558: obj_to_let(obj) /* should of course only be called for things in invent */
     559: register struct obj *obj;
     560: {
     561:     register struct obj *otmp;
     562:     register char ilet;
     563:
     564:     if(flags.invlet_constant)
     565:         return(obj->invlet);
     566:     ilet = 'a';
     567:     for(otmp = invent; otmp && otmp != obj; otmp = otmp->nobj)
     568:         if(++ilet > 'z') ilet = 'A';
     569:     return(otmp ? ilet : NOINVSYM);
     570: }
     571:
     572: prinv(obj)
     573: register struct obj *obj;
     574: {
     575:     pline(xprname(obj, obj_to_let(obj)));
     576: }
     577:
     578: static char *
     579: xprname(obj,let)
     580: register struct obj *obj;
     581: register char let;
     582: {
     583:     static char li[BUFSZ];
     584:
     585:     (void) sprintf(li, "%c - %s.",
     586:         flags.invlet_constant ? obj->invlet : let,
     587:         doname(obj));
     588:     return(li);
     589: }
     590:
     591: ddoinv()
     592: {
     593:     doinv((char *) 0);
     594:     return(0);
     595: }
     596:
     597: /* called with 0 or "": all objects in inventory */
     598: /* otherwise: all objects with (serial) letter in lets */
     599: doinv(lets)
     600: register char *lets;
     601: {
     602:     register struct obj *otmp;
     603:     register char ilet;
     604:     int ct = 0;
     605:     char any[BUFSZ];
     606:
     607:     morc = 0;       /* just to be sure */
     608:
     609:     if(!invent){
     610:         pline("Not carrying anything.");
     611:         return;
     612:     }
     613:
     614:     cornline(0, (char *) 0);
     615:     ilet = 'a';
     616:     for(otmp = invent; otmp; otmp = otmp->nobj) {
     617:         if(flags.invlet_constant) ilet = otmp->invlet;
     618:         if(!lets || !*lets || index(lets, ilet)) {
     619:             cornline(1, xprname(otmp, ilet));
     620:             any[ct++] = ilet;
     621:         }
     622:         if(!flags.invlet_constant) if(++ilet > 'z') ilet = 'A';
     623:     }
     624:     any[ct] = 0;
     625:     cornline(2, any);
     626: }
     627:
     628: dotypeinv ()                /* free after Robert Viduya */
     629: /* Changed to one type only, so he doesnt have to type cr */
     630: {
     631:     char c, ilet;
     632:     char stuff[BUFSZ];
     633:     register int stct;
     634:     register struct obj *otmp;
     635:     boolean billx = inshop() && doinvbill(0);
     636:     boolean unpd = FALSE;
     637:
     638:     if (!invent && !u.ugold && !billx) {
     639:         pline ("You aren't carrying anything.");
     640:         return(0);
     641:     }
     642:
     643:     stct = 0;
     644:     if(u.ugold) stuff[stct++] = '$';
     645:     stuff[stct] = 0;
     646:     for(otmp = invent; otmp; otmp = otmp->nobj) {
     647:         if (!index (stuff, otmp->olet)) {
     648:         stuff[stct++] = otmp->olet;
     649:         stuff[stct] = 0;
     650:         }
     651:         if(otmp->unpaid)
     652:         unpd = TRUE;
     653:     }
     654:     if(unpd) stuff[stct++] = 'u';
     655:     if(billx) stuff[stct++] = 'x';
     656:     stuff[stct] = 0;
     657:
     658:     if(stct > 1) {
     659:         pline ("What type of object [%s] do you want an inventory of? ",
     660:         stuff);
     661:         c = readchar();
     662:         if(index(quitchars,c)) return(0);
     663:     } else
     664:         c = stuff[0];
     665:
     666:     if(c == '$')
     667:         return(doprgold());
     668:
     669:     if(c == 'x' || c == 'X') {
     670:         if(billx)
     671:         (void) doinvbill(1);
     672:         else
     673:         pline("No used-up objects on the shopping bill.");
     674:         return(0);
     675:     }
     676:
     677:     if((c == 'u' || c == 'U') && !unpd) {
     678:         pline("You are not carrying any unpaid objects.");
     679:         return(0);
     680:     }
     681:
     682:     stct = 0;
     683:     ilet = 'a';
     684:     for (otmp = invent; otmp; otmp = otmp -> nobj) {
     685:         if(flags.invlet_constant) ilet = otmp->invlet;
     686:         if (c == otmp -> olet || (c == 'u' && otmp -> unpaid))
     687:         stuff[stct++] = ilet;
     688:         if(!flags.invlet_constant) if(++ilet > 'z') ilet = 'A';
     689:     }
     690:     stuff[stct] = '\0';
     691:     if(stct == 0)
     692:         pline("You have no such objects.");
     693:     else
     694:         doinv (stuff);
     695:
     696:     return(0);
     697: }
     698:
     699: /* look at what is here */
     700: dolook() {
     701:     register struct obj *otmp, *otmp0;
     702:     register struct gold *gold;
     703:     char *verb = Blind ? "feel" : "see";
     704:     int ct = 0;
     705:
     706:     if(!u.uswallow) {
     707:     if(Blind) {
     708:         pline("You try to feel what is lying here on the floor.");
     709:         if(Levitation) {                /* ab@unido */
     710:         pline("You cannot reach the floor!");
     711:         return(1);
     712:         }
     713:     }
     714:     otmp0 = o_at(u.ux, u.uy);
     715:     gold = g_at(u.ux, u.uy);
     716:     }
     717:
     718:     if(u.uswallow || (!otmp0 && !gold)) {
     719:     pline("You %s no objects here.", verb);
     720:     return(!!Blind);
     721:     }
     722:
     723:     cornline(0, "Things that are here:");
     724:     for(otmp = otmp0; otmp; otmp = otmp->nobj) {
     725:     if(otmp->ox == u.ux && otmp->oy == u.uy) {
     726:         ct++;
     727:         cornline(1, doname(otmp));
     728:         if(Blind && otmp->otyp == DEAD_COCKATRICE && !uarmg) {
     729:         pline("Touching the dead cockatrice is a fatal mistake ...");
     730:         pline("You die ...");
     731:         killer = "dead cockatrice";
     732:         done("died");
     733:         }
     734:     }
     735:     }
     736:
     737:     if(gold) {
     738:     char gbuf[30];
     739:
     740:     (void) sprintf(gbuf, "%ld gold piece%s",
     741:         gold->amount, plur(gold->amount));
     742:     if(!ct++)
     743:         pline("You %s here %s.", verb, gbuf);
     744:     else
     745:         cornline(1, gbuf);
     746:     }
     747:
     748:     if(ct == 1 && !gold) {
     749:     pline("You %s here %s.", verb, doname(otmp0));
     750:     cornline(3, (char *) 0);
     751:     }
     752:     if(ct > 1)
     753:     cornline(2, (char *) 0);
     754:     return(!!Blind);
     755: }
     756:
     757: stackobj(obj) register struct obj *obj; {
     758: register struct obj *otmp = fobj;
     759:     for(otmp = fobj; otmp; otmp = otmp->nobj) if(otmp != obj)
     760:     if(otmp->ox == obj->ox && otmp->oy == obj->oy &&
     761:         merged(obj,otmp,1))
     762:             return;
     763: }
     764:
     765: /* merge obj with otmp and delete obj if types agree */
     766: merged(otmp,obj,lose) register struct obj *otmp, *obj; {
     767:     if(obj->otyp == otmp->otyp &&
     768:       obj->unpaid == otmp->unpaid &&
     769:       obj->spe == otmp->spe &&
     770:       obj->dknown == otmp->dknown &&
     771:       obj->cursed == otmp->cursed &&
     772:       (index("%*?!", obj->olet) ||
     773:         (obj->known == otmp->known &&
     774:         (obj->olet == WEAPON_SYM && obj->otyp < BOOMERANG)))) {
     775:         otmp->quan += obj->quan;
     776:         otmp->owt += obj->owt;
     777:         if(lose) freeobj(obj);
     778:         obfree(obj,otmp);   /* free(obj), bill->otmp */
     779:         return(1);
     780:     } else  return(0);
     781: }
     782:
     783: /*
     784:  * Gold is no longer displayed; in fact, when you have a lot of money,
     785:  * it may take a while before you have counted it all.
     786:  * [Bug: d$ and pickup still tell you how much it was.]
     787:  */
     788: extern int (*occupation)();
     789: extern char *occtxt;
     790: static long goldcounted;
     791:
     792: countgold(){
     793:     if((goldcounted += 100*(u.ulevel + 1)) >= u.ugold) {
     794:         long eps = 0;
     795:         if(!rn2(2)) eps = rnd((int) (u.ugold/100 + 1));
     796:         pline("You probably have about %ld gold pieces.",
     797:             u.ugold + eps);
     798:         return(0);  /* done */
     799:     }
     800:     return(1);      /* continue */
     801: }
     802:
     803: doprgold(){
     804:     if(!u.ugold)
     805:         pline("You do not carry any gold.");
     806:     else if(u.ugold <= 500)
     807:         pline("You are carrying %ld gold pieces.", u.ugold);
     808:     else {
     809:         pline("You sit down in order to count your gold pieces.");
     810:         goldcounted = 500;
     811:         occupation = countgold;
     812:         occtxt = "counting your gold";
     813:     }
     814:     return(1);
     815: }
     816:
     817: /* --- end of gold counting section --- */
     818:
     819: doprwep(){
     820:     if(!uwep) pline("You are empty handed.");
     821:     else prinv(uwep);
     822:     return(0);
     823: }
     824:
     825: doprarm(){
     826:     if(!uarm && !uarmg && !uarms && !uarmh)
     827:         pline("You are not wearing any armor.");
     828:     else {
     829:         char lets[6];
     830:         register int ct = 0;
     831:
     832:         if(uarm) lets[ct++] = obj_to_let(uarm);
     833:         if(uarm2) lets[ct++] = obj_to_let(uarm2);
     834:         if(uarmh) lets[ct++] = obj_to_let(uarmh);
     835:         if(uarms) lets[ct++] = obj_to_let(uarms);
     836:         if(uarmg) lets[ct++] = obj_to_let(uarmg);
     837:         lets[ct] = 0;
     838:         doinv(lets);
     839:     }
     840:     return(0);
     841: }
     842:
     843: doprring(){
     844:     if(!uleft && !uright)
     845:         pline("You are not wearing any rings.");
     846:     else {
     847:         char lets[3];
     848:         register int ct = 0;
     849:
     850:         if(uleft) lets[ct++] = obj_to_let(uleft);
     851:         if(uright) lets[ct++] = obj_to_let(uright);
     852:         lets[ct] = 0;
     853:         doinv(lets);
     854:     }
     855:     return(0);
     856: }
     857:
     858: digit(c) char c; {
     859:     return(c >= '0' && c <= '9');
     860: }

#### Defined functions

addinv defined in line 47; used 14 times

- in /usr/src/games/hack/hack.apply.c line 8, 165
- in /usr/src/games/hack/hack.c line 10, 454
- in /usr/src/games/hack/hack.do.c line 8, 318
- in /usr/src/games/hack/hack.eat.c line 10, 107
- in /usr/src/games/hack/hack.u_init.c line 11, 272
- in /usr/src/games/hack/hack.unix.c line 327, 346
- in /usr/src/games/hack/hack.zap.c line 166, 175

askchain defined in line 517; used 2 times

- in line 507
- in /usr/src/games/hack/hack.apply.c line 180

assigninvlet defined in line 20; used 1 times

- in line 69

carried defined in line 219; used 4 times

- in /usr/src/games/hack/hack.c line 225
- in /usr/src/games/hack/hack.eat.c line 54
- in /usr/src/games/hack/hack.trap.c line 366, 374

carrying defined in line 226; used 7 times

- in /usr/src/games/hack/hack.apply.c line 42
- in /usr/src/games/hack/hack.mhitu.c line 121
- in /usr/src/games/hack/hack.shk.c line 207-208(2), 855(2)
- in /usr/src/games/hack/hack.wizard.c line 48

ckunpaid defined in line 436; used 1 times

- in line 495

countgold defined in line 792; used 1 times

- in line 811

ddoinv defined in line 591; used 2 times

- in /usr/src/games/hack/hack.cmd.c line 9, 40

delobj defined in line 123; used 8 times

- in /usr/src/games/hack/hack.c line 174-179(2), 188, 400
- in /usr/src/games/hack/hack.dog.c line 321
- in /usr/src/games/hack/hack.pri.c line 516
- in /usr/src/games/hack/hack.zap.c line 85, 589

deltrap defined in line 154; used 5 times

- in /usr/src/games/hack/hack.c line 173
- in /usr/src/games/hack/hack.search.c line 36, 87
- in /usr/src/games/hack/hack.trap.c line 62, 112

digit defined in line 858; used 2 times

- in line 369-374(2)

doinv defined in line 599; used 6 times

- in line 393-397(2), 593, 694, 838, 853

dolook defined in line 700; used 2 times

- in /usr/src/games/hack/hack.cmd.c line 11, 73

doprarm defined in line 825; used 2 times

- in /usr/src/games/hack/hack.cmd.c line 10, 77

doprgold defined in line 803; used 3 times

- in line 667
- in /usr/src/games/hack/hack.cmd.c line 11, 79

doprring defined in line 843; used 3 times

- in /usr/src/games/hack/hack.cmd.c line 11, 78
- in /usr/src/games/hack/hack.do_wear.c line 61

doprwep defined in line 819; used 2 times

- in /usr/src/games/hack/hack.cmd.c line 10, 76

dotypeinv defined in line 628; used 2 times

- in /usr/src/games/hack/hack.cmd.c line 11, 39

freegold defined in line 142; used 3 times

- in /usr/src/games/hack/hack.c line 346
- in /usr/src/games/hack/hack.mon.c line 459
- in /usr/src/games/hack/hack.steal.c line 17

freeinv defined in line 108; used 10 times

- in line 103
- in /usr/src/games/hack/hack.apply.c line 133
- in /usr/src/games/hack/hack.do.c line 60, 282
- in /usr/src/games/hack/hack.fight.c line 161, 175
- in /usr/src/games/hack/hack.shk.c line 971
- in /usr/src/games/hack/hack.steal.c line 47, 145, 168

freeobj defined in line 130; used 14 times

- in line 124, 777
- in /usr/src/games/hack/hack.c line 314, 447
- in /usr/src/games/hack/hack.do.c line 413
- in /usr/src/games/hack/hack.dog.c line 171
- in /usr/src/games/hack/hack.eat.c line 106
- in /usr/src/games/hack/hack.mon.c line 471
- in /usr/src/games/hack/hack.read.c line 133
- in /usr/src/games/hack/hack.shk.c line 933
- in /usr/src/games/hack/hack.steal.c line 139
- in /usr/src/games/hack/hack.trap.c line 375-378(2)
- in /usr/src/games/hack/hack.wizard.c line 59

g_at defined in line 258; used 11 times

- in line 715
- in /usr/src/games/hack/def.gen.h line 14
- in /usr/src/games/hack/def.gold.h line 11
- in /usr/src/games/hack/hack.c line 323, 342
- in /usr/src/games/hack/hack.mkobj.c line 138
- in /usr/src/games/hack/hack.mon.c line 457
- in /usr/src/games/hack/hack.pri.c line 323, 346
- in /usr/src/games/hack/hack.steal.c line 13
- in /usr/src/games/hack/hack.vault.c line 65

getobj defined in line 292; used 18 times

- in /usr/src/games/hack/hack.apply.c line 19, 186
- in /usr/src/games/hack/hack.do.c line 16, 259
- in /usr/src/games/hack/hack.do_name.c line 145-149(2)
- in /usr/src/games/hack/hack.do_wear.c line 24, 114, 176
- in /usr/src/games/hack/hack.eat.c line 113
- in /usr/src/games/hack/hack.engrave.c line 139
- in /usr/src/games/hack/hack.h line 52
- in /usr/src/games/hack/hack.potion.c line 15, 359-361(2)
- in /usr/src/games/hack/hack.read.c line 15
- in /usr/src/games/hack/hack.wield.c line 17
- in /usr/src/games/hack/hack.zap.c line 126

ggetobj defined in line 442; used 2 times

- in /usr/src/games/hack/hack.do.c line 80
- in /usr/src/games/hack/hack.read.c line 323

m_at defined in line 170; used 32 times

- in /usr/src/games/hack/def.monst.h line 52
- in /usr/src/games/hack/hack.apply.c line 201, 398
- in /usr/src/games/hack/hack.c line 128, 164, 483, 568
- in /usr/src/games/hack/hack.do.c line 208, 217, 232
- in /usr/src/games/hack/hack.do_name.c line 57
- in /usr/src/games/hack/hack.dog.c line 274
- in /usr/src/games/hack/hack.main.c line 271
- in /usr/src/games/hack/hack.makemon.c line 26, 155
- in /usr/src/games/hack/hack.mklev.c line 710
- in /usr/src/games/hack/hack.mkshop.c line 125, 223
- in /usr/src/games/hack/hack.mon.c line 417, 510
- in /usr/src/games/hack/hack.pri.c line 307, 474
- in /usr/src/games/hack/hack.read.c line 176
- in /usr/src/games/hack/hack.search.c line 43, 76
- in /usr/src/games/hack/hack.shk.c line 921
- in /usr/src/games/hack/hack.trap.c line 329
- in /usr/src/games/hack/hack.vault.c line 46
- in /usr/src/games/hack/hack.wizard.c line 54
- in /usr/src/games/hack/hack.zap.c line 315, 361, 458

merged defined in line 766; used 2 times

- in line 59, 761

mkgoldobj defined in line 271; used 2 times

- in line 390, 489

o_at defined in line 196; used 13 times

- in line 714
- in /usr/src/games/hack/hack.c line 323
- in /usr/src/games/hack/hack.dog.c line 162
- in /usr/src/games/hack/hack.fight.c line 288
- in /usr/src/games/hack/hack.h line 52
- in /usr/src/games/hack/hack.mhitu.c line 334
- in /usr/src/games/hack/hack.mkshop.c line 222
- in /usr/src/games/hack/hack.mon.c line 261, 844
- in /usr/src/games/hack/hack.pri.c line 316, 345
- in /usr/src/games/hack/hack.zap.c line 142, 323

o_on defined in line 237; used 7 times

- in /usr/src/games/hack/hack.shk.c line 35, 494-502(6)

obj_to_let defined in line 558; used 8 times

- in line 575, 832-836(5), 850-851(2)

prinv defined in line 572; used 6 times

- in line 821
- in /usr/src/games/hack/hack.c line 457
- in /usr/src/games/hack/hack.do_wear.c line 232
- in /usr/src/games/hack/hack.read.c line 443
- in /usr/src/games/hack/hack.wield.c line 42
- in /usr/src/games/hack/hack.zap.c line 176

sobj_at defined in line 207; used 13 times

- in /usr/src/games/hack/hack.apply.c line 291, 380, 409
- in /usr/src/games/hack/hack.c line 157, 163
- in /usr/src/games/hack/hack.h line 52
- in /usr/src/games/hack/hack.makemon.c line 157
- in /usr/src/games/hack/hack.mon.c line 211, 518-527(3)
- in /usr/src/games/hack/hack.shk.c line 901
- in /usr/src/games/hack/hack.trap.c line 330

stackobj defined in line 757; used 9 times

- in /usr/src/games/hack/hack.do.c line 75, 410
- in /usr/src/games/hack/hack.fight.c line 78
- in /usr/src/games/hack/hack.mon.c line 746-751(2), 762
- in /usr/src/games/hack/hack.steal.c line 190
- in /usr/src/games/hack/hack.trap.c line 85
- in /usr/src/games/hack/hack.zap.c line 206

t_at defined in line 246; used 14 times

- in /usr/src/games/hack/def.trap.h line 13
- in /usr/src/games/hack/hack.apply.c line 274, 328
- in /usr/src/games/hack/hack.c line 113, 169
- in /usr/src/games/hack/hack.dog.c line 288
- in /usr/src/games/hack/hack.mklev.c line 734
- in /usr/src/games/hack/hack.mkshop.c line 222
- in /usr/src/games/hack/hack.mon.c line 536
- in /usr/src/games/hack/hack.pri.c line 349
- in /usr/src/games/hack/hack.search.c line 32
- in /usr/src/games/hack/hack.trap.c line 139, 252, 330

useup defined in line 95; used 14 times

- in /usr/src/games/hack/hack.eat.c line 64, 257
- in /usr/src/games/hack/hack.potion.c line 187, 218, 367
- in /usr/src/games/hack/hack.pri.c line 522
- in /usr/src/games/hack/hack.read.c line 50, 73-79(3), 319, 434
- in /usr/src/games/hack/hack.wield.c line 89
- in /usr/src/games/hack/hack.zap.c line 632

xprname defined in line 578; used 4 times

- in line 10, 534, 575, 619

#### Defined variables

goldcounted defined in line 790; used 2 times

- in line 793, 810

lastinvnr defined in line 19; used 3 times

- in line 38(2), 44

m_atseg defined in line 168; used 4 times

- in line 179, 187
- in /usr/src/games/hack/hack.pri.c line 310-311(2)

#### Defined macros

NOINVSYM defined in line 17; used 2 times

- in line 42, 569

Last modified: 1985-10-01 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 2816 |