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