abstract
| - Below is the full text to invent.c from the source code of NetHack 2.2a. To link to a particular line, write [[NetHack 2.2a/invent.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code 1. /* SCCS Id: @(#)invent.c 2.1 87/10/19 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. 4. #include 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 16. 17. #define NOINVSYM '#' 18. 19. int lastinvnr = 51; /* 0 ... 51 */ 20. 21. static 22. assigninvlet(otmp) 23. register struct obj *otmp; 24. { 25. boolean inuse[52]; 26. register int i; 27. register struct obj *obj; 28. 29. for(i = 0; i < 52; i++) inuse[i] = FALSE; 30. for(obj = invent; obj; obj = obj->nobj) if(obj != otmp) { 31. i = obj->invlet; 32. if('a' <= i && i <= 'z') inuse[i - 'a'] = TRUE; else 33. if('A' <= i && i <= 'Z') inuse[i - 'A' + 26] = TRUE; 34. if(i == otmp->invlet) otmp->invlet = 0; 35. } 36. if((i = otmp->invlet) && 37. (('a' <= i && i <= 'z') || ('A' <= i && i <= 'Z'))) 38. return; 39. for(i = lastinvnr+1; i != lastinvnr; i++) { 40. if(i == 52) { i = -1; continue; } 41. if(!inuse[i]) break; 42. } 43. otmp->invlet = (inuse[i] ? NOINVSYM : 44. (i < 26) ? ('a'+i) : ('A'+i-26)); 45. lastinvnr = i; 46. } 47. 48. struct obj * 49. addinv(obj) 50. register struct obj *obj; 51. { 52. register struct obj *otmp; 53. 54. /* merge or attach to end of chain */ 55. if(!invent) { 56. invent = obj; 57. otmp = 0; 58. } else 59. for(otmp = invent; /* otmp */; otmp = otmp->nobj) { 60. if(merged(otmp, obj, 0)) 61. return(otmp); 62. if(!otmp->nobj) { 63. otmp->nobj = obj; 64. break; 65. } 66. } 67. obj->nobj = 0; 68. 69. if(flags.invlet_constant) { 70. assigninvlet(obj); 71. /* 72. * The ordering of the chain is nowhere significant 73. * so in case you prefer some other order than the 74. * historical one, change the code below. 75. */ 76. if(otmp) { /* find proper place in chain */ 77. otmp->nobj = 0; 78. if((invent->invlet ^ 040) > (obj->invlet ^ 040)) { 79. obj->nobj = invent; 80. invent = obj; 81. } else 82. for(otmp = invent; ; otmp = otmp->nobj) { 83. if(!otmp->nobj || 84. (otmp->nobj->invlet ^ 040) > (obj->invlet ^ 040)){ 85. obj->nobj = otmp->nobj; 86. otmp->nobj = obj; 87. break; 88. } 89. } 90. } 91. } 92. 93. return(obj); 94. } 95. 96. useup(obj) 97. register struct obj *obj; 98. { 99. if(obj->quan > 1){ 100. obj->quan--; 101. obj->owt = weight(obj); 102. } else { 103. setnotworn(obj); 104. freeinv(obj); 105. obfree(obj, (struct obj *) 0); 106. } 107. } 108. 109. freeinv(obj) 110. register struct obj *obj; 111. { 112. register struct obj *otmp; 113. 114. if(obj == invent) 115. invent = invent->nobj; 116. else { 117. for(otmp = invent; otmp->nobj != obj; otmp = otmp->nobj) 118. if(!otmp->nobj) panic("freeinv"); 119. otmp->nobj = obj->nobj; 120. } 121. } 122. 123. /* destroy object in fobj chain (if unpaid, it remains on the bill) */ 124. delobj(obj) register struct obj *obj; { 125. freeobj(obj); 126. unpobj(obj); 127. obfree(obj, (struct obj *) 0); 128. } 129. 130. /* unlink obj from chain starting with fobj */ 131. freeobj(obj) register struct obj *obj; { 132. register struct obj *otmp; 133. 134. if(obj == fobj) fobj = fobj->nobj; 135. else { 136. for(otmp = fobj; otmp->nobj != obj; otmp = otmp->nobj) 137. if(!otmp) panic("error in freeobj"); 138. otmp->nobj = obj->nobj; 139. } 140. } 141. 142. /* Note: freegold throws away its argument! */ 143. freegold(gold) register struct gold *gold; { 144. register struct gold *gtmp; 145. 146. if(gold == fgold) fgold = gold->ngold; 147. else { 148. for(gtmp = fgold; gtmp->ngold != gold; gtmp = gtmp->ngold) 149. if(!gtmp) panic("error in freegold"); 150. gtmp->ngold = gold->ngold; 151. } 152. free((char *) gold); 153. } 154. 155. deltrap(trap) 156. register struct trap *trap; 157. { 158. register struct trap *ttmp; 159. 160. if(trap == ftrap) 161. ftrap = ftrap->ntrap; 162. else { 163. for(ttmp = ftrap; ttmp->ntrap != trap; ttmp = ttmp->ntrap) ; 164. ttmp->ntrap = trap->ntrap; 165. } 166. free((char *) trap); 167. } 168. 169. struct wseg *m_atseg; 170. 171. struct monst * 172. m_at(x,y) 173. register x,y; 174. { 175. register struct monst *mtmp; 176. #ifndef NOWORM 177. register struct wseg *wtmp; 178. #endif 179. 180. m_atseg = 0; 181. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon){ 182. if(mtmp->mx == x && mtmp->my == y) 183. return(mtmp); 184. #ifndef NOWORM 185. if(mtmp->wormno){ 186. for(wtmp = wsegs[mtmp->wormno]; wtmp; wtmp = wtmp->nseg) 187. if(wtmp->wx == x && wtmp->wy == y){ 188. m_atseg = wtmp; 189. return(mtmp); 190. } 191. } 192. #endif 193. } 194. return(0); 195. } 196. 197. struct obj * 198. o_at(x,y) 199. register x,y; 200. { 201. register struct obj *otmp; 202. 203. for(otmp = fobj; otmp; otmp = otmp->nobj) 204. if(otmp->ox == x && otmp->oy == y) return(otmp); 205. return(0); 206. } 207. 208. struct obj * 209. sobj_at(n,x,y) 210. register n,x,y; 211. { 212. register struct obj *otmp; 213. 214. for(otmp = fobj; otmp; otmp = otmp->nobj) 215. if(otmp->ox == x && otmp->oy == y && otmp->otyp == n) 216. return(otmp); 217. return(0); 218. } 219. 220. carried(obj) register struct obj *obj; { 221. register struct obj *otmp; 222. for(otmp = invent; otmp; otmp = otmp->nobj) 223. if(otmp == obj) return(1); 224. return(0); 225. } 226. 227. struct obj * 228. carrying(type) 229. register int type; 230. { 231. register struct obj *otmp; 232. 233. for(otmp = invent; otmp; otmp = otmp->nobj) 234. if(otmp->otyp == type) 235. return(otmp); 236. return((struct obj *) 0); 237. } 238. 239. struct obj * 240. o_on(id, objchn) unsigned int id; register 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. register x,y; 251. { 252. register 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. register x,y; 263. { 264. register 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. register long q; 276. { 277. register struct obj *otmp; 278. 279. otmp = newobj(0); 280. /* should set o_id etc. but otmp will be freed soon */ 281. otmp->olet = GOLD_SYM; 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. register char *let,*word; 297. { 298. register struct obj *otmp; 299. register char ilet,ilet1,ilet2; 300. char buf[BUFSZ]; 301. char lets[BUFSZ]; 302. register int foo = 0, foo2; 303. register 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 == GOLD_SYM) let++, allowgold = TRUE; 313. if(*let == '#') let++, allowall = TRUE; 314. if(*let == '-') let++, allownone = TRUE; 315. if(allownone) *bp++ = '-'; 316. if(allowgold) *bp++ = GOLD_SYM; 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. #ifdef MARKER 332. || (!strcmp(word, "write with") && 333. (otmp->olet == TOOL_SYM && otmp->otyp != MAGIC_MARKER)) 334. #endif 335. ) { 336. foo--; 337. foox++; 338. } 339. } 340. if(ilet == 'z') ilet = 'A'; else ilet++; 341. } 342. bp[foo] = 0; 343. if(foo == 0 && bp > buf && bp[-1] == ' ') *--bp = 0; 344. (void) strcpy(lets, bp); /* necessary since we destroy buf */ 345. if(foo > 5) { /* compactify string */ 346. foo = foo2 = 1; 347. ilet2 = bp[0]; 348. ilet1 = bp[1]; 349. while(ilet = bp[++foo2] = bp[++foo]){ 350. if(ilet == ilet1+1){ 351. if(ilet1 == ilet2+1) 352. bp[foo2 - 1] = ilet1 = '-'; 353. else if(ilet2 == '-') { 354. bp[--foo2] = ++ilet1; 355. continue; 356. } 357. } 358. ilet2 = ilet1; 359. ilet1 = ilet; 360. } 361. } 362. if(!foo && !allowall && !allowgold && !allownone) { 363. pline("You don't have anything %sto %s.", 364. foox ? "else " : "", word); 365. return(0); 366. } 367. for(;;) { 368. if(!buf[0]) { 369. #ifdef REDO 370. if(!in_doagain) 371. #endif 372. pline("What do you want to %s [*]? ", word); 373. } else { 374. #ifdef REDO 375. if(!in_doagain) 376. #endif 377. pline("What do you want to %s [%s or ?*]? ", 378. word, buf); 379. } 380. cnt = 0; 381. ilet = readchar(); 382. while(digit(ilet) && allowcnt) { 383. #ifdef REDO 384. if (ilet != '?' && ilet != '*') savech(ilet); 385. #endif 386. cnt = 10*cnt + (ilet - '0'); 387. allowcnt = 2; /* signal presence of cnt */ 388. ilet = readchar(); 389. } 390. if(digit(ilet)) { 391. pline("No count allowed with this command."); 392. continue; 393. } 394. if(index(quitchars,ilet)) { 395. pline("Never mind."); 396. return((struct obj *)0); 397. } 398. if(ilet == '-') { 399. return(allownone ? &zeroobj : (struct obj *) 0); 400. } 401. if(ilet == GOLD_SYM) { 402. if(!allowgold){ 403. pline("You cannot %s gold.", word); 404. continue; 405. } 406. if(!(allowcnt == 2 && cnt < u.ugold)) 407. cnt = u.ugold; 408. return(mkgoldobj(cnt)); 409. } 410. if(ilet == '?') { 411. doinv(lets); 412. if(!(ilet = morc)) continue; 413. /* he typed a letter (not a space) to more() */ 414. } else if(ilet == '*') { 415. doinv((char *) 0); 416. if(!(ilet = morc)) continue; 417. /* ... */ 418. } 419. #ifdef REDO 420. if (ilet != '?' && ilet != '*') savech(ilet); 421. #endif 422. if(flags.invlet_constant) { 423. for(otmp = invent; otmp; otmp = otmp->nobj) 424. if(otmp->invlet == ilet) break; 425. } else { 426. if(ilet >= 'A' && ilet <= 'Z') ilet += 'z'-'A'+1; 427. ilet -= 'a'; 428. for(otmp = invent; otmp && ilet; 429. ilet--, otmp = otmp->nobj) ; 430. } 431. if(!otmp) { 432. pline("You don't have that object."); 433. continue; 434. } 435. if(cnt < 0 || otmp->quan < cnt) { 436. pline("You don't have that many! [You have %u]" 437. , otmp->quan); 438. continue; 439. } 440. break; 441. } 442. if(!allowall && let && !index(let,otmp->olet)) { 443. pline("That is a silly thing to %s.",word); 444. return(0); 445. } 446. if(allowcnt == 2) { /* cnt given */ 447. if(cnt == 0) return(0); 448. if(cnt != otmp->quan) { 449. register struct obj *obj; 450. obj = splitobj(otmp, (int) cnt); 451. if(otmp == uwep) setuwep(obj); 452. } 453. } 454. return(otmp); 455. } 456. 457. ckunpaid(otmp) register struct obj *otmp; { 458. return( otmp->unpaid ); 459. } 460. 461. /* interactive version of getobj - used for Drop and Identify */ 462. /* return the number of times fn was called successfully */ 463. ggetobj(word, fn, max) 464. char *word; 465. int (*fn)(), max; 466. { 467. char buf[BUFSZ]; 468. register char *ip; 469. register char sym; 470. register int oletct = 0, iletct = 0; 471. register boolean allflag = FALSE; 472. char olets[20], ilets[20]; 473. int (*ckfn)() = (int (*)()) 0; 474. xchar allowgold = (u.ugold && !strcmp(word, "drop")) ? 1 : 0; /* BAH */ 475. if(!invent && !allowgold){ 476. pline("You have nothing to %s.", word); 477. return(0); 478. } else { 479. register struct obj *otmp = invent; 480. register int uflg = 0; 481. 482. if(allowgold) ilets[iletct++] = GOLD_SYM; 483. ilets[iletct] = 0; 484. while(otmp) { 485. if(!index(ilets, otmp->olet)){ 486. ilets[iletct++] = otmp->olet; 487. ilets[iletct] = 0; 488. } 489. if(otmp->unpaid) uflg = 1; 490. otmp = otmp->nobj; 491. } 492. ilets[iletct++] = ' '; 493. if(uflg) ilets[iletct++] = 'u'; 494. if(invent) ilets[iletct++] = 'a'; 495. ilets[iletct] = 0; 496. } 497. pline("What kinds of thing do you want to %s? [%s] ", 498. word, ilets); 499. getlin(buf); 500. if(buf[0] == '\033') { 501. clrlin(); 502. return(0); 503. } 504. ip = buf; 505. olets[0] = 0; 506. while(sym = *ip++){ 507. if(sym == ' ') continue; 508. if(sym == GOLD_SYM) { 509. if(allowgold == 1) 510. (*fn)(mkgoldobj(u.ugold)); 511. else if(!u.ugold) 512. pline("You have no gold."); 513. allowgold = 2; 514. } else 515. if(sym == 'a' || sym == 'A') allflag = TRUE; else 516. if(sym == 'u' || sym == 'U') ckfn = ckunpaid; else 517. #ifdef SPELLS 518. if(index("!%?[()=*/+\"0", sym)){ 519. #else 520. if(index("!%?[()=*/\"0", sym)){ 521. #endif 522. if(!index(olets, sym)){ 523. olets[oletct++] = sym; 524. olets[oletct] = 0; 525. } 526. } 527. else pline("You don't have any %c's.", sym); 528. } 529. if(allowgold == 2 && !oletct) 530. return(1); /* he dropped gold (or at least tried to) */ 531. else 532. return(askchain(invent, olets, allflag, fn, ckfn, max)); 533. } 534. 535. /* 536. * Walk through the chain starting at objchn and ask for all objects 537. * with olet in olets (if nonNULL) and satisfying ckfn (if nonNULL) 538. * whether the action in question (i.e., fn) has to be performed. 539. * If allflag then no questions are asked. Max gives the max nr of 540. * objects to be treated. Return the number of objects treated. 541. */ 542. askchain(objchn, olets, allflag, fn, ckfn, max) 543. struct obj *objchn; 544. register char *olets; 545. int allflag; 546. int (*fn)(), (*ckfn)(); 547. int max; 548. { 549. register struct obj *otmp, *otmp2; 550. register char sym, ilet; 551. register int cnt = 0; 552. #ifdef SORTING 553. /* changes so the askchain is interrogated in the order specified. 554. * For example, if a person specifies =/ then first all rings will be 555. * asked about followed by all wands -dgk 556. */ 557. nextclass: 558. #endif 559. ilet = 'a'-1; 560. for(otmp = objchn; otmp; otmp = otmp2){ 561. if(ilet == 'z') ilet = 'A'; else ilet++; 562. otmp2 = otmp->nobj; 563. #ifdef SORTING 564. if (olets && *olets && otmp->olet != *olets) continue; 565. #else 566. if(olets && *olets && !index(olets, otmp->olet)) continue; 567. #endif 568. if(ckfn && !(*ckfn)(otmp)) continue; 569. if(!allflag) { 570. pline(xprname(otmp, ilet)); 571. addtopl(" [nyaq]? "); 572. sym = readchar(); 573. } 574. else sym = 'y'; 575. 576. switch(sym){ 577. case 'a': 578. allflag = 1; 579. case 'y': 580. cnt += (*fn)(otmp); 581. if(--max == 0) goto ret; 582. case 'n': 583. default: 584. break; 585. case 'q': 586. goto ret; 587. } 588. } 589. #ifdef SORTING 590. if (olets && *olets && *++olets) 591. goto nextclass; 592. #endif 593. pline(cnt ? "That was all." : "No applicable objects."); 594. ret: 595. return(cnt); 596. } 597. 598. obj_to_let(obj) /* should of course only be called for things in invent */ 599. register struct obj *obj; 600. { 601. register struct obj *otmp; 602. register char ilet; 603. 604. if(flags.invlet_constant) 605. return(obj->invlet); 606. ilet = 'a'; 607. for(otmp = invent; otmp && otmp != obj; otmp = otmp->nobj) 608. if(++ilet > 'z') ilet = 'A'; 609. return(otmp ? ilet : NOINVSYM); 610. } 611. 612. prinv(obj) 613. register struct obj *obj; 614. { 615. pline(xprname(obj, obj_to_let(obj))); 616. } 617. 618. static char * 619. xprname(obj,let) 620. register struct obj *obj; 621. register char let; 622. { 623. static char li[BUFSZ]; 624. 625. (void) sprintf(li, "%c - %s.", 626. flags.invlet_constant ? obj->invlet : let, 627. doname(obj)); 628. return(li); 629. } 630. 631. ddoinv() 632. { 633. doinv((char *) 0); 634. return(0); 635. } 636. 637. #ifdef SORTING 638. # ifdef SPELLS 639. char inv_order[] = "\")[%?+/=!(*0_`"; /* to be safe, include _ and ` */ 640. # else 641. char inv_order[] = "\")[%?/=!(*0_`"; 642. # endif 643. extern char *let_to_name(); 644. #endif 645. 646. /* called with 0 or "": all objects in inventory */ 647. /* otherwise: all objects with (serial) letter in lets */ 648. doinv(lets) 649. register char *lets; 650. { 651. register struct obj *otmp; 652. register char ilet; 653. int ct = 0; 654. char any[BUFSZ]; 655. #ifdef SORTING 656. char *invlet = inv_order; 657. int classcount = 0; 658. #endif /* SORTING /**/ 659. 660. morc = 0; /* just to be sure */ 661. 662. if(!invent){ 663. pline("Not carrying anything."); 664. return; 665. } 666. 667. cornline(0, (char *) 0); 668. #ifdef SORTING 669. nextclass: 670. classcount = 0; 671. ilet = 'a'; 672. for(otmp = invent; otmp; otmp = otmp->nobj) { 673. if(flags.invlet_constant) ilet = otmp->invlet; 674. if(!lets || !*lets || index(lets, ilet)) { 675. if (!flags.sortpack || otmp->olet == *invlet) { 676. if (flags.sortpack && !classcount) { 677. cornline(1, let_to_name(*invlet)); 678. classcount++; 679. } 680. cornline(1, xprname(otmp, ilet)); 681. any[ct++] = ilet; 682. } 683. } 684. if(!flags.invlet_constant) if(++ilet > 'z') ilet = 'A'; 685. } 686. if (flags.sortpack && *++invlet) goto nextclass; 687. #else 688. ilet = 'a'; 689. for(otmp = invent; otmp; otmp = otmp->nobj) { 690. if(flags.invlet_constant) ilet = otmp->invlet; 691. if(!lets || !*lets || index(lets, ilet)) { 692. cornline(1, xprname(otmp, ilet)); 693. any[ct++] = ilet; 694. } 695. if(!flags.invlet_constant) if(++ilet > 'z') ilet = 'A'; 696. } 697. #endif /* SORTING /**/ 698. any[ct] = 0; 699. cornline(2, any); 700. } 701. 702. dotypeinv () /* free after Robert Viduya */ 703. /* Changed to one type only, so he doesnt have to type cr */ 704. { 705. char c, ilet; 706. char stuff[BUFSZ]; 707. register int stct; 708. register struct obj *otmp; 709. boolean billx = inshop() && doinvbill(0); 710. boolean unpd = FALSE; 711. 712. if (!invent && !u.ugold && !billx) { 713. pline ("You aren't carrying anything."); 714. return(0); 715. } 716. 717. stct = 0; 718. if(u.ugold) stuff[stct++] = GOLD_SYM; 719. stuff[stct] = 0; 720. for(otmp = invent; otmp; otmp = otmp->nobj) { 721. if (!index (stuff, otmp->olet)) { 722. stuff[stct++] = otmp->olet; 723. stuff[stct] = 0; 724. } 725. if(otmp->unpaid) 726. unpd = TRUE; 727. } 728. if(unpd) stuff[stct++] = 'u'; 729. if(billx) stuff[stct++] = 'x'; 730. stuff[stct] = 0; 731. 732. if(stct > 1) { 733. #ifdef REDO 734. if (!in_doagain) 735. #endif 736. pline ("What type of object [%s] do you want an inventory of? ", 737. stuff); 738. c = readchar(); 739. #ifdef REDO 740. savech(c); 741. #endif 742. if(index(quitchars,c)) { 743. clrlin(); 744. return(0); 745. } 746. } else 747. c = stuff[0]; 748. 749. if(c == GOLD_SYM) 750. return(doprgold()); 751. 752. if(c == 'x' || c == 'X') { 753. if(billx) 754. (void) doinvbill(1); 755. else 756. pline("No used-up objects on the shopping bill."); 757. return(0); 758. } 759. 760. if((c == 'u' || c == 'U') && !unpd) { 761. pline("You are not carrying any unpaid objects."); 762. return(0); 763. } 764. 765. stct = 0; 766. ilet = 'a'; 767. for (otmp = invent; otmp; otmp = otmp -> nobj) { 768. if(flags.invlet_constant) ilet = otmp->invlet; 769. if (c == otmp -> olet || (c == 'u' && otmp -> unpaid)) 770. stuff[stct++] = ilet; 771. if(!flags.invlet_constant) if(++ilet > 'z') ilet = 'A'; 772. } 773. stuff[stct] = '\0'; 774. if(stct == 0) 775. pline("You have no such objects."); 776. else 777. doinv (stuff); 778. 779. return(0); 780. } 781. 782. /* look at what is here */ 783. dolook() { 784. register struct obj *otmp, *otmp0; 785. register struct gold *gold; 786. char *verb = Blind ? "feel" : "see"; 787. int ct = 0; 788. int fd = 0; 789. 790. #ifdef KAA 791. read_engr_at(u.ux, u.uy); /* Eric Backus */ 792. #endif 793. if(!u.uswallow) { 794. otmp0 = o_at(u.ux, u.uy); 795. gold = g_at(u.ux, u.uy); 796. } else { 797. pline("You %s no objects here.", verb); 798. return(!!Blind); 799. } 800. 801. /* added by GAN 10/30/86 */ 802. #ifdef FOUNTAINS 803. if(IS_FOUNTAIN(levl[u.ux][u.uy].typ)) { 804. fd++; 805. pline("There is a fountain here."); 806. } 807. #endif 808. #ifdef NEWCLASS 809. if(IS_THRONE(levl[u.ux][u.uy].typ)) { 810. fd++; 811. pline("There is an opulent throne here."); 812. } 813. #endif 814. if(u.ux == xupstair && u.uy == yupstair) { 815. fd++; 816. pline("There is a stairway up here."); 817. } 818. if(u.ux == xdnstair && u.uy == ydnstair) { 819. fd++; 820. pline("There is a stairway down here."); 821. } 822. if(Blind) { 823. pline("You try to feel what is lying here on the floor."); 824. if(Levitation) { 825. pline("But you can't reach it!"); 826. return(0); 827. } 828. } 829. 830. if(!otmp0 && !gold) { 831. if(Blind || !fd) 832. pline("You %s no objects here.", verb); 833. return(!!Blind); 834. } 835. 836. cornline(0, "Things that are here:"); 837. for(otmp = otmp0; otmp; otmp = otmp->nobj) { 838. if(otmp->ox == u.ux && otmp->oy == u.uy) { 839. ct++; 840. cornline(1, doname(otmp)); 841. 842. if(Blind && otmp->otyp == DEAD_COCKATRICE && !uarmg) { 843. pline("Touching the dead cockatrice is a fatal mistake ..."); 844. pline("You die ..."); 845. killer = "dead cockatrice"; 846. done("died"); 847. } 848. } 849. } 850. 851. if(gold) { 852. char gbuf[30]; 853. 854. (void) sprintf(gbuf, "%ld gold piece%s", 855. gold->amount, plur(gold->amount)); 856. if(!ct++) 857. pline("You %s here %s.", verb, gbuf); 858. else 859. cornline(1, gbuf); 860. } 861. 862. if(ct == 1 && !gold) { 863. pline("You %s here %s.", verb, doname(otmp0)); 864. cornline(3, (char *) 0); 865. } 866. if(ct > 1) 867. cornline(2, (char *) 0); 868. return(!!Blind); 869. } 870. 871. stackobj(obj) register struct obj *obj; { 872. register struct obj *otmp = fobj; 873. for(otmp = fobj; otmp; otmp = otmp->nobj) if(otmp != obj) 874. if(otmp->ox == obj->ox && otmp->oy == obj->oy && 875. merged(obj,otmp,1)) 876. return; 877. } 878. 879. /* merge obj with otmp and delete obj if types agree */ 880. merged(otmp,obj,lose) register struct obj *otmp, *obj; { 881. if(obj->otyp == otmp->otyp && 882. obj->unpaid == otmp->unpaid && 883. obj->spe == otmp->spe && 884. obj->dknown == otmp->dknown && 885. obj->cursed == otmp->cursed && 886. #ifdef SPELLS 887. (index("%*?!+", obj->olet) || 888. #else 889. (index("%*?!", obj->olet) || 890. #endif 891. (obj->known == otmp->known && 892. (obj->olet == WEAPON_SYM && obj->otyp < BOOMERANG)))) { 893. otmp->quan += obj->quan; 894. otmp->owt += obj->owt; 895. if(lose) freeobj(obj); 896. obfree(obj,otmp); /* free(obj), bill->otmp */ 897. return(1); 898. } else return(0); 899. } 900. 901. /* 902. * Gold is no longer displayed; in fact, when you have a lot of money, 903. * it may take a while before you have counted it all. 904. * [Bug: d$ and pickup still tell you how much it was.] 905. */ 906. extern int (*occupation)(); 907. extern char *occtxt; 908. static long goldcounted; 909. 910. countgold(){ 911. if((goldcounted += 100*(u.ulevel + 1)) >= u.ugold) { 912. long eps = 0; 913. if(!rn2(2)) eps = rnd((int) (u.ugold/100 + 1)); 914. pline("You probably have about %ld gold pieces.", 915. u.ugold + eps); 916. return(0); /* done */ 917. } 918. return(1); /* continue */ 919. } 920. 921. doprgold(){ 922. if(!u.ugold) 923. pline("You do not carry any gold."); 924. else if(u.ugold <= 500) 925. pline("You are carrying %ld gold piece%s.", u.ugold, plur(u.ugold)); 926. else { 927. pline("You sit down in order to count your gold pieces."); 928. goldcounted = 500; 929. occupation = countgold; 930. occtxt = "counting your gold"; 931. } 932. return(1); 933. } 934. 935. /* --- end of gold counting section --- */ 936. 937. doprwep(){ 938. if(!uwep) pline("You are empty handed."); 939. else prinv(uwep); 940. return(0); 941. } 942. 943. doprarm(){ 944. if(!uarm && !uarmg && !uarms && !uarmh) 945. pline("You are not wearing any armor."); 946. else { 947. char lets[6]; 948. register int ct = 0; 949. 950. if(uarm) lets[ct++] = obj_to_let(uarm); 951. if(uarm2) lets[ct++] = obj_to_let(uarm2); 952. if(uarmh) lets[ct++] = obj_to_let(uarmh); 953. if(uarms) lets[ct++] = obj_to_let(uarms); 954. if(uarmg) lets[ct++] = obj_to_let(uarmg); 955. lets[ct] = 0; 956. doinv(lets); 957. } 958. return(0); 959. } 960. 961. doprring(){ 962. if(!uleft && !uright) 963. pline("You are not wearing any rings."); 964. else { 965. char lets[3]; 966. register int ct = 0; 967. 968. if(uleft) lets[ct++] = obj_to_let(uleft); 969. if(uright) lets[ct++] = obj_to_let(uright); 970. lets[ct] = 0; 971. doinv(lets); 972. } 973. return(0); 974. } 975. 976. digit(c) char c; { 977. return(c >= '0' && c <= '9'); 978. } 979. 980. /* 981. * useupf(obj) 982. * uses up an object that's on the floor 983. */ 984. useupf(obj) 985. register struct obj *obj; 986. { 987. if(obj->quan > 1) { 988. obj->quan--; 989. obj->owt = weight(obj); 990. } else delobj(obj); 991. } 992. 993. #ifdef SORTING 994. /* 995. * Convert from a symbol to a string for printing object classes 996. * 997. * Names from objects.h 998. * char obj_symbols[] = { 999. * ILLOBJ_SYM, AMULET_SYM, FOOD_SYM, WEAPON_SYM, TOOL_SYM, 1000. * BALL_SYM, CHAIN_SYM, ROCK_SYM, ARMOR_SYM, POTION_SYM, SCROLL_SYM, 1001. * WAND_SYM, [SPBOOK_SYM], RING_SYM, GEM_SYM, 0 }; 1002. */ 1003. #define Sprintf (void) sprintf 1004. 1005. extern char obj_symbols[]; 1006. static char *names[] = {"Illegal objects", "Amulets", "Comestibles", "Weapons", 1007. "Tools", "Iron balls", "Chains", "Rocks", "Armor", 1008. "Potions", "Scrolls", "Wands", 1009. #ifdef SPELLS 1010. "Spellbooks", 1011. #endif 1012. "Rings", "Gems"}; 1013. char * 1014. let_to_name(let) 1015. char let; 1016. { 1017. char *pos = index(obj_symbols, let); 1018. extern char *HI, *HE; 1019. /* arbitrary buffer size by Tom May (tom@uw-warp) */ 1020. static char *buf = NULL; 1021. 1022. if (buf == NULL) 1023. buf = (char *) alloc (strlen(HI) + strlen(HE) + 15 + 1); 1024. 1025. if (pos == NULL) pos = obj_symbols; 1026. if (HI && HE) 1027. Sprintf(buf, "%s%s%s", HI, names[pos - obj_symbols], HE); 1028. else 1029. Sprintf(buf, "%s", names[pos - obj_symbols]); 1030. return (buf); 1031. } 1032. #endif /* SORTING /**/ 1033. 1034. reassign () 1035. { 1036. register int i; 1037. register struct obj *obj; 1038. 1039. for(obj = invent, i = 0; obj; obj = obj->nobj, i++) 1040. obj->invlet = (i < 26) ? ('a'+i) : ('A'+i-26); 1041. lastinvnr = i; 1042. }
|