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