invent.c (20360B)
1 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 2 /* invent.c - version 1.0.3 */ 3 4 #include <stdio.h> 5 #include "hack.h" 6 extern struct obj *splitobj(); 7 extern struct obj zeroobj; 8 extern char morc; 9 extern char quitchars[]; 10 static char *xprname(); 11 12 #ifndef NOWORM 13 #include "wseg.h" 14 extern struct wseg *wsegs[32]; 15 #endif /* NOWORM /**/ 16 17 #define NOINVSYM '#' 18 19 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 #ifdef REDO 363 if (!in_doagain) 364 #endif 365 pline("What do you want to %s [*]? ", word); 366 } else { 367 #ifdef REDO 368 if (!in_doagain) 369 #endif 370 pline("What do you want to %s [%s or ?*]? ", 371 word, buf); 372 } 373 374 375 cnt = 0; 376 ilet = readchar(); 377 while(digit(ilet) && allowcnt) { 378 #ifdef REDO 379 if (ilet != '?' && ilet != '*') 380 savech(ilet); 381 #endif 382 cnt = 10*cnt + (ilet - '0'); 383 allowcnt = 2; /* signal presence of cnt */ 384 ilet = readchar(); 385 } 386 if(digit(ilet)) { 387 pline("No count allowed with this command."); 388 continue; 389 } 390 if(index(quitchars,ilet)) 391 return((struct obj *)0); 392 if(ilet == '-') { 393 return(allownone ? &zeroobj : (struct obj *) 0); 394 } 395 if(ilet == '$') { 396 if(!allowgold){ 397 pline("You cannot %s gold.", word); 398 continue; 399 } 400 if(!(allowcnt == 2 && cnt < u.ugold)) 401 cnt = u.ugold; 402 return(mkgoldobj(cnt)); 403 } 404 if(ilet == '?') { 405 doinv(lets); 406 if(!(ilet = morc)) continue; 407 /* he typed a letter (not a space) to more() */ 408 } else if(ilet == '*') { 409 doinv((char *) 0); 410 if(!(ilet = morc)) continue; 411 /* ... */ 412 } 413 #ifdef REDO 414 if (ilet != '?' && ilet != '*') 415 savech(ilet); 416 #endif 417 if(flags.invlet_constant) { 418 for(otmp = invent; otmp; otmp = otmp->nobj) 419 if(otmp->invlet == ilet) break; 420 } else { 421 if(ilet >= 'A' && ilet <= 'Z') ilet += 'z'-'A'+1; 422 ilet -= 'a'; 423 for(otmp = invent; otmp && ilet; 424 ilet--, otmp = otmp->nobj) ; 425 } 426 if(!otmp) { 427 pline("You don't have that object."); 428 continue; 429 } 430 if(cnt < 0 || otmp->quan < cnt) { 431 pline("You don't have that many! [You have %u]" 432 , otmp->quan); 433 continue; 434 } 435 break; 436 } 437 if(!allowall && let && !index(let,otmp->olet)) { 438 pline("That is a silly thing to %s.",word); 439 return(0); 440 } 441 if(allowcnt == 2) { /* cnt given */ 442 if(cnt == 0) return(0); 443 if(cnt != otmp->quan) { 444 register struct obj *obj; 445 obj = splitobj(otmp, (int) cnt); 446 if(otmp == uwep) setuwep(obj); 447 } 448 } 449 return(otmp); 450 } 451 452 ckunpaid(otmp) register struct obj *otmp; { 453 return( otmp->unpaid ); 454 } 455 456 /* interactive version of getobj - used for Drop and Identify */ 457 /* return the number of times fn was called successfully */ 458 ggetobj(word, fn, max) 459 char *word; 460 int (*fn)(), max; 461 { 462 char buf[BUFSZ]; 463 register char *ip; 464 register char sym; 465 register int oletct = 0, iletct = 0; 466 register boolean allflag = FALSE; 467 char olets[20], ilets[20]; 468 int (*ckfn)() = (int (*)()) 0; 469 xchar allowgold = (u.ugold && !strcmp(word, "drop")) ? 1 : 0; /* BAH */ 470 if(!invent && !allowgold){ 471 pline("You have nothing to %s.", word); 472 return(0); 473 } else { 474 register struct obj *otmp = invent; 475 register int uflg = 0; 476 477 if(allowgold) ilets[iletct++] = '$'; 478 ilets[iletct] = 0; 479 while(otmp) { 480 if(!index(ilets, otmp->olet)){ 481 ilets[iletct++] = otmp->olet; 482 ilets[iletct] = 0; 483 } 484 if(otmp->unpaid) uflg = 1; 485 otmp = otmp->nobj; 486 } 487 ilets[iletct++] = ' '; 488 if(uflg) ilets[iletct++] = 'u'; 489 if(invent) ilets[iletct++] = 'a'; 490 ilets[iletct] = 0; 491 } 492 pline("What kinds of thing do you want to %s? [%s] ", 493 word, ilets); 494 getlin(buf); 495 if(buf[0] == '\033') { 496 clrlin(); 497 return(0); 498 } 499 ip = buf; 500 olets[0] = 0; 501 while(sym = *ip++){ 502 if(sym == ' ') continue; 503 if(sym == '$') { 504 if(allowgold == 1) 505 (*fn)(mkgoldobj(u.ugold)); 506 else if(!u.ugold) 507 pline("You have no gold."); 508 allowgold = 2; 509 } else 510 if(sym == 'a' || sym == 'A') allflag = TRUE; else 511 if(sym == 'u' || sym == 'U') ckfn = ckunpaid; else 512 if(index("!%?[()=*/\"0", sym)){ 513 if(!index(olets, sym)){ 514 olets[oletct++] = sym; 515 olets[oletct] = 0; 516 } 517 } 518 else pline("You don't have any %c's.", sym); 519 } 520 if(allowgold == 2 && !oletct) 521 return(1); /* he dropped gold (or at least tried to) */ 522 else 523 return(askchain(invent, olets, allflag, fn, ckfn, max)); 524 } 525 526 /* 527 * Walk through the chain starting at objchn and ask for all objects 528 * with olet in olets (if nonNULL) and satisfying ckfn (if nonNULL) 529 * whether the action in question (i.e., fn) has to be performed. 530 * If allflag then no questions are asked. Max gives the max nr of 531 * objects to be treated. Return the number of objects treated. 532 */ 533 askchain(objchn, olets, allflag, fn, ckfn, max) 534 struct obj *objchn; 535 register char *olets; 536 int allflag; 537 int (*fn)(), (*ckfn)(); 538 int max; 539 { 540 register struct obj *otmp, *otmp2; 541 register char sym, ilet; 542 register int cnt = 0; 543 #ifdef DGK 544 /* changes so the askchain is interrogated in the order specified. 545 * For example, if a person specifies =/ then first all rings will be 546 * asked about followed by all wands -dgk 547 */ 548 nextclass: 549 #endif 550 ilet = 'a'-1; 551 for(otmp = objchn; otmp; otmp = otmp2){ 552 if(ilet == 'z') ilet = 'A'; else ilet++; 553 otmp2 = otmp->nobj; 554 #ifdef DGK 555 if (olets && *olets && otmp->olet != *olets) continue; 556 #else 557 if(olets && *olets && !index(olets, otmp->olet)) continue; 558 #endif 559 if(ckfn && !(*ckfn)(otmp)) continue; 560 if(!allflag) { 561 pline(xprname(otmp, ilet)); 562 addtopl(" [nyaq]? "); 563 sym = readchar(); 564 } 565 else sym = 'y'; 566 567 switch(sym){ 568 case 'a': 569 allflag = 1; 570 case 'y': 571 cnt += (*fn)(otmp); 572 if(--max == 0) goto ret; 573 case 'n': 574 default: 575 break; 576 case 'q': 577 goto ret; 578 } 579 } 580 #ifdef DGK 581 if (olets && *olets && *++olets) 582 goto nextclass; 583 #endif 584 pline(cnt ? "That was all." : "No applicable objects."); 585 ret: 586 return(cnt); 587 } 588 589 obj_to_let(obj) /* should of course only be called for things in invent */ 590 register struct obj *obj; 591 { 592 register struct obj *otmp; 593 register char ilet; 594 595 if(flags.invlet_constant) 596 return(obj->invlet); 597 ilet = 'a'; 598 for(otmp = invent; otmp && otmp != obj; otmp = otmp->nobj) 599 if(++ilet > 'z') ilet = 'A'; 600 return(otmp ? ilet : NOINVSYM); 601 } 602 603 prinv(obj) 604 register struct obj *obj; 605 { 606 pline(xprname(obj, obj_to_let(obj))); 607 } 608 609 static char * 610 xprname(obj,let) 611 register struct obj *obj; 612 register char let; 613 { 614 static char li[BUFSZ]; 615 616 (void) sprintf(li, "%c - %s.", 617 flags.invlet_constant ? obj->invlet : let, 618 doname(obj)); 619 return(li); 620 } 621 622 ddoinv() 623 { 624 doinv((char *) 0); 625 return(0); 626 } 627 628 #ifdef DGK 629 char inv_order[] = "\")[%?/=!(*0_`"; /* to be safe, include _ and ` */ 630 extern char *let_to_name(); 631 #endif 632 633 /* called with 0 or "": all objects in inventory */ 634 /* otherwise: all objects with (serial) letter in lets */ 635 doinv(lets) 636 register char *lets; 637 { 638 register struct obj *otmp; 639 register char ilet; 640 int ct = 0; 641 char any[BUFSZ]; 642 #ifdef DGK 643 char *invlet = inv_order; 644 int classcount = 0; 645 #endif /* DGK /**/ 646 647 morc = 0; /* just to be sure */ 648 649 if(!invent){ 650 pline("Not carrying anything."); 651 return; 652 } 653 654 cornline(0, (char *) 0); 655 #ifdef DGK 656 nextclass: 657 classcount = 0; 658 ilet = 'a'; 659 for(otmp = invent; otmp; otmp = otmp->nobj) { 660 if(flags.invlet_constant) ilet = otmp->invlet; 661 if(!lets || !*lets || index(lets, ilet)) { 662 if (!flags.sortpack || otmp->olet == *invlet) { 663 if (flags.sortpack && !classcount) { 664 cornline(1, let_to_name(*invlet)); 665 classcount++; 666 } 667 cornline(1, xprname(otmp, ilet)); 668 any[ct++] = ilet; 669 } 670 } 671 if(!flags.invlet_constant) if(++ilet > 'z') ilet = 'A'; 672 } 673 if (flags.sortpack && *++invlet) goto nextclass; 674 #else 675 ilet = 'a'; 676 for(otmp = invent; otmp; otmp = otmp->nobj) { 677 if(flags.invlet_constant) ilet = otmp->invlet; 678 if(!lets || !*lets || index(lets, ilet)) { 679 cornline(1, xprname(otmp, ilet)); 680 any[ct++] = ilet; 681 } 682 if(!flags.invlet_constant) if(++ilet > 'z') ilet = 'A'; 683 } 684 #endif /* DGK /**/ 685 any[ct] = 0; 686 cornline(2, any); 687 } 688 689 dotypeinv () /* free after Robert Viduya */ 690 /* Changed to one type only, so he doesnt have to type cr */ 691 { 692 char c, ilet; 693 char stuff[BUFSZ]; 694 register int stct; 695 register struct obj *otmp; 696 boolean billx = inshop() && doinvbill(0); 697 boolean unpd = FALSE; 698 699 if (!invent && !u.ugold && !billx) { 700 pline ("You aren't carrying anything."); 701 return(0); 702 } 703 704 stct = 0; 705 if(u.ugold) stuff[stct++] = '$'; 706 stuff[stct] = 0; 707 for(otmp = invent; otmp; otmp = otmp->nobj) { 708 if (!index (stuff, otmp->olet)) { 709 stuff[stct++] = otmp->olet; 710 stuff[stct] = 0; 711 } 712 if(otmp->unpaid) 713 unpd = TRUE; 714 } 715 if(unpd) stuff[stct++] = 'u'; 716 if(billx) stuff[stct++] = 'x'; 717 stuff[stct] = 0; 718 719 if(stct > 1) { 720 #ifdef REDO 721 if (!in_doagain) 722 #endif 723 pline ("What type of object [%s] do you want an inventory of? ", 724 stuff); 725 c = readchar(); 726 #ifdef REDO 727 savech(c); 728 #endif 729 if(index(quitchars,c)) return(0); 730 } else 731 c = stuff[0]; 732 733 if(c == '$') 734 return(doprgold()); 735 736 if(c == 'x' || c == 'X') { 737 if(billx) 738 (void) doinvbill(1); 739 else 740 pline("No used-up objects on the shopping bill."); 741 return(0); 742 } 743 744 if((c == 'u' || c == 'U') && !unpd) { 745 pline("You are not carrying any unpaid objects."); 746 return(0); 747 } 748 749 stct = 0; 750 ilet = 'a'; 751 for (otmp = invent; otmp; otmp = otmp -> nobj) { 752 if(flags.invlet_constant) ilet = otmp->invlet; 753 if (c == otmp -> olet || (c == 'u' && otmp -> unpaid)) 754 stuff[stct++] = ilet; 755 if(!flags.invlet_constant) if(++ilet > 'z') ilet = 'A'; 756 } 757 stuff[stct] = '\0'; 758 if(stct == 0) 759 pline("You have no such objects."); 760 else 761 doinv (stuff); 762 763 return(0); 764 } 765 766 /* look at what is here */ 767 dolook() { 768 register struct obj *otmp, *otmp0; 769 register struct gold *gold; 770 char *verb = Blind ? "feel" : "see"; 771 int ct = 0; 772 773 if(!u.uswallow) { 774 if(Blind) { 775 pline("You try to feel what is lying here on the floor."); 776 if(Levitation) { /* ab@unido */ 777 pline("You cannot reach the floor!"); 778 return(1); 779 } 780 } 781 otmp0 = o_at(u.ux, u.uy); 782 gold = g_at(u.ux, u.uy); 783 } 784 785 if(u.uswallow || (!otmp0 && !gold)) { 786 pline("You %s no objects here.", verb); 787 return(!!Blind); 788 } 789 790 cornline(0, "Things that are here:"); 791 for(otmp = otmp0; otmp; otmp = otmp->nobj) { 792 if(otmp->ox == u.ux && otmp->oy == u.uy) { 793 ct++; 794 cornline(1, doname(otmp)); 795 if(Blind && otmp->otyp == DEAD_COCKATRICE && !uarmg) { 796 pline("Touching the dead cockatrice is a fatal mistake ..."); 797 pline("You die ..."); 798 killer = "dead cockatrice"; 799 done("died"); 800 } 801 } 802 } 803 804 if(gold) { 805 char gbuf[30]; 806 807 (void) sprintf(gbuf, "%ld gold piece%s", 808 gold->amount, plur(gold->amount)); 809 if(!ct++) 810 pline("You %s here %s.", verb, gbuf); 811 else 812 cornline(1, gbuf); 813 } 814 815 if(ct == 1 && !gold) { 816 pline("You %s here %s.", verb, doname(otmp0)); 817 cornline(3, (char *) 0); 818 } 819 if(ct > 1) 820 cornline(2, (char *) 0); 821 return(!!Blind); 822 } 823 824 stackobj(obj) register struct obj *obj; { 825 register struct obj *otmp = fobj; 826 for(otmp = fobj; otmp; otmp = otmp->nobj) if(otmp != obj) 827 if(otmp->ox == obj->ox && otmp->oy == obj->oy && 828 merged(obj,otmp,1)) 829 return; 830 } 831 832 /* merge obj with otmp and delete obj if types agree */ 833 merged(otmp,obj,lose) register struct obj *otmp, *obj; { 834 if(obj->otyp == otmp->otyp && 835 obj->unpaid == otmp->unpaid && 836 obj->spe == otmp->spe && 837 obj->dknown == otmp->dknown && 838 obj->cursed == otmp->cursed && 839 (index("%*?!", obj->olet) || 840 (obj->known == otmp->known && 841 (obj->olet == WEAPON_SYM && obj->otyp < BOOMERANG)))) { 842 otmp->quan += obj->quan; 843 otmp->owt += obj->owt; 844 if(lose) freeobj(obj); 845 obfree(obj,otmp); /* free(obj), bill->otmp */ 846 return(1); 847 } else return(0); 848 } 849 850 /* 851 * Gold is no longer displayed; in fact, when you have a lot of money, 852 * it may take a while before you have counted it all. 853 * [Bug: d$ and pickup still tell you how much it was.] 854 */ 855 extern int (*occupation)(); 856 extern char *occtxt; 857 static long goldcounted; 858 859 countgold(){ 860 if((goldcounted += 100*(u.ulevel + 1)) >= u.ugold) { 861 long eps = 0; 862 if(!rn2(2)) eps = rnd((int) (u.ugold/100 + 1)); 863 pline("You probably have about %ld gold pieces.", 864 u.ugold + eps); 865 return(0); /* done */ 866 } 867 return(1); /* continue */ 868 } 869 870 doprgold(){ 871 if(!u.ugold) 872 pline("You do not carry any gold."); 873 else if(u.ugold <= 500) 874 pline("You are carrying %ld gold pieces.", u.ugold); 875 else { 876 pline("You sit down in order to count your gold pieces."); 877 goldcounted = 500; 878 occupation = countgold; 879 occtxt = "counting your gold"; 880 } 881 return(1); 882 } 883 884 /* --- end of gold counting section --- */ 885 886 doprwep(){ 887 if(!uwep) pline("You are empty handed."); 888 else prinv(uwep); 889 return(0); 890 } 891 892 doprarm(){ 893 if(!uarm && !uarmg && !uarms && !uarmh) 894 pline("You are not wearing any armor."); 895 else { 896 char lets[6]; 897 register int ct = 0; 898 899 if(uarm) lets[ct++] = obj_to_let(uarm); 900 if(uarm2) lets[ct++] = obj_to_let(uarm2); 901 if(uarmh) lets[ct++] = obj_to_let(uarmh); 902 if(uarms) lets[ct++] = obj_to_let(uarms); 903 if(uarmg) lets[ct++] = obj_to_let(uarmg); 904 lets[ct] = 0; 905 doinv(lets); 906 } 907 return(0); 908 } 909 910 doprring(){ 911 if(!uleft && !uright) 912 pline("You are not wearing any rings."); 913 else { 914 char lets[3]; 915 register int ct = 0; 916 917 if(uleft) lets[ct++] = obj_to_let(uleft); 918 if(uright) lets[ct++] = obj_to_let(uright); 919 lets[ct] = 0; 920 doinv(lets); 921 } 922 return(0); 923 } 924 925 digit(c) char c; { 926 return(c >= '0' && c <= '9'); 927 }