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

askchain defined in line 517; used 2 times
assigninvlet defined in line 20; used 1 times
  • in line 69
ckunpaid defined in line 436; used 1 times
countgold defined in line 792; used 1 times
ddoinv defined in line 591; used 2 times
digit defined in line 858; used 2 times
doinv defined in line 599; used 6 times
dolook defined in line 700; used 2 times
doprarm defined in line 825; used 2 times
doprgold defined in line 803; used 3 times
doprring defined in line 843; used 3 times
doprwep defined in line 819; used 2 times
dotypeinv defined in line 628; used 2 times
ggetobj defined in line 442; used 2 times
merged defined in line 766; used 2 times
mkgoldobj defined in line 271; used 2 times
o_on defined in line 237; used 7 times
obj_to_let defined in line 558; used 8 times
xprname defined in line 578; used 4 times

Defined variables

goldcounted defined in line 790; used 2 times
lastinvnr defined in line 19; used 3 times
m_atseg defined in line 168; used 4 times

Defined macros

NOINVSYM defined in line 17; used 2 times
Last modified: 1985-10-01
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 5637
Valid CSS Valid XHTML 1.0 Strict